DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path standing-notes/loomworks-stele-body-of-work-brief-v0_4.md

Stele — Body of Work Brief — v0.4

DUNIN7 · Loomworks · Body of Work Brief · v0.4 · 2026-06-14 · Operator-facing

Stele — said "steel"

The principal layer — the part of Loomworks that knows who you are and proves it. This brief is the plain-English frame for the work: what Stele is, why it is worth building, how it sits against the field, what the work actually is, and what "done" looks like.

> In one paragraph. Every product Loomworks depends on assumes there is a someone acting — a person, or an agent acting for a person. Today that "someone" is established by scattered code inside the engine. Stele is the work of turning that scattered code into a clean, named product: an identity layer that creates and remembers who you are, authenticates you by passkey, manages your credentials, and — the new part — gives an AI agent a real identity of its own so it can act on your behalf. Stele is one of the four products that make Loomworks operational (alongside OVA, FORAY, and Loomworks itself). This brief describes the whole endeavour; the precise technical specification and the step-by-step build plan live in two companion documents, pointed to at the end.


Plain-language summary — what changed in v0.4

This version adds the part of the story v0.3 left as narrative: Stele now has a terminal destination beyond the in-engine phase plan. That destination is a clone-and-run standalone repository — its own code, its own SDK, comprehensive documentation with runnable examples, and a reference UI template — with no residual DUNIN7 or Loomworks dependency. And that destination has a dated, externally-visible milestone: the Operator is taking Stele to the Claude Code Miami group for independent testing, where the bar is plain — a stranger clones the repository and reaches a passing test run and a working sign-in without the Operator in the room.

Three things follow from naming that destination, and v0.4 works them out:

  1. The standalone goal is reached by re-sequencing the existing phase plan, not by a parallel track. The phases stay the spine; the standalone deliverables (de-engine-ing, packaging, the SDK, the docs, the UI template) are folded into the phase order so they fall out at the right phase, and the re-sequenced plan aims at the Miami date. (§5, §5A. The parallel-track alternative is named and set aside in §5A.)
  2. The persons.id foreign key is the gating design question, and it lands in Phase 1. Standalone Stele either owns its own principal table or defines that key as a host-supplied contract. v0.4 frames the decision sharply so Phase 1 resolves it with the standalone goal in view, rather than defaulting it (§4G).
  3. The full-cryptographic WebAuthn ceremony — deferred from Phase 0 as a named gap — closes at the Miami standalone-UI milestone, where a reference UI drives a real authenticator end to end (§4H, §6).

Everything in v0.3 that remains correct is preserved. What changed: §1 gains a line on the standalone destination; §4 gains the FK-decision sub-section (G) and the WebAuthn-ceremony-close sub-section (H); §5 is re-sequenced and gains §5A (the standalone work list, distributed into phases) and §5B (the FK decision framed for Phase 1); §6 names the two milestones with the standalone bar and the Miami date made concrete; §7 points at the current companion-document versions. The v0.3 milestone narrative is kept and sharpened, not replaced.


1. What Stele is

A doorway and a record of who is allowed through it.

Stele does three things, and only these three things:

The name fits the job twice over. A stele is an upright stone that bears an inscribed name, made permanent — which is what an identity layer does. And said "steel," it is the hardened structural spine the whole system stands on. Both meanings are exactly right for the part that holds who.

Example — what Stele does in a single sign-in. You open Loomworks. You tap your passkey. Stele checks it, asks for your authenticator code, and — once both check out — hands back a session that says "this is principal #a1b2, signed in, valid for 24 hours." That session carries only your identity number and the fact that you're verified. It carries no email, no roles, no permissions. Everything else gets looked up when needed. That is the whole of Stele's job in that moment: prove it's you, and say so in a way the rest of the system can trust.

It wears whatever brand and language the host gives it

