DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path phases/stele-extraction-phase-7/loomworks-stele-phase-7-p7-1-completion-record-v0_1.md

Loomworks — Stele Phase 7 P7-1 (Packaging Floor) Completion Record — v0.1

Version. 0.1 Date. 2026-06-19 Author. Marvin Percival (DUNIN7 Operator) with Claude.ai (CR drafting) on DUNIN7-M4; CC executing on DUNIN7-M4. Status. Completion record. CR-2026-114 (Stele Phase 7 P7-1 — Packaging Floor) is built, verified, and pushed: the standalone DUNIN7/stele repo (private) is live, and loomworks-engine consumes it as an installed package (merged-equivalent — pushed to main). Markdown primary (technical consumer).

Governing CR. change-requests/cr-2026-114-stele-phase-7-p7-1-packaging-floor-v0_1.md (record a5814ce).

Grounding line at execution. engine main = fe7c3f1 (CR-B merge) at Step-0; suite 2928/0/46. Re-confirmed fe7c3f1 before the engine re-point.


Plain-language summary

What P7-1 did. Lifted Stele out of the engine monorepo into its own standalone repository (DUNIN7/stele, private), gave it its own dependency manifest, and gave it an independently-runnable migration set — then re-pointed the engine to consume stele as an installed package. The done-bar held: a fresh clone installs from its own manifest and builds the three Stele tables against a fresh database with zero DUNIN7/Loomworks dependency.

What it did NOT do (held to scope): no SDK surface, no mountable router (P7-2); no reference app or docs (P7-3); did not re-open the §E router fork (resolved B / primitives-only); did not split persons/signup.py or decide the cookie helpers (P7-2).

The three decisions the CR made, as-built:

  1. actor.py stayed host-side — Stele's standalone library is 9 modules (the 10th, actor.py, constructs the host's ActorRef; it remains in the engine, re-pointed to import stele.registry).
  2. The migration set is one fresh consolidated baseline (down_revision = None), not a revision lift.
  3. Stele ships 3 tables, not 4 — KEK-direct TOTP encryption, no data_encryption_keys.

The one behavior change (TOTP secret: envelope → KEK-direct) resolved to a verified no-op against live data — see §3a.


1. What was built

DUNIN7/stele (private; main = 0d5e265) — a standalone repo:

loomworks-engine (main = ff0c4cf, pushed) — re-pointed to consume the package: loomworks.stele.stele. across 185 .py; stele added as an editable path dep; the 8 local module copies removed (actor.py kept).

2. The build

stele repo (4 commits, DUNIN7/stele main 0d5e265):

| # | Commit | What | |---|---|---| | 1 | b628a96 | Initial lift: 9 core modules verbatim from engine fe7c3f1 (actor.py excluded) | | 2 | 2ac288f | Standalone adaptation: KEK-direct TOTP crypto (stele/kek.py) + imports re-pointed loomworks.stele. | | 3 | d9a386d | D2: dependency manifest (pinned) + README | | 4 | 0d5e265 | D3: alembic root + consolidated 3-table baseline |

The verbatim lift was committed first so the standalone adaptation reads as an auditable diff against the engine snapshot.

engine (2 commits, loomworks-engine main ff0c4cf, pushed):

| # | Commit | What | |---|---|---| | 1 | 5d92cf5 | Re-point: consume stele (uv add --editable ../stele; 185 .py re-pointed; actor.py preserved → stele.registry) | | 2 | ff0c4cf | Remove the 8 local loomworks.stele copies (by-the-9; actor.py + __init__.py kept) |

Suite 2928 / 0 / 46 at every engine commit (after re-point; after removing copies). Add-and-verify throughout: the engine never had a window where it could not import what it needed (install → re-point → verify → remove).

3. As-built corrections (preserved, not smoothed)

3a — §6 re-wrap resolved to a verified NO-OP; the CR's "prevent lockout" premise was false against live data. The CR carried the TOTP envelope→KEK-direct switch as a migration that must re-wrap existing envelope-encrypted secrets "or lock principals out." Two findings, both recorded:

