* feat(l10): autonomous idle frontier-contemplation — the always-on life learns on its own Frontier survey move #2, path (c): give the always-on idle life a stream of experience via SYMBOLIC intake (not the afferent→field seam, which is deferred pending a commensurability ruling — docs/analysis/afferent-field-ingest-scope-2026-06-15.md). The idle heartbeat converges (idle_tick drains a finite backlog + saturates is-a closure, then does nothing forever); this makes it autonomously MINE its frontier with no user turn. Reuse-heavy (the mechanism largely existed): a gated idle pass wires ADR-0080 contemplation into the always-on loop. - core/config.py: contemplate_frontier_during_idle (default off → no behavior change). - chat/runtime.py: idle_tick pass 2b — when on, runs core.contemplation.run_contemplation() (mines the checked-in frontier-compare reports) and persists a reviewable ContemplationRun to <engine_state>/contemplation_runs/idle_<substrate_hash>.json. IDEMPOTENT per frontier (an already-mined frontier is not re-persisted → the life converges, no churn) and MEMOIZED per session (the static frontier is mined once, not re-read every beat). SPECULATIVE-only (ADR-0080: ContemplationFinding.__post_init__ RAISES if not SPECULATIVE → wrong=0 by construction; never ratified here — the HITL path is untouched). IdleTickResult gains frontier_findings. - chat/always_on.py: run_continuous did_work + HeartbeatRecord count frontier work, so the heartbeat/soak convergence (H3) stays honest. - core/cli.py: `core always-on --contemplate-frontier` (explicit learning-daemon mode) + honest per-beat log ("+N findings"). Adversarial 3-lens review (wrong=0/convergence, determinism/trust-boundary, test-vacuity) found 7; fixed the real ones: the MEDIUM torn-write (write_contemplation_run is now atomic temp+os.replace — the indefinite-uptime daemon expects SIGKILL mid-write, and the skip-guard would never repair a torn canonical file), the gitignore breadth (contemplation_runs/ at any engine-state root), the 64-bit filename truncation (full substrate_hash), and the re-mine-every-beat cost (session memoization). Deferred + documented: the shared contemplation miner embeds absolute report paths in finding CONTENT — a portability wrinkle that does NOT affect wrong=0/convergence/soak determinism (those key on the content-only substrate_hash) and touches shared code + its test surface; a follow-up. Tests (non-vacuous): 7 — off-by-default (no behavior change), mines-when-enabled, findings-SPECULATIVE (wrong=0), converges-idempotent, heartbeat-mines-then-converges, mines-once-per-session (memoization), atomic-no-orphan. 55 idle/contemplation/always-on + 96 invariants/contemplation + 28 smoke green; `core always-on --contemplate-frontier` mines end-to-end. engine_state contemplation_runs are per-life runtime state (gitignored). * fix(l10): isolate idle frontier pass + persist frontier_findings (#758) Three review blockers on the autonomous idle frontier-contemplation pass: 1. Daemon isolation. idle_tick's pass 2b called run_contemplation / write_contemplation_run bare inside the always-on loop (run_continuous wraps idle_tick in nothing but an exit-checkpoint finally), so a malformed frontier report or a transient FS fault would propagate out and KILL the continuous life. Wrap the optional pass best-effort (the exit-checkpoint boundary idiom): degrade to 0 findings + RuntimeWarning, leave did_work untouched, let a later beat retry. 2. Durable did_work explanation. HeartbeatRecord carried frontier_findings but serialize_report omitted it and AlwaysOnReport had no run total, so lived_life.json could show did_work=true with facts=0/proposals=0 and no persisted cause. Persist frontier_findings per-record + total_frontier_findings. 3. Honest HITL claim. The docstring/CLI/config said findings are "reviewable via the HITL path", but the existing HITL queue + workbench reader scan <repo>/contemplation/runs while the pass writes <engine_state>/contemplation_runs/. Narrow the claim to "persisted reviewable artifact, not yet in the HITL queue" (wiring that discovery is a follow-up). Tests: 4 new non-vacuous regressions (mining-failure degrade, write-failure degrade, always-on loop survives frontier failure, lived_life persists frontier_findings) — all fail against the unpatched pass. 38 L10/always-on/ workbench tests green.
6.4 KiB
Afferent → Field Ingest Seam — Scope & Decision Brief
Status: scope (decision-gated; field-touching, CLAUDE.md sanctioned-site implication) · Context: frontier survey move #2, after the always-on process (#747/#748/#752) + its long-horizon soak (#757) closed the idle lived-spine. This is the proposed next edge: give the always-on life a stream of experience by folding compiled afferent observations into the live cognitive field.
The gap it would close
The always-on heartbeat lives, holds closure, and resumes — but it is a continuously
idling life: idle_tick drains a finite backlog + saturates deductive closure, then
does no work forever (proven by the convergence gate H3 in evals/l10_always_on). There is
no afferent input channel into the idle loop. Separately, the sensorium is fully built
as a compiler/frame/merge substrate but is never wired to the field — ADR-0208's own
pipeline arrow (ObservationFrame → … → field / recall / cognition) stops at the merge.
This seam is the missing edge in listen → comprehend → … → replay.
What is confirmed (geometric feasibility)
- Units carry a field-shaped target.
CompilationUnitLike(sensorium/compiler/protocol.py:28) exposesversor: np.ndarray— a real CL(4,1) multivector — alongsideversor_condition. A liveObservationFrame's units therefore expose targets in the field's algebra. - The sanctioned pull pattern applies directly, closure-preserving BY CONSTRUCTION. The
exemplar is
session/context.py::_session_anchor_pull:
It explicitly replaced the rejectedR = word_transition_rotor(field_state.F, target) # rotor toward target R_step = rotor_power(R, α) # fractional, stays on Spin manifold pulled = versor_apply(R_step, field_state.F) # apply — no post-hoc unitize_slerp_toward(which broke closure and needed a forbidden post-hocunitize_versor). An afferent pull towardunit.versoris structurally identical → preservesversor_condition < 1e-6by construction, adds no normalization site. - Home:
session/context.py(the already-sanctioned site that owns the field), a new opt-inobserve(frame)that pulls the field toward each unit's versor by a fractional step. Default off → serving + existing behavior byte-unchanged.
The load-bearing wrinkle (the decision)
Closure-preservation is necessary but NOT sufficient. The sanctioned anchor-pull moves the field toward a session concept-attractor — a target in the cognitive semantic frame, carrying meaning ("the field anchors toward the session's concept"). An afferent unit's versor is in the same algebra (CL(4,1)) but:
Is the sensorium's CGA embedding semantically COMMENSURABLE with the cognitive field — or merely same-algebra, different meaning?
- If commensurable: pulling the field toward
unit.versoris genuine perception → cognitive state (decoding doctrine: the observation is real, the field moves toward it). The seam is clean and meaningful. - If not (same algebra, unrelated embedding): the pull is geometrically valid but semantically empty — the field drifts toward an arbitrary point. That is exactly the degenerate fit the field-as-standing-hand doctrine forbids ("geometrically-realizable structure only; never force a degenerate fit").
This question is unestablished in the code: the sensorium compiles units into CL(4,1) but nothing today asserts that embedding shares the cognitive field's semantic frame (they were built as disjoint tracks — CLAUDE.md: the afferent arc "is disjoint from the GSM8K serving path"). Wiring afferent → field is the first connection of the two.
Decisions for ratification (Shay reviews the design)
-
Commensurability ruling (the crux). Is the sensorium CGA embedding intended to be commensurable with the cognitive field? Three honest paths:
- (a) Commensurable by construction — if the modality packs project into the same concept manifold the cognition field uses, the pull is meaningful → build the seam. (Needs: evidence/assertion that the projection shares the frame, e.g. a shared concept-attractor basis, before any pull is wired.)
- (b) Bridge required — define an explicit, falsifiable map from a unit's versor to a cognitive-field target (a grounded embedding), so the pull is toward a meant point. Larger; an ADR + a commensurability gate.
- (c) Not yet — keep the tracks disjoint; the always-on life stays idle-converging for now; the stream-of-experience comes from a different intake (the autonomous determination-frontier — roadmap Step 5 — which feeds symbolic new questions, not afferent versors). Lower geometric risk, advances the telos via comprehension.
-
Sanctioned-site clause. If (a)/(b): extend
session/context.py's CLAUDE.md clause to cover afferent-observation pull (closure-preserving by construction AND semantic = perception→field), with the same bright-line justification. A CLAUDE.md amendment. -
ADR. Completing ADR-0208's arrow (
ObservationFrame → field) is the first afferent→cognitive-core connection; it likely warrants an ADR (extend 0208 or new), given the tracks were deliberately disjoint. -
Falsifiable gate (regardless of path). Any pull that "preserves closure" is only proven if a test fails when it doesn't: a soak guard (sibling to
evals/l10_always_on) asserting (i)versor_condition < 1e-6every observed beat, (ii) the same frame sequence → byte-identical field digest (determinism), (iii) a commensurability assertion — the field moves toward the observation (dist(F, target)decreases), not arbitrarily.
Recommendation
The geometry is clean; the semantics are the gate. Recommend ruling on decision 1
first — do not wire a field pull until the commensurability question is answered, or the
seam risks a closure-valid-but-meaningless fit. If commensurability isn't yet established
(likely), the higher-leverage telos move is path (c): the autonomous
determination-frontier intake (feed the idle heartbeat symbolic new questions it can
determine + commit wrong=0 / propose HITL) — which needs no field-embedding ruling and
directly converts the idle life into a learning one. The afferent→field seam then follows
once the embedding frame is established.