feat(deploy): timer die redeploy_scrum4us afvuurt als main beweegt #131

Merged
janpeter merged 4 commits from feat/scrum4us-deploy-trigger into main 2026-08-02 13:07:59 +02:00
Owner

Part C Task 7 — het sluitstuk van de deploy-ordering. Sinds Part B de web-deploy ín de flow trok is deze trigger niet meer dragend voor correctheid: vuurt hij nooit, dan is het resultaat "niets gedeployd" — zichtbaar en veilig — in plaats van "UI vóór API". Daarom bewust het kleinste dat werkt.

Bewijs

# check uitkomst
V1 flock PASS — met de lock vast doet een tweede kopie nul POSTs en eindigt op exit 0
V2 exit-code uit de SSE-body PASS — zie hieronder
V3 failure-teller PASS — 3 pogingen, dan opgeven zónder endpoint-aanroep; andere sha reset naar 1/3
V4 eerste tick deployt 9f91631 PASS — drie-weg-match, zie hieronder
V5 no-op tick PASSNOOP: checkout is bij (9f91631e87d9), exit 0, nul POSTs
V6 baseline + drift PASS — deze PR; drift-check no drift exit 0

V2 — getoetst tegen ECHTE bodies, geen fixture

phase1.sse (geslaagde flow) -> exit_code = 0
phase2.sse (echt gefaalde Task 6-run) -> exit_code = 1
afgekapte stream -> <leeg>   -> geteld als MISLUKT (fail closed)
lege body        -> <leeg>   -> geteld als MISLUKT (fail closed)

Dat laatste is het punt: /agent/v1/flow geeft HTTP 200 zodra het streamen begint, dus curl -f meldt succes bij een mislukte deploy. Kan de parser geen done-event vinden, dan telt dat als mislukking — niet als succes.

V3 — de hot-loop-guard

tick 1: exit=1  POSTs=1  state=[9f91631 fails=1]
tick 2: exit=1  POSTs=2  state=[9f91631 fails=2]
tick 3: exit=1  POSTs=3  state=[9f91631 fails=3]
tick 4: exit=1  POSTs=3  <- GEEN aanroep meer
        ERROR: OPGEGEVEN voor 9f91631e87d9 na 3 mislukte pogingen
        ERROR: menselijke actie nodig; een nieuwe commit op main wist deze toestand.

Getest met een stub-endpoint, niet met drie echte mislukte deploys.

V4 — de eerste echte tick

[scrum4us-deploy-trigger] OK: flow geslaagd voor 9f91631e87d9

srv checkout HEAD                : 9f91631e87d9
origin/main                      : 9f91631e87d9
nieuwste Vercel-deployment (sha) : 9f91631e87d9   state=READY target=production

De werkboom is daarna schoon, wat betekent dat assert_checkout_clean_scrum4us écht slaagde in plaats van overgeslagen te worden — de eerste end-to-end bevestiging dat de npm ci-fix de lockfile-churn wegneemt.

Keuzes

  • User=ops-agent is een keuze, geen toeval: /etc/ops-agent/secret is 0640 root:ops-agent, dus die gebruiker leest hem via de groep zonder de mode te verruimen. Dezelfde gebruiker bezit de checkout en heeft de git-credentials die ls-remote nodig heeft.
  • flock -n, opgeven in plaats van wachten: de volgende tick ziet dezelfde commit toch. Dit is dragend zolang de ops-agent geen admission control heeft — twee ticks zouden anders twee gelijktijdige db:migrate:deploy kunnen starten.
  • Geen Persistent=true op de timer: een gemiste tick hoeft niet ingehaald te worden.
  • TimeoutStartSec=5700 omdat de flow minuten duurt en systemd hem anders zou afkappen.