3b — the why-thread: envelope SCOPE_TOTP secrets were expected but absent (a walkable thread about CR-2026-102's landed state, not a P7-1 defect). The engine's registry.mint_principal / person_totp called encrypt_for_scope(SCOPE_TOTP, …) (the envelope path, which prefixes lwenv1:), yet zero lwenv1: TOTP secrets exist on playground_dev. The likely explanations: CR-2026-102's Step-3/4 SCOPE_TOTP call-site repoint / data migration never actually landed for these secrets (the key-custody migration script was recorded as gated/not-run), or the 38 values are mirrored-in legacy secrets from the personsprincipals expand window (written bare before envelope) and no fresh envelope-writing signup has occurred since. Flagged as a thread to walk about CR-2026-102's true landed state — it does not affect P7-1 (the standalone is KEK-direct; the engine reads bare tokens), but it means the engine's intended TOTP envelope encryption was not actually in effect for this corpus.

3c — the engine consumes stele via a relative-path editable dep (CR-sanctioned local install). engine/pyproject.toml now carries stele = { path = "../stele", editable = true } + the lock entry. This is the CR's sanctioned "editable/local path install at this stage" (§102; the published-package path is a later slice). Deploy-time implication (recorded): the engine requires the stele repo present at ../stele (i.e. both repos under the same parent) until the published-package slice replaces the path dep with a version pin. Today both sit under /Users/dunin7/.

3d — two live-DB schema facts the ORM model alone would have missed, reproduced in the baseline. The CR's "read the live DB, not the model shorthand" grounding caught: (a) webauthn_credentials.id and recovery_codes.id carry gen_random_uuid() server defaults while principals.id does not (the 0029 vs 0085 origin), and (b) two migration-only indexesidx_webauthn_credentials_person, idx_recovery_codes_person — present in the live DB but absent from __table_args__. Both reproduced; the baseline diffs byte-faithful against live (all 3 tables identical in columns/constraints/indexes).

3e — two soft Loomworks-isms kept for engine compat; noted forward for P7-2/3 polish. The standalone reads the KEK from the LOOMWORKS_SECRET_KEY env var (callers inject secret_key explicitly, so this is only the fallback default), and the session cookie name stays loomworks_session (a functional value the engine's host set/clear depends on). Both are STELE-native-rename candidates for P7-2/3 — left as the engine's names so the engine's deployment env and the engine re-point work unchanged.

4. Verification — clone-and-build done-bar met

5. End-state

6. Carry-forwards to P7-2 (and beyond)

  1. The §E primitives-only router — P7-2 constructs the mountable router (the me_security/auth_dev shape); signup/login stay host compositions; the reference app demonstrates the wiring. (CR-2026-115.)
  2. The session/cookie seamCOOKIE_NAME (loomworks_session), the host _clear_session_cookie, and api/deps.py session resolution; plus the queued direction loomworks-queued-direction-p7-2-session-delivery-ui-vs-agent-v0_1 (cookie vs bearer over the same token).
  3. The published-package slice — replace the engine's ../stele editable path dep with a version pin against a published stele (and the deploy-time co-location implication, §3c).
  4. STELE-native renamesLOOMWORKS_SECRET_KEY → a STELE env var; loomworks_session → a STELE cookie name (§3e). P7-2/3 polish.
  5. CR-2026-102 landed-state thread (§3b) — confirm whether the engine's TOTP envelope encryption was ever actually in effect; orthogonal to Stele.

7. Methodology lessons banked (for the next consolidation)

  1. Count before you convert. A migration framed as "prevent lockout" was a no-op against live data; the count-first discipline (Pin 2) turned a planned data migration into a one-line skip with a verified reason. The CR's premise was an assumption, not a fact — verified, then corrected.
  2. A premise can be false in two independent ways at once — here both the mechanism (host dual-paths decrypt → no lockout possible) and the data (zero envelope secrets → nothing to convert). Recording both, not just the first, makes the correction walkable.
  3. Read the live DB, not the ORM model — the two schema catches (§3d) were invisible to __table_args__; only the live DDL had them. (CR-B's "an inventory's lenses define its blind spots," reproduced.)
  4. Lift verbatim first, adapt second — committing the byte-for-byte lift before the standalone adaptation makes the adaptation an auditable diff, not an opaque rewrite.
  5. Add-and-verify for cross-repo moves — install the package, re-point, verify green, then remove the local copies. The engine never lost the ability to import what it needed.

DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks — Stele Phase 7 P7-1 (Packaging Floor) Completion Record — v0.1 — 2026-06-19