Files
msd-core/gsd-core/references/agent-contracts.md
Cody Anderson 8c9265d4e5 fix(#3724): warning-only Dimension 3b findings no longer force the revision loop (#3758)
* fix(#3724): stop advisory Dimension 3b findings from forcing the revision loop

Dimension 3b (undeclared/temporal coupling, #1954) is spec'd "never a
blocker" but tagged severity: warning — the tier plan-phase's revision
loop counts as must-fix — and the planner is never taught the rule, so
every multi-wave phase touching shared mutable state replans at least
once, and intentionally coupled plans re-flag identically every
iteration to the stall prompt.

Three coordinated changes:
- gsd-plan-checker: retag 3b to severity: info, the tier
  references/revision-loop.md already exempts by design; recognize a
  coupling_justified frontmatter declaration in the Do-NOT-flag list so
  deliberate pairs converge. Additions are offset by trimming 3b
  motivation prose — the checker sits 45 bytes under its LARGE hard cap.
- plan-phase step 12: INFO-only accept — an issues block with zero
  BLOCKER/WARNING entries accepts the plan and surfaces the advisories
  instead of re-entering the revision loop. Real blockers and warnings
  still gate unconditionally.
- gsd-planner: slim pointer in assign_waves to the new
  progressive-disclosure reference gsd-core/references/planner-coupling.md
  (the planner sits 19 chars under its own cap), which carries the
  shared-mutable-state rule and the coupling_justified escape hatch so
  first-pass plans avoid the finding when the coupling is unintentional.

Documented the coupling_justified field in docs/reference/plan-md.md.
Growth acks per #2914; inventory manifest and install-tree fixtures
regenerated for the new reference file.

Closes #3724

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* test(#3724): pin Dimension 3b at severity: info

The severity retag makes the old assertion (severity: warning) stale;
lock the advisory tier from both directions — info must be present,
warning must not — so a future edit cannot silently re-arm the
revision-loop trigger.

Refs #3724

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* chore(#3724): changeset fragment for PR #3758

Refs #3724

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* docs(#3724): roster planner-coupling.md in docs/INVENTORY.md

The new reference was enumerated in the manifest and all 19 install-tree
fixtures but missing its row in the Modular Planner Decomposition table —
the roster half the manifest-sync test cannot check. (Review Blocker.)

Refs #3724

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* test(#3724): cover all four acceptance criteria (review round 1)

- plan-checker-coupling: the 3b severity assertion is now a PARITY check
  deriving the exempt tier from revision-loop.md's flow instead of
  hardcoding info — editing either side alone reds the suite. New
  describe pins the other three criteria: plan-phase's INFO-only accept
  clause (proven failing-first), the BLOCKER + WARNING count staying
  intact, the coupling_justified Do-NOT-flag exemption + fix_hint, and
  the planner pointer + planner-coupling.md content.
- ack fragment: $comment's plan-phase figure corrected to +79B; the 2775
  pin note carried forward into the gsd-planner.md entry, updated for
  upstream's #3761/#3764 Rule-paragraph anchor (which this diff leaves
  verbatim).

The parallel-dependent-plans re-anchor this commit originally carried was
superseded by upstream #3764 during review; this branch no longer touches
that file.

Refs #3724

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* fix(#3724): review round 2 — align the stance enumeration, complete the template contract

MAJOR: <adversarial_stance>'s severity enumeration gains the INFO bullet so it
agrees with Dimension 3b's 'ALWAYS INFO' mandate instead of contradicting it.
Funded by extracting the inline <examples> block to the new progressive-
disclosure reference gsd-core/references/plan-checker-examples.md (@-inlined
from the same spot; #1949 precedent), which also restores the 3b motivation
clause round 1 traded away (Nit 4) and nets the agent file SMALLER than base
(49107 -> 48486) — the extraction the byte pressure was owed.

MINOR: gsd-core/templates/phase-prompt.md now carries coupling_justified, and
the field's shape becomes one 'plan-id: reason' string per coupled peer so a
plan justified against two peers can express it; docs/reference/plan-md.md's
Type column names the shape.

NIT: the 3409 ack's plan-phase entry no longer calls the #1168 workflow
ratchet an 'XL tier'.

Acks and derived artifacts updated accordingly (checker entry removed — a
shrink needs no ack; INVENTORY roster row + regen:derived for the new file).

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* test(#3724): derive the 3b negative severity assertion (review round 2)

Every severity token in the 3b span must BE the tier revision-loop.md exempts,
replacing the hardcoded severity:warning negative — if the loop's exemption
ever moves, the failure names the real conflict instead of blaming the agent
file with a mutually-unsatisfiable pair.

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* fix(#3724): refit the planner coupling pointer under the char cap

Upstream #3299 (PR #3390) grew agents/gsd-planner.md to 49146 chars at the
base, leaving 5 chars of headroom where the +16-char pointer was measured
against 13 more. The pointer prose shortens to 'Non-file coupling:' —
49150 chars, back under the strict 49152-char cap — and the ack figures
follow. The @-path the tests pin is unchanged.

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* fix(#3724): re-home the plan-phase ack after the #3823 spent-fragment sweep

Upstream #3078/#3823 deleted all fully-spent ack fragments, including
3409-unreachable-guard-arms.json, which carried this PR's plan-phase.md
+79B append. Per the collision remedy that sweep added: take the deletion
and home the still-live entry in this PR's own fragment. Figures
re-measured at this merge base (90871 -> 90950 LF bytes).

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* fix(#3724): absorb the spent #3172 plan-phase fragment into this PR's ack

Upstream #3825 shipped 3172-stated-failing-direction.json naming only
plan-phase.md, now spent at the base — colliding with this PR's live
plan-phase entry. Per the #3003 pattern the fully-spent single-path
fragment is deleted and this fragment stays the path's one source;
figures re-measured at this base (93073 -> 93152 LF bytes).

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* fix(#3724): review round 3 — true up the ack figures, restore the wave comment

The fragment's absolute sizes are re-measured and anchored to base
e40e9670 (planner 47259 -> 47330 chars, checker 45537 -> 44916 B,
plan-phase 91186 -> 91265 LF bytes), with a note that absolutes rot as
next moves — the deltas are the durable claims. The round-1 removal of
the '# Implicit dependency: files_modified overlap forces a later wave.'
pseudocode comment offset headroom base drift had already returned, so
it is restored (findings 2-3). Changeset gains the (#3724) backlink
(finding 4).

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* fix(#3724): review round 4 — close the verify-work surface, harden the boundaries

BLOCKER: verify-work.md's verify_gap_plans is the second multi-plan
consumer of the checker's sentinels, and its ISSUES FOUND handler entered
revision_loop with zero severity parsing — the guaranteed replan #3724
fixed in plan-phase, alive on the gap-closure surface. The handler now
counts BLOCKER + WARNING and accepts INFO-only returns with advisories
displayed. The checker's INFO stance bullet is reworded to the claim that
is true everywhere ('revision gates count only BLOCKER + WARNING').

Minor 1: plan-phase's iteration_count >= 3 arm recounts severities, so an
INFO-only third check accepts instead of halting on a '0 issues remain'
user gate. Minor 2: the coupling_justified exemption now requires the
entry to NAME the other plan, closing the blanket-suppression reading.
Nit 1: INVENTORY row states the extraction buys cap headroom, not context.
Nit 2: the advisory display gains a concrete format on both surfaces.

Ack fragment re-anchored at base ddde001a: verify-work.md +264B (new
entry), plan-phase.md +395B, checker still net negative (-512B).

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* test(#3724): pin the verify-work accept and the iteration-cap boundary (review round 4)

Two wiring assertions: verify_gap_plans' ISSUES FOUND handler gates on
BLOCKER + WARNING and accepts INFO-only blocks, and plan-phase's
iteration_count >= 3 arm recounts severities instead of gating advisories
— the limit+1 boundary of the gate this PR fixes.

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* fix(#3724): review round 5 — fail closed at the gates, surface the advisory

Blocker 1: the checker's step-10 status rule routes an INFO-only result to
## ISSUES FOUND (with a new ### Advisories (info) template section and a
severity-aware recommendation) so the orchestrator receives the block and
displays the advisory instead of silently accepting a bare PASSED.

Blockers 2+3: all three gate surfaces (plan-phase step 12 both arms,
verify-work verify_gap_plans) carry one canonical clause verbatim — an entry
whose severity is missing or unrecognized counts as a BLOCKER (fail closed) —
making the accept condition an explicit-INFO whitelist while keeping
issue_count coherent for stall math.

Major 1: the INFO stance bullet scopes its claim to the plan-phase and
verify-work gates (quick mode's loop still revises on any ISSUES FOUND).
Major 2: INVENTORY row and ack $comment state the extraction's real trade
(readability, +0.6 KB eager runtime context), not a cap remedy.
Minor 1: plan-md.md marks coupling_justified as prompt convention, unvalidated.
Nit 1: ack absolutes re-anchored at base 1e67ec97; checker now +120B and acked.

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* test(#3724): pin the round-5 contract — fail-closed parity, INFO-only return shape

New: three-surface verbatim parity test for the fail-closed clause (Blockers
2+3); checker return-contract test for the INFO-only ## ISSUES FOUND route and
advisories section (Blocker 1). All seven newly pinned tokens are absent at
f3a5682d, so each new assertion fails pre-fix.

Updated: accept-clause regexes track the explicit-INFO whitelist wording;
the severity sweep scopes to the span's fenced yaml examples via
yamlSeverityTiers (round-5 Minor 3, applied to the blocker negative too);
the iteration-cap comment states it is a prose pin, not an executed boundary
check (Minor 4); splitLines call sites document the line-pin coupling (Nit 2).

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* fix(#3724): adopt next's line wrap in the 3b motivation clause — drops a wrap-only hunk from the diff

Byte-identical content; the wrap difference was an artifact of the round-1
base adaptation predating upstream's #3003 landing.

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

* fix(#3724): review round 7 — gate every checker consumer, not just the two audited ones

Blocker: quick/steps/plan-checker-loop.md (issue-named in #3724) gets the
same canonical fail-closed clause and explicit-INFO whitelist accept as
plan-phase/verify-work — an INFO-only result proceeds instead of entering
quick mode's revision loop.
Major: import.md plan_validate handles the checker return by severity
(INFO-only never blocks an import) and is added to agent-contracts.md's
consumer enumeration, which had omitted it.
The checker's INFO stance bullet drops the quick-mode carve-out — the claim
is universally true again now that every consuming gate is severity-aware.
Minor: an applied coupling_justified exemption is surfaced as its own info
advisory so a stale one-sided declaration stays observable.
Nit: plan-phase's revision-iteration Display line is explicitly conditioned
on not having already proceeded to step 13.

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM
Emitted-Drift-Ack-Growth: import.md — #3724 round 7: the plan_validate step's checker-return handler becomes severity-aware — counts BLOCKER + WARNING failing closed and accepts an explicitly-INFO-only return with advisories displayed instead of blocking the import

* test(#3724): pin the round-7 surfaces — five-gate parity, quick/import accepts, exemption visibility

The verbatim fail-closed parity test extends to quick/steps/plan-checker-loop.md
and import.md plan_validate; new assertions pin quick mode's INFO-only proceed,
import's never-blocks accept, import.md's presence in agent-contracts.md's
consumer row, and the surfaced coupling_justified exemption advisory. All four
newly pinned token families are absent at the pre-fix head, so each new
assertion fails first.

Claude-Session: https://claude.ai/code/session_01GshUzpGjoxiw6uNRiFMHvM

---------

Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
2026-08-31 19:08:11 -04:00

13 KiB

Agent Contracts

Completion markers and handoff schemas for all GSD agents. Workflows use these markers to detect agent completion and route accordingly.

This doc describes what IS, not what should be. Casing inconsistencies are documented as they appear in agent source files.


Agent Registry

Agent Role Completion Markers Consumed by Kind
gsd-ai-researcher AI framework research No marker (writes the AI-SPEC.md framework section via Edit) gsd-core/workflows/ai-integration-phase.md reads the AI-SPEC.md section after the agent returns artifact+query
gsd-planner Plan creation ## PLANNING COMPLETE, ## OUTLINE COMPLETE, ## PHASE SPLIT RECOMMENDED, ## ⚠ Source Audit, ## CHECKPOINT REACHED, ## PLANNING INCONCLUSIVE gsd-core/workflows/plan-phase.md, gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md, gsd-core/workflows/plan-review-convergence.md, gsd-core/workflows/quick.md sentinel-match
gsd-executor Plan execution ## PLAN COMPLETE, ## CHECKPOINT REACHED gsd-core/workflows/plan-phase.md, gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md, agents/gsd-debug-session-manager.md, agents/gsd-debugger.md sentinel-match
gsd-phase-researcher Phase-scoped research ## RESEARCH COMPLETE, ## RESEARCH BLOCKED gsd-core/workflows/plan-phase.md, gsd-core/workflows/quick/steps/research-phase.md, agents/gsd-project-researcher.md sentinel-match
gsd-project-researcher Project-wide research ## RESEARCH COMPLETE, ## RESEARCH BLOCKED gsd-core/workflows/plan-phase.md, gsd-core/workflows/quick/steps/research-phase.md, agents/gsd-phase-researcher.md sentinel-match
gsd-plan-checker Plan validation ## VERIFICATION PASSED, ## ISSUES FOUND gsd-core/workflows/plan-phase.md, gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md, gsd-core/workflows/quick/steps/plan-checker-loop.md, gsd-core/workflows/import.md, gsd-core/workflows/ui-phase.md, gsd-core/workflows/verify-work.md, agents/gsd-ui-checker.md sentinel-match
gsd-research-synthesizer Multi-research synthesis ## SYNTHESIS COMPLETE, ## SYNTHESIS BLOCKED (unconsumed: blocked-research return — spawners detect failure via the #222 SUMMARY.md-on-disk check, no dispatch branch keys on the marker) gsd-core/workflows/new-milestone.md, gsd-core/workflows/new-project.md sentinel-match
gsd-debugger Debug investigation ## DEBUG COMPLETE, ## ROOT CAUSE FOUND, ## CHECKPOINT REACHED, ## INVESTIGATION INCONCLUSIVE, ## TDD CHECKPOINT, ## FIX REJECTED BY GUARDRAIL agents/gsd-debug-session-manager.md, gsd-core/workflows/diagnose-issues.md, gsd-core/workflows/plan-phase.md, agents/gsd-executor.md sentinel-match
gsd-debug-session-manager Debug checkpoint loop ## DEBUG SESSION COMPLETE, ## CONTINUE_REQUIRED gsd-core/workflows/debug.md sentinel-match
gsd-roadmapper Roadmap creation/revision ## ROADMAP CREATED, ## ROADMAP REVISED, ## ROADMAP BLOCKED gsd-core/workflows/new-milestone.md, gsd-core/workflows/new-project.md sentinel-match
gsd-ui-auditor UI review ## UI REVIEW COMPLETE gsd-core/workflows/ui-review.md sentinel-match
gsd-dom-verifier Live-DOM UAT verification No marker (writes {phase}-DOM-VERIFY.md directly; the frontmatter outcome / reason scalars carry the verdict, and could_not_look is never conflated with nothing_to_report) {phase}-DOM-VERIFY.md artifact, written by the live-dom-uat capability's execute:wave:post step dispatched from gsd-core/workflows/execute-phase.md artifact+query
gsd-ui-checker UI validation ## ISSUES FOUND, ## UI-SPEC VERIFIED gsd-core/workflows/plan-phase.md, gsd-core/workflows/quick/steps/plan-checker-loop.md, gsd-core/workflows/ui-phase.md, gsd-core/workflows/verify-work.md, agents/gsd-plan-checker.md sentinel-match
gsd-ui-researcher UI spec creation ## UI-SPEC COMPLETE, ## UI-SPEC BLOCKED gsd-core/workflows/ui-phase.md sentinel-match
gsd-verifier Post-execution verification ## Verification Complete (unconsumed: Marker Rule 2 recorded decision — intentional title-case marker; completion is detected via the artifact route, nothing matches the marker) *-VERIFICATION.md artifact + gsd_run query verification.status in gsd-core/workflows/verify-work.md artifact+query
gsd-integration-checker Cross-phase integration check ## Integration Check Complete (unconsumed: Marker Rule 2 recorded decision — intentional title-case marker; the auditor reads the inline report, nothing matches the marker) gsd-core/workflows/audit-milestone.md reads the agent's inline return text directly (agent has no Write tool -- it cannot write an artifact) structured-return
gsd-nyquist-auditor Sampling audit ## PARTIAL, ## ESCALATE, ## GAPS FILLED (non-standard) gsd-core/workflows/validate-phase.md, gsd-core/workflows/secure-phase.md, agents/gsd-security-auditor.md sentinel-match
gsd-security-auditor Security audit ## OPEN_THREATS, ## ESCALATE, ## SECURED (non-standard) gsd-core/workflows/secure-phase.md, gsd-core/workflows/validate-phase.md, agents/gsd-nyquist-auditor.md sentinel-match
gsd-codebase-mapper Codebase analysis No marker (writes docs directly) .planning/codebase/*.md artifacts, checked via ls/wc -l in gsd-core/workflows/map-codebase.md artifact+query
gsd-code-fixer Applies code-review fixes No marker (fix commits + REVIEW.md updates) gsd-core/workflows/code-review-fix.md reads REVIEW.md resolution state + git log artifact+query
gsd-code-reviewer Source-code review No marker (writes REVIEW.md) gsd-core/workflows/code-review.md reads REVIEW.md artifact+query
gsd-assumptions-analyzer Assumption extraction No marker (returns ## Assumptions sections) gsd-core/workflows/discuss-phase-assumptions.md reads the inline ## Assumptions sections from the agent's return structured-return
gsd-doc-classifier Planning-doc classification No marker (writes .planning/intel/classifications/*.json) gsd-core/workflows/ingest-docs.md reads the classification JSON artifact+query
gsd-doc-verifier Doc validation No marker (writes JSON to .planning/tmp/) .planning/tmp/verify-{doc_filename}.json artifact, read by gsd-core/workflows/docs-update.md artifact+query
gsd-doc-writer Doc generation No marker (writes docs directly) generated doc files, consumed by gsd-core/workflows/docs-update.md and gsd-core/workflows/docs-update/steps/dispatch-monorepo-packages.md artifact+query
gsd-domain-researcher Domain research No marker (writes the AI-SPEC.md domain section via Edit) gsd-core/workflows/ai-integration-phase.md reads the AI-SPEC.md section after the agent returns artifact+query
gsd-eval-auditor Evaluation coverage audit No marker (writes the REVIEW.md audit section) gsd-core/workflows/eval-review.md reads REVIEW.md artifact+query
gsd-eval-planner Evaluation strategy design No marker (writes the AI-SPEC.md evaluation section via Edit) gsd-core/workflows/ai-integration-phase.md reads the AI-SPEC.md section after the agent returns artifact+query
gsd-framework-selector Framework decision matrix No marker (returns the interactive decision matrix inline) gsd-core/workflows/ai-integration-phase.md reads the returned matrix structured-return
gsd-advisor-researcher Advisory research No marker (utility agent) gsd-core/workflows/discuss-phase/modes/advisor.md reads the inline comparison table from the agent's return structured-return
gsd-user-profiler User profiling No marker (returns JSON in analysis tags) gsd-core/workflows/profile-user.md extracts the inline <analysis> JSON block from the agent's return structured-return
gsd-intel-updater Codebase intelligence analysis No marker (.planning/intel/*.json artifacts) .planning/intel/*.json artifacts, read via gsd_run intel query / intel validate (no *.md workflow currently spawns this agent -- see docs/adr/22-plan-drift-guard.md, "never auto-spawned") artifact+query
gsd-mempalace-curator Ship-time MemPalace curation No marker (writes the session diary + cross-links) gsd-core/workflows/ship.md reads the diary artifacts artifact+query
gsd-pattern-mapper Codebase pattern mapping ## PATTERN MAPPING COMPLETE gsd-core/workflows/plan-phase.md (also spawned by gsd-core/workflows/settings.md) sentinel-match
gsd-doc-synthesizer Doc synthesis for /gsd:ingest-docs No marker (SYNTHESIS.md and INGEST-CONFLICTS.md artifacts) .planning/intel/SYNTHESIS.md and .planning/INGEST-CONFLICTS.md artifacts, read by gsd-core/workflows/ingest-docs.md artifact+query

Marker Rules

  1. ALL-CAPS markers (e.g., ## PLANNING COMPLETE) are the standard convention
  2. Title-case markers in gsd-verifier and gsd-integration-checker are intentional as-is, not bugs — a recorded decision. Their rows are artifact+query/structured-return (completion is detected through the row's Kind route), and the markers are carried as (unconsumed: Marker Rule 2 recorded decision …) annotations: an auditable exemption, never deleted and never silently passed. ## Synthesis Complete in gsd-doc-synthesizer was NOT covered by this rule; #3565 deleted it deliberately because it case-collides with gsd-research-synthesizer's ## SYNTHESIS COMPLETE and nothing matched it
  3. Non-standard markers (e.g., ## PARTIAL, ## ESCALATE) in audit agents indicate partial results requiring orchestrator judgment
  4. Kind describes how a caller actually detects an agent's completion, and is exactly one of:
    • sentinel-match -- a workflow, command, or another agent detects completion by an exact-case string match against a declared marker
    • artifact+query -- the agent writes a file (report, JSON, generated doc) and the caller reads or queries that artifact instead of matching any marker text
    • structured-return -- the agent has no way to write files (no Write tool) or simply doesn't; it returns parseable sections, a table, or JSON inline, and the caller reads that return text directly
  5. Markers must appear as H2 headings (## ) at the start of a line in the agent's final output
  6. The Consumed by / Kind columns are machine-enforced by check:contract-drift (scripts/check-contract-drift.cjs), which cross-checks this table against what each agents/*.md file actually emits in-fence and what every gsd-core/workflows/**, commands/**, and agents/** file actually consumes. Update this table whenever an agent's return contract changes -- a stale row is a violation the check will report, not something to leave for later.
  7. A marker entry annotated (unconsumed: <reason>) is emitted deliberately but matched by no workflow, command, or agent — a display/presentation format no orchestrator branch consumes (the ## ROADMAP DRAFT header was the canonical case until #3797 folded its content into ## ROADMAP CREATED). The check still verifies the marker is declared and emitted, and still counts it for case-collision purposes; only the consumer requirement is waived. Use it for display formats, never to silence a real orphan.

Key Handoff Contracts

Planner -> Executor (via PLAN.md)

Field Required Description
Frontmatter Yes phase, plan, type, wave, depends_on, files_modified, autonomous, requirements
<objective> Yes What the plan achieves
<tasks> Yes Ordered task list with type, files, action, verify, acceptance_criteria
<verification> Yes Overall verification steps
<success_criteria> Yes Measurable completion criteria

Executor -> Verifier (via SUMMARY.md)

Field Required Description
Frontmatter Yes phase, plan, subsystem, tags, key-files, metrics
Commits table Yes Per-task commit hashes and descriptions
Deviations section Yes Auto-fixed issues or "None"
Self-Check Yes PASSED or FAILED with details

Workflow Regex Patterns

Workflows match these markers to detect agent completion:

plan-phase.md matches:

  • ## RESEARCH COMPLETE / ## RESEARCH BLOCKED (researcher output)
  • ## PLANNING COMPLETE (planner output)
  • ## CHECKPOINT REACHED (planner/executor pause)
  • ## VERIFICATION PASSED / ## ISSUES FOUND (plan-checker output)

execute-phase.md matches:

  • ## PHASE COMPLETE (all plans in phase done)
  • ## Self-Check: FAILED (summary self-check)

NOTE: ## PLAN COMPLETE is the gsd-executor's completion marker but execute-phase.md does not regex-match it. Instead, it detects executor completion via spot-checks (SUMMARY.md existence, git commit state). This is intentional behavior, not a mismatch.