From 0b009b2717b66f2547a1615f3fe4272802111487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Tue, 29 Sep 2026 04:33:46 +0200 Subject: [PATCH 1/8] docs: daylog tech-dossier Freeze cascade --- 2026/2026-09-28--tech-dossier-freeze-cascade.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/2026/2026-09-28--tech-dossier-freeze-cascade.md b/2026/2026-09-28--tech-dossier-freeze-cascade.md index c812f99..ff1a627 100644 --- a/2026/2026-09-28--tech-dossier-freeze-cascade.md +++ b/2026/2026-09-28--tech-dossier-freeze-cascade.md @@ -8,8 +8,8 @@ Ladder (each tip autonomously `make html`; each depends on the previous): | 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) | | 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/ | **`dossiers.ngi.hacktivism.ch`** (primary Deploy) | -| 5 | `feat/website-views` | `42917e7` | http://127.0.0.1:8105/ | Deploy-Views (no 4th ht host yet) | +| 4 | `feat/website-design` | `2e26c80` | http://127.0.0.1:8104/ | — (no public host after views deploy) | +| 5 | `feat/website-views` | `fcab26c` | http://127.0.0.1:8105/ | **`dossiers.ngi.hacktivism.ch`** (primary Deploy) | Caddy roots (SoT `scripts/caddy/Caddyfile.koopa-live-wdGet`): @@ -29,14 +29,16 @@ basic_auth: `scripts/caddy/apply-dossiers-ngi-basicauth.sh` ## Live -- [dossiers.ngi](https://dossiers.ngi.hacktivism.ch/) ← website-design freeze +- [dossiers.ngi](https://dossiers.ngi.hacktivism.ch/) ← website-views freeze (`fcab26c`, Semigrafik + Stundendienst-Status) - [dossiers.2.ngi](https://dossiers.2.ngi.hacktivism.ch/) ← website-features (optional) - [dossiers.3.ngi](https://dossiers.3.ngi.hacktivism.ch/) ← sm-content (optional) -## Deploy (Freigabe 2026-09-28) +## Deploy (Freigabe 2026-09-28 design; Freigabe 2026-09-29 views via fertigstellen/deploy) -Primary: rsync `website/build/` from tip `feat/website-design` @ `2e26c80` → +Primary: rsync `website/build/` from tip `feat/website-views` @ `fcab26c` → `hernani@koopa:/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch/` (`--delete`, exclude `.DS_Store`). -**Result:** `RSYNC_OK` 2026-09-28 ~22:25+02 — ~2698 files / ~27M; live `dossier/sm/index.html` 41693 bytes. +**Result 2026-09-28 ~22:25+02 (design @ `2e26c80`):** `RSYNC_OK` — ~2698 files / ~27M; live `dossier/sm/index.html` 41693 bytes. + +**Result 2026-09-29 ~04:30+02 (views @ `fcab26c`):** `RSYNC_OK` — live `/` HTTP 200, `index.html` 1729B byte-match local build; Semigrafik ✓ main / ✓ sm-content→dossiers.3 / ✓ features→dossiers.2 / ✓ design / ✓ views→dossiers.ngi; `dossier/sm` 200 size 41693; `/static/css/style.css` 200 size 5746. Push offen (eigene Freigabe). From 9fa5ce19b61bdf8b6e54ad53ec447e2bbc028bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Tue, 29 Sep 2026 16:10:56 +0200 Subject: [PATCH 2/8] sites/dossiers.ngi: blank cascade landing with path-root stubs --- .../systemd/user/taler-landing-stats.timer | 6 +- scripts/taler-landing/README.md | 2 +- .../feat-sm-content/index.html | 63 +++++++++++++++++ .../feat-website-design/index.html | 63 +++++++++++++++++ .../feat-website-features/index.html | 63 +++++++++++++++++ .../feat-website-views/index.html | 68 ++++++++++++++++++ sites/dossiers.ngi.hacktivism.ch/index.html | 69 +++++++++++++++++++ .../main/index.html | 63 +++++++++++++++++ 8 files changed, 393 insertions(+), 4 deletions(-) create mode 100644 sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html create mode 100644 sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html create mode 100644 sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html create mode 100644 sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html create mode 100644 sites/dossiers.ngi.hacktivism.ch/index.html create mode 100644 sites/dossiers.ngi.hacktivism.ch/main/index.html diff --git a/configs/systemd/user/taler-landing-stats.timer b/configs/systemd/user/taler-landing-stats.timer index 7106c8a..2fc1d21 100644 --- a/configs/systemd/user/taler-landing-stats.timer +++ b/configs/systemd/user/taler-landing-stats.timer @@ -1,11 +1,11 @@ [Unit] -Description=Timer · Taler landing stats (every 2 min) +Description=Timer · Taler landing stats (every 4h) Documentation=file:%h/src/koopa/koopa-admin-log/scripts/taler-landing/README.md [Timer] OnBootSec=90s -OnUnitActiveSec=2min -AccuracySec=20s +OnUnitActiveSec=4h +AccuracySec=5min Persistent=true Unit=taler-landing-stats.service diff --git a/scripts/taler-landing/README.md b/scripts/taler-landing/README.md index fe74eae..9c487d0 100644 --- a/scripts/taler-landing/README.md +++ b/scripts/taler-landing/README.md @@ -50,7 +50,7 @@ systemctl --user list-timers 'taler-landing-stats*' Units: - `configs/systemd/user/taler-landing-stats.service` — oneshot collector -- `configs/systemd/user/taler-landing-stats.timer` — every **2 minutes** after boot +- `configs/systemd/user/taler-landing-stats.timer` — every **4h** after boot Installed paths: diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html new file mode 100644 index 0000000..b4b6e0e --- /dev/null +++ b/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html @@ -0,0 +1,63 @@ + + + + + +feat/sm-content · cascade + + + + +