Part C Task 7 — het sluitstuk van de deploy-ordering. Sinds Part B de web-deploy ín de flow trok is deze trigger **niet meer dragend voor correctheid**: vuurt hij nooit, dan is het resultaat "niets gedeployd" — zichtbaar en veilig — in plaats van "UI vóór API". Daarom bewust het kleinste dat werkt. ## Bewijs | # | check | uitkomst | |---|---|---| | V1 | flock | **PASS** — met de lock vast doet een tweede kopie **nul** POSTs en eindigt op exit 0 | | V2 | exit-code uit de SSE-body | **PASS** — zie hieronder | | V3 | failure-teller | **PASS** — 3 pogingen, dan opgeven zónder endpoint-aanroep; andere sha reset naar 1/3 | | V4 | eerste tick deployt `9f91631` | **PASS** — drie-weg-match, zie hieronder | | V5 | no-op tick | **PASS** — `NOOP: checkout is bij (9f91631e87d9)`, exit 0, nul POSTs | | V6 | baseline + drift | **PASS** — deze PR; drift-check `no drift` exit 0 | ### V2 — getoetst tegen ECHTE bodies, geen fixture ``` phase1.sse (geslaagde flow) -> exit_code = 0 phase2.sse (echt gefaalde Task 6-run) -> exit_code = 1 afgekapte stream -> <leeg> -> geteld als MISLUKT (fail closed) lege body -> <leeg> -> geteld als MISLUKT (fail closed) ``` Dat laatste is het punt: `/agent/v1/flow` geeft HTTP 200 zodra het streamen begint, dus `curl -f` meldt succes bij een mislukte deploy. Kan de parser geen `done`-event vinden, dan telt dat als mislukking — niet als succes. ### V3 — de hot-loop-guard ``` tick 1: exit=1 POSTs=1 state=[9f91631 fails=1] tick 2: exit=1 POSTs=2 state=[9f91631 fails=2] tick 3: exit=1 POSTs=3 state=[9f91631 fails=3] tick 4: exit=1 POSTs=3 <- GEEN aanroep meer ERROR: OPGEGEVEN voor 9f91631e87d9 na 3 mislukte pogingen ERROR: menselijke actie nodig; een nieuwe commit op main wist deze toestand. ``` Getest met een stub-endpoint, niet met drie echte mislukte deploys. ### V4 — de eerste echte tick ``` [scrum4us-deploy-trigger] OK: flow geslaagd voor 9f91631e87d9 srv checkout HEAD : 9f91631e87d9 origin/main : 9f91631e87d9 nieuwste Vercel-deployment (sha) : 9f91631e87d9 state=READY target=production ``` De werkboom is daarna schoon, wat betekent dat `assert_checkout_clean_scrum4us` écht slaagde in plaats van overgeslagen te worden — de eerste end-to-end bevestiging dat de `npm ci`-fix de lockfile-churn wegneemt. ## Keuzes - **`User=ops-agent`** is een keuze, geen toeval: `/etc/ops-agent/secret` is `0640 root:ops-agent`, dus die gebruiker leest hem via de groep zonder de mode te verruimen. Dezelfde gebruiker bezit de checkout en heeft de git-credentials die `ls-remote` nodig heeft. - **`flock -n`**, opgeven in plaats van wachten: de volgende tick ziet dezelfde commit toch. Dit is dragend zolang de ops-agent geen admission control heeft — twee ticks zouden anders twee gelijktijdige `db:migrate:deploy` kunnen starten. - **Geen `Persistent=true`** op de timer: een gemiste tick hoeft niet ingehaald te worden. - **`TimeoutStartSec=5700`** omdat de flow minuten duurt en systemd hem anders zou afkappen.
feat(deploy): timer die redeploy_scrum4us afvuurt als main beweegt
Some checks failed
CI / Root app checks (pull_request) Has been cancelled
CI / Ops-agent checks (pull_request) Has been cancelled
CI / Deploy artifact checks (pull_request) Has been cancelled
CI / Docker image build (pull_request) Has been cancelled
80366c91cd
Sluitstuk van de deploy-ordering. Sinds Part B de web-deploy IN de flow trok is
deze trigger niet meer dragend voor correctheid: vuurt hij nooit, dan is het
resultaat "niets gedeployd" — zichtbaar en veilig — in plaats van "UI voor API".
Daarom bewust het kleinste dat werkt.

Drie dingen maken het veilig, alle drie bewezen:

1. De exit-code komt uit de SSE-BODY, niet uit de HTTP-status. /agent/v1/flow
   geeft 200 zodra het streamen begint, dus `curl -f` meldt succes bij een
   MISLUKTE deploy. De parser is getoetst tegen twee ECHTE flow-bodies van vandaag
   (geslaagd -> 0, gefaalde Task 6-run -> 1), en geeft leeg terug bij een
   afgekapte of lege stream; dat telt als mislukking, dus fail closed.

