chore(ops-agent): compose project-name collisie-check voor max2 #55

Merged
janpeter merged 1 commit from chore/compose-collision-check into master 2026-07-10 00:19:11 +02:00
Owner

Spiegelt Ops-dashboard 59c2789 naar scrum4me-docker, met de runtime-conventie van max2: het script leeft in de clone naast scripts/check-ops-agent-drift.sh. Dat mag hier, want de rollout-flow doet git reset --hard origin/master (niet git pull --ff-only zoals 154), dus een vuile tree aborteert niets.

Twee correcties t.o.v. de 154-versie

1. Destructief = één projectnaam over meerdere directories, niet over meerdere bestanden.

Meerdere files in één map zijn de normale compose-layout: docker-compose.yml + docker-compose.override.yml worden auto-gemerged, extra -f-files worden bewust gestapeld. De bestandstelling markeerde /srv/scrum4me/compose (3 files) en /srv/immich (2 files) als destructief — allebei kerngezond.

Dat is niet cosmetisch. Het origineel houdt check (b) bewust warning-only met de redenering "an alarm that always fires is an alarm nobody reads". Met de bestandstelling gold precies dat voor check (a), die wél alarmeert.

2. _attic/ uitgesloten van de scan.

Dat is de aangewezen quarantaine voor .broken-kopieën. Op max2 leeft die op /srv/_attic/<datum>/, dus binnen de /srv scan-root. Zonder uitsluiting houden juist de bestanden die de quarantaine van het deploy-oppervlak haalde het rapport voorgoed rood. Een file onder _attic/ staat per constructie niet op een deploy-oppervlak; moet hij ooit weer draaien, dan wordt hij eerst teruggezet (zie _attic/<datum>/MANIFEST.txt).

Beide correcties zijn het waard om terug te vouwen in de 154-kopie.

Verificatie

Drie synthetische gevallen, allemaal zoals verwacht:

Geval Verwacht Uitkomst
Twee mappen, beide project compose FIRE 1 destructive, exit 1
Eén map, drie files (yml + override + extra) schoon clean, exit 0
_attic-kopie naast een live stack schoon clean, exit 0

Op max2, na quarantaine van de vier .broken-kopieën: 5 destructieve collisies → 2.

Resterend, allebei bekend en niet door deze PR op te lossen:

  • project compose — de ops-dashboard-clone op max2 staat op a1bab5d en mist 59c2789, dus deploy/compose/docker-compose.yml heeft daar nog geen name:. Verdwijnt zodra update_ops_dashboard draait.
  • project deploymotherless-scrapper/repo/deploy/docker-compose.override.yml en ops-dashboard/deploy/docker-compose.ops-dashboard.yml hebben geen name: en liggen allebei in een map die deploy heet. Vergt een name: upstream in die twee repo's.

Timer

00:35 + 10 min randomisatie → vuurt 00:35–00:45. Ruim van ops-agent-drift.timer (00:00–00:15), worker-logs-ingest.timer (00:15) en worker-logs-prune.timer (01:06).

De units zijn in deze PR niet op de host geïnstalleerd; dat vraagt een aparte, expliciete go van JP (root-systemd-timer = geplande code-uitvoering).

🤖 Generated with Claude Code

