core/docs/assessment/20-component-cards/always-on-process.md
Shay 901f028f32 docs(assessment): Phase 3 — component descent; the correction chain continues into code
Eight component cards in 20-component-cards/: the four zero-subsystem zones
(comprehend-organ, determine-phase, realize-phase, sensorium-falsification)
plus always-on-process, derivation-organs, surface-selection,
attention-allocation. Plus 05-phase3-findings.md and correction banners on
the M6 and M4 layer cards.

CORRECTIONS (C-1..C-5):
- THREE more map live-serving labels demoted to live-internal:
  comprehend-organ (a MATH SETUP ROUTER, not chat comprehension — imported
  by neither serving entrypoint), determine-phase and realize-phase (both
  behind accrue_realized_knowledge=False / idle flags; NO default-config
  serving turn touches any of the three).
- Phase 2's M6 card overstated ephemerality: Shape B+ persistence exists
  (persist_session_state, daemon-forced, "restored bit-exactly").
- Phase 2's M4 card understated the resolver: surface_resolution.py IS a
  declared-precedence resolver for the pipeline seam; only the upstream
  composer arms remain ordered branches. Third Door refines to "extend the
  existing pattern upstream."
- 34-vs-18 RESOLVED: 18 resolve_promotable_* organs existed AT the ADR-0252
  ratification commit; "34" counted modules (~32-33). No consolidation has
  occurred; the governing ADR's headline number has no stated basis.
- The 2026-07-25 verification doc's claim that accrual "is enabled by the
  production L10 process" is contradicted: CONTINUOUS_LIFE_CONFIG_FLAGS is
  exactly {persist_session_state, consolidate_determinations,
  strict_identity_continuity}.

NEW FINDINGS (F-6..F-10):
- F-6 THE CONTINUOUS LIFE MAY CONSOLIDATE AN EMPTY SET: the daemon forces
  the consolidator ON but not the accruer, and realize_comprehension — the
  only turn-path writer of realized facts — sits behind the accrual flag.
  The two halves of the lived learning loop are gated by different flags
  and only one is forced. Undocumented either way.
- F-7 ADR-0008's Allocation Physics LANDED, mutated, ungoverned: curvature
  kernel -> salience adapter -> attention threshold plan -> candidate
  intersection, with budget feedback making attention SELF-NARROWING
  across a walk. InhibitionMask is decoration. top_k=16/threshold=0.3 have
  no recorded derivation. CR-1 closes with a one-page ADR.
- F-8 two load-bearing naming traps (comprehend-organ; realize vs realizer).
- F-9 REALIZE is sound; its ceiling is the reader that feeds it (the #138
  fabrication locus — measured/pinned/held, recorded not re-discovered).
- F-10 _accrue_in_turn swallows exceptions into a no-op with no telemetry.

Phase 4 seed list consolidated: 8 hindrance candidates, 10 gap candidates,
each with its deciding authority. Method note recorded: three phases of
corrections, and nothing in the chain was caught by re-reading documents.
2026-07-27 15:57:36 -07:00

4.7 KiB
Raw Blame History

always-on-process — chat/always_on.py, chat/always_on_daemon.py, engine_state/, evals/l10_*

Kind: component (M6's built half) · Parent: M6 · Assessor: Fable 5 (Phase 3) Verified at: 8927c563 (2026-07-27) Liveness: live-internal (CLI-reachable, suite-orphaned) · Fitness: strained (proof debt, not design debt) · Topology role: runtime boundary

The process that runs the continuous-life heartbeat. Its design center is a single sentence from the daemon module: a restart is the same life or it stops — never a silent fork.

What it is / What it does

run_continuous(runtime, heartbeats, …) — each beat advances idle_tick (continuous learning), records closure + learning evidence, self-checkpoints on real work, checkpoints once at exit; heartbeats=None runs unbounded until stop, which is checked before each beat and interrupts the inter-beat wait. run_daemon wraps it with a single-instance fcntl.flock lock — kernel-released on process death, so no stale-lock window and no PID-reuse ambiguity; the lock file is deliberately never unlinked (unlinking would let a peer flock a different inode). lived_life.json feeds the Workbench Lived Life surface. Landed 2026-06-14 (18e25580, efd280d4).

The forced flag set (exact, from CONTINUOUS_LIFE_CONFIG_FLAGS):

{"persist_session_state": True,      # Shape B+ — persist the lived session across reboot
 "consolidate_determinations": True, # Step D — learn from determined facts each beat
 "strict_identity_continuity": True} # load-time identity guard — same life or refuse

Correction to the Phase 2 M6 card (Shape B+)

The M6 layer card carried forward "T1 vault and field excitation are discarded on exit by design (ADR-0146)." That is the default-config posture only. Under the daemon, persist_session_state=True activates Shape B+ persistence — chat/always_on.py:9: the lived state is "restored bit-exactly" — with opt-in persistence sites in chat/runtime.py:893952. So the residency question the M6 card called "the highest-value M6 question" (should the process hold vault/field?) is already partially answered in code: the mechanism exists, is opt-in, and is daemon-forced. What remains open is exactly what Shape B+ covers (session context vs full T1 vault vs field excitation — the persistence sites need a Phase-4 read) and whether it is proven at horizon.

What the soak would prove if run (evals/l10_always_on)

  • H1 closure — every observed idle beat is a valid versor, with an explicit vacuity guard: a run where the field never existed cannot pass "by saying nothing."
  • H2 bounded idle — a no-work idle beat adds nothing to the vault (no idle resource leak); flagged consolidation writes are exempt.
  • H3 convergence — a saturated idle life settles and stays settled, with a min_converged_tail so "settled" is observed, not assumed.
  • H4 reboot-resume — a mid-soak reboot resumes the SAME life; post-reboot closure holds on every segment.

Each predicate has *_holds and *_bites test pairs (mutated evidence must fail). This is exemplary falsification design. No recorded artifact exists; no suite runs any of it — the long horizon is python -m evals.l10_always_on's job, per its own docstring "run on demand / nightly," and no nightly exists.

Judgment

Fitness: strained — proof debt on a sound design. The lock discipline, the never-silent-fork rule, the vacuity-guarded predicates, and the bites-pairs are all careful work. What is missing is entirely evidentiary: a recorded soak artifact, a scheduled runner, and an ADR that owns the daemon (ADR-0146 rejected Shape A; the daemon is unowned by any ratifying decision).

Honest wrinkles:

  • The flag set forces the consolidator on but not the accruer (accrue_realized_knowledge absent) — see the determine-phase card: the continuous life may be consolidating an empty set. Unresolved.
  • strict_identity_continuity=True under the daemon vs False default means identity-continuity refusal behavior differs between the daemon and every other entrypoint — correct by design, but nowhere stated outside the flag dict.
  • The soak evals' own docstring designates a nightly cadence that has never been provisioned. Given the local-first CI doctrine (Mac runner, queue waits while asleep), a nightly soak is architecturally awkward — which may be why it never ran. That tension deserves a ruling, not silence.

Open questions: run the soak, record the artifact (→ the still-owed ADR-0146 Phase-4 spike); which suite owns l10/always_on pins (→ Phase 4); daemon's ratifying ADR (→ ruling); exact Shape B+ coverage (→ Phase 4 read of runtime.py:893952).