2. flock -n is dragend, geen extra laagje: de gedeployde ops-agent heeft nog geen
   admission control, dus twee ticks zouden twee gelijktijdige db:migrate:deploy
   kunnen starten. Bewezen: met de lock vast doet een tweede kopie geen enkele
   POST en eindigt op exit 0.

3. Failure-teller per sha tegen een hot loop. Faalt de flow NA git_pull, dan is
   HEAD verzet en doet de volgende tick niets. Faalt hij ERVOOR, dan beweegt HEAD
   niet en zou dezelfde deploy elke twee minuten opnieuw vuren. Na 3 pogingen op
   dezelfde sha stopt hij, luid; een nieuwe sha wist de teller. Bewezen met een
   stub-endpoint, niet met drie echte mislukte deploys.

User=ops-agent is een keuze, geen toeval: /etc/ops-agent/secret is 0640
root:ops-agent, dus die gebruiker leest hem via de groep zonder de mode te
verruimen. Dezelfde gebruiker bezit de checkout en heeft de git-credentials die
ls-remote nodig heeft.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
s4m-codex-reviewer requested changes 2026-08-02 11:16:24 +02:00
Dismissed
s4m-codex-reviewer left a comment

Verdict: REQUEST_CHANGES

geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.

Findings

  • errordeploy/ops-agent/systemd/scrum4us-deploy-trigger.service:18 — De unit start /srv/scrum4me/scripts/scrum4us-deploy-trigger.sh, maar deze PR voegt het script toe als deploy/ops-agent/scripts/scrum4us-deploy-trigger.sh en bevat geen setup/install-wijziging die het naar /srv/scrum4me/scripts/ kopieert. Als de referentiekopie naar /etc/systemd/system/ wordt toegepast zoals de comment beschrijft, faalt de service met een ontbrekende ExecStart en vuurt de timer nooit de redeploy_scrum4us flow af. Maak het runtime-pad consistent met de geleverde installatie of voeg de ontbrekende installatiestap toe.

  • warningdeploy/ops-agent/scripts/scrum4us-deploy-trigger.sh:44 — De kritieke SSE-parser en retry-state zijn nieuw, maar de diff bevat geen test of fixture voor done-events, ontbrekende done-events, niet-nul exit codes en de MAX_FAILS-limiet. Omdat de comments expliciet stellen dat de exit-code in de SSE-body de veiligheidsgrens is, verdient dit minimaal een gerichte shell-test of documented verification command voordat dit autonoom op een timer draait.

# Verdict: REQUEST_CHANGES geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden. ## Findings - **error** — `deploy/ops-agent/systemd/scrum4us-deploy-trigger.service:18` — De unit start `/srv/scrum4me/scripts/scrum4us-deploy-trigger.sh`, maar deze PR voegt het script toe als `deploy/ops-agent/scripts/scrum4us-deploy-trigger.sh` en bevat geen setup/install-wijziging die het naar `/srv/scrum4me/scripts/` kopieert. Als de referentiekopie naar `/etc/systemd/system/` wordt toegepast zoals de comment beschrijft, faalt de service met een ontbrekende `ExecStart` en vuurt de timer nooit de `redeploy_scrum4us` flow af. Maak het runtime-pad consistent met de geleverde installatie of voeg de ontbrekende installatiestap toe. - **warning** — `deploy/ops-agent/scripts/scrum4us-deploy-trigger.sh:44` — De kritieke SSE-parser en retry-state zijn nieuw, maar de diff bevat geen test of fixture voor `done`-events, ontbrekende `done`-events, niet-nul exit codes en de `MAX_FAILS`-limiet. Omdat de comments expliciet stellen dat de exit-code in de SSE-body de veiligheidsgrens is, verdient dit minimaal een gerichte shell-test of documented verification command voordat dit autonoom op een timer draait.
fix(deploy): trigger reproduceerbaar uit de repo, en getest
Some checks failed
CI / Root app checks (pull_request) Failing after 4m40s
CI / Ops-agent checks (pull_request) Successful in 15s
CI / Deploy artifact checks (pull_request) Successful in 12s
CI / Docker image build (pull_request) Successful in 1m22s
499e52a6c0
Twee review-bevindingen op deze PR.

