Skip to content

Commit ae32da7

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/smb-contract-traits
# Conflicts: # .claude/board/AGENT_LOG.md # .claude/board/EPIPHANIES.md # Cargo.toml
2 parents 56d729f + 10744cc commit ae32da7

19 files changed

Lines changed: 996 additions & 14 deletions

.claude/board/AGENT_LOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,18 @@ newest-first.** A `BlackboardEntry` by any other transport.
250250
**Commits:** `5e00049` (AGENT_LOG created) → `c0eda21` (blackboard protocol) → `13c1f19` (three-layer docs) → current
251251
**Tests:** 209 contract + 14 RBAC = 223 pass
252252
**Outcome:** Documented three coordination layers (Teleport / File Blackboard / Branch Pub-Sub). Added `cat >>` heredoc as canonical append pattern. Permissions opened for `cat >> AGENT_LOG.md`, `git push/fetch/pull`, `cargo test/check`. RBAC crate shipped (permission × role × policy × access). Ontology layer shipped (LinkSpec, PrefetchDepth, ActionSpec, ModelBinding, ModelHealth, SimulationSpec).
253+
254+
255+
## 2026-04-24T16:30 — Supabase subscriber v2 (sonnet, claude/supabase-subscriber-wire-up)
256+
257+
**D-ids:** DM-4a/b/c, DM-6a/b
258+
**Commit:** `ec3b5c7`
259+
**Tests:** 17 pass with realtime feature (13 without); 5 new tests total
260+
**Outcome:** Wired LanceMembrane::subscribe() from Phase-A disconnected mpsc stub to live tokio::sync::watch::Receiver<CognitiveEventRow> under [realtime] feature. PR #255 merged.
261+
262+
## 2026-04-24T16:30 — Archetype scaffold v2 (sonnet, claude/archetype-crate-scaffold)
263+
264+
**D-ids:** DU-2.1..2.6
265+
**Commit:** `816a7c0`
266+
**Tests:** 12 pass
267+
**Outcome:** Shipped `lance-graph-archetype` crate scaffold: Component + Processor traits, World meta-state with tick/fork/at_tick stubs, CommandBroker FIFO queue, ArchetypeError. PR #254 merged.

.claude/board/EPIPHANIES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ The bardioc Required/Optional/Free property concept maps 1:1 to the I1 Codec Reg
7676
Cross-ref: `contract::property` (PropertyKind, PropertySpec, Schema, SchemaBuilder), `contract::cam::CodecRoute`, smb-office-rs `lance-graph-contract-proposal.md`.
7777

7878

79+
## 2026-04-24 — FINDING: subscribe() wired; LanceVersionWatcher delivers always-latest CognitiveEventRow to subscribers (DM-4/6)
80+
81+
`LanceMembrane::subscribe()` now returns a `tokio::sync::watch::Receiver<CognitiveEventRow>` under the `[realtime]` feature gate — supabase-shape always-latest semantics. `project()` calls `watcher.bump(row)` after building the scalar row; subscribers observe the latest committed event without polling. `DrainTask` scaffold ships unconditionally (no feature gate) as a `Future` shell for the follow-up `steering_intent` drain loop. Tokio was already an optional dep in `lance-graph-callcenter/Cargo.toml` under `[realtime]` — no new deps required.
82+
83+
**Status:** FINDING
84+
7985
## 2026-04-24 — Vsa16kF32 switchboard carrier shipped (CrystalFingerprint::Vsa16kF32 + 16K algebra)
8086

8187
**Status:** FINDING

.claude/board/INTEGRATION_PLANS.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@
3636

3737
---
3838

39+
## v1 — Supabase Subscriber Wire-up (authored 2026-04-24)
40+
41+
**Author:** sonnet agent, session 2026-04-24 (branch claude/supabase-subscriber-wire-up)
42+
**Scope:** Flip `LanceMembrane::subscribe()` from Phase-A stub to a live `tokio::sync::watch::Receiver<CognitiveEventRow>` wired to `LanceVersionWatcher`; ship `DrainTask` scaffold.
43+
**Path:** `.claude/plans/supabase-subscriber-v1.md`
44+
**Deliverables:** DM-4a swap Subscription type, DM-4b `version_watcher.rs`, DM-4c uncomment `pub mod version_watcher`, DM-6a `drain.rs` scaffold, DM-6b uncomment `pub mod drain`.
45+
46+
**Status (2026-04-24):** In PR. All deliverables in branch `claude/supabase-subscriber-wire-up`.
47+
48+
**Confidence (2026-04-24):** FINDING — 17 tests pass (13 without realtime, 17 with; 4 new tests in `version_watcher.rs`, 1 new `subscribe_receives_on_project` in `lance_membrane.rs`). Zero regressions.
49+
50+
---
51+
3952
## v1 — Unified Integration: PersonaHub × ONNX × Archetype × MM-CoT × RoleDB (authored 2026-04-23)
4053

