core/chat
Shay efd280d45f
feat(l10): autonomous idle frontier-contemplation — the always-on life learns on its own (#758)
* 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.
2026-06-14 23:59:49 -07:00
..
__init__.py
__main__.py
always_on.py feat(l10): autonomous idle frontier-contemplation — the always-on life learns on its own (#758) 2026-06-14 23:59:49 -07:00
always_on_daemon.py feat(l10): always-on daemon/CLI — the process that runs the continuous-life heartbeat 2026-06-14 17:33:37 -07:00
anaphora.py feat(adr-0066): session-thread context + opt-in anaphora prefix (Phase 3.1 + 3.2) 2026-05-18 17:01:34 -07:00
articulation_telemetry.py feat(contemplation): Phase 5 — articulation-quality miner closes the loop 2026-05-21 10:55:39 -07:00
ask_runtime.py feat(ask): add runtime-facing ASK helper module 2026-06-10 03:34:02 -07:00
atom_equivalence.py feat(telemetry): ADR-0078 Phase 1 — composer/graph atom equivalence (observational) 2026-05-20 06:14:25 -07:00
cross_pack_grounding.py feat(register): R1–R4 register pack subsystem — deterministic surface variation 2026-05-19 16:52:36 -07:00
dispatch_trace.py chore(chat): dispatch trace for grounding-source dispatcher (ADR-0142 debt #2) (#233) 2026-05-24 15:22:02 -07:00
example_surface.py feat(register): R1–R4 register pack subsystem — deterministic surface variation 2026-05-19 16:52:36 -07:00
narrative_surface.py feat(register): R1–R4 register pack subsystem — deterministic surface variation 2026-05-19 16:52:36 -07:00
oov_surface.py feat(adr-0066): NARRATIVE + EXAMPLE intents with multi-clause composers (Phase 3.3 + 3.4) 2026-05-18 17:01:55 -07:00
pack_grounding.py feat: ADR-0086 + ADR-0087 + 100-register catalog — cognition lane closure 2026-05-21 00:08:12 -07:00
pack_resolver.py feat(packs): reland en_core_syntax_v1 foundation vocabulary (collision-audited) 2026-05-31 16:18:26 -07:00
pack_surface_candidate.py feat(pack-grounding): selector-ready gloss wiring via PackSurfaceCandidate 2026-05-19 07:26:46 -07:00
partial_surface.py feat(adr-0065): OOV cliff → five-tier honesty gradient (Phase 2.1 + 2.2) 2026-05-18 16:41:45 -07:00
refusal.py feat(adr-0037,adr-0038): per-predicate ethics refusal + hedge injection 2026-05-17 21:23:28 -07:00
register_substantive.py feat(register): ADR-0077 — substantive register knobs + layering boundary (R6) 2026-05-19 23:39:11 -07:00
register_variation.py feat(register): R5 — operator-visible register telemetry + tour demo 2026-05-19 19:03:07 -07:00
runtime.py feat(l10): autonomous idle frontier-contemplation — the always-on life learns on its own (#758) 2026-06-14 23:59:49 -07:00
teaching_grounding.py feat(adr-0083): transitive (multi-hop) teaching-grounded surface (#63) 2026-05-20 14:11:40 -07:00
telemetry.py feat(W-024): reboot_event audit trail entry (L10b.3, ADR-0158) (#284) 2026-05-25 20:37:00 -07:00
thread_context.py feat(adr-0066): session-thread context + opt-in anaphora prefix (Phase 3.1 + 3.2) 2026-05-18 17:01:34 -07:00
verdicts.py feat(adr-0039): audit completeness — TurnVerdicts bundle, stub TurnEvent, hedge_injected 2026-05-17 21:32:46 -07:00