Fassung: feat/sm-content

+

path /feat-sm-content/ · tip 089ef1f · depends on main

+ +

ladder position

+
cascade ladder (path roots on dossiers.ngi only) + + main + | +* feat/sm-content <-- this Fassung + | + feat/website-features + | + feat/website-design + | + feat/website-views
+

what this looks like

+

SM dossier prose content on top of main.

+

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

+ + + diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html new file mode 100644 index 0000000..376ae36 --- /dev/null +++ b/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html @@ -0,0 +1,63 @@ + + + + + +feat/website-design · cascade + + + + +

Fassung: feat/website-design

+

path /feat-website-design/ · tip 2e26c80 · depends on feat/website-features

+ +

ladder position

+
cascade ladder (path roots on dossiers.ngi only) + + main + | + feat/sm-content + | + feat/website-features + | +* feat/website-design <-- this Fassung + | + feat/website-views
+

what this looks like

+

Design/CSS layer on top of features.

+

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

+ + + diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html new file mode 100644 index 0000000..33c8f86 --- /dev/null +++ b/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html @@ -0,0 +1,63 @@ + + + + + +feat/website-features · cascade + + + + +

Fassung: feat/website-features

+

path /feat-website-features/ · tip 53a3176 · depends on feat/sm-content

+ +

ladder position

+
cascade ladder (path roots on dossiers.ngi only) + + main + | + feat/sm-content + | +* feat/website-features <-- this Fassung + | + feat/website-design + | + feat/website-views
+

what this looks like

+

Website feature routes on top of sm-content.

+

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

+ + + diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html new file mode 100644 index 0000000..d3fdd48 --- /dev/null +++ b/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html @@ -0,0 +1,68 @@ + + + + + +feat/website-views · cascade + + + + +

Fassung: feat/website-views

+

path /feat-website-views/ · tip fcab26c · depends on feat/website-design

+ +

ladder position

+
cascade ladder (path roots on dossiers.ngi only) + + main + | + feat/sm-content + | + feat/website-features + | + feat/website-design + | +* feat/website-views <-- this Fassung
+

what this looks like

+

Views/list layer on top of design (local tip; origin bbafc38).

+

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

+ +

views gap vs dossiers.ngi-0.eu: +Frozen Flask on this tip exposes project_list / project_detail / dossier_list / blank. +It does not yet mirror the Next.js category-style views on dossiers.ngi-0.eu. +This path documents that gap; category-parity views remain open work.

+ + + diff --git a/sites/dossiers.ngi.hacktivism.ch/index.html b/sites/dossiers.ngi.hacktivism.ch/index.html new file mode 100644 index 0000000..165a84d --- /dev/null +++ b/sites/dossiers.ngi.hacktivism.ch/index.html @@ -0,0 +1,69 @@ + + + + + +cascade landing + + + + +