Stele is a user-facing component, so it has to be able to present as a custom surface — any host's brand, any language the host supports. White-label and multi-language are first-class, designed in from the start (retrofitting them into an identity layer later is expensive and error-prone). The way it works keeps Stele clean: Stele provides the hooks; the host provides the content. Stele itself holds no brand and no copy. The login screen, the logo, the wording — all the host's. Stele just needs to be told, on each call, which brand and which language, and it makes sure the few things it unavoidably produces come out right.

Example — the same Stele, two brands. Aldous Coaching white-labels Loomworks. A coach signs in: the screen is Aldous's, the passkey prompt says "Sign in to Aldous Coaching," their authenticator app shows "Aldous Coaching," and every message reads in Spanish under Aldous's wording. None of that brand or copy lives in Stele — the host passes "Aldous Coaching" on the call and translates Stele's plain result-codes into its own Spanish. The user never sees "Loomworks" or "Stele." The same Stele, unchanged, serves a different customer's brand and language because it held neither to begin with. Adding a third language, or a tenth brand, never touches Stele.

Its terminal form is a repository a stranger can clone and run

New in v0.4 — the destination the rest of this brief now aims at.

Everything above describes Stele as it works inside Loomworks. But the point of giving identity a clean edge is that the edge becomes a thing you can hand to someone else. Stele's terminal form is a standalone repository: clone it, run it, and you have a working principal layer — its own code, its own dependency manifest, its own database migrations, an SDK that calls its contract, documentation whose examples actually run, and a reference UI template that drives a real sign-in end to end. No DUNIN7 account, no Loomworks engine, no hidden dependency on anything upstream. That is the form in which Stele stops being "Loomworks's identity code with a clean boundary" and becomes "an identity product anyone can pick up." Section 5 is the work of getting there; Section 6 is the externally-visible milestone that proves it arrived.


2. Why it is worth building as its own product

Because three other products are quietly leaning on it, and one of them can't stand up until it exists.

Stele's identity code already exists inside the engine — it was just never named or given a clean edge. So why do the work of pulling it out into its own product? Three reasons:

The other products assume it

OVA verifies that a principal is allowed to do something. FORAY records what a principal did. Loomworks governs what a principal may reach. All three assume a principal already exists — and none of them creates one. Stele is the thing they were all silently relying on. If OVA and FORAY are to be usable by anyone (which is the plan — they are independent products), the identity layer they assume has to be a real product too, not a Loomworks-only convenience buried in the engine.

Agents can't act until it exists

This is the urgent reason. Loomworks is about to introduce Companion Agents — AI agents that act on your behalf. An agent acting autonomously needs a verifiable identity of its own: a way to prove "I am this agent, authorised to act for this person." That mechanism does not exist today. An agent currently has no real identity to be. Stele is what gives it one. So the moment you want agents, you need Stele — they arrive together.

Example — why an agent needs its own identity. Imagine your Companion Agent drafts a document for you overnight. When it saves that draft, the system has to record who made it — and the honest answer isn't "you," it's "your agent, acting for you, under this authorisation." Without a real agent identity, the system can only pretend the agent is you, which erases the distinction that matters: a human reviewed and committed this versus an agent proposed it. Stele gives the agent a first-class identity so that distinction is preserved, truthfully, on every action. (And the final "commit" still requires a human — the agent can propose, never commit. That guarantee lives in Loomworks, not Stele, and stays permanent.)

A clean edge is a thing you can trust and test

Identity is the most security-critical code in the whole system. Buried inside the engine, you can only test it by running the entire engine around it. Pulled out as its own product with a clean front door, you can stand it up alone and hammer on it directly — create a principal, register a passkey, sign in, revoke a credential — touching nothing else. For a security layer, that isolation isn't a nicety; it's how you earn the right to trust it. And the strongest form of that test is a stranger doing it without you — which is what the standalone repository and the Claude Code Miami milestone are for (§6).


3. How Stele sits against the field

There are two kinds of competitor. Stele lives in the gap between them — deliberately.

We scanned the identity market to make sure Stele is complete where it should be and restrained where it should be. Two categories of product exist today:

Kind one — headless human-identity layers

