Version. 0.1
Date. 2026-05-24
Author. Claude Code
Engine HEAD. ead29a8 (merge of phase-62-memory-events-cleanup)
Tag. phase-62-memory-events-cleanup
Companion documents.
phase-62-cr-memory-events-cleanup-v0_1.md — the CR these notes close.loomworks-cr-b-memory-events-cleanup-design-v0_1.md — the design these notes execute.phase-61-implementation-notes-v0_1.md — CR-A close notes; CR-B inherits patterns.loomworks-substrate-hygiene-scoping-note-v0_2.md — the scoping that authorized the three-sibling-CR shape.
Phase 62 closed in three commits on the engine, merged as ead29a8:
87bec47 — Migration 0072_memory_events_phase_25_wiring_cleanup + _ANCHOR_PRIORITY relocation to src/loomworks/foray/anchor_priority.py6348c60 — Drop Phase 25 wiring from events.py; rename attestation column refs in stamp_commit_attestation SQLf2adf2f — Update tests for the rename + injection removal + registry moveThe cleanup proceeds as planned by the scoping note v0.2: CR-A (audit) shipped first, smallest, validated the reserved-location pattern; CR-B (Phase 25 wiring) ships second; CR-C (credit substrate) ships last.
memory_events.attestation no longer exists. memory_events.commit_webauthn_attestation carries the 1 preserved row (event_id 0673cfd7-354b-4e2a-8a33-9d7355ebf180) with WebAuthn proof data intact. memory_events.content_hash and memory_events.foray_tx_ref no longer exist.
Schema today:
| Column | Type | Status |
|---|---|---|
| event_id | UUID PK | unchanged |
| engagement_id | UUID NOT NULL | unchanged (FK to engagements) |
| engagement_version | BigInt NOT NULL | unchanged |
| object_id | UUID NOT NULL | unchanged |
| object_type | VARCHAR(64) NOT NULL | unchanged |
| object_version | Integer NOT NULL | unchanged |
| event_kind | VARCHAR(64) NOT NULL | unchanged |
| payload | JSONB NOT NULL | unchanged (no _foray injection) |
| provenance | JSONB NOT NULL | unchanged |
| timestamp | TIMESTAMPTZ NOT NULL | unchanged |
| actor_id | UUID NOT NULL | unchanged |
| actor_kind | VARCHAR(16) NOT NULL | unchanged |
| actor_instruction_version | Integer NULL | unchanged |
| commit_webauthn_attestation | JSONB NULL | renamed from attestation |
Dropped: content_hash (494 write-only rows in dev DB lost; no consumer); foray_tx_ref (0 rows; never written).
src/loomworks/foray/ now holds two helpers:
reserved_emit.py (from CR-A) — no-op _foray_reserved_emit(event_kind, payload)anchor_priority.py (new in CR-B) — the 19-entry _ANCHOR_PRIORITY dict
foray/__init__.py re-exports both. Imports work via either the submodule (loomworks.foray.anchor_priority) or the package (loomworks.foray).
src/loomworks/memory/events.py simplified substantially:
_ANCHOR_PRIORITY dict literal removed (relocated)compute_content_hash function removed (zero callers after the cleanup)_foray namespace injection block (was lines 236-255) removedcontent_hash and foray_tx_ref columns dropped; attestation renamed to commit_webauthn_attestationhashlib, json imports dropped_foray_reserved_emit("memory.<event_kind>", payload) call at the end of append_event — the single reserved-emit per CR-A's validated per-call-site discipline
src/loomworks/engagement/commit_orchestration.py:
stamp_commit_attestation SQL updated: SET commit_webauthn_attestation (was SET attestation)
| Metric | CR-A baseline (616bab9) | Final (CR-B) |
|---|---|---|
| Collected | 2708 | 2705 (-3 net) |
| Passed | 2674 | 2670 |
| Skipped | 33 | 33 |
| Failed | 2 (pre-existing) | 2 (same two) |
Test changes:
tests/test_phase_25_content_hash_and_foray.py (3 tests covered removed functionality)tests/test_phase_25_commit_attestation.py → tests/test_commit_webauthn_attestation.py (8 tests; logic preserved)tests/test_phase_53_discovery_to_seed.py::test_foray_namespace_injectedtests/test_phase_54_seed_commit_from_brief.py::test_foray_namespace_injectedtests/test_phase_31_seed_conversation.py::test_converse_foray_hookstests/test_phase_31_seed_conversation.py::test_key_provided_event (kept the surrounding test; removed only the _foray + content_hash assertions inside)test_phase_25_commit_orchestration.py (2 SELECT sites) and for content_hash drop in test_phase_48_reconciliation_evaluator.py (1 INSERT helper)_ANCHOR_PRIORITY in test_phase_53 (1), test_phase_54 (2), test_phase_55 (3), test_phase_58 (1 top-level)tests/test_foray_reserved_emit_for_memory.py — 2 tests asserting the hook fires + threads anchor_priority
Pre-existing failures unchanged (both confirmed against baseline): test_api_assertion_retract (JSON-encoding bug at app.py:461) and test_phase_44_evaluator::test_concern_scan_does_not_re_fire_within_dedup_window (dedup-window flake).
The load-bearing change of CR-B. Pre/post comparison:
Before migration (alembic 0071):
event_id attestation (first 150 chars)
0673cfd7-354b-4e2a-8a33-9d7355ebf180 {'challenge': 'l_VtYtA6rzJj2K0fZOFqigL9Xpb3VoO3e5FsYwHywDs',
'signature': 'MEUCIQC7Ubv-u4Q28XLbhXCMe9fQlNZNNRfs2lkhxeuIn
Pt4bgIgR5YQvb4YrnZCHxmp4sFmi_Y...
After migration (alembic 0072):
event_id commit_webauthn_attestation (first 150 chars)
0673cfd7-354b-4e2a-8a33-9d7355ebf180 {'challenge': 'l_VtYtA6rzJj2K0fZOFqigL9Xpb3VoO3e5FsYwHywDs',
'signature': 'MEUCIQC7Ubv-u4Q28XLbhXCMe9fQlNZNNRfs2lkhxeuIn
Pt4bgIgR5YQvb4YrnZCHxmp4sFmi_Y...
Same event_id. Identical data. Round-trip verified: alembic upgrade head → alembic downgrade -1 → alembic upgrade head preserves the row through the cycle.
The op.alter_column(... new_column_name=...) approach (true rename, PostgreSQL metadata-only) was correct for preserving operational WebAuthn data. A drop-and-add approach would have lost the proof; the design's insistence on a true rename was validated.
Design §6.3 said the 10 non-dedicated test files had only "incidental references — these tests do not test the Phase 25 wiring." During execution, this proved partially wrong. Four additional test functions DO test Phase 25 wiring directly:
test_phase_53_discovery_to_seed.py::test_foray_namespace_injected — asserts payload["_foray"] shape; tests removed injectiontest_phase_54_seed_commit_from_brief.py::test_foray_namespace_injected — same shape for Phase 54's event kindtest_phase_31_seed_conversation.py::test_converse_foray_hooks — asserts _foray on operator_turn/companion_turn/conversation_started_foray assertion block inside test_phase_31_seed_conversation.py::test_key_provided_event (trim, not full delete)
The pattern across these tests: each phase that added a new event kind to _ANCHOR_PRIORITY also added a test_foray_namespace_injected (or equivalent) test verifying its new entry got the _foray block injected. The design didn't enumerate these. They were discovered when grep for compute_content_hash and _foray namespace usage surfaced them post-migration.
Additionally: 7 _ANCHOR_PRIORITY import sites across 4 test files needed updating to import from loomworks.foray instead of loomworks.memory.events. The design said "no external importers" (§9.3) — that turned out to be false; the test code uses the registry liberally for entry-presence assertions.
content_hash
Design §2.7 inherited the events.py docstring claim "append_event is the single code path for writing to the memory event log." That claim is true for ORM-level writes, but not for raw SQL. There are 19+ raw INSERT sites across the codebase. Of these:
wasderivedfrom_backfill.py:121 and personal_engagement.py:241 — both write columns up to actor_instruction_version and stop. Clean — neither writes content_hash. Production was unaffected.test_phase_48_reconciliation_evaluator.py:128 did include content_hash in its INSERT, which failed all 6 reconciliation-evaluator tests until the column was removed from the helper.
The fix was mechanical (remove content_hash from one column list + one parameter map), but the root finding was the design's "single code path" claim was too strong — raw-SQL bypasses exist and are perfectly legitimate (each test helper has reasons to bypass append_event: avoiding circular imports, fixture-style setup, etc.).
The design's risk assessment §9.6 anticipated both slot-1 and slot-2 categories (registry import drift; views/raw-SQL dependency on dropped columns). The slot budget held: no halt-and-surface beyond what the slots covered.
_ANCHOR_PRIORITY symbol name kept (no rename to _FORAY_INTEGRATION_PRIORITY)
Held up cleanly during execution. The new module path (loomworks.foray.anchor_priority) provides the FORAY context. Imports read clearly: from loomworks.foray import _ANCHOR_PRIORITY. Test code didn't need refactoring beyond the import-path change. No reader was confused; no rename pressure surfaced. If a future ship wants to rename for clarity, that's a discrete one-line change with broader test churn — defer until a concrete clarity need emerges.
commit_webauthn_attestation column name (verbose two-piece)
Held up cleanly during execution. The verbose name read well in SQL and ORM contexts. No shorter alternative tempted. The two pieces of context proved load-bearing because the surrounding function names (stamp_commit_attestation, verify_commit_attestation) already overload "commit attestation" as a phrase — the column name needed the "webauthn" specificity to avoid echoing that ambiguity.
compute_content_hash removed entirely
Held up cleanly during execution. Three test files imported the function; all three imports were inside test functions that were also being deleted as part of removing the _foray namespace tests. Removing the function alongside its only callers was the right move. No production caller remained.
append_event (after post-append hooks fire)
Held up cleanly. The placement semantics ("emit only when the event fully landed and post-append hooks completed") proved correct during the new test development. The 2 new tests in test_foray_reserved_emit_for_memory.py exercise the emit, and the monkey-patch pattern works because the placement is deterministic.
CR-A established the principle (renamed one test file). CR-B now extended it twice:
test_phase_25_commit_attestation.py → test_commit_webauthn_attestation.py (logic preserved; framing matches surviving column)test_phase_25_content_hash_and_foray.py (both framing and tested functionality gone)Three CR-A pattern + three CR-B applications = the principle has settled. Promote to methodology candidate for the next consolidation pass. The principle: when a test's filename or function-name framing references an origin that has been cleaned up, the artifact should be renamed (if its logic survives) or deleted (if its tested functionality is also gone). CR-C will validate scale-up to a fourth instance (8 affected test files in credit).
CR-A: 3 sites → 3 emits. CR-B: 1 site → 1 emit. The principle "one emit per business event" holds across both scales. CR-C's 12 sites will be the third data point.
src/loomworks/foray/ continues to grow. CR-A added reserved_emit.py; CR-B added anchor_priority.py. CR-C should add value_flow.py or similar for credit-side emit support. The module shape is "one concern per file."op.alter_column(..., new_column_name=...) works on JSONB columns. CR-B used it for attestation → commit_webauthn_attestation; the data preserved cleanly. CR-C will likely have similar renames (e.g., credit.foray_action_flows → credit.flows, or column-level renames within the table); the pattern is now proven on the substrate.memory_events had pre-existing FKs to engagements, untouched). CR-C's credit.foray_action_flows table will need its own decision — likely keep existing FKs (if any), don't add new ones unless concrete need.# FORAY_RESERVED_LOCATION: <namespace>.<event_kind> immediately above the call."audit.<...>", "memory.<...>", "credit.<...>". The substrate prefix routes future FORAY integration unambiguously.test_foray_reserved_emit_is_importable_and_callable (inside test_voice_tune_setting_audit.py). CR-B added test_foray_reserved_emit_for_memory.py (2 tests: hook fires + anchor_priority threading). CR-C should add test_foray_reserved_emit_for_credit.py with one test per emit-shape variant (probably 2-3 tests).events.py:1-5 docstring said append_event is the single write path; that was true for ORM but not for raw SQL. CR-C's design phase should explicitly grep for raw-SQL writes to the affected tables before claiming "single code path" — there are likely test helpers (and possibly production code) bypassing the ORM-level writers.tests/ for the specific assertion patterns (payload["_foray"], references to the doomed table name, etc.) and enumerate them explicitly._ANCHOR_PRIORITY symbol rename to _FORAY_INTEGRATION_PRIORITY — design D3 said keep; execution confirmed; deferral stands. If CR-C surfaces a clearer name from a value-flow-side angle, methodology candidate.commit_webauthn_attestation — no query exercises a search by attestation today. Add when needed.anchor_priority payload field — no one reads it today. The data is threaded for future FORAY integration. If integration arrives and doesn't need it, drop later.Items surfaced during CR-B execution that don't fit CR-B:
test_api_assertion_retract JSON-encoding bug — same item flagged in Phase 61 implementation notes §6.1. Still pre-existing; still worth a small future fix at src/loomworks/api/app.py:461 (probably str(exc) or repr(exc) in the JSONResponse body).test_phase_44_evaluator::test_concern_scan_does_not_re_fire_within_dedup_window — same item flagged in Phase 61 implementation notes §6.2. Still pre-existing; worth investigation alongside CR-C since both touch evaluator surfaces.engagement_display_identifier_seq overflow — known follow-on workaround applied during CR-B as in CR-A (ALTER SEQUENCE ... RESTART WITH 1). Conftest still doesn't reset the sequence; existing follow-on stays open._ANCHOR_PRIORITY registry has 19 entries today. Phase 25 added the first batch; Phases 31/53/54/55/58/59 each added entries. The growth-pressure argument that the scoping note v0.2 §1 surfaced is now somewhat reduced: with the registry safely in src/loomworks/foray/, future entries land in the new home and don't add cleanup pressure. The argument is preserved here for future scoping rounds: the registry will keep growing as Loomworks adds anchor-worthy events.Items NOT for the ledger (resolved within CR-B):
CR-B landed clean. Two reserved slots consumed by execution-time discoveries that didn't require design revision. The attestation rename preserved real WebAuthn data (verified pre/post). The Phase 25 wiring is fully cleaned up; the foray module foundation now holds two helpers and is ready for CR-C's value-flow addition.
The methodology candidate "test-filename-to-current-substrate alignment" has three CR-validated instances now. CR-C will be the fourth; if it holds across credit's 8 affected test files, the principle is settled.
DUNIN7 — Done In Seven LLC — Miami, Florida Phase 62 Implementation Notes — v0.1 — 2026-05-24