Claude
Skills
Sign in
Back

goal-contract-capture

Included with Lifetime
$97 forever

Capture a FlowGoal contract as a project-local `.flow/goals/<id>.goal.yaml` file with outcome, acceptance criteria (with verification commands), specification elements (non-goals, failure modes, interface contracts), constraints, evaluator binding, continuation policy, and lifecycle frontmatter. Use when /flow:start passes the Spec Validation Gate, when /flow:goal create is invoked, or when /flow:review and /flow:address need a completion contract for a PR. This skill MUST be consulted because acceptance criteria alone do not constitute a contract — without an evaluator binding, boundaries, and lifecycle state, downstream phases cannot detect premature completion, the Stop hook cannot enforce evidence, and goals cannot resume across sessions.

Code Review

What this skill does


# Goal Contract Capture

You produce a FlowGoal contract — a durable completion contract that turns acceptance criteria + specification into a machine-readable, file-backed artifact. This skill is the 5th invoker of the existing `specification-capture` pattern; it wraps that skill (does NOT replace it) and adds the goal-specific fields needed for evaluator/Stop-hook enforcement.

## Iron Law

**No `/flow:goal create` without a complete contract. No `.flow/goals/<id>.goal.yaml` without an evaluator binding. The contract is the source of truth for the Stop hook and `/flow:goal evaluate`; gaps here cascade into silent premature completion.**

## Relationship to existing skills

This skill is a **wrapper**, not a fork:

| Existing skill | What it gives us | What this skill adds |
|---|---|---|
| `specification-capture` | non-goals, failure modes, interface contracts | the `specification` block in the goal YAML |
| `criterion-verification-map` | per-AC verification commands + expected evidence | the `objective.acceptance_criteria[].verification_command` field |
| `evidence-based-development` | ASSERTION/EVIDENCE/VERIFIED discipline | the `evidence_ref` linking the AC back to a FlowEvidence sidecar |

If those skills have already produced their outputs (decision journal manifest entries), this skill **reads from them** rather than re-asking the user.

## Inputs

The invoking command MUST pass:

1. **Goal id** — typically `issue-{N}`, `pr-{N}-review`, `pr-{N}-address`, or an ad-hoc slug. Validated against the schema's `^[a-z0-9][a-z0-9-]{0,63}$` pattern.
2. **Scope** — `repo`, `branch`, optionally `issue` and/or `pr`, optionally a `journal` path (`.decisions/issue-{N}.md`).
3. **Source** — typically the GitHub issue body (parsed for AC) or the PR description (parsed for review/address scope).
4. **Invocation reason** — `start | goal-create | review | address`. Used to choose the right outcome template and the right `evaluator.type`.

## Outputs

Single file: `.flow/goals/<id>.goal.yaml` conforming to `plugins/flow/schemas/v1/goal.schema.json`. Written via `bin/flow-goal-record.sh` (atomic, O_NOFOLLOW-defended).

Plus: one `goal-created` artifact appended to the linked decision journal via `bin/journal-record.sh --type goal-created --metadata goal_id=<id> --metadata source=<src>`.

## Workflow

1. **Pre-flight check** — refuse if `.flow/goals/<id>.goal.yaml` already exists and `lifecycle.status` is not in `{cancelled, failed}`. Surface the existing goal to the user via the six-field escalation; never silently overwrite an active goal.

2. **Compose `metadata`**:
   ```yaml
   metadata:
     id: <derived-from-invocation>
     created_at: <ISO-8601 UTC now>
     created_by: <invoking command, e.g. /flow:start>
     owner: <git user.email or @me>
   ```

3. **Compose `scope`** — from inputs. Set `journal` to the linked decision journal path. Leave `run_id` empty until `run-state-management` wires FlowRun creation.

