CR number. CR-2026-090
Version. 0.2
Date. 2026-05-12
Status. Amendment cycle 1; supersedes v0.1.
Target tag. phase-57-marketing-engagement-creation (annotated; engine + Operator Layer).
Authoritative inputs. loomworks-phase-57-scoping-note-v0_2.md; loomworks-phase-57-cr-drafting-handoff-v0_1.md; phase-57-step-0-findings-v0_1.md (engine repo docs/phase-impl-notes/, on branch phase-57-step-0 at 69adb17); current-status-manifest-v0_41.md. Amendment-cycle inputs added at v0.2: phase-57-halt-surface-2026-05-12-v0_1.md (engine repo docs/phase-impl-notes/ on branch phase-57-marketing-engagement-creation at a00f4a3; also in project knowledge); loomworks-phase-57-cr-amendment-scoping-note-v0_1.md; loomworks-phase-57-cr-amendment-handoff-v0_1.md. Precedent CRs: Phase 56 (phase-56-cr-conversational-creation-surface-voice-v0_2.md), Phase 55 (phase-55-cr-engagement-creation-assistance-v0_1.md), and for CR-version-bump shape: phase-49-cr-amendment-v0_2-v0_1.md.
Drafter posture. Drafted by Claude.ai per amendment handoff §12 kickoff. Eight CR-time verifications (CRV-1 through CRV-8) embedded as Step 0 pre-flight per Phase 53/55 precedent. Eight CR-amendment-time verifications (CRV-A1 through CRV-A8) embedded as Step 2a pre-flight per amendment handoff §8 — CC runs them against the live OL repo at amendment-execution start; naming-only divergences absorb in-flight, architectural divergences halt and surface a follow-on amendment-cycle note.
Amendment record (cycle 1, this version). Amendment cycle 1 absorbed per phase-57-halt-surface-2026-05-12-v0_1.md and loomworks-phase-57-cr-amendment-scoping-note-v0_1.md. Sub-arc 4 (OL surface alignment with engine identity contract) added; Step 2a inserted; Step 2 renamed Step 2b. OL vitest count 150 (was 149). Gate 5 amended; Gate 5b new (subsequent gates renumbered with +1 offset). One reserved buffer slot consumed (one remains). Engine substrate unchanged. Three methodology candidates (A + B + C) carry to v0.21 / v0.42. One queued direction added (OL surface-vs-contract audit, Phase 58+). Two minor accuracy fixes within sections the handoff §7.2 labeled "Unchanged" recorded in §4 discovery-record bookkeeping (§13 OL bullet; §17 OL close expected-vitest comment); both fixes correct factual claims about post-amendment OL state.
Phase 57 ships the first real-Operator usage of the Phase 55/56 conversational engagement creation surface. The marketing engagement (sibling to the Loomworks engagement under DUNIN7) is created live by the Operator using pre-drafted content from loomworks-marketing-creation-flow-content-v0_3.md and the Discovery-record terminal-turn path.
The phase has two outputs:
/operator engagement list.tests/fixtures/voice-calibration/real_operator_marvin_<YYYY-MM-DD>.md. First concrete instance of the persona-vs-real-Operator-contrast pattern named at scoping v0.1 §12.
One substrate addition closes the only known gap on the creation surface: the Field 6 per-field elicitation prompt component. The substrate is otherwise complete — Seed.additional_assertions: dict[str, str] exists, Phase 53's extraction skill parses Field 6, and the skill validates the structure. The gap is elicitation-only (V2 GAP-CONFIRMED-AS-EXPECTED at Step 0).
Amendment cycle 1 (v0.2) adds Sub-arc 4 — OL surface alignment with engine identity contract — to absorb the halt-surface finding that the Operator Layer signin form's empty-email guard contradicts the engine's WebAuthn discoverable-credential identity contract and the standing DUNIN7 principle that email must not be used for identity. The fix is OL-side only; engine substrate is correct and untouched. Phase 57's product + methodology deliverables are preserved unchanged.
Phase 55 (phase-55-engagement-creation-assistance) shipped the conversational creation surface — intent classifier, dispatcher routing, three scaffolding prompt templates (create_engagement_active.md, create_engagement_commit.md, intent_classifier.md), field_coverage map, terminal-turn affordance.
Phase 56 (phase-56-conversational-creation-surface-voice) voice-tuned that surface with plain-terms-discipline: three per-field elicitation prompts at prompts/intent_instructions/create_engagement/ (voice.md, constraints.md, success.md); the load_per_field_components loader at prompt_assets.py; dispatcher splice at prompt.py:817; voice principles document at docs/voice-principles-v0_1.md; persona calibration fixtures at tests/fixtures/voice-calibration/; calibration-gated tests at tests/test_phase_56_conversational_creation_surface_voice.py with helper at tests/helpers/voice_calibration.py; terminal-turn matcher token-set in router.py covering legacy + plain-terms phrasings.
Phase 57 closes the Field 6 gap (Phase 56 explicitly scoped Fields 3–5 only) and exercises the surface end-to-end on a real engagement for the first time.
Substrate baseline (from handoff §2; CC re-confirms at Step 0).
Engine repo DUNIN7/loomworks-engine at /Users/dunin7/loomworks-engine:
phase-56-conversational-creation-surface-voice at engine commit 0044e3b (annotated tag object 49457cb).main HEAD be7fba5 — one docs-only commit ahead of the tag (Phase 56 close handoff commit; post-tag-docs-on-main pattern methodology candidate noted at scoping v0.2 §New methodology observations).0064.main.phase-57-step-0 branch at 69adb17 (unmerged; Step 0 findings file).phase-56-step-0 branch exists locally (never pushed) — deleted at Phase 57 close per P57-D7 Option A retroactive cleanup.phase-55-step-0 not present locally (silently deleted between Phase 56 close and Phase 57 Step 0 per V0 DRIFT; silent Option-A application methodology candidate).
Operator Layer repo DUNIN7/loomworks at /Users/dunin7/loomworks:
phase-56-conversational-creation-surface-voice at OL commit 2cc0ebc (annotated tag object 2db3c88).Marketing site repo: not in Phase 57 scope. Workshop repo: not in Phase 57 scope.
Substrate baseline at amendment-cycle-1 start (post-halt, pre-resume; per amendment handoff §2).
Engine repo on branch phase-57-marketing-engagement-creation at a00f4a3 — CR archive commit + Field 6 substrate commit from Step 0 + Step 1; 2,280 always-run + 32 skipped (1 always-run + 2 calibration-gated added at Step 1); Alembic 0064 unchanged; working tree clean; halt-surface note filed at docs/phase-impl-notes/phase-57-halt-surface-2026-05-12-v0_1.md on the branch.
Operator Layer repo on branch phase-57-marketing-engagement-creation at 2cc0ebc (= Phase 56 commit; no OL changes yet — the amendment changes this); 149 vitest; 11 prerendered routes; lint/tsc/build clean; working tree clean.
Local stack at amendment-resume time: engine API up on :8000 with /healthz returning 200; CORS resolved (LOOMWORKS_ENV=development in local .env); OL dev server up on :3001; Marvin's Person row + passkey credential present in dev DB.
Halt-surface trajectory leading to amendment cycle 1 (per phase-57-halt-surface-2026-05-12-v0_1.md). Step 2 entry surfaced an architectural finding: the Operator Layer signin form at /operator/create-engagement (which redirects to /signin when unauthenticated) presents a required-email field. The Operator named a long-standing DUNIN7 principle — email must not be used for identity; email-hijack creates account-takeover via password-reset-to-email — that was not previously named in any source-of-truth document. CC's diagnostic established three findings against the live source on branch phase-57-marketing-engagement-creation: (1) the engine identity model is WebAuthn passkey — SignupBeginRequest, LoginBeginRequest, PersonRow all treat email as Optional; /auth/login/complete looks up the Person by credential_id not by email; the discoverable-credential flow is supported when email = None on /auth/login/begin; (2) the OL signin form's client-side gate at IdentifierStep.tsx:31 contradicts the engine contract by requiring email input where the engine does not — signin-flow.ts:42 POSTs {email: email.trim()} and the engine would accept {} cleanly; (3) the drift was not surfaced at Phase 41 / 48 / 50 close because the standing principle was not named in any source-of-truth document. The engine correctly embodies the standing principle; the contradiction is at the OL client-side gate only; the fix is OL-side and small.
All ten settled at scoping v0.2 (eight items) plus handoff (two items: D7 elevation to Option A, and D10 newly added at v0.2). CC executes against them; does not re-decide.
| Item | Setting | Source |
|------|---------|--------|
| P57-D1 | Shape B — usage event with bounded substrate tuning (one prompt component at Step 1). | Scoping v0.2 §Shape selection |
| P57-D2 | Stop at engagement-exists. Downstream marketing-engagement substrate (render specialists, marketing-shaped artifacts, marketing-engagement-specific assertion types) is Phase 58+. | Scoping v0.2 §Open construction decisions |
| P57-D3 | Discovery-record terminal-turn path. Not the brief-commit path. | Scoping v0.2 §Open construction decisions |
| P57-D4 | Author Field 6 prompt at Step 1. New file at prompts/intent_instructions/create_engagement/additional_assertions.md; ~11 lines; structural mirror of Phase 56's voice.md / constraints.md / success.md; +1 test. | Scoping v0.2 §Open construction decisions |
| P57-D5 | Real-Operator transcript fixture at tests/fixtures/voice-calibration/real_operator_marvin_<YYYY-MM-DD>.md. Filename distinguishes from persona fixtures. Date is literal Step 2 capture date. | Scoping v0.2 §Open construction decisions |
| P57-D6 | Closed. Field 6 surface fallback design no longer needed since Shape B confirmed and Step 1 lands the elicitation prompt directly. | Scoping v0.2 §Open construction decisions |
| P57-D7 | Option A — delete at close. Step 0 inspection branches are deleted at phase close. Phase 57 applies retroactively: phase-56-step-0 is also deleted at Phase 57 close. Going-forward convention: every phase deletes its Step 0 inspection branch at close. (The silent cleanup of phase-55-step-0 between Phase 56 close and Phase 57 Step 0 demonstrated Option A is the natural drift; Option A formalizes it.) | Handoff §4 (elevated from v0.2 Option B provisional) |
| P57-D8 | Independent engagement under DUNIN7. Marketing engagement is sibling of the Loomworks engagement, not a subsidiary. | Scoping v0.2 §Open construction decisions |
| P57-D9 | Sonnet for default Companion operation. Flagged for Phase 58+ at first-rendered-output cost surface; not a Phase 57 settled decision but recorded for downstream pickup. | Scoping v0.2 §Open construction decisions |
| P57-D10 | Capture-during-Step-2-only. V4 POSTURE-GAP friction phrases captured in Step 4 implementation notes; no Step 1 posture pre-tuning. Future micro-tuning phase informed by Step 2 evidence. | Handoff §4 (added at scoping v0.2 §Open construction decisions §New at v0.2) |
All ten amendment-cycle-1 construction decisions settled at the amendment scoping note (loomworks-phase-57-cr-amendment-scoping-note-v0_1.md). CC executes against them; does not re-decide.
| Item | Setting | Source |
|------|---------|--------|
| P57-A1 | Remove the empty-email guard; omit email from /auth/login/begin POST body when empty; update field surface text to indicate optionality. Email field stays present (narrows allowCredentials as a passkey hint when supplied); the discoverable-credential path is the normal path. | Amendment scoping note §P57-A1 |
| P57-A2 | One new vitest. Exercises empty-email submission → no emailEmptyError set → POST body omits email → mock returns a WebAuthn challenge → form transitions to the passkey step. Rejected alternatives: zero tests (regression-prone for a client-side gate); two tests (the with-email path is already covered by existing 149). | Amendment scoping note §P57-A2 |
| P57-A3 | Narrow audit limited to the signin form only. Sign-up, claim-flow, account-recovery, and other identity-adjacent OL surfaces deliberately out of amendment scope. OL surface-vs-contract audit queued as a Phase 58+ candidate. | Amendment scoping note §P57-A3 |
| P57-A4 | Public marketing form out of scope. The Phase 51 form takes email + jurisdiction as contact metadata for grant-request intake; the grant flows through Companion-as-Authority approval (Phase 50), not through email-keyed authentication. Principle distinguishes identity from contact. CRV-A7 verifies HOLDS at amendment-execution time; expected verdict HOLDS. | Amendment scoping note §P57-A4 |
| P57-A5 | CR version phase-57-cr-marketing-engagement-creation-v0_2.md. v0.1 preserved alongside as superseded; both archived at engine repo docs/phase-crs/. | Amendment scoping note §P57-A5 |
| P57-A6 | New Sub-arc 4: OL surface alignment with engine identity contract. Separate sub-arc keeps the engine / OL boundary visible. Rejected alternative: Sub-arc 1e extension of Field 6 prompt authoring (would muddy the engine / OL boundary). | Amendment scoping note §P57-A6 |
| P57-A7 | Test count update: OL vitest 149 → 150. Engine 2,280 always-run + 32 skipped unchanged. Alembic 0064 unchanged. | Amendment scoping note §P57-A7 |
| P57-A8 | Two CR §12 gate updates. Gate 5 amended to include Sub-arc 4 readiness. New Gate 5b: OL signin surface accepts empty email and proceeds to the WebAuthn discoverable-credential path. Subsequent gates renumbered with +1 offset. Total gates 17 → 18. | Amendment scoping note §P57-A8 |
| P57-A9 | Three methodology candidates carry to v0.21 / v0.42. Candidate A (engine-correct-surface-drifted); Candidate B (standing-principle-not-named-in-source-of-truth-documents-allows-contradicting-surface-to-ship); Candidate C (new at amendment scoping — substrate-friction-discipline-pattern-second-build-mode-firing, two-instance evidence: Phase 49 Step 4 + Phase 57 Step 2). | Amendment scoping note §P57-A9 |
| P57-A10 | One reserved buffer slot consumed. One remains available if Steps 2b–5 surface a second halt-and-amend cycle. First consumed reserved slot since Phase 49 Step 4; eight consecutive zero-consumption phases (50–56 + Phase 57 pre-halt) ended at this amendment. | Amendment scoping note §P57-A10 |
Discovery-record posture: positions named alongside corrections; alternatives that didn't fire preserved.
Position 1 — Pre-scoping. Phase 32 (the marketing engagement) was the first-line recommendation in both Phase 55 close handoff §9 and Phase 56 close handoff §9. Two consecutive close-handoff recommendations.
Position 2 (v0.1) — Recommendation Candidate I, Shape B. Phase 32 framed as a usage event with bounded substrate tuning. The Field 6 elicitation gap surfaced as the probable Step 0 finding that would drive the "bounded tuning" envelope. Calibration capture identified as the methodology byproduct.
Reshape candidates anticipated at v0.1 → v0.2 (none fired). Operator-reframe to Shape A (pure usage); Operator-reframe to Shape C (bundled prep with §1.3 refactor candidates or Phase 31 plain-terms residue); Step 0 reshape on V2 (Field 6 gap discovered as non-gap); Step 0 reshape on V3 (multi-value handling broken); Operator-reframe to Candidate II or III. None of these reshapes fired at v0.2 absorption.
Position 3 (v0.2) — Confirmatory narrowing; Shape B settled. Step 0 returned State 2 / no halt-condition firings: V0 HOLDS-WITH-DRIFT (two items absorbed as methodology candidates); V1 HOLDS (surface inventory matches manifest v0.41 §1); V2 GAP-CONFIRMED-AS-EXPECTED (Field 6 elicitation absent as predicted); V3 MULTI-VALUE-ACCEPTED (the surface elicits multi-value fields cleanly); V4 POSTURE-GAP minor (the pre-drafted-content posture surfaces minor friction worth capturing but not pre-tuning); V5 HOLDS (Discovery-record terminal-turn path clean); V6 HOLDS (marketing v0.3 content maps cleanly to Fields 1–6); V7 HOLDS (Phase 31 plain-terms residue isolated; doesn't bite Phase 32); V8 HOLDS (OL surface renders). The substrate-evidence-can-re-rationalize-selection pattern did not fire — v0.1 framing was on-target. The trajectory shape is confirmatory narrowing, not reshape. Worth recording as the baseline against which reshape trajectories stand out.
Position 4 (v0.2) — Two methodology candidates surfaced incidentally to V0.
phase-55-step-0. Between Phase 56 close and Phase 57 Step 0, phase-55-step-0 was silently deleted. Strengthens the Step 0 branch lifecycle named principle's "decision-by-default produces silent cleanup" framing. Methodology candidate refinement.
Position 5 (handoff) — P57-D7 elevated to Option A. The silent cleanup of phase-55-step-0 showed Option A is the natural drift. Option A formalizes the convention going forward and applies retroactively to phase-56-step-0 at Phase 57 close.
Carry to v0.42 manifest absorption and v0.21 methodology consolidation:
The trajectory leading to v0.2 is worth preserving in full for v0.42 manifest absorption and v0.21 methodology consolidation. This is the second build-mode firing of the substrate-friction-discipline-pattern (manifest v0.39 §2); the first such firing since Phase 49 (Step 4 → phase-49-step-4-amendment-scoping-v0_1.md → CR v0.3 → Step 4b — the canonical instance).
Position 1 (Phase 57 scoping v0.1 → v0.2 → CR-2026-090 v0_1). Phase 57 anticipated zero OL substrate changes. The CR explicitly named this at §16 test count predictions (OL vitest: 149 unchanged) and §6 (What Phase 57 does NOT deliver). Step 0 (V1–V8) verified engine-side substrate exhaustively; OL-side substrate was not Step 0's aperture because the scoping note did not anticipate OL substrate work.
Position 2 (Step 2 entry, pre-halt). Local stack readiness friction surfaced (CORS preflight 405 on OL :3001 → engine :8000). Resolved with LOOMWORKS_ENV=development added to local .env. CR §12 gate 5 (live OL stack ready) appeared met. Step 2 ready to begin. Note recorded in the halt-surface: gate 5 was met at the infrastructure layer but had not been validated at the architectural layer; the architectural validation happened only when the Operator looked at the signin surface and named the standing principle.
Position 3 (halt-surface diagnostic). Three findings against the live engine + OL source on the phase-57-marketing-engagement-creation branch:
SignupBeginRequest, LoginBeginRequest, PersonRow all treat email as Optional).IdentifierStep.tsx:31 contradicts the engine contract by requiring email input where the engine does not.The principle is correctly embodied in the engine; the contradiction is at the OL client-side gate only. The fix is one-line in scope.
Position 4 (this amendment). Narrow OL surface alignment scoped strictly to the signin form entry point. Sub-arc 4 added; one new build step (Step 2a) inserted before the paused Step 2 (renamed Step 2b for clarity). One vitest. Surface text updated. Engine untouched. Audit of sibling OL identity-adjacent surfaces (sign-up, claim, account recovery) queues as a Phase 58+ candidate rather than expanding amendment scope.
The four positions are preserved. Position 1 (no OL changes anticipated) is not erased by Position 4 (one OL change required). Position 1 was correct given the information accessible to Phase 57 scoping at the time; Position 4 corrects with the principle now named and the contradiction identified.
Two from the halt-surface; one new at amendment scoping. All carry to v0.42 manifest absorption and v0.21 methodology consolidation.
engine-correct-surface-drifted. Single-instance evidence at this halt. The engine's data model correctly implements a standing principle; the OL surface added a client-side requirement that contradicts the engine contract; the drift was not caught at any prior phase close (Phases 41/48/50 each shipped surfaces adjacent to identity without surfacing the contradiction). Generalizes to: surface implementations can drift from their underlying contract; surface-vs-contract audits catch this; the audit needs a trigger. The trigger at this instance was the first real-Operator usage event.standing-principle-not-named-in-source-of-truth-documents-allows-contradicting-surface-to-ship. Single-instance evidence at this halt. The standing DUNIN7 principle (email must not be used for identity) existed in the Operator's head as background knowledge but was not named in what-dunin7-is-building, the current-status manifest, any phase scoping note, any CR, or any investigation document. Three phases (41/48/50) made identity-adjacent surface decisions without the principle being a checkable document constraint. Generalizes to: DUNIN7 principles that aren't written down can't be enforced by phase planning; they surface as findings during usage events rather than at scoping time. Remediation: name the email-not-identity principle in what-dunin7-is-building at v0.21. This amendment does not perform the remediation; the remediation belongs to v0.21 consolidation work.substrate-friction-discipline-pattern-second-build-mode-firing. Two-instance evidence (Phase 49 Step 4 first; Phase 57 Step 2 second). The two instances are usefully different in shape — Phase 49 was engine-side architectural friction at impl time; Phase 57 is OL-side surface-vs-contract drift at first usage. The pattern shape generalizes; two-instance evidence is the standard promotion threshold per manifest v0.39 §2 / v0.40 §2 precedents.Two minor departures from the amendment handoff §7.2 instruction recorded here for discovery-record posture, both narrow accuracy fixes within sections the handoff labeled "Unchanged."
Both fixes are within the handoff's "Unchanged" interpretation when read as the structure and the commands are unchanged; both fixes correct factual claims that strict prose preservation would render inaccurate. Recording the departures here per the discovery-record posture rather than silently re-writing.
1a. Field 6 per-field elicitation prompt component.
prompts/intent_instructions/create_engagement/additional_assertions.md. New file.voice.md / constraints.md / success.md (CRV-1 verifies the file shape verbatim at Step 0 pre-flight).docs/voice-principles-v0_1.md. The prompt elicits Field 6 content per marketing v0.3's framing — "additional assertions" rendered as labeled key-value pairs the Operator wants associated with the engagement. The prompt asks for one open-ended question per the per-field elicitation pattern.
1b. field_coverage map extension.
field_coverage map is constructed (CRV-2 confirms the construction site and verifies the key convention).additional_assertions (matching the prompt filename; aligns with Phase 56's filename-to-key convention). CRV-2 verifies the existing keys verbatim — if Phase 56 used numeric keys (field_3 etc.) instead, CR absorbs in-flight as naming-only divergence and uses field_6.1c. Active-template scaffolding update.
prompts/create_engagement_active.md.operation_data["field_coverage"] is extended to include the Field 6 entry. Insertion point is after the existing Field 5 (success) entry, following the existing ordering convention. CRV-3 verifies the exact insertion point and ordering at Step 0 pre-flight.1d. Test exercising new prompt component loading.
tests/test_phase_57_marketing_engagement_creation.py (new test module following the Phase 56 naming pattern).load_per_field_components loader successfully loads the new additional_assertions.md component as part of the per-field prompt assembly. Always-run test.prompt_assets.py loader API (no loader changes per CRV-4).1e. (Not anticipated.) Loader extension. Only required if CRV-4 reveals the loader is hardcoded to specific keys. Default expectation per V1: loader handles arbitrary keys; no loader change needed.
Not substrate work; Operator-paced. Documented here for CR completeness.
/operator/create-engagement on the running stack (local OL against local engine).extract_discovery_to_seed_skill + induct_seed cascade runs (CRV-7 confirms signatures at pre-flight; V5 HOLDS at Step 0)./operator engagement list with induction pass clean.3a. Real-Operator transcript fixture.
tests/fixtures/voice-calibration/real_operator_marvin_<YYYY-MM-DD>.md where date is the literal Step 2 capture date.persona_*.md) by the real_operator_marvin_ prefix.3b. Calibration-gated tests.
tests/test_phase_57_marketing_engagement_creation.py.LOOMWORKS_RUN_CALIBRATION=1 environment variable per Phase 56 P56-D7 precedent. Skip in CI; pass locally with env var set. CRV-6 verifies the gating pattern, skipif decorator usage, and helper invocation against tests/test_phase_56_conversational_creation_surface_voice.py + tests/helpers/voice_calibration.py.3c. Implementation notes document.
docs/phase-impl-notes/phase-57-implementation-notes-v0_1.md.loomworks-explain-affordance-investigation-v0_1.md §6.4 candidate selection downstream); V4 POSTURE-GAP friction phrases captured during the live conversation (input to future micro-tuning phase per P57-D10); persona-vs-real-Operator delta notes (input to v0.21 methodology consolidation); any Step 1 substrate refinement made; as-shipped wording of the Field 6 prompt for reproducibility. At v0.2: amendment cycle 1 trajectory captured alongside the original Sub-arc 3c content — second build-mode firing of substrate-friction-discipline-pattern; Sub-arc 4 components as-shipped; any Step 2a refinements made; the standing DUNIN7 principle named in §3 of the halt-surface note (the first naming in a Loomworks document; awaiting v0.21 canonical naming in what-dunin7-is-building).Three substantive components plus one new vitest. All OL-side. Engine substrate is correct and untouched. The work resolves the halt-surface finding: the OL signin form's client-side empty-email guard contradicts the engine's WebAuthn discoverable-credential identity contract and the standing DUNIN7 principle that email must not be used for identity.
CR-amendment-time verifications CRV-A1 through CRV-A8 (specified in §10 Step 2a pre-flight) supply exact paths, line numbers, constant locations, and existing test conventions at execution time. Where paths or constants are cited below, CC verifies them live before edits; naming-only divergences absorb in-flight; architectural divergences halt and surface a follow-on amendment-cycle note in docs/phase-impl-notes/.
4a. Signin form empty-email guard removal.
IdentifierStep.tsx (halt-surface §2 Finding 2 cites IdentifierStep.tsx:31; CRV-A1 confirms exact path and current line at amendment-execution time — likely under src/components/signin/ or analogous).``` if (!email.trim()) { setLocalError(SIGNIN.emailEmptyError); return; } ``` Replace with: proceed to submission unconditionally (no email-required gate at the client). The engine accepts the empty-email POST cleanly per halt-surface Finding 1 and runs the WebAuthn discoverable-credential path.
SIGNIN.emailEmptyError likely becomes orphaned. CRV-A2 verifies the constant's location and other call-sites at amendment-execution time. If no other call-sites: delete the constant. If orphaned but otherwise harmless: leave with a one-line comment noting Phase 57 amendment cycle 1 removed the sole caller. Recommended: delete.4b. POST body construction.
signin-flow.ts (halt-surface §2 Finding 2 cites signin-flow.ts:42; CRV-A3 confirms exact path and POST body construction line at amendment-execution time)./auth/login/begin currently constructed as { email: email.trim() }. Change to omit the email field when empty. Idiomatic TypeScript shape:
```ts
const body = email.trim() ? { email: email.trim() } : {};
```
Exact TypeScript idiom selected at execution time within the existing file's style. Engine accepts {} cleanly per halt-surface Finding 1 — LoginBeginRequest.email: str | None = None, so an absent field and a null field are equivalent under Pydantic.
4c. Field surface text — optionality indication.
IdentifierStep.tsx (label) plus any helper-text component the form composes (CRV-A4 verifies). The strings probably live in a strings constants module such as SIGNIN.identifierLabel / SIGNIN.identifierPlaceholder / SIGNIN.identifierHelper (exact constants verified at execution time).Email (unchanged) or Email (optional) — execution-time pick.Email (optional) if not already.4d. Vitest pinning the corrected discoverable-credential path.
tests/components/signin/ or analogous (CRV-A5 verifies exact placement and naming convention against current 149-test surface).localError does NOT get set to emailEmptyError → POST body to /auth/login/begin is {} (or omits the email field equivalently) → mocked /auth/login/begin returns a WebAuthn challenge → form transitions to the passkey step. The test mocks the engine boundary at the fetch / API layer; does not exercise live engine.submits empty email to discoverable-credential path or proceeds to passkey step without requiring email input. CC selects final name at execution time within existing test-naming conventions on the branch.Cited verbatim for clarity; CR does not modify these:
prompt.py:817 — dispatcher splice (CRV-1 confirms line at pre-flight).prompt_assets.py — load_per_field_components loader (CRV-4 confirms arbitrary-key handling).router.py — terminal-turn matcher token-set.classifier.py / routing.py — IntentLabel literals (18 per manifest v0.41).prompts/intent_instructions/create_engagement/ (voice.md, constraints.md, success.md).
Engine substrate is unchanged at amendment cycle 1. Sub-arc 4 is OL-only. No engine endpoint, no engine schema, no Memory event, no _ANCHOR_PRIORITY entry, no Alembic migration. SignupBeginRequest, LoginBeginRequest, PersonRow, begin_signup, and the /auth/login/complete lookup-by-credential_id path all stay as halt-surface Finding 1 documented them.
Per scoping v0.2 §What Phase 57 does NOT deliver:
create_project.md plain-terms revision. V7 SURFACED-TO-OPERATOR "constraints" leak in the older creation path. Phase 31 is the Phase-31-path; marketing engagement runs the Phase-55-path; V7 residue isolated. Phase 58+ carry-forward.draft_engagement; raw-Markdown variant of extract_discovery_to_seed_skill. Non-urgent; remain queued.loomworks-explain-affordance-investigation-v0_1.md.origin/phase-* refs from pre-Phase-55 backfill remain out-of-scope (separate Operator-elective).Added at amendment cycle 1:
loomworks-queued-directions-and-deferred-work-v0_12.md (next version bump from v0.11) at Phase 57 close. The Phase 57 amendment fixes the signin entry point Marvin uses; the broader audit is well-shaped as a dedicated future phase with its own scoping arc and its own Step 0 inspection brief.what-dunin7-is-building v0.21 absorption. Per amendment scoping note settled item 5 (inheriting halt-surface §5 settled item 5): the standing DUNIN7 principle (email must not be used for identity) is named in the halt-surface §3 for the first-time-in-a-Loomworks-document record; canonical naming in what-dunin7-is-building is downstream v0.21 consolidation work, not Phase 57 scope.tests/test_phase_57_marketing_engagement_creation.py.LOOMWORKS_RUN_CALIBRATION=1 gating.tests/components/signin/ or analogous (CRV-A5 verifies). Test behavior: empty email submit → no emailEmptyError set → POST body to /auth/login/begin omits the email field → mocked engine returns a WebAuthn challenge → form transitions to the passkey step. Existing 149 OL vitest stay green. Post-Sub-arc-4 OL count: 150.
Tests must pass at Checkpoint A (substrate gate, extended at amendment cycle 1 to cover Step 2a OL substrate) and Checkpoint B (final gate). The calibration-gated tests are confirmed to pass locally with LOOMWORKS_RUN_CALIBRATION=1 and confirmed to skip without it before close.
load_per_field_components loader; no edits to the dispatcher splice at prompt.py:817; no schema or migration change. The Field 6 addition is purely additive (new prompt file + new map entry + new active-template line).SIGNIN.emailEmptyError constant change. Existing imports and call-sites of the signin form continue to work.0064. Eighth consecutive phase of typed-MemoryObject-without-migration (Phase 57 adds no MemoryObject subclass, no _ANCHOR_PRIORITY entry, no endpoint). Sub-arc 4 does not touch the engine; backwards-compat at the engine layer is total.IntentLabel additions. Creation-flow labels carried from Phase 55/56; no Phase 57 additions.
Amendment cycle 1 backwards-compat summary. Existing 149 OL vitest stay green; the new vitest pins the corrected behavior; engine substrate is untouched so all engine backwards-compat carries. The OL signin form remains functionally compatible with previously-registered passkey credentials — narrowing allowCredentials via a supplied email continues to work, and the new empty-email path activates the engine's existing discoverable-credential branch. No data migration, no client-side state migration, no API contract change.
No new surfaces. No new MemoryObject subclass; no new _ANCHOR_PRIORITY entry; no new endpoint. Existing FORAY surfaces (Phase 16 upload anchors; Phase 53 discovery_to_seed_extracted anchor at priority "standard"; standard induct_seed anchor) carry the Discovery-record path unchanged.
Amendment cycle 1 touches no Memory event, no _ANCHOR_PRIORITY entry, no engine endpoint, no FORAY hook. The signin path is the WebAuthn flow at the auth boundary; it does not write Memory events of its own. FORAY surfaces are unchanged at v0.2.
Six active steps + two reserved buffer slots (one consumed at amendment cycle 1; one remains). Reserved-slot-as-halt-condition-pre-commitment per manifest v0.39 §2; the eighth-consecutive zero-consumption observation projected at v0.1 is superseded — Phase 57 consumed one slot via Sub-arc 4 (Step 2a). Methodology candidate C captures this trajectory (substrate-friction-discipline-pattern-second-build-mode-firing).
Auto-mode posture: Step 0 + Step 1 auto-proceed. Checkpoint A halts before Step 2 and extends at amendment cycle 1 to cover Step 2a completion — Operator confirms substrate (Field 6) AND Sub-arc 4 fix before Step 2b live usage proceeds. Steps 2b–4 are Operator-paced (Step 2b is the live conversation; Steps 3/4 are CC capture). Checkpoint B (final) halts before tagging.
Status at amendment cycle 1. DONE pre-halt. CR archival path updates from v0_1 to v0_2 at amendment-execution time (CC re-archives the amended CR; preserves v0_1 alongside).
What. Standard pre-flight. CC archives this CR to engine repo at docs/phase-crs/phase-57-cr-marketing-engagement-creation-v0_2.md (preserves phase-57-cr-marketing-engagement-creation-v0_1.md alongside as superseded). Confirms baseline tags, test counts, Alembic head. Creates branch phase-57-marketing-engagement-creation from main on engine and OL repos. (Branch already exists pre-amendment-resume; CC re-archives the CR on the existing branch.)
Pre-flight reads. CR-time deltas — exact strings, file paths, signatures, naming conventions that scoping-time Step 0 didn't enumerate and that the CR drafter could not verify from Claude.ai. CC runs these against the live engine repo. Naming-only divergences absorb in-flight; architectural divergences halt and surface a phase-57-halt-surface-<timestamp>-v0_1.md note in docs/phase-impl-notes/.
prompts/intent_instructions/create_engagement/voice.md (or constraints.md or success.md) verbatim. Confirms structural shape Phase 57's additional_assertions.md mirrors. Expected: ~11 lines; plain-terms-discipline applied; one elicitation question per prompt; format aligned with Phase 56 precedent.field_coverage map key convention. Verify existing keys and their construction site. Expected: keys match prompt component filenames per V1 (so voice, constraints, success — Phase 57 adds additional_assertions). If numeric keys are used instead (field_3/field_4/field_5), Phase 57 uses field_6 per the same convention.field_coverage. Locate the site in prompts/create_engagement_active.md where the Companion populates operation_data["field_coverage"]. Phase 56 added entries for Fields 3–5; Phase 57 adds the Field 6 entry at the same construction site, following existing ordering convention (Field 6 entry inserted after the Field 5 entry).load_per_field_components loader signature and key handling. Read the loader at prompt_assets.py. Confirm it handles arbitrary keys (per V1). Expected: no loader change required. Failure mode: loader is hardcoded to specific keys → Sub-arc 1e activated (loader extension).tests/fixtures/voice-calibration/persona_*.md. Confirm the format Phase 57's real-Operator transcript fixture mirrors. Expected: structured format with conversation turns; speaker labels; optional metadata header. Format settled by Phase 56 P56-D2.tests/test_phase_56_conversational_creation_surface_voice.py for the four P56 calibration-gated tests. Confirm the LOOMWORKS_RUN_CALIBRATION=1 env-var gating pattern, the skipif decorator usage, and the test-helper invocation at tests/helpers/voice_calibration.py. Phase 57's gated tests mirror this pattern exactly.extract_discovery_to_seed_skill, and induct_seed. Confirm path Step 2b exercises is unchanged from Phase 56 close. V5 HOLDS at Step 0; CRV-7 is the drafting-time confirmation.docs/voice-principles-v0_1.md and the Phase 56 close session handoff for the explicit-refspec convention promoted at manifest v0.41 §2. Confirm the close commands Phase 57 uses verbatim. P57-D7 Option A retroactive cleanup added as Step 5 actions.
CR archival. Copy this CR file to engine repo docs/phase-crs/phase-57-cr-marketing-engagement-creation-v0_2.md (preserving v0_1 alongside as superseded).
Branch creation. git checkout -b phase-57-marketing-engagement-creation on engine and OL (already in place at amendment-cycle-1 resume).
Mode posture. Auto-proceed.
Acceptance gate. All eight CRV verdicts captured. Branch present on both repos. CR archived (v0_2 alongside v0_1). Baseline tag + test counts + Alembic head confirmed against handoff §2.
Halt threshold. Any CRV produces an architectural divergence (not naming-only) → halt-surface note + Operator-elective amendment cycle in a fresh Claude.ai chat. Baseline divergence (test count off by more than ±2 routine noise; Alembic head different; working tree dirty; tag missing) → halt before any further work.
Time. ~10 min.
Status at amendment cycle 1. DONE pre-halt. Engine substrate at a00f4a3 on the build branch; +1 always-run test added (2,280 always-run total); +1 calibration-gated and +1 additional gated test (32 skipped total) per the halt-surface §6 state-at-halt record.
What. Author additional_assertions.md per 1a. Extend field_coverage map per 1b. Update active-template per 1c. Add +1 test per 1d.
Build.
prompts/intent_instructions/create_engagement/additional_assertions.md (~11 lines).field_coverage map construction site (per CRV-2/3) to add the additional_assertions entry (or field_6 if numeric convention).prompts/create_engagement_active.md to add the Field 6 entry to the Companion-judgement site (per CRV-3 insertion point and ordering).tests/test_phase_57_marketing_engagement_creation.py with one always-run test exercising the new prompt component loading.Tests. +1 always-run.
Mode posture. Auto-proceed.
Acceptance gate. New prompt file present at the specified path with ~11 lines following Phase 56 structural shape. field_coverage map carries the new entry. Active-template Companion-judgement site references Field 6. New test green. Existing 2,279 tests still green. Lint clean.
Halt threshold.
field_coverage requires a loader change beyond the simple extension (CRV-4 failure). (Low probability — V1 confirms the loader handles arbitrary keys.)
Checkpoint A (extended at amendment cycle 1). Originally halted before Step 2 live usage to confirm Field 6 substrate. At amendment cycle 1 the checkpoint extends to also cover Step 2a (Sub-arc 4 fix). Live OL stack readied for Step 2b entry: /operator/create-engagement accessible; banner revision (Phase 56 ChatView.tsx:254) present; Sub-arc 4 fix landed; lint/tsc/build/test clean on OL including the new sign-in vitest at OL count 150.
Time. ~30 min.
What. Remove the empty-email guard at the OL signin form (per Sub-arc 4a); omit the email field from the /auth/login/begin POST body when empty (per Sub-arc 4b); update field surface text (label / placeholder / helper) to indicate optionality (per Sub-arc 4c); add one vitest pinning the corrected discoverable-credential path (per Sub-arc 4d). Delete the now-orphan SIGNIN.emailEmptyError constant if no other call-sites remain.
Pre-flight reads. CR-amendment-time verifications CRV-A1 through CRV-A8 per amendment handoff §8. CC runs these against the live OL repo on branch phase-57-marketing-engagement-creation at 2cc0ebc. Naming-only divergences absorb in-flight; architectural divergences halt and surface a follow-on phase-57-halt-surface-<timestamp>-v0_1.md note in engine repo docs/phase-impl-notes/ (the OL repo does not carry impl-notes; engine repo is the methodology home).
IdentifierStep.tsx exact path and current line numbers. Halt-surface cites IdentifierStep.tsx:31. Verify the file's location in the OL repo's tree (likely under src/components/signin/ or analogous) and confirm the empty-email-guard block's current line range. Path the CR's Sub-arc 4a edit at the verified location.SIGNIN.emailEmptyError constant — location and all call-sites. Determine the strings file/module (likely src/strings/signin.ts or analogous). Determine whether removing the sole caller (Sub-arc 4a) orphans the constant. Plan: delete if orphaned, leave with a one-line comment if any other caller remains. Record the decision in implementation notes.signin-flow.ts exact path and POST body construction at the cited line. Halt-surface cites signin-flow.ts:42. Verify the current shape of the body construction and any surrounding TypeScript style conventions; specify the new idiomatic conditional body in TypeScript within the existing file's style.SIGNIN.identifierLabel, SIGNIN.identifierPlaceholder, SIGNIN.identifierHelper (or whatever the exact constants are). Verify the actual constant names and current values. Specify new copy values per Sub-arc 4c within plain-terms-discipline; capture the as-shipped strings in the implementation notes for reproducibility.tests/components/signin/ or analogous). Confirm naming convention (file names, describe-block style, test-name style, mock patterns for the /auth/login/begin boundary). The new Sub-arc 4d vitest matches the existing convention./auth/login/begin POST body absent-email engine behavior. Halt-surface Finding 1 establishes this. Re-read the engine LoginBeginRequest schema and the route handler to triple-confirm at the time of execution. Expected verdict: engine accepts email: None cleanly via Pydantic optional default; absent field and null field are equivalent. If verdict shifts, halt and surface.2cc0ebc. Re-confirm on the OL repo's phase-57-marketing-engagement-creation branch at amendment-execution time. Expected: 149.Build.
IdentifierStep.tsx at the location CRV-A1 verifies — remove the empty-email guard block (4a).signin-flow.ts at the location CRV-A3 verifies — change the POST body construction to omit email when empty (4b).SIGNIN.emailEmptyError constant if CRV-A2 confirms no other call-sites; otherwise leave with a one-line comment.Tests. +1 OL vitest. OL vitest count 149 → 150.
Mode posture. Auto-proceed.
Acceptance gate. All four Sub-arc 4 components landed at the verified file locations. The new vitest passes; existing 149 OL vitest still pass; lint/tsc/build clean on OL. OL vitest count 150 (was 149). Implementation notes capture the as-shipped surface-text strings and the SIGNIN.emailEmptyError constant disposition.
Halt threshold.
LoginBeginRequest has shifted shape since the halt-surface diagnostic; the Phase 51 marketing form submission handler keys off email-as-identity. → halt and surface a follow-on phase-57-halt-surface-<timestamp>-v0_1.md note.IdentifierStep.tsx or signin-flow.ts already changed since halt-surface diagnostic time (the OL branch may have been edited between halt-surface filing and amendment-execution resumption). CC re-reads the halt-surface findings against current branch state; if findings still HOLD, proceed; if findings have shifted, surface to Operator before proceeding.Checkpoint A extends. Operator confirms Sub-arc 4 fix before Step 2b live usage proceeds. Gate 5 + new Gate 5b together cover the extended Checkpoint A acceptance condition.
Time. ~30 min.
What. Operator runs the marketing engagement creation. CC ensures local stack ready, observes the conversation, captures the live conversation log for fixture creation at Step 3.
Build (Operator-paced).
/operator/create-engagement on the running stack (local OL against local engine). With the Sub-arc 4 fix landed, the redirect to /signin accepts an empty-email submission and proceeds to the WebAuthn discoverable-credential flow; the browser presents the registered passkey; /auth/login/complete resolves identity by credential_id; the Operator is signed in.extract_discovery_to_seed_skill + induct_seed cascade runs./operator engagement list with induction pass clean.Tests. 0 new (the live event is the exercise).
Mode posture. Operator-paced.
Acceptance gate. Marketing engagement live in the local engine database. Engagement appears in /operator engagement list. Discovery record visible in Memory. Candidate seed produced. Induction pass clean. Marketing v0.3 content (Fields 1–6 with eight Field-6 entries) fully reflected in the inducted seed.
Halt threshold.
field_coverage correctly populated). Halt for diagnosis; Step 1 substrate may need amendment.induct_seed error). V5 HOLDS at Step 0, so this is low probability — but Step 2b is the live exercise; halt and diagnose if it fails.dict[str, str] cleanly — e.g., a key collision between two entries with the same Label).Time. ~30–60 min wall time (depends on Operator pace).
What. CC files the real-Operator transcript fixture. Adds calibration-gated tests. Runs the gated tests with LOOMWORKS_RUN_CALIBRATION=1 to confirm they pass; confirms they skip without the env var.
Build.
tests/fixtures/voice-calibration/real_operator_marvin_<YYYY-MM-DD>.md with the Step 2b conversation captured per Phase 56 persona fixture format (CRV-5).tests/test_phase_57_marketing_engagement_creation.py exercising the new fixture. Pattern mirrors CRV-6 evidence: LOOMWORKS_RUN_CALIBRATION=1 skipif decorator; helper invocation at tests/helpers/voice_calibration.py.Tests. +1–2 calibration-gated.
Mode posture. Auto-proceed.
Acceptance gate. Fixture file present at the dated path; format mirrors persona fixtures. Gated tests green with LOOMWORKS_RUN_CALIBRATION=1. Gated tests skip in CI default mode. Total skipped count adjusts from 30 to 31–32.
Halt threshold. Real-Operator transcript capture reveals a format incompatibility with Phase 56's persona fixture format (CRV-5 failure). Halt for diagnosis.
Time. ~20 min.
What. CC files docs/phase-impl-notes/phase-57-implementation-notes-v0_1.md capturing trajectory, comprehension gaps, V4 friction phrases, persona-vs-real-Operator deltas, and amendment-cycle-1 observations.
Build.
docs/phase-impl-notes/phase-57-implementation-notes-v0_1.md.SIGNIN.emailEmptyError disposition); Sub-arc 4 vitest as-shipped (path, test name, mocked boundaries); the second build-mode firing of substrate-friction-discipline-pattern (methodology candidate C); the halt-surface trajectory (Position 1 → Position 4); the standing DUNIN7 principle naming as the first-time-in-a-Loomworks-document record per halt-surface §3.Tests. 0 new.
Mode posture. Auto-proceed.
Acceptance gate. Document present at the specified path. All required sections populated, including amendment-cycle-1 sections. Carry-forward methodology candidates named (six from v0.1 + three new at v0.2: candidate A, candidate B, candidate C).
Halt threshold. None expected.
Time. ~15–20 min.
What. Apply refined close protocol with explicit refspecs per manifest v0.41 §2. Tag phase-57-marketing-engagement-creation on both repos (annotated). Apply P57-D7 Option A retroactive cleanup: delete phase-56-step-0 locally; delete phase-57-step-0 locally after merging Step 0 findings into the build branch context.
Build (refined close protocol, both repos where applicable). See §17 for the full command sequence. Summary:
main to phase-57-marketing-engagement-creation head.main to origin via git push origin refs/heads/main.git branch -d phase-57-marketing-engagement-creation.git push origin :refs/heads/phase-57-marketing-engagement-creation (only if pushed during build).git remote prune origin.main at docs/phase-impl-notes/phase-57-step-0-findings-v0_1.md. Then apply P57-D7 Option A:phase-56-step-0 locally: git branch -D phase-56-step-0 (force; never pushed).phase-57-step-0 locally: git branch -D phase-57-step-0 (force; never pushed).git tag -a phase-57-marketing-engagement-creation -m "Phase 57 close: marketing engagement creation" on both engine and OL repos.git push origin refs/tags/phase-57-marketing-engagement-creation (separate invocation per repo).git ls-remote origin 'refs/tags/phase-57-marketing-engagement-creation' (separate invocation per repo).Tests. 0 new. Final test sweep confirms all tests still green before Checkpoint B halt.
Mode posture. Auto-proceed through close-protocol mechanics; Checkpoint B halts before tagging. Operator final-confirms before tags land.
Acceptance gate. All Step 1 / Step 2a / Step 2b / Step 3 / Step 4 acceptance gates green. Working tree clean on main for both repos. Tags landed and verified on origin. phase-56-step-0 and phase-57-step-0 branches deleted locally (per P57-D7 Option A). Refined close protocol fired correctly via explicit refspecs.
Halt threshold.
Time. ~15 min.
(reserved — consumed by Sub-arc 4 work / Step 2a per P57-A10)
Phase 57's two reserved buffer slots: Step 6 consumed at amendment cycle 1 by the Sub-arc 4 budget; Step 7 remains available. Not literally a position in the build sequence — the consumption is at the budget layer; Step 2a sits earlier in the sequence chronologically. First consumed reserved slot since Phase 49 Step 4 (the canonical instance of substrate-friction-discipline-pattern); eight consecutive zero-consumption phases (50/51/52/53/54/55/56 + Phase 57 pre-halt) ended at this amendment. Per manifest v0.41 §1's observation that the no-mid-build-amendment pattern is "structural rather than coincidental," the consumption is now logged as the design intent firing correctly — slots exist to absorb mid-build amendment without derailing the phase. Methodology candidate C captures the cadence (seven-and-then-one-consumed-by-design).
(reserved — buffer for any further mid-build amendment arising from steps 2b–5)
One reserved buffer slot remains, available if Steps 2b–5 surface a second halt-and-amend cycle. None anticipated. Reserved-not-skipped principle preserved; the slot's value is its presence, not its consumption.
Per friction-discipline-pattern-family mid-build boundary. CC halts and writes a phase-57-halt-surface-<timestamp>-v0_1.md note in engine repo docs/phase-impl-notes/ on any of:
field_coverage map requires a loader change beyond simple extension. (Low probability — V1 confirms loader handles arbitrary keys.)LoginBeginRequest has shifted shape since the halt-surface diagnostic; the Phase 51 marketing form submission handler keys off email-as-identity (CRV-A7 CONTRADICTED, scope re-opens). Any Sub-arc 4 component (4a/4b/4c/4d) surfaces unexpected drift from CR specification. OL vitest count diverges beyond ±1 from the predicted 150. IdentifierStep.tsx or signin-flow.ts already changed since halt-surface diagnostic time in a way that invalidates the findings.Mid-build amendment scoping runs in a separate Claude.ai chat per the standard pattern (substrate-friction-discipline-pattern from manifest v0.39 §2 — note-first; Operator-elective amendment cycle). Amendment cycle 1 is the active instance at v0.2; further amendment cycles would consume the remaining reserved slot (Step 7) if needed.
Eighteen items per scoping v0.2 §Acceptance gates plus amendment-cycle-1 amendments per P57-A8 (Gate 5 amended; new Gate 5b inserted; subsequent gates renumbered with +1 offset from old 6→7 onwards).
| # | Gate | Where verified |
|---|------|---------------|
| 1 | Step 0 findings absorbed; v0.2 produced; CR drafting handoff filed (already met by this CR's existence); amendment scoping note absorbed (already met by this CR's existence at v0.2). | Pre-existing |
| 2 | Field 6 per-field elicitation prompt component landed at prompts/intent_instructions/create_engagement/additional_assertions.md (or final filename per CRV resolution); +1 test green. (Satisfied pre-amendment-resume at engine a00f4a3.) | Step 1 |
| 3 | field_coverage map extended to include the Field 6 entry; dispatcher splice route exercised. (Satisfied pre-amendment-resume.) | Step 1 |
| 4 | Active-template scaffolding at prompts/create_engagement_active.md updated for Field 6 elicitation; existing tests still green. (Satisfied pre-amendment-resume.) | Step 1 |
| 5 | (Amended at amendment cycle 1.) Live OL stack ready at Step 2 entry: /operator/create-engagement accessible; banner revision present; Sub-arc 4 fix landed (see Gate 5b); lint/tsc/build/test clean on OL including the new sign-in vitest at OL count 150. | Checkpoint A (extended) |
| 5b | (New at amendment cycle 1.) OL signin surface accepts empty email and proceeds to the WebAuthn discoverable-credential path. IdentifierStep.tsx empty-email guard removed; signin-flow.ts POST body omits the email field when empty; field label / placeholder / helper text indicate optionality (plain-terms-discipline, no methodology vocabulary in user-facing copy); SIGNIN.emailEmptyError constant deleted or orphaned-but-harmless per CRV-A2 resolution; new vitest pins the corrected behavior at the OL count-150 boundary. | Step 2a |
| 7 | Marketing engagement created live in the local engine database via /operator/create-engagement. Engagement appears in /operator engagement list. (Was Gate 6 in v0.1; renumbered +1.) | Step 2b |
| 8 | Discovery record produced and uploaded via Phase 16 pipeline; visible in Memory. (Was Gate 7 in v0.1.) | Step 2b |
| 9 | Phase 53 extract_discovery_to_seed_skill produced a candidate seed against the Discovery record. (Was Gate 8 in v0.1.) | Step 2b |
| 10 | induct_seed produced an induction-pass-clean Status on the marketing engagement. (Was Gate 9 in v0.1.) | Step 2b |
| 11 | Marketing v0.3 content (Fields 1–6 with eight Field-6 entries) fully reflected in the inducted seed. (Was Gate 10 in v0.1.) | Step 2b |
| 12 | Real-Operator transcript captured as tests/fixtures/voice-calibration/real_operator_marvin_<date>.md. Distinguished from persona fixtures by filename. (Was Gate 11 in v0.1.) | Step 3 |
| 13 | ~1–2 calibration-gated tests added exercising the new fixture; gates green with LOOMWORKS_RUN_CALIBRATION=1; skip in CI by default. (Was Gate 12 in v0.1.) | Step 3 |
| 14 | Phase 57 implementation notes document filed at docs/phase-impl-notes/phase-57-implementation-notes-v0_1.md carrying trajectory, comprehension-gap observations, V4 POSTURE-GAP friction phrases, persona-vs-real-Operator deltas, and amendment-cycle-1 observations (Sub-arc 4 as-shipped surface; methodology candidates A + B + C; standing-principle first-time-in-Loomworks-document record). (Was Gate 13 in v0.1.) | Step 4 |
| 15 | Engine test count within v0.2 estimate (~2,280 always-run + 31–32 skipped); OL vitest count 150; lint/tsc/build clean on OL; Alembic head unchanged at 0064. (Was Gate 14 in v0.1; OL count updated at amendment cycle 1.) | Checkpoint B |
| 16 | P57-D7 Option A retroactive cleanup applied: phase-56-step-0 deleted locally; phase-57-step-0 deleted locally (after findings merged forward). (Was Gate 15 in v0.1.) | Step 5 |
| 17 | Refined close protocol firing on both repos via explicit refspecs (refs/heads/..., refs/tags/...). (Was Gate 16 in v0.1.) | Step 5 |
| 18 | Tags phase-57-marketing-engagement-creation landed on both engine and OL repos; pushed; verified via git ls-remote origin 'refs/tags/...'. (Was Gate 17 in v0.1.) | Step 5 / Checkpoint B |
Total: 18 items (was 17 at v0.1). Gate 5b inserted between Gate 5 and old Gate 6 (now Gate 7) per the handoff §7.2 explicit instruction.
After Phase 57 close:
phase-57-marketing-engagement-creation at the post-Step-4 engine commit. Substrate: 2,280 always-run tests + 31–32 skipped; Alembic 0064 unchanged. New prompt file at prompts/intent_instructions/create_engagement/additional_assertions.md. New test module at tests/test_phase_57_marketing_engagement_creation.py. New fixture at tests/fixtures/voice-calibration/real_operator_marvin_<YYYY-MM-DD>.md. New implementation notes at docs/phase-impl-notes/phase-57-implementation-notes-v0_1.md. Halt-surface note at docs/phase-impl-notes/phase-57-halt-surface-2026-05-12-v0_1.md. Existing surfaces at prompts/create_engagement_active.md, the field_coverage map site, and prompt_assets.py / prompt.py:817 unchanged in shape, with the single Field 6 entry added. phase-56-step-0 and phase-57-step-0 deleted locally.phase-57-marketing-engagement-creation at the post-Step-2a OL commit. 150 vitest (was 149 at v0.1; +1 from Sub-arc 4d); 11 prerendered routes unchanged. Sub-arc 4 surface changes landed: IdentifierStep.tsx empty-email guard removed; signin-flow.ts POST body construction conditioned on email presence; field surface text (label / placeholder / helper) indicates optionality; SIGNIN.emailEmptyError constant deleted (or orphaned-but-harmless per CRV-A2 disposition); new vitest under tests/components/signin/ (or analogous per CRV-A5) pins the corrected discoverable-credential path. (v0.1 said "no OL changes in this phase; 149 vitest unchanged" — corrected at amendment cycle 1 per the discovery-record bookkeeping note in §4; the amendment handoff §7.2 instructed §13 as "Unchanged" but strict preservation produced an inaccuracy that the one-bullet fix resolves.)engine-correct-surface-drifted (new at amendment cycle 1); candidate B standing-principle-not-named-in-source-of-truth-documents-allows-contradicting-surface-to-ship (new at amendment cycle 1; remediation: name email-not-identity in what-dunin7-is-building at v0.21); candidate C substrate-friction-discipline-pattern-second-build-mode-firing (new at amendment cycle 1; two-instance evidence).Per scoping v0.2 §Carry-forward inventory:
Out-of-scope (carry beyond Phase 57):
draft_engagement; raw-Markdown variant of extract_discovery_to_seed_skill).create_project.md plain-terms revision.origin/phase-* refs from pre-Phase-55 backfill (out-of-scope cleanup; separate Operator-elective).instruction-refinement-during-absorption minor candidate.Newly enabled by Phase 57:
Added at amendment cycle 1:
engine-correct-surface-drifted. Single-instance evidence at the Phase 57 halt-surface. Generalization: surface implementations can drift from their underlying contract; the drift surfaces at first real usage; the audit needs a trigger.standing-principle-not-named-in-source-of-truth-documents-allows-contradicting-surface-to-ship. Single-instance evidence at the Phase 57 halt-surface. Remediation: name the email-not-identity principle in what-dunin7-is-building at v0.21. This amendment does not perform the remediation; v0.21 consolidation does.substrate-friction-discipline-pattern-second-build-mode-firing. Two-instance evidence (Phase 49 Step 4 + Phase 57 Step 2). Pattern shape reliable; carries as the standard mid-build resolution shape.loomworks-queued-directions-and-deferred-work-v0_12.md (next version bump from v0.11) at Phase 57 close. Phase 57 amendment candidates A + B feed the eventual phase's scoping.
Resume Phase 57 build at amendment cycle 1 per CR-2026-090 v0.2
(phase-57-cr-marketing-engagement-creation-v0_2.md). v0.1 is
superseded; both are archived at engine repo docs/phase-crs/.
Baseline confirmation at amendment-cycle-1 start (post-halt, pre-resume):
- Engine repo /Users/dunin7/loomworks-engine on branch
phase-57-marketing-engagement-creation at commit a00f4a3.
Tests: 2,280 always-run + 32 skipped (+1 always-run / +2 calibration-gated
added at Step 1 vs the Phase 56 baseline 2,279 / 30).
Alembic head 0064 unchanged. Working tree clean.
Halt-surface note present at
docs/phase-impl-notes/phase-57-halt-surface-2026-05-12-v0_1.md.
Step 0 findings present at
docs/phase-impl-notes/phase-57-step-0-findings-v0_1.md.
Step 1 substrate present at
prompts/intent_instructions/create_engagement/additional_assertions.md.
phase-57-step-0 branch at 69adb17 (unmerged; for P57-D7 retroactive cleanup
at Step 5). phase-56-step-0 branch exists locally (never pushed;
scheduled for P57-D7 Option A retroactive cleanup at Step 5).
- Operator Layer repo /Users/dunin7/loomworks on branch
phase-57-marketing-engagement-creation at commit 2cc0ebc
(= Phase 56 commit; no Phase 57 changes yet — Step 2a changes this).
149 vitest passed; 11 prerendered routes; lint/tsc/build clean.
- Local stack ready (engine API up on :8000, /healthz 200, CORS resolved
via LOOMWORKS_ENV=development in local .env; OL dev server up on :3001;
Marvin's Person row + passkey credential present in dev DB).
Per CR §10 Step 0: re-archive this CR (v0.2) to engine repo
docs/phase-crs/phase-57-cr-marketing-engagement-creation-v0_2.md
(preserving v0_1 alongside as superseded). CRV-1 through CRV-8 ran
pre-halt at Step 0 of the original build cycle; their verdicts hold.
Per CR §10 Step 2a (new at amendment cycle 1): run CRV-A1 through
CRV-A8 as Step 2a pre-flight reads against the live OL repo on
branch phase-57-marketing-engagement-creation at 2cc0ebc.
Naming-only divergences absorb in-flight; architectural divergences
halt and surface a follow-on phase-57-halt-surface-<timestamp>-v0_1.md
note in engine repo docs/phase-impl-notes/.
Per CR §10: six active build steps (Step 0 + Step 1 done pre-halt;
Step 2a is the resumption point at amendment cycle 1; Step 2b
follows the live signin fix; Steps 3–5 unchanged from v0.1) + two
reserved buffer slots (Step 6 consumed at amendment cycle 1 by
Sub-arc 4 work; Step 7 remains available if Steps 2b–5 surface
a second halt-and-amend cycle).
Per CR §10: auto-mode posture — Step 2a auto-proceeds; Checkpoint A
extends to cover Step 2a (Operator confirms Sub-arc 4 fix before
Step 2b proceeds); Steps 2b–4 are Operator-paced (Step 2b is the
live conversation; Steps 3/4 are CC capture); Checkpoint B (final)
halts before tagging.
Per CR §3 + §3.A: ten construction decisions P57-D1 through P57-D10
plus ten amendment-cycle-1 decisions P57-A1 through P57-A10 are
settled. CC executes against them; does not re-decide.
Per CR §11: halt-and-surface is preferred to draft-and-hope. Halt
thresholds at amendment cycle 1: CRV-A architectural divergence at
Step 2a; any Sub-arc 4 component (4a/4b/4c/4d) surfaces unexpected
drift; OL vitest count diverges beyond ±1 from 150; IdentifierStep.tsx
or signin-flow.ts already changed since halt-surface diagnostic time;
CRV-A7 CONTRADICTED (Phase 51 marketing form keys off email-as-identity,
which would re-open amendment scope); signin still fails despite
Sub-arc 4 at Step 2b (would indicate deeper engine-side issue);
Operator's live conversation surfaces friction the Field 6 prompt
can't resolve; Discovery-record terminal-turn cascade fails; marketing
v0.3 content reveals a Field-mapping mismatch; persona fixture format
incompatibility at Step 3; test-count divergence greater than 50%.
Per CR §17: refined close protocol with explicit refspecs (manifest
v0.41 §2). P57-D7 Option A retroactive cleanup applied at Step 5
(delete phase-56-step-0 + phase-57-step-0 locally after findings
merged forward).
Tag name: phase-57-marketing-engagement-creation. Annotated. Lands
on both engine and OL repos at Checkpoint B (final).
Begin at Step 2a (Sub-arc 4 OL signin alignment). CRV-A1 through
CRV-A8 first, then the four Sub-arc 4 components (4a/4b/4c/4d),
then await Operator confirmation at the extended Checkpoint A
before Step 2b live usage.
| Surface | Pre-Phase-57 | Phase-57 delta (v0.1) | Phase-57 delta (v0.2 amendment) | Post-Phase-57 | |---------|-------------|----------------------|--------------------------------|--------------| | Engine always-run | 2,279 | +1 | 0 | ~2,280 | | Engine skipped (calibration-gated) | 30 (= 26 pre-P56 + 4 P56-gated) | +1 to +2 | 0 | 31–32 | | OL vitest | 149 | 0 | +1 (Sub-arc 4d) | 150 | | Alembic migration head | 0064 | 0 | 0 | 0064 | | Prerendered OL routes | 11 | 0 | 0 | 11 |
Existing 2,279 substrate tests stay green throughout build. Calibration-gated tests pass with LOOMWORKS_RUN_CALIBRATION=1; skip in CI by default per P56-D7 precedent. Amendment cycle 1 adds +1 OL vitest exercising the empty-email discoverable-credential path; all 149 existing OL vitest stay green.
Aligned with Phase 56 CR-2026-080 v0.2 §3.1 close-protocol refinement and manifest v0.41 §2 named principle (explicit refspecs). Executed at Step 5 by CC; Checkpoint B halts before tag-push for Operator final confirmation. Unchanged at amendment cycle 1 — the close-protocol commands are step-5 work; they do not depend on Sub-arc 4 specifics.
cd /Users/dunin7/loomworks-engine
# 1. Confirm Step 0 findings present on main before Step 0 branch deletion
test -f docs/phase-impl-notes/phase-57-step-0-findings-v0_1.md \
&& echo "Step 0 findings present on main" \
|| { echo "ERROR: Step 0 findings missing"; exit 1; }
# 2. Confirm build branch is up-to-date with main (assuming build commits
# were made directly on main, or were merged forward)
git status
git log --oneline -5
# 3. Confirm tests green at close
.venv/bin/pytest -q
# Expected: ~2,280 passed, 31-32 skipped
# 4. Confirm working tree clean
git status --porcelain
# Expected: empty
# 5. Push main to origin via explicit refspec
git push origin refs/heads/main
# 6. Delete local build branch (if it exists as a separate branch)
git branch | grep phase-57-marketing-engagement-creation \
&& git branch -d phase-57-marketing-engagement-creation \
|| echo "Build branch already merged or not separate"
# 7. Delete remote build branch via explicit refspec (only if pushed during build)
git ls-remote origin 'refs/heads/phase-57-marketing-engagement-creation' \
&& git push origin :refs/heads/phase-57-marketing-engagement-creation \
|| echo "Build branch not on origin; skip remote delete"
# 8. Prune remote-tracking refs
git remote prune origin
# 9. P57-D7 Option A retroactive cleanup
git branch -D phase-56-step-0
git branch -D phase-57-step-0
# 10. [CHECKPOINT B HALT — Operator final-confirms before tags land]
# 11. Create annotated tag
git tag -a phase-57-marketing-engagement-creation \
-m "Phase 57 close: marketing engagement creation"
# 12. Push tag via explicit refspec
git push origin refs/tags/phase-57-marketing-engagement-creation
# 13. Verify tag landed on origin
git ls-remote origin 'refs/tags/phase-57-marketing-engagement-creation'
cd /Users/dunin7/loomworks
# 1. Confirm working tree clean (Sub-arc 4 changes already committed)
git status --porcelain
# Expected: empty
# 2. Confirm tests green
npm test -- --run
# Expected: 150 vitest passed (was 149 pre-amendment-cycle-1; +1 from Sub-arc 4d)
npm run lint
npm run tsc
npm run build
# Expected: all clean
# 3. Push main to origin via explicit refspec
git push origin refs/heads/main
# 4. [CHECKPOINT B HALT — Operator final-confirms before tags land]
# 5. Create annotated tag at the post-Step-2a OL commit
git tag -a phase-57-marketing-engagement-creation \
-m "Phase 57 close: marketing engagement creation"
# 6. Push tag via explicit refspec
git push origin refs/tags/phase-57-marketing-engagement-creation
# 7. Verify tag landed on origin
git ls-remote origin 'refs/tags/phase-57-marketing-engagement-creation'
git push origin refs/heads/<branch> — not git push origin <branch>.git push origin :refs/heads/<branch> — not git push origin --delete <branch>.git push origin refs/tags/<tag> — not git push origin <tag>.git ls-remote origin 'refs/heads/<name>' and git ls-remote origin 'refs/tags/<name>' — separate invocations.
The convention prevents the error: src refspec ... matches more than one failure mode that Phase 56 encountered and resolved in-session.
DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks Phase 57 CR — Marketing Engagement Creation — v0.2 — 2026-05-12