Compare commits

..

No commits in common. "c1fefcc766388420975fd0f4ea3cf77736df74e5" and "fcc2024045c6f3223fe171bf4c07eb4a4903f56b" have entirely different histories.

14 changed files with 10 additions and 457 deletions

View file

@ -8,8 +8,8 @@ Ladder (each tip autonomously `make html`; each depends on the previous):
| 1 | `main` | `d2fbd79` | http://127.0.0.1:8101/ | — | | 1 | `main` | `d2fbd79` | http://127.0.0.1:8101/ | — |
| 2 | `feat/sm-content` | `089ef1f` | http://127.0.0.1:8102/ | `dossiers.3.ngi.hacktivism.ch` (optional) | | 2 | `feat/sm-content` | `089ef1f` | http://127.0.0.1:8102/ | `dossiers.3.ngi.hacktivism.ch` (optional) |
| 3 | `feat/website-features` | `53a3176` | http://127.0.0.1:8103/ | `dossiers.2.ngi.hacktivism.ch` (optional) | | 3 | `feat/website-features` | `53a3176` | http://127.0.0.1:8103/ | `dossiers.2.ngi.hacktivism.ch` (optional) |
| 4 | `feat/website-design` | `2e26c80` | http://127.0.0.1:8104/ | — (no public host after views deploy) | | 4 | `feat/website-design` | `2e26c80` | http://127.0.0.1:8104/ | **`dossiers.ngi.hacktivism.ch`** (primary Deploy) |
| 5 | `feat/website-views` | `bbafc38` (origin tip; local soft-reset dropped bad `1b2fcf7`/`7aca0e8`) | http://127.0.0.1:8105/ | path roots under blank landing (see Live) | | 5 | `feat/website-views` | `42917e7` | http://127.0.0.1:8105/ | Deploy-Views (no 4th ht host yet) |
Caddy roots (SoT `scripts/caddy/Caddyfile.koopa-live-wdGet`): Caddy roots (SoT `scripts/caddy/Caddyfile.koopa-live-wdGet`):
@ -29,23 +29,14 @@ basic_auth: `scripts/caddy/apply-dossiers-ngi-basicauth.sh`
## Live ## Live
- [dossiers.ngi](https://dossiers.ngi.hacktivism.ch/) ← **blank cascade landing** (kal `sites/dossiers.ngi.hacktivism.ch/`; EN + ASCII ladder; views tip cite `bbafc38`) - [dossiers.ngi](https://dossiers.ngi.hacktivism.ch/) ← website-design freeze
- Path editions: `/main/`, `/feat-sm-content/`, `/feat-website-features/`, `/feat-website-design/`, `/feat-website-views/`
- Hourly branch-status builder: **kal** `scripts/dossiers-ngi/branch-status-hourly.py` → `sites/…/branch-status.json` (+ user timer); **not** inside tdpd
- tdpd `feat/website-views` local HEAD = origin = `bbafc38` (NO_PUSH; bad tips discarded locally)
- [dossiers.2.ngi](https://dossiers.2.ngi.hacktivism.ch/) ← website-features (optional) - [dossiers.2.ngi](https://dossiers.2.ngi.hacktivism.ch/) ← website-features (optional)
- [dossiers.3.ngi](https://dossiers.3.ngi.hacktivism.ch/) ← sm-content (optional) - [dossiers.3.ngi](https://dossiers.3.ngi.hacktivism.ch/) ← sm-content (optional)
## Deploy (Freigabe 2026-09-28 design; Freigabe 2026-09-29 views; Freigabe blank landing same day) ## Deploy (Freigabe 2026-09-28)
Earlier primary: rsync `website/build/` from tip `feat/website-views` → Primary: rsync `website/build/` from tip `feat/website-design` @ `2e26c80` →
`hernani@koopa:/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch/` `hernani@koopa:/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch/`
(`--delete`, exclude `.DS_Store`). (`--delete`, exclude `.DS_Store`).
**Result 2026-09-28 ~22:25+02 (design @ `2e26c80`):** `RSYNC_OK` — ~2698 files / ~27M; live `dossier/sm/index.html` 41693 bytes. **Result:** `RSYNC_OK` 2026-09-28 ~22:25+02 — ~2698 files / ~27M; live `dossier/sm/index.html` 41693 bytes.
**Result 2026-09-29 ~04:30+02 (views-era freeze):** `RSYNC_OK` — live `/` HTTP 200. Local tdpd later briefly carried wrong tips `1b2fcf7` → `7aca0e8` (ladder rewrite + hourly in tdpd); those were **dropped** locally back to `bbafc38` (TODO=430). Never push those tips.
**Result 2026-09-29 (blank landing kal @ `56ee97a`):** `RSYNC_OK` — live `/` HTTP 200 SIZE=3505 title `cascade landing`; path-root editions owned by koopa-admin-log `sites/dossiers.ngi.hacktivism.ch/`; NO_PUSH.
**TODO=430 follow-up (local, NO_PUSH):** kal landing EN/ASCII + tip cite `bbafc38`; hourly builder + systemd under kal; daylog tip table corrected. Deploy landing / enable timer on koopa needs Freigabe.

View file

@ -1,19 +0,0 @@
[Unit]
Description=Write dossiers.ngi branch-status.json from tdpd tips
Documentation=file:%h/src/koopa/koopa-admin-log/scripts/dossiers-ngi/README.md
After=default.target
[Service]
Type=oneshot
Nice=10
RemainAfterExit=no
Environment=TZ=Europe/Zurich
Environment=ADMIN_LOG=%h/src/koopa/koopa-admin-log
# Override on koopa if the tdpd checkout path differs
Environment=TDPD_ROOT=%h/git/src/ngi/tech-dossier-project-data
EnvironmentFile=-%h/.config/dossiers-ngi/branch-status.env
ExecStart=/usr/bin/python3 %h/src/koopa/koopa-admin-log/scripts/dossiers-ngi/branch-status-hourly.py
SuccessExitStatus=0 1
[Install]
WantedBy=default.target

View file

@ -1,13 +0,0 @@
[Unit]
Description=Timer · dossiers.ngi branch-status JSON (hourly)
Documentation=file:%h/src/koopa/koopa-admin-log/scripts/dossiers-ngi/README.md
[Timer]
OnBootSec=3min
OnUnitActiveSec=1h
AccuracySec=2min
Persistent=true
Unit=dossiers-ngi-branch-status.service
[Install]
WantedBy=timers.target

View file

@ -1,11 +1,11 @@
[Unit] [Unit]
Description=Timer · Taler landing stats (every 4h) Description=Timer · Taler landing stats (every 2 min)
Documentation=file:%h/src/koopa/koopa-admin-log/scripts/taler-landing/README.md Documentation=file:%h/src/koopa/koopa-admin-log/scripts/taler-landing/README.md
[Timer] [Timer]
OnBootSec=90s OnBootSec=90s
OnUnitActiveSec=4h OnUnitActiveSec=2min
AccuracySec=5min AccuracySec=20s
Persistent=true Persistent=true
Unit=taler-landing-stats.service Unit=taler-landing-stats.service

View file

@ -1,42 +0,0 @@
# dossiers-ngi — cascade landing + hourly branch-status
SoT for the blank cascade landing on **dossiers.ngi.hacktivism.ch**
(path roots only; no dossiers.2 / dossiers.3 ownership here).
| Path | Role |
|------|------|
| `sites/dossiers.ngi.hacktivism.ch/` | Landing HTML (EN, ASCII ladder) |
| `scripts/dossiers-ngi/branch-status-hourly.py` | Read tips from tdpd checkout → `branch-status.json` |
| `configs/systemd/user/dossiers-ngi-branch-status.{timer,service}` | Hourly oneshot on koopa |
## Env
| Var | Default | Meaning |
|-----|---------|---------|
| `TDPD_ROOT` | `$HOME/git/src/ngi/tech-dossier-project-data` | tech-dossier-project-data checkout for tip SHAs |
| `ADMIN_LOG` | (script derives from `__file__`) | koopa-admin-log root |
On koopa the clone often lives at `%h/src/koopa/koopa-admin-log`; set
`TDPD_ROOT` in the service `Environment=` if the tdpd path differs.
## Manual run
```bash
python3 scripts/dossiers-ngi/branch-status-hourly.py
# → sites/dossiers.ngi.hacktivism.ch/branch-status.json
```
## Deploy landing (Freigabe)
```text
hernani@koopa:/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch/
```
rsync from `sites/dossiers.ngi.hacktivism.ch/` — Freigabe this session required.
Hourly JSON can sit next to the HTML once the timer is installed on koopa
(Freigabe for host mutation).
## Ownership
Hourly builder belongs in **kal** (this tree). Do **not** put
`scripts/branch-status-hourly.py` back into tdpd.

View file

@ -1,86 +0,0 @@
#!/usr/bin/env python3
"""Emit branch-status.json for the dossiers.ngi path-root ladder.
Reads tip SHAs from the tech-dossier-project-data git checkout
(TDPD_ROOT / default). Writes under the kal landing SoT:
sites/dossiers.ngi.hacktivism.ch/branch-status.json
Path roots only under https://dossiers.ngi.hacktivism.ch/
(/main/, /feat-sm-content/, /feat-website-features/,
/feat-website-design/, /feat-website-views/).
Single public host only. Hourly builder lives in kal, not tdpd.
"""
from __future__ import annotations
import json
import os
import subprocess
import sys
from datetime import datetime, timezone
from pathlib import Path
ADMIN_LOG = Path(__file__).resolve().parents[2]
OUT = ADMIN_LOG / "sites" / "dossiers.ngi.hacktivism.ch" / "branch-status.json"
HOST = "https://dossiers.ngi.hacktivism.ch"
# Default local clone; override with TDPD_ROOT (koopa may use a different path).
DEFAULT_TDPD = Path.home() / "git" / "src" / "ngi" / "tech-dossier-project-data"
LADDER = [
("main", "", f"{HOST}/main/"),
("feat/sm-content", "main", f"{HOST}/feat-sm-content/"),
("feat/website-features", "feat/sm-content", f"{HOST}/feat-website-features/"),
("feat/website-design", "feat/website-features", f"{HOST}/feat-website-design/"),
("feat/website-views", "feat/website-design", f"{HOST}/feat-website-views/"),
]
def tdpd_root() -> Path:
raw = os.environ.get("TDPD_ROOT", "").strip()
return Path(raw).expanduser() if raw else DEFAULT_TDPD
def tip_of(repo: Path, branch: str) -> str:
try:
out = subprocess.check_output(
["git", "-C", str(repo), "rev-parse", "--short", branch],
stderr=subprocess.DEVNULL,
text=True,
).strip()
return out
except (subprocess.CalledProcessError, FileNotFoundError, OSError):
return ""
def main() -> int:
repo = tdpd_root()
if not (repo / ".git").exists() and not repo.is_dir():
print(f"TDPD_ROOT missing or not a dir: {repo}", file=sys.stderr)
return 1
branches = []
for name, parent, url in LADDER:
branches.append(
{
"branch": name,
"tip": tip_of(repo, name),
"parent": parent,
"url": url,
}
)
payload = {
"generated": datetime.now(timezone.utc).astimezone().isoformat(timespec="seconds"),
"host": HOST,
"branches": [
{"branch": b["branch"], "tip": b["tip"], "url": b["url"]}
for b in branches
],
}
OUT.parent.mkdir(parents=True, exist_ok=True)
OUT.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")
print(f"wrote {OUT}", file=sys.stderr)
return 0
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -50,7 +50,7 @@ systemctl --user list-timers 'taler-landing-stats*'
Units: Units:
- `configs/systemd/user/taler-landing-stats.service` — oneshot collector - `configs/systemd/user/taler-landing-stats.service` — oneshot collector
- `configs/systemd/user/taler-landing-stats.timer` — every **4h** after boot - `configs/systemd/user/taler-landing-stats.timer` — every **2 minutes** after boot
Installed paths: Installed paths:

View file

@ -1,31 +0,0 @@
{
"generated": "2026-09-30T02:30:50+02:00",
"host": "https://dossiers.ngi.hacktivism.ch",
"branches": [
{
"branch": "main",
"tip": "d2fbd79",
"url": "https://dossiers.ngi.hacktivism.ch/main/"
},
{
"branch": "feat/sm-content",
"tip": "089ef1f",
"url": "https://dossiers.ngi.hacktivism.ch/feat-sm-content/"
},
{
"branch": "feat/website-features",
"tip": "53a3176",
"url": "https://dossiers.ngi.hacktivism.ch/feat-website-features/"
},
{
"branch": "feat/website-design",
"tip": "2e26c80",
"url": "https://dossiers.ngi.hacktivism.ch/feat-website-design/"
},
{
"branch": "feat/website-views",
"tip": "bbafc38",
"url": "https://dossiers.ngi.hacktivism.ch/feat-website-views/"
}
]
}

View file

@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>feat/sm-content</title>
<style>
:root { color-scheme: dark; }
* { box-sizing: border-box; }
body {
margin: 0; padding: 1.5rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
font-size: 14px; line-height: 1.45;
background: #0b0d10; color: #c8d0d8;
}
a { color: #7ec8ff; text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 1.15rem; font-weight: 600; margin: 0 0 0.5rem; color: #e8eef4; }
.meta { color: #8a96a3; margin: 0 0 1rem; }
.nav { margin: 0.5rem 0 1rem; }
.nav a { margin-right: 0.85rem; }
ul.plain { padding-left: 1.2rem; margin: 0; }
li { margin: 0.25rem 0; }
.dim { color: #6a7682; }
</style>
</head>
<body>
<h1><code>/feat-sm-content/</code></h1>
<p class="meta">last-built: 2026-09-30T02:30:50+02:00 <span class="dim">·</span> <code>feat/sm-content</code> @ <code>089ef1f</code></p>
<div class="nav">
<a href="/">/</a>
<a href="/main/">/main/</a>
<a href="/feat-sm-content/">/feat-sm-content/</a>
<a href="/feat-website-features/">/feat-website-features/</a>
<a href="/feat-website-design/">/feat-website-design/</a>
<a href="/feat-website-views/">/feat-website-views/</a>
</div>
</body>
</html>

View file

@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>feat/website-design</title>
<style>
:root { color-scheme: dark; }
* { box-sizing: border-box; }
body {
margin: 0; padding: 1.5rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
font-size: 14px; line-height: 1.45;
background: #0b0d10; color: #c8d0d8;
}
a { color: #7ec8ff; text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 1.15rem; font-weight: 600; margin: 0 0 0.5rem; color: #e8eef4; }
.meta { color: #8a96a3; margin: 0 0 1rem; }
.nav { margin: 0.5rem 0 1rem; }
.nav a { margin-right: 0.85rem; }
ul.plain { padding-left: 1.2rem; margin: 0; }
li { margin: 0.25rem 0; }
.dim { color: #6a7682; }
</style>
</head>
<body>
<h1><code>/feat-website-design/</code></h1>
<p class="meta">last-built: 2026-09-30T02:30:50+02:00 <span class="dim">·</span> <code>feat/website-design</code> @ <code>2e26c80</code></p>
<div class="nav">
<a href="/">/</a>
<a href="/main/">/main/</a>
<a href="/feat-sm-content/">/feat-sm-content/</a>
<a href="/feat-website-features/">/feat-website-features/</a>
<a href="/feat-website-design/">/feat-website-design/</a>
<a href="/feat-website-views/">/feat-website-views/</a>
</div>
</body>
</html>

View file

@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>feat/website-features</title>
<style>
:root { color-scheme: dark; }
* { box-sizing: border-box; }
body {
margin: 0; padding: 1.5rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
font-size: 14px; line-height: 1.45;
background: #0b0d10; color: #c8d0d8;
}
a { color: #7ec8ff; text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 1.15rem; font-weight: 600; margin: 0 0 0.5rem; color: #e8eef4; }
.meta { color: #8a96a3; margin: 0 0 1rem; }
.nav { margin: 0.5rem 0 1rem; }
.nav a { margin-right: 0.85rem; }
ul.plain { padding-left: 1.2rem; margin: 0; }
li { margin: 0.25rem 0; }
.dim { color: #6a7682; }
</style>
</head>
<body>
<h1><code>/feat-website-features/</code></h1>
<p class="meta">last-built: 2026-09-30T02:30:50+02:00 <span class="dim">·</span> <code>feat/website-features</code> @ <code>53a3176</code></p>
<div class="nav">
<a href="/">/</a>
<a href="/main/">/main/</a>
<a href="/feat-sm-content/">/feat-sm-content/</a>
<a href="/feat-website-features/">/feat-website-features/</a>
<a href="/feat-website-design/">/feat-website-design/</a>
<a href="/feat-website-views/">/feat-website-views/</a>
</div>
</body>
</html>

View file

@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>feat/website-views</title>
<style>
:root { color-scheme: dark; }
* { box-sizing: border-box; }
body {
margin: 0; padding: 1.5rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
font-size: 14px; line-height: 1.45;
background: #0b0d10; color: #c8d0d8;
}
a { color: #7ec8ff; text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 1.15rem; font-weight: 600; margin: 0 0 0.5rem; color: #e8eef4; }
.meta { color: #8a96a3; margin: 0 0 1rem; }
.nav { margin: 0.5rem 0 1rem; }
.nav a { margin-right: 0.85rem; }
ul.plain { padding-left: 1.2rem; margin: 0; }
li { margin: 0.25rem 0; }
.dim { color: #6a7682; }
</style>
</head>
<body>
<h1><code>/feat-website-views/</code></h1>
<p class="meta">last-built: 2026-09-30T02:30:50+02:00 <span class="dim">·</span> <code>feat/website-views</code> @ <code>bbafc38</code></p>
<div class="nav">
<a href="/">/</a>
<a href="/main/">/main/</a>
<a href="/feat-sm-content/">/feat-sm-content/</a>
<a href="/feat-website-features/">/feat-website-features/</a>
<a href="/feat-website-design/">/feat-website-design/</a>
<a href="/feat-website-views/">/feat-website-views/</a>
</div>
</body>
</html>

View file

@ -1,47 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>cascade landing</title>
<style>
:root { color-scheme: dark; }
* { box-sizing: border-box; }
body {
margin: 0; padding: 1.5rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
font-size: 14px; line-height: 1.45;
background: #0b0d10; color: #c8d0d8;
}
a { color: #7ec8ff; text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 1.15rem; font-weight: 600; margin: 0 0 0.5rem; color: #e8eef4; }
.meta { color: #8a96a3; margin: 0 0 1rem; }
.nav { margin: 0.5rem 0 1rem; }
.nav a { margin-right: 0.85rem; }
ul.plain { padding-left: 1.2rem; margin: 0; }
li { margin: 0.25rem 0; }
.dim { color: #6a7682; }
</style>
</head>
<body>
<h1>cascade</h1>
<p class="meta">last-built: 2026-09-30T02:30:50+02:00</p>
<div class="nav">
<a href="/">/</a>
<a href="/main/">/main/</a>
<a href="/feat-sm-content/">/feat-sm-content/</a>
<a href="/feat-website-features/">/feat-website-features/</a>
<a href="/feat-website-design/">/feat-website-design/</a>
<a href="/feat-website-views/">/feat-website-views/</a>
</div>
<ul class="plain">
<li><a href="/main/"><code>/main/</code></a> <span class="dim">·</span> <code>main</code> @ <code>d2fbd79</code></li>
<li><a href="/feat-sm-content/"><code>/feat-sm-content/</code></a> <span class="dim">·</span> <code>feat/sm-content</code> @ <code>089ef1f</code></li>
<li><a href="/feat-website-features/"><code>/feat-website-features/</code></a> <span class="dim">·</span> <code>feat/website-features</code> @ <code>53a3176</code></li>
<li><a href="/feat-website-design/"><code>/feat-website-design/</code></a> <span class="dim">·</span> <code>feat/website-design</code> @ <code>2e26c80</code></li>
<li><a href="/feat-website-views/"><code>/feat-website-views/</code></a> <span class="dim">·</span> <code>feat/website-views</code> @ <code>bbafc38</code></li>
</ul>
</body>
</html>

View file

@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>main</title>
<style>
:root { color-scheme: dark; }
* { box-sizing: border-box; }
body {
margin: 0; padding: 1.5rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
font-size: 14px; line-height: 1.45;
background: #0b0d10; color: #c8d0d8;
}
a { color: #7ec8ff; text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 1.15rem; font-weight: 600; margin: 0 0 0.5rem; color: #e8eef4; }
.meta { color: #8a96a3; margin: 0 0 1rem; }
.nav { margin: 0.5rem 0 1rem; }
.nav a { margin-right: 0.85rem; }
ul.plain { padding-left: 1.2rem; margin: 0; }
li { margin: 0.25rem 0; }
.dim { color: #6a7682; }
</style>
</head>
<body>
<h1><code>/main/</code></h1>
<p class="meta">last-built: 2026-09-30T02:30:50+02:00 <span class="dim">·</span> <code>main</code> @ <code>d2fbd79</code></p>
<div class="nav">
<a href="/">/</a>
<a href="/main/">/main/</a>
<a href="/feat-sm-content/">/feat-sm-content/</a>
<a href="/feat-website-features/">/feat-website-features/</a>
<a href="/feat-website-design/">/feat-website-design/</a>
<a href="/feat-website-views/">/feat-website-views/</a>
</div>
</body>
</html>