Spiegelt Ops-dashboard `59c2789` naar `scrum4me-docker`, met de runtime-conventie van max2: het script leeft in de clone naast `scripts/check-ops-agent-drift.sh`. Dat mag hier, want de rollout-flow doet `git reset --hard origin/master` (niet `git pull --ff-only` zoals 154), dus een vuile tree aborteert niets. ## Twee correcties t.o.v. de 154-versie **1. Destructief = één projectnaam over meerdere *directories*, niet over meerdere bestanden.** Meerdere files in één map zijn de normale compose-layout: `docker-compose.yml` + `docker-compose.override.yml` worden auto-gemerged, extra `-f`-files worden bewust gestapeld. De bestandstelling markeerde `/srv/scrum4me/compose` (3 files) en `/srv/immich` (2 files) als destructief — allebei kerngezond. Dat is niet cosmetisch. Het origineel houdt check (b) bewust warning-only met de redenering *"an alarm that always fires is an alarm nobody reads"*. Met de bestandstelling gold precies dat voor check (a), die wél alarmeert. **2. `_attic/` uitgesloten van de scan.** Dat is de aangewezen quarantaine voor `.broken`-kopieën. Op max2 leeft die op `/srv/_attic/<datum>/`, dus **binnen** de `/srv` scan-root. Zonder uitsluiting houden juist de bestanden die de quarantaine van het deploy-oppervlak haalde het rapport voorgoed rood. Een file onder `_attic/` staat per constructie niet op een deploy-oppervlak; moet hij ooit weer draaien, dan wordt hij eerst teruggezet (zie `_attic/<datum>/MANIFEST.txt`). Beide correcties zijn het waard om terug te vouwen in de 154-kopie. ## Verificatie Drie synthetische gevallen, allemaal zoals verwacht: | Geval | Verwacht | Uitkomst | |---|---|---| | Twee mappen, beide project `compose` | FIRE | `1 destructive`, exit 1 | | Eén map, drie files (`yml` + `override` + `extra`) | schoon | `clean`, exit 0 | | `_attic`-kopie naast een live stack | schoon | `clean`, exit 0 | Op max2, na quarantaine van de vier `.broken`-kopieën: **5 destructieve collisies → 2**. Resterend, allebei bekend en niet door deze PR op te lossen: - project `compose` — de ops-dashboard-clone op max2 staat op `a1bab5d` en mist `59c2789`, dus `deploy/compose/docker-compose.yml` heeft daar nog geen `name:`. Verdwijnt zodra `update_ops_dashboard` draait. - project `deploy` — `motherless-scrapper/repo/deploy/docker-compose.override.yml` en `ops-dashboard/deploy/docker-compose.ops-dashboard.yml` hebben geen `name:` en liggen allebei in een map die `deploy` heet. Vergt een `name:` upstream in die twee repo's. ## Timer `00:35` + 10 min randomisatie → vuurt 00:35–00:45. Ruim van `ops-agent-drift.timer` (00:00–00:15), `worker-logs-ingest.timer` (00:15) en `worker-logs-prune.timer` (01:06). De units zijn in deze PR **niet** op de host geïnstalleerd; dat vraagt een aparte, expliciete go van JP (root-systemd-timer = geplande code-uitvoering). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chore(ops-agent): compose project-name collisie-check voor max2
All checks were successful
CI / Compose config (pull_request) Successful in 3s
CI / Docker build (pull_request) Successful in 5s
570b95acb9
Spiegelt Ops-dashboard 59c2789 (check-compose-collision.sh + systemd-units) naar
scrum4me-docker, met de runtime-conventie van max2: het script leeft in de clone
naast scripts/check-ops-agent-drift.sh. Dat kan hier omdat de rollout-flow
`git reset --hard origin/master` doet (niet `git pull --ff-only` zoals 154), dus
een vuile tree aborteert niets.

Twee correcties t.o.v. de 154-versie, allebei gedocumenteerd in de header:

1. Een projectnaam-collisie telt nu distinct DIRECTORIES, niet bestanden.
   Meerdere files in één map zijn de normale compose-layout: docker-compose.yml
   + docker-compose.override.yml worden auto-gemerged, extra -f files worden
   bewust gestapeld. De file-telling markeerde /srv/scrum4me/compose (3 files) en
   /srv/immich (2) als destructief. Een check die rood staat op een gezonde host
   wordt genegeerd — precies de reden waarom (b) in het origineel warning-only is.

2. `_attic/` wordt uitgesloten van de scan. Dat is de aangewezen quarantaine voor
   `.broken`-kopieën. Op max2 leeft die op /srv/_attic/<datum>/, dus binnen de
   /srv scan-root; zonder uitsluiting houden juist de bestanden die de
   quarantaine van het deploy-oppervlak haalde het rapport voorgoed rood.

Beide correcties zijn het waard om terug te vouwen in de 154-kopie.

Effect op max2 na quarantaine van de vier .broken-kopieën: 5 destructieve
collisies -> 2. Resterend: project `compose` (de ops-dashboard-clone mist 59c2789)
en project `deploy` (twee files zonder `name:` in mappen die `deploy` heten).

Timer op 00:35 +10min randomisatie, ruim van ops-agent-drift (00:00-00:15),
worker-logs-ingest (00:15) en worker-logs-prune (01:06).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
janpeter merged commit eb6c1cf8ed into master 2026-07-10 00:19:11 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
janpeter/scrum4me-docker!55
No description provided.