tech-dossier cascade landing

+

host: dossiers.ngi.hacktivism.ch · blank relational index · owned by koopa-admin-log

+ +

relation to main

+
cascade ladder (path roots on dossiers.ngi only) + + main + | + feat/sm-content + | + feat/website-features + | + feat/website-design + | + feat/website-views
+

Fassungen

+ +

Each path is its own root for that branch Fassung. No dossiers.2 / dossiers.3 subdomains.

+ + + diff --git a/sites/dossiers.ngi.hacktivism.ch/main/index.html b/sites/dossiers.ngi.hacktivism.ch/main/index.html new file mode 100644 index 0000000..be1875d --- /dev/null +++ b/sites/dossiers.ngi.hacktivism.ch/main/index.html @@ -0,0 +1,63 @@ + + + + + +main · cascade + + + + +

Fassung: main

+

path /main/ · tip d2fbd79 · depends on none (base)

+ +

ladder position

+
cascade ladder (path roots on dossiers.ngi only) + +* main <-- this Fassung + | + feat/sm-content + | + feat/website-features + | + feat/website-design + | + feat/website-views
+

what this looks like

+

Base freeze tip.

+

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

+ + + From c38d3c900add2a7fd1585a550a994b3fbdcc7f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Tue, 29 Sep 2026 22:15:04 +0200 Subject: [PATCH 3/8] docs: daylog tech-dossier Freeze cascade --- 2026/2026-09-28--tech-dossier-freeze-cascade.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/2026/2026-09-28--tech-dossier-freeze-cascade.md b/2026/2026-09-28--tech-dossier-freeze-cascade.md index ff1a627..776a34e 100644 --- a/2026/2026-09-28--tech-dossier-freeze-cascade.md +++ b/2026/2026-09-28--tech-dossier-freeze-cascade.md @@ -9,7 +9,7 @@ Ladder (each tip autonomously `make html`; each depends on the previous): | 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) | | 4 | `feat/website-design` | `2e26c80` | http://127.0.0.1:8104/ | — (no public host after views deploy) | -| 5 | `feat/website-views` | `fcab26c` | http://127.0.0.1:8105/ | **`dossiers.ngi.hacktivism.ch`** (primary Deploy) | +| 5 | `feat/website-views` | `7aca0e8` (Semigrafik `1b2fcf7`; unpushed, ahead origin `bbafc38` by 2) | http://127.0.0.1:8105/ | path roots under blank landing (see Live) | Caddy roots (SoT `scripts/caddy/Caddyfile.koopa-live-wdGet`): @@ -29,16 +29,20 @@ basic_auth: `scripts/caddy/apply-dossiers-ngi-basicauth.sh` ## Live -- [dossiers.ngi](https://dossiers.ngi.hacktivism.ch/) ← website-views freeze (`fcab26c`, Semigrafik + Stundendienst-Status) +- [dossiers.ngi](https://dossiers.ngi.hacktivism.ch/) ← **blank cascade landing** (kal tip `56ee97a`, sites/dossiers.ngi path roots; HTTP 200 SIZE≈3505) +- Path Unterseiten: `/main/`, `/feat-sm-content/`, `/feat-website-features/`, `/feat-website-design/`, `/feat-website-views/` +- Local freeze Semigrafik + hourly branch-status: tdpd `feat/website-views` @ `7aca0e8` ← `1b2fcf7` (unpushed) - [dossiers.2.ngi](https://dossiers.2.ngi.hacktivism.ch/) ← website-features (optional) - [dossiers.3.ngi](https://dossiers.3.ngi.hacktivism.ch/) ← sm-content (optional) -## Deploy (Freigabe 2026-09-28 design; Freigabe 2026-09-29 views via fertigstellen/deploy) +## Deploy (Freigabe 2026-09-28 design; Freigabe 2026-09-29 views; Freigabe blank landing same day) -Primary: rsync `website/build/` from tip `feat/website-views` @ `fcab26c` → +Earlier primary: rsync `website/build/` from tip `feat/website-views` → `hernani@koopa:/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch/` (`--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 2026-09-29 ~04:30+02 (views @ `fcab26c`):** `RSYNC_OK` — live `/` HTTP 200, `index.html` 1729B byte-match local build; Semigrafik ✓ main / ✓ sm-content→dossiers.3 / ✓ features→dossiers.2 / ✓ design / ✓ views→dossiers.ngi; `dossier/sm` 200 size 41693; `/static/css/style.css` 200 size 5746. Push offen (eigene Freigabe). +**Result 2026-09-29 ~04:30+02 (views Semigrafik era):** `RSYNC_OK` — live `/` HTTP 200; Semigrafik ladder on dossiers.ngi; later remade as tdpd tips `1b2fcf7` → `7aca0e8` (hourly builder). Push offen (eigene Freigabe). + +**Result 2026-09-29 (blank landing kal @ `56ee97a`):** `RSYNC_OK` — live `/` HTTP 200 SIZE=3505 title `cascade landing`; path-root Unterseiten owned by koopa-admin-log `sites/dossiers.ngi.hacktivism.ch/`; NO_PUSH. From 83998499da2761c05f6f7d6aed2426ef3f3f6f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Tue, 29 Sep 2026 22:41:37 +0200 Subject: [PATCH 4/8] sites/dossiers.ngi: EN ASCII cascade landing with tip cites --- .../feat-sm-content/index.html | 21 ++++++++-------- .../feat-website-design/index.html | 21 ++++++++-------- .../feat-website-features/index.html | 21 ++++++++-------- .../feat-website-views/index.html | 24 +++++++++---------- sites/dossiers.ngi.hacktivism.ch/index.html | 24 +++++++++---------- .../main/index.html | 21 ++++++++-------- 6 files changed, 68 insertions(+), 64 deletions(-) diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html index b4b6e0e..a3100e1 100644 --- a/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html @@ -33,7 +33,7 @@ li { margin: 0.25rem 0; } -

