Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 71 additions & 11 deletions examples/adversarial-implementation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ retains the selected providers and all three budgets through continuation.
consumer-driven API repairs, each from zero through ten. `maxResponseCorrections`
bounds extra response-format calls per completed assignment, from zero through
three. Zero admits no extra response call. It applies to ordinary planning,
implementation, selected feedback reviews and foundation replies, including
implementation, selected feedback reviews, independent delivery reviews and
foundation replies, including
repairs by their original owner. It authorizes no transport retry or repetition
of uncertain productive work. Continuing a Ticket keeps its consumed source
correction count and recorded allocation; it does not restart a failed attempt.
Expand Down Expand Up @@ -304,19 +305,45 @@ Independent review summaries allow 1500 characters; detailed observations belong
in `findings`. The request states this bound alongside the exact revision and
clause IDs. Ordinary phase and API-foundation summaries retain their own bounds.

A joined reply containing only `{"status":"in_progress"}` gets one completion
turn in the same native conversation, with the same reviewer, resolved model,
effort and exact source revision. The workflow saves the original reply, checks
that the checkout is clean and reserves `completion/` before sending a prompt
with a five-minute deadline. A second progress reply, unavailable conversation,
failed turn or changed source holds the review. Unmarked prose and malformed
verdicts do not authorize a completion turn. Status and reconciliation read the
saved evidence without prompting; a later invocation never starts an unused or
interrupted completion turn.

The completion turn has its own allowance. If it returns a review whose only
defect is summary length, the original formatting allowance still applies.

An otherwise-valid joined review with only an oversized summary can consume the
work item's recorded `maxResponseCorrections` allowance. Each correction stays
in the selected reviewer conversation with the same resolved model and effort.
It shortens only `summary`; every other result field is frozen. Zero permits no
extra call. The workflow records the original raw reply and rejection, reserves
each correction before dispatch, and saves its request, native outcome, reply,
source observations and disposition separately. Exhaustion, changed substance,
changed source or uncertain work holds explicitly; none selects a fallback
reviewer or repeats the completed review. Reconciliation validates this saved
chain without prompting. Historical assignments without a recorded allowance
have zero; a new workflow does not retroactively accept their rejected replies.


Use `--props-action reconcile` when the selected joined review has a saved
execution but no accepted receipt. Only the selection's attempt qualifies: the
original reviewer, or Astra after a retained transition from an eligible Fable
failure. It checks that attempt's assignment, joined execution, unchanged raw
reply, current schema, clauses and source before creating the missing receipt,
reply, any saved completion, current schema, clauses and source before creating the missing receipt,
and saves a raw reply the execution joined but never wrote. It never shortens text, changes a verdict, repeats
a model call or overwrites a contradictory receipt. Missing or uncertain execution
continues to hold. Status uses this same validation boundary to read receipts.

Reconciliation is limited to independent review from a work item launched under
the same response contract. Its assignment retains the exact response schema; a
missing or different schema refuses rather than reinterpreting an old reply. It cannot repair or adopt an ordinary rejected role
verdict, rewrite its raw rejection or partial work, or reset a correction budget.
missing or different schema refuses rather than reinterpreting an old reply. It validates only corrections recorded under the original review assignment.
It cannot adopt an ordinary rejected role verdict, rewrite its raw rejection or partial work, or reset a correction budget.
A current schema accepting older text does not retroactively approve that work.
Preserve the original rejection and require an explicit applicable
schema-amendment decision, recording the old bound, amended bound, exact raw
Expand Down Expand Up @@ -361,13 +388,46 @@ from claiming readiness or merging independently.

## Prepare requests without metadata repair turns

