DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path change-requests/cr-2026-103-stele-extraction-phase-0-v0_1.md

Loomworks change request — Stele extraction Phase 0 (stand up the module, move the zero-caller pieces) — CR-2026-103 — v0.1

Version. 0.1 Date. 2026-06-14 Status. Change request — the first executable phase of the Stele extraction. Stands up the named Stele module inside the engine and moves the identity pieces that have zero external callers, proving the module boundary and the test-in-isolation before anything load-bearing moves. Markdown primary (technical consumer: Claude Code). Halt-before-push; per-step commits; verify against engine-database truth. Decisions this CR rests on (all settled): (1) Stele's interface is a host-agnostic API contract, in-process first, service-ready. (2) The contract is complete (defines passkey-revoke and TOTP-rotate, which arrive in a later phase). (3) Sign-up split is approach B — mint-then-onboard with a heal path (Phase 4, not this CR). (4) Move, not duplicate — relocate code in small reversible slices; one implementation throughout; safety from small reversible steps, not a parallel fallback. (5) White-label/multi-language hooks (tenant_context, locale) thread into user-facing operations (later phases, not this CR). Source grounding. The Stele extraction scoping note v0.1 (Phase 0 definition), the integration design v0.2 (the contract), and the Claude Code coupling map (engine c210715). The coupling map established that the pieces below have zero external callers — that is what makes Phase 0 the safe first slice.


Plain-language summary

This is the first, safest step of giving Stele a clean boundary. It creates the Stele module and moves into it only the pieces of identity code that nothing else in the engine imports — the credential storage, recovery codes, TOTP logic, the WebAuthn ceremony, and the session encode/decode. Because nothing outside imports these, moving them cannot break any caller — which makes this the ideal slice to prove the module structure and to stand up the test harness that exercises Stele in isolation. No behaviour changes; this is pure relocation plus a standalone test. If anything looks off at the halt, it reverts as a single commit. Nothing load-bearing (the "who is signed in?" path, the identity records, sign-up) moves in this phase — those are later CRs.

1. Scope of Phase 0

In scope — move into the new stele module (zero external callers, per the coupling map):

Explicitly NOT in scope this phase (later CRs):

2. Steps (each its own commit; halt before push)

Step 0.1 — Create the module skeleton. Create the stele module/package inside the engine (confirm the engine's module layout and place it consistently — e.g. src/loomworks/stele/). Empty package with its __init__. Commit. No behaviour change.

Step 0.2 — Verify the zero-caller claim, then move the clean-internal pieces one file at a time. For EACH file in §1, before moving it: grep the whole engine for imports of its symbols from outside the identity set; confirm zero external importers (the coupling map says zero — verify against the live tree, do not trust the map alone). Then move the file into stele/, update any imports among the moved files to the new paths, and run the test suite. One commit per file moved. If any file turns out to have an unexpected external importer, halt and report rather than proceeding — that would mean the boundary differs from the coupling map and needs a decision.

Step 0.3 — Wire the KEK reference. The session and credential logic encrypt under the shared key-encryption key, which stays in credentials/ (it is also used by api-keys, system-config, and the credential store — it is shared infra, not Stele's). Confirm the moved Stele code references the KEK from its existing location and does not copy or move it. Commit if any import path adjustment is needed.

Step 0.4 — Stand up the isolation test harness. Write a test that exercises the moved Stele pieces without booting the rest of the engine — create the Stele tables, generate and store recovery codes, verify-and-consume one, run a WebAuthn registration ceremony against a test config, encode and decode a session. This is the proof that Stele is independently testable (the Operator's "minor ecosystem" requirement). The harness provides a test KEK and a test config; it does not import engagements, memory, or credit. Commit.

Step 0.5 — Full-suite regression. Run the complete engine test suite and confirm nothing broke (nothing should — no external caller was touched). Verify against the engine database that sign-in still works end to end (the login path still imports these symbols, now from stele/ — confirm the import-path updates are complete and correct). This is the database-truth check, not suite-only. Halt and report results.

3. What must not happen in Phase 0

4. Halt and report

After Step 0.5, halt before any push. Report: the module location, the files moved (with confirmation of zero external callers for each), the KEK-reference handling, the isolation test result (proof Stele exercises in isolation), and the full-suite + database sign-in regression result. On the Operator's review, push Phase 0; then Phase 1 (the identity records and registry) is the next CR.

5. Reversibility

Every step is its own commit. If the halt review finds a problem, the offending step reverts as a single commit with no effect on the others. There is no parallel copy to reconcile — a revert simply puts the moved file back at its prior path. This is the safety model: small, reversible slices, not a fallback implementation.


DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks change request — Stele extraction Phase 0 (stand up the module, move the zero-caller pieces) — CR-2026-103 — v0.1 — 2026-06-14