Skip to content

D-MBX-A6-P4: cycle loop-closure driver — sparse seal/apply + MUL-gate thought seam (control-loop contract) - #879

Merged
AdaWorldAPI merged 6 commits into
mainfrom
claude/medcare-rs-continue-ufsazd
Aug 2, 2026
Merged

D-MBX-A6-P4: cycle loop-closure driver — sparse seal/apply + MUL-gate thought seam (control-loop contract)#879
AdaWorldAPI merged 6 commits into
mainfrom
claude/medcare-rs-continue-ufsazd

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Aug 2, 2026

Copy link
Copy Markdown
Owner

What this is

Makes the merged #878 persist_sink cycle/WAL bootstrap load-bearing — its first caller — and closes the cycle control loop:

owners cast sparse intents → seal (one WAL write, Vn+1) + expose the sealed
paired-transition set → apply ONLY the sealed sparse transitions (represented
owners advance one legal step + watermark; unrepresented owners byte-identical)
→ CognitiveWork runs the MUL gate → owner_adapter casts the next intent →
held/Hold owners reschedule → loop → recover

Honesty ledger (what this PR proves vs does NOT)

  • Control-loop contract: PROVEN — 19 falsifiers over contract-probe fakes.
  • Actor-owned production wiring: NOT provenMailboxFleet + its HashMap impl is the probe/registry fleet; bridging the sealed sparse set into KanbanActor-owned state is open. Per the ratified sparse-cycle ruling, apply is writer-fires-inline (no message bus) by design.
  • cognitive-shader-driver / MailboxSoA thought: NOT proven — the P4c thought body is the real MUL gate (gate_decision_i4advance_on_gate), but its qualia/mantissa inputs come from a caller extractor (the deferred MailboxSoaView::qualia() seam), not a live SoA dispatch.
  • Durability: FAKE — contract-probe WalSink until the concrete LanceShardSink lands (compile+test green ≠ storage proven).

The load-bearing rule (enforced in code)

A DatasetVersion is global knowledge, NOT permission to advance every mailbox. Only owners with a sealed paired_move advance; the version tick never fans a step across the fleet (E-COMPLETE-CYCLE-IS-PHYSICALLY-SPARSE-…-1, E-D-MBX-SPINE-IS-STRAIGHT-TRACK-…-1).

Review round (grain-of-salt audit, commit 71d1db1)

Each finding was verified against code; all accepted items were real defects:

  1. Retry-safe seal — a WAL failure previously LOST the drained cycle. seal_cycle → Result<SealedCycle, Box<SealFailure>> now returns the complete frozen cast set byte-identical for retry. Falsifier: failed commit → zero owner mutation → same-cycle retry → exactly one version, no cast lost/duplicated.
  2. Restart-stable stream positionsstream_position = CastId was the P3d-documented trap ("cast_id is provenance only"): a reconstructed BatchWriter restarts at 0 and recover_and_apply silently skips positions ≤ watermark. collect_casts now takes the caller's durable position_base cursor; SealedCycle.next_position_base carries it forward. Restart falsifier pins the exact failure mode.
  3. Watermark-coupled applyapply_sealed_transitions advances the per-owner recovery watermark WITH the phase (one rule shared with recovery). Falsifier: normal apply → crash → recovery replays NOTHING (previously: replay → permanent StalePhase stall).
  4. ≤1-move/owner enforced PRE-seal — the old deferred counter sealed a durable move and then never applied it (recovery WOULD — divergent semantics). Extras (same cast or later casts; also kills the silent moves.first() truncation) return as HeldIntent, re-staged via restage_held. Sealed set == applied set; recovery-agrees falsifier.
  5. Mid-apply prefix preservedErr((partial, cause)), mirroring recover_and_apply; the prefix's watermarks survive.
  6. Hold = reschedule, never strandCognitiveWorkOutcome.held_owners + run_cognitive_work[_gated]_over re-poll; falsifier wakes a Held owner on a later cycle.
  7. recover_fleet partitions history once — O(history + Σtails), not O(fleet×history).
  8. P4d honesty — wait-free at the cast/cycle boundary (sequential pass); strengthened falsifier: two represented owners, A unfinished, B casts + advances without waiting. Concurrent per-owner execution is the actor leg, explicitly out of driver scope.

Declined with reason: routing P4b through KanbanActor mailboxes — contradicts the operator-ratified writer-fires-inline sparse ruling (no message bus for P4a/P4b). The honesty half is taken in docs instead (MailboxFleet is not a production-ownership claim).

Falsifiers (19 lib tests, cargo test -p lance-graph-supervisor --features cycle-driver)

  • 64k/17 headline — 65 536 mailboxes, 17 sealed → exactly 17 advance, 65 519 byte-identical, one WAL write, zero dataset reads, 17 watermarks.
  • Failed-seal → byte-identical retry · restart-stable positions across writer reconstruction · normal-apply-advances-watermark (no replay after crash) · held-move-lands-next-cycle + recovery-agrees · multi-move no-truncation · mid-apply prefix preservation.
  • MUL-gate discriminates — three distinct outputs for three inputs (Flow→Evaluation / Block→Prune / Hold→rescheduled-and-woken), None at absorbing columns.
  • P4e idempotence + load-bearing-watermark negative control · P4f O(dirty)-not-O(fleet) (640 resolves over a 64k fleet).

clippy (feature) + fmt clean; default (no-feature) supervisor build unchanged. Mints no new semantic/temporal/rung/witness type — composes SweepSlot/CycleFrame/KanbanMove/DatasetVersion/PersistError/StrategyOutcome/recover_and_apply/emit_bootstrap_intent/MailboxSoaOwner/gate_decision_i4.

Plan: .claude/plans/cycle-loop-closure-driver-v1.md (status synced). Board: STATUS_BOARD D-MBX-A6-P4 + LATEST_STATE honesty ledger.

🤖 Generated with Claude Code

claude added 5 commits August 2, 2026 08:46
…#878 follow-up)

Documentation-only. No Rust code, tests, public APIs, persist_sink.rs,
temporal.rs, or the persistence implementation change.

1) Sparse-delta ruling (persistence-cycle-wal-bootstrap-v1.md §2, NEW):
   "complete logical cycle ≠ full physical dataset rewrite". A globally-complete
   cycle persists ONLY its coalesced dirty-row delta + required durable
   transition metadata; unchanged rows are inherited from the sealed base
   version, never re-serialized because they participated. Records the verbatim
   storage invariant, the participation-vs-mutation split (a no-mutation
   participant needs no 512-byte row), the honest in-memory payload-duplication
   limitation (concrete sink must not persist both per-landing bytes AND the
   coalesced image), the capacity/backpressure ruling (dense cycle = explicit
   capacity event), and 5 concrete-sink falsifiers (sparse / no-op-policy /
   coalescing / dense-capacity / retention). Status: RATIFIED architecture,
   UNIMPLEMENTED in a concrete Lance sink. Preserves the horizontal(temporal.rs)
   / vertical(DatasetVersion) / revision.rs split — density only. Sections
   renumbered (§2 inserted; §3–§7 shifted, all internal §-refs updated).

2) Loop-closure driver plan (cycle-loop-closure-driver-v1.md, NEW): the seam
   that makes the merged persist_sink load-bearing at 64k — persist_sink has
   zero production callers today, so the loop is open. Closes collect →
   persist_cycle → sealed version → sync inline fan-step (on_version +
   try_advance_phase, NOT 64k async drive_once) → CognitiveWork → owner_adapter
   → next cycle. Mints no new types. Deliverables D-MBX-A6-P4a..f, probe-first.
   Home: lance-graph-supervisor.

Board: EPIPHANIES E-COMPLETE-CYCLE-IS-PHYSICALLY-SPARSE-NOT-A-FULL-REWRITE-1
(prepend); INTEGRATION_PLANS cycle-loop-closure-driver v1 (prepend); STATUS_BOARD
D-MBX-A6-P4 row + P3d flipped to Merged (#878, reshaped to cycle/WAL + sparse
ruling). Branch restarted from main after #878 merged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
…ed-transition application

Architecture/plan reconciliation before implementing the cycle-loop closure.
Documentation-only — no Rust code, tests, public APIs, or persistence
implementation changed (verified: zero .rs in changeset). Crate deps verified
against Cargo.toml, not asserted from memory.

1) THE CORRECTION (ChatGPT feedback, accepted — it caught a real same-session
   contradiction). The loop-closure plan's P4 had the supervisor FAN
   NextPhaseScheduler::on_version across the whole fleet → advance every
   non-absorbing mailbox per sealed version. That makes almost the entire fleet
   dirty every cycle, directly violating the sparse-cycle ruling
   (E-COMPLETE-CYCLE-IS-PHYSICALLY-SPARSE-NOT-A-FULL-REWRITE-1). Corrected model
   throughout §2/§3/§4/§6: a DatasetVersion is GLOBAL KNOWLEDGE, not permission
   to advance every mailbox. Owners think over Vn; owners that produce material
   updates emit sparse fire-and-forget intents; planner collects/coalesces/seals
   (one WAL → Vn+1) and exposes the sealed paired-transition set; the supervisor
   applies ONLY the sealed sparse transitions (represented owners advance one
   legal step; unrepresented owners byte-identical), inline (no dataset re-read;
   NOT 64k async drive_once). on_version becomes the intent-time lowering policy,
   not an apply-time fan; SymbiontBoard.step-advances-every-board is the SLICE
   shape-prover, not the production rule. Interim rule: <=1 durable phase
   transition per owner per sealed cycle. P4b falsifier is now the sparse shape:
   64k mailboxes / 17 sealed transitions -> exactly 17 advance, rest
   byte-identical, no second dataset read, one version. P4a..P4f re-scoped to
   supervisor-side sparse application.

2) RATIFIED OWNERSHIP MAP (§9, verified deps): contract = canonical types (zero
   fleet ownership); cognitive-shader-driver = MailboxSoA type/layout home +
   anatomy (not the runtime lifecycle); planner = decides + persistence contract
   (never mutates a supervisor-owned SoA, never deps supervisor); supervisor =
   exclusive runtime owner + P4 loop + applies only sealed sparse transitions;
   lance = storage substrate + external-reader subscription + future
   LanceShardSink. Dep direction verified: supervisor->contract, planner->contract,
   planner does NOT dep supervisor/symbiont/rs-graph-llm; supervisor->planner is
   the planned acyclic P4 edge; shader has an optional feature-gated planner dep
   (debug DTOs, not fleet ownership). NO cycles found.

