Version. 0.1 Date. 2026-06-12 Purpose. Open a fresh, isolated session to complete account-recovery for Loomworks personal identity: make the seed's three committed recovery mechanisms real where they are not, carry the seed's positive recovery commitment forward into the Companion functional spec (which currently states recovery only negatively), and resolve the sign-in email-field question inside recovery rather than ahead of it. This is scoping-and-build-planning work, not a single CR drafted in flight. Paste or upload this on arrival.
Role of this session. Scope, decide, and produce CR-drafting handoff(s) and any seed/spec amendment for Operator approval. Extended-inquiry on the design questions; disciplined on the build. Treat as Discovery raw material — when a position is corrected, name the prior alongside the current.
The seed already designed recovery well — line 137 names three credential-based mechanisms and rejects email. The problem is not design; it is that the design is only partly built, the spec never carried the design forward, and a sign-in email-field divergence surfaced that turns out to be entangled with the recovery design. This session makes recovery whole: build what is missing, document what is undocumented, and settle the email field with the recovery picture in full view.
This is authentication-framework work — seed territory, the highest-governance part of the project. Before any substantive work, have Claude Code (CC) surface from loomworks-record (highest-versioned present; do not assume from this handoff):
loomworks-candidate-seed-v0_12.md. The Authentication framework section is lines 101–141 (Identity, Sign-up, Sign-in, Account recovery, User-maintained attributes). Read it whole; this handoff quotes the operative lines but the session must read the live section.current-status-manifest-v0_51.md.loomworks-companion-functional-spec-v0_2.md, §10.3 the relevant section.The seed governs the spec; where the seed is silent the comprehensive specification governs.
A smoke test of the local Companion pair on the M4 (Operator Layer :3001 ↔ engine :8000) and a read-only investigation produced these. They are the starting facts.
> Recovery uses credentials the user controls and that cannot be hijacked at an external provider. Recovery codes generated at sign-up, additional registered authenticators, or operator-mediated identity verification are the acceptable mechanisms. Email-based password reset is not a recovery mechanism in Loomworks.
Three committed mechanisms: (1) recovery codes at sign-up, (2) additional registered authenticators, (3) operator-mediated identity verification. The seed commits the posture and (per its style) leaves mechanism detail to the specification. This is a positive commitment — recovery is not defined only negatively.
| Seed mechanism (line 137) | Engine state | Detail |
|---|---|---|
| Recovery codes at sign-up | BUILT, working | persons/recovery.py (generate, bcrypt-hash, store, verify-and-consume); 10 codes generated and displayed once at sign-up (persons/signup.py); redeemed at POST /auth/login/recovery (persons/login.py:442). |
| Additional registered authenticators | NOT usable (schema-only) | The data model is one-to-many (WebauthnCredentialRow, table webauthn_credentials, unique on credential_id not on person), so the schema allows multiple passkeys — but the only passkey-registration endpoint is POST /auth/signup/passkey. There is no endpoint to enroll a second/backup passkey for an existing user. So every user has exactly one passkey; this recovery path cannot be exercised today. |
| Operator-mediated identity verification | NOT built | No personal-account operator-recovery endpoint. (/admin/ is credit/provisioning; POST /engagements/{id}/contributors/{cid}/totp/reset is an engagement-operator resetting a contributor's* engagement-scoped TOTP — a different concern from a person recovering their own lost authenticator.) |
Today a user has exactly one passkey and one set of recovery codes, and nothing else. Recovery rests entirely on the codes. Lose the authenticator and the codes → permanently locked out; the other two seed-promised mechanisms do not exist in runnable form. This is the opposite failure shape from email: email recovery is too available (a backdoor); this is too unavailable (one working path, no redundancy). The seed correctly refused the over-available method; the under-availability is the unpaid cost.
Highest-value, lowest-cost fix: an endpoint to enroll a second passkey. The schema already supports it. A backup authenticator is a stronger recovery method than codes (not transcribable, not loseable-on-paper) and is the method serious passwordless systems lean on. This is a missing endpoint, not a missing design.
The Companion functional spec §10.3 states recovery only negatively ("recovery never uses email-based reset") and carries none of the seed's three positive mechanisms forward. No architecture/spec document in loomworks-record states a positive recovery mechanism. The positive commitment lives solely in the seed (line 137). The spec needs to carry the seed's positive commitment forward.
The Operator Layer sign-in form presents an optional email field, made optional in the Phase-57 amendment, used as a passkey-discovery hint; identity and lookup are by credential_id, not email. This diverges from the seed's Sign-in clause (line 133, verbatim):
> Sign-in does not request an email address. Sign-in does not key user lookup on email. Sign-in does not offer an email-based account recovery path.
And from spec §10.3 (heading and body both bake in "never requests email").
The Operator chose to relax line 133 to permit a non-identity email hint, rather than remove the field. Recorded. The Operator's stated rule: "email and mobile number can be associated with a user, but never used as the identity for sign-in."
The seed's Sign-in Path 1 already specifies the WebAuthn discoverable-credential mechanism for identifying the user:
> Path 1 — Passkey. The browser's native passkey prompt identifies the user (via the WebAuthn discoverable-credential mechanism) and authenticates them in a single step.
Discoverable credentials are exactly how a user with one-or-many passkeys signs in without naming themselves. So the email hint may be solving a problem the seed's own architecture already solves. Two honest readings, unresolved:
This session resolves which reading holds, with the recovery picture in full view, and only then finalizes either an amendment (v0.13) or a field-removal. The amendment was deliberately not drafted in the originating session because the recovery finding is material to it.
The email field's justification (passkey discovery) and the recovery design (additional authenticators, discoverable-credential sign-in) share the same mechanism — discoverable credentials. Deciding the field without the recovery picture is what produced the tension in the first place. One session, one coherent authentication-framework pass.
Candidate scope, in rough priority. The session confirms, reorders, or amends.
## Drafter's notes for v0.13 (numbered, Sign-in the affected section); (c) rename existing ## Drafter's notes for v0.12 → ## Drafter's notes preserved from v0.12; (d) add an inline > What changed from v0.12, and why (Discovery-record note). blockquote in the Sign-in subsection, quoting the old "does not request an email address" sentence and stating the relaxation. The amended seed goes to a new loomworks-candidate-seed-v0_13.md, leaving v0_12 byte-intact (standing record-doc rule). Spec §10.3 — fix the heading too ("…and never requests email"), not just the body.Operator-mediated recovery (§5.4) is another instance of a principle that recurred four times in the originating session (the skill/method vocabulary work, standing note v0.6 §2.1/§5/§7/§9.4): the source is acknowledged / supplies; the authority is granted by the Operator. Recovery-as-Operator-re-authorization is that principle at the credential layer — a governing human deliberately re-authorizes access, recorded. This is a strong v0.21 methodology consolidation candidate (source-supplies / Operator-governs), already flagged in the manifest. Not this session's work to consolidate, but if operator-mediated recovery is designed here, it should be designed in that principle's shape.
The skill/method/vertical vocabulary work from the originating session (standing note loomworks-standing-note-skill-method-vocabulary-v0_6, committed e04c222) is closed and unrelated. Its carried threads (personality/interaction domain; product-vs-service line; contract-proposal representation) are not this session's concern. The deployment question that started the originating thread (Companion live at dunin7.com) is deferred — the Operator confirmed local M4 access is sufficient for now; the Phase-52 engine-deployment gate remains deferred. Do not let either bleed in.
DUNIN7 — Done In Seven LLC — Miami, Florida Handoff → Recovery completeness session — v0.1 — 2026-06-12