Version. 0.1
Date. 2026-06-16
Author. Marvin Percival (DUNIN7 Operator) with Claude.ai (scoping) on DUNIN7-M4.
Status. Opening handoff for a fresh chat to scope and run the Stele contract phase — the physical teardown that 6b's view split deliberately deferred. Phase 6b is closed (merged 129d124, recorded CR-2026-110 v0.7, branch retired). Markdown primary (technical consumer / next-session orientation).
What the contract phase is. 6a split the tables and 6b re-homed every read off the fused Person view. Now nothing reads the host columns on persons through a view — so the contract phase physically tears down the transitional structure: drop the duplicate host columns from persons, re-target the 12 host foreign keys from persons to host_account, retire the two mirror triggers, and rename/relocate PersonRow host-side. After this, persons is principal-only (or gone), host_account is the sole host home, and the transitional mirroring is removed.
Why it is its own CR, and why it is different from 6a/6b. 6a and 6b were structured so the dangerous physical change came last, after the reads were safely moved. The contract phase is that last step. Critically: unlike 6b, this phase is all migrations. 6b was application-layer — alembic stayed at 0086 throughout, and that was a guarded invariant; its safety net was "the suite breaks loudly, revert pure Python." The contract phase is the opposite: every task is a schema migration. The safety model changes completely — migration up/down correctness, trigger-retirement ordering, and FK re-targeting against live data. This is genuinely more dangerous work and wants fresh, full-attention scoping with a real Step 0 inspect, not a continuation.
In order, from loomworks-record (record.dunin7.com, behind Cloudflare Access — if a file can't be reached directly, ask CC to fetch it):
loomworks-candidate-seed-vN_M in candidate-seeds/loomworks/ (canonical v0.12). The foundation document.current-status-manifest-vN_M in current-status/ (v0.61 just filed; confirm it is still highest). It marks 6b complete and names the contract phase as the next slice.change-requests/cr-2026-110-stele-extraction-phase-6b-v0_7.md. The 6b close-out; its "Contract phase — handoff" section is this phase's starting inventory.phases/stele-extraction-phase-6a/loomworks-stele-phase-6a-completion-record-v0_1.md. The mirror triggers (§5) and their ordered-pair retirement requirement; the column homes and the 12 host FKs.standing-notes/loomworks-stele-body-of-work-brief-v0_4.md (confirm highest). Where the contract phase sits (Phase 6 physical split: 6a + 6b + contract; Phase 7 = de-engine packaging).
| Ref | State |
|---|---|
| engine main | 129d124 (6b merged, --no-ff) |
| alembic | 0086 (will advance in the contract phase — this phase has migrations) |
| suite | 2933 / 46 / 0 |
| branches | no open Stele branch (6b retired) |
| views | one Principal (Stele) + HostAccount (host-side); Person view + get_current_person retired |
The new chat starts clean from main at 129d124.
The four teardown tasks, from CR v0.7's handoff:
persons host columns. Now that 6b re-homed every reader, the host columns on persons are duplicates of host_account. Drop them. Includes the mint host-column cleanup — mint stops writing email/mobile/onboarding_complete to persons. (Scope: which columns exactly, in what order relative to FK re-targeting and trigger retirement.)persons to host_account. (Scope: the real FK inventory, the re-target order, whether any FK is hot-path-sensitive, and the deferred/shared-id mechanics from 6a.)0085 (persons → principals) and 0086 (persons → host_account) fire in name-sort order. They must be retired so one never fires without the other (6a completion record §5). This is the single most ordering-sensitive task in the phase. (Scope: the exact retirement sequence; what depends on each trigger still firing during the column drop / FK re-target; whether retirement is one migration or an ordered sequence.)PersonRow host-side. The ORM row kept its name through 6b. Relocating it resolves the standing inversion: persons/host_account_view.py currently imports HostAccountRow from stele/models.py (the row still physically in Stele) — fine during expand, resolved at relocation. Use the token-level rename pattern proven in 6b 3.7 — a NAME-token sweep, NOT a blanket \bPerson\b regex, which would corrupt title="Person" (OpenAPI), "Test Person" string literals, and docstrings.
The ordering question is the heart of Step 0. These four tasks interact: the triggers keep host_account in sync with persons writes; dropping persons columns removes what the triggers mirror; re-targeting FKs changes what points where. The order — drop columns vs retire triggers vs re-target FKs — is not obvious and must be grounded against the real schema, not assumed. Expect this to be the central scoping work.
persons/migration.py imports Principal, _row_to_principal unused (the 6b 3.7 sweep renamed pre-existing dead imports). That file is touched at contract anyway; remove them here.personal_engagement_id= kwarg to local builders without reading it back. Consolidate onto the shared helper (tests/helpers/identity.py).persons.personal_engagement_id → engagements FK isolation issue (passes once any engagement-loading module is in the run; full suite green). Pre-existing. Directly relevant here — it surfaces exactly when personal_engagement_id's FK is re-targeted (task 2), so the FK re-target work should expect and resolve it.persons schema, the 12 FK definitions, both trigger bodies, and the column homes.git add -A).playground_dev, not the suite alone — especially for trigger retirement and FK re-targeting, where a schema change can pass unit tests but fail against real data shape.PersonRow rename (task 4). 6b's 3.7 sweep used a tokenizer so Person string literals and title="Person" were never corrupted. Reuse it.Phase 7 — de-engine completion + packaging: cut the remaining config/database/persons/shared-Base threads; Stele's own dependency manifest + migration set; the SDK surface; docs-with-runnable-examples; the reference UI template (closes the Phase 0 WebAuthn-ceremony gap). The clone-and-run standalone repo for the Claude Code Miami milestone. The contract phase is the last step before Stele is physically free of the host's schema.
DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks — Stele Extraction Contract Phase Opening Handoff — v0.1 — 2026-06-16