3) ADJACENT-CRATES DOCTRINE (§10): symbiont = golden-image + bystander research
   lab (forbidden as authoritative owner/scheduler/WAL/version/required dep);
   rs-graph-llm = optional capability basement (client/capability provider
   returning Outcomes, never owns the standing wave); ogar-* = AST/declaration/
   adapter basement (describes behaviour, never owns the cycle). Subagent
   anti-drift guardrail with STOP+report triggers (§11).

4) DRIFT AUDIT: the only genuine conflict was the P4 fan-step introduced this
   session (fixed). Other 'fan'/symbiont hits are corrected text, append-only
   AGENT_LOG history, or SymbiontBoard-slice / ractor-compile-time-argument
   descriptions in sibling plans (not production-ownership claims; now governed
   by the §10 doctrine).

Board: EPIPHANIES E-D-MBX-SPINE-IS-STRAIGHT-TRACK-VERSION-IS-NOT-A-FLEET-STEP-SIGNAL-1
(prepend); INTEGRATION_PLANS + STATUS_BOARD P4 row corrected to sparse.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
…st_sink's first production caller)

Closes the ZERO-caller gap on the merged #878 persist_sink: nothing drove the
seal→apply loop, so the sealed version never advanced any owner. New module
`lance-graph-supervisor::cycle_driver`, behind the `cycle-driver` feature
(optional ONE-WAY `lance-graph-planner` path-dep — planner never deps supervisor,
verified acyclic; default supervisor build stays light, no planner/ractor).

Mints NO domain types — composes the shipped organs:
- P4a: `collect_casts(writer, cycle, row_of)` drains a `BatchWriter<Vec<u8>>`'s
  staged casts into `Vec<SweepSlot>` (one slot/cast; stream_position = CastId;
  paired_move = first intended move). `seal_cycle(sink, frame, casts)` reads out
  the SPARSE `SealedTransition` set (only slots with a move, stream-ordered) then
  `persist_cycle` -> exactly one WAL write, one DatasetVersion.
- P4b: `apply_sealed_transitions(fleet, &SealedCycle)` iterates ONLY the sealed
  sparse set, resolves each owner via the `MailboxFleet` trait (blanket-impl'd
  for HashMap<MailboxId, O>), applies one legal `try_advance_phase`; EVERY
  unrepresented owner stays byte-identical (never resolved). Interim rule: <=1
  durable transition per owner per cycle (2nd same-owner move -> `deferred`);
  unknown owner -> `missing` (counted, not a crash); StalePhase/OwnerMismatch
  guards; reads NO dataset (version already sealed — no scan_sealed/versions/
  drive_once). `run_cycle` = P4a->P4b convenience.

The load-bearing rule, enforced in code: a DatasetVersion is GLOBAL KNOWLEDGE,
NOT permission to advance every mailbox — only the sealed sparse set advances
(E-D-MBX-SPINE-IS-STRAIGHT-TRACK-VERSION-IS-NOT-A-FLEET-STEP-SIGNAL-1 +
E-COMPLETE-CYCLE-IS-PHYSICALLY-SPARSE-NOT-A-FULL-REWRITE-1).

Tests: 7 cycle_driver lib tests (10 total in the crate), headline = the 64k/17
falsifier — 65_536 mailboxes, 17 sealed transitions -> exactly 17 advance, the
other 65_519 byte-identical, one WAL write, ZERO dataset reads. Plus
one-WAL-write amortization, empty-sparse-set-advances-nobody, interim-defer,
StalePhase corruption, missing-owner-counted, run_cycle round-trip. clippy
(--features cycle-driver) exit 0, fmt clean; default (no-feature) build
unchanged. Durability leg stays the contract-probe fake (FakeWalSink) — control
loop closed, storage NOT proven (Ladybug rule); concrete LanceShardSink still
deferred.

Cargo.lock updated for the new optional supervisor->planner dep. Plan
`.claude/plans/cycle-loop-closure-driver-v1.md`; STATUS_BOARD D-MBX-A6-P4 ->
P4a+P4b Shipped (slice); LATEST_STATE prepended. Remaining: P4c (CognitiveWork
thought body + cast round-trip), P4d/P4e/P4f.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
… driver (seal→step→think→cast→recover)

Extends the P4a/P4b driver in `lance-graph-supervisor::cycle_driver` to the full
control loop. Still mints NO domain types — reuses StrategyOutcome,
owner_adapter::emit_bootstrap_intent, recover_and_apply, LandedSlot.

- P4c `run_cognitive_work(fleet, applied, writer, think)`: owners that just
  entered CognitiveWork run a PLUGGABLE thought seam
  `think(&Owner) -> Option<(StrategyOutcome, payload)>` (NOT the shader) and route
  the Outcome into the next cycle's casts via owner_adapter (bootstrap-sentinel
  rebind → write-on-behalf cast). No mailbox mutation (the step is P4b, post-seal).
  MailboxFleet gained a read accessor `owner()`.
- P4d wait-free: a completed owner casts + advances with no synchronous neighbour
  wait; an incomplete owner never blocks a completed one (structural — fire-and-
  forget cast, no per-owner barrier; the cycle boundary is the WAL-amortization
  barrier, not a neighbour wait). Proven by falsifier.
- P4e `recover_fleet(sink, fleet, ids, watermarks)`: composes recover_and_apply
  per owner over scan_sealed; replays only the pending tail above each owner's
  durable watermark (idempotent); keeps the earned watermark on a mid-owner error.
  FleetRecovery{total_applied, owners_recovered}.
- P4f sparse-routing scale probe: CountingFleet proves apply cost is O(dirty),
  not O(fleet) — 640 owner-resolutions over a 65_536-owner fleet.

11 cycle_driver lib tests green (--features cycle-driver): the 64k/17 headline +
P4c round-trip (a CognitiveWork Outcome cast in cycle N advances the owner one
further legal step in N+1) + P4d wait-free + P4e idempotence with a load-bearing-
watermark NEGATIVE CONTROL (watermark lost → acyclic re-drive StalePhase-stalls)
+ P4f O(dirty). clippy clean on cycle_driver.rs, fmt clean; default (no-feature)
supervisor build unchanged. The test FakeWalSink now stores landings for P4e.
Durability leg still the contract-probe fake — control loop closed, storage NOT
proven (Ladybug rule); concrete LanceShardSink deferred.

The MedCare first-thought loop is code-complete on the control side. Remaining
before a real first thought: (a) a concrete LanceShardSink (durability, gated on
crash falsifiers) and (b) a real CognitiveWork thought body plugged into the P4c
seam (the shader/StyleStrategy — exists). STATUS_BOARD D-MBX-A6-P4 → P4a–P4f
Shipped (slice); LATEST_STATE prepended.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
The P4c CognitiveWork thought body was a pluggable seam; wire the REAL
shader — the MUL cognitive gate — into it, minting no new decision logic.

- shade_owner(owner, qualia, mantissa, reliability): reads the owner's
  current phase, runs contract::mul::i4_eval::gate_decision_i4 (the i4
  TrustTexture x FlowState gate), lowers via KanbanColumn::advance_on_gate
  (Flow->forward, Block->Prune-where-legal, Hold->rest). Composes
  kanban_actor::mul_target for the driver. Returns a bootstrap-sentinel
  StrategyOutcome so owner_adapter rebinds + casts write-on-behalf; no
  mailbox mutated (the durable step is P4b, next cycle).
- run_cognitive_work_gated: the shader-wired form of run_cognitive_work;
  a caller-supplied read_gate extractor supplies (qualia, mantissa,
  reliability, payload) and the gate decides. Delegates to
  run_cognitive_work (single routing path).
- The qualia seam: MailboxSoaView does not yet expose qualia() (deferred);
  P4c is the first consumer, so the extractor bridges it without touching
  the trait — the MailboxSoa contract stays unchanged.

Tests: +3 (11 -> 14). shade_owner Flow/Block/Hold discriminate (three
distinct outputs), absorbing-column yields None (DAG respected), and a
gated round-trip proves a Flow-qualia owner casts + advances to Evaluation
next cycle while a Hold-qualia owner rests at CognitiveWork. clippy+fmt
clean; default build unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This change adds a feature-gated cycle driver. It seals staged casts into one WAL cycle, applies sparse owner transitions, stages cognitive-work intents, evaluates MUL gates, and performs watermark-based fleet recovery. Documentation records the architecture and remaining concrete sink limitations.

Changes

Cycle loop closure