FINDING 1 — het gecommitte artefact kon de werkende host niet reproduceren.
ExecStart wees naar /srv/scrum4me/scripts/scrum4us-deploy-trigger.sh, maar niets
in de repo vulde dat pad; het script stond daar omdat ik het met de hand had
neergezet. Twee dingen gefixt:

- setup.sh installeert het script nu, naast repo-contains-sha.sh en
  update-operator-mcp.sh — dezelfde conventie, dus een gewone agent-deploy houdt
  het vers.
- De unit-header beschrijft nu vier stappen die letterlijk gevolgd een werkende
  timer opleveren, in plaats van drie die dat niet doen.

De reviewer zag één stap over het hoofd, en die ontbrak net zo goed: de state-map
/srv/scrum4us/trigger moet VOORAF bestaan. /srv/scrum4us is janpeter:janpeter, dus
ops-agent kan hem niet zelf aanmaken; het script probeert dat (install -d || true)
en strandt daarna op het lockbestand. Ook die map had ik met de hand gemaakt.

FINDING 2 — het bewijs stond in een chatrapport, niet in de repo.

test/scrum4us-deploy-trigger.test.ts dekt nu de twee dingen die het script zelf
zijn veiligheidsgrens noemt: de SSE-exit-code-parser en de MAX_FAILS-teller. De
fixtures zijn de ECHT opgevangen bodies van vandaag — een geslaagde run en de run
die daadwerkelijk faalde op assert_checkout_clean_scrum4us. Alleen de
stdout/stderr-payloads zijn eruit (tientallen KB build-log); elke event:/data:-regel
die de parser aanraakt is verbatim.

Alle vier de gedragingen zijn mutatiegetoetst: parser altijd-0, MAX_FAILS
onbereikbaar, teller-reset weg, NOOP zonder early exit. Elk maakt precies zijn
eigen test rood; na herstel weer 7/7 groen.

De test MOET async zijn: de stub-server draait in hetzelfde Node-proces, en
execFileSync blokkeert de eventloop — dan accepteert de server nooit en wacht curl
tot zijn --max-time. Dat kostte een testrun van vijf minuten voor het kwartje viel.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
s4m-codex-reviewer requested changes 2026-08-02 12:11:45 +02:00
Dismissed
s4m-codex-reviewer left a comment

Verdict: REQUEST_CHANGES

Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.

Findings

  • ERRORdeploy/ops-agent/setup.sh:129: de normale ops-agent setup installeert nu wel scrum4us-deploy-trigger.sh, maar maakt de verplichte state-directory /srv/scrum4us/trigger niet aan met eigenaar ops-agent:ops-agent. De nieuwe service draait als ops-agent en het script probeert install -d -m 0750 "$STATE_DIR" zelf, maar de service-comments zeggen terecht dat /srv/scrum4us niet van ops-agent is. Op een schone host strandt de eerste timer-run daardoor bij het openen van $STATE_DIR/lock, waardoor de timer het beoogde automatische redeploy-pad niet uitvoert. Voeg de state-directory installatie toe aan de deploy/setup-flow, of pas de runtime-locatie aan naar een directory die de service-user kan aanmaken.

Opmerkingen

De SSE-exitcode parsing en MAX_FAILS-guard zijn gericht getest met realistische fixtures. De blokkade zit in de operationele installatie: de runtime preconditie uit de unit wordt niet door de versioned setup afgedwongen.