4. **Compose `objective`** — pull AC text + verification commands from the existing `criterion-verification-map` output. Each AC is one entry with `status: pending` and `evidence_ref: null` initially. The `outcome` is a one-sentence statement derived from invocation reason:
   - `start` → "Issue #{N} is implemented and verified."
   - `goal-create` → user-supplied via AskUserQuestion.
   - `review` → "PR #{N} review completed with findings posted or no-finding evidence recorded."
   - `address` → "All unresolved findings on PR #{N} are resolved, commented, or escalated."

5. **Compose `specification`** — lift from `specification-capture`'s journal entries:
   - `non_goals` from the `## Specification > ### Non-goals` body
   - `failure_modes` from `### Failure modes`
   - `interface_contracts` from `### Interface contracts`

   If any block is empty, raise the six-field escalation per `references/escalation-format.md` — do NOT silently fill with placeholders.

6. **Compose `constraints`** — default to `tdd_required: true`, `require_all_pass: true`, `no_calendar_estimates: true`, `no_tier3_without_confirmation: true`. Add `denied_paths` from settings (`flow.goals.denied_paths` cascade key); add `allowed_paths` only if the goal narrows the tier model (e.g., a focused refactor).

7. **Compose `evaluator`**:
   ```yaml
   evaluator:
     type: flow_verdict_judge          # hybrid for fuzzy criteria; deterministic for command-only
     command: /flow:goal evaluate
     judge_agent: goal-evaluator-judge
     evidence_bundle_format: plugins/flow/references/evidence-bundle-format.md
     denied_context:
       - implementation_rationale
       - self_review_findings
   ```

8. **Compose `continuation`** — defaults: `mode: flow_managed`, `on_incomplete: continue_next_activity`, `on_blocked: six_field_escalation`, `on_complete: mark_achieved`, `max_iterations: <from settings, default 20>`.

9. **Compose `lifecycle`** — initial state:
   ```yaml
   lifecycle:
     status: active
     current_phase: <derived; start→explore, review→fan-out, address→categorize>
     current_activity: <first activity id>
     turns_evaluated: 0
     last_evaluation:
       result: incomplete
       reason: "Goal created; evidence not yet collected."
       at: <now>
   ```

10. **Write atomically** — call `bin/flow-goal-record.sh` with the composed YAML. Verify exit 0; surface stderr on any failure.

11. **Record journal artifact** — `bin/journal-record.sh --issue {N} --type goal-created --metadata goal_id=<id> --metadata source=<src>`.

12. **Verify the artifact** — read back `.flow/goals/<id>.goal.yaml` and validate against the schema (Python jsonschema if available). A schema mismatch here means the skill or the schema is broken; fail hard.

## Per-invoker scope

| Invoker | Captures | Skips |
|---|---|---|
| `start` | All blocks; outcome derived from issue title | nothing |
| `goal-create` | All blocks; outcome from AskUserQuestion | journal manifest if no issue |
| `review` | Outcome + AC (= review checklist) + constraints | specification (use issue's existing capture) |
| `address` | Outcome + AC (= one per unresolved PR comment) + constraints | specification (inherit from review goal) |

## Anti-patterns

- ❌ Silently overwriting an active goal — always surface and escalate.
- ❌ Filling in empty specification blocks with placeholders — escalate via six-field.
- ❌ Bypassing `bin/flow-goal-record.sh` for "speed" — atomicity + symlink defense matters.
- ❌ Setting `lifecycle.status: achieved` at creation — the only way to `achieved` is through `/flow:goal evaluate`.

## Reuse map

- `plugins/flow/skills/specification-capture/SKILL.md` — read the per-invoker scope table; this skill adds row 5 (`goal-create`).
- `plugins/flow/skills/criterion-verification-map/SKILL.md` — read for the AC verification-command shape.
- `plugins/flow/schemas/v1/goal.schema.json` — the canonical schema this skill writes against.
- `plugins/flow/bin/flow-goal-record.sh` — atomic writer.
- `plugins/flow/bin/journal-record.sh` — for the `goal-created` manifest artifact.
- `plugins/flow/references/escalation-format.md` — six-field escalation for any empty/ambiguous block.

Related in Code Review