diff --git a/CLAUDE.md b/CLAUDE.md index dc253935..66b19d81 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -144,3 +144,4 @@ Non-obvious rules for this repo: - **Prefer the built-in `Explore` and `Plan` subagents** for read-heavy context-gathering. Don't have an orchestrator command read the whole codebase in its own context. - **Skip ceremonial preambles** like "Great!", "I will now…", "All done!" — modern models trim them naturally and AWOS prompts shouldn't fight that. - **`AskUserQuestion` belongs in core `commands/*.md`** under an `# INTERACTION` section. AWOS targets Claude Code only, so the tool is a framework default rather than a host-specific customization — don't duplicate it into the `claude/commands/*.md` wrappers. +- **Do not hard-wrap markdown prose at 80 columns.** Let paragraphs and list items flow as a single line per logical unit. Markdown renderers reflow soft-wrapped text, and 80-col wrapping inflates diffs when prose is edited. Wrapping is fine only where the line is semantically a single token (a URL, a code identifier) or inside a fenced block whose literal line breaks matter. diff --git a/commands/hire.md b/commands/hire.md index cb86e934..6a3915c9 100644 --- a/commands/hire.md +++ b/commands/hire.md @@ -96,6 +96,18 @@ Follow this process precisely. | `python-backend` | `fastapi-expert` | — | — | | `aws-infra` | `terraform-pro`, `aws-deploy` | `aws-mcp` | `aws-infra-expert` | +**QA Complement Rule:** + +For each primary tech role identified above, search the registry for a complementary QA/testing agent in the same pass — query with the primary technology plus terms like "testing", "QA", or "acceptance" (e.g. `"React TypeScript testing acceptance"`). The intent is to surface any specialist that can write or run tests for that stack. + +Pick **one** QA agent per primary role, in this order of preference: + +1. A technology-specific tester from the registry or already in `.claude/agents/` (e.g. an agent dedicated to the project's actual testing stack — pytest-focused, React-component-focused, etc.). +2. The generic `testing-expert` from the `awos-recruitment` registry if no technology-specific tester is found. +3. Otherwise, no QA agent — record the gap in the Step 7 warning table. + +Do **not** hardcode tool names or runners (Playwright, Cypress, WebdriverIO, Vitest, pytest…) into the proposal. Pick a runner only after the project's actual stack is known — by reading `technical-considerations.md`, the package manifest, or any existing test configuration — and prefer whatever is already configured before suggesting a new one. Optimize for the project's testing efficiency and developer wall-clock time, not for a fixed default. + ## Step 5: Install Found Components Detect the project's package runner: prefer `bunx` if a `bun.lockb` or `bun.lock` is present in the project root, otherwise use `npx`. The commands below show both; pick one. diff --git a/commands/tasks.md b/commands/tasks.md index 981a3a2e..8f6e3df4 100644 --- a/commands/tasks.md +++ b/commands/tasks.md @@ -40,6 +40,7 @@ Follow this process precisely. 1. Analyze ``. If it clearly references a spec by name or index, identify the corresponding directory in `context/spec/`. 2. If the prompt is empty or ambiguous, list the spec directories that contain both `functional-spec.md` and `technical-considerations.md` and ask the user to choose. Do not proceed until a valid spec is selected. +3. **Interpret the prompt's intent on testing.** Read `` and decide whether the user wants to skip generated tests (e.g. wording like "skip tests", "no tests", "prototype", "throwaway", or an explicit `--no-tests` argument). Use natural-language understanding — substring matching alone would false-positive on phrases like "don't skip tests". When uncertain, ask the user via `AskUserQuestion` before continuing. Set `SKIP_TESTS = true` only when the intent is clear. Strip any explicit `--no-tests` / `skip tests` token from the prompt before further processing. ## Step 2: Gather and Synthesize Context @@ -53,28 +54,48 @@ Follow this process precisely. - A runnable slice means that after the work under it is done the application can be started and used without errors, and a small piece of new functionality is visible or testable. - Avoid horizontal, layer-based slices (e.g., "Do all database work" then "Do all API work"). - Create vertical slices — the smallest end-to-end pieces of functionality. - - A slice is valid only if its functionality is verified by the agent using real tools (curl, shell, or a browser-automation MCP if the project has one configured). + - A slice is valid only if its functionality is verified by the agent using whatever verification tool best fits the slice (curl/shell, a browser-automation MCP or CLI if the project has one configured, a unit/integration test runner, etc.). Pick by efficiency for the slice and wall-clock time — don't hardcode a tool order. - Check that the project has the MCPs, services, and dependencies needed for testing each slice. If something is missing, instruct the user to install it. - If a slice cannot be tested, explain why and get user approval before proceeding. - A slice is not complete unless it is tested or the user has explicitly approved skipping the test. + - **Verification artifacts are ephemeral.** Inline an artifact cleanup step into each Verify task — screenshots, recorded videos, generated e2e scripts and any other ephemeral files produced during verification get deleted at the end of the Verify task itself. Do **not** delete artifacts from the Feature Testing & Regression slice — those are intentionally kept for the regression suite. - **Your Thought Process for Generating the Plan:** - 1. First, identify the absolute smallest piece of user-visible value from the spec. This is your **Slice 1**. + 1. Identify the absolute smallest piece of user-visible value from the spec. This is **Slice 1**. 2. Create a high-level checklist item for that slice (e.g., `- [ ] **Slice 1: View existing avatar (or placeholder)**`). 3. Under that slice, create the nested tasks (database, backend, frontend) needed to implement and verify **only that slice**. - 4. **For each task, assign the appropriate subagent:** - - Identify the technology or domain the task involves + 4. Assign a subagent to every task: + - Identify the technology or domain the task involves. - Enumerate the universe of available specialist subagents by inspecting the `Agent` tool's description block in your own system prompt. This is an introspection step — no tool call is required, but it is mandatory. Both kinds of agents are listed there: project-local ones (declared as files under `.claude/agents/*.md`) and plugin-provided ones. Tell them apart by the `plugin-name:` prefix on `subagent_type` — plugin-provided agents carry it (e.g. `python-development:python-pro`); project-local agents do not. The always-available built-in `general-purpose` is your fallback when no specialist matches. - - Match the task to a subagent based on: - - Technology keywords - - Task intent - - Tech stack identified in technical-considerations.md - - Append the subagent assignment using format: `**[Agent: agent-name]**` at the end of the task description - - Use `general-purpose` when no specialist clearly matches — track these for the Recommendations table - 5. Next, identify the second-smallest piece of value that builds on the first. This is **Slice 2**. - 6. Create a high-level checklist item and its nested tasks with subagent assignments. - 7. Repeat this process until all requirements from the specification are covered. - 8. For each slice's verification task, identify required MCPs/services (browser MCP, curl, database access, etc.) and note any that may be missing. + - Match the task to a subagent based on technology keywords, task intent, and the tech stack identified in `technical-considerations.md`. + - Append the assignment as `**[Agent: agent-name]**` at the end of the task description. + - Use `general-purpose` only when no specialist matches — track these for the Recommendations table. + 5. Within the same slice, after the implementation tasks, add a Verify task that exercises the slice end-to-end and deletes its own verification artifacts before completing. Skip the Verify task if `SKIP_TESTS = true`. + 6. Repeat steps 1-5 for each subsequent slice until all spec requirements are covered. + 7. Append the **Feature Testing & Regression** slice as the final slice (skip this step entirely if `SKIP_TESTS = true`). See **Step 3a** below for how to select the QA agent and emit the slice — do not invent your own wording. + 8. For each slice's Verify task, identify required MCPs/services (browser MCP, curl, database access, etc.) and note any that may be missing for the Recommendations table in Step 4. + +## Step 3a: Select the QA Agent and Emit the Feature Testing & Regression Slice + +Skip this step if `SKIP_TESTS = true`. + +1. **Search for a QA-coded subagent** by introspecting the `Agent` tool's description block from Step 3.4. Pick the best fit using this order, but do not hardcode names — match on responsibility: + - A project-specific tester for the actual stack (e.g. `react-testing`, `pytest-tester`, a custom `acceptance-tester` in `.claude/agents/`). + - A general AWOS testing agent if installed (e.g. `testing-expert` from the `awos-recruitment` registry). + - The built-in `general-purpose` agent as the last resort. +2. **If no project-specific tester or AWOS testing agent is found,** stop and ask the user via `AskUserQuestion`. Present exactly three options: + 1. **Install a testing agent now** — run `/awos:hire` to add `testing-expert` (or a more specific tester) from the registry, then re-run `/awos:tasks`. + 2. **Generate the slice with `general-purpose`** — proceed and produce the Feature Testing & Regression slice, marking its tasks `**[Agent: general-purpose]**`. Flag this in the Recommendations table. + 3. **Skip the Feature Testing & Regression slice** — set `SKIP_TESTS = true` for this run only; the user can re-run `/awos:tasks` later once a tester is hired. +3. **Emit the slice** using the template below. Substitute `{qa-agent}` with the agent name selected above. Substitute `N` with the next slice number. Keep the wording — downstream automations depend on this exact structure. + + ```md + - [ ] **Slice N: Feature Testing & Regression** + + > Verifies the whole feature end-to-end against functional-spec.md, run after all implementation slices are complete. + - [ ] Read functional-spec.md acceptance criteria in full. Generate acceptance-level tests that verify the entire feature as a whole — not individual slices. Cover applicable layers (unit for pure logic, integration for service interactions, e2e for user flows) based on the project's testing stack. Write tests with RED validation (must fail before implementation is confirmed done). Annotate each test with `@spec: [spec-directory]` and `@regression` if suitable for long-term regression. **[Agent: {qa-agent}]** + - [ ] Run all generated tests. All must pass. Fix any failures before proceeding. **[Agent: {qa-agent}]** + ``` - **Example of applying the rule for "User Profile Picture Upload":** - **Bad, Horizontal Plan (DO NOT DO THIS):** @@ -85,11 +106,16 @@ Follow this process precisely. - `[ ] **Slice 1: Display a placeholder avatar on the profile page**` - `[ ] Task: Add a non-functional 'ProfileAvatar' UI component that shows a static placeholder image. **[Agent: react-expert]**` - `[ ] Task: Place the component on the profile page. **[Agent: react-expert]**` + - `[ ] Verify: Start the app, open the profile page, confirm the placeholder avatar renders, then delete any screenshots or recordings produced during the check. **[Agent: manual-qa-expert]**` - `[ ] **Slice 2: Display the user's actual avatar if it exists**` - `[ ] Task: Add avatar_url column to the users table via a migration. **[Agent: python-expert]**` - `[ ] Task: Update the user API endpoint to return the avatar_url. **[Agent: python-expert]**` - `[ ] Task: Update the 'ProfileAvatar' component to fetch and display the user's avatar_url, falling back to the placeholder if null. **[Agent: react-expert]**` - - `[ ] Task: Run the application. Use chrome MCP to connect the page in Browser. Verify that the profile page shows the correct avatar or placeholder. **[Agent: manual-qa-expert]**` + - `[ ] Verify: Run the application, drive the profile page through the available browser-automation tool (whichever the project ships — playwright-cli, cypress, the chrome MCP, etc.), confirm the correct avatar or placeholder is shown, and delete any screenshots or recordings produced during the check. **[Agent: manual-qa-expert]**` + - `[ ] **Slice 3: Feature Testing & Regression**` + > Verifies the whole feature end-to-end against functional-spec.md, run after all implementation slices are complete. + - `[ ] Read functional-spec.md acceptance criteria in full. Generate acceptance-level tests that verify the entire feature as a whole — not individual slices. Cover applicable layers (unit for pure logic, integration for service interactions, e2e for user flows) based on the project's testing stack. Write tests with RED validation (must fail before implementation is confirmed done). Annotate each test with @spec: [spec-directory] and @regression if suitable for long-term regression. **[Agent: testing-expert]**` + - `[ ] Run all generated tests. All must pass. Fix any failures before proceeding. **[Agent: testing-expert]**` ## Step 4: Present Draft and Refine @@ -97,12 +123,14 @@ Follow this process precisely. - Iterate until the user is satisfied (adjust, split, merge slices or tasks, or reassign subagents as needed). - If any tasks were assigned to `general-purpose` (because no specialist exists) or verification cannot be performed (missing MCPs/services), present a table: - | Task/Slice | Issue | Recommendation | - | --------------------- | -------------------------------------------------------- | ---------------------------------------------------- | - | Slice 2: Task 3 | Assigned to `general-purpose` — no TypeScript specialist | Install `typescript-pro` agent for proper delegation | - | Slice 3: Verification | Browser MCP not available | Install browser MCP to enable UI verification | + | Task/Slice | Issue | Recommendation | + | --------------------- | ----------------------------------------------------------------------------------- | ---------------------------------------------------- | + | Slice 2: Task 3 | Assigned to `general-purpose` — no TypeScript specialist | Install `typescript-pro` agent for proper delegation | + | Slice N (QA) | Feature Testing & Regression slice uses `general-purpose` — no QA-coded agent hired | Run `/awos:hire` to install `testing-expert` | + | Slice 3: Verification | Browser MCP not available | Install browser MCP to enable UI verification | ## Step 5: File Generation 1. Write the final slice/task list to `tasks.md` in the chosen spec directory. -2. Report the saved path and the next command: `/awos:implement`. +2. If `SKIP_TESTS = true`, record a one-line note at the top of the generated `tasks.md` so that downstream commands (e.g. `/awos:verify`) can detect the choice: ``. +3. Report the saved path and the next command: `/awos:implement`. diff --git a/commands/verify.md b/commands/verify.md index 6196bc24..223a018d 100644 --- a/commands/verify.md +++ b/commands/verify.md @@ -32,6 +32,17 @@ Verify a specification's implementation against its acceptance criteria. For eac --- +# CONSTRAINTS + +- **`/awos:verify` is a look-and-feel + spec-freshness check, not a test runner.** Generated test suites belong in the Feature Testing & Regression slice produced by `/awos:tasks` and executed by `/awos:implement`. This command verifies that the implementation matches the spec's acceptance criteria from a user's perspective and that downstream documentation has not drifted. +- **Step 3 still requires evidence.** Do not mark an acceptance criterion `[x]` without confirming it — either by driving the UI/API yourself or by getting an explicit user confirmation via `AskUserQuestion`. "The user can verify this manually" without a check is not acceptable. +- **For non-visual criteria, pick the tool by fit.** APIs, data, CLI, and business-logic criteria can be confirmed with whatever proves them fastest and most reliably — `curl`, shell, log/database inspection, a browser-automation tool, or direct user confirmation. Do not assume any specific tool is available; if none work, fall back to `AskUserQuestion`. The one exception is look-and-feel, covered next. +- **Look-and-feel means real rendering, with screenshots kept as evidence.** For any acceptance criterion describing something a user sees or does in a UI — a rendered page, a control, a state change, a redirect — in-process or component tests are **not** sufficient: they confirm logic, not look-and-feel. Start the app if it isn't running, drive the actual UI through whatever browser-automation tool the project ships (Playwright MCP/CLI, Cypress, the chrome MCP, etc.), and capture screenshots of the states the criteria describe. Save them to `docs/screenshots/` — the same evidence folder the `testing-expert` agent writes E2E captures to — naming each file so it sorts by spec: `docs/screenshots/-.png` (e.g. `docs/screenshots/011-scheduled-tasks-amber-pill.png`). The browser tool creates the folder on first write; do not edit `.gitignore` — git-ignoring `docs/screenshots/` is a one-time project setup, not part of verification. Reference the saved paths in the report — they are what the human reviews. +- **Honour the `skip-tests` mode.** If the spec's `tasks.md` carries the `` marker (set by `/awos:tasks` when the user opted out of test generation), perform Step 3 as a look-and-feel walk-through only — do not run or generate test suites, and treat missing test tooling as expected rather than as a verification failure. Visual criteria are still verified by rendering the UI and capturing screenshots; skip-tests suppresses test suites, not look-and-feel. +- **Session length does not excuse skipping.** Even in long sessions, Step 3 must run. + +--- + # PROCESS ### Step 1: Identify Target Specification @@ -49,9 +60,12 @@ Verify a specification's implementation against its acceptance criteria. For eac For each acceptance criterion in `functional-spec.md`: -1. **Verify:** Check if the implementation satisfies the criterion -2. **If met:** Mark it `[x]` -3. **If NOT met:** Report which criterion failed and what's missing, then stop +1. **Verify:** confirm the implementation satisfies the criterion. + - **Non-visual criterion** (API, data, CLI, logic): use whatever check fits best — `curl`, a shell command, log/database inspection. + - **Visual / UI criterion** (anything a user sees or does in a browser): start the app if needed (per `technical-considerations.md`), drive the running UI through the project's browser-automation tool, observe the actual rendered behavior, and save a screenshot of the verified state to `docs/screenshots/-.png` (the shared screenshot folder; see CONSTRAINTS). A passing component/test-client test does not satisfy a visual criterion — render it for real. +2. **If met:** mark it `[x]` and record the evidence — the command output for non-visual criteria, or the screenshot path for visual ones (e.g. "verified via curl /api/health", "see docs/screenshots/011-scheduled-tasks-amber-pill.png"). +3. **If NOT met:** report which criterion failed and what's missing, then stop. +4. **If no tool can verify the criterion in this environment:** ask the user via `AskUserQuestion` — "I can't verify [criterion] automatically because [reason]. Verify manually and confirm, or stop here?" Options: "I verified manually — mark as done" / "Stop — I'll fix the tooling first". Never mark criteria `[x]` without evidence from one of the paths above. ### Step 4: Mark as Completed @@ -84,3 +98,4 @@ Check if `context/product/` documents need updates based on what was learned dur - Success: spec verified and marked complete; report the verified criteria count. - Failure: list the unmet criteria with the command output that demonstrated the failure. - Verification disabled: list criteria marked `[?]` so the user knows what still needs manual confirmation. +- **Visual evidence:** for any UI criteria verified, list the retained screenshot paths under `docs/screenshots/` so the user can review the look-and-feel without re-running. diff --git a/plugins/awos/skills/ai-readiness-audit/dimensions/spec-driven-development.md b/plugins/awos/skills/ai-readiness-audit/dimensions/spec-driven-development.md index 63495223..6ccac741 100644 --- a/plugins/awos/skills/ai-readiness-audit/dimensions/spec-driven-development.md +++ b/plugins/awos/skills/ai-readiness-audit/dimensions/spec-driven-development.md @@ -117,9 +117,11 @@ Audits whether the project uses AWOS for spec-driven development. AWOS provides 4. Calculate the annotation ratio: annotated tasks / total tasks 5. Extract all unique agent names. Occasional `general-purpose` assignments are fine for small utility tasks (commits, running linters, config tweaks) — only flag if the majority of implementation tasks use `general-purpose`. 6. Check for domain mix-ups: frontend agents assigned to backend/database tasks or vice versa. Use keywords in the task description to detect domain (e.g., "migration", "database", "API endpoint" → backend; "component", "UI", "page", "styling" → frontend). - 7. Check that each slice's verification/testing task is assigned to a QA/tester agent (e.g., `manual-qa-expert`, `testing-expert`, or similar) — not to the same agent that implemented the slice. -- **Pass:** Majority of tasks have agent assignments with no systematic domain mix-ups and verification tasks are assigned to QA/tester agents -- **Warn:** Many tasks lack annotations, OR most implementation tasks use `general-purpose`, OR verification tasks lack dedicated QA agent + 7. Check QA agent coverage using whichever tasks model the spec follows: + - **New model:** if the spec ends with a slice titled "Feature Testing & Regression", verify its tasks are assigned to a QA-coded agent. Any agent whose role or skill set covers acceptance/regression testing counts — `testing-expert`, a project-specific tester (e.g. `react-testing`, `pytest-tester`), or a `general-purpose` assignment if the Recommendations table also flags missing QA tooling. Implementation slices do not need per-slice QA assignments in this model. + - **Legacy model:** if no Feature Testing & Regression slice is found, each implementation slice should have at least one Verify task assigned to a QA-coded agent (e.g. `manual-qa-expert`, `testing-expert`, or similar) — not to the agent that implemented the slice. +- **Pass:** Majority of tasks have agent assignments with no systematic domain mix-ups; AND either (new model) a Feature Testing & Regression slice carries QA-coded assignments, or (legacy model) per-slice Verify tasks are assigned to QA-coded agents +- **Warn:** Many tasks lack annotations, OR most implementation tasks use `general-purpose`, OR verification tasks lack a QA-coded agent; OR (new model) the Feature Testing & Regression slice is present but its tasks are unassigned - **Fail:** No agent annotations at all, OR systematic domain mix-ups across multiple specs - **Skip-When:** SDD-01 is FAIL (AWOS not installed), or no tasks.md files exist (covered by SDD-05) - **Severity:** medium diff --git a/src/CLAUDE.md b/src/CLAUDE.md index 368dcabd..d9022621 100644 --- a/src/CLAUDE.md +++ b/src/CLAUDE.md @@ -54,6 +54,8 @@ From `config/setup-config.js`: | `scripts/` | `.awos/scripts/` | no | | `claude/commands/` | `.claude/commands/awos/` | **yes** | +`.claude/agents/` is intentionally **not** a copy destination — it is the user's customization area for project-local subagents. AWOS-shipped agents (e.g. `testing-expert`) ride in via `awos-recruitment` on demand, so the installer never auto-populates this directory. + **Why the difference?** - `.awos/` files = Framework internals (user shouldn't edit these; overwritten on every run) diff --git a/src/config/setup-config.js b/src/config/setup-config.js index 2efe6a7b..4f319183 100644 --- a/src/config/setup-config.js +++ b/src/config/setup-config.js @@ -66,6 +66,10 @@ const copyOperations = [ manualUpdateUrl: 'https://github.com/provectus/awos/tree/main/claude/commands', }, + // Note: `.claude/agents/` is intentionally NOT a copy destination. It is the + // user's customization area (project-local subagents). AWOS-shipped agents + // (e.g. `testing-expert`) are hired on demand via `awos-recruitment`, so the + // installer must not silently overwrite anything users put there. ]; module.exports = { diff --git a/tests/lint-prompts.test.js b/tests/lint-prompts.test.js index 9db90b8f..e6583404 100644 --- a/tests/lint-prompts.test.js +++ b/tests/lint-prompts.test.js @@ -201,7 +201,7 @@ test('all /awos: cross-references resolve', () => { const references = new Set(); for (const f of allFiles) { - const text = readUtf8(f); + const text = readUtf8(f).replace(//g, ''); const matches = text.match(/\/awos:[a-z][a-z0-9-]*/g) || []; for (const m of matches) references.add(m); } @@ -501,6 +501,162 @@ test('agent-template.md cues the spawned agent to apply its skills', () => { ); }); +test('commands/tasks.md emits a Feature Testing & Regression slice', () => { + // The QA pyramid PR makes every spec end with a "Feature Testing & + // Regression" slice (unless the user opts out). Downstream tools — + // /awos:implement, the SDD-07 audit dimension, the awos-qa scenarios — + // grep for this literal slice name. If the slice is renamed or + // dropped, the assertion catches the regression before behavior tests + // hit it. + const body = readUtf8(path.join(commandsDir, 'tasks.md')); + assert.ok( + body.includes('Feature Testing & Regression'), + 'commands/tasks.md must reference the literal "Feature Testing & Regression" slice name so SDD-07 and awos-qa can detect it' + ); +}); + +test('commands/tasks.md picks the QA agent with a search-first rule', () => { + // Option A: testing-expert is one option among many — not a hard + // requirement. tasks.md must (a) instruct the agent to search for a + // QA-coded subagent rather than naming testing-expert as required, + // (b) offer an AskUserQuestion fallback when none is found, and + // (c) not contain the "Requires `testing-expert` agent" hard gate + // that the previous draft shipped with. + const body = readUtf8(path.join(commandsDir, 'tasks.md')); + assert.ok( + /Search for a QA-coded subagent/i.test(body), + 'commands/tasks.md must instruct a search-first QA agent selection (Step 3a)' + ); + assert.ok( + body.includes('AskUserQuestion'), + 'commands/tasks.md must use AskUserQuestion to offer the 3-option fallback when no QA agent is hired' + ); + assert.ok( + !/Requires\s+`?testing-expert`?\s+agent\.\s+If it is not present/i.test( + body + ), + 'commands/tasks.md must not hard-require testing-expert — the search-first rule replaces that gate' + ); +}); + +test('commands/tasks.md documents the skip-tests opt-out and persists it', () => { + // /awos:verify reads tasks.md to decide whether the spec is in + // skip-tests mode. The marker shape is part of the contract — if it + // moves, verify.md will not detect it. Lock the shape here. + const body = readUtf8(path.join(commandsDir, 'tasks.md')); + assert.ok( + body.includes(''), + 'commands/tasks.md must record SKIP_TESTS via the literal "" marker so /awos:verify can detect it' + ); + assert.ok( + /SKIP_TESTS\s*=\s*true/.test(body), + 'commands/tasks.md must keep the SKIP_TESTS flag wording — Step 1 and Step 3a both gate on it' + ); +}); + +test('commands/verify.md acknowledges the skip-tests marker', () => { + // The Slack thread feedback frames /awos:verify as look-and-feel + + // spec-freshness rather than a test runner. The skip-tests marker + // from /awos:tasks must short-circuit any test-running expectation + // in this command — the literal marker string is the join key. + const body = readUtf8(path.join(commandsDir, 'verify.md')); + assert.ok( + body.includes(''), + 'commands/verify.md must reference the "" marker so the two commands agree on the opt-out shape' + ); + assert.ok( + /look-and-feel|spec-freshness/i.test(body), + 'commands/verify.md must frame itself as a look-and-feel / spec-freshness check, not a test runner' + ); +}); + +test('verify.md does not hardcode a verification-tool priority order', () => { + // The Slack feedback was explicit: tools should be chosen by fit + // and wall-clock time, not a fixed ladder. The previous draft used + // an arrow ladder "browser MCP → curl/shell → AskUserQuestion". + // Lock that out. + const body = readUtf8(path.join(commandsDir, 'verify.md')); + assert.ok( + !/browser MCP\s*→\s*curl\/shell\s*→/.test(body), + 'commands/verify.md must not declare a hardcoded "browser MCP → curl/shell → AskUserQuestion" tool priority' + ); + assert.ok( + !/fallback order:\s*browser MCP/i.test(body), + 'commands/verify.md must not name a fixed verification-tool fallback order' + ); +}); + +test('hire.md QA Complement Rule is search-first and not tool-hardcoded', () => { + // Mirror of the verify.md anti-hardcoding rule. /awos:hire must + // propose a QA agent by searching the registry, not by always + // including testing-expert or always recommending Playwright for + // any frontend stack. Lock out the prior hard rules so they do not + // creep back in. + const body = readUtf8(path.join(commandsDir, 'hire.md')); + assert.ok( + /QA Complement Rule/.test(body), + 'commands/hire.md must declare a QA Complement Rule section' + ); + assert.ok( + !/always include\s+`?testing-expert`?/i.test(body), + 'commands/hire.md must not declare a blanket "always include testing-expert" rule — the rule is search-first now' + ); + assert.ok( + !/always include\s+`?playwright`?/i.test(body), + 'commands/hire.md must not declare a blanket "always include playwright" rule for any stack — tool choice depends on the project' + ); +}); + +test('setup-config does not auto-populate .claude/agents/', () => { + // .claude/agents/ is the user's customization area. The earlier draft + // of this PR shipped a `plugins/awos/agents` → `.claude/agents` copy + // operation that would silently clobber user-authored subagents on + // every install. AWOS-bundled agents (e.g. testing-expert) are hired + // through awos-recruitment instead — so the installer must not + // create or overwrite anything under .claude/agents/. + const { copyOperations } = require( + path.join(repoRoot, 'src', 'config', 'setup-config.js') + ); + const offending = copyOperations.find( + (op) => op.destination === '.claude/agents' + ); + assert.ok( + !offending, + 'setup-config must not declare a copy operation targeting .claude/agents/ — that directory is user-owned' + ); +}); + +test('templates/qa-context-template.md is not bundled with AWOS core', () => { + // The test-registry template was originally shipped with this PR but + // ended up unused inside the AWOS repo (the testing-expert agent that + // would have populated it lives in awos-recruitment). Lint stops the + // file from sneaking back in — if a future PR wants to add a related + // template, it should justify the contract first. + const file = path.join(templatesDir, 'qa-context-template.md'); + assert.ok( + !fs.existsSync(file), + 'templates/qa-context-template.md must not exist in AWOS core — it belongs alongside testing-expert in awos-recruitment' + ); +}); + +test('SDD-07 recognizes the dual-model QA coverage', () => { + // The audit dimension was updated to recognize both: + // - the new model (Feature Testing & Regression as the final slice) + // - the legacy per-slice Verify-task model + // If the wording drifts so that only the legacy model is recognized, + // every PR using the new model would warn — and vice versa. + const file = path.join(dimensionsDir, 'spec-driven-development.md'); + const body = readUtf8(file); + assert.ok( + /Feature Testing & Regression/.test(body), + 'SDD-07 must reference the new "Feature Testing & Regression" final slice when discussing QA coverage' + ); + assert.ok( + /Legacy model/i.test(body), + 'SDD-07 must still recognize the legacy per-slice QA verification model so older specs are not over-flagged' + ); +}); + test('context/ references in prompts are internally consistent', () => { // Build a writer/reader map by scanning all prompts. A path is considered // consistent if every reference to it appears in at least one prompt — i.e.