# Verdict: REQUEST_CHANGES Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden. ## Findings - **ERROR** — `deploy/ops-agent/setup.sh:129`: de normale ops-agent setup installeert nu wel `scrum4us-deploy-trigger.sh`, maar maakt de verplichte state-directory `/srv/scrum4us/trigger` niet aan met eigenaar `ops-agent:ops-agent`. De nieuwe service draait als `ops-agent` en het script probeert `install -d -m 0750 "$STATE_DIR"` zelf, maar de service-comments zeggen terecht dat `/srv/scrum4us` niet van `ops-agent` is. Op een schone host strandt de eerste timer-run daardoor bij het openen van `$STATE_DIR/lock`, waardoor de timer het beoogde automatische redeploy-pad niet uitvoert. Voeg de state-directory installatie toe aan de deploy/setup-flow, of pas de runtime-locatie aan naar een directory die de service-user kan aanmaken. ## Opmerkingen De SSE-exitcode parsing en MAX_FAILS-guard zijn gericht getest met realistische fixtures. De blokkade zit in de operationele installatie: de runtime preconditie uit de unit wordt niet door de versioned setup afgedwongen.
fix(deploy): state-map via StateDirectory, geen handmatige stap meer
Some checks failed
CI / Ops-agent checks (pull_request) Has been cancelled
CI / Deploy artifact checks (pull_request) Has been cancelled
CI / Docker image build (pull_request) Has been cancelled
CI / Root app checks (pull_request) Has been cancelled
2b28b2b87c
Tweede reviewronde op deze PR, en de reviewer heeft gelijk: ik had dit defect zelf
gevonden en met documentatie gesloten terwijl automatisering beschikbaar was.
setup.sh installeerde het script vanzelf, maar de map die dat script nodig heeft
vroeg nog een mens. Half-geautomatiseerd is de slechtste van de drie toestanden,
want het ziet er af uit.

StateDirectory=scrum4us-deploy-trigger laat systemd /var/lib/scrum4us-deploy-trigger
bij elke start aanmaken met de juiste eigenaar. De eis en de vervulling staan nu in
hetzelfde bestand, dus ze kunnen niet uit elkaar lopen. Zelfde mechanisme dat
ops-agent.service voor zijn flow-journals gebruikt.

Het script leest STATE_DIRECTORY dat systemd zet, met een fallback voor een
handmatige run buiten systemd om. De handmatige stap is uit de unit-header; er zijn
nu drie stappen in plaats van vier.

Live uitgevoerd met de timer kort gestopt zodat geen tick in de migratie viel; de
bestaande state (9f91631e87d9, fails=0) is verplaatst, niet gereset. Bewezen door
/var/lib weg te gooien en de service te starten: systemd maakt hem opnieuw aan als
drwxr-x--- ops-agent:ops-agent en de tick draait. Oude map pas daarna verwijderd.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
fix(backup): restore-test dekt ops-agent, en test niet langer een snapshot van mei
Some checks failed
CI / Root app checks (pull_request) Failing after 4m26s
CI / Ops-agent checks (pull_request) Successful in 15s
CI / Deploy artifact checks (pull_request) Successful in 11s
CI / Docker image build (pull_request) Successful in 1m24s
77117a58da
Drie dingen, waarvan het middelste het zwaarst weegt.

1. /etc/ops-agent wordt nu hersteld en inhoudelijk getoetst. Die config IS de
   deploy-pipeline — de command-whitelist plus elke flow — en stond aantoonbaar in
   de restic-set, maar werd hier nooit teruggehaald. "Is het vastgelegd" was bewezen
   en "kan het terugkomen" niet. De asserties tellen command-keys onder `commands:`
   en flows die daadwerkelijk een command_key bevatten; bestaat-en-niet-leeg is
   dezelfde holle vorm als een scanner die niets scant.

2. De snapshot-selectie was fout en dat maakte de hele test bijna betekenisloos.
   `restic snapshots --json --latest 1 | jq '.[0]'` geeft de laatste snapshot PER
   host/pad-combinatie; `.[0]` pakt daar de eerste groep uit. Toen de padlijst ooit
   van 7 naar 8 ging ontstond een tweede groep, en sindsdien koos deze regel
   stelselmatig de OUDSTE: de test valideerde een snapshot van 2026-05-17 terwijl er
   dagelijks nieuwe bijkwamen, en rapporteerde daar "success" over. Nu sorteren op
   tijd en de laatste nemen.

3. De dump-include is versmald tot de postgres-dumps. /var/backups/databases is
   inmiddels 65G (64G daarvan forgejo-zips) en /tmp heeft 2,3G vrij, dus de restore
   liep op ENOSPC — precies wat de comment erboven al zei te willen vermijden. De
   assertie kijkt alleen naar de nieuwste postgres-dump, dus dit dekt wat er getoetst
   wordt.