4154
**Author:** main-thread session 2026-04-23

.claude/board/STATUS_BOARD.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,9 @@ pattern IS the Supabase-shape transcode approach).
272272
|---|---|---|---|
273273
| DM-2 | `LanceMembrane: ExternalMembrane` impl with `project()` + compile-time BBB leak test | **In progress** | Phase A shipped `9a8d6a0``LanceMembrane` struct + `project()` + `ingest()` + `subscribe()` stub. Phase B: full Lance append + version counter pending DM-4. |
274274
| DM-3 | `CommitFilter` → DataFusion `Expr` translator (`[query]` feature) | **Queued** ||
275-
| DM-4 | `LanceVersionWatcher` — tails Lance version counter, emits Phoenix `postgres_changes` (`[realtime]`) | **Queued** | |
275+
| DM-4 | `LanceVersionWatcher` — tails Lance version counter, emits Phoenix `postgres_changes` (`[realtime]`) | **In PR** | branch `claude/supabase-subscriber-wire-up` — DM-4a/b/c: `version_watcher.rs` (117 LOC, 4 tests), `lib.rs` `pub mod version_watcher`, `LanceMembrane::watcher` field + `project()` calls `bump()`, `subscribe()` returns `watch::Receiver<CognitiveEventRow>`. |
276276
| DM-5 | `PhoenixServer` — minimal WS server, Phoenix channel subset (`[realtime]`) | **Queued** | Resolve UNKNOWN-2 (which consumers need Phoenix wire?) first |
277-
| DM-6 | `DrainTask``steering_intent` Lance read → `UnifiedStep``OrchestrationBridge::route()` | **Queued** | |
277+
| DM-6 | `DrainTask``steering_intent` Lance read → `UnifiedStep``OrchestrationBridge::route()` | **In PR** | branch `claude/supabase-subscriber-wire-up` — DM-6a/b scaffold: `drain.rs` (89 LOC, 2 tests), `lib.rs` `pub mod drain`, `Poll::Pending` until follow-up PR wires real drain loop. |
278278
| DM-7 | `JwtMiddleware` + `ActorContext``LogicalPlan` RLS rewriter (`[auth]`) | **Queued** | Resolve UNKNOWN-3 (pgwire?) + UNKNOWN-4 (actor_id type) first |
279279
| DM-8 | `PostgRestHandler` — query-string → DataFusion SQL → Lance scan → Arrow response (`[serve]`) | **Queued** | Confirm PostgREST compat needed (§ 8 stop point 4) before building |
280280
| DM-9 | End-to-end test: shader fires → `LanceMembrane::project()` → Lance append → Phoenix subscriber receives event | **Queued** | Depends on DM-2 through DM-6 |
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Archetype Transcode Crate Scaffold — v1
2+
3+
> **Status:** In progress (2026-04-24)
4+
> **Owner:** @archetype-specialist, @truth-architect
5+
> **Scope:** NEW crate `crates/lance-graph-archetype/`; deps only on `lance-graph-contract`, `arrow`, `lance` (peer-dep, optional).
6+
> **Depends on:** ADR-0001 Decision 1 (transcode-not-bridge). No runtime dependency on upstream Python.
7+
8+
## Goal
9+
10+
Flip `lance-graph-archetype` from "does-not-exist" to "scaffolded-and-locked." Ship the 6 foundational trait/struct files per ADR-0001 Decision 1. No runtime behaviour yet — this is the LOCKED-MAPPING-INCOMPLETE → LOCKED-AND-SCAFFOLDED pivot.
11+
12+
## Deliverables
13+
14+
- **DU-2.1**`crates/lance-graph-archetype/Cargo.toml` + `src/lib.rs` + workspace `members` entry in root `Cargo.toml`.
15+
- **DU-2.2**`src/component.rs: pub trait Component { fn arrow_field() -> arrow::datatypes::Field; fn type_id() -> &'static str; }` plus a test-only `MockComponent` impl asserting trait-object construction.
16+
- **DU-2.3**`src/processor.rs: pub trait Processor { fn matches(schema: &arrow::datatypes::Schema) -> bool; fn process(batch: arrow::record_batch::RecordBatch) -> Result<arrow::record_batch::RecordBatch, ArchetypeError>; }`.
17+
- **DU-2.4**`src/world.rs: pub struct World { tick: u64, dataset_uri: String }` with `new() / tick() / current_tick() / fork(&self, branch: &str) / at_tick(&self, tick: u64)` methods. `fork()` and `at_tick()` return `Err(ArchetypeError::Unimplemented { method: "..." })` stubs — docstrings tie to ADR-0001:61-72 / 95.
18+
- **DU-2.5**`src/command_broker.rs: pub struct CommandBroker { queue: Vec<Command>, ... }` + `pub enum Command { Spawn, Despawn, Update }` — channel-based drain interface with `submit() / drain()` method stubs.
19+
- **DU-2.6**`src/error.rs: pub enum ArchetypeError { Unimplemented { method: &'static str }, SchemaMismatch { ... }, LanceIo(...) }` with `thiserror::Error` impl.
20+
21+
## Non-goals (explicit)
22+
23+
- Runtime World tick behaviour — stubs only.
24+
- `AsyncProcessor` (Python async equivalent) — future follow-up.
25+
- Entity=`PersonaCard` wiring — DU-2.7, later PR.
26+
- Lance dataset integration beyond the `dataset_uri: String` placeholder — the `fork()``lance::checkout(branch)` wiring is DU-2.8.
27+
28+
## Acceptance criteria
29+
30+
- `cargo check -p lance-graph-archetype` compiles cleanly.
31+
- `cargo test -p lance-graph-archetype` — minimum 4 tests pass (one per core trait + one per stub-returns-Unimplemented).
32+
- `cargo test --workspace` — no regressions in other crates.
33+
- Root `Cargo.toml` workspace.members updated.
34+
- `STATUS_BOARD.md` DU-2 row status: Queued → In progress.
35+
- Verdict flip in `.claude/plans/unified-integration-v1.md §6`: Archetype row `LOCKED-MAPPING-INCOMPLETE``LOCKED-AND-SCAFFOLDED`.
36+
- `.claude/board/INTEGRATION_PLANS.md` — prepend entry pointing to this plan file.
37+
- `.claude/board/LATEST_STATE.md § Contract Inventory` — add a new block for `lance-graph-archetype` naming the shipped types.
38+
- `.claude/board/EPIPHANIES.md` — prepend short FINDING entry noting scaffold landed.
39+
40+
## Architecture notes
41+
42+
Per ADR-0001 Decision 1 (`.claude/adr/0001-archetype-transcode-stack.md:14-102`): this crate defines its OWN Rust interface. It does NOT mirror the Python `VangelisTech/archetype` API. The Python repo is a DESIGN SPEC, not a runtime dependency. "Upstream Python API unstable" is NOT a blocker.
43+
44+
Per ADR-0001 Decision 3 (`adr/0001-archetype-transcode-stack.md:320-334`): BBB invariant bans `Vsa16kF32` / `RoleKey` / `NarsTruth` / `BlackboardEntry` from crossing the membrane. Archetype types defined in this crate are INSIDE-BBB; they do NOT appear on `CognitiveEventRow`. The scalar projection for "archetype tick happened" is already covered by `CognitiveEventRow.cycle_fp_hi/lo` + `MetaWord`.
45+
46+
Mapping (locked, do not re-litigate):
47+
48+
| ECS concept | lance-graph-contract type | This crate |
49+
|---|---|---|
50+
| Entity | `contract::persona::PersonaCard` | imported, not redefined |
51+
| World | `contract::a2a_blackboard::Blackboard` (runtime) + `World { dataset_uri, tick }` (archetype meta) | the latter is new here |
52+
| Tick | `contract::collapse_gate::GateDecision` fire | imported, not redefined |
53+
| Component | trait in this crate | **DU-2.2** |
54+
| Processor | trait in this crate | **DU-2.3** |
55+
| CommandBroker | struct in this crate | **DU-2.5** |
56+
57+
## File layout
58+
59+
```
60+
crates/lance-graph-archetype/
61+
Cargo.toml
62+
src/
63+
lib.rs # pub use component::*; etc.
64+
component.rs # trait Component
65+
processor.rs # trait Processor
66+
world.rs # struct World
67+
command_broker.rs # struct CommandBroker, enum Command
68+
error.rs # enum ArchetypeError (thiserror)
69+
```
70+
71+
## Test layout
72+
73+
Each module gets a `#[cfg(test)] mod tests` with at minimum one test. Minimum 4 tests total:
74+
75+
1. `component::tests::mock_component_has_arrow_field`
76+
2. `processor::tests::trait_object_is_constructable`
77+
3. `world::tests::fork_returns_unimplemented`
78+
4. `world::tests::tick_increments`
79+
80+
## Dependencies
81+
82+
```toml
83+
[dependencies]
84+
lance-graph-contract = { path = "../lance-graph-contract" }
85+
arrow = { workspace = true }
86+
thiserror = { workspace = true }
87+
88+
[dev-dependencies]
89+
# nothing initially
90+
```
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Supabase-shape Subscriber Flow Wire-up — v1
2+
3+
> **Status:** In progress (2026-04-24)
4+
> **Owner:** @callcenter-specialist, @bus-compiler
5+
> **Scope:** `lance-graph-callcenter` crate only (plus `external_membrane.rs` if trait surface bends)
6+
> **Depends on:** none (substrate-independent)
7+
8+
## Goal
9+
10+
Flip `LanceMembrane::subscribe()` from GHOST to PARTIAL. Ship DM-4 `LanceVersionWatcher` + DM-6 `DrainTask`. Close the Outside-BBB loop so Lance dataset version bumps fire notifications to subscribers with filtered `CognitiveEventRow` payloads.
11+
12+
## Deliverables
13+
14+
- **DM-4a** — Swap `Subscription` associated type from `mpsc::Receiver<u64>` to `tokio::sync::watch::Receiver<CognitiveEventRow>` in `lance_membrane.rs`.
15+
- **DM-4b** — Create `crates/lance-graph-callcenter/src/version_watcher.rs`. Holds the `watch::Sender<CognitiveEventRow>`; `bump(row)` on each `project()` commit.
16+
- **DM-4c** — Uncomment `pub mod version_watcher` in `lib.rs:71-72`; export `LanceVersionWatcher`.
17+
- **DM-5a**`subscribe(filter)` returns the `watch::Receiver` wrapped with a `CommitFilter` predicate combinator.
18+
- **DM-6a** — Create `crates/lance-graph-callcenter/src/drain.rs`. Scaffold only — `DrainTask` struct + `drain()` method that currently returns `Poll::Pending`. Wiring to `OrchestrationBridge::route()` is the follow-up PR.
19+
- **DM-6b** — Uncomment `pub mod drain` in `lib.rs:78-79`; export `DrainTask`.
20+
- **DM-7** — Flip test `subscribe_returns_disconnected_receiver` to `subscribe_receives_on_project` — assert `rx.borrow().version > 0` after a `project()` call.
21+
22+
## Non-goals (explicit)
23+
24+
- `dialect` Phase-B source wiring — separate TECH_DEBT row (@callcenter-specialist).
25+
- `scent` Phase-C CAM-PQ cascade — blocked on substrate migration (PR B, pending).
26+
- `PhoenixServer` DM-5 — Queued separately.
27+
- `DrainTask` runtime drain of `steering_intent` — this PR ships only the scaffold.
28+
29+
## Acceptance criteria
30+
31+
- `cargo test -p lance-graph-callcenter --lib` — 11 existing tests pass + new `subscribe_receives_on_project` test passes. Zero regressions.
32+
- `bbb_scalar_only_compile_check` still compiles.
33+
- `cargo check --workspace` compiles.
34+
- Verdict flip in `.claude/plans/unified-integration-v1.md §6`: Supabase row `GHOST``PARTIAL` (one-line Edit on the table row).
35+
- `.claude/board/INTEGRATION_PLANS.md` — prepend entry pointing to this plan file.
36+
- `.claude/board/STATUS_BOARD.md` — DM-4 / DM-6 rows status updated.
37+
- `.claude/board/EPIPHANIES.md` — prepend short FINDING entry noting subscribe wire-up.
38+
39+
## Architecture notes
40+
41+
Per CLAUDE.md BBB invariant, `Subscription` must carry Arrow-scalar content only — `CognitiveEventRow` is the canonical outbound DTO and is already scalar-only (compile-time enforced by `bbb_scalar_only_compile_check`). `tokio::sync::watch` is the right primitive for the supabase-realtime-shaped fan-out: single-producer (the membrane), many-consumer (subscribers), always-latest semantics (skip stale revisions).
42+
43+
Implementation sketch:
44+
45+
```rust
46+
// version_watcher.rs
47+
pub struct LanceVersionWatcher {
48+
tx: tokio::sync::watch::Sender<CognitiveEventRow>,
49+
}
50+
impl LanceVersionWatcher {
51+
pub fn new(initial: CognitiveEventRow) -> Self { ... }
52+
pub fn bump(&self, row: CognitiveEventRow) { let _ = self.tx.send(row); }
53+
pub fn subscribe(&self) -> tokio::sync::watch::Receiver<CognitiveEventRow> { self.tx.subscribe() }
54+
}
55+
```
56+
57+
The `CommitFilter` wrapper is NOT a new trait — it's a method `LanceMembrane::subscribe_filtered(filter: CommitFilter) -> impl Stream<Item = CognitiveEventRow>` that calls `self.watcher.subscribe()` and uses `tokio_stream::wrappers::WatchStream::new(rx).filter(move |row| filter.matches(row))`.
58+
59+
## File-level edits (full list)
60+
61+
1. `crates/lance-graph-callcenter/Cargo.toml` — add `tokio = { workspace = true, features = ["sync"] }` if not present; add `tokio-stream = { workspace = true }` (minimal features).
62+
2. `crates/lance-graph-callcenter/src/version_watcher.rs` — NEW.
63+
3. `crates/lance-graph-callcenter/src/drain.rs` — NEW (scaffold).
64+
4. `crates/lance-graph-callcenter/src/lib.rs:71-72` — uncomment `pub mod version_watcher`.
65+
5. `crates/lance-graph-callcenter/src/lib.rs:78-79` — uncomment `pub mod drain`.
66+
6. `crates/lance-graph-callcenter/src/lance_membrane.rs:56` — field `watcher: LanceVersionWatcher`.
67+
7. `crates/lance-graph-callcenter/src/lance_membrane.rs:117``type Subscription = watch::Receiver<CognitiveEventRow>`.
68+
8. `crates/lance-graph-callcenter/src/lance_membrane.rs:186-189``subscribe()` body = `self.watcher.subscribe()`.
69+
9. `crates/lance-graph-callcenter/src/lance_membrane.rs``project()` path (wherever it completes a commit) — call `self.watcher.bump(row)` after the Lance write.
70+
10. `crates/lance-graph-callcenter/src/lance_membrane.rs` tests — flip `subscribe_returns_disconnected_receiver` to `subscribe_receives_on_project`.
71+
11. `crates/lance-graph-contract/src/external_membrane.rs` — IF the `Subscription` associated type is declared here with bounds, widen to `Clone + Send` as needed. Do NOT add Vsa/RoleKey/NarsTruth — BBB deny-list stays intact.
72+
12. Board files (INTEGRATION_PLANS, STATUS_BOARD, EPIPHANIES, unified-integration-v1 §6) — per Acceptance.
73+
74+
## Test
75+
76+
- New test `subscribe_receives_on_project` — construct `LanceMembrane`, call `subscribe()``rx`, call `project(some_event)` → assert `rx.borrow().<relevant field>` matches `some_event`.

