* test(#1949): add failing-first tests for <precondition> element Red phase for issue #1949 (Design by Contract: <precondition> element asserted before task execution). Tests assert: - docs/reference/plan-md.md documents the new <precondition> element - agents/gsd-planner.md @-references planner-preconditions.md and stays under the 49152-char cap (progressive-disclosure requirement) - gsd-core/references/planner-preconditions.md exists and documents the three emission cases mandated by the issue (user_setup / prior-phase artifact / env-var) and the contract triad mapping - agents/gsd-executor.md asserts <precondition> before task execution and routes unmet preconditions through existing checkpoint machinery - cmdVerifyPlanStructure (behavioral via runGsdTools) accepts plans both with and without <precondition> — the additive-validation guarantee - Parity assertion: plan-md.md and planner-preconditions.md agree on the canonical tag spelling (DEFECT.GENERATIVE-FIX-DIVERGENCE guard) Most prose-contract assertions are Red until the implementation lands. The behavioral validator assertions pass immediately (regression guards proving the validator already accepts unknown optional tags). * feat(#1949): <precondition> task element — Design by Contract Add an optional <precondition> element to <task> in PLAN.md (issue #1949, The Pragmatic Programmer Topic 23). The front-of-task side of the plan contract — preconditions (before) ↔ postconditions (<verify>/<done>/ <acceptance_criteria>, after) ↔ invariants (must_haves.truths, across the whole plan). Together with the tracer-bullet proposal (#1945), this closes both ends of the 'outrunning your headlights' failure mode for an autonomous AI executor. Acceptance criteria met: - <precondition> is an optional element on <task>; plans that omit it validate unchanged (cmdVerifyPlanStructure checks for presence of required tags, does not reject unknown optional tags). - gsd-executor evaluates the precondition before any other task work. Unmet halts execution with a checkpoint:human-verify and no partial commit; met or absent produces no visible change to execution flow. Unmet is never auto-approved under AUTO_CFG=true — a missing prerequisite is a fact the executor cannot establish on its own. - gsd-planner emits <precondition> in exactly the three cases the issue mandates: user_setup consumption, prior-phase artifact dependency, and env-var/runtime-config dependency. - Tests cover met, unmet, and absent preconditions plus the additive- validator guarantee. Files: - gsd-core/references/planner-preconditions.md (NEW): full emission rules, the three cases with worked examples, format guidance, anti-patterns, the contract triad mapping, and the executor assertion contract. Progressive disclosure. - agents/gsd-planner.md: slim <precondition> note in Task Anatomy with @-reference to the new file. To stay under the 49152-char agent-file cap (27-char headroom before this change), the inline <comment_text_discipline> and <region_scoped_negative_gate> summaries are compressed to one-line pointers — their full rules already live in planner-antipatterns.md, so no content is lost. - agents/gsd-executor.md: new step 0 'Precondition check' in the execute_tasks loop, before the type dispatch, routing unmet through checkpoint_return_format. - docs/reference/plan-md.md: new Preconditions section in the schema reference, with the canonical example and the three emission cases. - CONTEXT.md: Precondition glossary entry as a sibling of Tracer Bullet. - docs/INVENTORY.md + INVENTORY-MANIFEST.json: row for the new references/planner-preconditions.md (regen via gen-inventory-manifest). - tests/precondition-element.test.cjs: failing-first tests covering schema docs, planner emission contract, executor assertion contract, reference-file presence + the three cases, behavioral additive- validator guarantee, and a parity assertion (DEFECT.GENERATIVE-FIX- DIVERGENCE guard). - .changeset/quick-hawks-bark.md: Added fragment. Companion to #1945 (tracer bullets). * chore(#1949): regen agent-size baseline + install-tree goldens Documented baseline regenerations required by the feat(#1949) prose changes (RULESET.AGENT_SIZE_BUDGET + golden-install-parity): - npm run size:baseline — locks in the new gsd-executor.md size (+1050 bytes: the precondition-check step 0 block). gsd-planner.md is net smaller (-142 bytes: compressed two inline summary blocks whose full rules already lived in planner-antipatterns.md to make room for the slim <precondition> pointer). No hard-cap breach. - npm run gen:golden — pick up the new references/planner-preconditions.md + the two changed agent files across all 18 runtime install trees. Both regens are CI-mandated after intentional agent/reference changes; see CLAUDE.md 'RULESET.AGENT_SIZE_BUDGET' and the comments in tests/golden-install-parity.test.cjs. * fix(#1949): bound <precondition> checks to read-only (security review) Apply the security-review finding (LOW, isolated /security-review subagent): the executor's 'run the cheapest check' phrasing for a plan-author-controlled prose line was broader than ideal — a hostile plan author could craft a <precondition> whose 'cheapest check' is side-effecting (curl to an attacker host under the guise of verification, rm -rf before checking, secret emission). The risk is inherited from GSD's existing plan-trust model (<verify>, <action>, <done> already direct the executor to run arbitrary shell), so <precondition> does not materially expand it. But the new prose actively directs execution ('run the check') rather than passively consuming the element, so the bound is worth making explicit. Tightened across all four surfaces that describe the check shape: - agents/gsd-executor.md step 0: 'Verify with read-only checks only — file existence, env var presence (no value output), idempotent GET /health-style pings. Do NOT run commands with side effects (writes, network POSTs, secret emission) as the check; if a side-effecting check seems required, halt and surface via checkpoint instead.' - gsd-core/references/planner-preconditions.md Format section: same bound, plus the halt-and-surface escape hatch. - docs/reference/plan-md.md Preconditions section: mirrored. - CONTEXT.md Precondition glossary entry: mirrored. Regenerated agent-size baseline (executor grew 46186 -> 46440; still under the 49152 cap) and install-tree goldens. * chore(#1949): backfill changeset pr number 2422 Per CONTRIBUTING.md changeset workflow + feature-builder directive Step 8.7: backfill the placeholder pr:0 with the real PR number immediately after gh pr create returns. Avoids the fail_invalid_fragment gate. * fix(#1949): cite [#1949] on allow-test-rule exemption (ADR-456) CI's lint:ci runs lint-allow-test-rule-refs which per ADR-456 requires every // allow-test-rule: exemption on a NEW test file to carry an issue reference (#NNN or URL). My earlier push omitted it. Local 'npm run lint' (eslint) does NOT run this check — only 'npm run lint:ci' does. CLAUDE.md explicitly warns: 'lint:ci ≠ lint — CI runs lint:ci; a local pass is not the gate.' I should have run lint:ci before pushing; correcting now. Pattern matches the companion feature's test file: tests/tracer-bullet.test.cjs:1 // allow-test-rule: source-text-is-the-product [#1945]
This commit is contained in:
5
.changeset/quick-hawks-bark.md
Normal file
5
.changeset/quick-hawks-bark.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Added
|
||||
pr: 2422
|
||||
---
|
||||
**`<precondition>` task element (Design by Contract)** — plans may now declare a runnable/checkable fact a task assumes (env var set, prior-phase artifact present, external-setup done) that plan ordering does not guarantee; the executor asserts it before running the task and halts with a checkpoint on unmet instead of building on a broken assumption. Plans that omit `<precondition>` behave exactly as today. (#1949)
|
||||
@@ -362,7 +362,10 @@ Phase 1 deliverable under `--mvp` on a new project — the Phase-1 whole-applica
|
||||
Single-feature task that moves one user capability from open-to-close (happy path) end-to-end. Contrast with the horizontal layer (all models, then all APIs, then all UI). The default planning unit under tracer-first decomposition (the leading task is a Tracer Bullet); SPIDR Splitting axes (Spike, Paths, Interfaces, Data, Rules) are the canonical decomposition tools when a slice is too large for one phase.
|
||||
|
||||
### Tracer Bullet
|
||||
The default GSD decomposition lead: a **permanent, production-quality, minimal end-to-end slice** that wires one path through every layer a phase touches and becomes part of the skeleton of the final system — written for keeps, not thrown away. Contrast with a **prototype** (throwaway reconnaissance code, deleted once its lesson is learned): a tracer's *functionality* gaps are acceptable but its *architectural* gaps are not; stubs are allowed only where they can later be filled without an architectural change. GSD ships tracers, never prototypes — which is why `gsd-planner` LEADS every plan with a `type="tracer"` task (default; `--no-tracer` / `TRACER_MODE=false` opts back into horizontal layers) and `gsd-executor` runs an early integration feedback gate on the tracer's `<verify>` before expansion tasks (autonomous: halt-on-fail; interactive: `checkpoint:human-verify`). Origin: *The Pragmatic Programmer* "Tracer Bullets" (#1945); the Walking Skeleton is the Phase-1 whole-application special case. See Vertical Slice, MVP Mode, Walking Skeleton.
|
||||
The default GSD decomposition lead: a **permanent, production-quality, minimal end-to-end slice** that wires one path through every layer a phase touches and becomes part of the skeleton of the final system — written for keeps, not thrown away. Contrast with a **prototype** (throwaway reconnaissance code, deleted once its lesson is learned): a tracer's *functionality* gaps are acceptable but its *architectural* gaps are not; stubs are allowed only where they can later be filled without an architectural change. GSD ships tracers, never prototypes — which is why `gsd-planner` LEADS every plan with a `type="tracer"` task (default; `--no-tracer` / `TRACER_MODE=false` opts back into horizontal layers) and `gsd-executor` runs an early integration feedback gate on the tracer's `<verify>` before expansion tasks (autonomous: halt-on-fail; interactive: `checkpoint:human-verify`). Origin: *The Pragmatic Programmer* "Tracer Bullets" (#1945); the Walking Skeleton is the Phase-1 whole-application special case. See Vertical Slice, MVP Mode, Walking Skeleton, Precondition.
|
||||
|
||||
### Precondition
|
||||
The front-of-task side of the GSD plan contract (issue #1949, *The Pragmatic Programmer* Topic 23 — Design by Contract). An optional `<precondition>` element on `<task>` stating, in a single line of runnable/checkable prose, what must already be true for the task to begin safely — e.g. "`OPENAI_API_KEY` is set", "`dist/schema.json` from Phase 02 exists", "server responds to GET /health". `gsd-executor` evaluates it before any other task work, using **read-only checks only** (file existence, env var presence with no value output, idempotent `GET /health`-style pings — no writes, no network POSTs, no secret emission; if a side-effecting check seems required, the executor halts and surfaces a checkpoint rather than running it): met-or-absent is a no-op (back-compat for every existing plan); unmet returns a `checkpoint:human-verify` with no partial commit, and is NEVER auto-approved under `AUTO_CFG=true` (a missing prerequisite is a fact the executor cannot establish on its own, not a verification step). `gsd-planner` emits `<precondition>` in exactly three cases — `user_setup` consumption, prior-phase artifact dependency, or env-var/runtime-config dependency — when the assumption is not already guaranteed by `depends_on` ordering. Closes the contract triad whose other two sides are postconditions (`<verify>`/`<done>`/`<acceptance_criteria>`) and invariants (`must_haves.truths`). The structural validator (`cmdVerifyPlanStructure`) does not reject unknown optional tags, so adding `<precondition>` passes plan-structure validation unchanged. Canonical schema reference: `docs/reference/plan-md.md` → Preconditions; emission rules + anti-patterns: `gsd-core/references/planner-preconditions.md`. The architectural-end companion is the Tracer Bullet (#1945); together they close both ends of the "outrunning your headlights" failure mode. See Tracer Bullet.
|
||||
|
||||
### Behavior-Adding Task
|
||||
Predicate over a PLAN.md task: `tdd="true"` frontmatter AND `<behavior>` block names a user-visible outcome AND `<files>` includes at least one non-`*.md` / non-`*.json` / non-`*.test.*` source file. Pure doc/config/test-only tasks are exempt. The MVP+TDD Gate (in `references/execute-mvp-tdd.md`) only halts execution on this predicate; the gsd-executor agent applies all three checks at runtime. Currently a prose-only specification — no shared utility.
|
||||
|
||||
@@ -144,6 +144,10 @@ At execution decision points, apply structured reasoning:
|
||||
|
||||
For each task:
|
||||
|
||||
0. **Precondition check (before any other task work):** If the task carries a `<precondition>` element, evaluate that single prose line first — it names a runnable/checkable fact the task assumes (env var set, prior-phase artifact present, server responding to `/health`, `user_setup` step done). Verify with **read-only checks only** — file existence, env var presence (no value output), idempotent `GET /health`-style pings. Do NOT run commands with side effects (writes, network POSTs, secret emission) as the check; if a side-effecting check seems required, halt and surface via checkpoint instead.
|
||||
- **Met OR absent:** continue with no visible change to execution flow. The precondition is a no-op for the rest of the task loop.
|
||||
- **Unmet:** STOP — return a `checkpoint:human-verify` (use `checkpoint_return_format`) with `**Blocked by:** Precondition not met: <precondition text>`. Do NOT partial-commit the task. Unmet preconditions are NEVER auto-approved, even under `AUTO_CFG=true` — a missing prerequisite is not a verification step a human can rubber-stamp; it is a fact the executor cannot establish on its own. The human either satisfies the precondition (sets the env var, completes the `user_setup` step, regenerates the artifact) or reruns `/gsd:plan-phase` to restructure.
|
||||
|
||||
1. **If `type="auto"`:**
|
||||
- Check for `tdd="true"` → follow TDD execution flow
|
||||
- Execute task, apply deviation rules as needed
|
||||
|
||||
@@ -193,23 +193,19 @@ Every task has four required fields:
|
||||
**Grep gate hygiene:** `grep -c` counts comments, so header prose can be self-invalidating. Use `grep -v '^#' | grep -c token`. Bare `== 0` gates on unfiltered files are forbidden.
|
||||
|
||||
<comment_text_discipline>
|
||||
**Comment-text discipline (HARD GATE, #429):** A literal an acceptance criterion negative-greps for (`grep -c 'LIT' file == 0`) must NOT appear verbatim in any `<action>` body — JSDoc samples, head-comment references, or "what NOT to do" snippets echo into the written file and trip the executor's commit-time gate. `validate_plan` (`verify.plan-structure`) fails plan creation on violation. Rephrase the literal by concept, or — when it must legitimately appear — add an allowlist marker on its own line:
|
||||
|
||||
`<!-- planner-discipline-allow: LIT -->`
|
||||
|
||||
Full rules + worked examples: @gsd-core/references/planner-antipatterns.md ("Comment-Text Discipline").
|
||||
**Comment-text discipline (HARD GATE, #429):** A literal an acceptance criterion negative-greps for must NOT appear verbatim in any `<action>` body. Full rules + `<!-- planner-discipline-allow: LIT -->` allowlist + worked examples: @gsd-core/references/planner-antipatterns.md ("Comment-Text Discipline").
|
||||
</comment_text_discipline>
|
||||
|
||||
<region_scoped_negative_gate>
|
||||
**Region-scoped negative gates (WARN, #968):** Region-scope a file-wide negative grep when a sibling task needs that construct elsewhere in the same file; `validate_plan` WARNS. See: @gsd-core/references/planner-antipatterns.md ("Region-Scoped Negative Gates").
|
||||
|
||||
**Verify-gate hygiene (#1478/#1479):** See @gsd-core/references/planner-antipatterns.md.
|
||||
**Region-scoped negative gates (WARN, #968)** and **Verify-gate hygiene (#1478/#1479):** @gsd-core/references/planner-antipatterns.md.
|
||||
</region_scoped_negative_gate>
|
||||
|
||||
**<done>:** Acceptance criteria - measurable state of completion.
|
||||
- Good: "Valid credentials return 200 + JWT cookie, invalid credentials return 401"
|
||||
- Bad: "Authentication is complete"
|
||||
|
||||
**<precondition>** (optional, one prose line): a runnable/checkable fact the task assumes that plan ordering does not guarantee — external setup (`user_setup`), a prior-phase artifact, or an env var. The executor asserts it before running the task and halts on unmet. Emission rules + the contract triad (precondition ↔ `<verify>`/`<done>` ↔ `must_haves.truths`): @~/.claude/gsd-core/references/planner-preconditions.md.
|
||||
|
||||
See @~/.claude/gsd-core/references/planner-guidance.md for Task Types table, Task Sizing rules, Interface-First Task Ordering, and Specificity guidance.
|
||||
|
||||
## TDD Detection
|
||||
|
||||
@@ -254,6 +254,7 @@
|
||||
"planner-interface-context.md",
|
||||
"planner-load-graph-context.md",
|
||||
"planner-mvp-mode.md",
|
||||
"planner-preconditions.md",
|
||||
"planner-reviews.md",
|
||||
"planner-revision.md",
|
||||
"planner-source-audit.md",
|
||||
|
||||
@@ -385,6 +385,7 @@ The `gsd-planner` agent is decomposed into a core agent plus reference modules t
|
||||
| `planner-revision.md` | Plan revision patterns for iterative refinement. |
|
||||
| `planner-source-audit.md` | Planner source-audit and authority-limit rules. |
|
||||
| `planner-mvp-mode.md` | Vertical-slice planning rules for MVP mode. |
|
||||
| `planner-preconditions.md` | Emission rules for the optional `<precondition>` task element (issue #1949, Design by Contract): when to emit, the three cases (user_setup / prior-phase artifact / env-var), format, anti-patterns, and the contract triad mapping. |
|
||||
| `planner-human-verify-mode.md` | Rules for `workflow.human_verify_mode = end-of-phase`: suppress `checkpoint:human-verify` task emission and route deferred items via `<verify><human-check>`. |
|
||||
| `planner-graphify-auto-update.md` | How `load_graph_context` surfaces `.last-build-status.json` auto-update state (running / failed / stale head) alongside the existing staleness annotation. Opt-in via `graphify.auto_update` (#3347). |
|
||||
| `planner-interface-context.md` | Interface context rules for executors — how to extract key interfaces/types/exports from existing code and document new interfaces that downstream plans will consume. |
|
||||
|
||||
@@ -160,7 +160,34 @@ References source files the executor needs to read. Includes project-level plann
|
||||
|
||||
### `<tasks>`
|
||||
|
||||
Contains one or more `<task>` elements. Every task element must carry `<name>`, `<files>`, `<read_first>`, `<action>`, `<verify>`, `<acceptance_criteria>`, and `<done>` for `type="auto"` and `type="tracer"` tasks.
|
||||
Contains one or more `<task>` elements. Every task element must carry `<name>`, `<files>`, `<read_first>`, `<action>`, `<verify>`, `<acceptance_criteria>`, and `<done>` for `type="auto"` and `type="tracer"` tasks. An optional `<precondition>` element (see [Preconditions](#preconditions)) may sit between `<name>` and `<files>`.
|
||||
|
||||
---
|
||||
|
||||
## Preconditions
|
||||
|
||||
`<precondition>` is an **optional** element on `<task>` (issue #1949, *The Pragmatic Programmer* Topic 23 — Design by Contract). It states, in a single line of runnable/checkable prose, what must already be true for the task to begin safely. It closes the front-of-task side of the contract triad — preconditions (before) ↔ postconditions (`<verify>`/`<done>`/`<acceptance_criteria>`, after) ↔ invariants (`must_haves.truths`, across the whole plan).
|
||||
|
||||
```xml
|
||||
<task type="auto">
|
||||
<name>Add /reveal endpoint handler</name>
|
||||
<precondition>server bootstraps and responds to GET /health (from the tracer slice)</precondition>
|
||||
<files>server/reveal.ts</files>
|
||||
<action>…</action>
|
||||
<verify>curl /reveal?path=… opens the OS file manager</verify>
|
||||
<done>Endpoint committed and manually verified</done>
|
||||
</task>
|
||||
```
|
||||
|
||||
**Optional and back-compat:** a plan that omits `<precondition>` on every task behaves exactly as today — the executor skips the check with no visible change. Adding `<precondition>` to a task tells the executor to assert it before any other task work (read-only checks only: file existence, env var presence, idempotent health pings; no side-effecting checks — halt and surface a checkpoint if one seems required) and halt (returning a `checkpoint:human-verify`, no partial commit) on an unmet precondition. Plans that include `<precondition>` pass `verify plan-structure` unchanged — the structural validator checks for the presence of required tags and does not reject unknown optional tags.
|
||||
|
||||
**Emission cases** (planner-side): emit `<precondition>` only when a task relies on state the plan's own `depends_on` ordering does not already guarantee. Three cases cover every legitimate use:
|
||||
|
||||
1. **External service setup** (`user_setup` frontmatter) — the consuming task ties a specific setup step to itself so the executor halts if the setup was skipped.
|
||||
2. **Prior-phase artifact dependency** — a generated schema, a migration's dist output, a contract file from an earlier phase. Cross-phase `depends_on` does not cross phase boundaries, so `<precondition>` is the explicit pointer.
|
||||
3. **Environment variable / runtime configuration** — a tool, API, or script the task invokes requires an env var or runtime config that exists *now*, not at plan time.
|
||||
|
||||
Full emission rules, anti-patterns ("the system is ready" is not checkable; do not use `<precondition>` for intra-plan sequencing — that is what `depends_on` is for), and the contract triad mapping: see `gsd-core/references/planner-preconditions.md`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
156
gsd-core/references/planner-preconditions.md
Normal file
156
gsd-core/references/planner-preconditions.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# Planner Preconditions — `<precondition>` Element
|
||||
|
||||
> Progressive-disclosure reference for `agents/gsd-planner.md`. The planner agent
|
||||
> reads this file when it needs the full emission rules for the `<precondition>`
|
||||
> task element (issue #1949, *The Pragmatic Programmer* Topic 23 — Design by
|
||||
> Contract). The slim pointer in `agents/gsd-planner.md` → `<task_breakdown>`
|
||||
> routes here; the canonical schema row lives in `docs/reference/plan-md.md`.
|
||||
|
||||
## The contract triad
|
||||
|
||||
Every task in a PLAN.md participates in a three-sided contract:
|
||||
|
||||
| Contract side | GSD element | When it binds |
|
||||
|---|---|---|
|
||||
| **Precondition** | `<precondition>` (optional element on `<task>`) | Before the task begins. What must already be true for the task to run safely. |
|
||||
| **Postcondition** | `<verify>` + `<done>` + `<acceptance_criteria>` | After the task ends. What the task guarantees on return. |
|
||||
| **Invariant** | `must_haves.truths` (plan frontmatter) | Across the whole plan/phase. What always holds. |
|
||||
|
||||
GSD already models postconditions and invariants well. `<precondition>` closes
|
||||
the missing side: it states, in runnable/checkable terms, what must be true
|
||||
*before* a task begins — so an autonomous executor stops the instant an
|
||||
assumption is false, instead of building ten atomic commits on top of a
|
||||
migration that never ran.
|
||||
|
||||
This is the front-of-task companion to the tracer-bullet proposal (#1945):
|
||||
tracers prove the *architecture* end-to-end before expansion; preconditions prove
|
||||
each expansion task's *assumptions* before it runs. Together they close both ends
|
||||
of the "outrunning your headlights" failure mode.
|
||||
|
||||
## When to emit `<precondition>`
|
||||
|
||||
Emit `<precondition>` ONLY when a task relies on state the plan's own `depends_on`
|
||||
ordering does not already guarantee. Three cases cover every legitimate use; if
|
||||
the task's prerequisite is intra-plan sequencing, use `depends_on`, NOT
|
||||
`<precondition>`.
|
||||
|
||||
### Case 1 — External service setup (`user_setup`)
|
||||
|
||||
The task depends on an external service the developer must set up (account
|
||||
creation, secret retrieval, dashboard configuration, billing activation). The
|
||||
`user_setup` frontmatter field already enumerates these steps; `<precondition>`
|
||||
on the consuming task ties a specific setup step to a specific task so the
|
||||
executor halts if the setup was skipped.
|
||||
|
||||
```xml
|
||||
<task type="auto">
|
||||
<name>Send welcome email via SendGrid</name>
|
||||
<precondition>SENDGRID_API_KEY is set (user_setup step 1 complete)</precondition>
|
||||
<files>src/email/welcome.ts</files>
|
||||
<action>...</action>
|
||||
<verify>...</verify>
|
||||
<done>Welcome email dispatched for a test user</done>
|
||||
</task>
|
||||
```
|
||||
|
||||
### Case 2 — Prior-phase artifact dependency
|
||||
|
||||
The task consumes an artifact a prior phase promised (a generated schema, a
|
||||
migration's dist output, a contract file). Cross-phase `depends_on` does not
|
||||
cross phase boundaries, so a `<precondition>` is the explicit pointer.
|
||||
|
||||
```xml
|
||||
<task type="auto">
|
||||
<name>Generate TypeScript client from schema</name>
|
||||
<precondition>dist/schema.json from Phase 02 exists and is non-empty</precondition>
|
||||
<files>src/client/generated.ts</files>
|
||||
<action>...</action>
|
||||
<verify>...</verify>
|
||||
<done>Client generated and compiles</done>
|
||||
</task>
|
||||
```
|
||||
|
||||
### Case 3 — Environment variable / runtime configuration
|
||||
|
||||
The task shells out to a tool, hits an API, or runs a script that requires an
|
||||
environment variable or runtime config that exists *now* (not at plan time).
|
||||
|
||||
```xml
|
||||
<task type="auto">
|
||||
<name>Add /reveal endpoint handler</name>
|
||||
<precondition>server bootstraps and responds to GET /health (from the tracer slice)</precondition>
|
||||
<files>server/reveal.ts</files>
|
||||
<action>...</action>
|
||||
<verify>curl /reveal?path=... opens the OS file manager</verify>
|
||||
<done>Endpoint committed and manually verified</done>
|
||||
</task>
|
||||
```
|
||||
|
||||
## Format
|
||||
|
||||
`<precondition>` is a single line of prose inside the `<task>` element, placed right after `<name>` and before `<files>`. It is **prose, not a structured block** — concrete enough that the executor agent can run a read-only check (file existence, env var presence, idempotent `GET /health`-style ping), prose enough not to require a parser extension. The executor MUST verify with read-only checks only: no writes, no network POSTs, no secret emission. If a side-effecting check seems required, the executor halts and surfaces a checkpoint rather than running it.
|
||||
|
||||
```xml
|
||||
<task type="auto">
|
||||
<name>...</name>
|
||||
<precondition>...</precondition>
|
||||
<files>...</files>
|
||||
<action>...</action>
|
||||
<verify>...</verify>
|
||||
<done>...</done>
|
||||
</task>
|
||||
```
|
||||
|
||||
## What NOT to put in a `<precondition>`
|
||||
|
||||
- **Vague readiness checks.** "The system is ready" is not checkable. Name the
|
||||
concrete signal: a `curl` response, a file path, an env var name.
|
||||
- **Intra-plan ordering.** "Task 1 has completed" — that is what `depends_on`
|
||||
is for. Reserve `<precondition>` for state the plan's wave/dependency graph
|
||||
cannot express.
|
||||
- **Implementation choices.** "We have chosen library X" — that belongs in the
|
||||
`<action>` body or a `## Decisions` row, not a runtime fact.
|
||||
- **Things the task itself creates.** A precondition names a fact the task
|
||||
*assumes*; if the task produces it, it is a postcondition (`<done>`).
|
||||
|
||||
## Executor behavior (assertion contract)
|
||||
|
||||
The executor agent reads `<precondition>` before any other task work:
|
||||
|
||||
| State | Executor behavior |
|
||||
|---|---|
|
||||
| **Absent** | No visible change — execute the task exactly as today. Back-compat for every existing plan. |
|
||||
| **Met** | No visible change — proceed with the task. The precondition is logged in the SUMMARY only if it was non-trivial to verify. |
|
||||
| **Unmet** | STOP — return a `checkpoint:human-verify` (use `checkpoint_return_format`) with `**Blocked by:** Precondition not met: <precondition text>`. Do NOT partial-commit the task. Unmet preconditions are NEVER auto-approved — a missing prerequisite is not a verification step a human can rubber-stamp, it is a fact the executor cannot establish on its own. |
|
||||
|
||||
## Plan-structure validation
|
||||
|
||||
`cmdVerifyPlanStructure` checks for the presence of required tags (`<name>`,
|
||||
`<action>`, etc.) and warns on missing recommended tags (`<verify>`, `<done>`,
|
||||
`<files>`). It does **not** reject unknown optional tags, so adding
|
||||
`<precondition>` to a plan passes validation unchanged. A future ADR may add
|
||||
structured validation if drift emerges; v1 ships prose-only to keep the surface
|
||||
minimal (Hyrum's Law: the smaller the observable surface, the less the system
|
||||
depends on by accident).
|
||||
|
||||
## Out of scope
|
||||
|
||||
The following are explicitly NOT part of v1:
|
||||
|
||||
- **Structured precondition DSL** (e.g. `<precondition kind="env" var="X"/>`).
|
||||
Prose-first keeps complexity flat; structured validation can land in a later
|
||||
PR if prose proves insufficient.
|
||||
- **Automatic precondition emission for every task.** The three cases above are
|
||||
a hard ceiling (Zawinski's Law guard). Most tasks do not need a precondition.
|
||||
- **Cross-task preconditions.** A precondition binds one task to one fact. Use
|
||||
`depends_on` or a parent plan's `must_haves` for multi-task contracts.
|
||||
|
||||
## See also
|
||||
|
||||
- *The Pragmatic Programmer*, Topic 23 — "Design by Contract" (Hunt & Thomas).
|
||||
- `docs/reference/plan-md.md` — canonical PLAN.md schema reference (where
|
||||
`<precondition>` appears in the task-element table).
|
||||
- Tracer-bullet proposal (#1945) — the architectural-end companion to this
|
||||
front-of-task contract.
|
||||
- `agents/gsd-executor.md` → `<execution_flow>` → precondition check step — the
|
||||
assertion surface that consumes what this reference defines.
|
||||
@@ -14,7 +14,7 @@
|
||||
"gsd-domain-researcher.md": 7032,
|
||||
"gsd-eval-auditor.md": 12496,
|
||||
"gsd-eval-planner.md": 7008,
|
||||
"gsd-executor.md": 45338,
|
||||
"gsd-executor.md": 46644,
|
||||
"gsd-framework-selector.md": 6778,
|
||||
"gsd-integration-checker.md": 15238,
|
||||
"gsd-intel-updater.md": 18166,
|
||||
@@ -23,7 +23,7 @@
|
||||
"gsd-pattern-mapper.md": 12487,
|
||||
"gsd-phase-researcher.md": 40866,
|
||||
"gsd-plan-checker.md": 44780,
|
||||
"gsd-planner.md": 49314,
|
||||
"gsd-planner.md": 49172,
|
||||
"gsd-project-researcher.md": 22242,
|
||||
"gsd-research-synthesizer.md": 13847,
|
||||
"gsd-roadmapper.md": 22273,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "1db46cac3f4d9889",
|
||||
"agents/gsd-eval-auditor.md": "1b8391f1aafb067f",
|
||||
"agents/gsd-eval-planner.md": "3d10fd11147f6857",
|
||||
"agents/gsd-executor.md": "5dc97b2515b36731",
|
||||
"agents/gsd-executor.md": "152955064cf4c9d2",
|
||||
"agents/gsd-framework-selector.md": "daa62c79619c76bf",
|
||||
"agents/gsd-integration-checker.md": "0643cd2d779b131c",
|
||||
"agents/gsd-intel-updater.md": "26c1f1e028c6346a",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "e62ee90d39084802",
|
||||
"agents/gsd-phase-researcher.md": "cff1196c8e8bb4fa",
|
||||
"agents/gsd-plan-checker.md": "dd1e7cdc837d8f3e",
|
||||
"agents/gsd-planner.md": "c5de6bb9b277e4d4",
|
||||
"agents/gsd-planner.md": "6a442501f9d4caa8",
|
||||
"agents/gsd-project-researcher.md": "85de7f562872ee9b",
|
||||
"agents/gsd-research-synthesizer.md": "18a2e1b30ff7ae3a",
|
||||
"agents/gsd-roadmapper.md": "7a8465ac6d4dd29e",
|
||||
@@ -115,6 +115,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "90cb2ecd1f3eb4d8",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cdac9dde7cd8fa84",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "671c9ea949889c4a",
|
||||
"agents/gsd-eval-auditor.md": "fcaec7b00f94c435",
|
||||
"agents/gsd-eval-planner.md": "a4a5b4b3f7828ba3",
|
||||
"agents/gsd-executor.md": "2df526331a77b2aa",
|
||||
"agents/gsd-executor.md": "47c648f6622e939f",
|
||||
"agents/gsd-framework-selector.md": "4b77eebbe9288d80",
|
||||
"agents/gsd-integration-checker.md": "fa53e2d78be1de74",
|
||||
"agents/gsd-intel-updater.md": "fa40e685d7441ace",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "43c6021cf7caabfa",
|
||||
"agents/gsd-phase-researcher.md": "f1f6fd6a3e67c7a8",
|
||||
"agents/gsd-plan-checker.md": "bf1a4e636f2390de",
|
||||
"agents/gsd-planner.md": "4614c9f6250d08d4",
|
||||
"agents/gsd-planner.md": "55cc953c6a52ae05",
|
||||
"agents/gsd-project-researcher.md": "4531b7cc8f5e5f7d",
|
||||
"agents/gsd-research-synthesizer.md": "4a4f68e6c75b133a",
|
||||
"agents/gsd-roadmapper.md": "bb2f57695dbab32c",
|
||||
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "ca7a7af3f35ae61b",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"agents/gsd-domain-researcher.md": "f1e03df842ddfb95",
|
||||
"agents/gsd-eval-auditor.md": "d0f45fff7370bb0b",
|
||||
"agents/gsd-eval-planner.md": "9cc049b82897daa4",
|
||||
"agents/gsd-executor.md": "e96f3cbde4428497",
|
||||
"agents/gsd-executor.md": "3c8d4fd1c29542bb",
|
||||
"agents/gsd-framework-selector.md": "85005d716f9d98f7",
|
||||
"agents/gsd-integration-checker.md": "17a8ee731986564d",
|
||||
"agents/gsd-intel-updater.md": "4953a465db9dadc1",
|
||||
@@ -24,7 +24,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "b45b5e106775bec1",
|
||||
"agents/gsd-phase-researcher.md": "4772d9eada32e8bd",
|
||||
"agents/gsd-plan-checker.md": "75851b147f35354a",
|
||||
"agents/gsd-planner.md": "a5cdb261a6ccbb96",
|
||||
"agents/gsd-planner.md": "4636f48b1b7ca1f6",
|
||||
"agents/gsd-project-researcher.md": "d7f355894519f9fe",
|
||||
"agents/gsd-research-synthesizer.md": "1c738df9932d325a",
|
||||
"agents/gsd-roadmapper.md": "453e9471ad27c7ea",
|
||||
@@ -185,6 +185,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "add55e135dd968da",
|
||||
"gsd-core/references/planner-mvp-mode.md": "98bcd2020c30cbd2",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"agents/gsd-domain-researcher.md": "5f7d366251b957fe",
|
||||
"agents/gsd-eval-auditor.md": "fea2759beff0a642",
|
||||
"agents/gsd-eval-planner.md": "112f6730f23854e3",
|
||||
"agents/gsd-executor.md": "e44ea5156ca2a42d",
|
||||
"agents/gsd-executor.md": "e63187a0bbff74eb",
|
||||
"agents/gsd-framework-selector.md": "c350ee693cb1aa4e",
|
||||
"agents/gsd-integration-checker.md": "c8b4e65dee89c8ea",
|
||||
"agents/gsd-intel-updater.md": "5b41e05f90ce89d9",
|
||||
@@ -24,7 +24,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "b45b5e106775bec1",
|
||||
"agents/gsd-phase-researcher.md": "85217c69c1ed2ac6",
|
||||
"agents/gsd-plan-checker.md": "c70134c61b969589",
|
||||
"agents/gsd-planner.md": "c07a226ddd579839",
|
||||
"agents/gsd-planner.md": "3098091aa1f0756d",
|
||||
"agents/gsd-project-researcher.md": "f468e96f8339d1e0",
|
||||
"agents/gsd-research-synthesizer.md": "7be02e47f4fd901b",
|
||||
"agents/gsd-roadmapper.md": "8a7f1f1256a6aed5",
|
||||
@@ -114,6 +114,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "ca7a7af3f35ae61b",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"agents/gsd-domain-researcher.md": "0fecdaea86466a56",
|
||||
"agents/gsd-eval-auditor.md": "36c44303085df2f8",
|
||||
"agents/gsd-eval-planner.md": "3ddea88a69b4da3f",
|
||||
"agents/gsd-executor.md": "9b51734f64049fda",
|
||||
"agents/gsd-executor.md": "343f7d59b160d74a",
|
||||
"agents/gsd-framework-selector.md": "564669d479433f15",
|
||||
"agents/gsd-integration-checker.md": "1bbbdd3d420b994e",
|
||||
"agents/gsd-intel-updater.md": "42c40fffbc720d0b",
|
||||
@@ -28,7 +28,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "b526065fd2efa19c",
|
||||
"agents/gsd-phase-researcher.md": "c507db2ba66038f4",
|
||||
"agents/gsd-plan-checker.md": "a609245dbdc4ef2b",
|
||||
"agents/gsd-planner.md": "2fa5c5d4529ef651",
|
||||
"agents/gsd-planner.md": "c2ab476257cd07cf",
|
||||
"agents/gsd-project-researcher.md": "049f816c6caa4316",
|
||||
"agents/gsd-research-synthesizer.md": "2f7dcbff50371d4c",
|
||||
"agents/gsd-roadmapper.md": "bbb23d3097911516",
|
||||
@@ -118,6 +118,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "e469016f2d51b5bc",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "1c1a800108a2b225",
|
||||
"agents/gsd-eval-auditor.md": "99012004b14ea602",
|
||||
"agents/gsd-eval-planner.md": "4ebdd7fe9cbb0cfe",
|
||||
"agents/gsd-executor.md": "4f4bbb77be53a135",
|
||||
"agents/gsd-executor.md": "44149e405a126f90",
|
||||
"agents/gsd-framework-selector.md": "7726fccc86bfeb50",
|
||||
"agents/gsd-integration-checker.md": "2d8339790bbb2dc3",
|
||||
"agents/gsd-intel-updater.md": "c51339956197cbd3",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "92cfa2e6c2a06bf3",
|
||||
"agents/gsd-phase-researcher.md": "6338474da1a5d65e",
|
||||
"agents/gsd-plan-checker.md": "e704c083b02e8c35",
|
||||
"agents/gsd-planner.md": "1ade235391742f7e",
|
||||
"agents/gsd-planner.md": "8e3e314f962711cd",
|
||||
"agents/gsd-project-researcher.md": "e43c59f7f1f2f37a",
|
||||
"agents/gsd-research-synthesizer.md": "87955470c3c129b2",
|
||||
"agents/gsd-roadmapper.md": "20b69eff61a7a9fa",
|
||||
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "ca7a7af3f35ae61b",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -102,8 +102,8 @@
|
||||
"agents/gsd-eval-auditor.toml": "9b81d61b3c5f722d",
|
||||
"agents/gsd-eval-planner.md": "73f2ad2ff2797a51",
|
||||
"agents/gsd-eval-planner.toml": "09468ad1a34ac468",
|
||||
"agents/gsd-executor.md": "895482e838b13815",
|
||||
"agents/gsd-executor.toml": "a95f6ad24154e646",
|
||||
"agents/gsd-executor.md": "ed8080096522f7ec",
|
||||
"agents/gsd-executor.toml": "126d79d90e2fdf4f",
|
||||
"agents/gsd-framework-selector.md": "ebae32430887d2e0",
|
||||
"agents/gsd-framework-selector.toml": "637e4e021b7ec380",
|
||||
"agents/gsd-integration-checker.md": "9cc875676cf7d741",
|
||||
@@ -120,8 +120,8 @@
|
||||
"agents/gsd-phase-researcher.toml": "44a3d510cd0ce3bd",
|
||||
"agents/gsd-plan-checker.md": "e7f02c10ea788aee",
|
||||
"agents/gsd-plan-checker.toml": "6f8ceb421d0ad721",
|
||||
"agents/gsd-planner.md": "7d48d3a81760af05",
|
||||
"agents/gsd-planner.toml": "2527d19b0c47ec66",
|
||||
"agents/gsd-planner.md": "cb3ff2ef2c58617c",
|
||||
"agents/gsd-planner.toml": "ac51638704036f71",
|
||||
"agents/gsd-project-researcher.md": "959f2e57c3d69ed8",
|
||||
"agents/gsd-project-researcher.toml": "f395e8e8c4baf1ed",
|
||||
"agents/gsd-research-synthesizer.md": "497f85adf53259ef",
|
||||
@@ -221,6 +221,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "ca7a7af3f35ae61b",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "7889bfa28e82156b",
|
||||
"gsd-core/references/planner-revision.md": "2ebf1a714d1ec4bf",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.agent.md": "d603239b3e9fe428",
|
||||
"agents/gsd-eval-auditor.agent.md": "3c03009564de55c8",
|
||||
"agents/gsd-eval-planner.agent.md": "14751876fc2b5f16",
|
||||
"agents/gsd-executor.agent.md": "761523a925bd2649",
|
||||
"agents/gsd-executor.agent.md": "e75e46a35b7b260a",
|
||||
"agents/gsd-framework-selector.agent.md": "cafeec0b3489be45",
|
||||
"agents/gsd-integration-checker.agent.md": "30439b804927acc7",
|
||||
"agents/gsd-intel-updater.agent.md": "238c1a886f35a25c",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.agent.md": "b1f488b0fa6a2395",
|
||||
"agents/gsd-phase-researcher.agent.md": "03cfb510a766fe93",
|
||||
"agents/gsd-plan-checker.agent.md": "c50a5b008ddcbfad",
|
||||
"agents/gsd-planner.agent.md": "2664dc34defa7580",
|
||||
"agents/gsd-planner.agent.md": "8f5f400efea5e446",
|
||||
"agents/gsd-project-researcher.agent.md": "d73bdbe986ffa8a6",
|
||||
"agents/gsd-research-synthesizer.agent.md": "f03eed4aa89e47c5",
|
||||
"agents/gsd-roadmapper.agent.md": "322048cf8ddcb4e5",
|
||||
@@ -116,6 +116,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "641b6c1ce4dd0c8c",
|
||||
"gsd-core/references/planner-mvp-mode.md": "355d8a9ff2b2b67e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "56395dbdabf076f6",
|
||||
"agents/gsd-eval-auditor.md": "ad2840fd5cd76172",
|
||||
"agents/gsd-eval-planner.md": "2049dac060d00eda",
|
||||
"agents/gsd-executor.md": "68796b76140841c2",
|
||||
"agents/gsd-executor.md": "e3d78836e115b18c",
|
||||
"agents/gsd-framework-selector.md": "4b77eebbe9288d80",
|
||||
"agents/gsd-integration-checker.md": "5da30584d06b878c",
|
||||
"agents/gsd-intel-updater.md": "b8971c5d96e63b38",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "1229c215677f740d",
|
||||
"agents/gsd-phase-researcher.md": "982d59921bed463d",
|
||||
"agents/gsd-plan-checker.md": "ba51999876d40cf2",
|
||||
"agents/gsd-planner.md": "1feec75fe52b56bd",
|
||||
"agents/gsd-planner.md": "c788d7fb84cf5433",
|
||||
"agents/gsd-project-researcher.md": "beeac940d3a10e76",
|
||||
"agents/gsd-research-synthesizer.md": "6315f016d55176f4",
|
||||
"agents/gsd-roadmapper.md": "d28e7d4bac46dde2",
|
||||
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "ca7a7af3f35ae61b",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "412cdbb05ba252ea",
|
||||
"agents/gsd-eval-auditor.md": "4ffb265063c318e5",
|
||||
"agents/gsd-eval-planner.md": "03448fc9c5774b56",
|
||||
"agents/gsd-executor.md": "c1f807f853dc53d7",
|
||||
"agents/gsd-executor.md": "b70c976372c77dc1",
|
||||
"agents/gsd-framework-selector.md": "ea9981d65d6b3429",
|
||||
"agents/gsd-integration-checker.md": "35b4f2969d279871",
|
||||
"agents/gsd-intel-updater.md": "5fe5edfae2719cb8",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "cea092600aeb3978",
|
||||
"agents/gsd-phase-researcher.md": "2bd0402f33d757ca",
|
||||
"agents/gsd-plan-checker.md": "4b4e2b475bf5b5c3",
|
||||
"agents/gsd-planner.md": "a48726410b038084",
|
||||
"agents/gsd-planner.md": "d5fa8236f975aacd",
|
||||
"agents/gsd-project-researcher.md": "425a7df7f37a5c06",
|
||||
"agents/gsd-research-synthesizer.md": "9d31c87fc2c87ffa",
|
||||
"agents/gsd-roadmapper.md": "64dce5d5f9fa5654",
|
||||
@@ -115,6 +115,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "8f598e08696843c0",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "a3874d80bcbc7380",
|
||||
"agents/gsd-eval-auditor.md": "630d4cd3bd6ea195",
|
||||
"agents/gsd-eval-planner.md": "3db12cde12aeb2c1",
|
||||
"agents/gsd-executor.md": "c53d111b0c795f7c",
|
||||
"agents/gsd-executor.md": "73278ea652cac62f",
|
||||
"agents/gsd-framework-selector.md": "ad5f2c6b9bec6270",
|
||||
"agents/gsd-integration-checker.md": "c503e2f4a3d8ec05",
|
||||
"agents/gsd-intel-updater.md": "231393da62a45b2e",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "6a5408fd11d70391",
|
||||
"agents/gsd-phase-researcher.md": "94818f28c498bb26",
|
||||
"agents/gsd-plan-checker.md": "56164206242c8caf",
|
||||
"agents/gsd-planner.md": "1fbe1f6e9c3b74f0",
|
||||
"agents/gsd-planner.md": "13c4b6db72b6bbb3",
|
||||
"agents/gsd-project-researcher.md": "60573a38d3dfd9fe",
|
||||
"agents/gsd-research-synthesizer.md": "1f7cd286c5783c86",
|
||||
"agents/gsd-roadmapper.md": "277e0a3252553ab7",
|
||||
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "ca7a7af3f35ae61b",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
"agents/subagents/gsd-eval-auditor.yaml": "e3d868bd5fefe938",
|
||||
"agents/subagents/gsd-eval-planner.md": "70f8c5727bfb9876",
|
||||
"agents/subagents/gsd-eval-planner.yaml": "df8499f7af297ec2",
|
||||
"agents/subagents/gsd-executor.md": "948d122c6607e343",
|
||||
"agents/subagents/gsd-executor.md": "20cf0b2aa886d35c",
|
||||
"agents/subagents/gsd-executor.yaml": "e29422986636fd64",
|
||||
"agents/subagents/gsd-framework-selector.md": "a15b7aa1e0576e16",
|
||||
"agents/subagents/gsd-framework-selector.yaml": "fb52c31cde27b0e3",
|
||||
@@ -79,7 +79,7 @@
|
||||
"agents/subagents/gsd-phase-researcher.yaml": "7633c8e82617e7cc",
|
||||
"agents/subagents/gsd-plan-checker.md": "bd302afc01ed40f0",
|
||||
"agents/subagents/gsd-plan-checker.yaml": "8295181071121db8",
|
||||
"agents/subagents/gsd-planner.md": "aaaac708b1cf2939",
|
||||
"agents/subagents/gsd-planner.md": "d29376ff9f57cc60",
|
||||
"agents/subagents/gsd-planner.yaml": "2e83ee194bcd7fbd",
|
||||
"agents/subagents/gsd-project-researcher.md": "39bc2ec5a8b18283",
|
||||
"agents/subagents/gsd-project-researcher.yaml": "ce12586b0347e2dc",
|
||||
@@ -179,6 +179,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "ca7a7af3f35ae61b",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "71250e759ca9e723",
|
||||
"agents/gsd-eval-auditor.md": "c88890105f32ace6",
|
||||
"agents/gsd-eval-planner.md": "60bddb70a937f796",
|
||||
"agents/gsd-executor.md": "4f180ee85214abe8",
|
||||
"agents/gsd-executor.md": "84c0a7dc19ddb6c5",
|
||||
"agents/gsd-framework-selector.md": "1c0a10355e787675",
|
||||
"agents/gsd-integration-checker.md": "a9de5928e5a5c649",
|
||||
"agents/gsd-intel-updater.md": "493e07482fa6198a",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "7c6d1d9817a9c1e7",
|
||||
"agents/gsd-phase-researcher.md": "9874110700b41f48",
|
||||
"agents/gsd-plan-checker.md": "28ca3dc43669894f",
|
||||
"agents/gsd-planner.md": "4e568338c7ee6b80",
|
||||
"agents/gsd-planner.md": "87d1aa910eb02ad5",
|
||||
"agents/gsd-project-researcher.md": "dae210ae0b3c6e2b",
|
||||
"agents/gsd-research-synthesizer.md": "e02c6ad5d1b74171",
|
||||
"agents/gsd-roadmapper.md": "1658a40b20d8b575",
|
||||
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "97f6e67b56c072c1",
|
||||
"gsd-core/references/planner-mvp-mode.md": "35d30284ea9110c0",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
1
tests/fixtures/golden-install-parity/pi.json
vendored
1
tests/fixtures/golden-install-parity/pi.json
vendored
@@ -82,6 +82,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "ca7a7af3f35ae61b",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "bd054bb27beed2a7",
|
||||
"agents/gsd-eval-auditor.md": "57cc7458ab5de6b7",
|
||||
"agents/gsd-eval-planner.md": "01b665728dde4ccf",
|
||||
"agents/gsd-executor.md": "988960899bd49c68",
|
||||
"agents/gsd-executor.md": "6dcccfef842a49ac",
|
||||
"agents/gsd-framework-selector.md": "82ba6abea84226b7",
|
||||
"agents/gsd-integration-checker.md": "90835dbc7dfa1691",
|
||||
"agents/gsd-intel-updater.md": "3cc4f6ddd04676ec",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "83c66c7722e8b165",
|
||||
"agents/gsd-phase-researcher.md": "284e55a86ae46d7f",
|
||||
"agents/gsd-plan-checker.md": "c8a8fcc8ed38eff0",
|
||||
"agents/gsd-planner.md": "75989c686d191143",
|
||||
"agents/gsd-planner.md": "f0a5bede90f23be4",
|
||||
"agents/gsd-project-researcher.md": "b5baac64a15c85e2",
|
||||
"agents/gsd-research-synthesizer.md": "6cd9b501dc97bd50",
|
||||
"agents/gsd-roadmapper.md": "c357a77ab919e9e5",
|
||||
@@ -115,6 +115,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "3f6f5ee62d86f72d",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "b80f76874c04e515",
|
||||
"agents/gsd-eval-auditor.md": "470bf16303ec4d2e",
|
||||
"agents/gsd-eval-planner.md": "22334fde85723c9d",
|
||||
"agents/gsd-executor.md": "2e92d53ec70b614f",
|
||||
"agents/gsd-executor.md": "b3baa767abac0593",
|
||||
"agents/gsd-framework-selector.md": "7726fccc86bfeb50",
|
||||
"agents/gsd-integration-checker.md": "7cd2072984411c7f",
|
||||
"agents/gsd-intel-updater.md": "83de6ba9172891c3",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "b5d7a4abb1baecb9",
|
||||
"agents/gsd-phase-researcher.md": "2256f1f82212c757",
|
||||
"agents/gsd-plan-checker.md": "523119bd5d6599fe",
|
||||
"agents/gsd-planner.md": "3cbce9388340c855",
|
||||
"agents/gsd-planner.md": "fb330c599b9c1dac",
|
||||
"agents/gsd-project-researcher.md": "ddf7794e81300032",
|
||||
"agents/gsd-research-synthesizer.md": "a124b00271748d07",
|
||||
"agents/gsd-roadmapper.md": "493ef92b42b12cf4",
|
||||
@@ -115,6 +115,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "9a9383599893ea7e",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "56395dbdabf076f6",
|
||||
"agents/gsd-eval-auditor.md": "fb64fc5acf359747",
|
||||
"agents/gsd-eval-planner.md": "2049dac060d00eda",
|
||||
"agents/gsd-executor.md": "5d56ba16562745d0",
|
||||
"agents/gsd-executor.md": "45c4632bc67a12a2",
|
||||
"agents/gsd-framework-selector.md": "4b77eebbe9288d80",
|
||||
"agents/gsd-integration-checker.md": "4ffb37fb230c2b90",
|
||||
"agents/gsd-intel-updater.md": "a81d77c143c02108",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "ada0c169daa2f0ec",
|
||||
"agents/gsd-phase-researcher.md": "2a45ebde829555ec",
|
||||
"agents/gsd-plan-checker.md": "33fbf70b7b24eb1e",
|
||||
"agents/gsd-planner.md": "c4072a4678c17485",
|
||||
"agents/gsd-planner.md": "61ac0bd59b5b836a",
|
||||
"agents/gsd-project-researcher.md": "f6697b316b5995ba",
|
||||
"agents/gsd-research-synthesizer.md": "04036f38c1d373ea",
|
||||
"agents/gsd-roadmapper.md": "fb62e1e3de84b5f9",
|
||||
@@ -115,6 +115,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "18d50b6d12db830e",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"agents/gsd-domain-researcher.md": "049f588663814fa2",
|
||||
"agents/gsd-eval-auditor.md": "54870d3b07433525",
|
||||
"agents/gsd-eval-planner.md": "552e9fa164c51ce8",
|
||||
"agents/gsd-executor.md": "b49a6d92b2cd9831",
|
||||
"agents/gsd-executor.md": "59fbb1e047b9a7c4",
|
||||
"agents/gsd-framework-selector.md": "8a795f230436ad2e",
|
||||
"agents/gsd-integration-checker.md": "c1760a0bbd4f7bf5",
|
||||
"agents/gsd-intel-updater.md": "944f1d903e2e9e09",
|
||||
@@ -25,7 +25,7 @@
|
||||
"agents/gsd-pattern-mapper.md": "68ecefd60811a669",
|
||||
"agents/gsd-phase-researcher.md": "2235f61764d8e969",
|
||||
"agents/gsd-plan-checker.md": "bb38f345d3d41edc",
|
||||
"agents/gsd-planner.md": "e76def94ab518216",
|
||||
"agents/gsd-planner.md": "42f6e9832d5c2edc",
|
||||
"agents/gsd-project-researcher.md": "f572892f138734ff",
|
||||
"agents/gsd-research-synthesizer.md": "29949bf3f049a8f1",
|
||||
"agents/gsd-roadmapper.md": "840ac933e3b094f9",
|
||||
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md": "b28fa3da6ae739a8",
|
||||
"gsd-core/references/planner-load-graph-context.md": "ca7a7af3f35ae61b",
|
||||
"gsd-core/references/planner-mvp-mode.md": "cfd535c9c545e73e",
|
||||
"gsd-core/references/planner-preconditions.md": "4511829607ec9107",
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
|
||||
1
tests/fixtures/install-tree/antigravity.json
vendored
1
tests/fixtures/install-tree/antigravity.json
vendored
@@ -115,6 +115,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/augment.json
vendored
1
tests/fixtures/install-tree/augment.json
vendored
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/claude.json
vendored
1
tests/fixtures/install-tree/claude.json
vendored
@@ -114,6 +114,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/cline.json
vendored
1
tests/fixtures/install-tree/cline.json
vendored
@@ -118,6 +118,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/codebuddy.json
vendored
1
tests/fixtures/install-tree/codebuddy.json
vendored
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/codex.json
vendored
1
tests/fixtures/install-tree/codex.json
vendored
@@ -221,6 +221,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/copilot.json
vendored
1
tests/fixtures/install-tree/copilot.json
vendored
@@ -116,6 +116,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/cursor.json
vendored
1
tests/fixtures/install-tree/cursor.json
vendored
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/hermes.json
vendored
1
tests/fixtures/install-tree/hermes.json
vendored
@@ -115,6 +115,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/kilo.json
vendored
1
tests/fixtures/install-tree/kilo.json
vendored
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/kimi.json
vendored
1
tests/fixtures/install-tree/kimi.json
vendored
@@ -179,6 +179,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/opencode.json
vendored
1
tests/fixtures/install-tree/opencode.json
vendored
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/pi.json
vendored
1
tests/fixtures/install-tree/pi.json
vendored
@@ -82,6 +82,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/qwen.json
vendored
1
tests/fixtures/install-tree/qwen.json
vendored
@@ -115,6 +115,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/trae.json
vendored
1
tests/fixtures/install-tree/trae.json
vendored
@@ -115,6 +115,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/windsurf.json
vendored
1
tests/fixtures/install-tree/windsurf.json
vendored
@@ -115,6 +115,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
1
tests/fixtures/install-tree/zcode.json
vendored
1
tests/fixtures/install-tree/zcode.json
vendored
@@ -186,6 +186,7 @@
|
||||
"gsd-core/references/planner-interface-context.md",
|
||||
"gsd-core/references/planner-load-graph-context.md",
|
||||
"gsd-core/references/planner-mvp-mode.md",
|
||||
"gsd-core/references/planner-preconditions.md",
|
||||
"gsd-core/references/planner-reviews.md",
|
||||
"gsd-core/references/planner-revision.md",
|
||||
"gsd-core/references/planner-source-audit.md",
|
||||
|
||||
233
tests/precondition-element.test.cjs
Normal file
233
tests/precondition-element.test.cjs
Normal file
@@ -0,0 +1,233 @@
|
||||
// allow-test-rule: source-text-is-the-product [#1949]
|
||||
// Agent .md, reference .md, and docs/reference/*.md files — their text IS what the
|
||||
// runtime loads. Per CONTRIBUTING.md exception matrix, asserting these files
|
||||
// document the <precondition> contract tests the deployed surface, not derived
|
||||
// behavior. The behavioral test (cmdVerifyPlanStructure) asserts the validator
|
||||
// stays additive. Issue #1949.
|
||||
|
||||
'use strict';
|
||||
|
||||
const { describe, test } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
|
||||
const ROOT = path.resolve(__dirname, '..');
|
||||
const PLANNER = path.join(ROOT, 'agents', 'gsd-planner.md');
|
||||
const EXECUTOR = path.join(ROOT, 'agents', 'gsd-executor.md');
|
||||
const PLAN_MD_DOC = path.join(ROOT, 'docs', 'reference', 'plan-md.md');
|
||||
const PRECONDITIONS_REF = path.join(ROOT, 'gsd-core', 'references', 'planner-preconditions.md');
|
||||
|
||||
function read(rel) {
|
||||
return fs.readFileSync(rel, 'utf-8').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
||||
}
|
||||
|
||||
// ─── Schema documentation (docs/reference/plan-md.md) ────────────────────────
|
||||
|
||||
describe('issue #1949: plan-md.md documents <precondition>', () => {
|
||||
test('plan-md.md mentions <precondition> as an optional task element', () => {
|
||||
const doc = read(PLAN_MD_DOC);
|
||||
assert.match(
|
||||
doc,
|
||||
/<precondition>/,
|
||||
'docs/reference/plan-md.md must document the <precondition> element'
|
||||
);
|
||||
});
|
||||
|
||||
test('plan-md.md states <precondition> is optional and does not break plans that omit it', () => {
|
||||
const doc = read(PLAN_MD_DOC);
|
||||
assert.ok(
|
||||
/optional/.test(doc) && /precondition/.test(doc),
|
||||
'plan-md.md must describe <precondition> as optional'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Planner emission contract (agents/gsd-planner.md) ──────────────────────
|
||||
|
||||
describe('issue #1949: gsd-planner.md declares <precondition> emission', () => {
|
||||
test('planner references the precondition reference file', () => {
|
||||
const planner = read(PLANNER);
|
||||
assert.ok(
|
||||
planner.includes('planner-preconditions.md'),
|
||||
'gsd-planner.md must @-reference planner-preconditions.md (progressive disclosure)'
|
||||
);
|
||||
});
|
||||
|
||||
test('planner is under the 49152-char cap after adding <precondition> content', () => {
|
||||
const planner = read(PLANNER);
|
||||
assert.ok(
|
||||
planner.length < 49152,
|
||||
`gsd-planner.md is ${planner.length} chars, must be < 49152 (LF-normalized)`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Planner-preconditions reference file (progressive disclosure) ───────────
|
||||
|
||||
describe('issue #1949: planner-preconditions.md exists with the three emission cases', () => {
|
||||
test('reference file exists', () => {
|
||||
assert.ok(fs.existsSync(PRECONDITIONS_REF), `Missing: ${PRECONDITIONS_REF}`);
|
||||
});
|
||||
|
||||
test('reference documents the user_setup emission case', () => {
|
||||
const ref = read(PRECONDITIONS_REF);
|
||||
assert.ok(
|
||||
/user_setup/.test(ref) || /external service setup/i.test(ref),
|
||||
'planner-preconditions.md must document the user_setup / external-setup emission case'
|
||||
);
|
||||
});
|
||||
|
||||
test('reference documents the prior-phase artifact emission case', () => {
|
||||
const ref = read(PRECONDITIONS_REF);
|
||||
assert.ok(
|
||||
/prior.?phase artifact/i.test(ref) || /artifact from (a )?prior/i.test(ref),
|
||||
'planner-preconditions.md must document the prior-phase-artifact emission case'
|
||||
);
|
||||
});
|
||||
|
||||
test('reference documents the env-var emission case', () => {
|
||||
const ref = read(PRECONDITIONS_REF);
|
||||
assert.ok(
|
||||
/env(ironment)? var/i.test(ref),
|
||||
'planner-preconditions.md must document the env-var emission case'
|
||||
);
|
||||
});
|
||||
|
||||
test('reference maps the contract triad (precondition / postcondition / invariant)', () => {
|
||||
const ref = read(PRECONDITIONS_REF);
|
||||
assert.ok(
|
||||
/postcondition|<verify>|<done>/.test(ref),
|
||||
'planner-preconditions.md must map <precondition> to existing postconditions (<verify>/<done>)'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Executor assertion contract (agents/gsd-executor.md) ────────────────────
|
||||
|
||||
describe('issue #1949: gsd-executor.md asserts <precondition> before task execution', () => {
|
||||
test('executor mentions <precondition>', () => {
|
||||
const exec = read(EXECUTOR);
|
||||
assert.match(
|
||||
exec,
|
||||
/<precondition>/,
|
||||
'gsd-executor.md must reference <precondition>'
|
||||
);
|
||||
});
|
||||
|
||||
test('executor routes an unmet precondition through checkpoint machinery (halt, no partial commit)', () => {
|
||||
const exec = read(EXECUTOR);
|
||||
assert.ok(
|
||||
/precondition/i.test(exec) && /checkpoint/.test(exec),
|
||||
'gsd-executor.md must route unmet <precondition> through checkpoint machinery'
|
||||
);
|
||||
});
|
||||
|
||||
test('executor treats a met/absent precondition as a no-op (does not change flow)', () => {
|
||||
const exec = read(EXECUTOR);
|
||||
assert.ok(
|
||||
/no.op|no visible change|continue/i.test(exec),
|
||||
'gsd-executor.md must state that a met or absent precondition produces no visible change'
|
||||
);
|
||||
});
|
||||
|
||||
test('executor is under the 49152-char cap after adding <precondition> content', () => {
|
||||
const exec = read(EXECUTOR);
|
||||
assert.ok(
|
||||
exec.length < 49152,
|
||||
`gsd-executor.md is ${exec.length} chars, must be < 49152 (LF-normalized)`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Behavioral test: validator stays additive (cmdVerifyPlanStructure) ──────
|
||||
//
|
||||
// `cmdVerifyPlanStructure` checks for PRESENCE of required tags. It must not
|
||||
// reject unknown optional tags. This is the "does not break plans that omit it"
|
||||
// plus "does not break plans that include it" guarantee from acceptance #1.
|
||||
// Pattern mirrors tests/tracer-bullet.test.cjs (companion feature #1945).
|
||||
|
||||
function planWith({ precondition = null } = {}) {
|
||||
const lines = [
|
||||
'<task type="auto">',
|
||||
' <name>Task 1: Test</name>',
|
||||
];
|
||||
if (precondition !== null) {
|
||||
lines.push(` <precondition>${precondition}</precondition>`);
|
||||
}
|
||||
lines.push(
|
||||
' <files>src/x.ts</files>',
|
||||
' <action>Do the thing.</action>',
|
||||
' <verify><automated>echo ok</automated></verify>',
|
||||
' <done>Done</done>',
|
||||
'</task>',
|
||||
'',
|
||||
);
|
||||
return [
|
||||
'---',
|
||||
'phase: 01-test',
|
||||
'plan: 01',
|
||||
'type: execute',
|
||||
'wave: 1',
|
||||
'depends_on: []',
|
||||
'files_modified: [src/x.ts]',
|
||||
'autonomous: true',
|
||||
'must_haves:',
|
||||
' truths:',
|
||||
' - "something is true"',
|
||||
'---',
|
||||
'',
|
||||
'<tasks>',
|
||||
'',
|
||||
...lines,
|
||||
'</tasks>',
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
function verifyPlan(tmpDir, content) {
|
||||
const rel = path.join('.planning', 'phases', '01-test', '01-01-PLAN.md');
|
||||
fs.mkdirSync(path.join(tmpDir, '.planning', 'phases', '01-test'), { recursive: true });
|
||||
fs.writeFileSync(path.join(tmpDir, rel), content);
|
||||
const result = runGsdTools(`verify plan-structure ${rel}`, tmpDir);
|
||||
assert.ok(result.success, `verify plan-structure failed to run: ${result.error}`);
|
||||
return JSON.parse(result.output);
|
||||
}
|
||||
|
||||
describe('issue #1949: cmdVerifyPlanStructure accepts <precondition> (additive)', () => {
|
||||
test('plan with <precondition> passes structural validation', (t) => {
|
||||
const tmp = createTempProject();
|
||||
t.after(() => cleanup(tmp));
|
||||
|
||||
const out = verifyPlan(tmp, planWith({ precondition: 'OPENAI_API_KEY is set in the environment' }));
|
||||
assert.strictEqual(out.valid, true, `plan with <precondition> must be valid, errors: ${JSON.stringify(out.errors)}`);
|
||||
assert.deepStrictEqual(out.errors, [], 'no validation path may reject a <precondition> task');
|
||||
assert.ok(
|
||||
!(out.warnings || []).some((w) => /precondition/i.test(w)),
|
||||
'nothing may flag the <precondition> element specifically',
|
||||
);
|
||||
});
|
||||
|
||||
test('plan without <precondition> still passes structural validation (back-compat)', (t) => {
|
||||
const tmp = createTempProject();
|
||||
t.after(() => cleanup(tmp));
|
||||
|
||||
const out = verifyPlan(tmp, planWith({ precondition: null }));
|
||||
assert.strictEqual(out.valid, true, `plan without <precondition> must be valid (back-compat), errors: ${JSON.stringify(out.errors)}`);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Parity: docs/reference/plan-md.md and planner-preconditions.md agree ────
|
||||
//
|
||||
// DEFECT.GENERATIVE-FIX-DIVERGENCE: two surfaces describing the same schema
|
||||
// must agree on the canonical tag spelling. This is the parity guard against
|
||||
// silent drift.
|
||||
|
||||
describe('issue #1949: parity between plan-md.md and planner-preconditions.md', () => {
|
||||
test('both surfaces spell the canonical tag <precondition>', () => {
|
||||
const doc = read(PLAN_MD_DOC);
|
||||
const ref = read(PRECONDITIONS_REF);
|
||||
assert.ok(doc.includes('<precondition>'), 'plan-md.md must spell <precondition>');
|
||||
assert.ok(ref.includes('<precondition>'), 'planner-preconditions.md must spell <precondition>');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user