DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path inspection-briefs/loomworks-personal-path-token-consumer-inspection-findings-v0_1.md

Loomworks — Personal-Path Token-Consumer Inspection — Findings — v0.1

Version. 0.1 Date. 2026-08-16 Status. Findings of the read-only inventory commissioned by the personal-memory posture note §5. No changes made. Commissioned by. standing-notes/loomworks-personal-memory-posture-note-v0_1 §5, Operator direction 2026-08-16. Question. Which code paths spend AI tokens WITHOUT explicit person invocation, and which of those touch person-scoped Memory? Candidates named by the brief: proactive behaviors (Phase 44 machinery), classifiers, enrichment, scheduled work. Inspected. loomworks-engine src/loomworks/, current main working tree, 2026-08-16. Read-only; retirement or gating of anything below is a subsequent Operator-gated change request. Canonical home. loomworks-record.


Plain-language summary

The posture note's §3 rule already holds in the live system: no path both spends tokens and touches person-scoped Memory outside an explicit invocation. The intersection is empty. The Phase 44 proactive machinery — the obvious suspect — reads personal Memory every five minutes but spends zero tokens: it is deterministic SQL plus regex date extraction, and every notification body is a hardcoded template, never model-composed. Exactly one background loop spends tokens without a person at the keyboard (the composition orchestrator's 5-second render-advance tick), and it is engagement-scoped, credit-gated, and downstream of a person having created the composition. The retirement candidates the brief anticipated do not exist as live spenders. What the inventory did surface is four latent paths — defined in the tree but unwired — that would become background token spenders if anyone registers them; under this posture they should be treated as fenced, not free.

1. Live token spend without explicit invocation — one path, not personal

The CompositionOrchestrator loop. Started at api/app.py:236-247; engagement/composition_orchestrator.py:1407 _run(), LOOP_TICK_SECONDS = 5.0. Each tick scans render_compositions_view for initiated/step_in_progress compositions and advances one step: advance_composition (:696) → specialist.produce_render / .rerender (:1021, :1033) → agents/render_specialist.py:988 llm_client.complete(...), credit-gated at :966.

2. Phase 44 proactive machinery — reads personal Memory, spends nothing

The brief's primary suspect, cleared on all four sub-questions:

3. Classifiers and enrichment — all request-scoped

Every classifier/enrichment call sits inside a request handler, i.e. fires only on an explicit person turn or capture:

4. Scheduled and background machinery — null findings

Checked and clear (zero tokens each): the credit lifecycle evaluator (daily; template emails), the credit reconciliation evaluator (daily; deterministic diff), the external-polling loop (5s; status queries, base impl unimplemented), non-seed scheduler cadences (30s; consideration-open events only), the consumption hook (records spend already made), SSE stream generators (heartbeats), lifespan bootstraps (construct clients, make zero calls), and the one-shot maintenance modules (orphaned-findings sweep, backfills — no scheduler, no caller). BackgroundAgentRunner (agents/runner.py:81) is not a scheduler: every dispatch into it originates from a person action (produce-shape/render endpoints, spend-pause approval, approval-card actions); the LLM round-trip completes after the 202, but nothing self-starts. No apscheduler, no celery, no cron entrypoints.

5. Latent paths — defined but unwired; fence under this posture

Four paths would become background token spenders the day someone registers them. None is live; all should be treated as requiring an Operator-gated CR that engages this posture note before wiring:

  1. Drift post-append dispatch (engagement/post_append_dispatch.py:100-190; also considerations.py:750-786): would spend 2 completions per memory event written, unbounded, event-driven. configure_drift_dispatch has no production caller. Highest-volume latent spender.
  2. Shape-confirmed auto-render hook (engagement/shape_confirmed_dispatch.py:79; sibling shape_produced_dispatch.py:170): registering it turns one shape confirmation into N render completions with no further person input. Not registered.
  3. Seed-cadence synthesis on the 30-second scheduler tick (scheduler/tick_loop.py:285agents/seed_cadence_synthesis.py:219): the scheduler runs by default, but seed_cadence_synthesis_agent is never set on app state in the tree, so seed-scope firings error rather than spend. A deployment that sets it converts a pure DB timer into a recurring spender whose prompt grows with seed amendment history.
  4. Grant-decision proposer (credit/grant_decision_dispatcher.py:480:504, max_tokens=4096): docstring anticipates wiring "to a route or a periodic walk"; the periodic-walk option would be a timer-driven spender. No production caller.

None of the four touches person-scoped Memory; the fence is a cost fence, not a personal-scope fence — but the posture note's cost ground applies to all of them.

6. Retirement candidates

None. The brief asked which existing consumers are candidates for retirement or gating; the answer is that the live system already conforms — nothing on the personal path spends un-invoked tokens, so there is nothing to retire. The actionable residue is preventive: the four latent paths in §5 carry a wiring hazard, and the posture's §3 rule ("passive-cheap by rule") currently holds by absence of wiring rather than by any structural guard. Whether that deserves a structural fence (e.g., the personal engagement excluded by construction from any future dispatch registration) is an Operator call, not made here.


DUNIN7 — Done In Seven LLC — Miami, Florida Personal-Path Token-Consumer Inspection — Findings — v0.1 — 2026-08-16