Goal Evidence Ledger
Contract
Iron law: no AC transitions to pass without a FlowEvidence sidecar whose proves: [<AC.id>] names it, and every non-trivial sidecar declares what it does NOT prove. Invoked by goal-evaluator (Step 2, once per verification command), by /flow:start Phase 4 and /flow:address (verification-evidence sidecars on the FlowRun), and by /flow:goal evaluate for judge reports. Inputs: evidence id, type, proves list, and optional command, exit code, raw-output path, limitations, negative cases. Returns the sidecar path, which the caller sets as the AC's evidence_ref. Permitted skips: limitations on holdout_validation and verdict types; the raw .txt when nothing was captured. The helper is never skipped.
Inputs
- Evidence id —
evidence-<AC.id>-<descriptor>-<turn>; lowercase, digits, _-.
- Evidence type — one of
evidence.schema.json's enum: command_result, test_result, lint_result, runtime_smoke_result, visual_result, git_diff, holdout_validation, verdict, human_approval, review_comment_snapshot, ci_status, llm_judge_report, artifact_check, path_boundary_check.
- Proves — AC ids this evidence supports.
- Optional:
command, exit_code, raw output path, limitations, negative_cases.
Outputs
.flow/runs/<run-id>/evidence/<evidence-id>.evidence.yaml (schema plugins/flow/schemas/v1/evidence.schema.json).
.flow/runs/<run-id>/evidence/<evidence-id>.txt — raw stdout/stderr when captured.
- An
evidence-captured journal artifact.
- One line appended to
.flow/runs/<run-id>/events.jsonl.
Workflow
Step 1: Compose
apiVersion: flow.synapti.ai/v1
kind: FlowEvidence
metadata:
id: <evidence-id>
goal: <goal-id>
run_id: <run-id>
activity_id: <activity-id, if any>
created_at: <ISO-8601 UTC>
evidence:
type: <enum-value>
command: <bash command, if applicable>
exit_code: <captured, if command type>
output_ref: <relative path to .txt, if captured>
proves:
- <AC.id>
limitations:
- <what this evidence does NOT prove>
negative_cases:
- <adversarial or boundary cases exercised>
Step 2: Negative space
| Evidence type |
Required |
command_result, test_result, lint_result, visual_result, llm_judge_report |
limitations |
runtime_smoke_result |
limitations + negative_cases |
holdout_validation, verdict |
none — the verdict format owns its negative space |
The schema rejects a command_result without limitations at write time.
Step 3: Write
bin/flow-record-evidence.sh --run-id <run-id> --evidence-file <composed.yaml> [--raw-output <stdout-capture>]
The helper writes atomically (tempfile + rename via _journal_atomic.py), refuses symlinked targets and lockfiles, validates the schema when jsonschema is installed, and copies the raw output next to the sidecar. Surface any non-zero exit with its stderr.
Step 4: Journal
bin/journal-record.sh --issue {N} --type evidence-captured --metadata evidence_id=<id> --metadata goal_id=<goal-id> --metadata proves=<comma-list of AC ids>
Step 5: Link
The caller updates the AC in .flow/goals/<id>.goal.yaml: status: evidence_collected, evidence_ref: .flow/runs/<run-id>/evidence/<evidence-id>.evidence.yaml, last_evaluated_at: <now>.
Rules
- Evidence is append-only: a correction is a new sidecar (
evidence-AC1-retest-turn2) and the AC's evidence_ref moves to it; the old sidecar stays as audit trail.
- One run proving two ACs is one sidecar with
proves: [AC1, AC2].
- Capture evidence before the verdict; never after the goal is
achieved.
- Never write a sidecar with
echo >; the helper is the only writer.
References
plugins/flow/skills/evidence-based-development/SKILL.md — the ASSERTION/EVIDENCE/VERIFIED discipline this ledger materializes.
plugins/flow/references/evidence-bundle-format.md — the bundle layout the judge consumes.
1---2name: goal-evidence-ledger3description: Maintain the append-only evidence ledger: `.flow/runs/<run-id>/evidence/*.evidence.yaml` sidecars plus matching `.txt` raw captures, written only via `bin/flow-record-evidence.sh`. Use when goal-evaluator runs a verification command, when /flow:start or /flow:address captures verification evidence on a FlowRun, or when /flow:goal evaluate produces a judge report. Evidence that lives only in the transcript dies with the session; only file-backed, schema-validated sidecars prove ACs durably and satisfy the judge's Independence Protocol.4---56# Goal Evidence Ledger78## Contract910Iron law: no AC transitions to `pass` without a FlowEvidence sidecar whose `proves: [<AC.id>]` names it, and every non-trivial sidecar declares what it does NOT prove. Invoked by `goal-evaluator` (Step 2, once per verification command), by `/flow:start` Phase 4 and `/flow:address` (verification-evidence sidecars on the FlowRun), and by `/flow:goal evaluate` for judge reports. Inputs: evidence id, type, proves list, and optional command, exit code, raw-output path, limitations, negative cases. Returns the sidecar path, which the caller sets as the AC's `evidence_ref`. Permitted skips: `limitations` on `holdout_validation` and `verdict` types; the raw `.txt` when nothing was captured. The helper is never skipped.1112## Inputs13141. **Evidence id** — `evidence-<AC.id>-<descriptor>-<turn>`; lowercase, digits, `_-`.152. **Evidence type** — one of `evidence.schema.json`'s enum: command_result, test_result, lint_result, runtime_smoke_result, visual_result, git_diff, holdout_validation, verdict, human_approval, review_comment_snapshot, ci_status, llm_judge_report, artifact_check, path_boundary_check.163. **Proves** — AC ids this evidence supports.174. Optional: `command`, `exit_code`, raw output path, `limitations`, `negative_cases`.1819## Outputs20211. `.flow/runs/<run-id>/evidence/<evidence-id>.evidence.yaml` (schema `plugins/flow/schemas/v1/evidence.schema.json`).222. `.flow/runs/<run-id>/evidence/<evidence-id>.txt` — raw stdout/stderr when captured.233. An `evidence-captured` journal artifact.244. One line appended to `.flow/runs/<run-id>/events.jsonl`.2526## Workflow2728### Step 1: Compose2930```yaml31apiVersion: flow.synapti.ai/v132kind: FlowEvidence33metadata:34 id: <evidence-id>35 goal: <goal-id>36 run_id: <run-id>37 activity_id: <activity-id, if any>38 created_at: <ISO-8601 UTC>39evidence:40 type: <enum-value>41 command: <bash command, if applicable>42 exit_code: <captured, if command type>43 output_ref: <relative path to .txt, if captured>44 proves:45 - <AC.id>46 limitations:47 - <what this evidence does NOT prove>48 negative_cases:49 - <adversarial or boundary cases exercised>50```5152### Step 2: Negative space5354| Evidence type | Required |55|---|---|56| `command_result`, `test_result`, `lint_result`, `visual_result`, `llm_judge_report` | `limitations` |57| `runtime_smoke_result` | `limitations` + `negative_cases` |58| `holdout_validation`, `verdict` | none — the verdict format owns its negative space |5960The schema rejects a `command_result` without `limitations` at write time.6162### Step 3: Write6364```bash65bin/flow-record-evidence.sh --run-id <run-id> --evidence-file <composed.yaml> [--raw-output <stdout-capture>]66```6768The helper writes atomically (tempfile + rename via `_journal_atomic.py`), refuses symlinked targets and lockfiles, validates the schema when `jsonschema` is installed, and copies the raw output next to the sidecar. Surface any non-zero exit with its stderr.6970### Step 4: Journal7172```bash73bin/journal-record.sh --issue {N} --type evidence-captured --metadata evidence_id=<id> --metadata goal_id=<goal-id> --metadata proves=<comma-list of AC ids>74```7576### Step 5: Link7778The caller updates the AC in `.flow/goals/<id>.goal.yaml`: `status: evidence_collected`, `evidence_ref: .flow/runs/<run-id>/evidence/<evidence-id>.evidence.yaml`, `last_evaluated_at: <now>`.7980## Rules8182- Evidence is append-only: a correction is a new sidecar (`evidence-AC1-retest-turn2`) and the AC's `evidence_ref` moves to it; the old sidecar stays as audit trail.83- One run proving two ACs is one sidecar with `proves: [AC1, AC2]`.84- Capture evidence before the verdict; never after the goal is `achieved`.85- Never write a sidecar with `echo >`; the helper is the only writer.8687## References8889- `plugins/flow/skills/evidence-based-development/SKILL.md` — the ASSERTION/EVIDENCE/VERIFIED discipline this ledger materializes.90- `plugins/flow/references/evidence-bundle-format.md` — the bundle layout the judge consumes.