Fassung: feat/sm-content

+

edition: feat/sm-content

path /feat-sm-content/ · tip 089ef1f · depends on main

what this looks like

SM dossier prose content on top of main.

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

+ diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html index 376ae36..12c451c 100644 --- a/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html @@ -33,7 +33,7 @@ li { margin: 0.25rem 0; } -

Fassung: feat/website-design

+

edition: feat/website-design

path /feat-website-design/ · tip 2e26c80 · depends on feat/website-features

what this looks like

Design/CSS layer on top of features.

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

+ diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html index 33c8f86..257847a 100644 --- a/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html @@ -33,7 +33,7 @@ li { margin: 0.25rem 0; } -

Fassung: feat/website-features

+

edition: feat/website-features

path /feat-website-features/ · tip 53a3176 · depends on feat/sm-content

what this looks like

Website feature routes on top of sm-content.

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

+ diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html index d3fdd48..1b622fd 100644 --- a/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html @@ -33,8 +33,8 @@ li { margin: 0.25rem 0; } -

Fassung: feat/website-views

-

path /feat-website-views/ · tip fcab26c · depends on feat/website-design

+

edition: feat/website-views

+

path /feat-website-views/ · tip bbafc38 · depends on feat/website-design

what this looks like

-

Views/list layer on top of design (local tip; origin bbafc38).

+

Views/list layer on top of design (origin tip).

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

views gap vs dossiers.ngi-0.eu: diff --git a/sites/dossiers.ngi.hacktivism.ch/index.html b/sites/dossiers.ngi.hacktivism.ch/index.html index 165a84d..a7b111e 100644 --- a/sites/dossiers.ngi.hacktivism.ch/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/index.html @@ -46,24 +46,24 @@ li { margin: 0.25rem 0; }

relation to main

cascade ladder (path roots on dossiers.ngi only) - main - | - feat/sm-content - | - feat/website-features - | - feat/website-design - | - feat/website-views
-

Fassungen

+ main @ d2fbd79 + | + +-- feat/sm-content @ 089ef1f + | + +-- feat/website-features @ 53a3176 + | + +-- feat/website-design @ 2e26c80 + | + +-- feat/website-views @ bbafc38 +

editions

  • /main/ — main @ d2fbd79 · base
    Base freeze tip.
  • /feat-sm-content/ — feat/sm-content @ 089ef1f · depends on main
    SM dossier prose content on top of main.
  • /feat-website-features/ — feat/website-features @ 53a3176 · depends on feat/sm-content
    Website feature routes on top of sm-content.
  • /feat-website-design/ — feat/website-design @ 2e26c80 · depends on feat/website-features
    Design/CSS layer on top of features.
  • -
  • /feat-website-views/ — feat/website-views @ fcab26c · depends on feat/website-design
    Views/list layer on top of design (local tip; origin bbafc38).
  • +
  • /feat-website-views/ — feat/website-views @ bbafc38 · depends on feat/website-design
    Views/list layer on top of design (origin tip).
