Document adversarial implementation workflow WIP - #181
Conversation
PR #181: Document adversarial implementation workflow WIP11 files, +3337 / -0 Scope🔴 PR has 3337 lines changed. Split into focused PRs. 🟡 3337 lines changed. PRs under 400 receive more thorough review. Structural✅ No structural bloat detected. Slop✅ Slop indicators look low. Static Analysis✅ Oxlint found no issues. CorrectnessNo extraneous code patterns detected. |
End-goal implementation audit — 2026-08-02Reviewed PR head The target remains coherent: the user owns material decisions; planner and implementor converge through evidence; workflow state and environmental effects are explicit; agents do not own Git, GitHub, or workspace effects; and every live resource is scope-owned. Settled contracts to fold into the target documentsThese are documentation updates, not missing product features.
Shipped foundation available to the end goal
The document-level logic in Missing feature checklist for the complete workflowWorkflow identity, artifacts, and resumption
Stage execution and user continuation
Workspace ownership
Enforceable sandbox and permissions
Deterministic Git and GitHub effects
End-to-end workflow contract
Not blockers for this workflow
This checklist should shrink as features land. A settled contract updates the target documents and moves to the shipped foundation; only capabilities absent from the runtime remain unchecked. |
Current delivery mapThe root document is the workflow. A durable workflow run may continue through multiple document executions. Each issue remains an independently reviewable stop point. Living target and shipped document logic
Workflow identity and environment foundations
#199 and #227 can proceed independently. #218 is designed and stacks on PR #341 until #289 merges. Persistence and workspace composition
Workspace state is retained across completion, failure, cancellation, and interruption; scope teardown releases only ephemeral provider attachments. Point-in-time snapshots, rollback, and training export are not prerequisites for normal resumption. Deterministic Git and GitHub effects
Authority, composition, and certification
Dependency spine#298 is superseded by #291, which owns durable lookup, Implementors validate authorized slices. Taras settles #227, #290 exhaustion, and #302's term and installation architecture before those stories are delegated. #218's product decisions are recorded in the issue; its implementor validates that design rather than choosing a replay or provider model. |
Parallel delivery mapCurrent at PR head Parallel wavesShared-code collision rulesMaximum useful initial concurrency is three implementation lanes ( |
8d90204 to
503b114
Compare
Milestone story mapCreated the Adversarial implementation workflow milestone. Every task in the approved delivery sequence now has a canonical story:
PR #181 itself is also attached to the milestone as the living end-goal artifact. Each new story records scope, observable acceptance criteria, dependencies, and its sequence position. Existing stories #199, #203, #218, and #227 remain canonical rather than being duplicated. |
1a01e58 to
014447b
Compare
Fresh head on current main — #292Replaced the stale head The markup did not runEvery stage passed props through expression props as This is #305, still open — "Expression-valued component props can read The error model reaches the stagesA stage component is split by its
One claim I did not repeat: Stale claims removed
VocabularyCollapsed onto the concepts #289, #291 and #298 authorize — artifact ledger, artifact version, run identity, pinned source revision, stop reason, terminal record, stage boundary, declared inputs, cross-process continuation — replacing the four names these files used for a ledger and the three for a run. Engine state is described as scoped to the operation that owns it, with no module-scoped registry. Missing capabilities cite the issue that supplies them (#289, #291, #293, #294, #295, #296, #297, #298, #300, #302) rather than saying only "not implemented". ClassificationShipped: Evidence
Gates: Outstanding before merge#203 is still open and is an input to this target, not something this PR closes. Before merge this branch rebases onto the |
014447b to
68733d7
Compare
Rebased onto
|
User authority now gates execution — head
|
| Scenario | Agent turns | proceed |
Stages that ran |
|---|---|---|---|
| Material choice, user declines | 1 | false |
none — both bindings stayed unresolved |
| Material choice, user authorizes | 2 | true |
PLANNING-RAN, IMPLEMENTATION-RAN |
| No material choice | 2 | true (explicit <Parse> branch) |
PLANNING-RAN, IMPLEMENTATION-RAN |
The declining path records no subsequent agent turn. In the third scenario a declining <Answer> was in scope and never consulted, because <Elicit> never ran — the continuation came from the explicit branch. All four <Output> outcome branches were exercised separately and each renders its own outcome with no unbound-binding error, including rejected-at-acceptance.
5. Verification
Probes rerun: 9 frontmatters parse (UserCheckpoint now returnMode=value, the rest text), 5 embedded schemas compile, 21 shipped + 5 repository names resolve, 9 missing names unresolved. Vocabulary sweep clean.
Local gates: fmt, lint (0 errors), check, test (349 passed, 0 failed), check:jsr, tsc — all green.
All ten PR checks green: composability, deploy, jsr, lint, review, site, smoke, test-bun, test-deno, test-node.
Authority now survives the component boundary — head
|
| Scenario | Agent turns | commit | PR | issues | Result |
|---|---|---|---|---|---|
| Plan review declined | 3 | 0 | 0 | 0 | terminal=declined, authorized=false; no authorization question, no implementation turn |
| All approved, verdicts pass | 8 | 1 | 1 | 1 | accepted |
| PR review declined | 7 | 1 | 1 | 0 | implementation.terminal=declined; no acceptance question |
| Failing verdict, approved | 12 | 1 | 1 | 1 | revision turn runs; reaches implementation only after the later passing verdict |
| Exhaustion | 20 | 0 | 0 | 0 | terminal=exhausted, authorized=false; reaches neither |
Mutations, each changing an observed result:
| Mutation | Effect |
|---|---|
<Issue> moved ahead of its approval |
declined PR review goes issues 0 → 1 — the issue is created despite the decline |
Caller gate bypassed (planning.authorized → true) |
declined plan review goes prompts 3 → 6 — advances to the authorization question |
Planning's return reduced to text |
authorized / terminal / verdictPassed render as unresolved literals; the caller cannot gate at all |
Correction to my previous report
I described the earlier probe as discriminating the gating. It stubbed the outer stages, so it never exercised any internal-decision path — the harness was built not to see exactly what you found. The scenarios above run the real documents.
Verification
Probes rerun: 9 frontmatters parse (UserCheckpoint, Planning, Implementation now returnMode=value), 5 embedded schemas compile, 21 shipped + 5 repository names resolve, 9 missing names unresolved. Vocabulary sweep clean. #328's missing-capability classification kept, and #327's.
Local gates: fmt, lint (0 errors), check, test (349 passed, 0 failed), check:jsr, tsc.
Docs updated for the new boundaries: start.md (flow, gate section, data-flow table), artifacts.md (StageResult added; the three-kind split now says only parsed results can gate), the specification, and the PR description.
All ten checks green: composability, deploy, jsr, lint, review, site, smoke, test-bun, test-deno, test-node.
Sources returned, derived state removed — head
|
| Scenario | Agent turns | commit | PR | issues | Result |
|---|---|---|---|---|---|
| Plan review declined | 3 | 0 | 0 | 0 | no authorization question, no implementation turn |
| All approved | 8 | 1 | 1 | 1 | accepted |
| PR review declined | 7 | 1 | 1 | 0 | no deferred issue, no acceptance question |
| Failing verdict, approved | 12 | 1 | 1 | 1 | revision turn; reaches implementation only after the later passing verdict |
| Planning exhaustion | 20 | 0 | 0 | 0 | proceed=true passed=false; reaches neither |
| PR-review exhaustion | 24 | 5 | 5 | 5 | proceed=true passed=false; acceptance never reached |
Mutations, each changing an observed result:
| Mutation | Effect |
|---|---|
Gate on a duplicated authorized field |
declined plan review advances, prompts 3 → 6 |
Declare the handle as string |
Return validation failed — after commit and issue effects have run |
<Issue> moved ahead of its approval |
declined PR review goes issues 0 → 1 |
Verification
Probes rerun: 9 frontmatters parse, 5 embedded schemas compile, 21 shipped + 5 repository names resolve, 9 missing unresolved. Sweep clean, including StageResult. #327 and #328 classifications retained.
Local gates: fmt, lint (0 errors), check, test (349 passed, 0 failed), check:jsr, tsc. Docs updated: start.md, artifacts.md, the specification, the data-flow table, and the PR description.
All ten checks green: composability, deploy, jsr, lint, review, site, smoke, test-bun, test-deno, test-node.
Adversarial Implementation dependency-map deltaThe Workspace topology decision now has two evidence paths: #349 tests whether Deno can own the persistent SQLite Workspace directly while reusing Cloudflare's DOFS and FUSE layers. It compares real FUSE and the userspace shim independently, and compares its portability, durability, security, and maintenance boundary against PR #348's bundled-workerd result. |
Adversarial Implementation dependency map — Workspace design revisionPR #358 captures the design decisions produced by #346 and the Workspace interview. It changes the implementation path materially: Evidence and decisions
Current implementation pathRelevance audit
No implementation issue should independently re-decide Workspace explicitness, filesystem restoration, topology, Agent write authority or transaction granularity. Those changes now require an architecture/spec revision first. |
Worker Shell topology delta — INCLUDE#357 / PR #362 resolves the final optional topology gate positively. One Worker Shell invocation satisfies The initial local capability set therefore includes Workspace-scoped Worker Shell through Production implementation moves to #363 with four constraints that are no longer open design questions:
Updated path: PR #358 records the accepted architecture and observable contract. #357 closes when its evidence PR is accepted. |
Correction: spike evidence remains outside production mainPRs #350 and #353 were accidentally merged while their stack was being collapsed. PR #364 reverts both squash commits, restoring main exactly to its pre-spike tree. PR #362 remains an unmerged 20-file proof stacked on the #351 evidence branch. The disposition is:
Do not merge the spike source trees as prerequisites for #363. Production work consumes their measured contracts and may selectively adapt proven code under the repository's normal architecture and dependency rules. |
Adversarial Implementation issue reconciliation after #358The authoritative production dependency map now lives in #218. The retained Workspace foundation is sequenced as: The missing production stories are now explicit:
Stale contracts were reconciled in #199, #227, #290–#295, #297, #299–#302. In particular, the plan no longer uses #357 is closed with an INCLUDE verdict. PR #362 remains unmerged experimental evidence; #363 owns production Worker Shell after #365/#366. PRs #350 and #353 likewise remain unmerged evidence. |
The adversarial implementation workflow target was written against a main that predates the error-model rules (#315), the error vocabulary rename (#317), error-model semantics (#319), and operation-scoped state (#325). It asserted `<CollectFailures>` as structural syntax, "the unresolved diagnostic", and a durable layer that "replays recorded results" — none of which describe main. This re-derives it on 7d7bdf2. The error model reaches the documents. A stage component is split by its `<Output>` boundary: the region inside runs under the `output` error mode, everything outside is documentation and runs under `throw`, which no `<PrintErrors>` region replaces. So a stage returns a complete validated result or it fails, keeping only what it had already rendered — the final `<Parse>` in each repair loop is a real gate. `throwOnError` is load-bearing for the same reason: without it a failed prompt records its failure and returns its text, raising nothing to decide. The markup did not run. Every stage passed props through expression props as `agent={props.planner}`, which fails on main with `props is not defined` — an expression prop reads the bare binding while text interpolation reads the namespace. Unifying them is #305, whose acceptance includes expression props reading `props.name`. 22 sites are corrected to the spelling main supports, and the asymmetry is recorded with the issue that removes it. Vocabulary is collapsed onto the concepts #289, #291, and #298 authorize: artifact ledger, artifact version, run identity, pinned source revision, stop reason, terminal record, stage boundary, declared inputs, and cross-process continuation, in place of the four names these files used for a ledger and the three for a run. Missing capabilities now cite the issue that supplies them rather than saying only "not implemented", and replay is described as reaching the state execution resumes from, never as the continuation itself. Planning-loop exhaustion stays open. It is recorded against #290, which pins the behavior; this change reports `verdict.passed` and does not call an exhausted loop converged. Evidence: `inspectDocument` parses all 9 frontmatters and compiles both schema kinds; `compileParseSchema` compiles all 5 embedded draft-07 schemas; `inspectComponent` resolves 21 shipped and 5 repository names and confirms 9 missing ones unresolved; `InstructionFiles` runs end to end against the repository's own AGENTS.md.
Rebased onto 511776e. #326 closed #203 by proving the two projection lifetimes with real modifiers — L8 for a projected `persist` resource and Q14 for a projected daemon — which were the acceptance criteria this target had the weakest evidence for. Projected content keeping its caller's bindings while its live effects belong to the component invocation is now stated as shipped, along with why it matters: a process a stage starts stops before the workspace it ran in is removed, which is the ordering `<Worktree>` (#293) is built on. `architecture.md` is authoritative on the error model, so the `output` row reads "fails the run; `<PrintErrors>` can print instead" as the registry states it. The engine does not do that yet — an outer boundary ends the run instead, whether the failure arose in the region itself or in content projected into it — so the discrepancy is classified as missing and filed as #327 rather than allowed to redefine the settled contract. No stage writes `<PrintErrors>`, so nothing here depends on it. The distinction the target does keep is the one the registry makes: a `throw` decision is the mode a boundary cannot replace. Every stage's parsing sits in documentation, so the final `<Parse>` is a gate for that reason and not because printing is unavailable.
…entory `<UserCheckpoint>` captured `elicitation.proceed` and then returned only rendered prose, so a caller had nothing to branch on. `start.md` invoked `Planning` and `Implementation` unconditionally and the two stages branched on the planner verdict alone: a user answering `proceed: false` could not stop anything. That contradicts the central user-authority contract and #290's acceptance. `<UserCheckpoint>` now declares `returns` and binds a schema-validated decision — `proceed` plus the assessment fields a later prompt quotes. One `decisionSchema` serves both paths: `<Elicit>` binds it when the assessment reports a material choice, and an explicit `<Parse>` binds `"proceed": true` with its reason when there is none, so continuation is represented rather than inferred from absent elicitation data. Every affected transition is gated — a declined handoff does not start Planning, a declined authorization does not start Implementation, a declined review neither revises nor accepts, and a declined acceptance finishes as rejected rather than falling into the accepted branch. Nesting is what the language supports; it is not stopping. The run still expands to `<Output>` and completes, with no clean halt at a stage boundary and no stop reason recorded for one. That is classified as missing under #298 over #289 rather than described as enforcement. Two engine limitations surfaced while proving this and are filed rather than worked around silently. `<Content />` is substituted only at a body's top level or directly inside `<Output>`, never nested inside a `<Prompt>` (#328) — `Discovery` and `UserCheckpoint` used exactly that shape and could not expand, so both now take the material as a prop. And a binding made inside a Markdown component's projected content does not escape to its caller, while the same binding inside a registered function component does; the harness had to account for that to test the real components. artifacts.md claimed every listed result was JSON declared inline. It is corrected into three kinds: `PlannerHandoff` and `ImplementationPlan` are prose with no schema and cannot gate anything; the four parsed results are described using only fields their inline schemas declare; and `UserDecision` is the checkpoint's declared return, with the actor and timestamp that would make it auditable marked missing under #291. Discrimination over the shipped subset, with a turn-recording stub agent: a declined checkpoint records 1 agent turn and neither stage runs; the authorized path records 2 and both run; a no-material-choice assessment records 2 and proceeds on its explicit `<Parse>` branch while a declining answer in scope is never consulted.
`Planning` and `Implementation` consumed their internal checkpoint decisions and returned only prose, so authority leaked at the component boundary. A declined plan review broke the planning loop, but `start.md` still asked the authorization question and could reach `Implementation`; a declined pull-request review still let the change be reported accepted. `Implementation` also created deferred `<Issue>` effects before its review checkpoint ran, so the planner's proposed disposition became a durable GitHub object before the user approved it. The earlier probe stubbed the outer stages, so it never exercised those paths. Both stages are now value components. Each returns its prose, the parsed verdict's fields, the complete `UserDecision` it resolved, and two derived control fields the caller gates on: `authorized`, which is `proceed && verdict.passed`, and `terminal`, which distinguishes `converged` from `declined` and `exhausted`. A stage cannot approve its own advancement, and an exhausted loop reports itself distinctly and fails closed — which is not a decision about what exhaustion should do, still unresolved under #290. `start.md` gates on those returns: authorization is requested only after a passing plan verdict and an approving plan-review decision, acceptance only after a passing pull-request verdict and an approving review decision. It renders the human-readable reports from the returned fields. Deferred `<Issue>` creation moved inside the approved branch, after the checkpoint. `proceed: true` authorizes the exact proposed transition and effects; the free-text response records reasoning and never amends effects, because an effect that has already executed cannot be amended by prose. `proceed: false` performs none of them. Discrimination against the real `Planning`, `Implementation`, and `UserCheckpoint`, stubbing only the agent transport and the three deterministic components that do not exist. A declined plan review: 3 agent turns, no authorization question, no implementation turn, no effects. A declined pull-request review: no deferred issue, no acceptance question. A failing verdict with approval performs the revision turn and reaches the next stage only after a later passing verdict. Exhaustion reaches neither. Moving `<Issue>` ahead of approval creates the issue despite a decline; bypassing a caller gate advances past a declined review; reducing either return to text leaves the gate fields unresolved. Each mutation changes an observed result.
Two contract problems in the replacement for the authority leak.
`Implementation` declared `pullRequest: { type: string }` and returned the
raw binding. #295 specifies a structured handle — number, URL, head and
base identities, state, reviews, comments, checks — so a conforming
`<PullRequest>` would perform its durable effects and only then fail this
component's return validation. The previous harness stubbed the handle as
a string, which is exactly why the probe stayed green. `start.md` consumes
none of it and the artifact ledger records the effect and handle
independently (#291), so the field is gone and `report` renders the named
fields a reader needs. If a later caller needs the handle it gets #295's
object schema, never a placeholder.
Both stages also returned `authorized` and `terminal`, duplicating
`decision.proceed && verdictPassed` and a second reading of the same two
fields. A return schema can require both sources to be present but cannot
require a derived flag to agree with them, so a record pairing
`proceed: false` with `authorized: true` validated — and `authorized` read
confusingly next to the separate authorization checkpoint. Both are gone,
along with the `StageResult` name, which was coined without the permission
architecture.md's terminology registry requires; it is not being added
there.
`start.md` now computes each gate where it uses it, from the authoritative
pair. After a loop, `decision.proceed` false is a decline and
`decision.proceed` true with `verdictPassed` false is exhaustion; the gate
refuses both and the output tells them apart, while the terminal policy
stays unresolved under #290. Deferred `<Issue>` creation keeps its
corrected position after the checkpoint, inside the approved path.
Discrimination reruns against the real documents with effects stubbed at
their specified shapes. Declined plan review: 3 turns, no authorization
question, no effects. Declined pull-request review: no deferred issue, no
acceptance question. Fail-then-pass reaches implementation only after the
passing verdict. Planning exhaustion and pull-request-review exhaustion
each reach neither. Mutations: gating on a duplicated `authorized` field
advances a declined review (3 turns becomes 6); declaring the handle as a
string fails return validation after commit and issue effects have already
run; moving `<Issue>` ahead of approval creates it despite the decline.
Two inconsistencies left by the return-contract fix. The migration to value components was described in some places and not others. The specification still said `Planning` and `Implementation` return derived `authorized` and `terminal` fields, which they stopped doing. And the specification, `start.md`, and `primitives.md` all still described every component body as split by `<Output>` into documentation under `throw` and a region under `output`. That is true only of the text components: a value component declares `returns`, renders nothing, cannot contain `<Output>` at all, and runs its entire body fail-fast, binding nothing when it fails. Each document now says which kind it is talking about, and `Planning`, `Implementation`, and `UserCheckpoint` describe their own bodies as value bodies. The pull-request reviewer could not see what it was reviewing. #295 resolves reviews, comments, and checks alongside the identities, and the prompt rendered only number, state, URL, head, and base — while `runtime.md` denies agent network access, so the planner had no way to recover the rest. An adversarial review that cannot see a failing check or an existing objection is uninformed rather than adversarial. Every category is now rendered explicitly into the review prompt and into the checkpoint material the user reads, each collection iterated with `<Each>` rather than stringified, and the prompt names the revision under review: the diff at `headSha` against `baseSha`, with a verdict describing that head alone. The member field names inside reviews, comments, and checks are #295's to settle; these documents depend on that schema rather than defining a competing one. What is settled here is that the planner receives the complete snapshot. The handle stays internal — `start.md` gates on the verdict and decision — so the earlier claim that nothing consumes it was wrong, and the PR description is corrected too. Discrimination adds a structured `<PullRequest>` stub carrying non-empty reviews, comments, and checks with distinct markers. It captures the actual rendered planner prompt and the checkpoint material and asserts every category, both head identities, and the diff instruction reach them. Omitting any one category reddens exactly its own assertions and leaves the others green. Nothing in the test uses agent network access. The six gate scenarios and the three earlier mutations still hold.
…on text Three claims did not match what the documents do. `artifacts.md` still said nothing consumes the pull-request handle. The boundary is now stated exactly: `Implementation` consumes all of it internally, `start.md` never receives it — what crosses the stage boundary is the verdict and the decision — and the artifact ledger records the effect independently (#291). The specification said both text components do their work in documentation. Only `Discovery` does. `InstructionFiles` puts its `<Each>` and `<File>` reads inside `<Output>`, and probing that case corrected a second assumption in the same sentence: `<File>` prints its own failures, so an unreadable instruction file is decided as a printed error before the region's `output` mode sees it. The run continues; what stops the caller is the binding rule, since `as` refuses a body holding a printed error and `instructions` stays unbound. `start.md` gains the same qualifier, because "an undecided error fails the run" is only true of undecided ones. The user checkpoint did not carry what the PR claimed it did. The planner prompt rendered each review's body; `checkpointMaterial` rendered only the author, state, and head. A user approving a change has to read the original objection, not the planner's summary of it, so the body is now in both. The earlier probe missed this because it asserted the review *author* on the checkpoint material and the *body* only on the prompt — an assertion too weak to see the omission it was meant to cover. Discrimination now asserts the body on both surfaces. Dropping any category reddens both symmetrically, and dropping the body from the checkpoint alone reddens the checkpoint while the prompt stays green — the exact shape of the defect.
`checkpointMaterial` presented the pull request and the verdict but not the two things approval actually sets in motion. When a verdict fails, approval sends `verdict.revisionPrompt` to the implementor, and the checkpoint never showed it. A `defer` disposition sends the complete finding to `<Issue>`, including `finding.evidence`, and the checkpoint showed only the title, disposition, and description. That contradicts the document's own rule. `proceed: true` authorizes the exact transition and the exact effects presented for assessment, which means nothing if the material omits them: a user could approve revision instructions and issue evidence they had never read. `Planning` already showed its revision prompt; `Implementation` did not. Both are now in the material, unchanged and unsummarized — the literal `verdict.revisionPrompt`, and each finding's evidence rendered beneath it with a nested `<Each>`. The explanatory text in the component and the specification says why, rather than asserting that approval covers effects it never displayed. Discrimination gains distinct markers for both. The baseline asserts they reach the checkpoint, that the revision prompt the implementor receives carries the same value, and that `<Issue>` receives the same complete finding — the stub now records what it was passed. Removing either field from the checkpoint reddens exactly its own assertion while the effect assertions stay green, which is the shape of the leak: the effect still fires, the user just never saw it.
The target described a `<Workflow>`/`<Sandbox>`/`<Stage>` spine over a sidecar Git ledger at `refs/xmd/runs`, an implicit worktree, an implementor that edits files, and a `<PullRequest>` handle carrying reviews, comments and checks. None of that is the architecture any more, and three of those constructs were rejected rather than deferred. The command selects the environment: `xmd workflow start` creates the run and its one retained Workspace, and the root document is the workflow. Named `<Repository>` and `<Worktree>` compose the checkouts from ordinary root props, so nothing resolves through a hidden alias and no single worktree is implied. Agents are read-only under that host ceiling, so the implementor returns constrained XMD that `<Expand>` admits and expands as ordinary durable effects, and `<Git.Add>`, `<Git.Commit>`, an explicit `<Git.Push>` and `<PullRequest>` follow in that order. Waiting for the user is a durable suspension that `resume` continues, which is what `<Stage>` was reaching for. Retention is no longer speculative. #291 and #365 are shipped foundation: the run retains its filtered journal, Workspace roots, and metadata, and one expansion publishes its mutation, logical root and journal result in one transaction. `JournalProvenance` (#425) is what makes that history evidence rather than storage, and it is named where the documents discuss retained evidence. Every remaining capability is marked as target behavior against #218's dependency order. Two gaps are now stated rather than assumed away. #295 moved reviews, comments and checks out of the creation result, and no issue owns the forge read that returns them to a network-denied reviewer; and the journal records which run and expansion produced a decision but not which person answered. Props are namespaced throughout (#305), `<Content />` projects at any depth (#328), and the obsolete asymmetry notes are gone.
382d115 to
16ac13e
Compare
#292 synchronization handoffHead and base
The branch was rebased, not merged. It had to be: What changedOne commit, eleven files, docs only. Nothing outside Retired constructs.
Restructured stages.
Markup migrated. Every expression prop reads Settled contracts incorporated
What remains unimplementedNine names the documents write do not resolve on Two gaps with no ownerBoth are stated in the documents rather than papered over, and both probably want issues:
Three smaller questions are raised against their owning issues rather than answered here: One documentation discrepancy left alone: VerificationDocumentation-only, so this is inspection through current
The workflow still does not run end to end, and nothing here claims it does. |
Why
#181 is the end-goal target for the planner → implementor → human-decider
adversarial implementation loop. It only earns that role while it describes the
architecture the project is actually building, and the path underneath it moved:
#291 and #365 shipped, #425 named what the journal witness proves, #218 became
the authoritative dependency map, and #298's
<Stage>was rejected outrightrather than deferred. #292 tracks keeping this target synchronized.
What changes
Before:
The target described a
<Workflow>/<Sandbox>/<Stage>spine over anartifact ledger in sidecar Git history at
refs/xmd/runs, one implicitworktree, an implementor agent that edits files directly, a single
<Commit>,and a
<PullRequest>handle carrying reviews, comments and checks. It markedretention and atomic effects as unbuilt, and described the props asymmetry and
the
<Content />nesting bug as current behavior.After:
The command selects the environment.
xmd workflow startcreates the workflowrun and its one retained Workspace (#366); the root document is the workflow,
because #298 rejected stage subdivision. Named
<Repository>and<Worktree>compose the checkouts from ordinary root props, so no locator resolves through a
hidden alias and no single worktree is implied (#293). Agents are read-only
under a host ceiling a document cannot raise, so the implementor returns
constrained XMD that
<Expand>preflights and expands as ordinary durableeffects (#302, #369), and
<Git.Add>,<Git.Commit>, an explicit<Git.Push>and
<PullRequest>follow in that order (#294, #370, #295).<Issue>stillsits inside the approved branch (#296). Lexical
<Dir>and<Agent.AddDir>areseparate operations, and the two stages that give an agent a checkout say so.
Waiting for the user is a durable suspension that releases the executor and
xmd workflow resumecontinues — which is what<Stage>was reaching for.Retention is no longer speculative. #291 and #365 are described as shipped
foundation: the run retains its filtered journal, versioned Workspace roots,
Repository/Worktree metadata and Agent-session mappings, addressed by public run
ID, and one expansion publishes its mutation, logical Workspace root and journal
result in one transaction.
JournalProvenance(#425) is named where thedocuments discuss retained evidence — it is what makes history this run's
history rather than merely storage.
refs/xmd/runsis gone.Props are namespaced everywhere (#305),
<Content />projects at any depth(#328), and #203's lifetime rule stays. Every unbuilt capability is a table row
naming its issue.
Two gaps are now stated instead of assumed away:
<PullRequest>'s creationresult, and no open issue owns the forge read that returns them to a
network-denied reviewer. The requirement is preserved verbatim; the mechanism
is marked unowned.
person answered it. No open issue owns that either.
How it works
The workflow still works outside in: it establishes observable, independently
reviewable boundaries, then implements smaller PRs within them. Review findings
that would derail the active chain become explicit follow-up issues when
deferral is safe and the user approved it.
Review guide
Start with:
workflows/adversarial-implementation/start.mdThen review:
workflows/adversarial-implementation/Implementation.md— the largest change:read-only agents, generated XMD, and the Git/forge effect order.
workflows/adversarial-implementation/primitives.md— the inventory, noworganized as Implement retained Workflow Workspace restoration #218's four-phase dependency map.
workflows/adversarial-implementation/artifacts.md— retained run state andJournalProvenancereplacing the artifact ledger.workflows/adversarial-implementation/runtime.md— the host ceiling replacing<Sandbox>, and suspension/interruption/cancellation.specs/adversarial-implementation-workflow.md— the same reconciliation atcontract level, including the rewritten open-questions list.
Planning.md,Discovery.md,UserCheckpoint.md,InstructionFiles.md—namespaced props and
<Agent.AddDir>.Look carefully at:
main;including decisions a stage resolves internally and returns;
authorizes it;
another;
should become issues before this merges;
architecture.md— "document execution" and"workflow run" are now distinguished where the old text said "run".
What must stay true
responsibilities: the planner proposes a theory of implementation and the
implementor validates it.
and a stage returns its decision and verdict as data rather than prose.
Git.Pushis explicit and separate from bothGit.CommitandPullRequest.SQLite.
deferred findings stay visible without silently expanding the active chain.
How to verify it
Documentation-only, so verification is inspection through current
mainratherthan a runtime suite:
inspectDocumentparses every frontmatter block in the nine workflow documentsand compiles its declared props and returns schemas through
main;compileParseSchemacompiles all five embedded draft-07 schemas. 9documents, 5 embedded schemas, 0 failures.
inspectComponentresolves every component name the documents write, throughthe same
selectComponentpath execution uses. 21 resolve —Agent,Break,Capture,Discovery,Each,Elicit,Else,File,Glob,If,Implementation,InstructionFiles,Loop,Output,Parse,Planning,Prompt,Return,SafeParse,Session,UserCheckpoint—and 9 do not:
Agent.AddDir,Expand,Git.Add,Git.Commit,Git.Push,Issue,PullRequest,Repository,Worktree. That set isexactly what the "what runs today" tables claim, so a table that drifts from
mainfails this check.git diff --check origin/main...HEAD— clean.deno task lintcoverspackages scripts .reviews/componentsand does notreach
specs/orworkflows/, so it was not run; no source or test filechanged.
The workflow still does not run end to end, and this change does not claim it
does.
Scope
Included
documents, and the runtime, artifact and primitive documents.
JournalProvenanceterminology where the documents discuss retained evidence.Intentionally unchanged
specs/andworkflows/changes.specs/workflow-workspace-spec.md§7.5, which still says<PullRequest>"returns the request URL through
as" while Add a deterministic PullRequest workflow effect #295 settles a minimal structuredresult. These documents follow Add a deterministic PullRequest workflow effect #295 and name it; reconciling the spec sentence
is a separate change.
<Call>are deliberately not on this path.New abstractions
open issue or to shipped syntax, and
<Expand>is used with the workflowWorkspace specification's own placeholder caveat that Evaluate Agent-generated XMD through a constrained allowlist #369 settles the name.
Risks and limitations
do not resolve, and neither
xmd workflow startnorresumeexists.comments and checks, and elicitation actor identity. Both are flagged in the
documents; neither has an issue yet.
<Agent.AddDir>'s exact placement relative to<Session>, and whetherre-registering a path a session already holds is idempotent, are Enforce read-only workflow Agent authority #302's to
settle.
PlanningandImplementationstate the requirement rather thanassume the answer.
<PullRequest>again under a new expansionidentity. Not opening a second pull request depends on Add shared external forge-effect reconciliation #297's natural-key
observation, and Add a deterministic PullRequest workflow effect #295's "conflicting head is diagnosed" has to distinguish a
head that deliberately advanced on the same branch from a conflicting one.
outputdecision remains contract the engine does not meet (An outer <PrintErrors> does not print a failure an <Output> region decided #327);no stage depends on it.
Scope confirmation
main, not merged.