carlos / platform Public
REJECT
Reviewed a3bf7d6c..5b6c95ed; the supplied diff matches exactly. Nothing was changed, and no tests or simulations were run. The recorded 3,000-seed pass and six caught mutations are useful evidence, but the simulation models the activator and does not exercise the production launch preparation, delayed callbacks, or failed persistence described below. Recorded results
These findings are latent until the flag is ON, most severe first:
- High — instance gates run before potentially blocking launch preparation, not at execution. swaphold.go:359, swap.go:311.
A planned wake, fallback, hold pin, or overlap successor passes its gate and enters StartStaged. The backend then reads config, prepares sockets/files, and, for nested instances, contacts root. During that work the lease can disappear, a fence can arrive, or the attempt/build can become superseded or held. Execution still proceeds: the flat path reaches exec.Command at backend_exec.go:1448; the nested path reaches startRole at backend_exec.go:1630, without another gate.
This violates §7.4, PF7, and the P5/P6 execution-bound ownership obligation. Killing the process afterward cannot undo a hold build’s migration. Smallest fix: carry the gate through StartStaged into the final launch point after preparation, covering both backends and every staged-instance caller; honour cancellation there too.
- High — a hold worker can restore its predecessor after the hold build executed. workerswap.go:101, activator.go:2770.
Worker A is replaced by hold build B. B executes and can migrate the database. Before its installation into the entry, a newer desire supersedes B. The post-exec check sheds B and leaves the old incarnation unchanged. ReplaceWorker sees gateSuperseded and calls restoreLocked(e, prev), automatically executing A.
This violates §§6.4/8.3 and P5’s hold-everywhere invariant. “Not installed” is not evidence that B never executed. Smallest fix: preserve explicit execution evidence through the respawn result; permit predecessor restoration only when the hold build provably never executed. Otherwise stop and preserve the required recovery restriction.
- High — cold-wake admission reopens before its failure is recorded. activator.go:1394, wakeplan.go:503.
Hold B executes and fails its first health check. wake emits the failure event, deletes the entry, unlocks, and closes ready; only afterward does afterWake → OnGen install HeldDown. A request scheduled in that gap creates another wake and plans B before the record exists. Planned wakes have no running scheduler slot to block it.
The observer has the same ordering weakness: it clears firstWatch at wakeplan.go:579 before delivering GenFailed. This violates §8.1’s failure-before-publication/admission ordering and O7. Smallest fix: retain an outcome/admission fence until the off-lock failure transition completes; publish failure and reopen admission afterward. Join the observer’s outcome with terminal cleanup.
- High — an old outcome can remove a newer planned wake’s failure-record protection. rollout/wakeplan.go:244, manager.go:637.
An old first-wake observer has a delayed GenCancelled. The host begins a new first wake of B with good build A. A sibling fails B; root moves the installing routes to C. The old event executes delete(m.planned, host), deleting B’s newer registration. Pass now prunes B’s failure record, and the new wake’s planCheck admits B.
This recreates simulation invariant I1 and violates §8.4. It is not a minor “three-way coincidence.” Host-keyed observing and mutable wakeRev also let old events affect newer observation/config state. Smallest fix: carry a unique wake token through WakePlan and GenEvent; clear or activate only matching state, with the config revision captured in that wake’s event.
- High — failed persistence loses failure holds across agent restart. failures.go:100, scheduler.go:203.
B fails, but the atomic file replacement fails, for example because storage is full. The transition retains the record only in memory, logs the error, and continues. Restart the agent before a successful retry: OpenFailureBook reads the previous valid file, or treats its absence as an empty book. B is eligible again, including after a hold failure.
This violates §8.4’s restart durability. The dirty flag does not close the crash window. Smallest safe fix: persist an unresolved-attempt marker before dangerous execution, refuse execution if that write fails, and clear it only after a durable outcome. Startup must conservatively reconcile or refuse unresolved markers; write failures cannot be treated as journal-only errors.
- High — losing delegation silently bypasses existing failure records. host/rollout.go:137, host/rollout.go:287.
An armed agent records a hold failure for installed B. It restarts with CARLOS_SWAP=overlap still set but delegation unavailable. swapArming declines the feature; armRollout returns before loading the book or installing refusal hooks. Legacy wake/converge paths can execute B.
This violates §§6.4/8.4 and O1’s fail-closed intent. An infrastructure prerequisite failing is not an operator clearing a failure hold. Smallest fix: leave generation containment disabled but refuse managed starts and stand down their bounce legs when the requested feature cannot arm.
- Medium — config delivery does not consistently reach activation or truthful acknowledgement. syncexec.go:615, host/rollout.go:382.
Three concrete paths remain:
- An awake native sidecar receives a changed config file, but hostBounce == nil clears Delivered. No config attempt is queued; unchanged-file passes subsequently do nothing. - An in-scope socket route outside Managed receives the global successful no-op restart. ConfigDelivered ignores it, and its ack can say Restarted:true while the old process continues. - In refusing mode, a sleeping managed exec route also receives a successful no-op; that path does not apply configTrack’s Hibernating correction.
These violate §§6.5/8.1/10. Smallest fix: separate delivery notification from legacy bounce eligibility; retain Delivered for managed sidecars, preserve the existing restart for unmanaged exec routes, and explicitly acknowledge refused sleepers as delivered-on-wake.
- Medium — a pre-exec refusal permanently consumes a host retry. queue.go:348, failures.go:200.
Retry a host in a halted B cohort. Admission clears forceBuild; staging or an execution gate then abandons the attempt before B executes. finish releases the canary but does not restore the allowance. The cohort remains halted, while another RetryHost returns false because the host already appears in Retried.
This violates §8.4’s promised next canary and the scheduler liveness obligation. Smallest fix: retain/re-arm the build-specific retry allowance on pre-exec abandonment; consume it on a meaningful executed outcome.
The following affects the box with the flag OFF:
- Low — an existing member-visible failure string changes outside the flag. workerbuild.go:36.
A worker’s generations-file publication fails with the flag unset. The shared sentinel now says build not published… instead of worker build not published…; memberSafeWakeReason passes that changed wording through. This violates index review focus 1’s unchanged legacy behavior outside the assigned exceptions. Smallest fix: preserve the existing worker wording and use a separate member-safe mapping for the new instance path.
I found no additional lock-order inversion in the reviewed scheduler paths. The single generations writer and preservation of both version and path pins are sound structural choices; they do not repair the execution and outcome-ordering gaps above.
The following judges all 35 ledger rulings. Line numbers refer to progress.md.
| Ruling | Judgment | Reason | |---|---|---| | PF1, L63 | Agree | Merged producer signatures supersede stale plan signatures. | | PF2, L64 | Agree | Compile-time interface contracts have a useful, limited purpose. | | PF3, L65 | Agree | Appending columns preserves the established scan/write ordering. | | PF4, L66 | Agree | A verified newer signed pointer is the specified retry signal; install authorization remains root’s. | | PF5, L67 | Agree with conditions | Fixed scheduler reasons are correct, but planned-wake error passthrough still needs the same protection before enablement. | | PF6, L68 | Agree | The anchor changes follow the merged implementation. | | PF7, L69 | Agree with conditions | The composed checks are right, but must reach the actual backend launch boundary, finding 1. | | PF8, L70 | Agree | Consuming the existing worker publication/gate contract avoids a second lifecycle. | | PF9, L71 | Agree with conditions | Publication refusal is abandonment, but preserve flag-off wording and do not assume startup catches later storage failures. | | PF10, L72 | Agree | Binding the legacy sidecar to the chosen staged identity is required. | | PF11, L73 | Disagree | Supersession alone does not authorize restoration after a hold build executed, finding 2. | | PF12, L74 | Agree | Extending the existing writer and retaining both pin namespaces is correct. | | PF13, L75 | Agree | Existing sweep interfaces already consume the generations file. | | PF14, L76 | Agree | One flag-independent writer configuration is the intended ownership. | | PF15, L77 | Disagree | Declining into legacy execution discards previously established failure protection, finding 6. | | PF16, L78 | Agree | Proof-mint requests must not enter the stage relay. | | PF17, L79 | Agree with conditions | Deferral is valid only while every claims-backed launch remains closed. | | PF18, L80 | Agree with conditions | The scheduler-slot transition is ordered, but cold-wake/observer outcomes still violate O7, finding 3. | | T2 fingerprint, L85 | Agree | Empty new columns must not force snapshots across the fleet. | | T2 archive canonicalization, L86 | Agree with conditions | It fixes upgrade comparisons; dropping unknown future ownership-bearing fields must remain forbidden. | | T4 slice copying, L93 | Agree | Returned records must not share mutable slices with the book. | | T4 dirty persistence, L94 | Disagree | Retrying later does not establish restart durability, finding 5. | | T5 early cohort type, L99 | Agree | This repairs a declaration-order defect without changing behavior. | | T5 adoption dedupe, L100 | Agree | Re-adopting the serving artifact has no work; restart/config remain distinct. | | T6 forced canary, L104 | Agree | A retry must still wait behind an unsettled canary. | | T8 install-by-hand, L116 | Agree with conditions | The supported same-build retry signals must be explicit; ordinary identical restamping cannot be advertised as one. | | T8 sleeper/prune scope, L118 | Agree | Sleepers need no redundant config attempt, and every installing route retains the record. | | T9 verdict floor, L123 | Agree with conditions | Skipping B is safe only before execution and with later paced adoption still possible; document the additional 20-second policy. | | T10 no-good bootstrap, L128 | Agree | This preserves the explicit bootstrap exception without lifting host-specific hold-down. | | T11 respawn deviations, L134 | Disagree | Omitting execution evidence makes the supersession restoration unsafe, finding 2. | | T14 refusal hooks, L145 | Agree with conditions | Standing down convergence is correct; an uncaptured worker must also be refused rather than recycled from the live link. | | T14 refusing config ack, L149 | Agree with conditions | Awake refusal is correct, but the actual sleeper path must set Hibernating, finding 7. | | T15 relay refinement, L155 | Agree | Any changed install stamp ends the recorded request; moves remain separate. | | T10 planned retention, L161 | Disagree | “Any event for the host” can clear a newer plan, finding 4. | | T10 early registration, L163 | Agree with conditions | Early registration closes the slow-read window only when subsequent removal is token-scoped. |
For the deferred minors, Merge means fix before this branch lands, Flag means before enabling anywhere, and Defer means safe to carry. Related test gaps are grouped on one line.
| Ledger item | Triage | |---|---| | T1 L83: whitespace/near-miss flag cases; stale surface-test comment | Defer. | | T2 L88: unknown/duplicate/case-variant JSON keys; future timer-field compatibility; isolated replay-refusal test | Defer, retaining the unknown-ownership-field condition above. | | T3 L90: older policy load overwriting a newer result | Flag: serialize or version cache fills. | | T3 L90: refresh backoff and policy-loader edge-case tests | Flag: bound repeated failed reads and cover missing/error distinctions. | | T3 L90: literal default hold value | Defer. | | T4 L97: persistence under the book lock and missing durable-write protocol | Merge: finding 5; keep the in-memory safety transition ordered. | | T5 L101: running-attempt, config/backoff and deferral test gaps | Flag. | | T5 L101: wantConfig("") behavior | Defer: production revision inputs should remain nonempty. | | T6 L107: abandoned forced attempt loses retry | Merge: finding 8. | | T6 L107: older non-canary failure interacting with a retried canary | Flag: establish and test the retry-generation boundary. | | T6 L107: retry bound to current wantBuild | Defer/closed: current manager binding occurs under the same scheduler lock as book clearance. | | T6 L109: full-capacity admission postpones later view updates | Defer: bounded by the next admission pass. | | T6 L109: cohort retention/later-wave canary behavior | Defer: retain settled state for the same cohort; explicit retry must reset it. | | T6 L109: unbounded test loop | Merge: bound its failure path on this shared box. | | T6 L109: missing concurrency-one/two-cohort coverage | Flag. | | T6 L109: unrelated attempt consuming retry flag | Flag: test alongside finding 8 and consume only the matching adoption allowance. | | T7 L113: delivery-order, addr and removal coverage | Flag: include native sidecars and the real host wiring. | | T7 L113: claims-enabled delivery coverage | Defer until claims launch opens, then required. | | T7 L113: configBackoff(0) documentation | Defer. | | T8 L120: unbounded ack write holding a slot | Flag: bound/cancel publication and test shutdown with a blocked writer. | | T8 L120: substring reason mapping | Flag: replace fragile classification where necessary during plan 6’s reason audit. | | T8 L120: duplicated halted-event code | Defer. | | T8 L120: scheduler state never shrinks | Defer/partly closed: departed hosts/config tracks are removed; idle app/cohort collection can follow. | | T8 L120: execution does not recheck Managed | Flag: revalidate eligibility before dispatching against a changed route. | | T8 L120: synchronous policy/pointer reads on the tick | Flag: bound latency so one store failure cannot stall convergence. | | T8 L120: missing shutdown test; timing-dependent sleeper regression | Flag. | | T9 L126: claims refusal is log-only; claimed result lacks Worker | Defer while claims remain closed. | | T9 L126: WakeWorker timeout shorter than successful fallback | Flag: align caller and operation budgets. | | T9 L126: raw planned-wake error passthrough | Flag: sanitize before member publication; plan 6 wording alone is insufficient. | | T9 L126: stale unexpectedExit | Defer/closed for replacement: T11 resets it for its observation. | | T9 L126: worker fallback event assertions | Flag. | | T9 L126: repeated drift notification | Defer/closed: Manager.Nudge coalesces it. | | T9 L126: missing short-window gate-refusal assertion | Merge: add with finding 1’s execution-bound tests. | | T10 L132: pointer read uses agent rather than wake context | Flag: pass the wake’s cancellation/deadline. | | T10 L132: repeated staging refusals/root touches | Defer: preserve existing throttling. | | T10 L132: missing cohort-halted event before scheduler registration | Flag. | | T10 L132: panic cleanup in Nudge; redundant condition | Defer. | | T10 L132: config active before first-wake settle | Defer: health-passing execution can activate config; promotion to good still waits for settle. | | T10 L132: missing hold/no-good test | Flag. | | T10 L164: late event clears newer planned entry | Merge: finding 4. | | T10 L169: inaccurate moved-twice refusal wording | Flag: plan 6 inventory/review. | | T11 L135: blocking serving callback | Defer/implemented mitigation: agent wiring uses the ordered asynchronous writer; strengthen its blocked-write test before Flag. | | T11 L135: untested admitting branch of CoalesceRecycle | Flag. | | T11 L135: reused em-dash error message | Flag: replace/review the new attempt-facing use. | | T11 L135: successful parked one-shot never records good | Flag: §6.5 treats its clean exit as success. | | T12 L140: bucket retention omits GoodVersion | Flag: preserve recoverable good artifacts across retention. | | T12 L140: outdated adoption comment | Defer. | | T12 L140: hold publication occurs after stopping incumbent | Flag: publish the chosen pin before causing the outage. | | T12 L140: missing route makes generation-pin resolution fail box-wide | Defer: fail-closed is preferable; follow up with retained self-contained identities. | | T12 L140: lifetime-long plan pins; duplicated filtering | Defer: these over-retain rather than omit live builds. | | T13 L142: briefly stale serving/awake status; missing mid-wake marker | Flag: ensure deploy-watch completion cannot race these states. | | T13 L142: only cancellation closes observation in tests | Flag: cover every terminal event. | | T13 L142: observation keyed only by host | Merge: finding 4’s token fix. | | T13 L142: unknown config error becomes “health” | Flag: correct reason classification with plan 6. | | T13 L142: shared report pointer | Defer, provided published reports remain immutable. | | T14 L152: all statuses count as held on box | Defer: conservative retention is correct; fix the comment later. | | T14 L152: weak slow-serving-write test | Flag. | | T14 L152: refusing recycle with no captured build uses live link | Flag: refuse that spawn. | | T14 L152: loose nudge throttle; misleading refusal log | Defer. | | T14 L152: unmanaged config no-op | Merge: finding 7. | | T14 L146: populated legacy parent not rejected | Flag: implement the missing containment transition guard. | | T14 L153: absent SelectedRestart | Defer while claims remain closed; required before enabling on a claims-on box. | | T15 L157: unreadable baseline can retain relay indefinitely | Flag: provide a bounded/revalidated exit condition. | | T15 L157: moves call-site test | Flag. | | T15 L157: relay state exists only in memory | Defer: normal blocked-head observation can reconstruct it. | | T16 L165: self-derived I3 exemptions, unproven secondary checks, early-return holes | Flag: strengthen independent liveness assertions. | | T16 L165: omitted running-attempt refusal, hidden stale-row/callback interleavings | Merge: add deterministic regressions for findings 1–4. | | T16 L165: copied timing constants | Defer. | | T16 L165: unknown mutant silently succeeds; script leaves scratch | Merge: fail unknown selections and clean owned scratch on exit. | | T16 L165: nondeterministic replay | Flag: stabilize event ordering or record enough scheduling information to reproduce failures. |
The carried obligations resolve as follows:
| Obligation | Disposition | |---|---| | O1: usable containment, no populated legacy parent | Open: finding 6 before merge; populated-parent guard before flag. | | O2: planned/legacy-sidecar staged identity | Implemented for the managed planned paths; retain the documented unmanaged boundary. | | O3: claims-backed launches remain refused | Satisfied on this base; do not weaken it during fixes. | | O4: wrap pre-body hostguard refusals | Deferred only until the isolated claims launch opens. | | O5: abandonment backoff | Implemented; retry allowance still needs finding 8. | | O6: failure identity comes from dispatch | Implemented. | | O7: held-down admission before reopening | Open: cold wakes and observers need finding 3. | | O8: member-safe failure reasons | Scheduler events improved; planned-wake passthrough remains a pre-flag obligation. | | O9: extend the one generations writer | Implemented. | | T3/T4 carries: uncertain demand means hold; missing-policy distinction; failure timestamp; complete prune scope | Implemented, subject to findings 4–5’s retention/durability corrections. | | T5/T6 carries: backoff, repeated signed retry, atomic finish/failure, config failure accounting, canary settle | Implemented in the principal scheduler paths; retry-abandonment remains open. | | T7 carry: older activation must not reset newer config failures | Implemented in configTrack; wake events still need immutable token/revision association. | | T8 carries: off-lock callbacks, serialized delivery after file write | Implemented structurally; preserve that lock order while fixing outcome fences. | | T11/T13 carries: recycle coalescing, cheap serving callback, departed-host pruning, nonblocking status nudge | Wired; the identified lifecycle/coverage work remains before flag. | | T14→T15: relay wiring and shared marker helper | Implemented. |
Beyond plan 6, enabling CARLOS_SWAP anywhere still owes:
- All merge blockers above, plus the Flag items in the triage.
- The populated-legacy-parent guard and real containment evidence: generation placement, parent limits, termination proof, and crash-surviving children.
- The explicitly carried D1 daemon-reload measurement, real-unit KillSidecar/control checks, and proof that unsupported nondefault
CARLOS_OPT_DIRlayouts fail closed. Ledger:19 - Crash/restart evidence for failure persistence, execution-bound gate regressions using production backend preparation, and delayed-observer/rewake regressions.
- Shutdown evidence covering scheduler attempts, first-wake observers, blocked config publication, and serving publication.
- Final-tip repository gate and supported cross-build evidence after fixes. Earlier task-level passes and the final simulation do not establish that whole-branch gate.
- Claims-on boxes remain excluded until isolated launch, selected config restart, pre-body classification, and the deferred claimed-wake details are completed.
The inherited flag-off descendant-proof limitation remains recorded technical debt; it is not evidence that generation containment is safe to enable.