The clearest example is Ory Kratos — an API-first identity server that does registration, login, recovery, sessions, and a broad menu of credential types (passwords, social login, email/SMS magic links, passkeys, authenticator codes, recovery codes). This is the right comparison for Stele's human side, and it gives us the checklist for what "complete" means.

But Stele is deliberately narrower here — and that narrowness is a feature. Loomworks's security posture rejects most of that menu: no passwords, no email-as-identity, no email/SMS magic links (because email is never identity). Stele keeps the strong, phishing-resistant subset — passkey, authenticator code, recovery codes — and drops the rest on purpose. Stele is not "Kratos with features missing." It is the opinionated, hardened subset the seed demands.

Kind two — agent / non-human identity platforms

A hot, well-funded category (Oasis, Astrix, Entro — Oasis alone raised $120M this year). But look closely at what they do: they discover, monitor, and govern the machine credentials that other systems issued — API keys, tokens, service accounts. They are a governance overlay. **None of them is the thing that issues first-class identity to an agent.** The industry's own 2026 consensus is that agents need first-class verifiable identities and traceable delegation — and that this layer is still being built.

That gap is exactly where Stele sits. Stele issues first-class identity to both humans and agents under one model. It is the issuer the market says is missing, not the governance overlay the market already has plenty of.

> The position, plainly: Kind-one products do human identity but have no real answer for agents. Kind-two products govern agents but don't issue them an identity. Stele is a single principal layer that issues first-class identity for both humans and agents — narrower than Kratos on credential types by design, and doing the agent-issuing job the well-funded agent-governance crowd doesn't do.

What Stele deliberately does not do

The competitors blur "issue identity" together with "authorise actions" and "monitor behaviour." Loomworks keeps these separate on purpose. So Stele's scope is fenced:

Stele issues and authenticates. It does not monitor, score, or govern. Keeping that line sharp is what keeps Stele a clean product instead of sprawling into everything.


4. What the work actually is

Mostly careful moving, with one genuine new build, one real refactor, and — new in v0.4 — the de-coupling and packaging that make the result a repository a stranger can clone.

The encouraging finding from mapping the actual code: most of this is extraction, not invention. The identity code exists and works; the work is giving it a clean front door and filling a few real gaps. Here is the whole body of work, in plain terms.

A. Give Stele a front door (the contract)

Define Stele as a set of clean requests and responses — "authenticate this person," "tell me who this session belongs to," "register a passkey," "revoke this credential," "mint a new principal," "give this agent an identity." This front door is shaped like a web API even though, at first, it runs inside the engine — so that later, when a second product needs Stele, turning it into a standalone service is just "put a network under the door," not a rewrite. (The precise contract is written in the companion technical document.)

B. Move the existing identity code behind the door (the extraction)

Pull the identity rows, the credential storage, the passkey/authenticator/recovery logic, the session handling, and the actor construction into a named Stele module. The reassuring part: the two scariest-looking numbers — the 119 places that ask "who is signed in?" and the 93 places that use the identity to label an action — don't change at all, because Stele slots in underneath them. Most of the work is mechanical moving and updating where code is imported from.

C. Fill two real gaps the scan exposed

Measuring Stele against a complete identity layer surfaced two holes in today's code that a finished product must close:

Choosing to define the complete contract — including these gaps — is the right call precisely because we control the first use case (the Companion). We get to design the whole ecosystem thoughtfully and prove it against a consumer we also build, rather than reverse-engineering a contract from whatever the first integration happened to need.

D. The one real refactor — splitting sign-up

