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.
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.
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.
memory_events only.SELECT); one full render completion (typically thousands of tokens, per the specialist binding's max_tokens) per advanced step.The brief's primary suspect, cleared on all four sub-questions:
notifications/evaluator.py; no import from agents/anthropic/orchestration.prompt). Time-based triggers are raw SQL over current_memory_objects in the person's personal engagement (:359-371) plus regex date extraction (extract_dates :149); concern-based triggers are an engagement listing plus MAX(timestamp) staleness against a 14-day threshold (:224-240, :56).notifications/listener.py:259, registered at api/app.py:321-322): SQL lookups plus hardcoded f-string voices (:161, :173, :185).evaluator.py:54). Per-tick cost is queries only, O(persons × engagements) in DB reads, never in tokens.evaluator.py:320, :328, :395-401, :459-471).companion_notifications table and the in-process SSE bus.Every classifier/enrichment call sits inside a request handler, i.e. fires only on an explicit person turn or capture:
orchestration/classifier.py:238, sole caller converse.py:871), responder (responder.py:76), completeness (completeness.py:88), correction check (correction_check.py:148), find-files (find_files.py:130). These are the personal-memory recall seams — invoked, per §3.uploads/summarization.py:47, only above a size threshold, one call), vision description (uploads/vision/claude_vision.py:142, skills/image_description.py:195), seed extraction (skills/seed_extraction_core.py:241) — all reached only from api/routers/uploads.py:815.api/routers/sales_tools.py:209) run post-response via background_tasks but are request-initiated and usage-ceiling-checked before enqueue; no personal Memory.find_files.py:3).
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.
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:
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.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.scheduler/tick_loop.py:285 → agents/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.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.
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