carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1Dormant merge: **ACCEPT WITH FIXES**
2Flag-on for boxes without host claims: **NOT YET SAFE**
3
4Read-only review of `650e6152..4c9bc525`. No files changed or tests run. All repository anchors below refer to `4c9bc525`.
5
61. **High / Merge — A stopping instance can lose track of its returning sidecar.**
7
8 `internal/activator/activator.go:4437` clears `sidecarStartDone` before deferred cleanup runs. Sequence: `beginStopLocked` marks stopping; the restart returns and clears the channel; `stop()` reads nil at `:3593`; the returned sidecar is still draining through `stopSidecarNow`.
9
10 Nested instances are particularly exposed: `internal/activator/opset.go:390` skips host-cgroup proof for their layout, while the main process’s stop proves only its own role (`internal/activator/unitproc.go:89`). The lease can therefore be released at `activator.go:3973` while the sidecar remains.
11
12 Even when the join is captured, `stopSidecarNow` merely logs a failed stop (`activator.go:746`), then forgets the returned process. Closing the join is not termination proof.
13
14 **Smallest fix:** retain the join through cleanup, retain any unproven returned sidecar, and require its termination before releasing the lease. Add deterministic tests for the missed-join window and nested `ErrStillRunning`.
15
162. **High / Merge — Two seed-obligation errors release the lease without proving surviving processes gone.**
17
18 A successful flag-off seed may leave a helper running: `internal/activator/backend_exec.go:1072` deliberately skips descendant cleanup. If obligation discharge fails, `:1104` returns an ordinary error; `internal/activator/activator.go:2061` consequently releases the lease. No installed instance exists whose terminal stop will prove that helper gone.
19
20 Likewise, an obligation read error returns without `ErrSeedUnproven` at `backend_exec.go:1286`, causing Restore’s error path to release at `activator.go:1987`. Nested wakes skip the preceding host proof (`internal/activator/opset.go:429`).
21
22 **Smallest fix:** preserve the lease whenever seed termination remains unknown. Attempt proof after discharge failure; classify unreadable obligations conservatively. Test both paths with a surviving process. A subsequent wake’s proof cannot justify an earlier release.
23
243. **High / Flag — I9 does not prove the required stale-grant guarantee.**
25
26 `internal/rollout/sim_test.go:747` considers a failure “answered” by another grant’s **issuance**, recorded at `:1967`, regardless of whether that grant is applied.
27
28 Counterexample: issue G0; begin another hold execution; issue G1; renew the marker with M14’s missing generation bump; deliver G0 first. `answered` sees G1 and suppresses the violation even though G0 cleared the later marker. Delivery is explicitly oldest-first (`:1975`).
29
30 I9 also excludes facts by execution-start time rather than restriction-change order, including all same-step facts (`:2025`, `:2033`). That leaves late outcomes and same-step changes outside the asserted guarantee.
31
32 **Smallest fix:** give the independent model ordered restriction transitions and capture their identity at publication. Check each accepted grant against that state; issuance alone must never discharge a fact. Add deterministic masking, late-outcome and same-step witnesses, then rerun the mutants.
33
344. **Medium / Merge — Manual obligation recovery is not serialized against wakes.**
35
36 The procedure in `docs/superpowers/plans/2026-10-07-zero-downtime-deploys-6-roll-notes.md:424` proves emptiness, deletes database files, then removes the obligation, but never excludes concurrent wakes.
37
38 Between proof and deletion, Restore can discharge the obligation and begin another seed (`internal/activator/backend_exec.go:1281`). The operator can then delete that new seed’s database.
39
40 **Smallest fix:** require exclusive maintenance across proof, database deletion, directory sync and obligation removal; resume wakes afterward. Correct deletion order alone is insufficient.
41
425. **Low / Flag — The literal generation non-repetition proof omits counter exhaustion.**
43
44 `internal/rollout/failures.go:751` and `:756` increment `uint64` without checking overflow. Thus “every subsequent generation is larger” is not an unconditional property.
45
46 This is not a plausible operational exhaustion scenario, but it contradicts the stated hard limit.
47
48 **Smallest fix:** fail closed before exhaustion, including `Snapshot`, and test the boundary. Do not silently wrap under the same book identity.
49
50**1. Plan-review findings 1–12**
51
52| Finding | Disposition | Evidence |
53|---|---|---|
54| 1. Replacement/removal generations | ADDRESSED | Per-app generations; marker replacement and pruning touch them: `internal/rollout/failures.go:898`, `:901`, `:1242`. |
55| 2. Upgrade identity rotation | ADDRESSED | Schema/durability migration rotates identity: `internal/rollout/failures.go:520`. |
56| 3. Failed seed’s partial database | ADDRESSED | Write-ahead obligation and Restore settlement: `internal/activator/backend_exec.go:1198`, `:1281`. Lease errors remain finding 2. |
57| 4. Required placement fallback | ADDRESSED | Required starts refuse fallback; final defensive guard: `internal/cgroup/cgroup.go:449`, `:500`, `:538`. |
58| 5. In-flight sidecar start | PARTIAL | Join added at `internal/activator/activator.go:3593`, but finding 1 defeats it. |
59| 6. Successful seed descendants | ADDRESSED | Flag-on successful seeds require descendant proof: `internal/activator/backend_exec.go:1072`. |
60| 7. Independent I9 facts | PARTIAL | Model facts exist, but exemptions weaken the oracle: `internal/rollout/sim_test.go:747`, `:2033`. |
61| 8. Mutation witnesses | ADDRESSED | Real-path mutations and named invariant checks: `internal/rollout/testdata/rolloutsim/mutate.sh:104`, `:160`, `:298`. |
62| 9. Retry transport/restart | ADDRESSED | Separate signed log; legacy restart processing retained: `internal/release/hostretrylog.go:36`; `internal/host/restart.go:944`. |
63| 10. Independent save retries | ADDRESSED | Startup and periodic retry: `internal/host/rolloutdeclined.go:109`, `:324`. |
64| 11. Test committed revision | ADDRESSED | Checkpoint-before-mutation requirement: `docs/superpowers/plans/2026-10-12-zero-downtime-flag-readiness-2.md:29`. Ledger reports checkpointed runs. |
65| 12. Factual/environment corrections | PARTIAL | Forwarder fixed at `internal/console/instancepage.go:67`; plan `:26` still contradicts supplied scratch/cache rules. |
66
67**Hard-limit assessment:** within the non-overflow range and stated file assumptions, I found no additional production mutation missing its generation change. Publication refuses dirty state; acceptance retries the save and refuses remaining dirtiness (`internal/rollout/failures.go:1095`, `:1134`). Reopen uses the highest saved sequence; migration rotates identity (`:511`, `:520`). These are substantial improvements. Certification remains incomplete because of findings 3 and 5 and the unaudited restore/clone assumption (`:349`; roll notes `:379`).
68
69The M13–M17 mutations exercise real paths: failed-save publication→I10; marker renewal, reopened sequence reuse, old-book grants and sibling-created records→I9. The runner requires the named invariant, not just any failure (`mutate.sh:104`, `:160`, `:298`). Their reported kills demonstrate sensitivity, not completeness of I9. I did not rerun them. The last inspected 3000-seed log showed the baseline passed and mutation checks still progressing.
70
71Tasks 3–7 close their identified implementation gaps, subject to real-box evidence:
72
73- **3–4:** capability/unsaved refusals and shared console eligibility agree (`internal/console/apiretry.go:88`; `instancepage.go:49`).
74- **5:** declined execution pins identity and tier; production installs `BeforeExec` (`internal/activator/backend_exec.go:1685`, `:2952`; `internal/host/agent.go:451`).
75- **6:** success requires the matching clean park, no fence/shutdown, and current scheduler revision (`internal/activator/workerswap.go:195`).
76- **7:** required placement cannot fall through to PID movement (`internal/cgroup/cgroup.go:538`).
77- **8:** remains incomplete through findings 1–2.
78
79I found no additional lock-order inversion or direct disk I/O under `Service.mu` in the changed cleanup paths; host proof drops the mutex before I/O (`internal/activator/opset.go:382`). The schema-3 refusal is deliberate local downgrade protection, not an incompatible external wire change (`internal/rollout/failures.go:501`). All seven new member-facing literals carry TODO-COPY markers (`internal/console/apiretry.go:42`, `:45`; `browserretry.go:22`, `:23`; `swapcopy.go:67`, `:72`, `:81`).
80
81**5. Every ledger ruling**
82
83Line numbers identify rulings in `/home/paulca/.cache/zdd-impl/readiness2/ledger.md`.
84
85| Lines | Position | Reason / condition |
86|---|---|---|
87| 9 | Agree with conditions | Hard rule is correct; findings 3 and 5 prevent certification. |
88| 10 | Agree | Capability-gated signed transport: `internal/console/apiretry.go:88`. |
89| 11 | Agree | Separate rev-18 amendment preserves the binding specification. |
90| 12 | Agree | Own-build recovery is appropriate: `internal/activator/activator.go:2523`. |
91| 13 | Agree with conditions | Authorized stop proof must include finding 1. |
92| 14 | Agree with conditions | Durable obligation is right; close finding 2. |
93| 15 | Agree | Required-placement refusal: `internal/cgroup/cgroup.go:449`. |
94| 16 | Agree | Restart must apply checked grants, not seed-skip them: `internal/host/restart.go:944`. |
95| 17 | Agree | Clean-park qualification: `internal/activator/workerswap.go:195`. |
96| 18 | Agree | Real-box work remains external: roll notes `:455`. |
97| 22 | Agree | Per-app generation matches record scope: `internal/rollout/failures.go:836`. |
98| 23 | Disagree | Calling conflicting cache commands “house rules” does not resolve plan `:26`. |
99| 40 | Agree with conditions | Migration and downgrade protection are sound; restore-path audit remains required (`failures.go:349`, `:520`). |
100| 46 | Agree | Renewal witness matches M14’s actual mutation: `mutate.sh:107`. |
101| 48 | Disagree in part | App-wide facts are right; issuance-as-answer and skipped same-step facts are not sufficient: finding 3. |
102| 50 | Agree | M17’s zero-only bump isolates stale-grant safety from initial-generation liveness (`mutate.sh:131`). |
103| 51 | Agree | Forced sibling health failure is a legitimate witness (`mutate.sh:139`). |
104| 57 | Agree | Historic legacy retries remain quiet while eligible signed retries are processed (`internal/host/restart.go:129`, `:143`). |
105| 64 | Agree | Declined-down wording and shared refusal match behavior (`instancepage.go:49`, `:77`). |
106| 68–69 | Agree | Pinned tier and recorded-build sidecar fallback agree (`backend_exec.go:2952`; `activator.go:2523`). |
107| 74 | Agree | Abandoning non-clean exits preserves the clean-park condition (`workerswap.go:195`). |
108| 80 | Agree with conditions | Placement classification is heuristic; the probe does not prove ancestor permissions (`internal/cgroup/cgroup_linux.go:78`). |
109| 81 | Agree | Single latch decision plus final fallback guard closes the identified race (`internal/cgroup/cgroup.go:445`, `:538`). |
110| 86 | Disagree in part | Whole-host proof/reseeding are sound; calling the lost-sidecar scenario impossible is unsupported by finding 1. |
111| 88 | Agree with conditions | Write-ahead/nested obligations improve recovery; finding 2 remains. |
112| 94 | Agree with conditions | Database-first order is necessary; exclusive recovery is also necessary: finding 4. |
113
114**6. Every deferred minor**
115
116Grouped by ledger entry; every item receives a disposition.
117
118| Ledger entry | Triage |
119|---|---|
120| Task 1, line 41 | **Defer:** randomness failure refusing starts is conservative (`internal/rollout/failures.go:524`). Memory-only simulation concern is superseded by disk-backed seeds (`sim_test.go:504`). “Grants never expire” is already corrected by verification (`internal/release/hostretry.go:75`). **Merge:** resolve the reported `TestACancelledObservationRecordsNothing` and `TestAPointerClearRequeuesBeforeTheNextChannelIsRead` flakes; do not dismiss known failures as scheduling noise. |
121| Task 1, line 43 | **Flag:** audit every data-directory copy/restore path and rotate identity. **Defer:** deliberate schema-3 downgrade refusal, with upgrade recovery (roll notes `:370`, `:379`). |
122| Task 2, line 52 | **Flag:** obtain final M14/M16/M17 evidence after fixing I9. **Defer:** duplicate reconciled facts are redundant rather than permissive (`sim_test.go:2031`). |
123| Task 3, lines 58, 60 | **Defer:** double-counted read errors; missing nil-handler/no-GET test; missing legacy lost-position test; missing history lost-position test; census key-specific coverage. These concern diagnostics or coverage around the checked delivery path (`internal/host/restart.go:129`, `:301`, `:857`). **Merge:** squash intermediate ungreen commits and validate the final tip. |
124| Task 5, line 71 | **Defer:** long comment; silent version-mismatch refusal; unreachable nested identity omission; unreachable flat unversioned-link arm; missing real-backend fallback test; refused-seed coverage limited to absent databases. Production hook installation and pinning support this disposition (`internal/host/agent.go:451`; `backend_exec.go:1685`; `activator.go:2523`). |
125| Task 6, line 76 | **Defer:** untested shutdown clause, positive control not asserting park, overstated timing comment. The production conjunction is explicit (`internal/activator/workerswap.go:195`). |
126| Task 7, line 83 | **Defer:** fixture-only placement misclassification, common-ancestor EACCES diagnostic gap, linking `testing`. None opens required-placement fallback (`internal/cgroup/cgroup_linux.go:66`; `cgroup.go:538`). |
127| Task 8, line 89 | **Defer:** claims-path cleared-Seed/ColdRestore gap; pre-existing undelegated flag-off sidecar limitation; approximately 35-second shutdown wait. These do not excuse the separately identified nested-sidecar defect (`internal/activator/opset.go:385`, `:402`; `activator.go:3596`). |
128| Task 8, line 91 | **Merge:** unreadable-obligation lease release and successful-seed discharge lease release—finding 2. **Defer:** planted-directory recovery, existing-obligation refusal, pre-existing older-kernel worker/uncontained proof behavior, stale `reapUncontainedStop` plan name (`backend_exec.go:1200`, `:1281`; roll notes `:436`). **Merge:** resolve `TestARetainedCopyIsPublishedBeforeItIsRecorded` flakiness; repeated failures are not “noise.” |
129| Task 9, line 96 | **Defer:** successful-but-unproven reseed wording, cosmetic wrapping, preamble omitting separately listed real-box items. Recovery and outstanding checks are described nearby (roll notes `:416`, `:455`). |
130
131**7. Explicit flag-on answer**
132
133**No—even without host claims, this branch is not yet ready to enable `CARLOS_SWAP`.**
134
135The remaining gates are distinct:
136
137- **Branch fixes:** findings 1–5; correction of the conflicting verification instructions; resolution of reported flaky tests; required final build/test/cross-build gates; and a completed mutation sweep using the repaired I9 on the resulting revision.
138- **Contract/operational gates:** Paul’s rev-18 sign-off; the separate copy-review gate; and the restore/clone audit required by the identity proof (`failures.go:349`; roll notes `:379`). Claims-on arming remains excluded as instructed.
139- **Real-box proof:** delegated cgroup placement, sibling limits, legacy-parent recovery, live-generation sidecar respawn, unsupported-clone3 refusal, seed/normal-stop helper termination before lease release, nested/root unit control, sidecar fallback, mixed-version retries, unsaved-book recovery, downgrade/clone behavior, outstanding round-1 checks and flagship gates E–G (roll notes `:455` onward).
140
141Real-box success cannot substitute for repairing the cleanup paths or the simulation oracle.