Today, creating an account does several things in one inseparable step: it mints the principal (Stele's job) and sets up the person's memberships and personal workspace (Loomworks's job). Pulling Stele out means cutting that into "Stele mints the principal" → "Loomworks sets up the account." This is the one place that is genuine design, not mechanical moving, because it raises a real question: what happens if the account setup fails after the principal already exists? This gets its own careful, isolated step. The approach is settled: approach B — Stele mints and commits, the host onboards next, and a principal-without-onboarding is a defined, recoverable state. (Locked decision; see the integration design §4.2 and the manifest's locked-decisions list.)

Example — why the sign-up split needs thought. Today, signing up is all-or-nothing: either you get a principal and a workspace, or nothing. Once Stele mints principals separately, you could end up with a principal that exists but whose workspace setup failed halfway. That's not necessarily bad — it just has to be a defined, recoverable state, not an accident. Because Stele is meant to stand on its own eventually, the cleaner long-term choice is to let the principal exist and have the workspace setup heal afterward — rather than welding the two back together in a way that won't survive Stele becoming a separate service.

E. The agent identity (the genuinely new build)

Everything above is the human side. The new construction is giving an agent a real, verifiable identity — using established open standards (the same token-exchange standards the industry is converging on) rather than inventing our own. This is what unblocks Companion Agents, and it's sequenced after the human-side extraction is solid.

F. Complete the recovery story

With passkey-revoke and authenticator-rotate now defined, finish the "how do you get back in when you've lost a factor" story — inside the now-clean Stele boundary, where it's a matter of completing a defined module rather than untangling scattered code.

G. The persons.id foreign key — the gating decision for standalone

New in v0.4. This is the one decision the standalone destination turns on, and it lands in Phase 1.

Here is the coupling that independent testing will expose first. Stele's credential rows and recovery rows point at a person by a foreign key — persons.id. Inside the engine, that key points at the shared persons table, which today carries both Stele's identity columns and Loomworks's account-lifecycle columns (the spend preference, the pause flag, and the rest), all under one database Base. As long as Stele runs inside the engine, that's fine — the table is right there.

But a stranger who clones a standalone Stele has no persons table from Loomworks. So the foreign key has to mean one of two things, and Phase 1 must choose which:

The standalone bar — a stranger clones it and gets to a passing test run and a working sign-in without the Operator in the room — bears directly on this. Under host-supplied-contract, a stranger cannot reach a passing test run by cloning alone; they must first build a host table that the repository doesn't ship. Under own-its-own-table, the clone is self-sufficient. **The decision is framed for Phase 1 in §5B, with the recommendation surfaced but not pre-decided — Phase 1's Base/foreign-key decision is this decision, and the Operator settles it there.**

H. Close the WebAuthn full-ceremony gap — at the standalone UI

New in v0.4. Names where the Phase 0 carry-forward gap closes.

Phase 0 verified the load-bearing half of authentication against the real database end to end — session decode through "who is signed in," recovery's read path, the relying-party configuration — but it could not exercise a full cryptographic WebAuthn ceremony (a real signed attestation on registration, a real signed assertion on authentication), because that requires a real browser and a real hardware or software authenticator producing a signed credential, which a headless test cannot do. The Phase 0 completion record named this as an acceptable gap carried forward — acceptable because the moved code is a byte-identical rename (a rename can break import resolution, which the running server disproves, but cannot break cryptography), and because the half every authenticated request actually runs on did get the full real-database check.

v0.4 names where that gap closes: at the Claude Code Miami standalone-UI milestone. The reference UI template (§5A) drives a real authenticator end to end — register a passkey with a real signed attestation, sign in with a real signed assertion — which is precisely the ceremony a headless harness cannot reach. This is not a loose end; it is the natural and correct place to close it, because the standalone milestone is the first point at which a real UI and a real authenticator are both in the loop. The carry-forward and its closure point are now recorded together.


5. The order of the work

Lowest-risk first, so the boundary is proven before the one hard part — now re-sequenced so the standalone deliverables fall out at the right phase and the plan aims at the Miami date.

v0.4's structural choice: the standalone goal is reached by re-sequencing this phase plan, not by running a separate packaging track beside it. The phases below stay the spine of the work; the standalone deliverables — de-engine-ing, packaging, the SDK, the docs, the UI template — are folded into the phase order at the phase each naturally belongs to, and the later phases are arranged to reach a clone-and-run repository by the Miami date. (Why re-sequence rather than parallel-track: §5A.)

| Phase | What happens | Standalone deliverable folded in | Risk | |---|---|---|---| | 0 | (complete, pushed) Stand up the Stele module; move the pieces nothing else touches (credential storage, recovery, authenticator, passkey ceremony, session encode/decode) | The named module boundary — the precondition for everything below | Lowest — proved the boundary | | 1 | Move the identity records and the principal view; carry the credential row models and credentials.py; make the persons.id foreign-key / Base decision (§4G, §5B) | The packaging foundation: own-table-or-contract decided; if own-table, Stele's own principal table + the first of its own migrations | Low-mechanical on the moves; the FK decision is the load-bearing one | | 2 | Move the actor construction (how an action gets labelled with who did it) | Cuts the actor-construction thread off the engine's internals | Low, contained | | 3 | Point "who is signed in?" at Stele — its name and shape unchanged, so the 119 callers don't move | Cuts the session-resolution thread to a contract call | Low to move, but test the full sign-in path hard | | 4 | Split sign-up (approach B): Stele mints the principal, Loomworks sets up the account | Cuts the mint↔onboarding thread — the last functional coupling to the engine | The one real refactor — its own scrutiny | | 5 | Complete recovery + build passkey-revoke and authenticator-rotate, inside the clean boundary | The complete, honest credential lifecycle the SDK and docs document | New build, into a defined shape | | 6 | De-engine completion + packaging: cut the remaining config/database/persons/shared-Base threads the isolation harness still imports; give Stele its own dependency manifest and its own migration set; stand up the SDK surface over the contract | The clone-and-run repository, dependency-complete and migration-complete | Moderate — this is where "no residual dependency" gets proven | | 7 | Docs-with-runnable-examples + reference UI template: comprehensive documentation whose examples execute against the standalone repo; a reference UI that drives a real authenticator end to end (closes the Phase 0 WebAuthn ceremony gap — §4H) | The two artifacts a stranger needs to clone-and-run; the Miami milestone target | Moderate — the UI is where the full WebAuthn ceremony is exercised for the first time | | Later | Build agent identity (token-exchange standards) and the agent actor path | First-class agent principals in the standalone product | The new construction; unblocks agents |

Every phase is committed separately, paused for your review before anything is pushed, and tested against the real database — not just the test suite. The auth path is tested hardest. Phases 0–5 are the in-engine extraction (Phase 0 done); Phases 6–7 are the de-engine-ing and packaging that turn the extracted module into a repository a stranger can clone; the agent build follows.

Note on the agent build and the Miami date. The agent identity (E / "Later") is not a precondition for the Miami milestone. The Miami bar is "a stranger reaches a passing test run and a working sign-in" — a human-side claim. Agent identity can land before or after Miami without moving the date; it is sequenced by the Companion Agent need, not by the standalone milestone. If the Miami date approaches and the agent build is not done, the standalone repository ships with the human side complete and the agent operations defined-but-pending, which is an honest state.

5A. The standalone work list, and why re-sequence rather than parallel-track

New in v0.4.

The standalone milestone implies five concrete workstreams. v0.4 distributes them into the phases above rather than into a separate track. Here is each, what it concretely means against current state, and where it lands:

  1. De-engine-ing — cutting the threads the isolation harness still imports. Phase 0's isolation harness proves the moved logic runs without the rest of the engine, but it still reaches for engine-level configuration, the engine's database setup, the shared persons/account columns, and the shared SQLAlchemy Base. Standalone means cutting each of those: Stele reads its own configuration, owns its own database session setup, owns its own principal table (per the §4G decision), and declares its own Base. Most of these threads are cut as a side effect of the phase that owns them — the Base thread at Phase 1, the session-resolution thread at Phase 3, the mint↔onboarding thread at Phase 4 — and the residue (config, database setup, whatever the harness still imports after Phase 5) is cut at Phase 6. This is the central reason to re-sequence rather than parallel-track: the de-engine-ing is not separable from the phases that do the cutting; each thread is cut cleanest by the phase that already touches it, not by a parallel effort reaching back into finished phases.
  2. Packaging — own dependency manifest, own migrations. A clone-and-run repository brings its own dependencies (its own manifest, pinned) and its own database migrations (so a stranger runs one command and has the schema). The migrations begin at Phase 1 (the first Stele-owned table, if own-table is chosen) and complete at Phase 6 (the full migration set for the standalone schema). The dependency manifest is assembled at Phase 6, once the de-engine-ing has revealed exactly what Stele depends on and nothing more.
  3. The SDK surface. The contract (§3 of the integration design) is the set of operations; the SDK is the callable form of that contract for a host integrating against standalone Stele. It lands at Phase 6, over the now-complete contract, so it never has to be revised to track an operation that hasn't settled.
  4. Docs-with-runnable-examples. Comprehensive documentation whose code examples execute against the standalone repository — not prose snippets, but examples a stranger runs and watches succeed. This is the difference between "documented" and "a stranger can clone-and-run." Lands at Phase 7, against the finished SDK and packaged repo, so every example runs against the real shipping surface.
  5. The reference UI template. A working front-end that drives Stele's flows end to end — sign-up, sign-in, credential management — and, critically, drives a real authenticator, which is what closes the Phase 0 WebAuthn ceremony gap (§4H). Lands at Phase 7. It is a template (a host adapts it), not Stele's own UI — Stele renders no UI (integration design §8.2); the template shows a host how to.

> Why re-sequence (lean A), and the alternative set aside. The alternative considered was a parallel packaging track: keep the phase plan reaching "clean in-engine module + service-ready contract," and run a separate track that does de-engine-ing, SDK, docs, and UI against whatever phase state exists at the Miami date. Its appeal is that a slip in Phase 4 (the one real refactor) wouldn't block packaging work that doesn't depend on it. It was set aside because the largest standalone workstream — de-engine-ing — is not independent of the phases: each engine thread is cut cleanest by the phase that already touches that code, and a parallel track would either duplicate that cutting or reach back into finished phases to do it, re-opening boundaries the phase plan deliberately closed. Re-sequencing keeps each thread cut once, by the phase that owns it, with the packaging-specific work (manifest, SDK, docs, UI) gathered into Phases 6–7 where it has the finished surface to build against. The cost of re-sequencing — that a slip in an early phase pushes the Miami date — is accepted: the Miami date is the Operator's to set against real phase progress, and an honest date that moves with the work beats a parallel track that ships a packaged repo around an unfinished core. (This is the structural choice v0.4 turns on; it is recorded here with its alternative per corrections-not-smoothed discipline.)

5B. The persons.id foreign-key decision, framed for Phase 1

New in v0.4. This sub-section exists so Phase 1 resolves the decision deliberately rather than defaulting it.

Phase 1 already makes a Base/foreign-key decision — it moves the identity records and now also carries the credential row models and credentials.py, which means it decides, once, how the identity rows relate to the shared persons.id and the shared Base. v0.4's point is that this decision and the standalone own-table-or-contract decision are the same decision, and Phase 1 should make it as one, with the standalone consequence in view.

The decision, stated as one question Phase 1 answers:

> Does standalone Stele ship its own principal table (foreign keys point inward), or declare persons.id as a contract the host must satisfy (foreign keys point at a host-supplied table)?

The two branches and their standalone consequences (from §4G), restated as the choice Phase 1 faces:

Recommendation surfaced, not pre-decided: own-its-own-table, because the standalone bar is "a stranger reaches a passing test run and a working sign-in by cloning," and host-supplied-contract makes the clone insufficient on its own. But this is Phase 1's call, made when the real Base-split work is in front of the Operator — v0.4's job is to ensure Phase 1 sees both faces of the one decision and the standalone consequence of each, not to settle it here. The Phase 1 change request should state the decision explicitly, present both branches, and record which was chosen and why (corrections-not-smoothed).


6. What "done" looks like

The outcomes this work delivers.

The two milestones, and the standalone bar

There are two milestones, not one, and naming the second keeps the plan honest.

Milestone one — Stele works for the Companion. Running inside the engine, with Loomworks as the only consumer. This is reached across Phases 0–5: the extraction is complete, the gaps are filled, the Companion runs on Stele unchanged above the line. The contract is designed and proven against a consumer we control.

Milestone two — Stele is offerable to an outside group, and a stranger reaches a passing test run and a working sign-in without the Operator in the room. This is the standalone milestone, reached across Phases 6–7: the de-engine-ing is complete, the repository is packaged (own manifest, own migrations), the SDK is up, the docs' examples run, and the reference UI drives a real authenticator end to end. This is where Stele becomes genuinely standalone.

The bar, stated plainly: a stranger clones the repository and gets to a passing test run and a working sign-in, without the Operator in the room. Every Phase 6–7 deliverable is in service of that one sentence. A passing test run means the cloned repository's own suite runs green on a machine that has never seen Loomworks. A working sign-in means the reference UI drives a real authenticator through a real WebAuthn ceremony — which is also the moment the Phase 0 carry-forward gap (§4H) closes.

The externally-visible milestone — Claude Code Miami

The first external test is a local technical audience: the Claude Code Miami developer group. It is close to an ideal first outside consumer — technical enough to integrate against the contract and file real feedback, and, crucially, a second consumer, which is the exact forcing function the architecture has been waiting for. Several pieces of work were deliberately deferred "until a second consumer needs it" (turning Stele into a reachable form a stranger can stand up, and splitting the identity data away from Loomworks's account data — the §4G decision). A real outside group with a date attached is what turns those deferrals from "someday" into "now," and de-risks them — you extract because a concrete consumer is going to use it, not on speculation.

It is also the honest test of the contract. The Companion is a consumer we control — excellent for designing the contract, but weak for proving it, because we will unconsciously shape both sides to fit. A stranger building on Stele without us in the room is the real proof: if they can, the contract is genuinely good. And a local group using the open-source Stele (at stele.dunin7.com, under DUNIN7) is the start of the adoption story — first real users, first feedback, possibly first contributors.

One caution preserved from v0.3: don't offer it the day the Companion works — offer it after the de-engine-ing and packaging (Phases 6–7), or every integrator gets hand-held through an in-process module that was never built to be reached from outside, and the "test" measures patience rather than quality. The right moment is: Companion-proven (Phase 5) → de-engined-and-packaged (Phase 6) → docs-and-UI-template (Phase 7) → then a clone a stranger can run.


7. The companion documents

This brief is the readable frame. The precise specifications live here.

loomworks-stele-integration-design-v0_2 — The complete API contract: every operation, its exact request and response, marked live (exists today) or to build — plus the host integration contract (how the Companion, and later OVA/FORAY/others, consume Stele), the white-label/multi-language hooks (§8), and the in-process-first implementation path. (Note: §5.2 already defers the physical identity/account table split to the service extraction; the §4G/§5B decision in this brief pulls that split forward to Phase 1 in service of the standalone goal — when the integration design next versions, it should record that the split is no longer deferred to service extraction but decided at Phase 1.)

cr-2026-103-stele-extraction-phase-0 — The executable Phase 0 plan (v0.3 on the record), now complete and pushed (engine origin/main e4656b4). The Phase 1 change request is the next to be drafted, and it is the one that must surface the §4G/§5B foreign-key decision explicitly.

loomworks-stele-phase-0-completion-record-v0_1 — What Phase 0 closed, the two mid-flight boundary corrections, the isolation proof, the real-database sign-in result, and the named WebAuthn-ceremony gap carried forward to the standalone-UI milestone (closed at Phase 7 per §4H).

The decisions waiting on you before Phase 1 becomes an executable change request:

  1. The persons.id foreign-key decision (§5B): own-its-own-table or host-supplied-contract. Recommendation surfaced (own-table); Phase 1's call.
  2. Confirm the re-sequenced phase plan (§5): the standalone deliverables folded into Phases 6–7, the agent build sequenced independently of the Miami date.
  3. Set the Miami date against real phase progress — the date the re-sequenced plan aims at, the Operator's to set and move with the work.

DUNIN7 — Done In Seven LLC — Miami, Florida Stele — Body of Work Brief — v0.4 — 2026-06-14