fix(manager): retry failed static reconciliation - #1302
Conversation
Review — independent cold review at
|
Addendum — withdrawing one Q2 sub-finding (the mark-count remark)Correcting the durable record: my Q2 note claimed the brief's "25 marks vs baseline 27" was "a reporting imprecision" because "this suite has 25 The mechanism I missed. A "mark" is not a suite
What still holds: the earliest-red conclusion for the named cell General lesson for the next re-derivation: a progress counter that scans a whole transcript measures the transcript, not the test. When marks and cells disagree, the gap is usually the code under test printing in the same |
0644898 to
ec6f1f7
Compare
|
BLOCK on reviewed sha Independent review of that exact head. Verdict was formed before reading any other review comment on this PR. I disagree with the existing APPROVE on this sha: the two items below are product defects, not merge-gate weather. The PR-owned patch at live head 1. Redrive engine (attacked, not only read)Four attempts is real. Fresh durable re-read is real on the retry path. Live owner / sibling. BLOCK: Adversarial probe against a real JWT
That is work after shutdown, including a second exact-op terminal, plus boot continuing to re-register after 2. Hand-merged status contract (coherence, not parent-text)Both Reached states in the redrive run: BLOCK: cluster document revision stayed at 10 while the status output digest changed.
The same file already treats a changed 3. Suites
Ran:
Unnamed suites I picked:
Also ran Did not run 4. Mutation mark countStartup suite has 25
5. Scope and hygieneBody ends with Inventory sentinels: CI at
|
|
Transfer proof for the current-main fold to
|
APPROVE
|
|
Independent re-review after re-point. This verdict binds only APPROVE Confirmed live head with This SHA is the fold of Independently recomputed Shutdown control still holds on this tree. CI at this exact SHA. Workflow presence is listed separately from job conclusion. Incomplete work is unmeasured, not green.
I did not run Residuals, not blockers:
|
Summary
statusandcotal status --componentsplanStaticSlotResume, and the existing deterministic exact terminalConvergence and safety
The status snapshot is not authority. Before every re-drive the manager re-reads the slot from broker KV and runs the same planner again. The retry reuses
retireOpId(lifecycleUid), sorunStaticTerminalpasses its own same-op frozen retirement and resumes the idempotent head transition. A different retirement op or another frozen operation is reported asrefused-foreignand is never force-cleared.The delays are scheduling only and never release a fence. The durable non-retired slot and exact-op state keep refusing alias reuse between attempts. No new lifecycle or second terminal operation is minted.
The 1s retry covers a one-shot control-plane or eviction blip. The 5s and 30s spacing gives a recovering broker more time without hammering a persistently unavailable authority. Four total entries are a finite per-process budget. A failure lasting beyond about 36 seconds becomes
retry-exhausted; the alias stays unavailable and needs a manager restart. The next process receives a fresh budget because its counters are in memory and the durable row remains the sole authority.recoveredremains visible until the next static reconciliation sweep, then clears. The literal dispositions, next retry time, error, and remedy are visible in status and component health.Scope of #774
This PR addresses the reported static-lifecycle reconciliation wedge: failed terminals now produce a failed aggregate, remain visible in current health, and receive bounded same-process re-drives. It does not implement general desired-fleet convergence from a last-applied user manifest or relaunch missing declared seats on manager boot. That broader boot-convergence scope remains open, so #774 stays open and this PR only references it.
Relationship to #1274
This change reports whether a reconciliation attempt is running, waiting, recovered, refused, or exhausted. It does not independently project whether static footprint cleanup completed. The durable cleanup marker and a general read verb remain #1274's scope.
Changeset
Patch. This adds recovery and operator visibility without changing lifecycle wire semantics. The fixed package group will version every package together; the changeset names the manager, CLI, and connector-core docs bundle that changed directly.
Verification
pnpm typecheckcompleted across the 27 TypeScript workspace projects. The 28th project,@cotal-ai/example-04-frontier-faces, is JS-only and skipped by the recursive typecheck.pnpm smoke:manager-reconcile-redrivepassed 30 checks against a real authenticatednats-serverand in-process Manager. Its shutdown control gates the first exact terminal, provesstop()waits for it, proves the serial sweep does not start the later orphan, proves startup leaves no manager service registered after stop completes, and proves a later sweep is refused by the stop fence.pnpm smoke:manager-reconcile-startuppassed 25 checks.status serves while later orphan rows remain ACTIVE: the baseline completed with 27 progress marks, while the mutant reached 25 marks and failed that cell rather than an earlier one. Progress marks are✓matches across combined stdout and stderr, so these totals include the manager's own reconcile progress lines as well as suite cells. The earliest-red result also follows independently from the non-fail-fast check order: the only earlier cell still passes because the awaited sweep terminalizesorphan-0, while the named cell requires the status service to answer with the final orphan still active. The anchor targets the structuralstartupReconciledeclaration and branch, not the catch message text.main,manager-service-contract.tspreserves both the custody field added onmainand this PR’sstaticReconciliationfield.pnpm smoke:manager-servicepassed 25 checks.pnpm smoke:manager-service-invokepassed 12 checks, including generic resolution of manager cluster document revision 11 after thestatusoutput digest changed.stop waits for an accepted startup reconciliation terminal,the shutdown fence prevents the serial sweep from starting a later terminal, andstartup cannot publish the manager service after stop completes.static reconciliation status advances the manager cluster revisionwith 13 marks.node scripts/mutation-proof.mjs --config implementations/manager/smoke/fixtures/manager-reconcile-redrive.mutations.jsonkilled both the aggregate-report and re-drive mutations at their named cells.reconcile-startup.jsonmutation 0 killed the serial-start mutant atstatus serves while later orphan rows remain ACTIVE, with 25 progress marks against a 27-mark green baseline. Progress marks are✓matches across combined stdout and stderr, so these totals include the manager's own reconcile progress lines as well as suite cells. The non-fail-fast check order and the passing earlierorphan-0cell independently establish that this named cell is the earliest red. The anchor targets the structural startup reconciliation assignment and branch rather than the operator message text.pnpm smoke:mutation-fixtureschecked 1,758 anchors with zero dead or ambiguous anchors.pnpm smoke:gate-inventorypassed.pnpm smoke:ci-fragmentspassed.pnpm smoke:required-arg-seampassed after updating the attributed 119/88 to 124/92 call-site count.pnpm smoke:flag-inventorypassed.pnpm check:docs-voicepassed.pnpm check:docsbundlepassed.pnpm changeset statusreports the fixed package group patch plan.pnpm smoke:component-healthwas attempted after its build. Under concurrent local validation it first reached the final delivery cell and observed the holder before its ready lease appeared, then a serial rerun reached the web cell after its subprocess exceeded the command timeout. The manager component cells passed locally, including the new static-reconciliation fallback and the distinction between present-not-serving and absent. Exact-head CI then completed all four Linux smoke shards green. Its mutation reproof rancomponent-healthwith a 17-mark green baseline and killed all four mutants at their named cells.The broader changed-source mutation workflow did not complete: the configured 60-minute job limit cancelled it while it was still traversing the large
manager.tsfixture intersection, before it reachedreconcile-startup.json. Its log already contained unrelated timed-out, inconclusive, and ungradable fixture verdicts. The focused committed-head startup proof above is the issue-specific mutation result; the aggregate changed-source workflow is not claimed green.Refs #774