These rules apply to separate phase requests and Ticket role calls.
`Phase.Request` renders the complete prompt before entering an Agent, including
initial repository instructions, role instructions, assignment, selected text and
response schema. A missing selected component or input fails there; a packet
above 256000 characters refuses before provider dispatch. The selected evidence
keeps its separate 64000-character bound; the complete-prompt ceiling also accommodates
mandatory initialization instructions and the response schema. Nothing is truncated.
Claude workflow-role calls use the CLI's scoped `claude-workflow-role` provider.
Each role installs it directly around its authored session, covering initial and
continued prompts. It disables native shell/subagent backgrounding and denies
`ScheduleWakeup` and `Monitor`;
ordinary interactive Sidekick calls keep their defaults. A retained session that
lacks matching creation settings refuses before another prompt. Each role joins
its owned processes and returns its result in the same call. The upfront brief
contains work, evidence and lifetime rules. Identical role instructions selected
as input are delivered once; a different captured version retains the current
role brief too. The frozen submission guide contains response schema, limits and
routing. Reading defaults to result preparation; an earlier read must resolve a
concrete reporting requirement that blocks a work decision. Every result,
including an early blocker, requires the complete guide within the same call.

These rules apply to separate phase requests and Ticket role calls. Codex authors
prose committed to workflow documents, including guides, component instructions
and prompt templates. Claude roles may write internal runtime handoffs, hold
prompts and summaries.
`Phase.Run` freezes the submission guide in its reserved attempt directory.
`Phase.Request` checks that guide and prepares the phase prompt before entering
an Agent. The prompt includes initial repository and role instructions,
the assignment, selected text and an absolute reference to `submission-guide.md`
in the attempt directory. The guide contains the complete submission instructions
and the current role- and phase-specific JSON contract. Read it before returning
any result, including an early blocker, source conflict or unanswered decision.
The same retained native call reads the file and returns the result; staging the
guide adds no model call.

The guide and its hash receipt are runner-owned. Preparation refuses occupied
paths and confirms that the published text is readable under current File
permissions and protection. After saving each raw reply, the workflow verifies
the guide and receipt against the expected submission instructions before it
accepts a result or starts a correction. Missing, unreadable or changed files
hold the attempt with its raw reply preserved. Corrections retain their existing
inline repair packet, original session and allowance.

A missing selected component or input fails before provider dispatch. A prompt
above 256000 characters refuses without truncation. The guide has its own
256000-character and UTF-8-byte bounds. Selected evidence keeps its separate
64000-character allowance; moving submission instructions does not enlarge it.
Provider configuration and client compatibility retain their existing checks before a turn starts.
No paid prompt probes installation or repairs launch metadata.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ props:

<Adversarial.Schema as="schemas" />
<Phase.Profile role="planner" design={true} plannerProvider={props.assignment.plannerProvider} assessment={props.assignment.assessment} as="profile" />
<Output><Agent name={profile.provider}><Session name={props.assignment.session} model={profile.model} effort={profile.effort}><Phase.Session directory={props.assignment.identityDirectory} name={props.assignment.session} requireExisting={props.assignment.sessionEstablished === true || props.correction !== null}><Prompt throwOnError={true}>
<Let as="request">
<If condition={props.correction !== null}>
You remain the original Planner. This is response-only correction {props.correction.ordinal} with {props.correction.remaining} remaining. Shorten only the rejected summary or handoff to its stated bound. Every other result value is frozen by the supplied schema, including the API, outcome, source revision, artifacts, assessment and command evidence.

Expand Down Expand Up @@ -48,4 +48,6 @@ Return exactly one JSON object satisfying this contract. Evidence names actual c
<Json value={schemas.foundation} />
</Else>
</If>
</Prompt></Phase.Session></Session></Agent></Output>
</Let>
<Phase.ProviderName agent={profile.provider} as="provider" />
<Output><If condition={profile.provider === "claude"}><AgentProvider name={provider} defaultAgent="claude"><Agent name="claude"><Session name={props.assignment.session} model={profile.model} effort={profile.effort}><Phase.Session directory={props.assignment.identityDirectory} name={props.assignment.session} requireExisting={props.assignment.sessionEstablished === true || props.correction !== null}><Prompt throwOnError={true}>{request}</Prompt></Phase.Session></Session></Agent></AgentProvider><Else><Agent name={profile.provider}><Session name={props.assignment.session} model={profile.model} effort={profile.effort}><Phase.Session directory={props.assignment.identityDirectory} name={props.assignment.session} requireExisting={props.assignment.sessionEstablished === true || props.correction !== null}><Prompt throwOnError={true}>{request}</Prompt></Phase.Session></Session></Agent></Else></If></Output>
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ A release that fails ends the run and leaves the attempt reserved, so it holds
for reconciliation and can never select a replacement.

