DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path investigations/loomworks-seed-creation-engine-contract-v0_1.md

Loomworks — Seed-creation engine contract (interface layer)

Version. 0.1 Date. 2026-06-03 Provenance. Engine-source trace, Operator: Marvin Percival. The engine-interface layer beneath the seed-creation mechanism map: what the seed-creation core requires to be handed, and whether structured extraction is callable independently of any conversation flow. Status. Investigation / contract statement. Report-only — no design, no fix, no engine changes. Reads with (the seed/boundary set).

Code citations. engine: = the loomworks-engine repo at time of writing; line numbers indicative, names load-bearing.


Primary finding — is structured extraction callable independently?

There is no single "structured-extraction capability." There are two, with opposite coupling:

Fix-size consequence: reusing Phase 53 over a conversation already exists (at the cost of a throwaway Markdown file). Making Phase-31-grade extraction callable independently of the conversation engine does not exist as a seam — extraction is fused into the conversation prompt + turn handler.


The seed-creation contract

Entry points and what each requires

| Entry point | Source | Requires (shape) | Produces | |---|---|---|---| | draft_seed | creation.py:82 | The six fields already structured: what_the_work_is/who_consumes_the_work/voice_of_the_work/success_conditions: str, constraints: list[str], additional_assertions: dict[str,str]; plus R-A10 initial_contributors: list[UUID], initial_agents: list[UUID]; an actor: ActorRef; db. | Seed v1 under ADMIN engagement (seed_drafted). Does not extract — pure constructor/persister. | | amend_candidate_seed | creation.py:145 | A prior_seed: Seed + fields to change (others carry forward); actor, db. Pre-instantiation. | Seed v+1 (seed_amended, wasRevisionOf). | | induct_seed | creation.py:409 | A Seed + SeedInductionAgent + AgentRunner + actor + db. | One cycle; Findings + SeedInductionLoopCycle; convergence = zero open findings (:501). | | commit_engagement | creation.py:681 | A converged seed (no open findings, else NotConvergedError) + a human actor (kind != "agent", else AgentCannotCommitError). | Engagement v1 (engagement_committed). | | commit_engagement_divergent | creation.py:725 | Seed + human actor + non-empty rationale (else EmptyRationaleError). | Divergent Engagement. | | (row wiring) | engagements.py:255-288 / me_create_engagement.py:216-258 | A caller must separately INSERT an engagements row (state='candidate') and UPDATE candidate_seed_iddraft_seed does not create the row. | Candidate engagement linked to the seed. |

Rich vs. thin — what determines convergence

Induction examines the seed against R-A5–R-A11; an empty field yields a finding.

The contract, stated cleanly

> To create a well-formed convergent seed, a caller must hand draft_seed all six R-A5–R-A9 + R-A11 fields already populated with substantive, concrete content — in the shape _validate_extracted_payload enforces — plus R-A10 (initial_contributors=[person], initial_agents=[]) and a contributor-kind actor; having FIRST converted its raw material (a conversation, a document, form input) into those six fields by an extraction step the engine does NOT perform inside draft_seed. Then induct_seed to convergence and commit_engagement with a human actor.

The pivotal clause: the engine's seed-construction core is content-agnostic and does not extract. Turning raw material into the six fields is a separate obligation the caller must satisfy before draft_seed — and the engine offers exactly one reusable tool for it (Phase 53, file-shaped) and one non-reusable one (Phase 31, welded to the conversation).

Boundary: clean vs. assumes-a-caller (per the standing note)

Clean — any wrapper can satisfy: draft_seed, amend_candidate_seed, induct_seed, commit_engagement/_divergent, _create_engagement — they take structured fields / a Seed / an actor and assume nothing about provenance. The form-path HTTP routes are clean surfaces over that core. extract_discovery_to_seed_skill is almost clean — a standalone callable producing the canonical payload — with one coupling: input is a file_path, not text/turns.

Not clean — assumes a particular caller's shape:

Bottom line: the construction/induction/commit core is clean and wrapper-agnostic; the extraction step is where the engine either assumes the Companion (Phase 31, welded) or offers a file-shaped reusable tool (Phase 53). A wrapper's whole obligation reduces to "produce the six fields in the canonical shape, by whatever means, before draft_seed."


Investigation / contract only. No engine or wrapper code changed. No mechanism redesigned or proposed. Filed in loomworks-record/investigations/. Pairs with the seed-creation map, the three-paths deep-dive, the engine-boundary inventory, and standing-notes/loomworks-standing-note-engine-wrapper-boundary-v0_1.md (the lens).