The scoping note for Phase 63 — the work that closes the friction surfaced during Phase 62's first day of real use. The editor at record.dunin7.com works, but the operator must hold several pieces of state in their head to use it without producing wrong output. Phase 63 fixes the friction at the source and adds the audit substrate that lets the operator (or anyone else) see what happened on the system over time.
Three pieces of work, named precisely in this document. One design decision to settle before execution. Out-of-scope explicit. The note is written to be read in full without referencing other documents; everything needed to understand Phase 63's shape is on these pages.
Phase 62 closed on 2026-05-22 with the editor at record.dunin7.com functional and verified end-to-end. Five findings were captured in that close, named as queued items for future polish. Within twelve hours of close, on the morning of 2026-05-23, the editor was used to update the Loomworks Architecture Specification from v0.2 to v0.3 in preparation for substantive content work.
That update surfaced two additional findings and made several of the original five matter more than they did in the abstract. Specifically:
Surfacing these in conversation, a fourth question emerged: what about audit? The Phase 62 close named "commits show generic email attribution" as Finding 3. The fix initially imagined was forwarding the Cloudflare Access authentication header. But the project already has FORAY as the universal transaction grammar and audit substrate. And each operator already carries a UUID independent of any access-control framework. So the right framing isn't "fix the email forwarding" — it's "wire editor commits as FORAY transactions, with UUID as the actor identity, and provide an audit viewer to read them back."
Closing these together as Phase 63 produces a coherent piece of work. Editor refinement and audit-substrate wiring share a build target (the editor's commit path) and share a verification surface (the operator using the editor and being able to see the trail of their work). Splitting them into two phases would duplicate the build context and defer the audit work past its natural moment.
Before scoping Phase 63's audit work, an inspection was performed on the loomworks-engine repository to ground both the Operator's and Claude.ai's working understandings of FORAY. The inspection found the following facts, relevant to Phase 63:
FORAY is implemented inside loomworks-engine, not as a separate package. Three distinct substrates exist under the FORAY name:
credit.foray_action_flows table. Used for credit transactions; carries a balance-update trigger.audit.foray_events table. Used today only for setting-change events (when an operator changes a Companion tunable). Append-only, no trigger.memory_events table. Content hashes are computed on every event; the foray_tx_ref column is structurally present but always NULL today.For Phase 63, the narrative-event substrate (audit.foray_events) is the right home for editor commits. The migration that created this table explicitly anticipates editor-style events as future event types — adding "editor_commit" requires no schema migration, only a new event-type constant and a new writer helper.
The Operator's prior framing held that "the only element missing was the blockchain hashing persistence." This is approximately right but understates the gap. Three nested layers of incompleteness exist:
None of this blocks Phase 63. Existing FORAY callers today write rows that are not anchored; those rows will retroactively gain anchors when the anchoring layer eventually lands. Phase 63's editor-commit rows join that population. The schema is positioned so anchoring can be added without further migrations.
The inspection surfaced one genuinely substantial gap for Phase 63: no public read API exists for any FORAY surface today. The narrative-event table has no HTTP routes, no application-level query helpers exposed outside its own module. If Phase 63 builds an audit viewer, the read API must be built as part of Phase 63's scope.
This is the largest piece of new substrate work Phase 63 introduces. It is bounded — a read API for a single table is a known shape — but it is not free.
FORAY's narrative-event writer accepts actor_person_id: UUID as a typed identity parameter. No role-grant chain composition; identity is opaque to FORAY itself. The Operator's framing that "we are not asking for OVA characteristics here, simply a UUID on a FORAY event that can be recalled for a purpose" matches the implementation exactly. OVA does not enter Phase 63's scope.
Three pieces of work, named with enough specificity that the next step (Step 0 inspection) knows what to verify against current code state.
The version-bump operation gets a content-aware behavior: when the operator chooses "Save as New Version," the editor scans the document for self-references to the current version string before creating the new versioned file. Each found occurrence is surfaced to the operator with line context and a proposed replacement. The operator approves or declines each occurrence via checkbox. Approved changes are applied atomically with the version-bump commit; declined occurrences remain unchanged.
This addresses two real concerns: (a) the document's internal state ends up consistent with its filename after the bump, and (b) intentional historical references to old versions (for example, "in v0.1 we considered X but rejected it") are preserved because the operator sees each occurrence individually.
After the bump commit lands, the editor closes its current session and re-opens automatically pointing at the new versioned file. The operator continues editing the version they just created, not the predecessor that was just archived. The current behavior (editor remains pointed at the now-archived path) is replaced.
The save action labels and visual treatment get reworked so the two save operations are clearly different. "Save as New Version" gets a visual treatment that signals consequence; "Save (Minor Correction)" reads as an in-place edit. The exact treatment is a design decision left to execution time, but the requirement is that an operator looking at the buttons can tell at a glance which produces a new version and which doesn't.
Every commit from the editor at record.dunin7.com emits a FORAY narrative-event row to the audit.foray_events table in the loomworks-engine database. The row carries the operator's UUID as the actor, the engagement context (initially the loomworks-record repository itself; per-document context as a payload field), and a structured payload describing what changed.
Three new pieces ship in the engine:
editor_commit, registered in the audit module's event types.write_editor_commit_event(...), taking actor UUID, document path, prior content hash, new content hash, commit message, and optional engagement ID. Constructs the FORAY row and persists it via the existing audit substrate.No schema migration required. No anchoring required. The row lands; the row accumulates; the operator's audit trail begins to exist.
A new section on record.dunin7.com presents FORAY narrative events back to the operator. The section is reachable from the landing page like any other section. The viewer surface has three behaviors:
The viewer requires a new HTTP read API on loomworks-engine that exposes audit.foray_events rows with the appropriate filters. The API is implemented as part of Piece 3's scope. The API surface is bounded — a single resource (the audit-events table) with a small filter set.
How the viewer page reaches the engine's API is a deployment-architecture question Step 0 inspection will need to answer. record.dunin7.com runs on Cloudflare Pages with serverless functions; loomworks-engine runs separately. The viewer either calls the engine's API directly (requiring authentication propagation) or proxies through a Pages Function on record.dunin7.com (which then calls the engine). The choice has consequences for authentication, latency, and observability. Settling it is part of Step 0.
One question remains open after this scoping note that should be settled before Change Request drafting. It is named here so the next session opens with it visible.
Does the audit viewer's filter set include filtering by event type (showing only editor commits, or only setting changes, or only credit flows), or does the viewer present a unified event stream where the event type is a column but not a primary filter?
The first treatment makes the viewer feel like several audits (one per event type); the second makes it feel like one audit (across the system, with event type as metadata). Both are defensible; they produce different operator experiences and different code shapes.
The choice depends on whether the audit viewer is "the audit trail of the editor" specifically or "the audit trail of the system" generally. The first reading is narrower and ships faster. The second reading is more aligned with FORAY's framing as "the audit substrate" and produces a more durable surface, but requires unifying the three FORAY substrates (value flows, narrative events, memory events) at the query layer — which the inspection named as one of the things FORAY does not do today.
Recommendation for this scoping: the audit viewer in Phase 63 covers narrative events only (the substrate the editor commits land in). Value flows and memory events are out of scope for Phase 63's viewer. This produces a narrower but coherent surface that the Operator can use immediately. A future phase can unify the three substrates if and when that becomes load-bearing.
Named explicitly so the boundary is visible.
FORAY's anchoring layer. No Kaspa connection, no signing primitives, no anchor-batch pipeline. Editor-commit FORAY rows accumulate without anchoring; they will gain anchoring when that work eventually lands as its own phase or arc. This is acknowledged in the audit viewer's design: signature fields are not surfaced on event entries until they carry content.
Cross-substrate FORAY consolidation. The three FORAY substrates (value flows, narrative events, memory events) remain independent. The audit viewer reads narrative events only. Future work unifies them if needed.
OVA development. OVA is not a dependency of FORAY's current implementation. Phase 63 uses opaque UUID identity throughout. OVA's seam-and-stub work continues on its own track.
The smaller Phase 62 polish findings unrelated to the version-bump operation. Specifically: new-document creation accepting only a slug (the operator can post-edit the title); the Monaco loader double-load warning (visual noise only). These remain in queued directions for a future polish phase. Their inclusion would expand Phase 63's scope past the coherent-arc bound this scoping note draws.
Content updates to existing documents. The architecture specification update that the editor friction surfaced is itself substantial work; it is not part of Phase 63. The architecture spec gets updated separately, either through Path A or Path B, on its own track, once Phase 63 has made the editor trustworthy enough that Path B is the natural choice.
The scoping conversation that produced this note contributed several methodology candidates worth recording. They will be carried to the v0.21 methodology consolidation alongside the existing backlog.
Three times in the conversation that produced this scoping note, Claude.ai reached to design new capabilities that the project's existing substrate already addressed: FORAY for audit (the Operator surfaced); UUID for identity (the Operator surfaced); FORAY's database persistence (the Operator surfaced). The pattern is consistent: substrate that exists is treated as future work when the design conversation runs without first inventorying what is already built.
The discipline: before proposing design work, inventory what existing project substrate already addresses the question. Failing to do so produces redundant work and obscures the value of substrate that already exists. The instinct should be inventory-first, design-second. The architecture specification is the natural starting point — if a section says "Substrate operating," the substrate exists and design proceeds from there.
The architecture specification's "Substrate operating" framing for FORAY is conceptually accurate — rows are being written for state-changing actions. The code-level inspection refined that: the implementation is more pedestrian than the framing suggests (ordinary PostgreSQL rows, identity passed opaquely, no role-grant composition); three substrates share the FORAY name; no public read API exists.
The discipline: when design depends on substrate specifics, code-level inspection isn't optional even when the architecture spec says the substrate is operating. The two documents serve different purposes. The spec orients; the inspection grounds the design in implementation reality.
The pattern used in this session — Claude.ai poses a question, Claude Code reads and synthesizes against the actual codebase, Claude.ai reasons over the synthesis — turned a multi-hour wandering reorientation into a focused half-hour. This is the right shape for any question of the form "what is the state of X, and what does that mean for Y" when X lives in code or the repository.
The discipline: for navigational reading of repository documents or codebases, route the work to Claude Code with a question-shaped kickoff, not a data-dump kickoff. Claude Code reads and synthesizes; the report comes back as orientation, not raw material. Claude.ai then reasons over the orientation. Use Claude.ai for what only Claude.ai can do (engagement with the operator, design conversation, methodology synthesis) and Claude Code for what it does best (reading repository state).
The Operator surfaced this discipline directly during the session: "going forward, you do not reference material for me to look at, rather, you should simply give me the text you want me to consider right in the question." Reference-heavy writing forces the Operator to either remember what was meant or stop reading to look it up; when several references pile up in one message, the cognitive cost compounds into a message that cannot be engaged with.
The discipline: in Operator-facing responses, include the actual text you want the Operator to consider, written out, in the message. References are for things the Operator already has open or doesn't need to engage with directly. Longer messages from Claude.ai are an acceptable cost; messages the Operator cannot engage with are not.
Phase 63 follows the standard methodology cadence used by Phases 56 and 62 before it. Five further steps, each typically a session of work:
| Step | What it produces | Surface |
|---|---|---|
| Step 0 — Inspection | Pre-flight verification of the assumptions in this scoping note against actual code state. Includes verifying the FORAY extension pattern in the engine, the audit substrate's exact API shape, the deployment-architecture question for record.dunin7.com calling the engine, and any Phase 62 editor code that needs updating for the version-bump scanner. | Claude.ai produces a Step 0 inspection brief; Claude Code executes; findings come back |
| Change Request drafting | The Change Request document itself — step-by-step execution plan with acceptance gates. | Claude.ai drafts; cross-check cycle absorbs any findings |
| Execution | The work itself. Editor refinement in the loomworks-record repository's Pages Functions and editor.js; FORAY writer in loomworks-engine; audit viewer on record.dunin7.com; read API in the engine. | Claude Code executes against the CR; Claude.ai surfaces any halt-and-surface events |
| Close | Tag both relevant repositories at the phase name. File close handoff. Trigger manifest absorption (which will be the first absorption since v0.41 — closing several other phases of carry-forward at the same time, separately). | Standard close protocol |
Phase 63 will likely take four to six sessions of focused work end-to-end. The longest single piece is the audit viewer (Piece 3) because it spans three surfaces — the read API on the engine, the deployment-architecture wiring between record.dunin7.com and the engine, and the viewer page itself. The other two pieces are bounded to single surfaces each.
Once Phase 63 closes, the architecture specification update that triggered this whole arc resumes against an editor that the Operator can trust as a Path B working surface — and against an audit substrate that records the trail of the update work itself. The discipline the architecture specification names ("each substantive change to Loomworks should update this document") becomes operationally observable.