feat: TD-INT 1–14 complete + LF-21/22/90/91/92 + W-1..4#263
feat: TD-INT 1–14 complete + LF-21/22/90/91/92 + W-1..4#263AdaWorldAPI merged 4 commits intomainfrom
Conversation
… LF-90)
Three SMB REQUESTs delivered on the contract surface:
LF-21 — SemanticType enum on PropertySpec:
PlainText, Iban, Currency(&'static str), Email, Phone,
Date(DatePrecision), Geo(GeoFormat), Address, File(&'static str),
Image, Url, TaxId, CustomerId, InvoiceNumber.
Plus DatePrecision (Day/Month/Year/DateTime) and GeoFormat
(LatLon/Wgs84/PlusCode). Added `semantic_type` field to
PropertySpec; all const constructors default to PlainText;
`.with_semantic_type(st)` builder method. Zero-dep.
LF-22 — ObjectView on Schema:
ObjectView { card, detail, summary_template } — all &'static.
Const constructor. Added `view: Option<ObjectView>` to Schema;
SchemaBuilder gets `.view(ObjectView)` method. Tells outside-BBB
UI which properties to show at card vs detail zoom level.
LF-90 — AuditEntry + AuditLog trait:
AuditEntry { actor, action_id, action_kind, timestamp_ms,
predicate_target, signature: [u8; 64] }.
AuditAction enum (Create/Update/Delete/Read/Export/Import/
Approve/Reject). AuditLog trait with append/entries_for_entity/
entries_by_actor — associated Error type, zero-dep.
216 tests pass. Full workspace cargo check clean.
https://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh
…arl 2³ query
Five additions across three crates extending the boring outside-BBB
DTO surface and closing two privacy/filter wiring gaps:
TD-INT-9 — RBAC at LanceMembrane fan-out:
- New `MembraneGate` trait in contract::external_membrane (zero-dep).
- `LanceMembrane.gate: RwLock<Option<Arc<dyn MembraneGate>>>` field.
- `set_gate(gate)` / `clear_gate()` methods.
- `project()` consults gate.should_emit() before watcher.bump.
- `AllowAllGate` no-op default for callers that don't want gating.
- Test: gate denies → row returned, fan-out skipped.
TD-INT-13 — Server-side CommitFilter at LanceMembrane fan-out:
- `CommitFilter::matches(actor, free_e, style, is_commit)` predicate.
- `LanceMembrane.server_filter: RwLock<CommitFilter>` field.
- `set_server_filter(filter)` method.
- `project()` checks filter before watcher.bump (server-side push-down).
- 2 tests: filter mismatch skips emit, filter match passes emit.
TD-INT-7 — Pearl 2³ causal mask query predicate (causal-edge):
- `CausalEdge64::matches_causal(query_mask)` const fn.
- `CausalEdge64::matches_causal_mask(CausalMask)` type-safe wrapper.
- Semantics: edge contains AT LEAST query_mask bits.
- 5 tests covering full match, subset match, non-match, zero-mask
(matches anything), high-bit ignore.
LF-91 — Service-level objective (SLA):
- New `crates/lance-graph-contract/src/sla.rs` module.
- `SlaPolicy { max_latency_ms, min_freshness_ms, priority }`.
- `SlaPriority` enum (Background < Standard < Interactive < Urgent).
- `STANDARD` and `INTERACTIVE` const policies.
LF-92 — Multi-tenant isolation:
- `TenantId = u64` alias.
- `TenantScope` enum (Single / Multi / All).
- `.contains()` / `.as_slice()` methods. `Default = All`.
10 new tests in contract (225 total pass), 4 new in callcenter
(16 total), 5 new in causal-edge. Full workspace cargo check clean.
Both bus and consumer alike: SMB session can install a MembraneGate
to enforce per-tenant scope, attach SlaPolicy hints to incoming
requests, and use matches_causal as Cypher WHERE filter without
this session having to write callcenter→rbac→tenant glue.
https://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh
…isambiguation hook
TD-INT-5 — role-indexed similarity in binary space:
RoleKey::hamming_in_slice(fp_a, fp_b) — Hamming distance restricted
to this role's [slice_start..slice_end). Bits outside contribute
zero. Mask-aware first/last word handling.
RoleKey::resonance_in_slice(fp_a, fp_b) — 1 - hamming/slice_width,
density-agnostic. Binary-space analogue of unbind+cosine for a role.
3 tests in role_keys.rs.
Activation: callers can now compare two SPO triples on SUBJECT plane
only via SUBJECT_KEY.resonance_in_slice(...), or PREDICATE plane via
PREDICATE_KEY.resonance_in_slice(...). The full f32 VSA cosine path
is the next architectural step (requires Vsa16kF32 alongside Binary16K
in the bindspace columns); this is the honest binary-space first step.
TD-INT-6 — ContextChain disambiguation wire in cypher_bridge:
disambiguate_parse_candidates(chain, position, candidates) helper
in cypher_bridge.rs. Calls ContextChain::disambiguate, returns Ok
on confident pick or Err(DisambiguationResult) on escalate.
2 tests covering empty + single-candidate escalation paths.
Activation: dormant today (regex stub returns single candidate). Wire
is in place for when the real lance-graph::parser::parse_cypher_query
ships and returns N parse trees on ambiguous queries.
Full workspace cargo check clean. 228 contract lib tests pass.
https://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh
…chema validation, neural-debug registry TD-INT-5 (CORRECTED) — per-plane palette distance via ndarray: REVERTED hamming_in_slice from role_keys.rs — slicing/comparison algebra belongs in ndarray, not in lance-graph-contract. RoleKey stays Layer-2 catalogue (slice boundaries only). ADDED PlaneDistance in lance-graph-planner/cache/convergence.rs: wraps ndarray::hpc::palette_distance::SpoDistanceMatrices for per-plane O(1) comparison. Methods: spo_distance(), subject_distance(), predicate_distance(), object_distance(). Build once from palette codebooks, compare via pre-computed 256×256 L1 tables. This is architecturally correct: ndarray = hardware (SIMD, palette, Base17); lance-graph = thinking (calls ndarray). No bit ops in contract. TD-INT-8 — Schema validation on SPO commit: SpoBuilder::with_schema(Schema) + validate() + commit_validated() in lance-graph/graph/spo/builder.rs. Commit-time validation returns FailureTicket::missing_required on missing Required predicates. Existing SpoBuilder::commit() unchanged for backward compat. FailureTicket::missing_required constructor added to contract. TD-INT-11 — neural-debug runtime registry populated: RuntimeRegistry with record(row, NeuronState), snapshot() → Vec, global accessor via registry()/init_registry(). NeuronState enum (Alive/Static/NaN). Re-exported from neural-debug lib.rs. 10 tests passing. Full workspace cargo check clean. 423 lib tests pass across all affected crates. https://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh
…n_01SbYsmmbPf9YQuYbHZN52Zh PR #263 covers all 14 TD-INT items + LF-21/22/90/91/92 + W-1..4. TD-INT-5 corrected per user feedback (no Hamming in contract; palette distance via ndarray). UNKNOWN-3 answer: DataFusion logical-plan, not pgwire. UNKNOWN-4 answer: String (JWT sub). Both pending user confirmation for LF-3. https://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d59994b1db
ℹ️ 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".
| let mut step = self.membrane.ingest(intent); | ||
| // Errors are counted as drained — the bridge owns | ||
| // retry / dead-letter semantics. DrainTask is a pump. | ||
| let _ = self.bridge.route(&mut step); |
There was a problem hiding this comment.
Preserve failed routes instead of dropping intents
DrainTask removes each intent from the channel and then ignores bridge.route errors (DomainUnavailable, ExecutionFailed, etc.), but still advances drained; this causes permanent data loss whenever routing fails because the popped intent is never retried or dead-lettered. In production this means transient downstream faults silently discard user events instead of back-pressuring or surfacing failure.
Useful? React with 👍 / 👎.
| // retry / dead-letter semantics. DrainTask is a pump. | ||
| let _ = self.bridge.route(&mut step); | ||
| self.drained += 1; | ||
| continue; |
There was a problem hiding this comment.
Bound drain loop work to avoid executor starvation
The poll implementation drains in an unbounded loop and immediately continues after each received intent, so under sustained traffic (channel never empty) this future can monopolize a Tokio worker thread and starve unrelated tasks. A cooperative async future should process a bounded batch per poll and yield Pending (or re-wake itself) to keep scheduler fairness.
Useful? React with 👍 / 👎.
Summary
Closes all 14 TD-INT cognitive-loop technical debt items plus 8 LF outside-BBB surface extensions and 4 SMB wishlist items. 16 files changed, +1523 / −42, 423 lib tests passing across 5 crates.
TD-INT items (all 14 complete)
SpoDistanceMatrices)d59994bb39acdfCausalEdge64::matches_causal(query_mask)const fne70f944SpoBuilder::commit_validated → FailureTicket)d59994bMembraneGatetrait +set_gate)e70f944RuntimeRegistry,NeuronState::Alive/Static/NaN)d59994bOrchestrationBridge::route)b39acdfCommitFilter::matchesat membrane fan-oute70f944run_convergencetriplets → palette layers → callback)Outside-BBB surface (LF items)
SemanticTypeenum (Iban, Date, TaxId, Currency, …)ObjectViewenum (Card/Detail/Summary + template methods)AuditEntry+AuditLog(immutable audit trail)SlaPolicy+SlaPriority(Background/Standard/Interactive/Urgent)TenantId+TenantScope(Single/Multi/All + contains/as_slice)SMB wishlist items (W-1..4, delivered PR #262)
LineageHandle::mergefor multi-source upsertsMarking::most_restrictivefor GDPR row-level foldingVecStoremock implementingEntityStore+EntityWriterArchitectural correction in this PR
TD-INT-5 was initially implemented as
RoleKey::hamming_in_slice(CPU bit ops in lance-graph-contract). Reverted. Slicing/comparison algebra belongs in ndarray (SpoDistanceMatrices, palette-quantized per-plane L1 distance). Corrected toPlaneDistancein planner/convergence.rs wrapping ndarray's existing infrastructure. RoleKey stays Layer-2 catalogue only.Cross-session coordination
SMB session (
session_01GDZ7W6k75paRxBznbZXV4t) consumed W-1..4 and LF-21/22/90 via bus protocol onclaude/blackboard. Their VERIFY-PENDING entries are tracked. Protocol state machine: REQUEST (SMB) → WIP (LG) → DONE (LG) → VERIFY (SMB).Test plan
cargo check— full workspace cleancargo test -p lance-graph-contract --lib— 227 passedcargo test -p lance-graph-planner --lib— 170 passedcargo test -p lance-graph-callcenter— 16 passedcargo test --manifest-path crates/neural-debug/Cargo.toml --lib— 10 passedcargo test --manifest-path crates/causal-edge/Cargo.toml --lib— 16 passed (1 pre-existing failure intables::tests::test_build_fast, not in any changed code path)https://claude.ai/code/session_01SbYsmmbPf9YQuYbHZN52Zh
Generated by Claude Code