carlos / platform Public
REJECT
- High — Task 5: intent cleanup can erase an unrecorded failure. A failed wake deletes its activator entry before delivering
OnGen(internal/activator/activator.go:1453,:1549).Ownschecks only that entry (:2068), sodropUnownedWakescan run between deletion and failure delivery (internal/rollout/manager.go:638). AddingEndthere allows: hold B executes and fails → entry disappears → intent is durably removed → agent crashes before recording B. F5 survives. Smallest plan fix: require token-specific proof of no execution or completed outcome delivery before ending an orphaned intent. Do not equate!Ownswith an outcome. Also handle the successful “B untried, good build booted”GenHealthypath (internal/activator/wakeplan.go:667), which has no later terminal event to close B’s intent.
- High — Task 5: the persisted mode can differ from the executed mode.
resolveselects mode from policy/demand (internal/rollout/manager.go:852), butSwapconverts foreign-layout overlap attempts into holds (internal/activator/swap.go:264). An intent written beforeSwaptherefore records overlap; a crash after the foreign hold executes reconstructs neither hold-down nor marker. Automatic fallback becomes possible. Smallest plan fix: persist the effective execution mode before any stop or launch, including layout overrides. Add a foreign-layout hold crash/reopen regression.
- High — Task 4: ignoring a stale book write does not prevent a stale cohort halt.
failCohortcallsq.haltunconditionally afterRecord(internal/rollout/queue.go:497). Thus a delayed pre-retry failure can be ignored by the proposed book guard but still halt the newly reopened cohort and supersede its attempts. The book-only tests miss this. Smallest plan fix: return a distinct stale-outcome disposition and suppress the entire failure transition for it. Test throughdoneandOnGen, asserting queue admission and running-attempt revisions remain unchanged after retry.
- High — Task 4: preserving the first sequence for repeated executions of the same hold build leaves N6 open. The plan explicitly preserves
Seq/Atwhen account/app/build match. Current marking identifies only that triple (internal/rollout/failures.go:199); good publication clears later (internal/rollout/manager.go:979). Sequence: an existing B marker precedes C’s snapshot; B executes again while C’s publication is delayed; re-marking B preserves its old sequence; C clears the restriction protecting B’s newer execution. Smallest plan fix: identify executions separately from builds. Refresh the marker epoch for each distinct execution while deduplicating repeated reports of the same execution. Extend N6’s regression accordingly.
- High — Tasks 8–10: the promised recovery cannot be requested through the supported door. Declined status publishes no host holds (
internal/host/rollout.go:481), andretryHostBuildrejects every unavailable report (internal/console/apiretry.go:50). Marker-only declined hosts therefore cannot obtain the signed retry Task 9 requires. There is also an armed mismatch: status can report marker B while the installed target is A (internal/rollout/status.go:84); the console signs B, but Task 8’s proposedwantBuildcheck requires A. Smallest plan fix: specify declined hold reporting and permit authenticated retries for those holds; distinguish the restricted execution/build from the requested recovery target. Add API-to-box tests for both sequences. The declined-recovery ruling is agree with conditions, not implementable as written.
- High — Task 9: the exec gate misses nested and claims-backed declined launches. Nested starts call
runExecGate, notlaunchGate(internal/activator/backend_exec.go:1682). Claimed wakes check the declined planner before preparation (internal/activator/claimwake.go:214), then obtain the executable from the live link (internal/activator/claim_snapshot.go:87). Neither receives Task 9’s new final gate. A repoint after planning can still select a held build. Smallest plan fix: enumerate and gate all declined launch mechanisms against the actual selected identity. Resolve, or explicitly retain as an enablement blocker, the acknowledged flat live-link read/exec race. Accepting claims-on decline does not waive enforcement of inherited failure restrictions.
- High — Task 3: rollback provenance is checked at planning but remains bypassable at execution. The proposed
planCheckchange updates only the marked-build arm. Its existing good-build arm permits execution whenever the captured route installs its good build (internal/rollout/wakeplan.go:317). A marker established or replaced after planning is therefore not checked against the rollback authorization. Smallest plan fix: capture verified rollback authorization tied to the marker’s identity/epoch, and require that same authorization at the final gate without performing store I/O there. N5/N7’s proposed selection changes are sound; ruling 205 needs this execution-time condition.
- High — Tasks 2 and 17: missing-record handling and deferred status defects remain incomplete. Task 2 preserves an absent host’s existing mode. If it previously entered
modeURL, polling continues because the loop checks only mode andurlLive(deploywatch.go:317), ignoringunread. Separately, the deferred status issue is a real flag-on defect: waking/stopping hosts retain old queue observations (internal/rollout/manager.go:347,:372), while status derivesAwakesolely from cached serving (internal/rollout/status.go:49). A waking host can appear asleep before its settle is registered. Spec §9.1’s genuine-sleeper exception does not justify that. Smallest plan fix: suspend URL polling while the target is unreadable and test prior-URL-to-missing transitions. Carry explicit waking/stopping state into completion, or retain this as an enablement blocker.
- High — Task 6: classifying an uncertain exit is insufficient to authorize fallback. Nested start errors can wrap both the proposed exited sentinel and failed termination proof (
internal/activator/backend_exec.go:1709).spawnPlannedcurrently refuses fallback whenproc == nil(internal/activator/wakeplan.go:393). The task requires fallback for the sentinel without specifying how to distinguish successful cleanup from an unproven live generation. Smallest plan fix: carry explicit termination evidence. Permit nil-process fallback only after proven cleanup; otherwise record the failure and retain containment. Test both cleanup outcomes. The hold-failure classification itself is sound.
- Medium — Tasks 11 and 13: specify safe publication ordering, not just the intended result. Task 13’s insertion point is inside
a.mu(internal/activator/swaphold.go:107), butpersistGenerationstakesgenMuthena.mu(internal/activator/generations_file.go:238). An inline implementation deadlocks. Task 11’s FIFO writer likewise does not establish activation order when callbacks are submitted after releasingm.mu(internal/rollout/wakeplan.go:445). Smallest plan fix: prescribe hold publication outsidea.mu, followed by reacquisition and full admission revalidation before stopping. Sequence acknowledgement jobs at the state transition, with nonblocking submission and defined cancellation/join behavior.
- Medium — Tasks 11 and 13 contradict the flag-off constraint.
configAckFuncalso serves ordinary flag-off sync (internal/host/agent.go:1152); imposing its new timeout changes that behavior. Bucket retention is unconditional (internal/host/retention.go:26), so addingGoodVersionpins changes deletion eligibility even after disabling swaps. Task 15 is not the only exception. Smallest plan fix: explicitly authorize these exceptions or scope the new behavior to flag-on operation. Do not claim every added behavior is controlled by an armed/declined hook.
- Medium — Task 14: an existing generation directory does not prove the parent is safe. The proposed test deliberately permits parent PIDs when
g1exists. An empty leftoverg1does not move legacy processes out of the parent. CurrentensureParentmerely returns when populated, andStartChildGatedproceeds (internal/cgroup/gen.go:133,:168). Smallest plan fix: refuse direct parent processes regardless of child-directory existence; distinguish direct membership from descendant population. Propagate the refusal throughStartChildGated, and test a populated parent with an empty stale generation directory.
- Medium — Tasks 8 and 17: the signing ruling needs a stronger recovery identity. Root signing correctly closes unsigned forgery, but the proposed grant names only the build, with an in-memory replay watermark. The underlying retry clears the current restriction (
internal/rollout/manager.go:533,:539). After restart, a captured grant can clear a later failure of that same build. The ruling acknowledges this exposure; that is not closure of failure-specific authorization. Smallest plan fix: bind grants to a persisted restriction/retry epoch and persist consumption, or explicitly retain the replay limitation as an unresolved security decision. I agree with conditions on signing, conservative unresolved-intent reconciliation, and schema-2 refusal; the current reader really rejects unknown schemas (internal/rollout/failures.go:118). I agree with the owner’s claims exclusion and decline interpretation. I disagree with categorizing all remaining status work as non-defects. Coverage-only items, simulation replay, and real-box evidence may remain deferred, explicitly retaining their gate obligations.
- Low — Tasks 1–3, 14 and 17: correct task-local examples and copy instructions.
overlapEnvtakes a string, sooverlapEnv(nil)is invalid (internal/host/rollout_test.go:58).DirStore.Putreturns two values (internal/release/store.go:402).putTestRecordis absent;TestListRecordsseeds throughCreateRecord(internal/provision/provision_test.go:413). Task 3’s “signed” harness pointer is an unsigned fixture (internal/rollout/fake_test.go:352), and the proposed book clock must explicitly useh.clock.ensureParentcurrently returns nothing, requiring a signature/caller change (internal/cgroup/gen.go:127,:168). Smallest plan fix: replace placeholders with exact helpers/signatures and separate mocked pointer tests from signature verification. Add TODO-COPY markers wherever new errors can reach members; planned wake errors can pass through directly (internal/rollout/wakeplan.go:304). ReusingHeldDownRefusalalso needs correction where rollback is deliberately refused: its approved text promises rollback recovery (:47).
Read-only review of e61b858e; no files changed and no tests run.