Cargo.lock

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ members = [
77
"crates/lance-graph-contract",
88
"crates/neural-debug",
99
"crates/lance-graph-callcenter",
10+
"crates/lance-graph-archetype",
1011
"crates/lance-graph-rbac",
1112
]
1213
exclude = [
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "lance-graph-archetype"
3+
version = "0.1.0"
4+
edition = "2021"
5+
description = "Archetype transcode scaffold (ECS-style types transcoded to Arrow/Lance). Per ADR-0001 Decision 1: defines its OWN Rust interface (not a mirror of upstream Python). Inside-BBB only — types in this crate never cross the CognitiveEventRow membrane."
6+
license = "Apache-2.0"
7+
keywords = ["lance", "graph", "archetype", "ecs", "transcode"]
8+
9+
[dependencies]
10+
lance-graph-contract = { path = "../lance-graph-contract" }
11+
# NOTE: plan specified { workspace = true } for arrow/thiserror, but this
12+
# workspace has no shared [workspace.dependencies] table today; using
13+
# explicit versions consistent with the rest of the codebase (arrow 57,
14+
# thiserror 2). See PR description for the single-line deviation.
15+
arrow = "57"
16+
thiserror = "2"
17+
18+
[dev-dependencies]
19+
# nothing initially

0 commit comments

Comments
 (0)