Skip to content

Agent Output Schemas

Every PACE agent produces a structured YAML artifact validated against a JSON Schema. These artifacts are stored in .pace/day-N/ and passed as inputs to downstream agents.


Story Card (PRIME)

File: .pace/day-N/story-card.yaml

day: 1
agent: PRIME
theme: "User model and password hashing"
stories:
- title: "Secure user creation"
acceptance_criteria:
- "User.create() stores bcrypt-hashed password"
- "User.verify_password() returns True for correct password"
out_of_scope:
- "OAuth / social login"
FieldTypeDescription
dayintegerDay number
agentstringAlways "PRIME"
themestringDay theme from plan.yaml
storieslistOne or more story objects
stories[].titlestringStory title
stories[].acceptance_criterialist[string]Testable conditions
stories[].out_of_scopelist[string]Explicitly deferred items

Handoff Note (FORGE)

File: .pace/day-N/handoff.yaml

day: 1
agent: FORGE
commit: "a3f9c12d8e4b..."
approach: "Added User dataclass with bcrypt password hashing via passlib."
risk: "bcrypt rounds set to 12 — acceptable for auth latency."
dependencies: "passlib[bcrypt] added to requirements.txt"
built: "src/models/user.py — User.create(), User.verify_password()"
edge_cases_tested:
- "Wrong password returns False"
- "Empty password raises ValueError"
known_gaps: []
tdd_red_phase_confirmed: true
iterations_used: 18

Fields written by FORGE (via complete_handoff tool):

FieldTypeDescription
commitstringFull git commit SHA of the implementation
approachstringNarrative of the implementation strategy
riskstringKnown risks or trade-offs in this implementation
dependenciesstringNew packages or services introduced
builtstringFiles and public symbols created or modified
edge_cases_testedlist[string]Edge cases explicitly covered by tests
known_gapslist[string]Acceptance criteria deferred or not fully met

Fields injected by the framework (not generated by the LLM):

FieldTypeDescription
dayintegerDay number
agentstringAlways "FORGE"
tdd_red_phase_confirmedbooleantrue when confirm_red_phase was called; false when tdd_enforcement is off
iterations_usedintegerNumber of LLM calls made before complete_handoff fired. Use this to tune forge.max_iterations.

Gate Report (GATE)

File: .pace/day-N/gate-report.yaml

day: 1
agent: GATE
criteria_results:
- criterion: "User.create() stores bcrypt-hashed password"
result: PASS
evidence: "tests/test_user_model.py::test_create_hashes_password PASSED"
- criterion: "CI pipeline green"
result: PARTIAL
evidence: "CI not yet configured — mapped to out_of_scope"
blockers: []
deferred:
- "CI pipeline — not yet configured in this sprint"
gate_decision: SHIP
hold_reason: ""
FieldTypeValuesDescription
dayintegerDay number
agentstring"GATE"
criteria_resultslistOne entry per acceptance criterion
criteria_results[].criterionstringExact criterion text
criteria_results[].resultstringPASS, PARTIAL, FAILVerdict for this criterion
criteria_results[].evidencestringTest name, log line, CI URL, or code reference
blockerslist[string]Human-readable description of each FAIL
deferredlist[string]PARTIAL items mapped to out_of_scope
gate_decisionstringSHIP, HOLDDay decision
hold_reasonstringActionable instruction for FORGE when HOLD

Sentinel Report (SENTINEL)

File: .pace/day-N/sentinel-report.yaml

day: 1
agent: SENTINEL
findings:
- check: "Hardcoded secrets in source files"
result: PASS
evidence: "Secret pattern scan returned no results"
- check: "HTTP timeout on external API calls"
result: ADVISORY
evidence: "src/clients/payment.py:42 — requests.get() with no timeout parameter"
advisories:
- "No timeout on requests.get() in payment.py:42 — add timeout=30"
blockers: []
sentinel_decision: ADVISORY
hold_reason: ""
FieldTypeValuesDescription
dayintegerDay number
agentstring"SENTINEL"
findingslistOne entry per security/SRE check
findings[].checkstringWhat was checked
findings[].resultstringPASS, ADVISORY, FAILCheck verdict
findings[].evidencestringFile path, line number, or test name
advisorieslist[string]Non-blocking findings (one per ADVISORY result)
blockerslist[string]Exploitable vulnerabilities (one per FAIL result)
sentinel_decisionstringSHIP, HOLD, ADVISORYDay decision
hold_reasonstringActionable instruction for FORGE when HOLD

Conduit Report (CONDUIT)

File: .pace/day-N/conduit-report.yaml

day: 1
agent: CONDUIT
findings:
- check: "Action version pinning"
result: ADVISORY
evidence: ".github/workflows/ci.yml uses actions/checkout@master"
- check: "Test gate in CI"
result: PASS
evidence: "ci.yml job 'test' runs pytest before any deploy step"
advisories:
- "actions/checkout@master in ci.yml — pin to @v4"
blockers: []
conduit_decision: ADVISORY
hold_reason: ""
FieldTypeValuesDescription
dayintegerDay number
agentstring"CONDUIT"
findingslistOne entry per DevOps check
findings[].checkstringWhat was checked
findings[].resultstringPASS, ADVISORY, FAILCheck verdict
findings[].evidencestringWorkflow file name, step name, Makefile target
advisorieslist[string]Non-blocking findings
blockerslist[string]Broken CI or leaked secrets (FAIL)
conduit_decisionstringSHIP, HOLD, ADVISORYDay decision
hold_reasonstringActionable instruction for FORGE when HOLD

Cycle Cost Record

File: .pace/day-N/cycle.md

Written by the orchestrator on SHIP (after all agents pass). Contains the total pipeline cost for the day.

day: 1
cycle_cost_usd: 2.8431
forge_cost_usd: 2.3105
generated_at: "2026-03-13T05:47:11Z"
FieldTypeDescription
dayintegerDay number
cycle_cost_usdfloatTotal cost of the full PRIME → FORGE → GATE → SENTINEL → CONDUIT pipeline for this day
forge_cost_usdfloatFORGE-only cost (subset of cycle_cost_usd)
generated_atstringISO-8601 UTC timestamp when the cycle completed

Run Attempts Log

File: .pace/day-N/attempts.yaml

Appended to after every pipeline run (SHIP or HOLD), including retries. Provides a complete cost history for each day, making retry costs visible in PROGRESS.md.

- run: 1
date: "2026-03-13T04:12:33Z"
cost_usd: 3.4821
outcome: HOLD
hold_reason: "GATE HOLD: CI timed out waiting for check-runs"
- run: 2
date: "2026-03-13T05:47:11Z"
cost_usd: 3.1054
outcome: SHIP
FieldTypeDescription
runintegerAttempt number (1-based)
datestringISO-8601 UTC timestamp for this attempt
cost_usdfloatFull LLM spend for this run (all agents)
outcomestringSHIP or HOLD
hold_reasonstringFirst 120 characters of the hold reason (only present on HOLD)

PROGRESS.md shows $X.XX (Nx) in the Actual Cost column when N > 1, and the Cost Summary includes “Total actual (incl. retries)” and “Wasted on retries” rows.


Decision semantics

DecisionMeaningDay advances?
SHIPNo failures or advisoriesYes
ADVISORYNo failures, but concerns worth trackingYes (advisory stored)
HOLDAt least one blocking failureNo (FORGE must fix)

For GATE specifically, PARTIAL in criteria_results means a criterion was not fully met but maps to an out_of_scope item — GATE can still issue SHIP or ADVISORY if all non-deferred criteria pass.