From c65a4052140a58085590343aecb5e51f0f7668a0 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 4 Aug 2026 11:57:33 +0000 Subject: [PATCH] supervisor+contract: quarantine the legacy actor surfaces; correct stale 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 Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki --- .claude/board/EPIPHANIES.md | 18 +++ .claude/board/PR_ARC_INVENTORY.md | 1 + .claude/board/STATUS_BOARD.md | 2 +- .../plans/kanban-64k-inverted-awareness-v1.md | 54 ++++++++- crates/lance-graph-contract/src/kanban.rs | 22 ++-- .../lance-graph-contract/src/orchestration.rs | 5 +- crates/lance-graph-contract/src/soa_view.rs | 14 ++- .../src/cycle_driver.rs | 36 +++--- .../src/kanban_actor.rs | 113 +++++++++++++----- crates/lance-graph-supervisor/src/lib.rs | 5 +- 10 files changed, 201 insertions(+), 69 deletions(-) diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index f84520d62..90a078138 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,3 +1,21 @@ +## 2026-08-04 — E-ACTOR-IS-NOT-THE-PHASE-PATH-1 — #879 is the complete phase-progression path; KanbanActor has no assigned architectural responsibility + +**Status:** RATIFIED (operator ruling, 2026-08-04) + CORRECTION of a same-week over-reach in `kanban-64k-inverted-awareness-v1` §A1. **Confidence:** High. Documentation and legacy-surface quarantine only — **no runtime behaviour changed, no #879 redesign, no future actor proposal.** + +**The ruling, in the required words.** *"#879 is the complete and independent production phase-progression path. 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."* + +**The production path** (complete and standalone in #879): `plan evaluation → KanbanMove intent → BatchWriter → sparse seal → one WAL/version → inline apply of the sealed transitions`. No actor bridge, actor fleet, actor-owned driver, actor custody model, or actor message path is required. + +**The transport/engine separation (do not conflate).** The legacy surfaces are `KanbanMsg::{Advance, MulAdvance, Tick}` plus 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 MUL gate is independent (`lance_graph_contract::mul::i4_eval::gate_decision_i4`) and is consumed directly by the #879 path via `cycle_driver::shade_owner` and `run_cognitive_work_gated[_over]`; marking the wrappers legacy does not deprecate the gate. The NARS tactic recipes and the awareness rung ladder are **separate and untouched** — they are not part of KanbanActor and no coupling is implied. + +**Stale comments corrected in the same pass** (`cycle_driver.rs` is canonical #879 code and NOT stale — only inherited comments were): the driver header no longer describes an actor-owned tree with an open bridge; the honesty ledger no longer lists "actor-owned production wiring" as an unproven deliverable (it is not a deliverable); `run_cognitive_work` is documented as *"a sequential contract-probe adapter used to prove the seal→apply→intent roundtrip — it 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."* The same obsolete ractor-drives framing was corrected in `supervisor/lib.rs`, `contract::kanban`, `contract::soa_view`, and `contract::orchestration`. + +**Caller/spawn migration inventory** (kept strictly as deletion-impact evidence and the removal work-list — no architectural legitimacy): `kanban_actor.rs`'s own `#[cfg(test)]` unit tests; `tests/w2b_real_owner_probe.rs` (60/103/144); `onebrc-probe/src/lane_e.rs:170` — library source, not a test — via `drive_version_tick`. An earlier draft claimed every spawn was in one file; that was a single-file check written up as a repository-wide census, caught by external review. Operational fix: re-run the search at write-time and keep the command with the claim. + +**The correction this supersedes.** §A1 first offered a two-seam design gate (per-mailbox `KanbanMsg` apply — the message bus #879's writer-fires-inline ruling had already excluded — vs a "guarantee-dummy owner"), and the first fix of that then framed the actor as an ownership injector and sketched a future planning-initiation adapter. All of it is struck: the corrections kept building. The reusable lesson: **when correcting an over-built design, the correction must not itself build** — check a reviewer's framing against standing rulings, and check a self-proposed replacement against whether anything asked for it. + +**W1 ledger corrected:** SHIPPED — a held owner is rescheduled, re-polled, wakes, and advances later (#879's own falsifiers). 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. + ## 2026-08-03 — E-THE-DEFECTS-LIVE-IN-THE-FALSIFIERS-NOT-THE-MEASUREMENTS-1 — across three consecutive probe PRs, every defect found by review was in a falsifier or a label; none was in a measurement **Status:** FINDING (observed, not designed). **Confidence:** High as a description of #862/#875/#876 — the three PRs' own review records are the evidence, and each states the pattern locally; what is new here is that the pattern is *consecutive and unbroken*, which only became visible when the three arc entries were written together during the 2026-08-03 backfill. Documentation-only. diff --git a/.claude/board/PR_ARC_INVENTORY.md b/.claude/board/PR_ARC_INVENTORY.md index 9f62c7b74..21cfbfed5 100644 --- a/.claude/board/PR_ARC_INVENTORY.md +++ b/.claude/board/PR_ARC_INVENTORY.md @@ -62,6 +62,7 @@ - **Review** — three external rounds, every finding verified against source before acting. Consistency round (3): a κ/ICC contradiction between the C2 rule and the D3 fusion measure; a task reference that resolved to an unrelated GitHub PR (qualified as session-local everywhere); a stale "no production caller" ground-state row. Inline round (4): a missed wave-table gate row; the `write-on-behalf.md` caller status. External P1/P2: the `MailboxFleet` impossibility (above) and vague W2 thresholds ("materially below"/"must converge") — the PR's own inertness rule turned on itself, fixed by pre-registration. **Claim-ceiling check passed clean twice** (claim (a) conditional on W2, claim (b) capped at reliability). **Process finding:** the "no production caller yet" fact went stale **three times** on this one branch; the durable form is citing the call site, never asserting the absence. - **Process (governance)** — an operator-ruled **separation-of-concerns violation** occurred mid-arc: private-consumer identifiers were written into public plan/board text, the PR body, and PR comments. Remediated the same session — source files scrubbed, the three unmerged commits rewritten into one clean commit and force-pushed (`--force-with-lease`, unmerged PR branch only; `main` never touched), PR body rewritten, bot comments patched via REST. Honest residue recorded at the time: force-push removes refs but GitHub may retain orphaned SHAs until GC, comment/PR-body edit histories persist in the UI, and **pre-existing** occurrences on merged `main` history (older board entries, crate filenames) were surfaced for an operator decision rather than rewritten unilaterally. The standing lesson: the public/private boundary is a *drafting-time* rule, not a review-time cleanup. - **Docs** — the plan; the four module headers; board files per the mandatory hygiene rule. +- **⊘ Correction (2026-08-04, operator ruling `E-ACTOR-IS-NOT-THE-PHASE-PATH-1`):** the "Withdrawn" line above is right that `MailboxFleet`-over-registry is impossible, but **both replacement seams are also struck**. #879 remains the canonical and independent phase-progression path (`plan evaluation → KanbanMove intent → BatchWriter → sparse seal → one WAL/version → inline apply`); no actor bridge, fleet, owned driver, or custody model is required. "First ACTOR-OWNED caller of `emit_bootstrap_intent`" is withdrawn as a milestone; the actor surface is marked LEGACY in source. Two drafting defects, recorded: a reviewer's framing was checked against source but not against standing rulings, and the *replacement* I then wrote invented an ownership architecture nothing had asked for. - **Confidence (2026-08-03):** working as a *plan* — no code paths changed, so nothing here can regress behaviour. Its central claims are deliberately unproven: claim (a) is CONJECTURE until W2 measures it against the pre-registered thresholds, claim (b) is capped at reliability. The doc-header pass is verified mechanically (diff adds only `//!` lines; neither edited file appears in a `cargo fmt --check` diff — though `lance-graph-ontology` carries extensive PRE-EXISTING fmt drift in `hydrators/` and `odoo_blueprint/`, untouched here). ## 2026-08-02 — lance-graph #879 — D-MBX-A6-P4 cycle loop-closure driver: sparse seal/apply + the MUL-gate thought seam diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index d8a3d693c..b1d842b76 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -5,7 +5,7 @@ Plan: `.claude/plans/kanban-64k-inverted-awareness-v1.md` (operator anchors a/b; | D-id | Deliverable | Repo | Status | Evidence | |---|---|---|---|---| | D-KIA-0 | jc capability map + dichotomous-statistics decision note (phi/KR-20/kappa naming; Spearman dropped at view 2) | lance-graph | Queued | plan W0 | -| D-KIA-A1 | actor-fleet driver seam — design gate (guarantee-dummy single owner vs per-mailbox KanbanMsg apply; MailboxFleet-over-registry withdrawn per codex P1); first ACTOR-OWNED caller of owner_adapter::emit_bootstrap_intent; #879 caveat fixes (retry footgun guard, held_owners strand falsifier, missing-owner counter) | lance-graph | Queued | plan W1 | +| D-KIA-A1 | ⊘ RESCOPED 2026-08-04 (E-ACTOR-IS-NOT-THE-PHASE-PATH-1): #879 is the complete phase-progression path; KanbanActor has no assigned architectural responsibility (legacy compatibility code). SHIPPED: held-owner reschedule/wake. OPEN: run_cycle drained-writer retry guard; missing-owner counter in cognitive_pass | lance-graph | Queued | plan W1 | | D-KIA-A2 | parallelism falsifier (protocol pre-registered: median-of-5, >=2x at >=4k owners, +/-10% stay-silent; kill = regrade claim (a)) | lance-graph | Queued | plan W2 | | D-KIA-B1 | catalog binary-range criterion contract type + generalized catalog-mirror drift guard | lance-graph | Queued | plan W3 | | D-KIA-C5 | cohort-statistic witness type under the ELEVATED carve-out + held-out anti-circularity gate | lance-graph | Queued | plan W4 | diff --git a/.claude/plans/kanban-64k-inverted-awareness-v1.md b/.claude/plans/kanban-64k-inverted-awareness-v1.md index 285b85fa3..126f2cc9b 100644 --- a/.claude/plans/kanban-64k-inverted-awareness-v1.md +++ b/.claude/plans/kanban-64k-inverted-awareness-v1.md @@ -85,6 +85,52 @@ mailbox-phase state, no second owner, no ack*: (`KanbanMsg::Advance`, the shipped S4 edge). Either seam lands the first **actor-owned** `emit_bootstrap_intent` caller (the existing `cognitive_pass` caller is HashMap-fleet-driven). + +> **⊘ CORRECTION (operator ruling, 2026-08-04) — A1 above is WRONG as written; +> there is no design gate and no actor seam to choose.** +> +> **#879 is the complete and independent production phase-progression path.** +> +> **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.** +> +> The production path, 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.** #879 is not being redesigned by this correction. +> +> 1. Both A1 seams are struck — the per-mailbox `KanbanMsg` apply (the message +> bus #879's writer-fires-inline ruling already excluded) *and* the +> guarantee-dummy owner framing, which invented an ownership architecture the +> ruling does not call for. +> 2. **"First ACTOR-OWNED caller of `emit_bootstrap_intent`" is withdrawn** as a +> milestone. Corrected W1 ledger (statuses fixed 2026-08-04): **SHIPPED** — +> a held owner is rescheduled, re-polled, wakes, and advances later (#879's +> own falsifiers). **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. +> 3. `KanbanMsg::{Advance, MulAdvance, Tick}` and the five re-exported driver +> helpers are marked **LEGACY** in source (disclosure in the first five header +> lines of `kanban_actor.rs`). Marked, not deleted: `onebrc-probe`'s Lane E is +> a live consumer via `drive_version_tick`. No runtime behaviour changed. +> 4. **Caller/spawn migration inventory (corrected).** Kept strictly as +> evidence for why immediate deletion would break current consumers and as +> the removal work-list — it confers no architectural legitimacy. `KanbanActor` is spawned in three places, none +> of them the supervisor tree: `kanban_actor.rs`'s own `#[cfg(test)]` tests; +> `tests/w2b_real_owner_probe.rs` (60/103/144); and +> `onebrc-probe/src/lane_e.rs:170` — **library source, not a test**. An earlier +> version of this line claimed every spawn was in one file: a single-file check +> written up as a repository-wide census, caught by external review. Third +> absence-claim of this arc to rot; the operational fix is to re-run the search +> at write-time and keep the command with the claim. +> +> Board: `EPIPHANIES.md` `E-ACTOR-IS-NOT-THE-PHASE-PATH-1`. - Design constraint: the seal/collect side stays single-writer (one `BatchWriter`); parallelism lives in the **thought phase** (owners think concurrently, cast ahead-fire), never in the seal. Ordering is already the @@ -99,8 +145,9 @@ Either seam lands the first **actor-owned** `emit_bootstrap_intent` caller (symmetry with `apply_sealed_transitions`). **A2 — the parallelism falsifier.** The claim is only honest if measured: -N actors thinking concurrently (tokio joinset over `MulAdvance`-gated work) -vs. the same N sequentially, same corpus, same seals. +N owners thinking concurrently (tokio joinset over cycle-driver MUL-gated +`CognitiveWork` — NOT the deprecated `MulAdvance` actor arm; corrected +2026-08-04) vs. the same N sequentially, same corpus, same seals. - **Can-fire:** concurrent wall-clock materially below sequential at 4k+ owners with non-trivial per-thought work. - **Stay-silent:** with trivial thought bodies the two must converge (else the @@ -147,6 +194,7 @@ convention. actually provide toward ICC/α/ρ with variance components? Output: a one-page capability map. Everything below adjusts to what's found. + **C2 — name the dichotomous statistics correctly.** Over binary catalog criteria: Pearson→**φ** (report the marginal-capped ceiling), Cronbach's α→**KR-20**, ICC→**κ-family agreement**, Spearman **degenerates and is @@ -213,7 +261,7 @@ only if the comparison runs on jc's non-binary escalation): | Wave | D-id | Deliverable | Gate to pass | Model | |---|---|---|---|---| | W0 | D-KIA-0 | jc capability map (C1) + dichotomous-statistics decision note (C2 naming) | read-only; note on board | main thread | -| W1 | D-KIA-A1 | actor-fleet driver seam — design gate: guarantee-dummy single owner vs per-mailbox `KanbanMsg` apply (`MailboxFleet`-over-registry withdrawn, codex P1) + first ACTOR-OWNED `emit_bootstrap_intent` caller + #879 caveat fixes | existing 19 falsifiers stay green over the actor fleet; strand falsifier; no-ack audit clean | Opus design → Sonnet impl | +| W1 | D-KIA-A1 | ⊘ RESCOPED 2026-08-04 — no design gate, no actor seam choice, no actor-owned `emit_bootstrap_intent` milestone (all withdrawn; actors do not drive). #879 is the canonical phase-progression path and is not redesigned. SHIPPED: held-owner reschedule/wake (#879 falsifiers). OPEN: run_cycle drained-writer retry guard (retry `SealFailure.casts`, not the writer); missing-owner counter in `cognitive_pass` | existing 19 falsifiers stay green; strand falsifier; no-ack audit clean | Opus design → Sonnet impl | | W2 | D-KIA-A2 | parallelism falsifier (protocol pre-registered in §2 A2: median-of-5, ≥2× at ≥4k owners, ±10 % stay-silent) | can-fire + stay-silent both green, else regrade claim (a) | Opus | | W3 | D-KIA-B1 | catalog criterion contract type + catalog-mirror drift guard | field-isolation matrix; `v3-envelope-auditor` verdict LAYOUT-CLEAN/GATED | Sonnet impl, Opus gate | | W4 | D-KIA-C5 | witness type under ELEVATED ruling + C6 held-out gate | zero-copy verdict ELEVATED recorded; anti-circularity falsifier | Opus | diff --git a/crates/lance-graph-contract/src/kanban.rs b/crates/lance-graph-contract/src/kanban.rs index 18b3e96d2..47c7b701b 100644 --- a/crates/lance-graph-contract/src/kanban.rs +++ b/crates/lance-graph-contract/src/kanban.rs @@ -2,8 +2,10 @@ //! //! The seam where three subsystems meet over the ONE per-mailbox SoA: //! - **lance-graph-planner** emits a [`KanbanMove`] (the plan's output unit), -//! - **ractor** (the mailbox owner, `lance-graph-supervisor`) drives the -//! transition — advancing a [`KanbanColumn`] *is* the mailbox lifecycle step, +//! - **lance-graph-supervisor**'s sealed-cycle driver applies the transition +//! (the #879 path: plan evaluation → `KanbanMove` intent → `BatchWriter` → +//! sparse seal → one WAL/version → inline apply) — advancing a +//! [`KanbanColumn`] *is* the mailbox lifecycle step, //! - **surrealdb** (`surreal_container`) projects the columns as the kanban view //! over SoA-shaped Lance rows. //! @@ -31,8 +33,9 @@ use crate::mul::GateDecision; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] #[repr(u8)] pub enum KanbanColumn { - /// `t < -550 ms` (Libet readiness-potential window): ractor owns the SoA; - /// counterfactual pre-planning / expansion happens here. The spawn state. + /// `t < -550 ms` (Libet readiness-potential window): the mailbox owner + /// holds the SoA; counterfactual pre-planning / expansion happens here. The + /// spawn state. #[default] Planning = 0, /// `t >= -550 ms`: the SoA mutates under cognitive operations; the Σ-commit @@ -72,9 +75,9 @@ impl KanbanColumn { /// Is this an **absorbing** column — the mailbox cycle ends here with no /// successor (`Commit` = calcify to cold path, `Prune` = drop)? /// - /// `Plan` is NOT absorbing (it re-deliberates back to `Planning`). The ractor - /// lifecycle driver tombstones the mailbox iff the cycle reaches an absorbing - /// column — the LE-3 cycle-end commit/SLA decision hooks here. + /// `Plan` is NOT absorbing (it re-deliberates back to `Planning`). The + /// sealed-cycle driver tombstones the mailbox iff the cycle reaches an + /// absorbing column — the LE-3 cycle-end commit/SLA decision hooks here. #[inline] pub fn is_absorbing(self) -> bool { matches!(self, Self::Commit | Self::Prune) @@ -160,7 +163,8 @@ impl KanbanColumn { /// restating the literal. pub const LIBET_COMMIT_WINDOW_US: u32 = 550_000; -/// One kanban transition: the planner's output unit and the ractor's lifecycle step. +/// One kanban transition: the planner's output unit and the sealed cycle's +/// lifecycle step (applied inline by the #879 path after the sparse seal). /// /// `Copy` and small (≤ 16 B) so it rides the airgap as owned microcopy, never a /// borrow into the SoA (R1). The witness is a *pointer* (R4). @@ -431,7 +435,7 @@ mod tests { assert!(!KanbanColumn::Plan.is_absorbing()); assert!(KanbanColumn::Plan.is_terminal()); // terminal decision, but... assert!(KanbanColumn::Plan.can_transition_to(KanbanColumn::Planning)); // ...re-enters. - // The ractor driver tombstones iff absorbing. + // The sealed-cycle driver tombstones iff absorbing. assert!(!KanbanColumn::Planning.is_absorbing()); assert!(!KanbanColumn::Evaluation.is_absorbing()); } diff --git a/crates/lance-graph-contract/src/orchestration.rs b/crates/lance-graph-contract/src/orchestration.rs index 74abb12a6..8a8f7bb17 100644 --- a/crates/lance-graph-contract/src/orchestration.rs +++ b/crates/lance-graph-contract/src/orchestration.rs @@ -50,8 +50,9 @@ pub enum StepDomain { /// Medcare reality-check vertical (clinic data sovereignty). Medcare, /// 4-phase Rubicon kanban transition over the per-mailbox SoA — the seam - /// where the planner (emits), ractor (owns/drives), and surrealdb (projects) - /// meet. `step_type` prefix `"kanban."`. See [`crate::kanban`]. + /// where the planner (emits), the supervisor's sealed-cycle driver + /// (applies), and surrealdb (projects) meet. `step_type` prefix + /// `"kanban."`. See [`crate::kanban`]. Kanban, } diff --git a/crates/lance-graph-contract/src/soa_view.rs b/crates/lance-graph-contract/src/soa_view.rs index 5d301ea7b..e685f10ae 100644 --- a/crates/lance-graph-contract/src/soa_view.rs +++ b/crates/lance-graph-contract/src/soa_view.rs @@ -5,8 +5,9 @@ //! cognitive operations. This module is the **zero-dep borrow vocabulary** that //! lets three holders read the SAME bytes: //! -//! - `cognitive-shader-driver`'s `MailboxSoA` — the in-RAM hot owner (implements -//! [`MailboxSoaOwner`]; ractor drives it), +//! - `cognitive-shader-driver`'s `MailboxSoA` — the in-RAM hot owner +//! (implements [`MailboxSoaOwner`]; its transitions are applied by the #879 +//! sealed-cycle driver), //! - `surreal_container` — the transparent kv-lance-backed VIEW (implements the //! read-only [`MailboxSoaView`] over the same Lance columns; no Arrow re-encode), //! - `lance-graph-planner` — a CONSUMER (plans over the columns directly). @@ -45,7 +46,7 @@ pub enum IdentityPlane { /// cycle runs off), the P64 perturbation ladder writes [`Explore`](StyleLane::Explore), /// and the L4 learning seam writes [`Learned`](StyleLane::Learned) via NARS revision — /// each write an **owned SoA update** on the mailbox's own lane (`MailboxSoaOwner`, -/// ractor sole-mutator), never a by-convention `&mut`. Triangle plan +/// single-writer by ownership), never a by-convention `&mut`. Triangle plan /// `.claude/plans/triangle-tenants-gestalt-separation-v1.md` §1. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum StyleLane { @@ -285,7 +286,8 @@ pub trait MailboxSoaView { } } -/// The mutation airgap for the SoA **owner** only (the ractor-driven hot path). +/// The mutation airgap for the SoA **owner** only (the hot path; transitions +/// are applied by the #879 sealed-cycle driver). /// /// A read-only view (e.g. `surreal_container`) deliberately does **not** implement /// this — that is what makes "the view is read-only" a structural guarantee rather @@ -302,8 +304,8 @@ pub trait MailboxSoaOwner: MailboxSoaView { /// ([`KanbanColumn::can_transition_to`]) before mutating. /// /// Returns the emitted [`KanbanMove`] on a legal edge, or - /// [`RubiconTransitionError`] on an illegal one (no mutation occurs). The ractor - /// lifecycle driver should prefer this over the unchecked + /// [`RubiconTransitionError`] on an illegal one (no mutation occurs). The + /// sealed-cycle driver should prefer this over the unchecked /// [`advance_phase`](MailboxSoaOwner::advance_phase) so an illegal transition is a /// typed error, not silent corruption. fn try_advance_phase( diff --git a/crates/lance-graph-supervisor/src/cycle_driver.rs b/crates/lance-graph-supervisor/src/cycle_driver.rs index c4de6c6a3..18acff29c 100644 --- a/crates/lance-graph-supervisor/src/cycle_driver.rs +++ b/crates/lance-graph-supervisor/src/cycle_driver.rs @@ -44,19 +44,16 @@ //! through `MailboxSoaOwner::try_advance_phase` — no ractor message bus, no //! dataset re-read, NOT a 64k async `drive_once` fan. //! -//! **What [`MailboxFleet`] is and is NOT:** it is the driver's owner-resolution -//! seam (and its `HashMap` impl the probe/registry fleet used by the tests). -//! It is **NOT** a claim of production supervisor ownership: the actor-owned -//! path (`kanban_actor::KanbanActor`, behind the `supervisor` feature, where -//! actor State IS the owner and mutation is serialized in the mailbox handler) -//! remains the production actor tree. Bridging the sealed sparse set into -//! actor-owned state (a `MailboxFleet` impl that resolves into actor state, or -//! delivery via the owner's mailbox) is **open, not shipped**. +//! **What [`MailboxFleet`] is:** the driver's owner-resolution seam, with its +//! `HashMap` impl as the keyed fleet the driver and its tests use. This +//! sealed-cycle path (#879) is the complete and independent production +//! phase-progression path — there is no actor bridge waiting to be completed. +//! (`kanban_actor` is legacy compatibility code with no assigned architectural +//! responsibility; see its module header.) //! //! ## Honesty ledger (what is proven vs not) //! //! - **Control-loop contract: proven** (this module's falsifiers, over fakes). -//! - **Actor-owned production wiring: NOT proven** (see above). //! - **cognitive-shader-driver / MailboxSoA thought: NOT proven** — the P4c //! thought body here is the real **MUL gate** ([`shade_owner`] = //! `gate_decision_i4` + `advance_on_gate`), but its qualia/mantissa inputs @@ -177,9 +174,8 @@ pub struct CollectedCasts { /// **unrepresented owners are never resolved and never touched** (that is what /// keeps them byte-identical). /// -/// Scope honesty: the `HashMap` impl below is the probe/registry fleet. The -/// production actor-owned path (`KanbanActor` state) is NOT bridged yet — see -/// the module docs' ownership section. +/// The `HashMap` impl below is the driver's keyed fleet (order-free access; +/// cross-mailbox ordering is the read side's job, per the temporal contract). pub trait MailboxFleet { /// The concrete owner type this fleet holds. type Owner: MailboxSoaOwner; @@ -189,8 +185,8 @@ pub trait MailboxFleet { fn owner_mut(&mut self, id: MailboxId) -> Option<&mut Self::Owner>; } -/// A `HashMap` keyed by `MailboxId` — the probe/registry fleet (tests + any -/// non-actor registry). NOT the production actor tree (see module docs). +/// A `HashMap` keyed by `MailboxId` — the driver's keyed fleet (order-free +/// access). impl MailboxFleet for HashMap { type Owner = O; fn owner(&self, id: MailboxId) -> Option<&O> { @@ -549,11 +545,13 @@ where /// casts it **write-on-behalf**. This never mutates a mailbox (the step is P4b, /// post-seal); it only stages the next intent. /// -/// Execution is sequential within the pass (a synchronous loop) — the wait-free -/// property is at the **cast/cycle boundary** (an owner whose thought declines -/// or is unfinished never blocks a completed owner's cast), NOT intra-pass -/// concurrent execution. Concurrent per-owner thought execution belongs to the -/// actor leg (`kanban_actor`), not this driver. +/// `run_cognitive_work` is a sequential contract-probe adapter used to prove +/// the seal→apply→intent roundtrip. It does not define the production +/// execution model. +/// +/// Production cognition may run independently and concurrently over the sealed +/// `Vn`. Completed immutable outcomes converge only at the deterministic +/// ordering/coalescing/seal boundary. pub fn run_cognitive_work( fleet: &F, applied: &AppliedCycle, diff --git a/crates/lance-graph-supervisor/src/kanban_actor.rs b/crates/lance-graph-supervisor/src/kanban_actor.rs index 2bd0d37d2..4e1d66b18 100644 --- a/crates/lance-graph-supervisor/src/kanban_actor.rs +++ b/crates/lance-graph-supervisor/src/kanban_actor.rs @@ -1,28 +1,54 @@ -//! S4 — the kanban-advance ractor actor (the smallest *true* OUT-leg wire). +//! ⚠ LEGACY SURFACE (2026-08-04). #879 is the complete and independent +//! production phase-progression path. 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. //! -//! Per the operator ownership model ("every SoA is owned by its ractor actor — -//! mailbox-as-owner"), the Rubicon phase of a per-mailbox SoA is advanced by the -//! actor that OWNS it, in reaction to a message. There is no owner-registry held -//! by a bridge and no "absent owner" case: the actor's `State` IS the owner -//! ([`MailboxSoaOwner`]). +//! Its presence does not designate it as the future home of an ownership, +//! planning-initiation, concurrency, cognition, reasoning, or lifecycle +//! mechanism. //! -//! ## Why this is the safe substrate +//! ## The canonical path (PR #879 — complete and standalone) //! -//! A ractor actor processes ONE message at a time, so the owner sees a strict -//! single-writer: `&mut state` during `handle` cannot alias another writer. That -//! is the compile-time "no aliasing / no data race / no use-after-free" guarantee -//! the canon attributes to mailbox-as-owner (E-CE64-MB-4) — realized here by -//! Rust's `&mut` + ractor's serialized mailbox, not by a lock. +//! ```text +//! plan evaluation -> KanbanMove intent -> BatchWriter -> sparse seal +//! -> one WAL/version -> inline apply of the sealed transitions +//! ``` //! -//! ## What it does NOT do (kept honest) +//! No actor bridge, actor fleet, actor-owned driver, actor custody model, or +//! actor message path is required. Nothing in this module participates in that +//! path. //! -//! This is the OWNER-advance mechanism only. It does NOT resolve a `kanban.*` -//! `UnifiedStep` to a mailbox (that delivery edge is `step_type` → mailbox id → -//! `ractor::registry::where_is` → `cast`, a separate seam) and it does NOT drive -//! the advance from a MUL gate (S2) or a Lance version tick (S3) — those compose -//! ON TOP by sending [`KanbanMsg::Advance`]. The owner advances **itself** via -//! the contract's checked [`MailboxSoaOwner::try_advance_phase`]; an illegal -//! Rubicon edge is a typed [`RubiconTransitionError`], never silent corruption. +//! ## Legacy surfaces in this module +//! +//! `KanbanMsg::{Advance, MulAdvance, Tick}` and the driver 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 — they are NOT +//! the canonical MUL reasoning engine.** The living MUL gate is independent +//! (`lance_graph_contract::mul::i4_eval::gate_decision_i4`) and is consumed +//! directly by the #879 path via `cycle_driver::shade_owner` and +//! `cycle_driver::run_cognitive_work_gated[_over]`; marking the wrappers here +//! legacy does not deprecate that gate. `Phase` (a pure read) is unaffected. +//! +//! ## Stale-comment correction +//! +//! Comments in this file previously described the ractor as the thing that +//! advances a mailbox's Rubicon phase, with MUL gating and version ticks +//! composing "on top". That framing is corrected: phase progression is enacted +//! only by the #879 sealed-cycle path above. +//! +//! ## Caller/spawn migration inventory (2026-08-04) +//! +//! Kept strictly as (a) evidence for why immediate deletion would break +//! current consumers and (b) the removal work-list — it confers no +//! architectural legitimacy. `KanbanActor` is spawned by: this file's own +//! `#[cfg(test)]` unit tests (line 384+); the integration probe +//! `tests/w2b_real_owner_probe.rs` (60/103/144); and +//! `onebrc-probe/src/lane_e.rs:170` — library source, not a test — via +//! `drive_version_tick`. (An earlier draft claimed every spawn was in this +//! file; that was a single-file check written up as a repository-wide census, +//! and it was wrong.) use lance_graph_contract::kanban::{KanbanColumn, KanbanMove, RubiconTransitionError}; use lance_graph_contract::mul::i4_eval::gate_decision_i4; @@ -33,6 +59,9 @@ use ractor::{Actor, ActorProcessingErr, ActorRef, RpcReplyPort}; /// Messages the kanban actor accepts. pub enum KanbanMsg { + /// ⚠ **LEGACY (2026-08-04)** — not part of phase progression. #879's sealed + /// cycle is the canonical path; see the module header. + /// /// Advance the owned mailbox's Rubicon phase to `to` (checked against the /// lifecycle DAG). Replies with the emitted [`KanbanMove`] on a legal edge, /// or a [`RubiconTransitionError`] on an illegal one (no mutation occurs). @@ -42,6 +71,12 @@ pub enum KanbanMsg { }, /// Read the owned mailbox's current Rubicon phase (no mutation). Phase { reply: RpcReplyPort }, + /// ⚠ **LEGACY (2026-08-04)** — a legacy actor-message *wrapper* only, NOT + /// the canonical MUL reasoning engine. The living gate + /// (`gate_decision_i4`) is independent and not deprecated; the #879 path + /// consumes it directly (`cycle_driver::shade_owner`, + /// `run_cognitive_work_gated[_over]`). + /// /// **Atomic** S2 step: run the MUL gate (`gate_decision_i4` over `qualia` + /// `mantissa`) against the owner's CURRENT phase and advance in ONE message. /// Replies `Ok(Some(move))` on advance, `Ok(None)` on Hold, or the typed @@ -53,6 +88,9 @@ pub enum KanbanMsg { mantissa: i8, reply: RpcReplyPort, RubiconTransitionError>>, }, + /// ⚠ **LEGACY (2026-08-04)** — not part of phase progression. A version tick + /// is global knowledge, never permission to advance (#879's ratified rule). + /// /// **Atomic** S3 IN-leg step: a substrate version tick (`at`) advances the /// owner along the Rubicon **forward arc** — `phase().next_phases().first()` — /// in ONE message, reading the owner's phase at the instant of mutation. This @@ -70,10 +108,9 @@ pub enum KanbanMsg { }, } -/// A ractor actor whose `State` IS a [`MailboxSoaOwner`] — the SoA mailbox and -/// its owning actor are the same thing (mailbox-as-owner). On -/// [`KanbanMsg::Advance`] the owner advances its own phase via -/// [`MailboxSoaOwner::try_advance_phase`]. +/// ⚠ **LEGACY compatibility / consumer surface (2026-08-04).** Retained so +/// existing callers keep building; **not** part of phase progression — see the +/// module header. A ractor actor holding a [`MailboxSoaOwner`] as its `State`. pub struct KanbanActor { _marker: core::marker::PhantomData, } @@ -211,6 +248,11 @@ fn phase_from_name(name: &str) -> Option { /// field — the target is recovered from the step string + the registry /// (mailbox-as-owner addressing). Multi-mailbox resolves because `where_is` /// looks up any registered mailbox by name. +/// ⚠ **LEGACY (2026-08-04)** — constructs [`KanbanMsg::Advance`], a +/// legacy arm. Delivery/advance belongs to cycle-driver + +/// BatchWriter + KanbanStep. Re-exported from `lib.rs`, so this notice is +/// repeated here for callers who never see the module header. +/// pub async fn deliver_kanban_step(step_type: &str) -> Result { let (mailbox, to) = parse_kanban_step(step_type) .ok_or_else(|| KanbanRouteError::BadStepType(step_type.to_string()))?; @@ -251,6 +293,11 @@ pub fn mul_target( /// `Planning` and collide. (The earlier two-RPC `Phase`-then-`Advance` shape had /// that race.) `advance_on_gate` only yields a DAG-legal successor, so `Illegal` /// here would signal a gate/DAG drift bug — surfaced, not panicked. +/// ⚠ **LEGACY (2026-08-04)** — constructs [`KanbanMsg::MulAdvance`], a legacy +/// actor-message *wrapper*, NOT the MUL reasoning engine. The living gate +/// (`gate_decision_i4`) is canonical and not deprecated; the #879 path consumes +/// it directly. Re-exported from `lib.rs`; notice repeated for callers. +/// pub async fn drive_mul_advance( actor: &ActorRef, qualia: QualiaI4_16D, @@ -280,11 +327,16 @@ pub async fn drive_mul_advance( /// transition run inside the SAME serialized mailbox message, so concurrent ticks /// cannot read a stale phase and collide — they chain along the arc instead /// (codex #578 lesson, applied to the IN-leg). This is the actor-side realization -/// of the contract's [`NextPhaseScheduler`] policy; use [`drive_scheduled_tick`] -/// when a custom [`VersionScheduler`] policy (version-delta gating, `Plan`/`Prune` -/// over the forward arc, batching) reads a richer view. +/// of the contract's [`NextPhaseScheduler`] policy. Both this helper and +/// [`drive_scheduled_tick`] (the [`VersionScheduler`]-policy variant) are +/// legacy — see the module header. /// /// [`NextPhaseScheduler`]: lance_graph_contract::scheduler::NextPhaseScheduler +/// ⚠ **LEGACY (2026-08-04)** — constructs [`KanbanMsg::Tick`], a legacy +/// arm. A version tick is global knowledge, never permission to advance. +/// **Live consumer:** `onebrc-probe/src/lane_e.rs` calls this per batch; it keeps +/// working (marked, not removed) and is the named migration target. +/// pub async fn drive_version_tick( actor: &ActorRef, at: DatasetVersion, @@ -309,6 +361,10 @@ pub async fn drive_version_tick( /// decision, which the owner (defaulting to `Native`) can't make. For the pure /// forward-arc policy prefer the atomic [`drive_version_tick`]; reach for this /// only when the policy needs a richer view than the owner computes internally. +/// ⚠ **LEGACY (2026-08-04)** — constructs [`KanbanMsg::Tick`], a legacy +/// arm. Scheduling policy belongs to the cycle-driver, not an actor RPC. +/// Re-exported from `lib.rs`; notice repeated for callers. +/// pub async fn drive_scheduled_tick( scheduler: &S, view: &V, @@ -365,6 +421,9 @@ where /// guard against a future non-terminating policy, not a normal exit: exceeding it /// returns [`KanbanRouteError::Rpc`] with a non-termination note rather than /// looping forever. +/// ⚠ **LEGACY (2026-08-04)** — drives through the legacy arms. +/// Re-exported from `lib.rs`; notice repeated for callers. +/// pub async fn run_to_absorbing( actor: &ActorRef, max_ticks: usize, diff --git a/crates/lance-graph-supervisor/src/lib.rs b/crates/lance-graph-supervisor/src/lib.rs index 499bb9074..5244c81df 100644 --- a/crates/lance-graph-supervisor/src/lib.rs +++ b/crates/lance-graph-supervisor/src/lib.rs @@ -70,8 +70,9 @@ pub mod supervisor; #[cfg(feature = "supervisor")] pub mod actors; -/// S4 OUT-leg: the kanban-advance actor (mailbox-as-owner; the owner advances -/// its own Rubicon phase on a message). +/// Legacy kanban actor surface — no assigned architectural responsibility. +/// Phase progression is the #879 sealed-cycle path (`cycle_driver`); see the +/// module header for the legacy notice and the caller migration inventory. #[cfg(feature = "supervisor")] pub mod kanban_actor;