diff --git a/CHANGELOG.md b/CHANGELOG.md index 53208320..bbcbb14b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to the claude-plugins project will be documented in this fil The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Entries are listed newest-first; each plugin section is treated as released when merged to `main`. +### code v1.16.2 + +#### Changed +- `guided-manual-qa` checks whether a fixed-port control launcher supports isolated ports, sessions, or project names for concurrent workers before choosing it, and falls back to a documented manual isolated stack with recorded process ownership proof when it does not. +- `guided-manual-qa` no longer treats a parent supervisor, launchd wrapper, or control command reporting `started` as readiness; the actual listener and the route-owned ready selector must be proven first. A wrapper that hangs before spawning its child gets one bounded foreground diagnostic of the same command, stopped before any fallback. + ### code v1.16.1 #### Changed diff --git a/plugins/code/.claude-plugin/plugin.json b/plugins/code/.claude-plugin/plugin.json index d5ce3e56..115da630 100644 --- a/plugins/code/.claude-plugin/plugin.json +++ b/plugins/code/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "code", "description": "Code and planning framework plugin", - "version": "1.16.1", + "version": "1.16.2", "author": { "name": "ClosedLoop", "email": "support@closedloop.ai" diff --git a/plugins/code/skills/guided-manual-qa/SKILL.md b/plugins/code/skills/guided-manual-qa/SKILL.md index dcb8d9ce..13caa005 100644 --- a/plugins/code/skills/guided-manual-qa/SKILL.md +++ b/plugins/code/skills/guided-manual-qa/SKILL.md @@ -24,7 +24,7 @@ State the proposed scope, environment, fixtures, and known gaps before launching - Lock the runtime target before launching anything. The default manual-QA target is the exact active worktree running locally. A Vercel deployment, branch preview, staging URL, or green preview check is evidence that a remote deployment exists; it is not authorization to use that deployment for manual QA. Use a remote preview only when the user explicitly requests it or current repository instructions explicitly designate it as the manual-QA target for this change. If neither authority exists, remain local. - Treat the origin as part of the test contract. Record the approved scheme, host, and port, then verify the browser's actual URL before accepting screenshots, observations, or human confirmation. Evidence collected from an unapproved origin is invalid setup evidence: record an `ORACLE CORRECTION`, withdraw any dependent result, and reopen the affected checkpoints on the approved origin. - On an authenticated page, wait for a visible control owned by the target route and verify the settled browser URL after client bootstrap. An initial navigation or launcher-ready URL alone can precede an auth redirect. The bundled launcher accepts `--ready-selector` for this gate; see [references/browser-state-fixtures.md](references/browser-state-fixtures.md). -- Use repository-supported bootstrap and launch commands from the exact active worktree. Do not invent a setup path when the repository documents one. +- Use repository-supported bootstrap and launch commands from the exact active worktree. Do not invent a setup path when the repository documents one. Before choosing a control launcher that binds fixed ports, verify whether it supports isolated ports, sessions, or project names for concurrent workers. If it does not, use a documented manual isolated stack and record exact process ownership proof. - Keep source unchanged while merely testing. Any generated data, config, or fixture must be disposable, ignored, or stored outside the tracked tree unless the user separately asks to productize it. - Use only local or explicitly designated non-production data and services. Prefer repository-supported seeds, fixtures, test accounts, and reset paths. Never point destructive or mutating tests at production. - Before starting services, inspect relevant listeners and processes. Do not kill or reuse an unrelated process. If a port is occupied, identify its owner and use a documented alternative or stop for direction. @@ -33,7 +33,7 @@ State the proposed scope, environment, fixtures, and known gaps before launching - Before the first checkpoint, prove the entire persistence chain: container or native service identity, host-to-container port mapping when applicable, database name, migration state, seed profile/source, non-sensitive population summary, and the app/API process's effective connection target. A successful seed against one database does not prove the running application uses it. - Distinguish mock-backed and database-backed surfaces explicitly. A fixture-only prototype may need no database, while adjacent production consumers of the same shared component may require a locally seeded app/API stack. Record which checkpoint uses which data source; do not describe prototype fixtures as seeded production data or skip a required production-consumer regression because the prototype renders. - A prototype is an optional harness for eligible shared code, not a manual-QA destination by itself. Do not add prototype-only E2E tests. Assess repository-supported E2E coverage for affected production code separately; neither a manual finding nor Storybook reachability automatically requires a new E2E test. -- Start services from the resolved worktree. Record the launch commands, working directories, process identifiers, ports, and health checks. Prove that each tested listener belongs to this worktree using the strongest available evidence: process command and cwd, parent process, build or commit marker, service metadata, or a repository-provided diagnostic endpoint. +- Start services from the resolved worktree. Record the launch commands, working directories, process identifiers, ports, and health checks. Prove that each tested listener belongs to this worktree using the strongest available evidence: process command and cwd, parent process, build or commit marker, service metadata, or a repository-provided diagnostic endpoint. A parent supervisor, launchd wrapper, or control command reporting `started` is not readiness by itself; prove the actual listener and the route-owned ready selector before presenting a checkpoint. If a wrapper hangs before spawning the child or listener, run one bounded foreground diagnostic of the same documented command to distinguish wrapper failure from app/runtime failure, then stop that diagnostic before trying a fallback. - If the QA session spans tool calls or worker turns, keep its services under a repository-supported or OS-supported owner that survives that boundary. Record how to inspect and stop that owner. On resume, read the existing QA record and recheck the current head, owned processes, listeners, data target, and exact route; earlier PIDs and ready checks are historical evidence, not proof that the environment is still available. Then apply "Rebind results after a head change" in [references/plan-methodology.md](references/plan-methodology.md) to every recorded result, name the next `PENDING` checkpoint as the resume point in the record, and continue from it. Do not re-present a checkpoint whose result still applies to the current head. - After that proof succeeds, launch the UI the user requested for the intentional interactive session. Do not open unrelated surfaces or claim an unlaunched surface was exercised. - Record feature-flag assignments, roles, permissions, account or fixture identity, and other state that changes the observable result. Redact credentials and secrets. diff --git a/tools/guided-manual-qa/src/skill-contract.test.ts b/tools/guided-manual-qa/src/skill-contract.test.ts index 38856bc9..7d8c50d9 100644 --- a/tools/guided-manual-qa/src/skill-contract.test.ts +++ b/tools/guided-manual-qa/src/skill-contract.test.ts @@ -96,6 +96,22 @@ describe("guided-manual-qa skill contract", () => { ); }); + it("proves service readiness beyond a launcher or wrapper report", () => { + const environment = section(skill, "## Prepare a trustworthy local environment"); + expect(environment).toContain( + "Before choosing a control launcher that binds fixed ports, verify whether it supports isolated ports, sessions, or project names for concurrent workers.", + ); + expect(environment).toContain( + "use a documented manual isolated stack and record exact process ownership proof", + ); + expect(environment).toContain("reporting `started` is not readiness by itself"); + expect(environment).toContain( + "prove the actual listener and the route-owned ready selector before presenting a checkpoint", + ); + expect(environment).toContain("run one bounded foreground diagnostic of the same documented command"); + expect(environment).toContain("then stop that diagnostic before trying a fallback"); + }); + it("stays standalone and harness-neutral", () => { for (const path of textFiles(SKILL_ROOT)) { const text = readFileSync(path, "utf8");