-

Each path is its own root for that branch Fassung. No dossiers.2 / dossiers.3 subdomains.

+

Each path is its own root for that branch edition. Single public host dossiers.ngi only.

diff --git a/sites/dossiers.ngi.hacktivism.ch/main/index.html b/sites/dossiers.ngi.hacktivism.ch/main/index.html index be1875d..9f9490c 100644 --- a/sites/dossiers.ngi.hacktivism.ch/main/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/main/index.html @@ -33,7 +33,7 @@ li { margin: 0.25rem 0; } -

Fassung: main

+

edition: main

path /main/ · tip d2fbd79 · depends on none (base)

what this looks like

Base freeze tip.

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

+ From 2b9f6c6b8305c11a756cbefa456237d7fed8a23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Tue, 29 Sep 2026 23:27:19 +0200 Subject: [PATCH 5/8] ops: dossiers-ngi hourly branch-status builder + systemd timer --- .../user/dossiers-ngi-branch-status.service | 19 +++++ .../user/dossiers-ngi-branch-status.timer | 13 +++ scripts/dossiers-ngi/README.md | 42 ++++++++++ scripts/dossiers-ngi/branch-status-hourly.py | 84 +++++++++++++++++++ .../branch-status.json | 37 ++++++++ 5 files changed, 195 insertions(+) create mode 100644 configs/systemd/user/dossiers-ngi-branch-status.service create mode 100644 configs/systemd/user/dossiers-ngi-branch-status.timer create mode 100644 scripts/dossiers-ngi/README.md create mode 100755 scripts/dossiers-ngi/branch-status-hourly.py create mode 100644 sites/dossiers.ngi.hacktivism.ch/branch-status.json diff --git a/configs/systemd/user/dossiers-ngi-branch-status.service b/configs/systemd/user/dossiers-ngi-branch-status.service new file mode 100644 index 0000000..a6ad491 --- /dev/null +++ b/configs/systemd/user/dossiers-ngi-branch-status.service @@ -0,0 +1,19 @@ +[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 diff --git a/configs/systemd/user/dossiers-ngi-branch-status.timer b/configs/systemd/user/dossiers-ngi-branch-status.timer new file mode 100644 index 0000000..e6c701b --- /dev/null +++ b/configs/systemd/user/dossiers-ngi-branch-status.timer @@ -0,0 +1,13 @@ +[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 diff --git a/scripts/dossiers-ngi/README.md b/scripts/dossiers-ngi/README.md new file mode 100644 index 0000000..11da294 --- /dev/null +++ b/scripts/dossiers-ngi/README.md @@ -0,0 +1,42 @@ +# 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. diff --git a/scripts/dossiers-ngi/branch-status-hourly.py b/scripts/dossiers-ngi/branch-status-hourly.py new file mode 100755 index 0000000..feae12a --- /dev/null +++ b/scripts/dossiers-ngi/branch-status-hourly.py @@ -0,0 +1,84 @@ +#!/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, + "tdpd_root": str(repo), + "branches": 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()) diff --git a/sites/dossiers.ngi.hacktivism.ch/branch-status.json b/sites/dossiers.ngi.hacktivism.ch/branch-status.json new file mode 100644 index 0000000..74c3df4 --- /dev/null +++ b/sites/dossiers.ngi.hacktivism.ch/branch-status.json @@ -0,0 +1,37 @@ +{ + "generated": "2026-09-30T02:30:50+02:00", + "host": "https://dossiers.ngi.hacktivism.ch", + "tdpd_root": "/Users/newkamek/git/src/ngi/tech-dossier-project-data", + "branches": [ + { + "branch": "main", + "tip": "d2fbd79", + "parent": "", + "url": "https://dossiers.ngi.hacktivism.ch/main/" + }, + { + "branch": "feat/sm-content", + "tip": "089ef1f", + "parent": "main", + "url": "https://dossiers.ngi.hacktivism.ch/feat-sm-content/" + }, + { + "branch": "feat/website-features", + "tip": "53a3176", + "parent": "feat/sm-content", + "url": "https://dossiers.ngi.hacktivism.ch/feat-website-features/" + }, + { + "branch": "feat/website-design", + "tip": "2e26c80", + "parent": "feat/website-features", + "url": "https://dossiers.ngi.hacktivism.ch/feat-website-design/" + }, + { + "branch": "feat/website-views", + "tip": "bbafc38", + "parent": "feat/website-design", + "url": "https://dossiers.ngi.hacktivism.ch/feat-website-views/" + } + ] +} From ef0ff7f60d47f80004d7a1d18d694085ddba5ba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Wed, 30 Sep 2026 01:08:52 +0200 Subject: [PATCH 6/8] docs: daylog tech-dossier Freeze cascade tip correction --- 2026/2026-09-28--tech-dossier-freeze-cascade.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/2026/2026-09-28--tech-dossier-freeze-cascade.md b/2026/2026-09-28--tech-dossier-freeze-cascade.md index 776a34e..b24c6cd 100644 --- a/2026/2026-09-28--tech-dossier-freeze-cascade.md +++ b/2026/2026-09-28--tech-dossier-freeze-cascade.md @@ -9,7 +9,7 @@ Ladder (each tip autonomously `make html`; each depends on the previous): | 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) | | 4 | `feat/website-design` | `2e26c80` | http://127.0.0.1:8104/ | — (no public host after views deploy) | -| 5 | `feat/website-views` | `7aca0e8` (Semigrafik `1b2fcf7`; unpushed, ahead origin `bbafc38` by 2) | http://127.0.0.1:8105/ | path roots under blank landing (see Live) | +| 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) | Caddy roots (SoT `scripts/caddy/Caddyfile.koopa-live-wdGet`): @@ -29,9 +29,10 @@ basic_auth: `scripts/caddy/apply-dossiers-ngi-basicauth.sh` ## Live -- [dossiers.ngi](https://dossiers.ngi.hacktivism.ch/) ← **blank cascade landing** (kal tip `56ee97a`, sites/dossiers.ngi path roots; HTTP 200 SIZE≈3505) -- Path Unterseiten: `/main/`, `/feat-sm-content/`, `/feat-website-features/`, `/feat-website-design/`, `/feat-website-views/` -- Local freeze Semigrafik + hourly branch-status: tdpd `feat/website-views` @ `7aca0e8` ← `1b2fcf7` (unpushed) +- [dossiers.ngi](https://dossiers.ngi.hacktivism.ch/) ← **blank cascade landing** (kal `sites/dossiers.ngi.hacktivism.ch/`; EN + ASCII ladder; views tip cite `bbafc38`) +- 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.3.ngi](https://dossiers.3.ngi.hacktivism.ch/) ← sm-content (optional) @@ -43,6 +44,8 @@ Earlier primary: rsync `website/build/` from tip `feat/website-views` → **Result 2026-09-28 ~22:25+02 (design @ `2e26c80`):** `RSYNC_OK` — ~2698 files / ~27M; live `dossier/sm/index.html` 41693 bytes. -**Result 2026-09-29 ~04:30+02 (views Semigrafik era):** `RSYNC_OK` — live `/` HTTP 200; Semigrafik ladder on dossiers.ngi; later remade as tdpd tips `1b2fcf7` → `7aca0e8` (hourly builder). Push offen (eigene Freigabe). +**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 Unterseiten owned by koopa-admin-log `sites/dossiers.ngi.hacktivism.ch/`; NO_PUSH. +**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. From c406352e1adae82faf4007322647d8637120b24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Wed, 30 Sep 2026 03:41:39 +0200 Subject: [PATCH 7/8] sites/dossiers.ngi: strip meta keep links and last-built --- .../branch-status.json | 6 --- .../feat-sm-content/index.html | 42 ++++------------- .../feat-website-design/index.html | 42 ++++------------- .../feat-website-features/index.html | 42 ++++------------- .../feat-website-views/index.html | 46 ++++--------------- sites/dossiers.ngi.hacktivism.ch/index.html | 46 +++++-------------- .../main/index.html | 42 ++++------------- 7 files changed, 57 insertions(+), 209 deletions(-) diff --git a/sites/dossiers.ngi.hacktivism.ch/branch-status.json b/sites/dossiers.ngi.hacktivism.ch/branch-status.json index 74c3df4..1d049ef 100644 --- a/sites/dossiers.ngi.hacktivism.ch/branch-status.json +++ b/sites/dossiers.ngi.hacktivism.ch/branch-status.json @@ -1,36 +1,30 @@ { "generated": "2026-09-30T02:30:50+02:00", "host": "https://dossiers.ngi.hacktivism.ch", - "tdpd_root": "/Users/newkamek/git/src/ngi/tech-dossier-project-data", "branches": [ { "branch": "main", "tip": "d2fbd79", - "parent": "", "url": "https://dossiers.ngi.hacktivism.ch/main/" }, { "branch": "feat/sm-content", "tip": "089ef1f", - "parent": "main", "url": "https://dossiers.ngi.hacktivism.ch/feat-sm-content/" }, { "branch": "feat/website-features", "tip": "53a3176", - "parent": "feat/sm-content", "url": "https://dossiers.ngi.hacktivism.ch/feat-website-features/" }, { "branch": "feat/website-design", "tip": "2e26c80", - "parent": "feat/website-features", "url": "https://dossiers.ngi.hacktivism.ch/feat-website-design/" }, { "branch": "feat/website-views", "tip": "bbafc38", - "parent": "feat/website-design", "url": "https://dossiers.ngi.hacktivism.ch/feat-website-views/" } ] diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html index a3100e1..bd25fd1 100644 --- a/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/feat-sm-content/index.html @@ -3,7 +3,7 @@ -feat/sm-content · cascade +feat/sm-content - -

edition: feat/sm-content

-

path /feat-sm-content/ · tip 089ef1f · depends on main

+

/feat-sm-content/

+

last-built: 2026-09-30T02:30:50+02:00 · feat/sm-content @ 089ef1f

-

ladder position

-
cascade ladder (path roots on dossiers.ngi only) - - main @ d2fbd79 - | -* +-- feat/sm-content @ 089ef1f <-- this edition - | - +-- feat/website-features @ 53a3176 - | - +-- feat/website-design @ 2e26c80 - | - +-- feat/website-views @ bbafc38
-

what this looks like

-

SM dossier prose content on top of main.

-

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

- - diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html index 12c451c..d4a7fae 100644 --- a/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/feat-website-design/index.html @@ -3,7 +3,7 @@ -feat/website-design · cascade +feat/website-design - -

edition: feat/website-design

-

path /feat-website-design/ · tip 2e26c80 · depends on feat/website-features

+

/feat-website-design/

+

last-built: 2026-09-30T02:30:50+02:00 · feat/website-design @ 2e26c80

-

ladder position

-
cascade ladder (path roots on dossiers.ngi only) - - main @ d2fbd79 - | - +-- feat/sm-content @ 089ef1f - | - +-- feat/website-features @ 53a3176 - | -* +-- feat/website-design @ 2e26c80 <-- this edition - | - +-- feat/website-views @ bbafc38
-

what this looks like

-

Design/CSS layer on top of features.

-

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

- - diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html index 257847a..ed90716 100644 --- a/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/feat-website-features/index.html @@ -3,7 +3,7 @@ -feat/website-features · cascade +feat/website-features - -

edition: feat/website-features

-

path /feat-website-features/ · tip 53a3176 · depends on feat/sm-content

+

/feat-website-features/

+

last-built: 2026-09-30T02:30:50+02:00 · feat/website-features @ 53a3176

-

ladder position

-
cascade ladder (path roots on dossiers.ngi only) - - main @ d2fbd79 - | - +-- feat/sm-content @ 089ef1f - | -* +-- feat/website-features @ 53a3176 <-- this edition - | - +-- feat/website-design @ 2e26c80 - | - +-- feat/website-views @ bbafc38
-

what this looks like

-

Website feature routes on top of sm-content.

-

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

- - diff --git a/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html b/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html index 1b622fd..5bc14c7 100644 --- a/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/feat-website-views/index.html @@ -3,7 +3,7 @@ -feat/website-views · cascade +feat/website-views - -

edition: feat/website-views

-

path /feat-website-views/ · tip bbafc38 · depends on feat/website-design

+

/feat-website-views/

+

last-built: 2026-09-30T02:30:50+02:00 · feat/website-views @ bbafc38

-

ladder position

-
cascade ladder (path roots on dossiers.ngi only) - - main @ d2fbd79 - | - +-- feat/sm-content @ 089ef1f - | - +-- feat/website-features @ 53a3176 - | - +-- feat/website-design @ 2e26c80 - | -* +-- feat/website-views @ bbafc38 <-- this edition
-

what this looks like

-

Views/list layer on top of design (origin tip).

-

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

- -

views gap vs dossiers.ngi-0.eu: -Frozen Flask on this tip exposes project_list / project_detail / dossier_list / blank. -It does not yet mirror the Next.js category-style views on dossiers.ngi-0.eu. -This path documents that gap; category-parity views remain open work.

- diff --git a/sites/dossiers.ngi.hacktivism.ch/index.html b/sites/dossiers.ngi.hacktivism.ch/index.html index a7b111e..7126152 100644 --- a/sites/dossiers.ngi.hacktivism.ch/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/index.html @@ -15,26 +15,19 @@ body { } a { color: #7ec8ff; text-decoration: none; } a:hover { text-decoration: underline; } -h1 { font-size: 1.15rem; font-weight: 600; margin: 0 0 0.75rem; color: #e8eef4; } -h2 { font-size: 1rem; font-weight: 600; margin: 1.25rem 0 0.5rem; color: #e8eef4; } -.meta { color: #8a96a3; margin-bottom: 1rem; } -.box { - border: 1px solid #2a3340; background: #12161c; - padding: 0.85rem 1rem; margin: 0.75rem 0; white-space: pre; overflow-x: auto; -} +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; } -.note { color: #b8a46a; margin-top: 1rem; max-width: 72ch; white-space: normal; } -.ok { color: #7dcea0; } -.dim { color: #6a7682; } -ul.plain { padding-left: 1.2rem; } +ul.plain { padding-left: 1.2rem; margin: 0; } li { margin: 0.25rem 0; } +.dim { color: #6a7682; } + - -

tech-dossier cascade landing

-

host: dossiers.ngi.hacktivism.ch · blank relational index · owned by koopa-admin-log

+

cascade

+

last-built: 2026-09-30T02:30:50+02:00

-

relation to main

-
cascade ladder (path roots on dossiers.ngi only) - - main @ d2fbd79 - | - +-- feat/sm-content @ 089ef1f - | - +-- feat/website-features @ 53a3176 - | - +-- feat/website-design @ 2e26c80 - | - +-- feat/website-views @ bbafc38
-

editions

-

Each path is its own root for that branch edition. Single public host dossiers.ngi only.

- diff --git a/sites/dossiers.ngi.hacktivism.ch/main/index.html b/sites/dossiers.ngi.hacktivism.ch/main/index.html index 9f9490c..c4ca691 100644 --- a/sites/dossiers.ngi.hacktivism.ch/main/index.html +++ b/sites/dossiers.ngi.hacktivism.ch/main/index.html @@ -3,7 +3,7 @@ -main · cascade +main - -

edition: main

-

path /main/ · tip d2fbd79 · depends on none (base)

+

/main/

+

last-built: 2026-09-30T02:30:50+02:00 · main @ d2fbd79

-

ladder position

-
cascade ladder (path roots on dossiers.ngi only) - -* main @ d2fbd79 <-- this edition - | - +-- feat/sm-content @ 089ef1f - | - +-- feat/website-features @ 53a3176 - | - +-- feat/website-design @ 2e26c80 - | - +-- feat/website-views @ bbafc38
-

what this looks like

-

Base freeze tip.

-

Blank relational stub. Frozen Flask build for this tip is separate; this page only shows cascade relation and path root.

- - From c1fefcc766388420975fd0f4ea3cf77736df74e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Wed, 30 Sep 2026 03:41:41 +0200 Subject: [PATCH 8/8] ops: dossiers-ngi hourly branch-status emit tip fields only --- scripts/dossiers-ngi/branch-status-hourly.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/dossiers-ngi/branch-status-hourly.py b/scripts/dossiers-ngi/branch-status-hourly.py index feae12a..e121273 100755 --- a/scripts/dossiers-ngi/branch-status-hourly.py +++ b/scripts/dossiers-ngi/branch-status-hourly.py @@ -71,8 +71,10 @@ def main() -> int: payload = { "generated": datetime.now(timezone.utc).astimezone().isoformat(timespec="seconds"), "host": HOST, - "tdpd_root": str(repo), - "branches": branches, + "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")