<Let as="entry" value={props.selection.reviewers[props.position]} />
<Dir path={props.attempt}><File path="assignment.json"><Json value={{work:props.selection.work,revision:props.selection.revision,reviewer:entry.reviewer,acceptance:props.selection.policy.acceptance,responseSchema:props.selection.responseSchema}} /></File></Dir>
<Dir path={props.attempt}><File path="assignment.json"><Json value={{work:props.selection.work,revision:props.selection.revision,reviewer:entry.reviewer,acceptance:props.selection.policy.acceptance,responseSchema:props.selection.responseSchema,...(props.selection.maxResponseCorrections === undefined ? {} : {maxResponseCorrections:props.selection.maxResponseCorrections})}} /></File></Dir>
<Try>
<Delivery.Role delivery={props.delivery} revision={props.selection.revision} reviewer={entry.reviewer} choices={entry.choices} position={props.position} attempt={props.attempt} />
<Dir path={props.attempt}><File path="execution.json"><Json value={{status:"completed",failure:null}} /></File></Dir>
Expand Down
58 changes: 58 additions & 0 deletions examples/adversarial-implementation/components/Delivery/Finish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
description: 'Finish an incomplete review once in its original conversation, or read that saved turn. Use <Delivery.Finish delivery={delivery} revision={revision} reviewer={reviewer} catalog={catalog} attempt={attempt} dispatch={false} as="reply" />.'
props:
type: object
properties:
delivery: {type: object}
revision: {type: string, pattern: '^[0-9a-f]{40}$'}
reviewer: {type: object}
catalog: {type: object}
attempt: {type: string, pattern: '^/'}
dispatch: {type: boolean}
required: [delivery, revision, reviewer, catalog, attempt, dispatch]
additionalProperties: false
returns: {type: string}
---

The initial turn has returned an explicit progress reply. Reserve the one
completion turn before prompting. Its reply and source evidence stay separate
from the first turn and any later summary corrections.