Gedraaid, via dezelfde wrapper als de flow:

  Restoring snapshot 5e65ed04 ... at 2026-08-02 03:39:25
  ✓ /etc/ops-agent/commands.yml (43601 bytes)
  ✓ ops-agent/commands.yml: command-keys: 98 (min 20)
  ✓ ops-agent/flows: flows met stappen: 18 (min 5)
  Overall: success

Vóór de fix koos dezelfde run snapshot bf4ac324 van 17 mei, met 41 keys en 8 flows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
s4m-codex-reviewer approved these changes 2026-08-02 12:51:06 +02:00
Dismissed
s4m-codex-reviewer left a comment

Verdict: APPROVED

Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.

Findings

  • Geen blokkerende of error-severity findings gevonden.

Review-notities

  • De nieuwe deploy/ops-agent/scripts/scrum4us-deploy-trigger.sh behandelt de relevante failure mode correct door de terminale SSE done body te parsen in plaats van op HTTP 200/curl-success te vertrouwen.
  • De combinatie van flock, per-SHA MAX_FAILS state en systemd StateDirectory= is passend voor een onbeheerde timer en voorkomt zowel parallelle deploys als een hot loop op dezelfde mislukte SHA.
  • De testdekking raakt de belangrijkste risico's: echte SSE success/failure/truncated fixtures, lege body, no-op checkout, fail counter en counter-reset bij nieuwe SHA.
  • De setup-wijziging installeert het script waar de service naar verwijst; de systemd unit/timer bevatten voldoende operationele instructies voor activatie.
# Verdict: APPROVED Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden. ## Findings - Geen blokkerende of error-severity findings gevonden. ## Review-notities - De nieuwe `deploy/ops-agent/scripts/scrum4us-deploy-trigger.sh` behandelt de relevante failure mode correct door de terminale SSE `done` body te parsen in plaats van op HTTP 200/curl-success te vertrouwen. - De combinatie van `flock`, per-SHA `MAX_FAILS` state en systemd `StateDirectory=` is passend voor een onbeheerde timer en voorkomt zowel parallelle deploys als een hot loop op dezelfde mislukte SHA. - De testdekking raakt de belangrijkste risico's: echte SSE success/failure/truncated fixtures, lege body, no-op checkout, fail counter en counter-reset bij nieuwe SHA. - De setup-wijziging installeert het script waar de service naar verwijst; de systemd unit/timer bevatten voldoende operationele instructies voor activatie.
s4m-codex-reviewer left a comment

Verdict: APPROVED

Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.

Findings

  • Geen blokkerende of error-severity findings gevonden.

Review-notities

  • De nieuwe deploy-trigger behandelt de relevante failure modes expliciet: SSE-terminal event parsing in plaats van HTTP-status, non-blocking flock, en een per-remote-sha fail-counter tegen hot loops.
  • De systemd unit gebruikt StateDirectory= conform het bestaande ops-agent patroon voor service-owned runtime state.
  • De testdekking raakt de belangrijkste risico's: succesvolle, gefaalde, lege en afgekapte SSE bodies; MAX_FAILS gedrag; reset bij nieuwe sha; en NOOP wanneer de checkout bij is.
  • De restore-test wijziging corrigeert de snapshotselectie en beperkt restore-includes beter tot de assertiedoelen, inclusief inhoudelijke checks voor de ops-agent deploy-pipeline.
# Verdict: APPROVED Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden. ## Findings - Geen blokkerende of error-severity findings gevonden. ## Review-notities - De nieuwe deploy-trigger behandelt de relevante failure modes expliciet: SSE-terminal event parsing in plaats van HTTP-status, non-blocking `flock`, en een per-remote-sha fail-counter tegen hot loops. - De systemd unit gebruikt `StateDirectory=` conform het bestaande ops-agent patroon voor service-owned runtime state. - De testdekking raakt de belangrijkste risico's: succesvolle, gefaalde, lege en afgekapte SSE bodies; MAX_FAILS gedrag; reset bij nieuwe sha; en NOOP wanneer de checkout bij is. - De restore-test wijziging corrigeert de snapshotselectie en beperkt restore-includes beter tot de assertiedoelen, inclusief inhoudelijke checks voor de ops-agent deploy-pipeline.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
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/Ops-dashboard!131
No description provided.