Skip to content

feat(odoo) + docs: op_emitter Phase 2 + ARM-discovery plan + Odoo blueprint survival dossier#435

Merged
AdaWorldAPI merged 3 commits into
mainfrom
claude/activate-lance-graph-att-k2pHI
May 30, 2026
Merged

feat(odoo) + docs: op_emitter Phase 2 + ARM-discovery plan + Odoo blueprint survival dossier#435
AdaWorldAPI merged 3 commits into
mainfrom
claude/activate-lance-graph-att-k2pHI

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented May 29, 2026

Copy link
Copy Markdown
Owner

Summary

Four commits, three concerns — all session-survival-shaped (everything needed to resume on a fresh session is committed and pushed).

1. op_emitter.rs — Phase 2 SoA→SoC codegen (commit f87a1295)

Completes the Odoo SoA → Foundry SoC pipeline started by style_recipe.rs (PR #433):

  • bucket_corpus(entities) — walks every entity×method pair, pairs each derive_style_recipe output with its semantic OdooMethodKind bucket (10 variants).
  • emit_op_dispatch(buckets) — emits deterministic compilable Rust source: one RECIPE_<HEX8>: u32 const per unique recipe_id (identical DAtom profiles collapse to one const; N Op entries still emitted in the bucket slice), one struct <Pascal>Op { method_id, recipe_id } + static <UPPER>_OPS: &[<Pascal>Op] slice per kind with methods. Zero-dep emitted output — consumers write to OUT_DIR from build.rs and include!().
  • 12/12 tests; 230/230 existing lance-graph-ontology tests green; zero warnings.

2. Board hygiene for D-ODOO-OP-1 (commit fece37d9)

Adds the D-ODOO-OP-1 (Shipped) row to STATUS_BOARD next to D-ODOO-STYLE-1; AGENT_LOG entry prepended.

3. ARM-discovery integration plan + handover (commit 718a1424)

Authors the missing upstream proposer leg into the SPO substrate. Today's proposers (curated L-docs + AST-extracted Odoo source) are bounded by the literal artifact; this plan adds runtime-tabular-data ARM discovery, gated through the epiphany-brainstorm-council before reaching the deterministic codegen path.

Pipeline:

parquet stream → Stage A (pair-stats trunk + optional Aerial+ fan-in)
              → Stage B (ARM truth → NARS truth)
              → Stage C (SpoStore hypothesis test: revise / commit-contradiction)
              → Stage D (council ratification gate — the determinism firewall)
              → Stage E (op_emitter codegen consumes ratified only)

ARM (support, confidence) maps verbatim to NARS (c, f) per Karabulut, Groth, Degeler 2025 §2 (arxiv 2504.19354v1). Externalize-interpretation doctrine independently confirmed by Abreu, Cruz, Guerreiro 2025 §4 (arxiv 2511.13661v1). Iron rules respected: I-NOISE-FLOOR-JIRAK (mandatory Stage-A threshold via D-ARM-7), I-SUBSTRATE-MARKOV, I-VSA-IDENTITIES. Epiphany anchors: E-SOA-IS-THE-ONLY, E-BATON-1, E-INTERPRET-NOT-STORE-1.

Adds D-ARM-1..D-ARM-12 (12 deliverables, 1 new crate lance-graph-arm-discovery, ~2,400 LOC). Two corrections proposed to PR #434's unified-SoA plan (§7): separate discovery_arc: [u32; D] SoA column (in-flight candidate evidence) + discovery_origin: u8 per-row provenance byte.

4. Odoo blueprint survival dossier (commit 4a6c2776)

User-stated need: "create a PR with all 70, strategies for extraction and tools for extraction so it doesn't get lost and if the session dies the other session has EVERYTHING." Delivered as four new docs:

  • .claude/knowledge/odoo-blueprint-inventory-v1.md — index of all 66 pub const OdooEntity declarations across 15 lanes (11,563 LOC, 130 tests). Alphabetical per-entity index with const→model→kind→lane:line→L-doc:lines→description. Per-lane summary, wave provenance, EXT-2 coverage matrix, what's NOT in the corpus.
  • .claude/knowledge/odoo-extraction-strategies-v1.md — the three proposer legs (Curated/Extracted/ArmDiscovered): what each sees, what each emits, throughput, confidence, council posture, convergence diagram, ProvenanceTier partial order, what the doctrine forbids.
  • .claude/knowledge/odoo-extraction-tools-v1.md — tool stacks: Sonnet-agent fan-out (Leg 1), tools/odoo-blueprint-extractor/ (Leg 2: 654 LOC entry + 950 LOC parsers), planned lance-graph-arm-discovery (Leg 3: 2,400 LOC across 12 D-ARM-*), cross-cutting ruff_spo_triplet language-agnostic SPO IR. Tool-to-leg matrix; "where to find each tool if the session dies"; Stage-2 enrichment targets.
  • .claude/handovers/2026-05-29-2230-odoo-blueprint-survival-dossier.md — verified numbers (66/11563/130/99209/48-of-53), one-paragraph each strategy + tool, five fastest paths into the corpus, six pre-dossier loss-risks (all now captured), concrete next-move priority list.

Canonical count clarification: 66 pub consts (the prior "70" was a fuzzy OdooEntity { literal match including nested struct refs). EXT-6 reported 53 because L11-L15 Wave-3 additions came AFTER 2026-05-28 EXT-6 was authored. Numbers reconcile.

The "5 agents" question identified: Wave 1 (commit f5702675) = 21 entities, L1-L5, 5 Sonnet agents fanned out one-per-lane. Wave 3 (333a1ff2) reused the 5-agent pattern for L11-L15.

Cross-session review notes from #434 author

Surfaced during PR #435 review; pending application:

  • Jirak math bug in plan §4: formula should be n^{-(p/2-1)} not n^{-1/(p/2-1)}. At p=3 the rate IS classical Berry-Esseen, so "stricter than IID" framing only bites for p ∈ (2, 3). Suggested default: p ≈ 2.5 rather than 3.0. Pending fix on this PR.
  • §7 corrections fold into v1.1 amendment (not D-ARM-6 spec-side). docs: unified-soa-convergence-v1 integration plan + handover (ONE SoA end-to-end, 9 consumers, Libet −550 ms kanban, Lance 6.0.1 stack) #434 author offered to author the amendment. Sequencing: D-MBX-A3 (SoA column) should wait for v1.1 to land both discovery_arc + discovery_origin at once, avoiding 2-column→3-column rework.
  • §7.1 reframing: discovery candidates don't "compete" for witness arc — witness arc is committed-revisions-only; the motivation is per-row K-concurrent in-flight hypotheses tracking.
  • Recipe-dedup is intentional (decline CodeRabbit's hard-assert suggestion; style_recipe.rs:84-85 already documents collapse-by-recipe_id).
  • §7 corrections need council ratification (PR feat(odoo): style_recipe D-Atom interpretation + epiphany brainstorm council #433 council-bypass doesn't apply to derived spec refinements).
  • discovery_origin bit layout: widen proposer-id to 3 bits (8 proposers, cheap to pre-reserve) + 3 reserved bits.

Test plan

Files

Code (op_emitter Phase 2):

  • crates/lance-graph-ontology/src/odoo_blueprint/op_emitter.rs (+400 LOC new)
  • crates/lance-graph-ontology/src/odoo_blueprint/mod.rs (+8 lines)

Plans + handovers + governance (ARM-discovery + survival dossier):

  • .claude/plans/streaming-arm-nars-discovery-v1.md (+766 LOC new) — Leg 3 integration plan
  • .claude/handovers/2026-05-29-2030-arm-discovery-author-to-impl.md (+225 LOC) — Leg 3 handover
  • .claude/knowledge/odoo-blueprint-inventory-v1.md (+204 LOC) — 66-entity inventory
  • .claude/knowledge/odoo-extraction-strategies-v1.md (+~240 LOC) — three proposer legs
  • .claude/knowledge/odoo-extraction-tools-v1.md (+~210 LOC) — tool stacks
  • .claude/handovers/2026-05-29-2230-odoo-blueprint-survival-dossier.md (+~140 LOC) — survival pointer
  • .claude/board/INTEGRATION_PLANS.md — prepended ARM-discovery section
  • .claude/board/STATUS_BOARD.md — D-ODOO-OP-1 Shipped row + new ARM-discovery section with D-ARM-1..12
  • .claude/board/AGENT_LOG.md — three prepends (op_emitter shipped; ARM plan authored; survival dossier authored)

https://claude.ai/code/session_017gZ6sPRXYPj5n7uJ7NBtRv

claude added 3 commits May 29, 2026 18:42
…ry SoC)

Groups OdooStyleRecipe corpus by OdooMethodKind dispatch bucket, then emits
deterministic compilable Rust: RECIPE_* collapse-key consts + per-kind Op
structs + per-kind static Op slices. Output is a zero-dep Rust source String
for build.rs → OUT_DIR → include!() integration.

- `BucketedRecipe { method_id, kind, recipe }` — bridge between Phase 1
  (DAtom interpretation) and Phase 2 (codegen dispatch).
- `bucket_corpus(entities)` — walk all entity×method pairs, pair each
  derive_style_recipe output with its semantic OdooMethodKind bucket.
- `emit_op_dispatch(buckets)` — emit header + RECIPE_* consts (sorted by
  recipe_id) + per-kind Op struct + static slice. Deterministic: buckets in
  OdooMethodKind declaration order; within each bucket sorted by recipe_id
  then method_id. Identical DAtom profiles collapse to one RECIPE_* const
  (recipe_id dedup), N Op entries still emitted.
- 12 tests covering: empty corpus, grouping, method_id formatting, recipe dedup,
  determinism, sort order, kind_ord injectivity + roundtrip, atom_comment.
- 230/230 existing lance-graph-ontology tests remain green.

https://claude.ai/code/session_017gZ6sPRXYPj5n7uJ7NBtRv
…NARS → SpoStore proposer leg

Plan: `.claude/plans/streaming-arm-nars-discovery-v1.md` (+766 LOC, 18 §, 12 D-ARM-* deliverables,
10 OQs, 5 risks). Authors the missing UPSTREAM proposer leg into the SPO substrate — runtime
tabular data (20K-200K rows/window) → pair-stats (deterministic trunk) + optional Aerial+ neural
fan-in → NARS-truth translator → SpoStore round-trip hypothesis test (revise / commit
contradiction per The Click) → epiphany-brainstorm-council ratification gate (the firewall) →
op_emitter codegen. Two corrections proposed to PR #434's unified-SoA plan (§7): separate
`discovery_arc: [u32; D]` SoA column for in-flight candidate evidence (distinct from witness-arc
for committed revisions) + `discovery_origin: u8` per-row provenance byte.

Handover: `.claude/handovers/2026-05-29-2030-arm-discovery-author-to-impl.md` — next-session
entry sequence, council ratification ask for `E-DISCOVERY-CODEGEN-BRACKET-1` candidate epiphany +
the §7 corrections, blockers (PR #434 D-MBX-A3 landing, `spo::truth::Contradiction` primitive
verification), Wave 1-8 execution order.

Anchor papers: Karabulut, Groth, Degeler — Neurosymbolic Association Rule Mining (arxiv
2504.19354v1, Apr 2025; ARM `(support, confidence)` maps verbatim to NARS `(c, f)`); Abreu, Cruz,
Guerreiro — Ontology-Driven M2M Transformation (arxiv 2511.13661v1, Nov 2025; §4 "from
code-centric to ontology-driven" ratifies the externalize-interpretation doctrine). The two
papers BRACKET the architecture: discovery upstream, codegen downstream, SPO+NARS middle.

Iron rules: I-NOISE-FLOOR-JIRAK (mandatory Stage A threshold), I-SUBSTRATE-MARKOV (NARS revision
IS the Markov trajectory), I-VSA-IDENTITIES (typed triples never content). Epiphany anchors:
E-SOA-IS-THE-ONLY, E-BATON-1, E-INTERPRET-NOT-STORE-1.

Board hygiene: INTEGRATION_PLANS.md prepend, STATUS_BOARD.md new D-ARM-1..D-ARM-12 section,
AGENT_LOG.md prepend.

Spec only. No code. No cargo invoked.

https://claude.ai/code/session_017gZ6sPRXYPj5n7uJ7NBtRv
@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR documents the completion of ARM discovery planning and specification alongside the Phase 2 bucket-dispatch codegen for Odoo operation emission. The ARM discovery plan defines a five-stage streaming pipeline for association-rule discovery, NARS translation, hypothesis testing, ratification, and downstream codegen. The op_emitter module provides deterministic Rust code generation with recipe deduplication and per-kind dispatch structure emission.

Changes

ARM Discovery Planning & Implementation Handover

Layer / File(s) Summary
Integration Plan Overview and Status
.claude/board/AGENT_LOG.md, .claude/board/INTEGRATION_PLANS.md, .claude/board/STATUS_BOARD.md
New integration plan index entry for streaming-arm-nars-discovery-v1 linked to specification and handover documents; status board updated with shipped Odoo deliverables (D-ODOO-STYLE-1, D-ODOO-OP-1) and queued ARM discovery deliverables (D-ARM-1D-ARM-12).
Technical Specification and Pipeline Design
.claude/plans/streaming-arm-nars-discovery-v1.md
Full 766-line specification defining five-stage discovery pipeline (proposers, ARM-to-NARS translation, hypothesis testing, ratification, deterministic codegen), Jirak thresholding math, 20K–200K row/window throughput regime, SoA integration touchpoints, two proposed schema corrections (discovery_arc, discovery_origin), open questions, risks, and success criteria.
Implementation Sequence and Risk Mitigation
.claude/handovers/2026-05-29-2030-arm-discovery-author-to-impl.md
Handover document recording prerequisite reading order, ratified five-stage pipeline contract, mandatory Stage-A noise-floor gating, open conjectures and blockers, recommended implementation wave sequence by task, explicit risks (Stage D gating complexity, witness-arc separation, benchmark-first approach), and cross-references.

Odoo op_emitter Phase 2 Codegen Implementation

Layer / File(s) Summary
Module Contract and Data Model
crates/lance-graph-ontology/src/odoo_blueprint/mod.rs, crates/lance-graph-ontology/src/odoo_blueprint/op_emitter.rs (lines 1–125)
New public op_emitter module with BucketedRecipe (method ID, dispatch kind, recipe) and EmitStats (method count, unique recipes, per-kind counts) data contracts; bucket_corpus function walks entity methods, derives per-method OdooStyleRecipe, and returns flat corpus paired with OdooMethodKind.
Deterministic Code Generation Engine
crates/lance-graph-ontology/src/odoo_blueprint/op_emitter.rs (lines 126–229)
emit_op_dispatch converts BucketedRecipe corpus to deterministic Rust source (String) plus statistics; deduplicates recipes by recipe_id via BTreeMap, groups entries by kind in declaration order, emits RECIPE_* consts for each unique recipe, emits per-kind *Op structs and *_OPS static slices, enforces determinism via intra-bucket sorting by recipe_id then method_id.
Helper Functions and Utilities
crates/lance-graph-ontology/src/odoo_blueprint/op_emitter.rs (lines 230–325)
Internal helpers: kind_ord/kind_from_ord provide stable OdooMethodKind ordinal mapping; kind_type_name/kind_slice_name derive emitted struct/slice names; atom_comment formats recipe atom weights into human-readable doc-comment strings with empty-recipe handling.
Test Suite and Validation
crates/lance-graph-ontology/src/odoo_blueprint/op_emitter.rs (lines 326–625)
12 comprehensive unit tests validating empty-input codegen, correct per-kind struct/static/const emission, recipe deduplication and unique counts, determinism across repeated calls, intra-bucket entry ordering, kind ordinal roundtrip correctness, and atom_comment formatting edge cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • AdaWorldAPI/lance-graph#433: The new op_emitter::bucket_corpus and emit_op_dispatch functions consume OdooStyleRecipe and DAtom structures defined in PR #433's odoo_blueprint::style_recipe module.

Poem

🐰 A spec so grand, five stages deep,
Discovery streams, while emitters leap,
Recipes bucketed, deterministic and bright,
ARM meets NARS in structured delight!
Phase 2 ships while plans take flight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the two main components of the changeset: Phase 2 op_emitter implementation for Odoo and the streaming ARM→NARS integration plan with documentation.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/activate-lance-graph-att-k2pHI

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

@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

🤖 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/STATUS_BOARD.md:
- Around line 618-635: The STATUS_BOARD shows D-ARM-1..D-ARM-12 but other PR
text still refers to D-ARM-1..D-ARM-9; locate all occurrences of the
"streaming-arm-nars-discovery-v1" section and any references to the D-ARM range
(e.g., "D-ARM-1..D-ARM-9") and make them consistent with the canonical list in
STATUS_BOARD by updating the range and any enumerations to D-ARM-1..D-ARM-12
(or, if the intent is to remain at 1..9, remove/merge entries D-ARM-10..D-ARM-12
to that canonical list); ensure any summaries, tables, and cross-references
(including mentions of specific items like D-ARM-10, D-ARM-11, D-ARM-12, and the
header "streaming-arm-nars-discovery-v1") are updated so all governance docs and
PR text match the same deliverable count.

In @.claude/handovers/2026-05-29-2030-arm-discovery-author-to-impl.md:
- Around line 40-43: The fenced code block containing the pipeline diagram
"parquet stream → Stage A (proposer) → Stage B (translator) → Stage C
(hypothesis test) → Stage D (ratification — epiphany-brainstorm-council) → Stage
E (op_emitter codegen)" needs a language identifier to satisfy markdownlint;
update the opening fence from ``` to ```text so the block is labeled as text
(leave the block contents unchanged) — locate the fenced block in the document
and change only the opening fence to include "text".

In @.claude/plans/streaming-arm-nars-discovery-v1.md:
- Around line 32-81: The fenced pipeline diagram block is missing a language tag
causing markdown lint MD040; update the opening fence in
.claude/plans/streaming-arm-nars-discovery-v1.md from ``` to a tagged fence like
```text (leave the closing ``` unchanged) so the block is recognized as plain
text and the linter warning is resolved.
- Around line 83-84: Update the deliverable-range mentions so they are
consistent: replace every instance of the summary string "D-ARM-1 … D-ARM-9"
with "D-ARM-1 … D-ARM-12" (or vice versa if you intend to shrink the scope) so
it matches the consolidated plan that lists "D-ARM-1 … D-ARM-12"; ensure you
update the top summary occurrence and the other occurrences of the same range
text (the block around the later summary lines that currently reference the
mismatched range) so all mentions of the deliverable range are identical.
- Around line 381-383: The numeric examples in the threshold section
mis-evaluate the exponent from the formula n^{-1/(p/2-1)}; update the text in
the "jirak" module threshold discussion to use the correct arithmetic (exponent
= -1/(p/2 - 1)), e.g. p=4 -> n^{-1}, p=3.0 -> n^{-2}, p=2.5 -> n^{-4}, and
correct the example lines referenced (the current incorrect statements around
the threshold section and the later repeat) so the narrative and any operational
guidance for the jirak module consistently reflect these corrected exponents.

In `@crates/lance-graph-ontology/src/odoo_blueprint/op_emitter.rs`:
- Around line 136-139: The current collapse into recipe_map using recipe_id only
(recipe_map, buckets, OdooStyleRecipe) can silently merge different profiles
that share an ID; update the insertion logic to validate that any existing
&OdooStyleRecipe for a given recipe_id is equivalent to the incoming b.recipe
(compare the relevant profile fields or compute a stable profile hash), and if
they differ either (a) surface an explicit error/ panic or (b) use a
disambiguating key (e.g., recipe_id + profile_hash) instead of recipe_id alone,
so mismatched profiles are never silently overwritten.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 51fd3ae7-696d-48fa-b069-517ed785c7c5

📥 Commits

Reviewing files that changed from the base of the PR and between 1186dfd and 718a142.

📒 Files selected for processing (7)
  • .claude/board/AGENT_LOG.md
  • .claude/board/INTEGRATION_PLANS.md
  • .claude/board/STATUS_BOARD.md
  • .claude/handovers/2026-05-29-2030-arm-discovery-author-to-impl.md
  • .claude/plans/streaming-arm-nars-discovery-v1.md
  • crates/lance-graph-ontology/src/odoo_blueprint/mod.rs
  • crates/lance-graph-ontology/src/odoo_blueprint/op_emitter.rs

Comment on lines +618 to +635
## streaming-arm-nars-discovery-v1 — upstream proposer leg into the SPO substrate (20K-200K rows/window pair-stats + optional Aerial+ → NARS-truth → SpoStore hypothesis test → council ratification → op_emitter codegen)

The missing UPSTREAM discovery leg. Today's proposers (curated L-docs + AST-extracted Odoo source) are bounded by the literal artifact; this plan adds runtime-tabular-data ARM discovery, gated through the epiphany-brainstorm-council before reaching the deterministic codegen path. Plan: `.claude/plans/streaming-arm-nars-discovery-v1.md`. Handover: `.claude/handovers/2026-05-29-2030-arm-discovery-author-to-impl.md`.

| D-id | Title | Crate | Lines | Conf | Status | Notes |
|---|---|---|---|---|---|---|
| D-ARM-1 | `ProvenanceTier::{Curated,Extracted,ArmDiscovered,Ratified,Conjecture}` enum + ordering | lance-graph-contract | 50 | HIGH | **Queued** | blocks all other D-ARM-*; additive |
| D-ARM-2 | `Proposer` trait + `CandidateRule` carrier + `WindowMetadata` | lance-graph-contract | 100 | HIGH | **Queued** | blocks D-ARM-3, D-ARM-9 |
| D-ARM-3 | Pair-stats proposer (default trunk, deterministic, k² pair counters per window) | lance-graph-arm-discovery::proposer::pair_stats | 400 | HIGH | **Queued** | depends on D-ARM-1/2/7; blocks D-ARM-12 |
| D-ARM-4 | ARM-truth → NARS-truth translator + Odoo `FeedProjector` impl | lance-graph-arm-discovery::translator | 200 | HIGH | **Queued** | depends on D-ARM-1/2 |
| D-ARM-5 | Hypothesis test: SpoStore round-trip, NARS revision, contradiction commit per The Click | lance-graph-arm-discovery::hypothesis | 350 | MED | **Queued** | depends on D-ARM-4; verifies `spo::truth::Contradiction` primitive exists |
| D-ARM-6 | `RatificationQueue` ring buffer + corrections-to-#434 spec PR (`discovery_arc D=8`, `discovery_origin u8`) | lance-graph-arm-discovery::queue + #434 spec follow-up | 200 + spec | MED | **Queued** | depends on PR #434 D-MBX-A3 landing |
| D-ARM-7 | Jirak-2016 weak-dependence significance thresholds (mandatory Stage A floor) | lance-graph-arm-discovery::jirak | 150 | HIGH | **Queued** | blocks D-ARM-3; cites I-NOISE-FLOOR-JIRAK |
| D-ARM-8 | `Feed` + `FeedProjector` + window-size config + Odoo `account.move` projector example | lance-graph-arm-discovery::feed | 250 | MED | **Queued** | depends on D-ARM-2 |
| D-ARM-9 | Aerial+ IPC client (feature-gated `arm-aerial`, NDJSON over Unix socket) | lance-graph-arm-discovery::proposer::aerial_ipc | 200 | MED | **Queued** | optional; depends on D-ARM-2 |
| D-ARM-10 | `op_emitter::bucket_corpus` ratification filter (`confidence ≥ Ratified`) + 2 tests | lance-graph-ontology::op_emitter | 30 | HIGH | **Queued** | depends on D-ARM-1 |
| D-ARM-11 | `style_recipe.rs` rule 8 — ArmDiscovered backing adds `DAtom::Compute` weight 2 (provisional) | lance-graph-ontology::style_recipe | 80 | MED | **Queued** | depends on D-ARM-1 |
| D-ARM-12 | End-to-end pipeline test + bench (synthetic Odoo feed → all 5 stages → council micro-batch) | lance-graph-arm-discovery::tests + benches | 400 | MED | **Queued** | depends on Waves 1-6; informs OQ-ARM-2 + OQ-ARM-7 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align D-ARM deliverable count across governance docs.

This section tracks D-ARM-1..D-ARM-12, while related text elsewhere in this PR still states D-ARM-1..D-ARM-9. Please normalize the count/range to avoid planning drift and board/report mismatch.

🤖 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/STATUS_BOARD.md around lines 618 - 635, The STATUS_BOARD shows
D-ARM-1..D-ARM-12 but other PR text still refers to D-ARM-1..D-ARM-9; locate all
occurrences of the "streaming-arm-nars-discovery-v1" section and any references
to the D-ARM range (e.g., "D-ARM-1..D-ARM-9") and make them consistent with the
canonical list in STATUS_BOARD by updating the range and any enumerations to
D-ARM-1..D-ARM-12 (or, if the intent is to remain at 1..9, remove/merge entries
D-ARM-10..D-ARM-12 to that canonical list); ensure any summaries, tables, and
cross-references (including mentions of specific items like D-ARM-10, D-ARM-11,
D-ARM-12, and the header "streaming-arm-nars-discovery-v1") are updated so all
governance docs and PR text match the same deliverable count.

Comment on lines +40 to +43
```
parquet stream → Stage A (proposer) → Stage B (translator) → Stage C (hypothesis test)
→ Stage D (ratification — epiphany-brainstorm-council) → Stage E (op_emitter codegen)
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add language identifier to fenced code block.

The fenced code block lacks a language specification, which markdownlint flags. Since this is a pipeline diagram, use text as the identifier.

📝 Proposed fix
-  ```
+  ```text
   parquet stream → Stage A (proposer) → Stage B (translator) → Stage C (hypothesis test)
   → Stage D (ratification — epiphany-brainstorm-council) → Stage E (op_emitter codegen)
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

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

(MD040, fenced-code-language)

🤖 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/handovers/2026-05-29-2030-arm-discovery-author-to-impl.md around
lines 40 - 43, The fenced code block containing the pipeline diagram "parquet
stream → Stage A (proposer) → Stage B (translator) → Stage C (hypothesis test) →
Stage D (ratification — epiphany-brainstorm-council) → Stage E (op_emitter
codegen)" needs a language identifier to satisfy markdownlint; update the
opening fence from ``` to ```text so the block is labeled as text (leave the
block contents unchanged) — locate the fenced block in the document and change
only the opening fence to include "text".

Comment on lines +32 to +81
```
parquet/stream
▼ Stage A — proposers (parallel feeds)
┌──────────────────────────────────────────────────────────────┐
│ A1. Streaming pair-stats [deterministic, default trunk] │
│ sufficient statistics per (item_i, item_j) over window │
│ → support, confidence, Jirak-bound significance │
│ A2. Aerial+ neural-symbolic [optional, behind feature flag] │
│ autoencoder + reconstruction-probe rule extraction │
│ → support, confidence (paper Algorithm 1) │
└──────────────────────────────────────────────────────────────┘
▼ Stage B — translator (ARM truth → NARS truth)
┌──────────────────────────────────────────────────────────────┐
│ confidence (ARM) → frequency (NARS f ∈ [0, 1]) │
│ support × window_size → confidence (NARS c ∈ [0, 1)) │
│ → CandidateTriple { s, p, o, truth: TruthValue, origin } │
└──────────────────────────────────────────────────────────────┘
▼ Stage C — hypothesis test (against SpoStore + EdgeColumn)
┌──────────────────────────────────────────────────────────────┐
│ for each candidate: │
│ prior = SpoStore::lookup(s,p,o) │
│ match prior │
│ ─ Some(t) → SpoStore::revise(t, candidate.truth) │
│ (NARS revision; widens confidence, weights │
│ frequency by inverse variance) │
│ ─ Contradiction(prior, c, candidate, c') → │
│ commit a Contradiction edge per The Click │
│ ─ None → queue for ratification (Stage D) │
└──────────────────────────────────────────────────────────────┘
▼ Stage D — ratification (epiphany-brainstorm-council gate)
┌──────────────────────────────────────────────────────────────┐
│ threshold-survive candidates with `origin = ArmDiscovery` │
│ pass through the 5-savant council before becoming a triple │
│ the codegen path consumes. NEVER auto-promote — discovery │
│ is the Epiphany branch of The Click, not the Commit branch.│
└──────────────────────────────────────────────────────────────┘
▼ Stage E — codegen (op_emitter consumes ratified)
┌──────────────────────────────────────────────────────────────┐
│ `op_emitter::emit_op_dispatch` takes ratified triples that │
│ carry `OdooConfidence::Ratified` (new variant) and emits │
│ `RECIPE_* ` consts + per-kind Op slices. Determinism rests │
│ on the ratification gate — Stage D is the firewall between │
│ nondeterministic proposers and deterministic compile path. │
└──────────────────────────────────────────────────────────────┘
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language tag to the fenced code block to satisfy markdown linting.

The pipeline block is an untyped fenced block; assign a language (for example text) to clear MD040 and keep docs lint-clean.

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

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

(MD040, fenced-code-language)

🤖 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/streaming-arm-nars-discovery-v1.md around lines 32 - 81, The
fenced pipeline diagram block is missing a language tag causing markdown lint
MD040; update the opening fence in
.claude/plans/streaming-arm-nars-discovery-v1.md from ``` to a tagged fence like
```text (leave the closing ``` unchanged) so the block is recognized as plain
text and the linter warning is resolved.

Comment on lines +83 to +84
Total new crates: **1** (`lance-graph-arm-discovery`). Total new deliverables: **D-ARM-1 … D-ARM-9**. Two corrections to PR #434's unified-SoA plan (§7 of this doc): an extra `discovery_arc` SoA column and a `discovery_origin: u8` provenance byte.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Resolve internal deliverable-range mismatch (1..9 vs 1..12).

At Line 83, the summary says “D-ARM-1 … D-ARM-9”, but the consolidated plan/table defines D-ARM-1 … D-ARM-12. Please make the top summary match the final scope.

Also applies to: 513-529

🤖 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/streaming-arm-nars-discovery-v1.md around lines 83 - 84,
Update the deliverable-range mentions so they are consistent: replace every
instance of the summary string "D-ARM-1 … D-ARM-9" with "D-ARM-1 … D-ARM-12" (or
vice versa if you intend to shrink the scope) so it matches the consolidated
plan that lists "D-ARM-1 … D-ARM-12"; ensure you update the top summary
occurrence and the other occurrences of the same range text (the block around
the later summary lines that currently reference the mismatched range) so all
mentions of the deliverable range are identical.

Comment on lines +381 to +383
Jirak (correct): the threshold scales as `n^{-1/(p/2-1)}` with `p` the moment characterizing dependence (p=4 → `n^{-1/2}`, p=2.5 → `n^{-0.25}`). For ARM items with shared categorical encoding and partial-order purchase dependence (the canonical weak-dependence pattern), p ≈ 3.0 is a reasonable default, giving `n^{-1}` decay — much stricter than the IID `n^{-1/2}`.

**Operational consequence for D-ARM-7:** the `jirak` module exposes:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix Jirak exponent arithmetic in the threshold section.

The numeric examples don’t match the formula n^{-1/(p/2-1)}.
At Line 381-382, p=3.0 gives exponent -2 (not -1), and p=2.5 gives -4 (not -0.25). This materially changes the proposed threshold behavior and should be corrected before implementation guidance is consumed.

Also applies to: 393-394

🤖 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/streaming-arm-nars-discovery-v1.md around lines 381 - 383, The
numeric examples in the threshold section mis-evaluate the exponent from the
formula n^{-1/(p/2-1)}; update the text in the "jirak" module threshold
discussion to use the correct arithmetic (exponent = -1/(p/2 - 1)), e.g. p=4 ->
n^{-1}, p=3.0 -> n^{-2}, p=2.5 -> n^{-4}, and correct the example lines
referenced (the current incorrect statements around the threshold section and
the later repeat) so the narrative and any operational guidance for the jirak
module consistently reflect these corrected exponents.

Comment on lines +136 to +139
let mut recipe_map: BTreeMap<u32, &OdooStyleRecipe> = BTreeMap::new();
for b in buckets {
recipe_map.entry(b.recipe.recipe_id).or_insert(&b.recipe);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate recipe profile equivalence before collapsing by recipe_id.

At Line 136–Line 139, dedup uses only recipe_id. If two distinct profiles ever share an ID, they’re silently merged, producing incorrect generated dispatch metadata.

Proposed guard against accidental collision collapse
-    for b in buckets {
-        recipe_map.entry(b.recipe.recipe_id).or_insert(&b.recipe);
-    }
+    for b in buckets {
+        match recipe_map.entry(b.recipe.recipe_id) {
+            std::collections::btree_map::Entry::Vacant(v) => {
+                v.insert(&b.recipe);
+            }
+            std::collections::btree_map::Entry::Occupied(o) => {
+                let existing = o.get();
+                assert!(
+                    existing.atoms == b.recipe.atoms
+                        && existing.regulation_iris == b.recipe.regulation_iris
+                        && existing.return_kind == b.recipe.return_kind,
+                    "recipe_id collision with non-identical profiles: 0x{:08X}",
+                    b.recipe.recipe_id
+                );
+            }
+        }
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let mut recipe_map: BTreeMap<u32, &OdooStyleRecipe> = BTreeMap::new();
for b in buckets {
recipe_map.entry(b.recipe.recipe_id).or_insert(&b.recipe);
}
let mut recipe_map: BTreeMap<u32, &OdooStyleRecipe> = BTreeMap::new();
for b in buckets {
match recipe_map.entry(b.recipe.recipe_id) {
std::collections::btree_map::Entry::Vacant(v) => {
v.insert(&b.recipe);
}
std::collections::btree_map::Entry::Occupied(o) => {
let existing = o.get();
assert!(
existing.atoms == b.recipe.atoms
&& existing.regulation_iris == b.recipe.regulation_iris
&& existing.return_kind == b.recipe.return_kind,
"recipe_id collision with non-identical profiles: 0x{:08X}",
b.recipe.recipe_id
);
}
}
}
🤖 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-ontology/src/odoo_blueprint/op_emitter.rs` around lines
136 - 139, The current collapse into recipe_map using recipe_id only
(recipe_map, buckets, OdooStyleRecipe) can silently merge different profiles
that share an ID; update the insertion logic to validate that any existing
&OdooStyleRecipe for a given recipe_id is equivalent to the incoming b.recipe
(compare the relevant profile fields or compute a stable profile hash), and if
they differ either (a) surface an explicit error/ panic or (b) use a
disambiguating key (e.g., recipe_id + profile_hash) instead of recipe_id alone,
so mismatched profiles are never silently overwritten.

@AdaWorldAPI AdaWorldAPI merged commit bcc3786 into main May 30, 2026
6 checks passed
@AdaWorldAPI AdaWorldAPI changed the title feat(odoo) + docs(arm-discovery): op_emitter Phase 2 + streaming ARM→NARS integration plan feat(odoo) + docs: op_emitter Phase 2 + ARM-discovery plan + Odoo blueprint survival dossier May 30, 2026
AdaWorldAPI pushed a commit that referenced this pull request May 30, 2026
…rigin / ProvenanceTier (vs every conflicting source)

User: "only document the details ... the original was wrong, codex/coderabbit
was wrong, you or the other session suggested to fix it or already fixed it
and I don't know what is correct."

This doc resolves the epistemic confusion. Documentation ONLY — no code or
plan modified.

Verified ground truth (file:line citations, not memory):
- 66 (not 70) OdooEntity consts; all reachable from #435 HEAD 4a6c277; indexed
- discovery_origin / ProvenanceTier exist in ZERO .rs files — only 7 .claude docs.
  The byte has NOT hardened in the WAL. Window to fix the width is OPEN; no migration owed.
- mod.rs:450 OdooConfidence = {Curated, Extracted, Conjecture} (3 variants) is the
  only provenance enum that compiles today.

The conflict, laid out with arithmetic:
- ProvenanceTier named across the corpus = 6 distinct concepts (Curated/Extracted/
  Conjecture/ArmDiscovered/Ratified/Derived) but every layout gives it a 2-bit
  field = 4 slots. 6 > 4. My own plan contradicts itself (§7.2 = 4 tiers, D-ARM-1 = 5).
- proposer-id width: committed #435 layout = 2 bits (4 slots, full); cross-session
  review = 3 bits (8); canonical core spec = 3 bits but declares it INSUFFICIENT and
  says widen to 6 bits (64) or u16. The committed version is the most-wrong.

What is correct (per the now-canonical uploaded cognitive-risc specs):
- proposer-id -> 6 bits (64) or move discovery_origin to u16. Headline correction.
- ProvenanceTier stable 4 = {Curated, Extracted, ArmDiscovered, Ratified}; treat
  Derived as a separate reasoning-provenance axis; decide Conjecture's fate.
- Canonical specs disagree with THEMSELVES on the tier set (core: ArmDiscovered/
  Ratified; wikidata: Derived) — one reconciliation pass owed.

Open decisions left explicitly to the user (OD-1 width, OD-2 Conjecture/Derived,
OD-3 code/spec divergence). Jirak math flagged as the second contested detail with
fix direction (n^-(p/2-1), default p~2.5) but exact in-file target must be re-verified
when backend is healthy before patching.

Canonical specs are NOT on this branch — they live on
origin/claude/cognitive-risc-core-9PMW8; relevant lines quoted inline for self-containment.

https://claude.ai/code/session_017gZ6sPRXYPj5n7uJ7NBtRv
AdaWorldAPI pushed a commit that referenced this pull request May 30, 2026
…rigin / ProvenanceTier (vs every conflicting source)

User: "only document the details ... the original was wrong, codex/coderabbit
was wrong, you or the other session suggested to fix it or already fixed it
and I don't know what is correct."

This doc resolves the epistemic confusion. Documentation ONLY — no code or
plan modified.

Verified ground truth (file:line citations, not memory):
- 66 (not 70) OdooEntity consts; all reachable from #435 HEAD 4a6c277; indexed
- discovery_origin / ProvenanceTier exist in ZERO .rs files — only 7 .claude docs.
  The byte has NOT hardened in the WAL. Window to fix the width is OPEN; no migration owed.
- mod.rs:450 OdooConfidence = {Curated, Extracted, Conjecture} (3 variants) is the
  only provenance enum that compiles today.

The conflict, laid out with arithmetic:
- ProvenanceTier named across the corpus = 6 distinct concepts (Curated/Extracted/
  Conjecture/ArmDiscovered/Ratified/Derived) but every layout gives it a 2-bit
  field = 4 slots. 6 > 4. My own plan contradicts itself (§7.2 = 4 tiers, D-ARM-1 = 5).
- proposer-id width: committed #435 layout = 2 bits (4 slots, full); cross-session
  review = 3 bits (8); canonical core spec = 3 bits but declares it INSUFFICIENT and
  says widen to 6 bits (64) or u16. The committed version is the most-wrong.

What is correct (per the now-canonical uploaded cognitive-risc specs):
- proposer-id -> 6 bits (64) or move discovery_origin to u16. Headline correction.
- ProvenanceTier stable 4 = {Curated, Extracted, ArmDiscovered, Ratified}; treat
  Derived as a separate reasoning-provenance axis; decide Conjecture's fate.
- Canonical specs disagree with THEMSELVES on the tier set (core: ArmDiscovered/
  Ratified; wikidata: Derived) — one reconciliation pass owed.

Open decisions left explicitly to the user (OD-1 width, OD-2 Conjecture/Derived,
OD-3 code/spec divergence). Jirak math flagged as the second contested detail with
fix direction (n^-(p/2-1), default p~2.5) but exact in-file target must be re-verified
when backend is healthy before patching.

Canonical specs are NOT on this branch — they live on
origin/claude/cognitive-risc-core-9PMW8; relevant lines quoted inline for self-containment.

https://claude.ai/code/session_017gZ6sPRXYPj5n7uJ7NBtRv
AdaWorldAPI pushed a commit that referenced this pull request May 30, 2026
…rigin / ProvenanceTier (vs every conflicting source)

User: "only document the details ... the original was wrong, codex/coderabbit
was wrong, you or the other session suggested to fix it or already fixed it
and I don't know what is correct."

This doc resolves the epistemic confusion. Documentation ONLY — no code or
plan modified.

Verified ground truth (file:line citations, not memory):
- 66 (not 70) OdooEntity consts; all reachable from #435 HEAD 4a6c277; indexed
- discovery_origin / ProvenanceTier exist in ZERO .rs files — only 7 .claude docs.
  The byte has NOT hardened in the WAL. Window to fix the width is OPEN; no migration owed.
- mod.rs:450 OdooConfidence = {Curated, Extracted, Conjecture} (3 variants) is the
  only provenance enum that compiles today.

The conflict, laid out with arithmetic:
- ProvenanceTier named across the corpus = 6 distinct concepts (Curated/Extracted/
  Conjecture/ArmDiscovered/Ratified/Derived) but every layout gives it a 2-bit
  field = 4 slots. 6 > 4. My own plan contradicts itself (§7.2 = 4 tiers, D-ARM-1 = 5).
- proposer-id width: committed #435 layout = 2 bits (4 slots, full); cross-session
  review = 3 bits (8); canonical core spec = 3 bits but declares it INSUFFICIENT and
  says widen to 6 bits (64) or u16. The committed version is the most-wrong.

What is correct (per the now-canonical uploaded cognitive-risc specs):
- proposer-id -> 6 bits (64) or move discovery_origin to u16. Headline correction.
- ProvenanceTier stable 4 = {Curated, Extracted, ArmDiscovered, Ratified}; treat
  Derived as a separate reasoning-provenance axis; decide Conjecture's fate.
- Canonical specs disagree with THEMSELVES on the tier set (core: ArmDiscovered/
  Ratified; wikidata: Derived) — one reconciliation pass owed.

Open decisions left explicitly to the user (OD-1 width, OD-2 Conjecture/Derived,
OD-3 code/spec divergence). Jirak math flagged as the second contested detail with
fix direction (n^-(p/2-1), default p~2.5) but exact in-file target must be re-verified
when backend is healthy before patching.

Canonical specs are NOT on this branch — they live on
origin/claude/cognitive-risc-core-9PMW8; relevant lines quoted inline for self-containment.

https://claude.ai/code/session_017gZ6sPRXYPj5n7uJ7NBtRv
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