fix(ops-agent): legacy-vs-legacy admission bewaakt, met zelfherstellende lease #142
No reviewers
Labels
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
janpeter/Ops-dashboard!142
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/legacy-admission-lease"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
startLegacyRunvergeleek een muterende legacy-run alleen tegen v2-leases. De enige legacy-vs-legacy-check wasLEGACY_RUN_ID_ACTIVE, gesleuteld op een per-run-uniekrun_id, dus die vuurde nooit.Gemeten matrix (zoals hij WAS)
acquireLeaseSetLEGACY_MUTATION_ACTIVE)V2_MUTATION_ACTIVE)Drie van de vier hoeken waren al dicht; de v2-kant deed de check al. De fix is dezelfde check in de andere richting.
Waarom niet kaal
acquireLeaseSetDie is bewust niet zelfherstellend: een verlopen conflict gaat via
retainExpiredConflictsnaarretained+attention_required, en de acquire faalt alsnog.LEASE_TTL_MSbetekent daar escaleer naar operator-reconciliatie, niet geef vrij. Voor v2 klopt dat — een gestrande gefaseerde deploy mag niet stilzwijgend worden overgenomen.Een legacy-run heeft die staat niet en dus niets te reconcilieren. Kaal hergebruik had de gap ingeruild voor een wedge: een gecrashte deploy blokkeert dan alles tot iemand handmatig een forced release met bewijs doet.
Daarom precies EEN afwijking, alleen op
host:<host>:legacy-mutation: een verlopen lease wordt overgenomen in plaats van retained. Store, CAS-lus,LEASE_TTL_MSenrenewLeaseSetzijn hetzelfde mechanisme. Release zonder proof om dezelfde reden —ReconciledReleaseProofeist evidence uit een event-log dat een legacy-run niet heeft.Heartbeat op
LEASE_RENEW_INTERVAL_MS(15s): de TTL is 60s terwijl echte deploys 8 minuten duren, dus zonder vernieuwing valt de bescherming halverwege elke deploy weg.De v2-kant leest nu ook de lease in plaats van de in-memory Map. Die Map had geen vervaltijd, dus een gecrashte legacy-run blokkeerde v2 tot de agent herstartte — die wedge bestond al vóór deze PR.
Classificatie hergebruikt (
classifyLegacyFlow/read_onlyuit de whitelist, fail-closed muterend); geen tweede classificatie.Integratiepunt: de deploy-trigger
Een 409 levert geen
done-event op, viel in de fail-closed tak en kreegcode=-1. Drie gelijktijdigheidsweigeringen zouden de auto-deploy permanent hebben uitgeschakeld voor die sha: normaal gedrag dat de automatisering sloopt. De HTTP-status wordt nu apart gelezen en een 409 telt niet als mislukking. Deflockblijft staan.Bewijzen (op de live agent)
http=200en draaide, Ahttp=409 {"reason_code":"LEGACY_MUTATION_ACTIVE","conflicting_run_ids":[...]}. Herhaald tijdens een ECHTEredeploy_scrum4us: ook 409.kill -9op de agent middenin een run; de wees-lease bleef staan. T+30s: 409 — een levende run wordt niet gestolen. T+65s: 200 — overgenomen.redeploy_scrum4us: 22 stappen, alleexit_code: 0, done-event 0, geen gefaalde stap.mainfalen er 4, waaronder beide die de gap asserteren. Trigger 8/8. Bestaande admission/locks/legacy-routes 41 groen. Typecheck schoon.Bevinding buiten de fix
Alle 101 command-keys zijn muterend; nul
read_only.classifyExecCommandis fail-closed en niemand heeft ooitread_only: truegezet — ook niet opgit_statusofsystemctl_status. Deze PR serialiseert daarmee alle exec-calls, niet alleen deploys.Daardoor is de eis read-only mag niet geblokkeerd worden op deze host niet aan te tonen: er zijn geen read-only commando's. Het gedrag staat wel in de tests, tegen een echte store. Statuscommando's
read_only: truegeven is een aparte wijziging aancommands.ymlen zit bewust niet in deze PR.🤖 Generated with Claude Code
Verdict: APPROVED
Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.
Findings
Beoordeling
De diff sluit aan op de productstandaard dat legacy v1-mutaties en v2-mutaties wederzijds uitgesloten zijn, terwijl expliciet read-only v1-werk beschikbaar blijft. De nieuwe legacy-mutatielease vult de legacy-vs-legacy admission-gap, gebruikt dezelfde duurzame lease-store/CAS-basis, laat verlopen legacy-leases zelf herstellen en voorkomt dat HTTP 409-admissionweigeringen de deploy-trigger als storing laten meetellen.
De toegevoegde tests dekken de belangrijkste regressierisico's: tweede muterende legacy-run weigeren, vrijgave, read-only parallelisme, verlopen lease-overname, niet-verlopen leaseweigering, v2-vs-legacy interactie en de deploy-trigger 409-route.