<Delivery.Schema as="schemas" />
<If condition={props.catalog.state !== "selected" || typeof props.catalog.model !== "string" || !props.catalog.model}><Fail message="The progress reply has no retained selected model. Preserve it and hold." /></If>
<Let as="directory" value={props.attempt + "/completion"} />
<Let as="request" value={{schema:"delivery-review-completion.v1",revision:props.revision,reviewer:props.reviewer,model:props.catalog.model,original:props.attempt + "/raw.txt",timeout:"5m",responseSchema:schemas.review}} />
<Let as="sourceSchema" value={{type:"object",properties:{head:{const:props.revision},clean:{const:true}},required:["head","clean"]}} />
<If condition={props.dispatch}>
<Ticket.Checkout repository={props.delivery.repository} as="before" />
<If condition={before.head !== props.revision || !before.clean}><Fail message="Source changed before review completion. Preserve the first reply and hold." /></If>
<Let as="quoted" value={"'" + directory.replaceAll("'","'\"'\"'") + "'"} />
```bash exec as="reserved"
mkdir -- {quoted}
```
<If condition={reserved.exitCode !== 0}><Fail message="The review completion is already reserved or cannot be reserved. No prompt is repeated." /></If>
<Dir path={directory}><File path="request.json"><Json value={request} /></File><File path="source-before.json"><Json value={before} /></File></Dir>
<Delivery.Turn as="turn"><Agent name={props.reviewer.provider}><Session name={props.reviewer.session} model={props.catalog.model} effort={props.reviewer.effort ?? undefined}><Phase.Session directory={props.delivery.directory + "/sessions"} name={props.reviewer.session} requireExisting={true}><Prompt throwOnError={true} timeout={request.timeout}>
Continue your unfinished independent review of {props.revision} from this conversation. Finish only the checks still needed. Keep source unchanged, run checks in the foreground and join them before returning. Return the final verdict for the original acceptance clauses as one JSON object. If you cannot finish, report the concrete blocker in the verdict. This is the only completion turn.
<Json value={request.responseSchema} />
</Prompt></Phase.Session></Session></Agent></Delivery.Turn>
<Dir path={directory}><File path="outcome.json"><Json value={{reviewer:props.reviewer,catalog:props.catalog,turn}} /></File></Dir>
<If condition={turn.state !== "reply"}><Fail message={"Review completion failed: " + turn.failure + ". Preserve both turns and hold."} /></If>
<Dir path={directory}><File path="raw.txt">{turn.reply}</File></Dir>
<Ticket.Checkout repository={props.delivery.repository} as="after" />
<Dir path={directory}><File path="source-after.json"><Json value={after} /></File></Dir>
</If>
<Ticket.Text path={directory + "/request.json"} as="savedRequest" />
<Parse schema={{type:"object"}} as="packet">{savedRequest}</Parse>
<If condition={JSON.stringify(packet) !== JSON.stringify(request)}><Fail message="The saved completion request differs from the original review." /></If>
<Ticket.Text path={directory + "/outcome.json"} as="savedOutcome" />
<Parse schema={{type:"object"}} as="returned">{savedOutcome}</Parse>
<Ticket.Text path={directory + "/raw.txt"} as="reply" />
<If condition={JSON.stringify(returned.reviewer) !== JSON.stringify(props.reviewer) || JSON.stringify(returned.catalog) !== JSON.stringify(props.catalog) || returned.turn?.state !== "reply" || returned.turn.reply !== reply}><Fail message="The completion reply differs from its retained reviewer outcome." /></If>
<Ticket.Text path={directory + "/source-before.json"} as="beforeText" />
<Ticket.Text path={directory + "/source-after.json"} as="afterText" />
<Parse schema={sourceSchema} as="before">{beforeText}</Parse>
<Parse schema={sourceSchema} as="after">{afterText}</Parse>
<SafeParse schema={schemas.progress} as="progress">{reply}</SafeParse>
<If condition={progress.ok}><Fail message="The reviewer is still unfinished after its one completion turn. Preserve both replies and hold." /></If>
<Return value={reply} />
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ returns: {type: object}
<If condition={new Set(policy.acceptance.map(clause => clause.id)).size !== policy.acceptance.length || policy.acceptance.some(clause => !props.task.inputs.includes(clause.source))}>
<Fail message={"Give acceptance clauses distinct IDs and select each original source in task.inputs before launch. Duplicate IDs: " + policy.acceptance.map(clause => clause.id).filter((id,index,ids) => ids.indexOf(id) !== index).join(", ") + ". Missing source references: " + [...new Set(policy.acceptance.filter(clause => !props.task.inputs.includes(clause.source)).map(clause => clause.source))].join(", ") + ". No provider prompt began."} />
</If>
<Let as="delivery" value={{work:props.task.work,repository:props.task.repository,directory:props.task.directory + "/delivery",policy,inputs:props.inputs,required:["independent-review","required-ci","main-health"]}} />
<Let as="delivery" value={{work:props.task.work,repository:props.task.repository,directory:props.task.directory + "/delivery",policy,inputs:props.inputs,maxResponseCorrections:props.task.maxResponseCorrections ?? 0,required:["independent-review","required-ci","main-health"]}} />
<Delivery.Selection delivery={delivery} revision={"0".repeat(40)} as="selection" />
<If condition={selection.reviewers.some(entry => Object.values(props.task.sessions).includes(entry.reviewer.session))}><Fail message="Independent review uses a separate conversation from the implementation and feedback roles." /></If>
<Return value={delivery} />
Loading
Loading