feat(contract): materialize — the closed F→34→F awareness-dispatch loop (materialized awareness)#515
Conversation
Wires the 34 reasoning tactics (recipe_kernels) into a closed active-inference loop so awareness MATERIALIZES (is causal in dispatch) instead of sitting inert. The map showed the gap precisely: the 34 tactics were dispatch targets with no state→id selector and an open loop (they ran only in an example vs a toy ctx; the driver loop ran the 12 threshold ordinals, leaving the rich 34 inert). New module lance-graph-contract::materialize (zero-dep, offline): - select_tactic(&ThoughtCtx) -> u8 — the missing selector; free_energy (surprise) is the PRIMARY axis so dispatch tracks awareness by construction; dissonance/ sd(gate)/rung(tier) are secondary modulators; scored over recipe metadata. - materialize(&mut ThoughtCtx, max) -> Trace — the closed loop: select → Tactic::run (folds delta_conf) → settle gate (dispersion/contradiction decay) → recompute surprise → re-dispatch; rest GUARANTEED at CollapseGate FLOW. - awareness_is_causal(base, lo_f, hi_f) — the materialization predicate/falsifier. - recompute_free_energy, Step, Trace, HOMEOSTASIS_FLOOR. Decision (autonomous): recipe_kernels is the canonical "34" (ndarray hpc/styles/* is divergent/registry-less). ThoughtCtx already carries the awareness markers. The materialization criterion (falsifiable): awareness materializes iff perturbing it changes which tactic fires. Tests prove it: free_energy is causal in dispatch (+ sweep ranges ≥2 tactics), non-awareness fields (candidates/beliefs) are inert (specificity), the loop rests at FLOW within a few steps, is deterministic, ranges over the 34, and an at-rest ctx dispatches nothing. 6 tests green (+632 prior contract lib); clippy --all-targets -D warnings clean. Board: EPIPHANIES E-MATERIALIZED-AWARENESS-1 + LATEST_STATE contract inventory. Open (gated): driver-side ThoughtCtx::from_live + version-diff "what-fired-why" provenance. Prior-art positioning + [G] orientation boundary in the epiphany.
|
Warning Review limit reached
More reviews will be available in 20 minutes and 51 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughAdds ChangesMaterialized Awareness Dispatch Loop
Sequence Diagram(s)sequenceDiagram
participant Caller
participant materialize
participant gate_of
participant select_tactic
participant kernel
participant awareness_is_causal
Caller->>materialize: materialize(&mut ThoughtCtx, max_steps)
loop until GateState::FLOW or max_steps exhausted
materialize->>gate_of: gate_of(ctx.sd)
gate_of-->>materialize: GateState
materialize->>select_tactic: select_tactic(&ctx)
select_tactic-->>materialize: tactic_id: u8
materialize->>kernel: kernel(tactic_id).run(&mut ctx)
kernel-->>materialize: fired: bool, delta_conf: f32
materialize->>materialize: settle sd/dissonance, recompute_free_energy
materialize->>materialize: push Step{tactic_id, fired, delta_conf}
end
materialize-->>Caller: Trace{steps, rested, final_confidence, final_free_energy}
Caller->>awareness_is_causal: awareness_is_causal(&base, lo_f, hi_f)
awareness_is_causal->>select_tactic: select_tactic(&ctx_lo)
awareness_is_causal->>select_tactic: select_tactic(&ctx_hi)
select_tactic-->>awareness_is_causal: tactic_id_lo, tactic_id_hi
awareness_is_causal-->>Caller: tactic_id_lo != tactic_id_hi
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ab7f2034c4
ℹ️ 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".
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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/EPIPHANIES.md:
- Around line 6-8: In the criterion description for
`materialize::awareness_is_causal`, clarify that the "awareness encoding" being
perturbed is specifically `ThoughtCtx.free_energy` (the surprise metric).
Replace the abstract term "awareness encoding" with explicit reference to
free-energy/surprise as the primary causal knob, and ensure the wording makes
clear that this is the variable the test actually modulates to verify causality
in dispatch behavior.
In `@crates/lance-graph-contract/src/materialize.rs`:
- Line 160: The Vec::with_capacity(max_steps) call on the steps variable is
pre-allocating an unbounded amount of memory based on caller-provided input
before validating the context. Either initialize steps using Vec::new() instead
of with_capacity to avoid upfront allocation, or apply a reasonable upper bound
to the capacity value. Ensure the validation check (verifying context is in FLOW
state) happens before memory reservation to prevent potential denial of service
through excessive allocation.
- Around line 169-172: The settle update operations that modify ctx.sd,
ctx.dissonance, and ctx.free_energy are currently executing unconditionally
after tactic.run(ctx), even when the tactic does not fire. Wrap the settle decay
statements (ctx.sd *= SETTLE_SD, ctx.dissonance *= SETTLE_DISSONANCE, and
ctx.free_energy = recompute_free_energy(ctx)) in a conditional block that checks
if out.fired is true, ensuring these state modifications only occur when the
tactic actually fires rather than on no-op executions.
- Around line 73-110: The mechanism selection logic in the `want_mech` block
currently short-circuits on high dissonance (ctx.dissonance >= 0.5), preventing
free_energy thresholds from being evaluated when dissonance is high. This makes
dissonance the primary dispatch axis instead of free_energy. Restructure the
condition chain to check the free_energy thresholds (>= 0.66, >= 0.33) first to
determine the primary mechanism selection, then apply dissonance as a secondary
signal that can either adjust the selected mechanism or influence the
tie-breaking logic when the primary dispatch axis does not provide a clear
winner.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 7057798a-891b-4d5e-a010-54dc5463aece
📒 Files selected for processing (4)
.claude/board/EPIPHANIES.md.claude/board/LATEST_STATE.mdcrates/lance-graph-contract/src/lib.rscrates/lance-graph-contract/src/materialize.rs
…needs low F
Six review findings on the F→34→F loop, all valid:
1/4 select_tactic: free_energy is now the SOLE primary axis (mechanism
band), with dissonance demoted to a +1 tie-weight toward inference
tactics. The prior `dissonance >= 0.5` short-circuit overrode the
surprise-chosen mechanism, breaking the module's own materialization
criterion for any contradicted base. Mechanism match now scores +5 so
it strictly outweighs bucket(2)+tier(1)+reconcile(1).
2 materialize: settle/attend (sd↓, dissonance↓, confidence↑) now apply
ONLY on a tactic that actually fired — a blocked tactic must not fake
progress; the loop ends rather than spin on an unchanged state.
5 rest now requires gate FLOW AND surprise < HOMEOSTASIS_FLOOR — a cool
gate with unresolved surprise is not rest. Added ATTEND_GAIN (0.35)
so confidence rises each fired step, guaranteeing reported surprise
descends (active inference), not just sd decay.
6 bounded Vec::with_capacity(max_steps.min(64)).
3 EPIPHANIES E-MATERIALIZED-AWARENESS-1 wording: "perturbing the
awareness encoding" → "the surprise/free-energy signal"; rest
condition corrected to FLOW && surprise<floor.
Tests: added a dissonance=0.7 regression (surprise stays causal under
contradiction); already_at_rest now sets confidence=0.95/dissonance=0.0
so the stricter rest condition holds. 6/6 green, clippy clean.
Co-Authored-By: Claude <noreply@anthropic.com>
|
Resolved all 6 review findings in 22e50f5 — all were valid:
6/6 tests green, clippy clean. Generated by Claude Code |
…, cycle untouched) Wires the materialize F→34→F loop + ndarray HHTL fork_decision into the live cognitive-shader-driver cycle as a SIDE analysis. Per operator decision 2026-06-17: provenance-only — the gate/emit/persistence path is byte-for-byte unchanged; the analysis only records what the 34 would dispatch and whether the leaf residue forks. - contract: MaterializeProvenance (primitive-only Copy: first_tactic/steps/ rested/final_free_energy/fork:u8) as a new ShaderCrystal field; fork is ForkAction-as-u8 so the zero-dep crate doesn't import ndarray. - driver: materialize_provenance() builds a ThoughtCtx from the cycle's own observables (sd←std_dev exact, confidence←1−F, dissonance←|felt−demonstrated| DK gap), runs materialize, and computes fork_decision. The fork challenge is a std_dev dispersion proxy (CONJECTURE) with a std_dev-calibrated floor/σ — pending the real orthogonal CoarseResidue magnitude + real HHTL cascade depth (depth==max⇒leaf for now). - tests: confident cycle→Commit, scattered low-skill→ForkDomain; dispatch populates provenance (first_tactic==0 = at-rest case). 638 contract lib + driver tests green. Board: LATEST_STATE contract inventory + EPIPHANIES E-MATERIALIZED-AWARENESS-2 (the four-vocabulary unification grounded in shipped types). Co-Authored-By: Claude <noreply@anthropic.com>
…eflight
Read-based map (full reads of every critical-path consumer + two Opus inventory
agents for the rest) produced BEFORE any wiring, per operator directive ("map
the many dependencies before"; "two paths step by step, never delete the old
before testing the new"; "CausalEdge64 is duplicated — no handwaving").
Contents:
- §0 the two stores side by side; the D-MBX-A2 gap (content/topic/angle dense
hot per OQ-1-resolved, sigma, temporal, expert); cycle (Vsa16kF32) = DROP.
- §1 the CausalEdge64 duplication mapped exactly: causal_edge::edge (SPO baton,
used everywhere) vs ndarray::hpc::causal_diff (weight-diff codec, NEVER
imported into lance-graph). Both repr(transparent)/u64 → silent-corruption
hazard at the u64 level. The contract's raw-u64 edges_raw() is the firewall;
typed reattach only at MailboxSoA owner + p64-bridge. v2 layout drops temporal.
- §2 consumer map: column hot-spots (engine_bridge + driver), the 2 bin
construction sites, the 4 Arc::get_mut single-owner hazards, the singleton-
bound tests, and the ALREADY-built cold side (surreal_container
SurrealMailboxView impls MailboxSoaView; scheduler generic over it; the
driver already holds both bindspace + mailboxes).
- §3 W0–W7 delete-last wiring sequence (parity test W1, differential test W2,
feature-gated engine_bridge/dispatch swap W3/W4, bins W5, tombstone W6,
delete BindSpace LAST W7).
- §4 dedup hazards checklist.
No source wired. Branch off main (post-#516), independent of the open #515.
Co-Authored-By: Claude <noreply@anthropic.com>
CodeRabbit review on #517, both valid: - doc: sigma/temporal/expert were marked **GAP** in the §0 mapping table while the W1 DONE section said shipped — contradiction. Updated the three rows to **SHIPPED (W1)** and the "remaining D-MBX-A2 gap" line to content/topic/angle only (the W1b heap planes). - test: added test_mailbox_soa_reset_row_clears_a2_columns — reset_row() must clear the new temporal/expert/sigma columns (migration-invariant regression guard). 14 mailbox_soa tests green. Also rebased onto post-#515 main (e063416) so W1b will wire against the merged driver (which now carries the MaterializeProvenance provenance wire). Co-Authored-By: Claude <noreply@anthropic.com>
What
Wires the 34 reasoning tactics (
recipe_kernels) into a closedF → 34 → Factive-inference loop, so awareness materializes (is causal in dispatch) instead of sitting inert. Autonomous build per the "auto-resolve research probing" go-ahead.The dispatch-path map found the gap precisely: the 34 tactics were dispatch targets with no
state→idselector and an open loop (they ran only inexamples/cognitive_cycle.rsagainst a toy ctx; the driver loop ran the 12 threshold ordinals — the rich 34 were inert).ThoughtCtxalready carries the awareness markers (free_energy,sd,dissonance,confidence,rung);Tactic::runalready foldsdelta_conf. The missing piece was the selector + loop driver — this module.New module
lance-graph-contract::materialize(zero-dep, offline)select_tactic(&ThoughtCtx) -> u8— the missing selector;free_energy(surprise) is the primary axis so dispatch tracks awareness by construction;dissonance/sd(gate)/rung(tier) secondary; scored overrecipesmetadata (Mechanism/Bucket/Tier).materialize(&mut ThoughtCtx, max) -> Trace— the closed loop: select →Tactic::run→ settle gate (dispersion/contradiction decay) → recompute surprise → re-dispatch; rest guaranteed at CollapseGate FLOW (sd<SD_FLOW).awareness_is_causal(base, lo_f, hi_f)— the materialization predicate / falsifier.recompute_free_energy,Step,Trace,HOMEOSTASIS_FLOOR.The materialization criterion (falsifiable, tested)
6 tests green:
free_energyis causal in dispatch (+ sweep ranges ≥2 tactics); non-awareness fields (candidates/beliefs) are inert (specificity); the loop rests at FLOW within a few steps; deterministic; ranges over the 34; at-rest ctx dispatches nothing. (+632 prior contract lib tests; clippy--all-targets -D warningsclean.)Autonomous decisions
recipe_kernelsis the canonical "34" (ndarrayhpc/styles/*is divergent / registry-less → not canonical).contract(zero-dep, offline-green) — no spine-lock risk, no flaky lance-7 link.Grade & positioning
[NOVEL — probe-gated] by construction (no prior art for the 2³-rung→NARS-candidate→34-tactic loop — it's ours). Prior-art positioning (not competitors): NOTEARS/PCMCI/DCDI/ICP/SEA. Operating boundary respected [G]: Janzing-Schölkopf (Shannon-symmetric, colliders-only observationally) — dispatch claims revisable candidates, never identified orientation.
Open (gated, follow-up)
Driver-side wire: build
ThoughtCtx::from_livefromFreeEnergy/MulAssessment/hits indriver.rs, fold the dispatchTraceinto the SoA EdgeColumn / version-diff "what-fired-why" provenance. The materialization probe is the acceptance test for that wire too.Board:
EPIPHANIESE-MATERIALIZED-AWARENESS-1 +LATEST_STATEcontract inventory (same commit, per hygiene rule).🤖 Generated with Claude Code
https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi
Generated by Claude Code
Summary by CodeRabbit
New Features
Documentation