From df352cf012aa420eea67c7ea43bc0716808a3310 Mon Sep 17 00:00:00 2001 From: Andy Dalton Date: Fri, 4 Sep 2026 15:46:58 -0400 Subject: [PATCH 1/4] refactor(workflows): support demand-loaded routing Generalize workflow conventions and phase override completion contracts for lightweight dispatchers and centralized completion guidance. Assisted-by: Codex --- .coderabbit.yaml | 52 ++++++++++++++------ AGENTS.md | 12 +++-- CONTRIBUTING.md | 48 ++++++++++++------ _shared/recipes/phase-override-resolution.md | 9 ++-- bugfix/SKILL.md | 2 +- code-review/SKILL.md | 2 +- cve-fix/SKILL.md | 2 +- design/SKILL.md | 2 +- docs-writer/SKILL.md | 2 +- implement/SKILL.md | 2 +- kcs/SKILL.md | 2 +- prd/SKILL.md | 2 +- sizing/SKILL.md | 7 ++- 13 files changed, 94 insertions(+), 50 deletions(-) diff --git a/.coderabbit.yaml b/.coderabbit.yaml index b5ec2673..5a3b2bb4 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -61,8 +61,9 @@ reviews: - label: "workflow-structure" instructions: >- Apply when the PR changes SKILL.md, guidelines.md, controller.md, - or adds/removes/renames files in skills/ or commands/ directories. - Structural changes affect how AI agents discover and execute workflows. + dispatch.md, completion.md, or adds/removes/renames files in skills/ + or commands/ directories. Structural changes affect how AI agents + discover and execute workflows. - label: "new-workflow" instructions: >- @@ -153,15 +154,21 @@ reviews: step-by-step instructions or decision logic - Must include $ARGUMENTS placeholder to pass user context - Path references must be relative to the command file's location: - use ../skills/controller.md or ../SKILL.md, not absolute paths - and not skills/controller.md (missing ../ prefix) - - Every command must have a corresponding skill file it routes to + use ../skills/controller.md, ../skills/dispatch.md, ../SKILL.md, + or a direct phase-skill path; do not use absolute paths or omit + the required ../ prefix + - Every command must route to its corresponding phase, either through + a direct file reference or an explicit phase parameter passed to a + dispatcher (for example, PHASE=assess) - No IDE-specific syntax - # ── Phase skill files ─────────────────────────────────────── + # ── Workflow skill files ──────────────────────────────────── - path: "*/skills/*.md" instructions: | - Phase skill review (ai-workflows conventions): + Workflow skill review (ai-workflows conventions): + - First classify the file as a phase implementation, controller, + dispatcher, completion guide, or other support file. Apply + phase-specific rules only to phase implementations. - Maximum 10 steps per skill invocation — flag if exceeded (cognitive load / context window risk for AI agents) - Main steps must be numbered sequentially: no gaps, no @@ -174,8 +181,17 @@ reviews: - Synthesis tasks (summarization, assessment, verdict) must NOT be buried after heavy per-item processing — they degrade in long contexts - - controller.md must reference sibling skills as phase-name.md - (not skills/phase-name.md) — relative to its own directory + - controller.md, dispatch.md, and completion.md must reference sibling + skill files as file-name.md (not skills/file-name.md) — relative to + their own directory + - A controller may centrally dispatch phases and own transitions, or + limit itself to discovery and ambiguous-input routing when explicit + commands use a lightweight dispatcher + - A dispatcher must remain a thin router: resolve the requested phase, + preserve override behavior and context, and delegate transition + decisions rather than implementing phase logic + - A completion guide may centralize next-step recommendations so phase + files do not duplicate the workflow transition model - Skills referencing _shared/ resources must use the correct relative path depth (e.g., ../../_shared/recipes/self-review-gate.md from skills/) @@ -699,20 +715,28 @@ reviews: that exist. Flag references to files that don't exist (dangling references). Also flag skill or command files that exist but are never referenced from SKILL.md, controller.md, or any - command file (orphaned files). For skills/* simple skills, require + command file (orphaned files). Treat an explicit dispatcher parameter + such as PHASE=assess as a reference to skills/assess.md when the + dispatcher documents that mapping. Treat files referenced by a + reachable dispatcher or completion guide as reachable. For skills/* + simple skills, require only that supporting resources are reachable from SKILL.md or another reachable reference; do not require workflow-specific files. mode: "warning" - name: "no-content-duplication" instructions: | - When any of SKILL.md, guidelines.md, or controller.md in a - workflow is changed, compare it against whichever of the other - two files are present and check for verbatim duplication of + When any of SKILL.md, guidelines.md, controller.md, dispatch.md, or + completion.md in a workflow is changed, compare it against the other + architectural files that are present and check for duplication of multi-line instruction blocks or paragraphs. Each has a distinct role: SKILL.md is the thin entry point, guidelines.md holds principles/limits/ - safety/quality/escalation, controller.md manages phase dispatch. + safety/quality/escalation. A controller may own centralized phase + routing and transitions; in a demand-loaded design it handles + discovery and ambiguous routing, dispatch.md handles explicit phase + routing, and completion.md may hold the authoritative transition + model. Phase names and brief one-line descriptions appearing in multiple files is EXPECTED (cross-referencing, not duplication) — only flag substantial blocks of identical prose or diff --git a/AGENTS.md b/AGENTS.md index 23970470..2a035646 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,10 +37,12 @@ workflow-name/ guidelines.md # Behavioral rules: principles, hard limits, safety, quality README.md # Human-readable documentation (prerequisites, artifacts, usage) skills/ - controller.md # Optional phase dispatcher + controller.md # Optional discovery and ambiguous-input router + dispatch.md # Optional lightweight explicit-phase dispatcher + completion.md # Optional centralized next-step guidance phase-name.md # Implementation for each phase commands/ - phase-name.md # Thin wrappers that invoke controller or SKILL.md + phase-name.md # Thin wrappers that invoke a controller, dispatcher, SKILL.md, or phase scripts/ # Optional — deterministic operations invoked by skills prompts/ # Optional — prompt templates for sub-agent delegation ``` @@ -69,7 +71,7 @@ guidelines, README, or artifact lifecycle by default. 3. **Relative paths**: All file references must be relative to the file's location (for symlink compatibility) 4. **Phase-based execution**: Most workflows operate through discrete phases with explicit transitions 5. **Shared resources**: Cross-cutting concerns live in `_shared/` and are referenced by relative path from workflows or simple skills -6. **Phase overrides**: Projects can override individual phases by placing a replacement skill file at `.workflows/{workflow}/skills/{phase}.md` in their repo root. The controller checks for this override before falling back to the built-in default. See CONTRIBUTING.md for details. +6. **Phase overrides**: Projects can override individual phases by placing a replacement skill file at `.workflows/{workflow}/skills/{phase}.md` in their repo root. The controller or lightweight dispatcher checks for this override before falling back to the built-in default. See CONTRIBUTING.md for details. ### Shared Resources (`_shared/`) @@ -95,8 +97,8 @@ Recipes are self-contained, parameterized procedures that packages reference via ### File Reference Conventions Critical for symlink resolution: -- `commands/*.md` reference `../skills/controller.md` (if workflow has a controller) or `../SKILL.md` (for workflows without a controller) or `../skills/phase-name.md` (direct phase reference) -- `skills/controller.md` (when present) references sibling skills as `phase-name.md` (not `skills/phase-name.md`) +- `commands/*.md` reference `../skills/controller.md`, `../skills/dispatch.md`, `../SKILL.md`, or `../skills/phase-name.md`; dispatchers identify the target with an explicit phase parameter +- `skills/controller.md`, `skills/dispatch.md`, and `skills/completion.md` reference sibling skills as `phase-name.md` (not `skills/phase-name.md`) - `SKILL.md` references `guidelines.md` and optionally `skills/controller.md` (same directory) - `skills/{skill-name}/SKILL.md` references its resources relative to the simple skill directory (for example, `references/rendering.md`) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a41d13ff..df594f3a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,10 +37,12 @@ workflow-name/ guidelines.md # Behavioral rules: principles, hard limits, safety, quality, escalation README.md # Human-readable documentation skills/ - controller.md # Optional -- phase dispatch, transitions, next-step recommendations + controller.md # Optional -- workflow routing and orchestration + dispatch.md # Optional -- lightweight explicit-phase dispatch + completion.md # Optional -- centralized next-step recommendations phase-name.md # One file per phase commands/ - phase-name.md # Thin wrappers that invoke the controller or SKILL.md for a specific phase + phase-name.md # Thin wrappers that invoke a router, SKILL.md, or phase Project-level phase overrides (in the consuming repo): @@ -78,12 +80,16 @@ Some workflows use a controller to manage phase execution and transitions. This - List all phases with references to sibling skill files (e.g. `assess.md`, not `skills/assess.md`). - Define how to execute a phase (announce, read, execute, report, wait). -- Provide next-step recommendations after each phase. +- Provide next-step recommendations after each phase, directly or through a + dedicated completion guide. - Never auto-advance -- always wait for the user. ### skills/phase-name.md -Each phase skill contains the detailed steps for that phase. At the end, it should instruct the agent to report findings and re-read the controller for next-step guidance. +Each phase skill contains the detailed steps for that phase. At the end, it +should report findings and follow the workflow's completion contract: either +return to the invoking router, read a completion guide, or re-read the +controller, as defined by that workflow. ### commands/phase-name.md @@ -99,13 +105,21 @@ Dispatch the **phase-name** phase. Context: $ARGUMENTS ``` -The path `../skills/controller.md` is relative to the command file's location inside `commands/`. If the workflow has no controller, commands can reference `../SKILL.md` or the phase skill directly. +The path `../skills/controller.md` is relative to the command file's location +inside `commands/`. A workflow may instead use a lightweight +`../skills/dispatch.md` from its command wrappers to resolve overrides and load +only the requested phase and a dedicated completion guide. Migrate workflows +separately so each change can account for its routing and override contracts. +If the workflow has no controller or dispatcher, its command wrapper or +`../SKILL.md` entry point must perform the same override resolution before +reading the resolved phase file. Never bypass override resolution by reading a +phase skill directly. ## Path Conventions All internal file references must be **relative to the file's own location**: -- `commands/*.md` reference the controller as `../skills/controller.md` (or `../SKILL.md` if no controller) +- `commands/*.md` reference `../skills/controller.md`, `../skills/dispatch.md`, `../SKILL.md`, or a phase skill directly - `skills/controller.md` (when present) references sibling skills as `assess.md`, `fix.md`, etc. - `SKILL.md` references `guidelines.md` and optionally `skills/controller.md` (both in the same directory) @@ -115,21 +129,23 @@ This ensures symlinks resolve paths correctly regardless of where the workflow i ## Phase Overrides -Projects can override individual phase skills without forking the workflow. When a controller dispatches a phase, it checks for a project-level override before falling back to the built-in default: +Projects can override individual phase skills without forking the workflow. Every phase route—whether invoked through a controller, dispatcher, workflow entry point, or command wrapper—must resolve the phase filename and check for a project-level override before falling back to the built-in default: -1. **`.workflows/{workflow}/skills/{phase}.md`** — project-level override at the repo root -2. **`{phase}.md`** — workflow's built-in default (sibling file in `skills/`) +1. **`.workflows/{workflow}/skills/{phase-file}`** — project-level override at the repo root +2. **`{phase-file}`** — workflow's built-in default (sibling file in `skills/`) -For example, a team that needs a custom `/sync` phase for the design workflow drops a file at `.workflows/design/skills/sync.md` in their repo. The controller picks it up automatically and announces the override to the user. +For example, a team that needs a custom `/sync` phase for the design workflow drops a file at `.workflows/design/skills/sync.md` in their repo. The route resolves that file and announces the override to the user. -**Filename mapping.** Most workflows map `/phase` to `{phase}.md`, but some use different filenames. For example, docs-writer maps `/gather` to `gather-context.md` and `/plan` to `plan-structure.md`. Check the Phases list in the workflow's controller to find the correct filename for the override. +**Filename mapping.** Determine `{phase-file}` once from the workflow's routing documentation—its controller, dispatcher, or documented phase map—and use that same filename for both the project override and built-in fallback. Most workflows map `/phase` to `{phase}.md`, but some use different filenames. For example, docs-writer maps `/gather` to `gather-context.md` and `/plan` to `plan-structure.md`. ### Rules for Override Files -- **Start from a copy.** Copy the built-in phase file and modify it rather than writing from scratch. This avoids accidentally omitting contract scaffolding such as artifact paths, exit behavior, or the controller re-read instruction. +- **Start from a copy.** Copy the built-in phase file and modify it rather than writing from scratch. This avoids accidentally omitting contract scaffolding such as artifact paths and exit behavior. - **Full replacement.** An override replaces the entire phase — it is not merged with the built-in. The override file must be self-contained. -- **Same contract.** The override must read the same input artifacts and write the same output artifacts as the built-in phase. Downstream phases and the controller depend on this contract (see the Artifacts table in each controller). -- **Same exit behavior.** End the override file with the same "report findings and re-read the controller" instruction so the controller can recommend next steps. +- **Same contract.** The override must read the same input artifacts and write the same output artifacts as the built-in phase. Downstream phases and the workflow router depend on this contract (see the workflow's Artifacts table). +- **Same exit behavior.** Preserve the built-in phase's completion contract. + Depending on the workflow, that may return to the invoking router, read a + completion guide, or re-read the controller. - **No cross-references to built-in internals.** The override should not reference sibling files in the workflow's `skills/` directory — it lives in the project repo and should be self-contained. ### Version Control @@ -138,7 +154,7 @@ Commit `.workflows/` to the consuming repo. Overrides are team-level decisions ### Discoverability -When a project uses overrides, document them in the project's `CLAUDE.md` or `AGENTS.md` so newcomers know which phases behave differently from the built-in defaults. The controller announces overrides at runtime, but a static list prevents surprises when reading workflow documentation. +When a project uses overrides, document them in the project's `CLAUDE.md` or `AGENTS.md` so newcomers know which phases behave differently from the built-in defaults. The route announces project overrides at runtime, but a static list prevents surprises when reading workflow documentation. ### Example Project Layout @@ -254,7 +270,7 @@ for example `$bugfix assess`. 1. Install locally: `./install.sh cursor` (or `all`). 2. Open a Cursor project and reference the package to verify discovery. -3. For a workflow, run at least one phase and verify controller dispatch. For a +3. For a workflow, run at least one phase and verify its configured routing. For a simple skill, exercise its primary behavior and permission gates. 4. Run every changed script's tests and the same checks configured in CI. 5. Uninstall and reinstall to verify clean teardown: `./uninstall.sh && ./install.sh cursor`. diff --git a/_shared/recipes/phase-override-resolution.md b/_shared/recipes/phase-override-resolution.md index 9e171306..1003086c 100644 --- a/_shared/recipes/phase-override-resolution.md +++ b/_shared/recipes/phase-override-resolution.md @@ -1,6 +1,6 @@ --- name: phase-override-resolution -version: 0.1.0 +version: 0.1.1 --- # Recipe: Phase Override Resolution @@ -24,8 +24,11 @@ default. Use the first match found: 2. **`{PHASE_FILE}`** — workflow's built-in default (sibling file in `skills/`) If the override file exists but is empty, appears malformed, or does not -contain exit instructions to re-read the controller, warn the user and fall -back to the built-in default. +contain completion or exit guidance, warn the user and fall back to the +built-in default. Valid exit guidance may return control to the invoking +router, read a completion guide, or re-read a controller; require the same +behavioral contract as the workflow's built-in phase rather than one specific +routing architecture. If using a project override, announce it: *"Using project override for /{phase}."* diff --git a/bugfix/SKILL.md b/bugfix/SKILL.md index a1e3c054..ef99c1c3 100644 --- a/bugfix/SKILL.md +++ b/bugfix/SKILL.md @@ -1,6 +1,6 @@ --- name: bugfix -version: 0.7.0 +version: 0.7.1 description: >- Diagnostic and repair workflow that analyzes error logs, traces root causes, implements fixes, and verifies with regression tests. diff --git a/code-review/SKILL.md b/code-review/SKILL.md index 683328ff..80a22955 100644 --- a/code-review/SKILL.md +++ b/code-review/SKILL.md @@ -1,6 +1,6 @@ --- name: code-review -version: 0.4.0 +version: 0.4.1 description: >- AI-driven code review workflow that reviews uncommitted changes using a discoverable reviewer profile, presents findings for human decision, and diff --git a/cve-fix/SKILL.md b/cve-fix/SKILL.md index a3183a01..9d850e56 100644 --- a/cve-fix/SKILL.md +++ b/cve-fix/SKILL.md @@ -1,6 +1,6 @@ --- name: cve-fix -version: 0.4.0 +version: 0.4.1 description: >- Automated CVE remediation that reads vulnerability details from Jira vulnerability tickets, applies multi-strategy dependency fixes, validates diff --git a/design/SKILL.md b/design/SKILL.md index d75938a3..fdc4968f 100644 --- a/design/SKILL.md +++ b/design/SKILL.md @@ -1,6 +1,6 @@ --- name: design -version: 0.9.0 +version: 0.9.1 description: >- Design-and-decompose workflow that takes a PRD, researches the problem space, drafts a technical design document with a requirement-anchored testplan, diff --git a/docs-writer/SKILL.md b/docs-writer/SKILL.md index 69e919be..b4ca9873 100644 --- a/docs-writer/SKILL.md +++ b/docs-writer/SKILL.md @@ -1,6 +1,6 @@ --- name: docs-writer -version: 0.3.0 +version: 0.3.1 description: Documentation workflow that converts requirements into structured AsciiDoc sections, runs Vale for style compliance, and produces merge-ready content. Use when creating or updating AsciiDoc documentation from Jira tickets, GitHub issues, or feature descriptions. --- # Docs Writer Workflow Orchestrator diff --git a/implement/SKILL.md b/implement/SKILL.md index d122d10b..3f678a68 100644 --- a/implement/SKILL.md +++ b/implement/SKILL.md @@ -1,6 +1,6 @@ --- name: implement -version: 0.8.0 +version: 0.8.1 description: >- Story-to-code workflow that takes a Jira Story, plans the implementation, writes contract-based tests and production code via TDD, validates against diff --git a/kcs/SKILL.md b/kcs/SKILL.md index fa94f1fd..df81331b 100644 --- a/kcs/SKILL.md +++ b/kcs/SKILL.md @@ -1,6 +1,6 @@ --- name: kcs -version: 0.3.0 +version: 0.3.1 description: >- KCS article workflow that gathers bug context from Jira and user input, drafts a KCS Solution article in markdown, validates it against the KCS diff --git a/prd/SKILL.md b/prd/SKILL.md index b8f1a057..4e23ff38 100644 --- a/prd/SKILL.md +++ b/prd/SKILL.md @@ -1,6 +1,6 @@ --- name: prd -version: 0.9.0 +version: 0.9.1 description: >- Requirements-to-PRD workflow that ingests requirements from Jira, clarifies ambiguities through iterative Q&A, drafts a Product Requirements Document, diff --git a/sizing/SKILL.md b/sizing/SKILL.md index 0fe486e8..748e4312 100644 --- a/sizing/SKILL.md +++ b/sizing/SKILL.md @@ -1,6 +1,6 @@ --- name: sizing -version: 0.3.0 +version: 0.3.1 description: >- Pre-cycle Feature sizing workflow that assesses Features from Jira using T-shirt sizes (XS–XXL), produces per-team effort breakdowns (DEV, QE, UX, UI, DOCS), @@ -23,8 +23,7 @@ description: >- execute the `/ingest` phase in batch mode - Otherwise, ask the user for a Feature key or release identifier -If a step fails or produces unexpected output (e.g., Jira MCP errors, network -failures, invalid issue keys), stop and report the error to the user. Do not -advance to the next phase. Offer to retry the failed step or escalate. +If a step fails or produces unexpected output (e.g., Jira MCP errors, network failures, +invalid issue keys), stop and report the error to the user. Do not advance to the next phase. Offer to retry the failed step or escalate. For principles, hard limits, safety, quality, and escalation rules, see `guidelines.md`. From 0850943219f0a5fd13517376b6a0a54f7f487b89 Mon Sep 17 00:00:00 2001 From: Andy Dalton Date: Fri, 4 Sep 2026 15:47:15 -0400 Subject: [PATCH 2/4] refactor(e2e): demand-load phase routing Route explicit e2e phases through a lightweight dispatcher and centralize attended completion guidance without loading the full controller. Assisted-by: Codex --- e2e/README.md | 11 ++++- e2e/SKILL.md | 2 +- e2e/commands/code.md | 4 +- e2e/commands/ingest.md | 4 +- e2e/commands/plan.md | 4 +- e2e/commands/publish.md | 4 +- e2e/commands/respond.md | 4 +- e2e/commands/revise.md | 4 +- e2e/commands/validate.md | 4 +- e2e/skills/code.md | 2 +- e2e/skills/completion.md | 36 ++++++++++++++++ e2e/skills/controller.md | 92 ++++++---------------------------------- e2e/skills/dispatch.md | 22 ++++++++++ e2e/skills/ingest.md | 2 +- e2e/skills/plan.md | 2 +- e2e/skills/publish.md | 4 +- e2e/skills/respond.md | 2 +- e2e/skills/revise.md | 2 +- e2e/skills/validate.md | 2 +- 19 files changed, 104 insertions(+), 103 deletions(-) create mode 100644 e2e/skills/completion.md create mode 100644 e2e/skills/dispatch.md diff --git a/e2e/README.md b/e2e/README.md index 88bd8536..abba176c 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -40,6 +40,13 @@ graph TD | Publish | `/publish` | Push branch, create draft PR | `06-pr-description.md` | | Respond | `/respond` | Address reviewer comments | `07-review-responses.md` | +Each phase command invokes `skills/dispatch.md` with the requested phase. The +dispatcher resolves any project override, loads only that phase, and passes +along the command context. After the phase reports its result, +`skills/completion.md` supplies the shared next-step guidance without loading +the full controller. The controller remains the entry point for workflow +discovery and ambiguous requests. + ## Typical Flow ```text @@ -143,7 +150,9 @@ e2e/ ├── guidelines.md # Behavioral rules and guardrails ├── README.md # This file ├── skills/ -│ ├── controller.md # Phase dispatcher and transitions +│ ├── controller.md # Discovery and ambiguous-input router +│ ├── dispatch.md # Explicit-phase dispatcher +│ ├── completion.md # Shared next-step guidance │ ├── ingest.md # Fetch story, explore e2e infrastructure │ ├── plan.md # Map ACs to test scenarios │ ├── revise.md # Incorporate plan feedback diff --git a/e2e/SKILL.md b/e2e/SKILL.md index 8ee655a1..3fd17b10 100644 --- a/e2e/SKILL.md +++ b/e2e/SKILL.md @@ -1,6 +1,6 @@ --- name: e2e -version: 0.6.0 +version: 0.7.0 description: >- Story-to-e2e-test workflow that takes a Jira [QE] Story, discovers the project's e2e testing infrastructure, plans test scenarios, writes e2e diff --git a/e2e/commands/code.md b/e2e/commands/code.md index e5c5f455..f76808c9 100644 --- a/e2e/commands/code.md +++ b/e2e/commands/code.md @@ -4,8 +4,8 @@ description: "Write e2e test code following discovered patterns, committing incr --- # /code -Read `../skills/controller.md` and follow it. +Read `../skills/dispatch.md` and follow it with `PHASE=code`. -Dispatch the **code** phase. Context: +Context: $ARGUMENTS diff --git a/e2e/commands/ingest.md b/e2e/commands/ingest.md index 52f143f1..ff5e013f 100644 --- a/e2e/commands/ingest.md +++ b/e2e/commands/ingest.md @@ -4,8 +4,8 @@ description: "Fetch [QE] story, verify dependencies, explore e2e infrastructure, --- # /ingest -Read `../skills/controller.md` and follow it. +Read `../skills/dispatch.md` and follow it with `PHASE=ingest`. -Dispatch the **ingest** phase. Context: +Context: $ARGUMENTS diff --git a/e2e/commands/plan.md b/e2e/commands/plan.md index a6f8b560..075595e6 100644 --- a/e2e/commands/plan.md +++ b/e2e/commands/plan.md @@ -4,8 +4,8 @@ description: "Map acceptance criteria to e2e test scenarios, select reference su --- # /plan -Read `../skills/controller.md` and follow it. +Read `../skills/dispatch.md` and follow it with `PHASE=plan`. -Dispatch the **plan** phase. Context: +Context: $ARGUMENTS diff --git a/e2e/commands/publish.md b/e2e/commands/publish.md index d6f2e550..0b521a13 100644 --- a/e2e/commands/publish.md +++ b/e2e/commands/publish.md @@ -4,8 +4,8 @@ description: "Push feature branch and create draft PR for e2e tests" --- # /publish -Read `../skills/controller.md` and follow it. +Read `../skills/dispatch.md` and follow it with `PHASE=publish`. -Dispatch the **publish** phase. Context: +Context: $ARGUMENTS diff --git a/e2e/commands/respond.md b/e2e/commands/respond.md index 5019348a..e118a879 100644 --- a/e2e/commands/respond.md +++ b/e2e/commands/respond.md @@ -4,8 +4,8 @@ description: "Fetch and address PR reviewer comments on e2e test code" --- # /respond -Read `../skills/controller.md` and follow it. +Read `../skills/dispatch.md` and follow it with `PHASE=respond`. -Dispatch the **respond** phase. Context: +Context: $ARGUMENTS diff --git a/e2e/commands/revise.md b/e2e/commands/revise.md index ee37a597..5e7d4aa2 100644 --- a/e2e/commands/revise.md +++ b/e2e/commands/revise.md @@ -4,8 +4,8 @@ description: "Incorporate user feedback into the e2e test plan" --- # /revise -Read `../skills/controller.md` and follow it. +Read `../skills/dispatch.md` and follow it with `PHASE=revise`. -Dispatch the **revise** phase. Context: +Context: $ARGUMENTS diff --git a/e2e/commands/validate.md b/e2e/commands/validate.md index dc6df134..1911ab7b 100644 --- a/e2e/commands/validate.md +++ b/e2e/commands/validate.md @@ -4,8 +4,8 @@ description: "Run e2e tests, check for anti-patterns, verify scenario coverage, --- # /validate -Read `../skills/controller.md` and follow it. +Read `../skills/dispatch.md` and follow it with `PHASE=validate`. -Dispatch the **validate** phase. Context: +Context: $ARGUMENTS diff --git a/e2e/skills/code.md b/e2e/skills/code.md index 980aa8e8..6d9153d6 100644 --- a/e2e/skills/code.md +++ b/e2e/skills/code.md @@ -516,4 +516,4 @@ Report your results: - Any discoveries (especially feature defects) - Overall implementation status -Then **re-read the controller** (`controller.md`) for next-step guidance. +Then return to the invoking workflow router for completion guidance. diff --git a/e2e/skills/completion.md b/e2e/skills/completion.md new file mode 100644 index 00000000..400f5805 --- /dev/null +++ b/e2e/skills/completion.md @@ -0,0 +1,36 @@ +--- +name: completion +description: Recommend next steps after one attended e2e phase. +--- + +# E2E Phase Completion + +After the completed `PHASE` reports its results, recommend the best next step +for the actual outcome, mention relevant alternatives briefly, and stop for the +user. + +- **ingest:** Recommend `/plan` unless the story context, [DEV] dependencies, + or test infrastructure has blocking gaps. Recommend clarification or waiting + for dependencies when planning cannot proceed safely. +- **plan:** Recommend `/revise` for user-requested changes, or `/code` when the + user has already reviewed and accepted the plan. +- **revise:** Recommend `/code` when the user is satisfied, or another + `/revise` round when further changes remain. +- **code:** Recommend `/validate`. If implementation exposed a plan gap, note + the inline plan update or offer `/plan` when user review is needed. For a + feature defect, report it without recommending an out-of-scope product-code + fix. For missing test infrastructure, present the documented deviation + options for user choice. +- **validate:** Recommend `/publish` only when validation passed. When failures + or anti-patterns remain, recommend fixing them and rerunning `/validate`. + Add missing scenarios when an acceptance-criteria gap is fixable; escalate + ambiguous or non-e2e-testable criteria to the user. +- **publish:** Recommend `/respond` when review comments arrive; otherwise the + workflow is complete for now. +- **respond:** Recommend `/validate` after code changes, another `/respond` + round while comments remain, or note completion when the PR is approved and + no work remains. + +The user may start at `/code` with an existing plan or partial test +implementation, and may skip `/publish` and `/respond` when working locally. +Never auto-advance between attended phases. diff --git a/e2e/skills/controller.md b/e2e/skills/controller.md index a0abb223..545fecac 100644 --- a/e2e/skills/controller.md +++ b/e2e/skills/controller.md @@ -1,13 +1,13 @@ --- name: controller -description: Top-level workflow controller that manages phase transitions for e2e test implementation. +description: Discover and route ambiguous e2e test implementation requests. --- # E2E Test Workflow Controller -You are the workflow controller. Your job is to manage the e2e test -implementation workflow by executing phases and handling transitions -between them. +Use this controller for workflow discovery and ambiguous-input routing. Once a +phase is selected, delegate its execution and completion guidance to the +lightweight dispatcher. ## Phases @@ -59,84 +59,19 @@ the source repo: ## How to Execute a Phase -1. **Announce** the phase to the user: *"Starting /plan."* -2. **Locate** the skill file — read and follow - `../../_shared/recipes/phase-override-resolution.md` with - WORKFLOW=`e2e`, PHASE_FILE=`{phase}.md`. -3. **Read** the resolved skill file -4. **Execute** the skill's steps — the user should see your progress -5. When the skill is done, it will tell you to report findings and - re-read this controller. Do that — then use "Recommending Next Steps" - below to offer options. -6. Present the skill's results and your recommendations to the user -7. **Stop and wait** for the user to tell you what to do next. - -## Recommending Next Steps - -After each phase completes, present the user with **options** — not just one -next step. Use the typical flow as a baseline, but adapt to what actually -happened. - -### Typical Flow - -```text -ingest → plan → [revise loop] → code → validate → publish → [respond loop] -``` - -### What to Recommend - -**Continuing forward:** - -- `/ingest` completed → recommend `/plan` (almost always the right next step) -- `/plan` completed → recommend `/revise` for user review of the plan, or `/code` if the user has already reviewed inline -- `/revise` completed (user satisfied) → recommend `/code`, or another `/revise` round -- `/code` completed → recommend `/validate` (always — never skip validation) -- `/validate` completed (all passing) → recommend `/publish` -- `/validate` completed (failures remain) → recommend fixing issues, then re-running `/validate` -- `/publish` completed → recommend `/respond` when review comments arrive -- `/respond` completed → recommend another `/respond` round, or note that the workflow is done when the PR is approved and merged - -**Looping back:** - -- `/plan` reveals story gaps or contradictions → suggest the user clarify with the story author or update the story -- `/code` reveals plan gaps → the plan is updated inline during implementation; offer `/validate` when implementation is complete -- `/code` discovers a feature defect (test reveals a bug in the [DEV] implementation) → note it in the implementation report; the test may need to xfail or skip. Do NOT recommend fixing the feature — that is out of scope -- `/code` discovers a missing test infrastructure method (plan referenced a method that doesn't exist) → see deviation rules in `code.md`; a local helper may suffice, or the user decides whether to adjust the plan or add test infrastructure support outside this workflow -- `/validate` reveals test failures → offer to diagnose and fix, then re-run `/validate` -- `/validate` reveals anti-patterns → fix them during validation, then re-run the affected checks -- `/validate` reveals unsatisfied acceptance criteria → if fixable (missing test scenarios), write them during validation; if the criterion is ambiguous or not e2e-testable, escalate to the user -- `/respond` requires code changes → apply changes, re-run `/validate`, then continue responding - -**Skipping:** - -- If the user already has a plan or partial test implementation, they may start at `/code` -- If the user wants to skip PR creation (e.g., working locally), `/publish` and `/respond` may be skipped - -### How to Present Options - -Lead with your top recommendation, then list alternatives briefly: - -```text -Recommended next step: /code — begin writing e2e test code following the -approved plan. - -Other options: -- /revise — if you want to adjust the plan first -- /validate — if you've already written test code and want to check it -``` +Set `PHASE` to the selected phase, then read `dispatch.md` and follow it. The +dispatcher owns phase announcement, override resolution, execution, and +completion routing for both built-in phases and project overrides. ## Starting the Workflow -Before dispatching any phase, check if the project has its own `AGENTS.md` -or `CLAUDE.md`. If so, read it — it may contain project-specific conventions, -testing standards, or other guidance that affects how the workflow operates. - When the user provides a Jira issue key or URL: -1. Execute the **ingest** phase -2. After ingestion, present results and wait +1. Set `PHASE=ingest`. +2. Read `dispatch.md` and follow it. -If the user invokes a specific command (e.g., `/code`), execute that phase -directly — don't force them through earlier phases. +If the user invokes a specific command (e.g., `/code`), set `PHASE` to that +command's phase, then read `dispatch.md` and follow it. Do not force the user +through earlier phases. ## Error Handling @@ -164,7 +99,8 @@ subagent spawning. ## Rules - **Never auto-advance.** Always wait for the user between phases. -- **Recommendations come from this file, not from skills.** Skills report findings; this controller decides what to recommend next. +- **Recommendations come from `completion.md`.** Phase skills report findings; + the completion guide provides the authoritative next-step model. - **Jira is read-only.** The `/ingest` phase reads from Jira but never modifies it. No phase in this workflow writes to Jira. - **Plan evolves during implementation.** `/code` updates `02-plan.md` as tasks are completed. This is expected, not a sign of plan failure. - **Validation is mandatory before publishing.** Never recommend `/publish` unless `/validate` has passed. diff --git a/e2e/skills/dispatch.md b/e2e/skills/dispatch.md new file mode 100644 index 00000000..91ceecc6 --- /dev/null +++ b/e2e/skills/dispatch.md @@ -0,0 +1,22 @@ +--- +name: dispatch +description: Resolve and execute one explicitly requested e2e phase. +--- + +# E2E Phase Dispatch + +Before dispatching, read the project's `AGENTS.md` or `CLAUDE.md` only if +neither is already in the session. Then, given `PHASE`, announce +`Starting /{PHASE}.` and read and follow +`../../_shared/recipes/phase-override-resolution.md` with `WORKFLOW=e2e` and +`PHASE_FILE={PHASE}.md`. Read and execute the resolved phase file, passing +through the command context unchanged. + +The built-in fallback is the phase file beside this dispatcher. Follow the +phase through its reporting step. Treat any valid phase exit—returning to the +invoking router, requesting completion guidance, or re-reading the +controller—as a return to this dispatcher. Then read `completion.md` and follow +its guidance for `PHASE`. + +If override resolution or phase execution fails, report the failure and stop +without reading `completion.md`. diff --git a/e2e/skills/ingest.md b/e2e/skills/ingest.md index 5a9b89dd..71d6a378 100644 --- a/e2e/skills/ingest.md +++ b/e2e/skills/ingest.md @@ -744,4 +744,4 @@ Report your findings: - Story test plan status (test cases found / expected zero / anomalous zero / no testplan) - Assessment of readiness for `/plan` -Then **re-read the controller** (`controller.md`) for next-step guidance. +Then return to the invoking workflow router for completion guidance. diff --git a/e2e/skills/plan.md b/e2e/skills/plan.md index 1f81410c..647a410f 100644 --- a/e2e/skills/plan.md +++ b/e2e/skills/plan.md @@ -349,4 +349,4 @@ Report your results: - Note any risks or open questions - Assessment of plan completeness -Then **re-read the controller** (`controller.md`) for next-step guidance. +Then return to the invoking workflow router for completion guidance. diff --git a/e2e/skills/publish.md b/e2e/skills/publish.md index 5667ef3c..976501e0 100644 --- a/e2e/skills/publish.md +++ b/e2e/skills/publish.md @@ -230,7 +230,6 @@ Present: - PR URL (the full `https://github.com/...` link, not just `owner/repo#number`) - Branch name and base - Number of commits included -- Next steps (share with reviewers, wait for comments, then use `/respond`) ## Output @@ -244,6 +243,5 @@ Present: Report your results: - PR URL and branch name - Commits included -- Suggested next steps -Then **re-read the controller** (`controller.md`) for next-step guidance. +Then return to the invoking workflow router for completion guidance. diff --git a/e2e/skills/respond.md b/e2e/skills/respond.md index cc1411ee..3c92e1cd 100644 --- a/e2e/skills/respond.md +++ b/e2e/skills/respond.md @@ -231,4 +231,4 @@ Report your results: - Re-validation recommendation - Outstanding items -Then **re-read the controller** (`controller.md`) for next-step guidance. +Then return to the invoking workflow router for completion guidance. diff --git a/e2e/skills/revise.md b/e2e/skills/revise.md index 11052ac7..fa0f3d50 100644 --- a/e2e/skills/revise.md +++ b/e2e/skills/revise.md @@ -134,4 +134,4 @@ Report your results: - Any consistency updates made as a side effect - Assessment of plan readiness for `/code` -Then **re-read the controller** (`controller.md`) for next-step guidance. +Then return to the invoking workflow router for completion guidance. diff --git a/e2e/skills/validate.md b/e2e/skills/validate.md index 9426f4f7..bcd43cf5 100644 --- a/e2e/skills/validate.md +++ b/e2e/skills/validate.md @@ -394,4 +394,4 @@ Report your results: - Regression status - Overall verdict -Then **re-read the controller** (`controller.md`) for next-step guidance. +Then return to the invoking workflow router for completion guidance. From 703edbae971ea6a6b54f326f3e5b59b2ab529381 Mon Sep 17 00:00:00 2001 From: Andy Dalton Date: Fri, 4 Sep 2026 16:00:13 -0400 Subject: [PATCH 3/4] fix(e2e): tighten phase completion contracts Require architecture-compatible terminal exits, clarify ambiguous controller input, and distinguish valid failing phase outcomes from operational execution failures. Assisted-by: Codex --- _shared/recipes/phase-override-resolution.md | 12 ++++++------ e2e/skills/controller.md | 10 ++++++++-- e2e/skills/dispatch.md | 18 +++++++++++------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/_shared/recipes/phase-override-resolution.md b/_shared/recipes/phase-override-resolution.md index 1003086c..360e7b40 100644 --- a/_shared/recipes/phase-override-resolution.md +++ b/_shared/recipes/phase-override-resolution.md @@ -23,12 +23,12 @@ default. Use the first match found: at the repo root 2. **`{PHASE_FILE}`** — workflow's built-in default (sibling file in `skills/`) -If the override file exists but is empty, appears malformed, or does not -contain completion or exit guidance, warn the user and fall back to the -built-in default. Valid exit guidance may return control to the invoking -router, read a completion guide, or re-read a controller; require the same -behavioral contract as the workflow's built-in phase rather than one specific -routing architecture. +If the override file exists but is empty, appears malformed, or does not end +with a detectable terminal instruction, warn the user and fall back to the +built-in default. The terminal instruction must explicitly direct one supported +exit: return control to the invoking router, read a completion guide, or re-read +a controller. It must also select the same exit behavior as the workflow's +built-in phase; an override cannot substitute a different routing architecture. If using a project override, announce it: *"Using project override for /{phase}."* diff --git a/e2e/skills/controller.md b/e2e/skills/controller.md index 545fecac..3ff59311 100644 --- a/e2e/skills/controller.md +++ b/e2e/skills/controller.md @@ -73,16 +73,22 @@ If the user invokes a specific command (e.g., `/code`), set `PHASE` to that command's phase, then read `dispatch.md` and follow it. Do not force the user through earlier phases. +For any other input, summarize the available phases, ask the user for a Jira +issue key or URL or a specific phase command, and stop without reading +`dispatch.md`. + ## Error Handling -If any phase fails (Jira MCP errors, test failures, git errors): +If a phase cannot complete because of an operational error (for example, a +Jira MCP or git error): 1. **Stop immediately.** Do not advance to the next phase. 2. **Report the error** to the user with the specific error message. 3. **Offer options:** retry the failed step, skip the phase (if optional), or escalate. Do not fabricate results when a tool call fails. Do not silently continue -past errors. +past errors. A completed validation report with a failing verdict is a valid +phase outcome; route it through `completion.md` for fix-and-rerun guidance. ## Context Management diff --git a/e2e/skills/dispatch.md b/e2e/skills/dispatch.md index 91ceecc6..76732d2a 100644 --- a/e2e/skills/dispatch.md +++ b/e2e/skills/dispatch.md @@ -12,11 +12,15 @@ neither is already in the session. Then, given `PHASE`, announce `PHASE_FILE={PHASE}.md`. Read and execute the resolved phase file, passing through the command context unchanged. -The built-in fallback is the phase file beside this dispatcher. Follow the -phase through its reporting step. Treat any valid phase exit—returning to the -invoking router, requesting completion guidance, or re-reading the -controller—as a return to this dispatcher. Then read `completion.md` and follow -its guidance for `PHASE`. +The built-in fallback is the phase file beside this dispatcher. For this +workflow, the resolved phase must end by returning to the invoking workflow +router, matching the built-in phase contract. Follow the phase through its +reporting step and terminal return. Then read `completion.md` and follow its +guidance for `PHASE`; the dispatcher is the only component that reads the +completion guide. -If override resolution or phase execution fails, report the failure and stop -without reading `completion.md`. +If override resolution fails, an operational error prevents the phase from +completing, or the phase lacks a valid terminal return, report the failure and +stop without reading `completion.md`. A completed phase report with a failing +verdict, including `validate.md` reporting `FAIL`, is a valid outcome: read +`completion.md` so it can provide fix-and-rerun guidance. From f21213c8ca309b584016a3aac8e4a7df4478602c Mon Sep 17 00:00:00 2001 From: Andy Dalton Date: Fri, 4 Sep 2026 16:13:36 -0400 Subject: [PATCH 4/4] fix(e2e): preserve legacy phase exits Keep terminal-exit validation architecture-neutral and normalize supported legacy override exits through the demand-loaded dispatcher. Assisted-by: Codex --- _shared/recipes/phase-override-resolution.md | 5 +++-- e2e/skills/dispatch.md | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/_shared/recipes/phase-override-resolution.md b/_shared/recipes/phase-override-resolution.md index 360e7b40..c50197b1 100644 --- a/_shared/recipes/phase-override-resolution.md +++ b/_shared/recipes/phase-override-resolution.md @@ -27,8 +27,9 @@ If the override file exists but is empty, appears malformed, or does not end with a detectable terminal instruction, warn the user and fall back to the built-in default. The terminal instruction must explicitly direct one supported exit: return control to the invoking router, read a completion guide, or re-read -a controller. It must also select the same exit behavior as the workflow's -built-in phase; an override cannot substitute a different routing architecture. +a controller. The invoking workflow's router determines which supported exits +it accepts or normalizes; preserve the built-in phase's behavioral contract +without requiring one routing architecture for every workflow. If using a project override, announce it: *"Using project override for /{phase}."* diff --git a/e2e/skills/dispatch.md b/e2e/skills/dispatch.md index 76732d2a..c83eae38 100644 --- a/e2e/skills/dispatch.md +++ b/e2e/skills/dispatch.md @@ -12,15 +12,15 @@ neither is already in the session. Then, given `PHASE`, announce `PHASE_FILE={PHASE}.md`. Read and execute the resolved phase file, passing through the command context unchanged. -The built-in fallback is the phase file beside this dispatcher. For this -workflow, the resolved phase must end by returning to the invoking workflow -router, matching the built-in phase contract. Follow the phase through its -reporting step and terminal return. Then read `completion.md` and follow its -guidance for `PHASE`; the dispatcher is the only component that reads the +The built-in fallback is the phase file beside this dispatcher. Follow the +phase through its reporting step. Treat any supported phase exit—returning to +the invoking router, requesting completion guidance, or re-reading the +controller—as a return to this dispatcher. Then read `completion.md` and follow +its guidance for `PHASE`; the dispatcher is the only component that reads the completion guide. If override resolution fails, an operational error prevents the phase from -completing, or the phase lacks a valid terminal return, report the failure and +completing, or the phase lacks a supported terminal exit, report the failure and stop without reading `completion.md`. A completed phase report with a failing verdict, including `validate.md` reporting `FAIL`, is a valid outcome: read `completion.md` so it can provide fix-and-rerun guidance.