Layer / File(s) Summary
Architecture and integration contracts
.claude/board/*, .claude/plans/*
Documents the cycle-driver flow, sparse persistence rules, ownership boundaries, recovery requirements, and implementation status.
Cycle driver wiring and sparse application
crates/lance-graph-supervisor/Cargo.toml, crates/lance-graph-supervisor/src/lib.rs, crates/lance-graph-supervisor/src/cycle_driver.rs
Adds the feature, cycle contracts, cast collection, single-cycle sealing, and legal sparse owner transitions.
Cognitive work, MUL gating, and recovery
crates/lance-graph-supervisor/src/cycle_driver.rs
Adds intent staging, qualia-based gating, bootstrap handling, and watermark-based fleet recovery.
Cycle-driver validation
crates/lance-graph-supervisor/src/cycle_driver.rs
Adds fake persistence and tests for sparse execution, scale, gating, round trips, and recovery idempotence.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BatchWriter
  participant CycleDriver
  participant WalSink
  participant MailboxFleet
  BatchWriter->>CycleDriver: Drain staged casts
  CycleDriver->>WalSink: Persist one sealed cycle
  WalSink-->>CycleDriver: Return sparse transitions
  CycleDriver->>MailboxFleet: Apply represented transitions
  MailboxFleet-->>CycleDriver: Return application counts
Loading

Possibly related PRs

Suggested reviewers: claude

Poem

I hop through cycles, neat and bright,
Seal sparse casts before the night.
Owners move when records say,
Quiet mailboxes stay in place.
MUL gates guide the thought’s next flight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the cycle loop-closure driver and its main sparse seal/apply and MUL-gate changes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 4 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c2134c1. Configure here.

.map_err(PersistError::Illegal)?;
applied.push(step);
advanced.insert(t.owner);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deferred moves never advance again

Medium Severity

apply_sealed_transitions (and thus run_cycle) applies only one sealed transition per owner per cycle, deferring any subsequent ones. These durable, deferred transitions are not re-evaluated or applied in subsequent normal cycles, effectively stalling them until a recovery scan is performed.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c2134c1. Configure here.

let casts = collect_casts(writer, frame.cycle, row_of);
let sealed = seal_cycle(sink, frame, casts).await?;
let applied = apply_sealed_transitions(fleet, &sealed)?;
Ok((sealed, applied))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apply path never updates watermarks

High Severity

After apply_sealed_transitions updates an owner's phase, it doesn't advance the associated stream_position watermark. This means recover_fleet can attempt to replay already-applied moves, leading to a PersistError::StalePhase error because the owner's phase has already progressed.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c2134c1. Configure here.

let casts = collect_casts(writer, frame.cycle, row_of);
let sealed = seal_cycle(sink, frame, casts).await?;
let applied = apply_sealed_transitions(fleet, &sealed)?;
Ok((sealed, applied))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Retry after seal loses casts

High Severity

collect_casts drains BatchWriter payloads before persist_cycle succeeds, and run_cycle always collects first. On a retryable PersistError::Write, a caller that re-invokes run_cycle gets an empty drain while intent rows remain on the writer board, so those casts never reach the WAL unless the caller kept the earlier Vec&lt;SweepSlot&gt; and retries seal_cycle alone.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c2134c1. Configure here.

Some(SweepSlot {
cycle,
stream_position: cast.0,
owner,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CastId breaks stream watermarks

Medium Severity

collect_casts sets SweepSlot::stream_position to the per-writer CastId, which resets when BatchWriter::new() is used. That violates the persist contract that stream_position stay monotonic per owner across cycles, so recovery can skip new landings when an old watermark dominates restarted cast ids.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c2134c1. Configure here.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c2134c159e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +151 to +154
Some(SweepSlot {
cycle,
stream_position: cast.0,
owner,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use a restart-stable stream position

Do not use the in-memory CastId directly as the durable watermark key. BatchWriter::new() resets next_id to zero after a restart, while recover_and_apply skips every landing whose stream_position <= the previously persisted watermark. Consequently, casts sealed after a restart can reuse old positions and be silently skipped during the next recovery; the position must remain monotonic across writer instances, as required by SweepSlot's contract.

Useful? React with 👍 / 👎.

Comment on lines +275 to +276
let casts = collect_casts(writer, frame.cycle, row_of);
let sealed = seal_cycle(sink, frame, casts).await?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Retain drained casts when sealing fails

Preserve or return the collected casts when seal_cycle reports a retryable PersistError::Write. At this point collect_casts has drained pending_payloads, and seal_cycle consumes the only remaining payload copies, so a transient WAL failure drops every staged update; retrying run_cycle with the same writer sees an empty batch and can seal an empty cycle instead of the intended data.

Useful? React with 👍 / 👎.

Comment on lines +222 to +226
// Interim ≤1-per-owner: a later sealed move for an already-advanced owner
// waits for the next sealed horizon.
if advanced.contains(&t.owner) {
deferred += 1;
continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Carry deferred transitions into the next horizon

Actually retain the transition when a second same-owner cast is deferred. The branch only increments a counter and discards the transition reference; AppliedCycle returns no deferred moves and run_cycle does not stage them again. Thus, when stacked casts contain sequential moves for one owner, the later durable move never executes during normal operation despite the comment claiming it waits for the next sealed horizon.

Useful? React with 👍 / 👎.

Comment on lines +396 to +399
run_cognitive_work(fleet, applied, writer, |owner| {
let (qualia, mantissa, reliability, payload) = read_gate(owner)?;
let outcome = shade_owner(owner, &qualia, mantissa, reliability)?;
Some((outcome, payload))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reschedule owners when the gate holds

Requeue an owner when shade_owner returns None for Hold or for a blocked CognitiveWork phase. run_cognitive_work only evaluates owners present in AppliedCycle because they just entered CognitiveWork; casting nothing means that owner is absent from every subsequent cycle and the gate is never evaluated again, so common Hold decisions permanently strand the mailbox instead of resting for one cycle and re-evaluating.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (3)
crates/lance-graph-supervisor/src/cycle_driver.rs (3)

797-832: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a test for the OwnerMismatch branch.

The tests cover StalePhase and the missing-owner count. The OwnerMismatch guard at lines 233-238 and the Illegal mapping at lines 246-248 have no test. persist_cycle rejects cross-owner moves at seal time, so this guard is only reachable through a directly constructed SealedCycle. That is exactly what a test can build.

💚 Proposed test
+    // ── P4b: a cross-owner sealed move is rejected (defence in depth) ──────────
+    #[test]
+    fn p4b_cross_owner_move_is_an_owner_mismatch() {
+        let mut fleet: HashMap<MailboxId, FakeOwner> =
+            HashMap::from([(7, FakeOwner::at(7, KanbanColumn::Planning))]);
+        let sealed = SealedCycle {
+            version: DatasetVersion(1),
+            transitions: vec![SealedTransition {
+                stream_position: 0,
+                owner: 7,
+                // the move claims mailbox 8 while landing on owner 7
+                mv: mv(8, KanbanColumn::Planning, KanbanColumn::CognitiveWork),
+            }],
+        };
+        assert!(matches!(
+            apply_sealed_transitions(&mut fleet, &sealed),
+            Err(PersistError::OwnerMismatch { .. })
+        ));
+    }

Based on coding guidelines: "Add Rust unit tests alongside implementations via #[cfg(test)] modules; prefer focused scenarios over broad integration tests".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/lance-graph-supervisor/src/cycle_driver.rs` around lines 797 - 832,
Add a focused #[tokio::test] alongside the existing apply_sealed_transitions
tests that constructs a SealedCycle containing a directly created
SealedTransition whose owner differs from the move’s embedded owner, then assert
apply_sealed_transitions returns PersistError::OwnerMismatch. Also add coverage
for the Illegal mapping if it is a separate reachable branch, using the existing
test helpers and error-matching style without changing production behavior.

Source: Coding guidelines


356-377: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move the gate inference onto the carrier object.

shade_owner is a free function that receives the carrier (owner) and its cognitive state (qualia, mantissa) as separate arguments. Put the inference on the carrier instead, through an extension trait with a blanket impl. The call site then reads owner.shade(&qualia, mantissa, reliability). When MailboxSoaView::qualia() lands, the trait method can drop the extra arguments without changing the call shape.

♻️ Proposed extension trait
+/// Carrier-side MUL gate inference. Blanket-implemented for every
+/// `MailboxSoaOwner`; collapses to `shade(reliability)` once
+/// `MailboxSoaView::qualia()` lands.
+pub trait ShadeOwner: MailboxSoaOwner {
+    fn shade(
+        &self,
+        qualia: &QualiaI4_16D,
+        mantissa: i8,
+        reliability: f32,
+    ) -> Option<StrategyOutcome> {
+        let phase = self.phase();
+        let to = phase.advance_on_gate(&gate_decision_i4(qualia, mantissa))?;
+        Some(StrategyOutcome {
+            reliability,
+            intended_move: Some(KanbanMove {
+                mailbox: 0,
+                from: phase,
+                to,
+                witness_chain_position: 0,
+                exec: ExecTarget::Native,
+            }),
+        })
+    }
+}
+impl<O: MailboxSoaOwner> ShadeOwner for O {}

Then run_cognitive_work_gated calls owner.shade(&qualia, mantissa, reliability)?.

Based on coding guidelines: "Keep cognitive state and inference behavior on the carrier object: prefer methods such as trajectory.resolve() over free functions that separately receive the carrier state."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/lance-graph-supervisor/src/cycle_driver.rs` around lines 356 - 377,
Move the logic from the free function shade_owner onto the carrier via an
extension trait with a blanket impl for MailboxSoaOwner. Define the trait method
shade and have it perform the existing gate_decision_i4, phase advancement, and
StrategyOutcome construction; update run_cognitive_work_gated to call
owner.shade(&qualia, mantissa, reliability)? while preserving the current
sentinel move behavior.

Source: Coding guidelines


433-433: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider a version floor for scan_sealed.

recover_fleet always calls scan_sealed(None), so it materializes the entire sealed history into memory on every pass. The history grows with every cycle, so recovery time and peak memory grow without bound. Recovery becomes slower as the system runs longer.

Accept an optional from: Option<DatasetVersion> floor derived from the lowest persisted watermark, or plan a WAL truncation point before the concrete LanceShardSink lands.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/lance-graph-supervisor/src/cycle_driver.rs` at line 433, Update
recover_fleet and the scan_sealed call to avoid materializing the entire sealed
history: derive the lowest persisted watermark as a DatasetVersion floor and
pass it through the optional from parameter. Ensure recovery still includes
every sealed entry needed from that floor onward; if the sink cannot support
this yet, establish a WAL truncation point before introducing LanceShardSink.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/board/INTEGRATION_PLANS.md:
- Around line 1-35: Synchronize the plan metadata with the shipped P4a–P4f
implementation: in .claude/board/INTEGRATION_PLANS.md lines 1-35, mark the entry
historical or implemented and link the feature-gated driver; in
.claude/plans/cycle-loop-closure-driver-v1.md lines 3-13, replace the
planned/unshipped status, lines 42-52, mark the zero-production-caller statement
as historical, and lines 345-347, clarify that status discipline distinguishes
design history from implementation status.

In @.claude/plans/persistence-cycle-wal-bootstrap-v1.md:
- Line 269: Align the section numbering in the persistence-cycle document:
update the headings currently labeled “2.1” and “2.2” to “3.1” and “3.2” to
match the reference at §3.1, or consistently change the reference back to
§2.1/§2.2. Ensure all related cross-references use the same numbering scheme.
- Line 80: Update every diagram-only Markdown fence to declare the text language
for MD040 compliance: .claude/plans/persistence-cycle-wal-bootstrap-v1.md lines
80, 95, 122, 154, and 165, plus .claude/plans/cycle-loop-closure-driver-v1.md
lines 94 and 260. Add text to each opening fence without changing the diagram
contents.

In `@crates/lance-graph-supervisor/src/cycle_driver.rs`:
- Around line 232-251: Update apply_sealed_transitions to return the
already-built AppliedCycle together with PersistError on every OwnerMismatch,
StalePhase, or Illegal early return, constructing it from applied, deferred, and
missing. Align the result shape with persist_sink::recover_and_apply, then
update run_cycle to unpack/map the error tuple while preserving the recovered
applied prefix for callers to persist.
- Around line 433-457: Update the recovery flow around recover_fleet and
recover_and_apply to partition sealed landings by owner once before iterating
fleet_ids, then pass each owner’s grouped landings into recover_and_apply
instead of the full sealed slice. Preserve the existing per-owner ordering,
watermark updates, partial-error handling, and recovery counters.
- Around line 128-161: Document on collect_casts or its surrounding API that the
same BatchWriter instance must be reused across cycles, because
SweepSlot::stream_position derives from cast.0 and must remain monotonic per
owner for durable recovery watermarks; clarify that drain_pending_payloads only
clears staged payloads and does not permit recreating the writer with a reset
counter.

---

Nitpick comments:
In `@crates/lance-graph-supervisor/src/cycle_driver.rs`:
- Around line 797-832: Add a focused #[tokio::test] alongside the existing
apply_sealed_transitions tests that constructs a SealedCycle containing a
directly created SealedTransition whose owner differs from the move’s embedded
owner, then assert apply_sealed_transitions returns PersistError::OwnerMismatch.
Also add coverage for the Illegal mapping if it is a separate reachable branch,
using the existing test helpers and error-matching style without changing
production behavior.
- Around line 356-377: Move the logic from the free function shade_owner onto
the carrier via an extension trait with a blanket impl for MailboxSoaOwner.
Define the trait method shade and have it perform the existing gate_decision_i4,
phase advancement, and StrategyOutcome construction; update
run_cognitive_work_gated to call owner.shade(&qualia, mantissa, reliability)?
while preserving the current sentinel move behavior.
- Line 433: Update recover_fleet and the scan_sealed call to avoid materializing
the entire sealed history: derive the lowest persisted watermark as a
DatasetVersion floor and pass it through the optional from parameter. Ensure
recovery still includes every sealed entry needed from that floor onward; if the
sink cannot support this yet, establish a WAL truncation point before
introducing LanceShardSink.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ed2db7f4-0d99-440f-92d8-9a70ab441df0

📥 Commits

Reviewing files that changed from the base of the PR and between 18b5b65 and c2134c1.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • .claude/board/EPIPHANIES.md
  • .claude/board/INTEGRATION_PLANS.md
  • .claude/board/LATEST_STATE.md
  • .claude/board/STATUS_BOARD.md
  • .claude/plans/cycle-loop-closure-driver-v1.md
  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md
  • crates/lance-graph-supervisor/Cargo.toml
  • crates/lance-graph-supervisor/src/cycle_driver.rs
  • crates/lance-graph-supervisor/src/lib.rs

Comment on lines +1 to +35
## 2026-08-02 — cycle-loop-closure-driver v1 — PLANNED / CONJECTURE (the seam that makes persist_sink load-bearing at 64k) — main thread

**Plan:** `.claude/plans/cycle-loop-closure-driver-v1.md`
The loop-closure driver: the missing seam that turns the merged `persist_sink`
cycle/WAL bootstrap into a running loop at 64k concurrency. Today
`persist_sink::{persist_cycle, WalSink, versions}` has **zero production
callers** — the loop is open. The driver closes: owners think over the sealed
`Vn`; owners that produce material updates emit **sparse** fire-and-forget
intents; the planner collects/coalesces/freezes one cycle (one WAL, `Vn+1`) and
exposes the **sealed paired-transition set**; the supervisor applies **ONLY the
sealed sparse transitions** (each represented owner advances one legal step;
**all unrepresented owners stay byte-identical**); owners entering CognitiveWork
run the thought and cast the next intent via `owner_adapter`. **Correctness
pivot (corrects the earlier draft): a `DatasetVersion` is global knowledge, NOT
permission to advance every mailbox** — the earlier "fan `on_version` across the
whole fleet" model violated the sparse-cycle ruling and is removed. The sealed
transitions are applied INLINE by the writer (no dataset re-read; NOT 64k async
`LanceVersionScheduler::drive_once`, which is the reader-that-did-not-write
variant). Interim rule: ≤1 durable phase transition per owner per sealed cycle.
Mints NO new types — composes `KanbanMove`/`DatasetVersion`/`SweepSlot`/
`BatchWriter`/`NextPhaseScheduler`/`KanbanActor`/`owner_adapter`/
`recover_and_apply`. Deliverables D-MBX-A6-P4a (drain+seal) → P4b (apply sealed
sparse set; falsifier: 64k mailboxes / 17 sealed transitions → exactly 17
advance, rest byte-identical) → P4c (CognitiveWork+cast round-trip) → P4d
(wait-free emit) → P4e (recovery composition) → P4f (sparse-routing scale
16k/64k, W2a-gated), each probe-first. Home: `lance-graph-supervisor` (structural
fleet owner; new one-way planner path-dep, verified acyclic) with a planner
fallback. Also carries the D-MBX crate-responsibility map (§9), the
adjacent-crates doctrine for symbiont / rs-graph-llm / ogar-* (§10), and the
subagent anti-drift guardrail (§11). HONEST: the CONTROL loop closes; the
durability leg stays the contract-probe fake until the concrete `LanceShardSink`
lands. Board-as-tenant (D-V3-W2a) is a SCALE gate, not a control-loop blocker.
Companion to `persistence-cycle-wal-bootstrap-v1.md` §2 sparse-delta ruling
(EPIPHANIES `E-COMPLETE-CYCLE-IS-PHYSICALLY-SPARSE-NOT-A-FULL-REWRITE-1`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Synchronize the design-plan status with the shipped implementation.

Both documents retain pre-implementation wording while the current board records P4a–P4f as shipped.

  • .claude/board/INTEGRATION_PLANS.md#L1-L35: mark the entry historical or implemented, and link the feature-gated driver.
  • .claude/plans/cycle-loop-closure-driver-v1.md#L3-L13: update the planned/unshipped status.
  • .claude/plans/cycle-loop-closure-driver-v1.md#L42-L52: mark the zero-caller statement as historical.
  • .claude/plans/cycle-loop-closure-driver-v1.md#L345-L347: update the status discipline to distinguish design history from implementation status.
📍 Affects 2 files
  • .claude/board/INTEGRATION_PLANS.md#L1-L35 (this comment)
  • .claude/plans/cycle-loop-closure-driver-v1.md#L3-L13
  • .claude/plans/cycle-loop-closure-driver-v1.md#L42-L52
  • .claude/plans/cycle-loop-closure-driver-v1.md#L345-L347
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/board/INTEGRATION_PLANS.md around lines 1 - 35, Synchronize the plan
metadata with the shipped P4a–P4f implementation: in
.claude/board/INTEGRATION_PLANS.md lines 1-35, mark the entry historical or
implemented and link the feature-gated driver; in
.claude/plans/cycle-loop-closure-driver-v1.md lines 3-13, replace the
planned/unshipped status, lines 42-52, mark the zero-production-caller statement
as historical, and lines 345-347, clarify that status discipline distinguishes
design history from implementation status.

**"One complete cycle image" must NEVER be read as serializing every row merely
because every participant belonged to the cycle.** The load-bearing distinction:

```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Make all Markdown diagram fences explicit.

The same MD040 lint issue affects diagram-only fences in both plans.

  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md#L80-L80: add text to the opening fence.
  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md#L95-L95: add text to the opening fence.
  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md#L122-L122: add text to the opening fence.
  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md#L154-L154: add text to the opening fence.
  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md#L165-L165: add text to the opening fence.
  • .claude/plans/cycle-loop-closure-driver-v1.md#L94-L94: add text to the opening fence.
  • .claude/plans/cycle-loop-closure-driver-v1.md#L260-L260: add text to the opening fence.
🧰 Tools
🪛 markdownlint-cli2 (0.23.1)

[warning] 80-80: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

📍 Affects 2 files
  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md#L80-L80 (this comment)
  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md#L95-L95
  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md#L122-L122
  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md#L154-L154
  • .claude/plans/persistence-cycle-wal-bootstrap-v1.md#L165-L165
  • .claude/plans/cycle-loop-closure-driver-v1.md#L94-L94
  • .claude/plans/cycle-loop-closure-driver-v1.md#L260-L260
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/plans/persistence-cycle-wal-bootstrap-v1.md at line 80, Update every
diagram-only Markdown fence to declare the text language for MD040 compliance:
.claude/plans/persistence-cycle-wal-bootstrap-v1.md lines 80, 95, 122, 154, and
165, plus .claude/plans/cycle-loop-closure-driver-v1.md lines 94 and 260. Add
text to each opening fence without changing the diagram contents.

Source: Linters/SAST tools

> The version table performs **vertical** frame succession and lookup **only**.
> It does **not** perform horizontal causal ordering — that is the horizontal
> dimension's job (§2.1). Conflating the two is the error this section forecloses.
> dimension's job (§3.1). Conflating the two is the error this section forecloses.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Make the section references resolve.

The updated reference at Line 269 points to §3.1, but the corresponding headings remain ### 2.1 and ### 2.2. Rename those headings to 3.1 and 3.2, or keep all references at 2.1 and 2.2. The current mixed numbering breaks navigation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/plans/persistence-cycle-wal-bootstrap-v1.md at line 269, Align the
section numbering in the persistence-cycle document: update the headings
currently labeled “2.1” and “2.2” to “3.1” and “3.2” to match the reference at
§3.1, or consistently change the reference back to §2.1/§2.2. Ensure all related
cross-references use the same numbering scheme.

Comment thread crates/lance-graph-supervisor/src/cycle_driver.rs
Comment thread crates/lance-graph-supervisor/src/cycle_driver.rs
Comment thread crates/lance-graph-supervisor/src/cycle_driver.rs
…s + scope honesty

Grain-of-salt review of PR #879; each finding verified against code before
acting. All accepted items were real defects:

- Retry-safe seal: seal_cycle -> Result<SealedCycle, Box<SealFailure>>; a
  WAL failure returns the complete frozen cast set byte-identical for
  retry (previously the drained cycle was simply lost). Falsifier: failed
  commit -> zero owner mutation -> same-cycle retry -> one version.
- Restart-stable stream positions: collect_casts now takes the caller's
  durable position_base cursor; SealedCycle.next_position_base carries it
  forward (computed over ALL slots). Raw CastId was the P3d-documented
  'cast_id is provenance only' trap: a reconstructed BatchWriter restarts
  at 0 and recover_and_apply silently skips positions <= watermark.
  Restart falsifier pins the exact failure mode.
- Watermark-coupled apply: apply_sealed_transitions advances the per-owner
  recovery watermark WITH the phase (one rule shared with recovery); a
  crash after normal apply no longer replays into a StalePhase stall.
- <=1-move/owner enforced PRE-seal: extras (same cast or later casts;
  also fixes the silent moves.first() truncation) return as HeldIntent,
  re-staged via restage_held into a future cycle. Sealed set == applied
  set, so recovery and normal operation agree; the old seal-then-defer
  counter (which discarded durable moves) is demoted to defence-in-depth.
- Mid-apply errors return the applied prefix Err((partial, cause)),
  mirroring recover_and_apply.
- Hold = reschedule, never strand: CognitiveWorkOutcome.held_owners +
  run_cognitive_work[_gated]_over re-poll; falsifier wakes a Held owner.
- recover_fleet partitions sealed history once (O(history), not
  O(fleet x history)).
- Scope honesty: module honesty ledger (control-loop contract proven;
  actor-owned production wiring NOT proven — MailboxFleet HashMap is the
  probe/registry fleet, KanbanActor bridging open; shader-driver/SoA
  thought NOT proven — the MUL gate is real, inputs extractor-fed;
  durability fake). P4d reworded to wait-free-at-the-cast-boundary with a
  two-represented-owners falsifier (A unfinished, B casts regardless).

Declined: routing P4b through KanbanActor mailboxes — contradicts the
ratified writer-fires-inline sparse ruling; the honesty half is taken in
docs instead.

19 lib tests green (was 14); clippy + fmt clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
@AdaWorldAPI AdaWorldAPI changed the title D-MBX-A6-P4: cycle loop-closure driver + the real MUL gate plugged into the thinking seam D-MBX-A6-P4: cycle loop-closure driver — sparse seal/apply + MUL-gate thought seam (control-loop contract) Aug 2, 2026
@AdaWorldAPI
AdaWorldAPI merged commit 130d7b2 into main Aug 2, 2026
6 checks passed
AdaWorldAPI pushed a commit that referenced this pull request Aug 2, 2026
…ive plan

Six-agent read-only investigation + unshallowed git history (5 grafted
roots -> 4162 commits) established that lance-graph holds TWO MedCare
lineages, not one incomplete runtime:

- LIVE (consumer-pull): MedCare-rs medcare-bridge -> vendored
  lance-graph-ogar -> MedcareBridge = UnifiedBridge<HealthcarePort> ->
  OGAR canonical Health codebook 0x0901..0x090C. Bridge migration
  COMPLETED at ddb6c84 (2026-06-21); deprecated alias only. Contract
  codebook mirror verified in sync slot-for-slot; the 7-alias-vs-12-slot
  gap is intentional (harvest mints, no OGIT entity).
- DEAD (host-side scaffold): modules/medcare/manifest.yaml ->
  CallcenterSupervisor -> MedcareConsumerActor, frozen since birth
  2026-05-13. Manifest compile-time parsed but runtime-orphaned (one
  caller: a test); entity codes / action_capabilities / message_type
  discarded pre-codegen; medcare_policy nonexistent; StubConsumerActor
  hard-coded; Dispatch rejected before any child; MedCareActor /
  MedCareMessage exist in NEITHER repository.

New ACTIVE plan medcare-consumer-pull-thinking-proof-v1: prove one real
medical thought over the live consumer-pull path (HealthcarePort
classids -> cognitive-shader-driver + real MailboxSoA -> owner_adapter
cast -> the #879 sparse cycle loop), falsifiers F1-F4 including the
currently-absent Healthcare fail-closed unknown-actor test. ogar-obo
(MONDO/HPO/Uberon/PATO, verified real, zero consumer edges) is an
optional slice. Older MedCare plans classified (completed / dormant-
decision-required / stale-but-unmarked); open decisions carried, not
blocked on (OQ-2 retention 2190/3650, Ueberweisung/Anamnese canon gap,
dead-lineage retire-vs-revive, .grok lineage, NoopAuditSink default).

Documentation-only: no Rust, no tests, no manifests changed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
AdaWorldAPI pushed a commit that referenced this pull request Aug 2, 2026
…ive plan

Six-agent read-only investigation + unshallowed git history (5 grafted
roots -> 4162 commits) established that lance-graph holds TWO MedCare
lineages, not one incomplete runtime:

- LIVE (consumer-pull): MedCare-rs medcare-bridge -> vendored
  lance-graph-ogar -> MedcareBridge = UnifiedBridge<HealthcarePort> ->
  OGAR canonical Health codebook 0x0901..0x090C. Bridge migration
  COMPLETED at ddb6c84 (2026-06-21); deprecated alias only. Contract
  codebook mirror verified in sync slot-for-slot; the 7-alias-vs-12-slot
  gap is intentional (harvest mints, no OGIT entity).
- DEAD (host-side scaffold): modules/medcare/manifest.yaml ->
  CallcenterSupervisor -> MedcareConsumerActor, frozen since birth
  2026-05-13. Manifest compile-time parsed but runtime-orphaned (one
  caller: a test); entity codes / action_capabilities / message_type
  discarded pre-codegen; medcare_policy nonexistent; StubConsumerActor
  hard-coded; Dispatch rejected before any child; MedCareActor /
  MedCareMessage exist in NEITHER repository.

New ACTIVE plan medcare-consumer-pull-thinking-proof-v1: prove one real
medical thought over the live consumer-pull path (HealthcarePort
classids -> cognitive-shader-driver + real MailboxSoA -> owner_adapter
cast -> the #879 sparse cycle loop), falsifiers F1-F4 including the
currently-absent Healthcare fail-closed unknown-actor test. ogar-obo
(MONDO/HPO/Uberon/PATO, verified real, zero consumer edges) is an
optional slice. Older MedCare plans classified (completed / dormant-
decision-required / stale-but-unmarked); open decisions carried, not
blocked on (OQ-2 retention 2190/3650, Ueberweisung/Anamnese canon gap,
dead-lineage retire-vs-revive, .grok lineage, NoopAuditSink default).

Documentation-only: no Rust, no tests, no manifests changed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
AdaWorldAPI pushed a commit that referenced this pull request Aug 2, 2026
…t to deterministic regeneration; re-home the proof to the live consumer

Round-2 grain-of-salt realignment (operator-ruled), post-#879-merge.

1) Pre-commit failure contract. The authoritative rule is deterministic
   regeneration, not retained-batch retry:

     sealed Vn + unchanged Kanban task + deterministic computation
       = the same provisional intent on the next sweep

   Commit fails before Vn+1 exists -> publish nothing, mutate no owner,
   advance no watermark, discard provisional slots / held moves /
   planning results, rerun the unchanged task from Vn.

   - SealFailure{casts} reclassified: OPTIONAL retry cache /
     implementation convenience only — never the correctness mechanism,
     never a provisional-planning ledger; dropping it is always sound.
   - recover_fleet doc-pinned as COMMITTED-HISTORY recovery ONLY
     (Vn+1 exists, application/restart interrupted); explicitly
     separated from ordinary pre-commit write failure — no shared state.
   - HeldIntent doc-pinned as within-success scheduling convenience,
     discarded on a failed seal, regenerated by the next thought pass.
   - NEW authoritative falsifier
     pre_commit_failure_discards_everything_and_regenerates_from_vn:
     derive cycle C deterministically from Vn, inject commit failure,
     DROP the SealFailure cache, assert no version/phase/watermark
     change, rerun the unchanged task from Vn, assert the same SEMANTIC
     sparse cycle regenerates, allow commit, assert exactly one Vn+1 and
     one advance per represented owner. Object identity of the first
     heap batch deliberately not asserted.
   - The prior byte-identical-retry test demoted to an optional-cache
     probe (secondary, convenience path).

   20 cycle_driver tests green; clippy + fmt clean. Latency figures in
   review prose are operator-provided measurements, not
   workspace-reproduced benchmarks; their values are not restated.

2) Proof re-homed (medcare-consumer-pull-thinking-proof-v1 section 4):
   primary home = MedCare-rs (the live composition root); lance-graph
   contributes only genuinely-missing GENERIC seams — no MedCare-shaped
   host adapter here (that would rebuild the dead lineage in miniature).
   Hard requirement: the proof must invoke the existing
   cognitive-shader-driver + MailboxSoA operational unit; shade_owner
   only as the driver's existing downstream gate, never a substitute.
   Trace-and-report obligation added; F1 strengthened to a
   discriminating driver outcome.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
AdaWorldAPI pushed a commit that referenced this pull request Aug 3, 2026
…d-awareness v1

1. D3's fusion band used ICC endpoints on binary projections, contradicting
   the plan's own dichotomous rule (C2: ICC -> kappa-family) — reworded to
   kappa, with ICC scoped to the jc non-binary escalation only.
2. "task #65" is a session-local task-list number that GitHub resolves to an
   unrelated merged PR — every reference now says session-local explicitly.
3. The "no production caller of emit_bootstrap_intent" ground-state row was
   stale: cycle_driver.rs:516 (cognitive_pass) calls it, HashMap-fleet-driven.
   W1 is reworded as the first ACTOR-OWNED caller, which is the distinction
   #879's own honesty ledger draws.
AdaWorldAPI pushed a commit that referenced this pull request Aug 3, 2026
…ap for #862/#875/#876/#879

PR_ARC_INVENTORY prepend for #880 (Added / Locked / Withdrawn / Deferred /
Review / Process / Docs / Confidence) and the matching LATEST_STATE entry,
written immediately on merge rather than as later cleanup — the delay IS the
anti-pattern the file's own 2026-07-27 recovery note documents.

Also records, at the top of the arc, that the practice broke again: no arc
entry exists for #862, #875, #876 or #879. This entry does not reconstruct
them; it makes the gap visible instead of silent. Reconstruction (merged
diffs + commit messages + PR bodies + review record, never inference) is
queued. The session writing this drove two of the missing PRs and wrote no
entry at the time — naming that is the point.

The #880 entry pins what the plan locked before any measurement: the
pre-registered W2 parallelism thresholds, the dichotomous-statistics naming
discipline, reliability-not-validity, the MailboxFleet-over-registry
withdrawal with its structural reason, and the operator ruling that the
HashMap fleet is a deliberate order-free keyed store ordered by temporal.rs
at read time. It also records the public/private separation-of-concerns
violation and its remediation, with the residue stated honestly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI added a commit that referenced this pull request Aug 4, 2026
…w-h9osnl

board: post-merge arc + state entries for #880 — and record the arc gap for #862/#875/#876/#879
AdaWorldAPI pushed a commit that referenced this pull request Aug 4, 2026
…the pattern they share

Closes the gap recorded one PR earlier. Each entry is marked RECONSTRUCTED
with its sources (PR body, merged diff stats, merge commit, and — for
#875/#876/#879 — this session's direct authorship or full-diff review).
Forensic method per the 2026-07-27 precedent: never inference.

Arc is now unbroken #880 -> #879 -> #876 -> #875 -> #862 -> #856.

Also appends a dated correction to #880's arc-gap note: 'queued, not done'
held for about an hour before the operator ruled the backfill belongs to the
session still holding the context.

New EPIPHANIES entry E-THE-DEFECTS-LIVE-IN-THE-FALSIFIERS-NOT-THE-MEASUREMENTS-1,
which only became visible by writing the three probe entries together: across
those PRs and ~a dozen review findings, every defect was in a falsifier or a
label and none in a measurement. Carries the three concrete shapes (a
permutation that isn't one; a window too narrow to be real; a threshold that
cannot bite), the compounding case where fixing a falsifier reproduced the
error one level up, and the CI corollary that cargo test never runs an
example's main() so those asserts were decorative until #862 wired them.
Fenced honestly: absence of review-found measurement defects is not proof the
measurements were right.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI added a commit that referenced this pull request Aug 4, 2026
…w-h9osnl

board: backfill the four missing arc entries (#862/#875/#876/#879) + the pattern they share
AdaWorldAPI pushed a commit that referenced this pull request Aug 4, 2026
…he actor is a meta injector, not a driver

Operator ruling 2026-08-04: orchestration is cycle-driver + BatchWriter +
KanbanStep; the ractor is the ownership guarantee dummy (inject a SoA/kanban
at spawn, hold it so single-writer is provable) and KanbanStep acts on
behalf. An actor never drives a phase.

kanban_actor.rs: the deprecation disclosure sits in the FIRST FIVE header
lines so grep/sed/head cannot miss it, plus a marker on each of Advance /
MulAdvance / Tick. Marked, not deleted, per the ruling. Phase (a pure read)
is unaffected. Doc-comment-only diff — verified zero non-doc additions.

The one sanctioned future for the advance arm is consolidation with the 34
NARS tactic recipes (rung 3) and the 1-10 rung ladder — never a revival as a
standalone advance mechanism. Deprecation with a named exit, not a slow
delete.

Measured zombie state, recorded: every Actor::spawn of KanbanActor is inside
its own cfg(test) module (line 384+); MedcareConsumerActor is spawned
nowhere; the supervisor tree spawns StubConsumerActor (supervisor.rs:368),
which only logs. The actor layer is not half-wired, it is parallel and idle.

Plan A1 carried a two-seam design gate whose second option (per-mailbox
KanbanMsg apply) is the message bus PR #879's writer-fires-inline ruling had
already excluded — so there was never a choice to make. Struck, with the
mechanism named: a reviewer-proposed framing was promoted to a live option
after being checked against source but not against standing rulings. The bar
is both. 'First ACTOR-OWNED caller of emit_bootstrap_intent' withdrawn as a
milestone.

Arm C gains the C1 partial result (jc is in-tree; phi = pearson on binaries
and KR-20 = alpha on dichotomous items, so those are naming work, while
kappa is a genuine gap that blocks D3) and C1b: kappa + McDonald's omega +
effect size, ADDITIVE ONLY — any diff editing an existing jc statistic is an
automatic reject.

Board: EPIPHANIES E-ACTOR-IS-A-META-INJECTOR-NOT-A-DRIVER-1, arc correction
on #880, STATUS_BOARD A1 rescoped + C1b added.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI pushed a commit that referenced this pull request Aug 4, 2026
…he actor is a meta injector, not a driver

Operator ruling 2026-08-04: production orchestration is cycle-driver +
BatchWriter + KanbanStep; an actor's only sanctioned role is as a meta process
that injects a SoA or kanban. The ractor is the ownership guarantee dummy
(inject at spawn, hold, so single-writer is provable); KanbanStep acts on
behalf. An actor never drives a phase.

kanban_actor.rs: the deprecation disclosure sits in the FIRST FIVE header
lines so grep/sed/head cannot miss it, plus markers on Advance / MulAdvance /
Tick AND on all five publicly re-exported driver helpers (deliver_kanban_step,
drive_mul_advance, drive_version_tick, drive_scheduled_tick,
run_to_absorbing) — callers reach those through lib.rs without ever seeing the
module header. The contradictory recommendation of drive_scheduled_tick is
retired. Marked, not deleted. Phase (a pure read) is unaffected.
Doc-comment-only diff; fmt clean.

The one sanctioned future for the advance arm is consolidation with the 34
NARS tactic recipes (rung 3) and the 1-10 rung ladder — never a revival as a
standalone advance mechanism.

Spawn census, CORRECTED after external review: KanbanActor is spawned in
three places, none of them the supervisor tree — this file's own unit tests,
tests/w2b_real_owner_probe.rs (60/103/144, over the real MailboxSoA), and
onebrc-probe/src/lane_e.rs:170, which is LIBRARY SOURCE, not a test, and
drives via drive_version_tick. So there is no production wiring, but the layer
is NOT test-only, and Lane E is a live consumer of the deprecated Tick arm —
which is precisely why the arms are marked rather than removed. An earlier
draft asserted every spawn was in one file: a single-file check written up as
a repository-wide census. Third absence-claim to rot in this arc, made in the
same PR that records the rule against exactly that. The operational fix now
recorded: re-run the search at write-time and keep the command in the record.

Plan A1 carried a two-seam design gate whose second option (per-mailbox
KanbanMsg apply) is the message bus PR #879's writer-fires-inline ruling had
already excluded, so there was never a choice. Struck, with the mechanism
named: a reviewer-proposed framing was checked against source but not against
standing rulings. The W1 wave-table row and the A2 'MulAdvance-gated' wording
are synchronized to the corrected seam.

Arm C: C1 partial result (jc is in-tree; phi = pearson on binaries and KR-20 =
alpha on dichotomous items, so those are naming work; kappa is a genuine gap
blocking D3) and C1b: kappa + McDonald's omega + effect size, ADDITIVE ONLY —
any diff editing an existing jc statistic is an automatic reject. C2's
estimator mapping now keeps ICC as ICC (non-binary escalation only) and lists
kappa as a separate estimator rather than a renamed one.

Board: EPIPHANIES E-ACTOR-IS-A-META-INJECTOR-NOT-A-DRIVER-1 (with the
self-correction recorded), rule-4 correction line on #880's arc entry,
STATUS_BOARD A1 rescoped + C1b added.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI pushed a commit that referenced this pull request Aug 4, 2026
…se-progression comments

Documentation and legacy-surface cleanup only. No runtime behaviour change, no
new ownership architecture, no redesign of #879.

#879 remains the canonical and independent phase-progression path. KanbanActor
is not part of that path. The retained actor surface is legacy and may later
host an authorized planning-initiation adapter, but it never drives a lifecycle
phase.

Production phase progression, complete and standalone in #879:
  plan evaluation -> KanbanMove intent -> BatchWriter -> sparse seal
                  -> one WAL/version   -> inline apply
No actor bridge, actor fleet, actor-owned driver, or actor custody model is
required.

1. Marked LEGACY: KanbanMsg::{Advance, MulAdvance, Tick} and the five publicly
   re-exported driver helpers (deliver_kanban_step, drive_mul_advance,
   drive_version_tick, drive_scheduled_tick, run_to_absorbing). The disclosure
   is in the first five header lines so grep/sed/head cannot miss it, and is
   repeated at each public entry point because callers reach those through
   lib.rs without seeing the module header. Marked, not deleted: onebrc-probe
   Lane E is a live consumer via drive_version_tick. Phase (a pure read) is
   unaffected.
2. Corrected stale comments that described the ractor as advancing phases, with
   MUL gating and version ticks composing 'on top'. The prior design rationale
   is retained explicitly as a historical record, not as current behaviour.
3. KanbanActor is now described only as an optional compatibility / consumer
   surface.
4. Spawn census corrected after external review: three spawn sites, none the
   supervisor tree (own cfg(test) tests; tests/w2b_real_owner_probe.rs; and
   onebrc-probe/src/lane_e.rs:170, which is library source, not a test). An
   earlier draft claimed every spawn was in one file - a single-file check
   written up as a repository-wide census. Third absence-claim of this arc to
   rot; the operational fix recorded is to re-run the search at write-time and
   keep the command with the claim.

Plan/board: A1's two-seam design gate is struck in full. The per-mailbox
KanbanMsg apply was the message bus #879 already excluded; the guarantee-dummy
owner framing that replaced it invented an ownership architecture nothing asked
for. Both withdrawn, along with the actor-owned emit_bootstrap_intent
milestone. Recorded as E-ACTOR-IS-NOT-THE-PHASE-PATH-1.

Recorded as a FUTURE ACTIONABLE SLICE only, not implemented: an authorized
meta-level nudge that asks planning to reconsider or initiate a goal - it cannot
emit or apply a phase transition, the planner may ignore it, and only the #879
sealed-cycle path can enact a KanbanMove.

The jc/statistics roadmap is deliberately NOT part of this correction and is
removed from it; it returns as its own change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI pushed a commit that referenced this pull request Aug 4, 2026
…ale phase-progression comments

Documentation cleanup, stale-comment correction, legacy-surface quarantine, and
a caller/spawn migration inventory. No runtime changes, no #879 redesign, no
future actor proposal, no NARS/rung redesign, no statistics work, no change to
the living MUL gate.

#879 is the complete and independent production phase-progression path:

  plan evaluation -> KanbanMove intent -> BatchWriter -> sparse seal
                  -> one WAL/version   -> inline apply of the sealed transitions

KanbanActor has no assigned architectural responsibility. It is legacy
experimental compatibility code retained only because existing probes or
consumers still reference it. No new production architecture may depend on it.
Its presence does not designate it as the future home of an ownership,
planning-initiation, concurrency, cognition, reasoning, or lifecycle mechanism.

SEPARATION (do not conflate transport with the reasoning engine): the legacy
surfaces are KanbanMsg::{Advance, MulAdvance, Tick} and the re-exported helpers
deliver_kanban_step / drive_mul_advance / drive_version_tick /
drive_scheduled_tick / run_to_absorbing. MulAdvance and drive_mul_advance are
only legacy actor-message WRAPPERS -- not the canonical MUL reasoning engine.
The living gate (lance_graph_contract::mul::i4_eval::gate_decision_i4) is
independent, is consumed directly by the #879 path via cycle_driver::shade_owner
and run_cognitive_work_gated[_over], and is NOT deprecated. The NARS tactic
recipes and the awareness rung ladder are separate and untouched; no coupling to
KanbanActor is stated or implied.

cycle_driver.rs is canonical #879 code and is NOT stale -- only three inherited
comments were: the header's actor-tree/open-bridge framing (removed; there is no
actor bridge waiting to be completed), the honesty ledger's actor-owned
production wiring line (removed; it is not a required deliverable), and
run_cognitive_work's actor-leg claim, replaced with: it is a sequential
contract-probe adapter proving the seal->apply->intent roundtrip and does not
define the production execution model; production cognition may run
independently and concurrently over the sealed Vn, with completed immutable
outcomes converging only at the deterministic ordering/coalescing/seal boundary.
gate_decision_i4, shade_owner, run_cognitive_work_gated[_over], sealing,
transition application, recovery and runtime behaviour are unchanged.

The same obsolete ractor-drives-the-transition wording is corrected in
supervisor/lib.rs, contract::kanban, contract::soa_view and
contract::orchestration; those comments now point only at the #879 sealed-cycle
path.

The caller/spawn inventory is kept strictly as deletion-impact evidence and a
removal work-list, with no architectural legitimacy: own cfg(test) tests;
tests/w2b_real_owner_probe.rs; onebrc-probe/src/lane_e.rs:170 (library source,
not a test) via drive_version_tick.

Removed from this PR: the planning-initiation-adapter wording, the future
actor/nudge slice, any NARS/rung coupling to KanbanActor, the
ownership-injection and guarantee-dummy framing, and any suggestion that
parallel cognition belongs to an actor leg. Nothing replaces them.

W1 ledger corrected -- SHIPPED: held owner is rescheduled, re-polled, wakes and
advances later. OPEN: protect callers from retrying run_cycle with the drained
writer instead of retrying SealFailure.casts. OPEN: surface/count a missing
owner in cognitive_pass instead of silently skipping.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI pushed a commit that referenced this pull request Aug 4, 2026
…tatistics work as C1b

Post-merge hygiene, written on merge rather than as later cleanup (the delay is
the anti-pattern the arc's own recovery note documents). Arc entries for #881,
#882 and #883, plus the matching LATEST_STATE entry.

The #883 entry records the ruling in its canonical wording: #879 is the complete
and independent production phase-progression path; KanbanActor has no assigned
architectural responsibility and its presence designates it as the future home
of nothing. It also records the separation that must not blur -- MulAdvance and
drive_mul_advance are legacy actor-message WRAPPERS, not the canonical MUL
reasoning engine; gate_decision_i4 is independent, consumed directly by the #879
path, and not deprecated; the NARS recipes and awareness rung ladder are
separate and untouched. The spawn inventory is recorded as deletion-impact
evidence and a removal work-list only, with no architectural legitimacy.

Restores the statistics scope that was deliberately removed from #883, now as
its own deliverable rather than mixed into a legacy-surface correction:

- C1 result: jc is in-tree; reliability.rs ships pearson / spearman /
  cronbach_alpha / icc (Icc2_1, Icc3_1), plus jirak.rs for the C4 noise floors.
  phi = pearson on two binary variables and KR-20 = alpha on dichotomous items,
  so those two renames are reporting work, not new math. kappa is absent from jc
  entirely -- the real gap, and it blocks D3's fusion falsifier.
- C1b: kappa + McDonald's omega + effect size (Effektstärke), ADDITIVE ONLY.
  pearson/spearman/cronbach_alpha/icc stay untouched; any diff editing an
  existing jc statistic is an automatic reject, independent of merit.
- C2 corrected: kappa is a SEPARATE estimator, not a renamed ICC. ICC stays ICC
  for the non-binary escalation only.

No code, no runtime behaviour, no actor content.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI pushed a commit that referenced this pull request Aug 4, 2026
Both are the defect the wiring knowledge-doc had to be corrected for three
times today, fixed at the source rather than only in the doc that inherited it.

batch_writer.rs module doc named the wrong mechanism for the kanban advance:
"VersionScheduler::on_version -> try_advance_phase". No code does that. A
session took the sentence at face value and carried VersionScheduler into a
knowledge doc as part of this write path, where it contradicted that same
doc's own warning never to let a scheduler drive the advance. The actual
consumer of this module's `moves` argument is cycle_driver::collect_casts,
which reads intent_moves back and seals the first move per owner as
SweepSlot::paired_move; persist_sink::recover_and_apply then applies it via
try_advance_phase, consulting no scheduler. Also records the constraint that
appears nowhere else: at most one move per owner per cycle is sealed, so
casting three transitions performs one and defers two.

kanban_actor.rs repeats one claim three times — that gate_decision_i4 "is
consumed directly by the #879 path". A report called it false; measuring it
myself says it is accurate about OWNERSHIP and misleading about LIVENESS, so
the fix is a qualifier, not a retraction. shade_owner does call the gate, but
it has no caller outside cycle_driver.rs, run_cognitive_work_gated[_over] is
called only from that file's own test module, and cycle_driver has no
production caller. Both halves matter: the wrappers stay legacy AND the
canonical replacement is built-but-undriven.

Doc-comments only; no behaviour change. cargo fmt clean; clippy on both
crates shows no new warning (the one `savant_by_name` unused-import warning
reproduces with these changes stashed, so it is pre-existing and untouched).
AdaWorldAPI pushed a commit that referenced this pull request Aug 4, 2026
…on caveat

Operator ruling mapped to source: (1) batchwriter amortizes only changed —
sparse seal stays; (2) interlacing is prevented by temporal.rs at read time —
no write-side ordering or ack, ever. The caveat: recover_fleet's per-owner
HashMap partition preserves STORED order (scan_sealed explicitly does not
sort, and has the test proving it), where temporal.rs layer-1
local_trajectories re-sorts by cast_seq and is proven against out-of-order
storage. The hash path is a performance stopgap: equal-exactness rests on
stored==cast_seq order per owner, true under today's single-writer MemWal,
UNCERTIFIED in general. Wiring doc §8 carries the ruling; TECH_DEBT entry
defines the certification falsifier (property test: hash-partition apply
sequence == layer-1 sequence keyed on stream_position) with both closing
outcomes (certify-conditional or migrate via a small LocalCausalRow impl).
Until closed, new recovery reads route through layer-1.
AdaWorldAPI pushed a commit that referenced this pull request Aug 4, 2026
CodeRabbit findings (9), triaged on merit:

FIXED
- reason_whole_book: reject MORE-than-seven columns too (consume the 7th,
  refuse an 8th, count as drop_arity) — a producer appending a column must
  fail the gate, not pass because the first seven parsed. Verified inert on
  the real export: 40,767 rows, 0 dropped.
- blw_binding: the per-stance "effective ceiling" no longer pools right-side
  loci across unrelated pairs — disjoint A==B and A==C populations would
  have read as a three-locus collapse describing no facet that exists.
  Redundancy is now reported PER PAIR (on a counted pair's own co-bound
  verses the effective menu is 8). Kant's measured 27/27 pair unchanged.
- blw_binding: COLLAPSE_MIN_N explicitly labelled HAND-TUNED per
  I-NOISE-FLOOR-JIRAK — an anti-vacuity floor, never a significance
  threshold; no fake Jirak derivation for an ad-hoc detector.
- design note G6: row counts corrected to per-slice (9−s Aware / 5−s Strict;
  8/4 held only for slice 1 — §1.5's own emission rule proves it). The build
  lane was corrected mid-flight before implementing the wrong assertion.
- design note B5: regraded PENDING — a stated intent is not a Cargo.toml
  line; the jc dev-dep lands in the build commit and that hash closes it.
- TECH_DEBT: TD-RECOVERY entry moved to newest-first position.
- wiring doc: preflight grep is now an executable rg command with the count;
  FINDING/CONJECTURE grades stated explicitly on the §0/§8 claims.
- exec-run record: the clippy claim scoped exactly (example-target command;
  workspace-wide --all-targets is prohibited here and not even green on
  untouched code — ontology carries 12 pre-existing warnings).
- MD040: three fences tagged (text/rust/text).

SKIPPED with reason
- #[cfg(test)] module inside the example: no cargo test invocation in this
  repo (CI or local gates) passes --examples, so example test modules never
  execute — adding one creates exactly the blind gate the audit catalogued.
  The example's own hard-asserting main() is the falsifier and is run
  centrally.

OPERATOR RULINGS recorded (wiring doc §8/§9/§9a/§10 + TECH_DEBT):
- Deinterlacing happens BEFORE the write: temporal.rs is the canonical
  deinterlacer; a previously-known-order hash helper is a legitimate fast
  path ONLY once certified equally exact on the out-of-order regime — 64k
  concurrent thoughts never arrive in the same order, period. The TD entry's
  certification falsifier re-scoped accordingly (in-order-only certification
  certifies nothing).
- deepnsm-v2 is the intended FIRST CONSUMER of the write path; callcenter is
  the BBB membrane for external consumers 10^4-7x slower — hot path only for
  now.
- kanban_actor.rs read as the consumer-facing "prepare decision, wait for
  tick" surface — verified against MulAdvance (atomic gate+transition, codex
  #578) and Tick (NextPhaseScheduler realization); the #879 boundary stands
  (a tick is knowledge, never permission).
- Between batchwriter phases every mailbox concurrently decides-or-continues;
  never linear, ≤64k in parallel; the seal stays single-writer sparse. The
  synchronous loop is a placeholder inside a correct ownership model; A2's
  pre-registered falsifier converts the doctrine to measurement.

Gates: fmt clean; clippy clean on both touched examples; blw_binding re-run
(Kant now reports "1 counted collapsed pair of 3 observed"); reason_whole_book
ingest gate re-run green (0 dropped).
AdaWorldAPI pushed a commit that referenced this pull request Aug 5, 2026
2/2 tests, all 11 gates (G1-G11) both can-fire and can-stay-silent halves.
64 real MailboxSoA owners seeded from the real KJV corpus, armed by a
MetaWord write, discovered by a board scan alone, cast write-on-behalf
through emit_bootstrap_intent -> BatchWriter::cast -> run_cycle. No
messaging: two verbs only (CAST, LOOK INTO THE KANBAN), no new start bit,
no carry-over list, driver input is a compile-time-constant scan scope.

Measured: c1 24 casts / 1 WAL write / 24 transitions = 20 Flow
(Planning->CognitiveWork, Elixir = style's mint) + 4 Block
(Planning->Prune, Native = gate's mint); 40 untouched owners fully
decomposed (32 out-of-scope, 7 unarmed, 1 orphan); c5+c6 rest with zero
casts, no seal, wal_writes frozen, fleet byte-identical. G4's rest fires on
the shipped suite's own Flow fixture (flow_proxy=7, Calibrated) because
mantissa fell — not a zeroed-qualia rig. G5 distinguishes rescheduled rest
(rediscovered=8) from absorbing Prune (0). G9/G10 make the two OPEN #879
caveats observable (drained-writer retry footgun; missing-owner accounting
gap = exactly 1).

Central-gate catch: G11's self-scan matched its own success message (needles
were concatenation-guarded, the eprintln was not) — reworded, scan re-armed.
Build lane self-caught four bugs pre-handoff (hardcoded DatasetVersion(0)
base, tautological self-comparison, post-loop fingerprint, Option<&T>
mismatch). Mid-flight G2b correction folded in (CONTRA's Planning casts are
gate-minted, per the design note's own s2 step 8).

Gates: test 2/2 ok; fmt --check clean; clippy 0 warnings attributable.
CI: the probe is inert without --features cycle-driver; workflow NOT changed
(operator-approved only) — recorded as the open item.

Board: AGENT_LOG entry (orchestrator sole writer), STATUS_BOARD row.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI pushed a commit that referenced this pull request Aug 5, 2026
Operator-ruled correction of the hot-window design before it hardened
into more documentation. v4's H-5 said "the kanban pump rebases onto
the publish ack" — that resurrected a deprecated mechanic: rebasing a
pump is still a pump. The ack/pump/scheduler framing was deliberately
retired during the #879-#887 work and survives only as legacy consumer
terminology on the historical compatibility surface, never as
substrate mechanics. The 2026-07-10 correction chain had already
called the ack-gated advance a wait-shaped scheduler by construction;
this ruling completes it.

The authoritative execution path:

  think -> seal -> publish Lance version -> next cycle reads it

A published version becoming queryable IS the progression — nothing
signals it, acknowledges it, or schedules it. Durability trails
publication independently. The hot version window is therefore not a
message queue awaiting acknowledgement; it is a resident horizon of
immutable Lance versions: readers observe versions, writers publish
versions, persistence catches up on its own clock. The decoupling the
design delivers needs no trigger rewiring at all — cycle n+1 reads
published cycle n the moment it exists, which is already the whole
mechanism.

Ack/SLA/retry/notification vocabulary keeps exactly one legitimate
home: external consumer surfaces (ticket-processing-style workflows) —
an application concern, not a cognition concern.

Landed: v4 sH-5 rewritten (retraction recorded in place);
E-PROGRESSION-IS-EXISTENCE-NOT-COMMAND-1 prepended (names what it
corrects: the same-day hot-window entry's H-5 clause, and the ack/pump
vocabulary family as historical-surface-only); same-day retraction
pointer added inside the hot-window entry; STATUS_BOARD D-HWV-1 row
corrected. Docs only; no code touched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI pushed a commit that referenced this pull request Aug 5, 2026
2/2 tests, all 11 gates (G1-G11) both can-fire and can-stay-silent halves.
64 real MailboxSoA owners seeded from the real KJV corpus, armed by a
MetaWord write, discovered by a board scan alone, cast write-on-behalf
through emit_bootstrap_intent -> BatchWriter::cast -> run_cycle. No
messaging: two verbs only (CAST, LOOK INTO THE KANBAN), no new start bit,
no carry-over list, driver input is a compile-time-constant scan scope.

Measured: c1 24 casts / 1 WAL write / 24 transitions = 20 Flow
(Planning->CognitiveWork, Elixir = style's mint) + 4 Block
(Planning->Prune, Native = gate's mint); 40 untouched owners fully
decomposed (32 out-of-scope, 7 unarmed, 1 orphan); c5+c6 rest with zero
casts, no seal, wal_writes frozen, fleet byte-identical. G4's rest fires on
the shipped suite's own Flow fixture (flow_proxy=7, Calibrated) because
mantissa fell — not a zeroed-qualia rig. G5 distinguishes rescheduled rest
(rediscovered=8) from absorbing Prune (0). G9/G10 make the two OPEN #879
caveats observable (drained-writer retry footgun; missing-owner accounting
gap = exactly 1).

Central-gate catch: G11's self-scan matched its own success message (needles
were concatenation-guarded, the eprintln was not) — reworded, scan re-armed.
Build lane self-caught four bugs pre-handoff (hardcoded DatasetVersion(0)
base, tautological self-comparison, post-loop fingerprint, Option<&T>
mismatch). Mid-flight G2b correction folded in (CONTRA's Planning casts are
gate-minted, per the design note's own s2 step 8).

Gates: test 2/2 ok; fmt --check clean; clippy 0 warnings attributable.
CI: the probe is inert without --features cycle-driver; workflow NOT changed
(operator-approved only) — recorded as the open item.

Board: AGENT_LOG entry (orchestrator sole writer), STATUS_BOARD row.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI pushed a commit that referenced this pull request Aug 5, 2026
Operator-ruled correction of the hot-window design before it hardened
into more documentation. v4's H-5 said "the kanban pump rebases onto
the publish ack" — that resurrected a deprecated mechanic: rebasing a
pump is still a pump. The ack/pump/scheduler framing was deliberately
retired during the #879-#887 work and survives only as legacy consumer
terminology on the historical compatibility surface, never as
substrate mechanics. The 2026-07-10 correction chain had already
called the ack-gated advance a wait-shaped scheduler by construction;
this ruling completes it.

The authoritative execution path:

  think -> seal -> publish Lance version -> next cycle reads it

A published version becoming queryable IS the progression — nothing
signals it, acknowledges it, or schedules it. Durability trails
publication independently. The hot version window is therefore not a
message queue awaiting acknowledgement; it is a resident horizon of
immutable Lance versions: readers observe versions, writers publish
versions, persistence catches up on its own clock. The decoupling the
design delivers needs no trigger rewiring at all — cycle n+1 reads
published cycle n the moment it exists, which is already the whole
mechanism.

Ack/SLA/retry/notification vocabulary keeps exactly one legitimate
home: external consumer surfaces (ticket-processing-style workflows) —
an application concern, not a cognition concern.

Landed: v4 sH-5 rewritten (retraction recorded in place);
E-PROGRESSION-IS-EXISTENCE-NOT-COMMAND-1 prepended (names what it
corrects: the same-day hot-window entry's H-5 clause, and the ack/pump
vocabulary family as historical-surface-only); same-day retraction
pointer added inside the hot-window entry; STATUS_BOARD D-HWV-1 row
corrected. Docs only; no code touched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
AdaWorldAPI pushed a commit that referenced this pull request Aug 5, 2026
…ifiers)

`cycle-driver` is a SEPARATE feature that `supervisor` does not imply, so the
supervisor step -- despite being this crate's own step -- never compiled
`cycle_driver`, the three `probe_ignition*` / `d_ign_b_lenses` test binaries, or
any of #879's loop-closure contract.

Measured on this tree, not inferred:

  --features supervisor                 13 tests
  --features supervisor,cycle-driver    43 tests, 0 failed

The 30 in the gap include `probe_ignition_64k_start_at_full_population` -- the
65,536-owner / 17-sealed headline canonized as
E-64K-1TO1-OWNERS-IS-THE-MAIN-MODEL-1. It runs in 13.75 s and passes; it had
simply never run anywhere but a developer machine.

#891 recorded this gap and deliberately did not touch the workflow. #898 closed
the identical shape for callcenter (`--features query`) but not this one -- same
arc, same defect class, one closed and one left open. One added feature closes
it, and the new invocation is a strict superset of the old, so it cannot lose
coverage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants