DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path scoping-notes/loomworks-stele-phase-3-scoping-note-v0_1.md

Loomworks — Stele Extraction Phase 3 Scoping Note — v0.1

Version. 0.1 Date. 2026-06-15 Author. Marvin Percival (DUNIN7 Operator) with Claude.ai, against engine origin/main 677c46f (post-Phase-2). Status. Scoping note — precedes CR-2026-106. Markdown primary (technical consumer). Drafted against CC's read-only pre-flight at 677c46f, not from memory.


Plain-language summary

Phase 3 moves the sign-in resolution logic — the work of turning a session cookie into "this is who is acting" — into Stele. The function get_current_person stays in deps.py as a thin stub that calls Stele, so its 146 callers don't move. The phase also draws one boundary: **Stele answers who you are; the host keeps *what you're allowed to do here*** (engagement membership, can_commit). And it routes the one place that still builds a person-actor by hand through the actor_from_person constructor Phase 2 just moved.

This is the integration design's session.resolve operation (§3, §4): "the operation a host calls on every request to learn who is acting … the host keeps this dependency's name and signature, so the sites that depend on it do not change; only its body now calls Stele."

What the pre-flight found (the surface, at 677c46f)

The boundary decision (the load-bearing call, settled)

The resolution functions blend two jobs. Phase 3 splits them:

This is not a new decision — it is the host seam the integration design already commits to (§4: "Host-specific concerns never cross into Stele: engagements, memory events, credit/account lifecycle"). Phase 3 applies it to the resolution path.

Example of the cut. Today _resolve_cookie_actor does, in one function: decode session → load person → check the person's membership in the engagement → compute can_commit → build the actor. After Phase 3: Stele's session.resolve does "decode → load person → return principal"; the host code takes that principal and does "check membership → compute can_commit → build the engagement-scoped actor." Stele hands back Marvin; the host decides Marvin can commit in E4729.

The consolidation (decided: route)

The inline person-ActorRef build in _resolve_cookie_actor:1063-1067 routes through stele.actor.actor_from_person — the constructor Phase 2 moved. Reason: leaving a hand-rolled duplicate of a just-extracted constructor is exactly the drift the extraction removes.

Scope limit: person path only. The bearer-path _ActorRef(kind="contributor") (:975) and kind="agent") (:981) constructions stay inline and untouched — those are host/agent concerns, and the agent constructor is the "Later" build (no constructor exists to route to).

In scope for Phase 3

  1. Relocate the session→principal resolution into Stele as session.resolve (the integration design's named operation). deps.py:get_current_person becomes a thin delegator — same name, same signature, same return — so its 146 callers don't move.
  2. Draw the host seam in _resolve_cookie_actor / get_resolved_actor: Stele resolves the principal; the engagement/membership/can_commit layer stays host-side.
  3. Route the person path through stele.actor.actor_from_person (replacing the inline _ActorRef(kind="person") build).

Explicitly NOT in scope

Open question for the CR draft (one)

Where does session.resolve land in stele/? Two candidates:

Lean: stele/session.py — resolve is a session operation, and the module already holds the session primitives it needs. CC confirms at Step 0 pre-flight whether folding into session.py collides or fits, same as the Phase 2 actor.py destination check.

Method (unchanged from Phase 0/1/2)

Step 0 pre-flight (read-only, archive the CR, confirm coordinates/importers/baseline) → halt → execute with per-step commits, each move bundled with its repoints in one commit (the Phase 2 lesson) → halt-before-push → verify against playground_dev, not the suite alone → completion record + manifest bump.

Carry the Phase 2 lesson: model import topology, not just caller count, when drafting per-step suite expectations. Here the 146 callers depend on get_current_person by name — as long as the stub keeps that name and signature, relocating its body should not abort collection. The CR's Step 0 confirms this against the live tree.


DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks — Stele Extraction Phase 3 Scoping Note — v0.1 — 2026-06-15