{"id":"b538d362-599f-498a-828b-3e538ee1a380","shortId":"Cve7Q4","kind":"skill","title":"ql-plan","tagline":"Part of the quantum-loop autonomous development pipeline (brainstorm \\u2192 spec \\u2192 plan \\u2192 execute \\u2192 review \\u2192 verify). Convert a PRD into machine-readable quantum.json with dependency DAG, granular 2-5 minute tasks, and execution metadata. Use after creating a ","description":"# Quantum-Loop: Plan\n\nYou are converting a Product Requirements Document (PRD) into a machine-readable `quantum.json` file that will drive autonomous execution. Every decision you make here determines whether the execution loop succeeds or fails.\n\n## Phase 0: Phase-skip check (Phase 18 / P2.4)\n\nBefore reading the PRD, check whether a prior `/ql-plan` run already converted the same PRD + spec handoff into quantum.json:\n\n```bash\nPRD=$(ls -t tasks/prd-*.md 2>/dev/null | head -1)\nSPEC_HANDOFF=\".handoffs/spec.md\"\nARGS=()\n[[ -n \"$PRD\" ]]             && ARGS+=(\"$PRD\")\n[[ -f \"$SPEC_HANDOFF\" ]]    && ARGS+=(\"$SPEC_HANDOFF\")\n\nif bash lib/phase-skip.sh skip plan . \"${ARGS[@]}\"; then\n  echo \"[SKIP] plan is up-to-date — PRD + spec handoff unchanged.\"\n  bash lib/handoff.sh read plan | jq '.'\n  exit 0\nfi\n```\n\nAfter writing quantum.json and `.handoffs/plan.md`, record the fingerprint:\n\n```bash\nPRD_H=$(bash lib/phase-skip.sh hash \"$PRD\")\nSPEC_H=$(bash lib/phase-skip.sh hash \"$SPEC_HANDOFF\")\nFP=$(jq -cn --arg pp \"$PRD\" --arg ph \"$PRD_H\" --arg sp \"$SPEC_HANDOFF\" --arg sh \"$SPEC_H\" \\\n  '{artifacts: [{path: $pp, sha256: $ph}, {path: $sp, sha256: $sh}]}')\nbash lib/phase-skip.sh record plan \"$FP\" . >/dev/null\n```\n\n## Prerequisite: read prior-stage handoffs (Phase 15 / P2.3)\n\nBefore reading the PRD, ingest every prior-stage handoff so decisions, rejected alternatives, and risks carry forward across context compaction:\n\n```bash\nbash lib/handoff.sh all | jq '.'\nbash lib/handoff.sh read brainstorm | jq '.'\nbash lib/handoff.sh read spec | jq '.'\n```\n\nTreat `spec.decided` as binding (these are the ACs you MUST plan for), `spec.rejected` as closed (don't re-introduce), `spec.remaining` as explicit gaps you should surface to the user before finalizing the DAG, and the union of `brainstorm.risks ∪ spec.risks` as mandatory inputs to every story's risk consideration.\n\nAt the end of `/ql-plan`, write `.handoffs/plan.md`:\n\n```bash\nbash lib/handoff.sh write plan \"$(cat <<'JSON'\n{\n  \"decided\":   [\"<each DAG + wave decision>\", \"<contract materialization picks>\"],\n  \"rejected\":  [\"<each alternative story split / ordering considered>\"],\n  \"risks\":     [\"<carried from upstream + any new planning risks>\"],\n  \"files\":     [\"quantum.json\"],\n  \"remaining\": [\"<any AC you could not resolve into a concrete story>\"],\n  \"notes\":     \"<notes on parallelism, file-conflict sets, contract choices>\"\n}\nJSON\n)\"\n```\n\n## Step 1: Read the PRD\n\n1. Look for the most recent PRD in `tasks/prd-*.md`\n2. If multiple PRDs exist, ask the user which one to convert\n3. Read the entire PRD, extracting:\n   - User stories (US-NNN) with acceptance criteria\n   - Functional requirements (FR-N)\n   - Technical considerations and constraints\n   - Non-goals (to prevent scope creep during execution)\n\nAlso read:\n- Project files (package.json, pyproject.toml, etc.) for project name and tech stack\n- Existing code structure to determine correct file paths for tasks\n\n## Step 2: Analyze Dependencies\n\nBuild a dependency graph between stories. Dependencies follow natural layering:\n\n```\n1. Schema / Database changes (foundation)\n2. Type definitions / Models (depends on schema)\n3. Backend logic / API endpoints (depends on types)\n4. UI components (depends on API)\n5. Integration / Aggregate views (depends on components)\n```\n\n### Dependency Rules\n- A story that reads from a table DEPENDS ON the story that creates that table\n- A story that renders data DEPENDS ON the story that provides the API\n- A story that tests integration DEPENDS ON all component stories\n- If two stories touch unrelated parts of the codebase, they are INDEPENDENT (no dependency)\n\n### Cycle Detection\nAfter building the dependency graph, verify there are no cycles. If you detect a cycle:\n1. STOP and inform the user\n2. Explain which stories form the cycle\n3. Ask how to break the cycle (usually by splitting a story)\n\n### Contracts Generation (after dependency DAG)\n\nAfter building the dependency graph, scan for values that appear in 2+ stories' acceptance criteria or task descriptions. These are **contract candidates** — shared constants that parallel agents must agree on.\n\n1. **Identify candidates:** Look for repeated references to the same entity across stories — secret key names, environment variable names, type/class names, API route paths, event names, CSS class names\n2. **Group by category:** Organize candidates into logical categories:\n   - `secret_keys` — shared secret/config key names\n   - `env_vars` — environment variable names\n   - `shared_types` — type names, class names, enum values\n   - `api_routes` — API endpoint paths\n   - `event_names` — event/signal names\n   - `css_classes` — shared CSS class names or design tokens\n3. **Rule: When in doubt, add it** — an unused contract entry costs nothing; a missing contract causes cross-story mismatches that require manual fixes\n4. **Optional `pattern` field:** For values with a naming convention, add a `pattern` regex so the implementer can validate at runtime (e.g., `\"pattern\": \"^[a-z][a-z0-9-]*$\"`)\n\nExample contracts block:\n```json\n\"contracts\": {\n  \"secret_keys\": {\n    \"openai\": { \"value\": \"openai-api-key\", \"pattern\": \"^[a-z][a-z0-9-]*$\" },\n    \"db_password\": { \"value\": \"DATABASE_PASSWORD\" }\n  },\n  \"shared_types\": {\n    \"priority_enum\": { \"value\": \"Priority\" }\n  }\n}\n```\n\nAdd the `contracts` object to quantum.json at the top level, after `codebasePatterns`.\n\nFor language-specific shape and definition examples, read `references/contract-shapes.md` when generating structural contracts for shared types.\n\n### Structural Contract Generation (Enhanced)\n\nAfter building the basic contracts block above, enhance `shared_types` entries with structural information so that downstream layers (materialization, type audit) can generate real code files.\n\n#### Step 1: Detect Shared Types\n\nScan all stories' descriptions, acceptance criteria, and task descriptions for type names (classes, interfaces, structs, enums) that appear in **2 or more stories**. These are structural contract candidates.\n\nFor each shared type candidate:\n1. **`shape`** — A structured representation of the type's interface:\n   - `properties`: Array of `{name, type, readonly?}` entries\n   - `methods`: Array of `{name, params: [{name, type}], returns}` entries\n2. **`definition`** — A verbatim code string in the project's language (see Step 2 for language detection)\n3. **`owner`** — The story ID that primarily implements/defines the type (usually the story that creates it as an output)\n4. **`consumers`** — Array of story IDs that reference or depend on the type (all stories except the owner)\n5. **`definitionFile`** — The file path where the type definition should live (see \"Inferring `definitionFile` Paths\" below)\n\n**Anti-rationalization:** If 2+ stories reference a type by name, you MUST generate `shape` and `definition` fields. \"It's only used lightly\" or \"the shape is obvious\" are not valid reasons to skip structural contracts. The downstream materializer cannot generate a file without a `definition` or `shape`.\n\n#### Step 2: Detect Project Language\n\nDetermine the project's primary language by checking for config files in the project root:\n\n| Config File | Language | `definition` Style |\n|---|---|---|\n| `tsconfig.json` | TypeScript | `export interface X { ... }` or `export type X = { ... }` |\n| `pyproject.toml` or `setup.py` | Python | `class X(Protocol): ...` or `@dataclass class X: ...` |\n| `go.mod` | Go | `type X interface { ... }` or `type X struct { ... }` |\n\nDetection priority: check in the order listed above. If multiple config files exist, use the `definitionFile` extension as a tiebreaker.\n\n#### Step 3: Generate Language-Specific Definitions\n\nBased on the detected language, generate the `definition` string:\n\n**TypeScript:**\n```\nexport interface TaskResult {\n  id: string;\n  status: \"pending\" | \"passed\" | \"failed\";\n  output: string;\n  errorMessage?: string;\n}\n```\n\n**Python:**\n```\nfrom dataclasses import dataclass\nfrom typing import Optional\n\n@dataclass\nclass TaskResult:\n    id: str\n    status: str  # \"pending\" | \"passed\" | \"failed\"\n    output: str\n    error_message: Optional[str] = None\n```\n\n**Go:**\n```\ntype TaskResult struct {\n    ID           string `json:\"id\"`\n    Status       string `json:\"status\"`\n    Output       string `json:\"output\"`\n    ErrorMessage string `json:\"errorMessage,omitempty\"`\n}\n```\n\n#### Step 4: Reference for Examples\n\nSee `references/contract-shapes.md` for complete examples of `shape` JSON paired with `definition` strings for all three languages. Load this reference when shared types are detected — it contains guidance on when to generate `definition` (multi-consumer types) vs shape-only (advisory, single-consumer types).\n\n#### Step 5: Inferring `definitionFile` Paths\n\nWhen a contract entry does not have an explicit `definitionFile`, infer the path from the project's existing directory structure. Check directories in this priority order:\n\n1. `src/shared/types/` — TypeScript convention (most specific)\n2. `src/types/` — common alternative for TypeScript/general\n3. `src/interfaces/` — common alternative for interface-heavy projects\n4. `types/` — project-root convention (some projects keep types at root level)\n5. `shared/` — Python and Go convention\n\n**If a matching directory exists**, use it as the base path for the `definitionFile`. Append the type name in kebab-case with the appropriate language extension (`.ts`, `.py`, `.go`).\n\n**If none of these directories exist**, default based on the detected language:\n- **TypeScript:** `src/shared/types/<kebab-name>.ts`\n- **Python:** `src/shared/<snake_name>.py`\n- **Go:** `internal/shared/<snake_name>.go`\n\n**If `definitionFile` IS explicitly set** in a contract entry (e.g., from user input or a previous run), it takes precedence over any inference. Do not override explicit paths.\n\n#### Complete Enhanced Contract Example\n\nBelow is a complete example of a `contracts.shared_types` entry with all enhanced fields. This demonstrates a `TaskResult` type shared between US-003 (which implements it) and US-007/US-009 (which consume it), in a TypeScript project that has an existing `src/types/` directory:\n\n```json\n\"contracts\": {\n  \"shared_types\": {\n    \"task_result\": {\n      \"value\": \"TaskResult\",\n      \"pattern\": \"^[A-Z][a-zA-Z]*$\",\n      \"definitionFile\": \"src/types/task-result.ts\",\n      \"owner\": \"US-003\",\n      \"consumers\": [\"US-007\", \"US-009\"],\n      \"shape\": {\n        \"properties\": [\n          { \"name\": \"id\", \"type\": \"string\" },\n          { \"name\": \"status\", \"type\": \"'pending' | 'passed' | 'failed'\" },\n          { \"name\": \"output\", \"type\": \"string\" },\n          { \"name\": \"errorMessage\", \"type\": \"string\", \"readonly\": false }\n        ],\n        \"methods\": []\n      },\n      \"definition\": \"export interface TaskResult {\\n  id: string;\\n  status: 'pending' | 'passed' | 'failed';\\n  output: string;\\n  errorMessage?: string;\\n}\"\n    }\n  }\n}\n```\n\nKey points:\n- `definitionFile` was inferred from the existing `src/types/` directory (priority item 2), not hardcoded\n- `owner` is the story that creates the type as its primary output\n- `consumers` lists every other story that references the type\n- `shape` provides a structured representation that downstream tools can use to generate code if `definition` is missing\n- `definition` provides the verbatim code string in the detected language (TypeScript in this case)\n\n#### Stories with No Shared Types\n\nIf no type names appear in 2+ stories, do NOT generate `shape` or `definition` fields. The basic contracts block (with `value` and optional `pattern`) is sufficient. This maintains backward compatibility — entries with only `value` and `pattern` remain valid.\n\n### Interface Change Detection\n\nWhen a story modifies the return type, parameter types, or function/method signatures of code consumed by other stories, it creates a **contract-breaking change**. These changes require explicit coordination to prevent regressions in parallel execution.\n\n#### When to Set `contractBreaking: true`\n\nSet `contractBreaking: true` on any story that:\n\n1. **Changes a return type** of a function, method, or class consumed by another story\n2. **Changes parameter types** (adding required parameters, removing parameters, or changing parameter types) of a shared function or method\n3. **Changes a class/interface signature** (renaming methods, changing method visibility, altering inheritance) that other stories depend on\n\nWhen `contractBreaking` is set, the story description **MUST** include an explanation of what interface changed and why. This explanation helps the execution engine and human reviewers understand the blast radius.\n\n#### When to Set `fixes`\n\nSet `fixes: [\"US-XXX\"]` on any story that is specifically designed to resolve regressions or breakage introduced by another story. The `fixes` field is an array of story IDs whose regressions this story addresses.\n\n#### Scheduling Constraint\n\nStories with `contractBreaking: true` **MUST** have explicit `dependsOn` edges that prevent them from being co-scheduled (running in the same wave) with any story that consumes the changed interface. This ensures consumers always see the final version of the interface, not an in-flight breaking change.\n\n**Rule:** For every consumer of the changed interface, either:\n- The consumer `dependsOn` the contract-breaking story (consumer runs after), OR\n- The contract-breaking story `dependsOn` the consumer (breaking change runs after consumer finishes with old interface)\n\n#### Examples\n\n**Example 1: Breaking change to a shared interface**\n\nUS-003 changes the return type of `IParser.parse()` from `string` to `ParseResult`. US-005 and US-008 both call `IParser.parse()`. This is a contract-breaking change because consumers expect the old return type.\n\n```json\n{\n  \"id\": \"US-003\",\n  \"title\": \"Refactor IParser.parse() to return ParseResult\",\n  \"description\": \"Changes IParser.parse() return type from string to ParseResult. This is contractBreaking because US-005 and US-008 consume IParser.parse() and expect the old return type.\",\n  \"contractBreaking\": true,\n  \"dependsOn\": [],\n  \"storyType\": \"logic\"\n}\n```\n\nUS-005 and US-008 must add `\"US-003\"` to their `dependsOn` arrays so they run after the breaking change lands.\n\n**Example 2: Fixing regressions from a breaking change**\n\nUS-004 is created specifically to fix async regressions introduced by US-003's interface change. It patches call sites that were missed or broke unexpectedly.\n\n```json\n{\n  \"id\": \"US-004\",\n  \"title\": \"Fix async regressions from IParser refactor\",\n  \"description\": \"Fixes async call sites that broke when US-003 changed IParser.parse() return type.\",\n  \"fixes\": [\"US-003\"],\n  \"dependsOn\": [\"US-003\"],\n  \"storyType\": \"logic\"\n}\n```\n\n**Example 3: Non-breaking change (no flag needed)**\n\nUS-007 adds an optional `verbose` parameter with a default value to `IParser.parse()`. Existing callers continue to work without modification because the parameter is optional.\n\n```json\n{\n  \"id\": \"US-007\",\n  \"title\": \"Add optional verbose parameter to IParser.parse()\",\n  \"description\": \"Adds optional verbose parameter with default false. Existing callers are unaffected.\",\n  \"dependsOn\": [\"US-003\"],\n  \"storyType\": \"logic\"\n}\n```\n\nNote: `contractBreaking` is **NOT** set because adding an optional parameter with a default value does not change the interface for existing consumers.\n\n### Story Type Tagging\n\nAfter building the dependency DAG and contracts, assign a `storyType` field to every story. This field is used by the dag-validator to determine which restructuring is safe.\n\n#### Allowed Values\n\n| `storyType` | Description |\n|---|---|\n| `types-only` | Stories where ALL tasks create type definitions, interfaces, schemas, or `.d.ts` files with no runtime logic. |\n| `config` | Scaffold/config-only stories: migrations, `package.json` changes, Dockerfile, CI yaml, pure markdown. |\n| `test` | Stories that only add tests with no new source code. |\n| `logic` | Everything else (the default). Any story with business logic, API handlers, data processing, or external API calls. |\n\n#### Examples\n\n**`types-only`** — `US-001: Define TaskResult interface`\nTasks only create `.ts` interface files (e.g., `src/types/task-result.ts`). No runtime logic, no function bodies, no side effects — purely structural type definitions.\n\n**`config`** — `US-002: Set up database migration`\nTasks only create migration files, update `package.json` dependencies, or modify CI configuration. No `if` statements, no loops, no data transformations.\n\n**`test`** — `US-004: Add unit tests for task filtering`\nTasks only add test files (e.g., `tests/task-filter.test.ts`). No new source modules are created — only test coverage for existing code.\n\n**`logic`** — `US-003: Implement task filtering API`\nTasks contain `if`/`loop`/data logic, API route handlers, database queries, or calls to external services. This is the default and the most common type.\n\n#### Anti-Rationalization Guard\n\n> **If a story has any task that implements business logic, API handlers, data processing, or calls external APIs, it is `logic`, not `types-only`. When in doubt, use `logic`.**\n\nCommon traps:\n- A story that creates an interface AND a helper function is `logic`, not `types-only` — the helper function is runtime code.\n- A story that creates a schema file with validation logic (e.g., Zod schemas with `.refine()`) is `logic` — refinements execute at runtime.\n- A story that creates config AND a small utility to read that config is `logic` — the utility is runtime code.\n\n#### Default Behavior\n\nIf you are unsure, set `storyType` to `logic`. It is always safe to over-classify as `logic` — under-classifying as `types-only` can cause incorrect restructuring by the dag-validator, which may reorder stories that should not be reordered.\n\n### wiring_verification Generation\n\nTasks that create new modules, handlers, or components **SHOULD** have a `wiring_verification` object unless wiring is handled by a dependent story via `consumedBy`.\n\n**Rule:** If a task creates a new file (function, class, component, handler) that must be imported by an existing file, add:\n```json\n\"wiring_verification\": {\n  \"file\": \"path/to/caller.ts\",\n  \"must_contain\": [\"import { NewThing }\", \"NewThing\"]\n}\n```\n\n- `file`: The existing file that should import/call the new code\n- `must_contain`: Array of exact strings that must appear in that file after implementation\n\n**Exception:** If the task's output will be consumed by a dependent story (the dependent story is responsible for the import), use `consumedBy` instead of `wiring_verification`. Both on the same task is redundant.\n\n### consumedBy Generation\n\nIf a task's output is listed in a dependent story's acceptance criteria, the task **MUST** have a `consumedBy` field listing the consuming story IDs.\n\n**Rule:** When Story A creates a component/module and Story B's acceptance criteria reference it:\n1. Add `\"consumedBy\": [\"US-B\"]` to the task in Story A\n2. Add to Story B's **first task** description: `\"Import <component> from <path> (created by <Story A ID>). Do NOT create an inline replacement.\"`\n\nThis prevents the consumer story's agent from re-implementing something that already exists. The `consumedBy` field is the signal: \"Don't build this yourself — it will exist when your dependencies are satisfied.\"\n\n### coverageThreshold Generation\n\nSet the top-level `coverageThreshold` field in quantum.json:\n1. **Ask the user** for their desired coverage threshold, OR\n2. **Infer from project config:** check `.nycrc`, `jest.config.*`, `pyproject.toml [tool.coverage]`, `.coveragerc`, `go test` flags for an existing threshold\n3. **Default:** 80 (percent). Set to `null` to report coverage without blocking.\n\nThe quality-reviewer will enforce this threshold during review. If the project has no coverage tooling, the reviewer will skip enforcement on the first story and enforce after first successful measurement.\n\n## Step 3: Decompose Stories into Tasks\n\nFor each story, break it into granular tasks. Each task should take 2-5 minutes for an AI agent.\n\n### Task Requirements\nEach task MUST specify:\n- `id`: Sequential within the story (T-001, T-002, ...)\n- `title`: Short imperative description\n- `description`: Exact steps to perform. Include:\n  - What to create/modify\n  - Specific logic or behavior\n  - How it connects to other code\n- `filePaths`: Array of files this task creates or modifies\n- `commands`: Array of verification commands with expected behavior\n- `testFirst`: Boolean -- should a test be written first? (default: true for logic, false for config/scaffolding)\n- `status`: Always \"pending\" when created\n\n### Integration Wiring Rule (CRITICAL)\n\nEvery story that creates a new module, function, or component MUST include a final task that wires it into the existing codebase. Without this, parallel agents build components in isolation that are never called.\n\n**Bad:** Story creates `extract_docx_images()` but never modifies `DocxLoader.load()` to call it.\n**Good:** Story's last task is \"Wire `extract_docx_images()` into `DocxLoader.load()` — add import, call the function after text extraction, pass results to chunk builder.\"\n\nThe wiring task MUST specify:\n- Which existing file(s) to modify (the caller, not the new module)\n- What import to add\n- Where in the control flow to insert the call\n- A verification command that proves the wiring works (e.g., an integration test or a pipeline run)\n\nIf a story creates something that will be wired by a DEPENDENT story, document this explicitly in the dependent story's first task: \"Import and call `X` from the newly completed `US-NNN`.\"\n\n### Consumer Verification Pattern\n\nWhen Story A creates a function and Story B (dependent) should call it:\n- Story A's acceptance criteria: \"function exists, passes unit tests\"\n- Story B's acceptance criteria MUST include: \"pipeline calls `<function>` for every `<input>`\"\n\n**Bad:** US-007 AC says \"validate_plan_item rejects invalid items\" (only tests the function in isolation)\n**Good:** US-013 AC says \"pipeline calls validate_plan_item() for every generated plan item\" (verifies wiring)\n\nThe key shift: validation of wiring belongs on the **consumer** story, not the creator.\n\n### Task Sizing Guide\n\n**Right-sized (2-5 minutes):**\n- Write a test for one function\n- Implement one function to pass the test\n- Add one column to a database migration\n- Create one React component (no logic, just rendering)\n- Add one API route handler\n- **Wire a new module into an existing caller** (import + call + verify)\n\n**Too large (split these):**\n- \"Build the component with all its logic and tests\"\n- \"Create the API endpoint with validation and error handling\"\n- \"Add the feature end-to-end\"\n\n**Too small (combine these):**\n- \"Create an empty file\"\n- \"Add an import statement\"\n- \"Fix a typo in a comment\"\n\n### testFirst Mandate\n\n**`testFirst: true` is the default for ALL tasks.** TDD is a mandate, not a suggestion.\n\n**Exempt categories** (the ONLY cases where `testFirst: false` is allowed):\n- Config/scaffold files (migrations, package.json, tsconfig changes)\n- Pure type definitions (interfaces, type aliases, enums with no logic)\n- Documentation-only tasks (README, comments, markdown files)\n- The test task itself (when test and implementation are separate tasks)\n\n**For any exempt task**, the planner **MUST** add a `notes` field with justification:\n```json\n\"testFirst\": false,\n\"notes\": \"testFirst: false — pure type definition, no runtime logic\"\n```\n\n**Anti-rationalization line:** If a task has an `if`, a loop, a data transformation, or calls an external API, it is NOT config. Set `testFirst: true`.\n\n### Edge Case Test Requirements\n\nWhen `testFirst: true`, the task description MUST instruct the agent to include tests for:\n- **Boundary values:** None/null, empty string, NaN, zero, negative numbers\n- **Type variations:** scalar vs collection vs framework-specific types (e.g., DataFrame vs dict)\n- **Collision scenarios:** same identifier from different sources (e.g., same filename in different dirs)\n- **Scale:** 1 item (minimum), 10 items (typical), 100+ items (context pollution shows at scale)\n\nSee `references/edge-cases.md` for language-specific patterns.\n\nField data shows 100% of post-implementation bugs were edge cases that passed happy-path tests.\n\n## Step 4: Generate quantum.json\n\nAssemble the complete quantum.json with this structure:\n\n```json\n{\n  \"project\": \"[Project name from package.json or user input]\",\n  \"branchName\": \"ql/[feature-name-kebab-case]\",\n  \"description\": \"[One-line feature description from PRD title]\",\n  \"prdPath\": \"[Path to the PRD file]\",\n  \"designPath\": \"[Path to design doc, or null]\",\n  \"createdAt\": \"[ISO 8601 timestamp]\",\n  \"updatedAt\": \"[ISO 8601 timestamp]\",\n  \"stories\": [\n    {\n      \"id\": \"US-001\",\n      \"title\": \"[Story title]\",\n      \"description\": \"As a [user], I want [feature] so that [benefit]\",\n      \"acceptanceCriteria\": [\"criterion 1\", \"criterion 2\", \"Typecheck passes\"],\n      \"priority\": 1,\n      \"status\": \"pending\",\n      \"dependsOn\": [],\n      \"tasks\": [\n        {\n          \"id\": \"T-001\",\n          \"title\": \"[Task title]\",\n          \"description\": \"[Exact steps]\",\n          \"filePaths\": [\"path/to/file.ts\"],\n          \"commands\": [\"npm test -- path/to/test.ts\"],\n          \"testFirst\": true,\n          \"status\": \"pending\"\n        }\n      ],\n      \"review\": {\n        \"specCompliance\": { \"status\": \"pending\", \"issues\": [], \"reviewedAt\": null },\n        \"codeQuality\": { \"status\": \"pending\", \"issues\": [], \"reviewedAt\": null }\n      },\n      \"retries\": { \"attempts\": 0, \"maxAttempts\": 3, \"failureLog\": [] },\n      \"notes\": \"\"\n    }\n  ],\n  \"progress\": [],\n  \"codebasePatterns\": []\n}\n```\n\n### Field Rules\n- `branchName`: Always prefixed with `ql/`, followed by kebab-case feature name\n- `priority`: Integer starting at 1. Used as tiebreaker when DAG allows multiple stories.\n- `dependsOn`: Array of story IDs (e.g., `[\"US-001\", \"US-002\"]`). Empty array for stories with no dependencies.\n- `status`: Always \"pending\" for all stories and tasks when first created.\n- `retries.maxAttempts`: Default 3. Increase for complex stories if needed.\n\n## Step 5: Validate and Save\n\nBefore saving, verify:\n- [ ] Every story from the PRD is represented\n- [ ] Every acceptance criterion is preserved (not summarized or paraphrased)\n- [ ] Dependency graph has no cycles\n- [ ] Every story has at least one task\n- [ ] Every task has file paths and verification commands\n- [ ] All statuses are \"pending\"\n- [ ] Branch name follows `ql/` prefix convention\n- [ ] Priority numbers are sequential with no gaps\n- [ ] Every story that creates a function has a consumer story with a wiring AC\n- [ ] **File-touch conflict check:** No two parallel stories (neither depends on the other) share `filePaths` entries. If conflicts found:\n  - Add a \"Reconcile `<file>` changes from `<other-story>`\" task as the **last task** of the **higher-priority** (later-executing) story\n  - This task is written directly into `quantum.json` during plan generation — it is NOT added at runtime\n  - The reconciliation task runs AFTER both stories have merged (it depends on the other story implicitly via execution order)\n  - Add the conflict to `quantum.json` metadata: `\"fileConflicts\": [{\"file\": \"generator.py\", \"stories\": [\"US-007\", \"US-008\"]}]` so users see risks before execution\n  - This does NOT force sequential execution — it allows parallel but plans for the merge\n\nSave to: `quantum.json` in the project root.\n\nIf a previous `quantum.json` exists:\n1. Check if it's for the same feature (same branchName)\n2. If DIFFERENT feature: archive to `archive/YYYY-MM-DD-<old-branch>/quantum.json`\n3. If SAME feature: ask user whether to overwrite or merge\n\n## Step 6: Set Up Runner Scripts\n\nAfter saving quantum.json, ensure the user can run autonomous execution:\n\n1. Add to `.gitignore` if not already present: `.ql-wt/`, `.quantum-logs/`, `quantum.json.tmp`\n2. Check if `quantum-loop.sh` already exists in the project root\n3. If it does NOT exist, inform the user to get the runner scripts:\n\n> \"Plan saved to `quantum.json` with [N] stories and [M] total tasks. Dependencies: [describe the DAG briefly].\n>\n> **To execute:**\n> - Interactive (recommended): `/quantum-loop:ql-execute`\n> - Autonomous overnight (get runner scripts first):\n>   ```bash\n>   # Download runner scripts from the quantum-loop repo\n>   curl -sO https://raw.githubusercontent.com/andyzengmath/quantum-loop/main/templates/quantum-loop.sh && chmod +x quantum-loop.sh\n>   curl -sO https://raw.githubusercontent.com/andyzengmath/quantum-loop/main/templates/quantum-loop.ps1\n>   # Then run:\n>   ./quantum-loop.sh --max-iterations 20                    # Linux/Mac sequential\n>   ./quantum-loop.sh --parallel --max-parallel 4            # Linux/Mac parallel\n>   .\\quantum-loop.ps1 -MaxIterations 20 -SkipPermissions    # Windows PowerShell\n>   ```\"\n\nIf `quantum-loop.sh` already exists, just inform:\n> \"Plan saved to `quantum.json` with [N] stories and [M] total tasks.\n> Run `/quantum-loop:ql-execute` or `./quantum-loop.sh --max-iterations 20`.\"\n\n## Step 7: DAG Validation\n\nAfter generating quantum.json, spawn the dag-validator agent to analyze the DAG for bottlenecks, duplication, and file conflicts. The validator runs automatically — no user action required.\n\n### Spawning the dag-validator\n\nUse the Agent tool to spawn the dag-validator agent with `subagent_type` set to the dag-validator agent definition. Pass two arguments: the quantum.json path and the PRD path. Wait for the agent to complete.\n\n### Idempotency handling\n\nIf the dag-validator returns \"Already validated on \\<timestamp\\>\", skip the remaining validation steps. Print:\n\n> \"Plan already validated on \\<timestamp\\>. Skipping DAG validation.\"\n\n### Receiving results\n\nThe dag-validator returns:\n\n1. A list of stub story IDs (may be empty)\n2. A DAG Health Report text string\n\n### Stub flesh-out\n\nIf the dag-validator returned stub story IDs:\n\n1. Re-read quantum.json (the validator has modified it)\n2. For each stub ID, the story will have `STUB:` prefix in its `notes` field and empty `tasks`, `acceptanceCriteria`, and `filePaths`\n3. Re-invoke the planner with a scoped prompt:\n\n> \"Flesh out these stub stories: [list IDs]. Read the PRD at [prdPath] and the existing quantum.json for context. For each stub, add tasks (with filePaths, commands, testFirst), acceptanceCriteria, and filePaths. Do NOT modify any other stories. Follow all task sizing, testFirst, and wiring rules from this skill.\"\n\n4. Write the fleshed-out stories back to quantum.json\n\n### Stub validation\n\nAfter flesh-out, validate each stub:\n\n- `tasks.length > 0`\n- `acceptanceCriteria.length > 0`\n\nIf a stub passes validation: remove the `STUB:` prefix from its `notes` field.\n\n### Revert on failure\n\nIf a stub fails validation (empty `tasks` or `acceptanceCriteria`):\n\n1. Remove the stub story from the quantum.json `stories` array\n2. For every other story whose `dependsOn` contains the stub ID, remove the stub ID from their `dependsOn` array\n3. Log in the Health Report:\n\n> \"Stub \\<ID\\> could not be fleshed out — reverted to original DAG structure.\"\n\n### Output\n\nPrint the complete DAG Health Report to the user. This is the last thing the user sees before reviewing quantum.json. Format with clear section headers:\n\n- **Bottlenecks** — sequential chains and fan-out blockers detected\n- **Duplication Risks** — overlapping implementation concerns between stories\n- **File Conflicts** — files touched by multiple stories with severity classification\n- **Stubs Created** — new shared-utility stories extracted by the validator\n\n## Anti-Rationalization Guards\n\n| Excuse | Reality |\n|--------|---------|\n| \"Tasks don't need file paths, the agent will figure it out\" | Vague tasks produce vague implementations. Specify exact paths. |\n| \"This task is 10 minutes but it's not worth splitting\" | If it exceeds 5 minutes, the agent may run out of context. Split it. |\n| \"Dependencies are obvious, I don't need to specify them\" | What's obvious to you is invisible to a stateless agent. Specify all dependencies. |\n| \"All tasks should be testFirst\" | Config and scaffolding tasks don't need tests first. Be intentional. |\n| \"Verification commands aren't needed for this task\" | Every task needs a way to verify it worked. No exceptions. |\n| \"I'll skip cycle detection\" | Circular dependencies cause infinite loops in the execution engine. Always check. |\n| \"The wiring will happen naturally\" | It won't. Parallel agents can't see each other's work. Every story needs an explicit wiring task that modifies the CALLER, not just the new module. |\n| \"Creating the module is enough, someone will import it\" | Nobody will. If no task says \"add import X to file Y and call it at line Z\", it stays dead code forever. |","tags":["plan","quantum","loop","andyzengmath","agent-skills","agentskills","claude-code","claude-code-plugin","claude-code-skill","skillsmp"],"capabilities":["skill","source-andyzengmath","skill-ql-plan","topic-agent-skills","topic-agentskills","topic-claude-code","topic-claude-code-plugin","topic-claude-code-skill","topic-skillsmp"],"categories":["quantum-loop"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/andyzengmath/quantum-loop/ql-plan","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add andyzengmath/quantum-loop","source_repo":"https://github.com/andyzengmath/quantum-loop","install_from":"skills.sh"}},"qualityScore":"0.461","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 22 github stars · SKILL.md body (32,705 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-24T13:02:29.158Z","embedding":null,"createdAt":"2026-04-18T23:04:46.289Z","updatedAt":"2026-04-24T13:02:29.158Z","lastSeenAt":"2026-04-24T13:02:29.158Z","tsv":"'-001':2208,2808,3479,3508,3581 '-002':2235,2810,3583 '-003':1394,1435,1862,1898,1944,1977,2011,2018,2021,2083,2290 '-004':1966,1994,2262 '-005':1874,1919,1937 '-007':1400,1438,2034,2061,3066,3771 '-008':1877,1922,1940,3773 '-009':1440 '-013':3083 '-1':121 '-5':37,2790,3119 '/andyzengmath/quantum-loop/main/templates/quantum-loop.ps1':3943 '/andyzengmath/quantum-loop/main/templates/quantum-loop.sh':3935 '/data':2299 '/dev/null':119,217 '/ql-plan':101,316 '/quantum-loop':3911,3988 '/quantum-loop.sh':3946,3953,3993 '/quantum.json':3824 '/us-009':1401 '0':85,161,3540,4243,4245 '1':355,359,450,554,614,836,873,1249,1644,1854,2623,2699,3381,3495,3501,3565,3806,3852,4105,4135,4271 '10':3384,4410 '100':3387,3404 '15':225 '18':91 '2':36,118,369,437,455,560,595,643,859,899,912,973,1018,1255,1495,1561,1659,1958,2635,2709,2789,3118,3497,3817,3867,4115,4145,4281 '20':3950,3966,3997 '3':381,462,567,689,916,1092,1261,1678,2025,2727,2772,3542,3604,3825,3877,4166,4300 '4':470,714,935,1169,1270,3420,3958,4223 '5':476,953,1219,1283,3612,4421 '6':3837 '7':3999 '80':2729 '8601':3470,3474 '9':743,764 'a-z':737,758,1424 'a-z0':740,761 'a-za-z':1427 'ac':270,3067,3084,3685 'accept':393,597,844,2594,2619,3046,3056,3627 'acceptancecriteria':3493,4163,4203,4270 'acceptancecriteria.length':4244 'across':245,625 'action':4027 'ad':1663,2092,3738 'add':694,724,776,1942,2035,2063,2070,2178,2263,2271,2511,2624,2636,2934,2967,3134,3149,3187,3202,3281,3706,3760,3853,4197,4555 'address':1763 'advisori':1213 'agent':610,2660,2795,2900,3339,4010,4036,4044,4054,4069,4394,4424,4452,4516 'aggreg':478 'agre':612 'ai':2794 'alias':3250 'allow':2140,3238,3571,3787 'alreadi':103,2667,3858,3871,3972,4080,4091 'also':413 'alter':1688 'altern':240,1258,1264 'alway':1799,2431,2867,3550,3592,4505 'analyz':438,4012 'anoth':1657,1748 'anti':970,2321,3300,4382 'anti-ration':969,2320,3299,4381 'api':465,475,512,635,671,673,755,2195,2201,2294,2301,2334,2341,3151,3180,3318 'appear':593,857,1559,2540 'append':1303 'appropri':1313 'archiv':3821 'archive/yyyy-mm-dd-':3823 'aren':4474 'arg':125,128,133,141,188,191,195,199 'argument':4058 'array':884,891,937,1755,1948,2534,2835,2844,3575,3585,4280,4299 'artifact':203 'ask':374,568,2700,3829 'assembl':3423 'assign':2118 'async':1972,1997,2004 'attempt':3539 'audit':829 'automat':4024 'autonom':10,69,3850,3915 'b':2617,2628,2639,3038,3054 'back':4230 'backend':463 'backward':1583 'bad':2909,3064 'base':1098,1298,1326 'bash':112,137,155,171,174,180,212,248,249,253,258,319,320,3921 'basic':812,1571 'behavior':2420,2827,2850 'belong':3104 'benefit':3492 'bind':266 'blast':1723 'block':746,814,1573,2738 'blocker':4351 'bodi':2225 'boolean':2852 'bottleneck':4016,4344 'boundari':3344 'brainstorm':13,256 'brainstorm.risks':301 'branch':3659 'branchnam':3439,3549,3816 'break':571,1619,1812,1829,1838,1843,1855,1886,1954,1963,2028,2780 'breakag':1745 'briefli':3906 'broke':1989,2008 'bug':3409 'build':440,540,585,810,2112,2677,2901,3169 'builder':2946 'busi':2193,2332 'call':1879,1983,2005,2202,2307,2339,2908,2920,2936,2976,3018,3041,3061,3087,3163,3315,4562 'caller':2047,2078,2959,3161,4534 'candid':605,616,648,867,872 'cannot':1008 'carri':243,333 'case':1310,1549,3233,3327,3412,3445,3558 'cat':324 'categori':646,651,3230 'caus':705,2447,4498 'chain':4346 'chang':453,1594,1620,1622,1645,1660,1669,1679,1685,1709,1794,1813,1820,1844,1856,1863,1887,1906,1955,1964,1980,2012,2029,2102,2168,3244,3709 'check':89,97,1029,1073,1243,2714,3690,3807,3868,4506 'chmod':3936 'choic':352 'chunk':2945 'ci':2170,2250 'circular':4496 'class':641,667,681,684,852,1055,1060,1131,1654,2500 'class/interface':1681 'classif':4369 'classifi':2436,2441 'clear':4341 'close':277 'cn':187 'co':1781 'co-schedul':1780 'code':427,833,903,1531,1540,1609,2184,2287,2377,2418,2531,2833,4570 'codebas':531,2896 'codebasepattern':787,3546 'codequ':3532 'collect':3357 'collis':3367 'column':3136 'combin':3196 'command':2843,2847,2979,3517,3654,4201,4473 'comment':3211,3260 'common':1257,1263,2318,2354 'compact':247 'compat':1584 'complet':1176,1368,1375,3023,3425,4071,4321 'complex':3607 'compon':472,482,521,2474,2501,2884,2902,3144,3171 'component/module':2614 'concern':4357 'config':1031,1037,1081,2163,2233,2403,2411,2713,3322,4461 'config/scaffold':3239 'config/scaffolding':2865 'configur':2251 'conflict':349,3689,3704,3762,4020,4361 'connect':2830 'consider':311,401 'constant':607 'constraint':403,1765 'consum':936,1207,1216,1403,1436,1510,1610,1655,1792,1798,1817,1824,1831,1842,1847,1889,1923,2107,2554,2605,2657,3027,3107,3680 'consumedbi':2490,2568,2580,2601,2625,2670 'contain':1198,2296,2518,2533,4288 'context':246,3389,4193,4429 'continu':2048 'contract':351,579,604,698,704,745,748,778,801,806,813,866,1004,1225,1347,1370,1416,1572,1618,1828,1837,1885,2117 'contract-break':1617,1827,1836,1884 'contractbreak':1635,1638,1696,1768,1916,1931,2087 'contracts.shared':1379 'control':2971 'convent':723,1252,1275,1288,3664 'convert':24,53,104,380 'coordin':1625 'correct':431 'cost':700 'could':4308 'coverag':2284,2706,2736,2754 'coveragerc':2719 'coveragethreshold':2688,2695 'creat':45,497,930,1503,1615,1968,2151,2214,2242,2281,2359,2381,2402,2469,2495,2612,2646,2650,2840,2870,2878,2911,2996,3033,3141,3178,3198,3601,3675,4371,4540 'create/modify':2823 'createdat':3468 'creator':3111 'creep':410 'criteria':394,598,845,2595,2620,3047,3057 'criterion':3494,3496,3628 'critic':2874 'cross':707 'cross-stori':706 'css':640,680,683 'curl':3931,3939 'cycl':537,548,553,566,573,3639,4494 'd.ts':2157 'dag':34,296,328,583,2115,2132,2453,3570,3905,4000,4008,4014,4032,4042,4052,4077,4096,4102,4117,4129,4316,4322 'dag-valid':2131,2452,4007,4031,4041,4051,4076,4101,4128 'data':504,2197,2258,2336,3312,3402 'databas':452,768,2238,2304,3139 'dataclass':1059,1123,1125,1130 'datafram':3364 'date':150 'db':765 'dead':4569 'decid':326 'decis':72,238,330 'decompos':2773 'default':1325,2042,2075,2098,2189,2314,2419,2728,2859,3218,3603 'defin':2209 'definit':457,794,900,961,985,1014,1040,1097,1105,1183,1204,1464,1533,1536,1568,2153,2232,3247,3295,4055 'definitionfil':954,966,1086,1221,1232,1302,1341,1431,1485 'demonstr':1387 'depend':33,439,442,446,459,467,473,480,483,492,505,518,536,542,582,587,944,1693,2114,2247,2487,2557,2560,2591,2685,3004,3011,3039,3590,3635,3696,3751,3902,4432,4455,4497 'dependson':1773,1825,1840,1933,1947,2019,2081,3504,3574,4287,4298 'describ':3903 'descript':601,843,848,1701,1905,2002,2069,2143,2643,2814,2815,3335,3446,3451,3483,3512 'design':687,1740,3464 'designpath':3461 'desir':2705 'detect':538,551,837,915,1019,1071,1101,1196,1329,1544,1595,4352,4495 'determin':76,430,1022,2135 'develop':11 'dict':3366 'differ':3372,3378,3819 'dir':3379 'direct':3729 'directori':1241,1244,1292,1323,1414,1492 'doc':3465 'dockerfil':2169 'document':57,3006,3256 'documentation-on':3255 'docx':2913,2930 'docxloader.load':2918,2933 'doubt':693,2351 'download':3922 'downstream':825,1006,1525 'drive':68 'duplic':4017,4353 'e.g':735,1349,2218,2274,2388,2985,3363,3374,3579 'echo':143 'edg':1774,3326,3411 'effect':2228 'either':1822 'els':2187 'empti':3200,3347,3584,4114,4161,4267 'end':314,3191,3193 'end-to-end':3190 'endpoint':466,674,3181 'enforc':2744,2760,2766 'engin':1717,4504 'enhanc':808,816,1369,1384 'enough':4544 'ensur':1797,3845 'entir':384 'entiti':624 'entri':699,819,889,898,1226,1348,1381,1585,3702 'enum':669,773,855,3251 'env':658 'environ':630,660 'error':1142,3185 'errormessag':1119,1163,1166,1458,1480 'etc':419 'event':638,676 'event/signal':678 'everi':71,232,307,1512,1816,2123,2875,3063,3092,3619,3626,3640,3647,3672,4283,4480,4524 'everyth':2186 'exact':2536,2816,3513,4405 'exampl':744,795,1172,1177,1371,1376,1852,1853,1957,2024,2203 'exceed':4420 'except':950,2546,4490 'excus':4385 'execut':19,41,70,79,412,1631,1716,2396,3723,3758,3779,3785,3851,3908,3914,3991,4503 'exempt':3229,3276 'exist':373,426,1083,1240,1293,1324,1412,1490,2046,2077,2106,2286,2509,2524,2668,2682,2725,2895,2953,3049,3160,3805,3872,3882,3973,4190 'exit':160 'expect':1890,1926,2849 'explain':561 'explan':1705,1713 'explicit':285,1231,1343,1366,1624,1772,3008,4528 'export':1044,1048,1108,1465 'extens':1087,1315 'extern':2200,2309,2340,3317 'extract':386,2912,2929,2941,4377 'f':130 'fail':83,1116,1139,1452,1475,4265 'failur':4261 'failurelog':3543 'fals':1462,2076,2863,3236,3289,3292 'fan':4349 'fan-out':4348 'featur':3189,3442,3450,3489,3559,3814,3820,3828 'feature-name-kebab-cas':3441 'fi':162 'field':717,986,1385,1569,1752,2121,2126,2602,2671,2696,3284,3401,3547,4159,4258 'figur':4396 'file':65,340,348,416,432,834,956,1011,1032,1038,1082,2158,2217,2244,2273,2384,2498,2510,2515,2522,2525,2543,2837,2954,3201,3240,3262,3460,3650,3687,3767,4019,4360,4362,4391,4559 'file-conflict':347 'file-touch':3686 'fileconflict':3766 'filenam':3376 'filepath':2834,3515,3701,4165,4200,4205 'filter':2268,2293 'final':294,1802,2888 'fingerprint':170 'finish':1848 'first':2641,2763,2768,2858,3014,3600,3920,4469 'fix':713,1728,1730,1751,1959,1971,1996,2003,2016,3206 'flag':2031,2722 'flesh':4124,4176,4227,4237,4311 'flesh-out':4123,4236 'fleshed-out':4226 'flight':1811 'flow':2972 'follow':447,3554,3661,4212 'forc':3783 'forev':4571 'form':564 'format':4339 'forward':244 'found':3705 'foundat':454 'fp':185,216 'fr':398 'fr-n':397 'framework':3360 'framework-specif':3359 'function':395,1651,1675,2224,2365,2374,2499,2882,2938,3035,3048,3078,3126,3129,3677 'function/method':1606 'gap':286,3671 'generat':580,799,807,831,982,1009,1093,1103,1203,1530,1565,2466,2581,2689,3093,3421,3734,4003 'generator.py':3768 'get':3887,3917 'gitignor':3855 'go':1063,1147,1287,1318,1337,1339,2720 'go.mod':1062 'goal':406 'good':2922,3081 'granular':35,2783 'graph':443,543,588,3636 'group':644 'guard':2323,4384 'guid':3114 'guidanc':1199 'h':173,179,194,202 'handl':2484,3186,4073 'handler':2196,2303,2335,2472,2502,3153 'handoff':109,123,132,135,153,184,198,223,236 'handoffs/plan.md':167,318 'handoffs/spec.md':124 'happen':4510 'happi':3416 'happy-path':3415 'hardcod':1497 'hash':176,182 'head':120 'header':4343 'health':4118,4304,4323 'heavi':1268 'help':1714 'helper':2364,2373 'higher':3719 'higher-prior':3718 'human':1719 'id':920,940,1111,1133,1151,1154,1444,1469,1758,1896,1992,2059,2607,2802,3477,3506,3578,4111,4134,4149,4182,4291,4295,4307 'idempot':4072 'identifi':615,3370 'imag':2914,2931 'imper':2813 'implement':730,1396,2291,2331,2545,2664,3127,3270,3408,4356,4403 'implements/defines':923 'implicit':3756 'import':1124,1128,2506,2519,2566,2644,2935,2965,3016,3162,3204,4547,4556 'import/call':2528 'in-flight':1809 'includ':1703,2820,2886,3059,3341 'incorrect':2448 'increas':3605 'independ':534 'infer':965,1220,1233,1362,1487,2710 'infinit':4499 'inform':557,822,3883,3975 'ingest':231 'inherit':1689 'inlin':2652 'input':305,1352,3438 'insert':2974 'instead':2569 'instruct':3337 'integ':3562 'integr':477,517,2871,2987 'intent':4471 'interact':3909 'interfac':853,882,1045,1066,1109,1267,1466,1593,1708,1795,1806,1821,1851,1860,1979,2104,2154,2211,2216,2361,3248 'interface-heavi':1266 'internal/shared':1338 'introduc':282,1746,1974 'invalid':3073 'invis':4448 'invok':4169 'ipars':2000 'iparser.parse':1868,1880,1901,1907,1924,2013,2045,2068 'iso':3469,3473 'isol':2904,3080 'issu':3529,3535 'item':1494,3071,3074,3090,3095,3382,3385,3388 'iter':3949,3996 'jest.config':2716 'jq':159,186,252,257,262 'json':325,353,747,1153,1157,1161,1165,1180,1415,1895,1991,2058,2512,3287,3430 'justif':3286 'kebab':1309,3444,3557 'kebab-cas':1308,3556 'keep':1278 'key':628,653,656,750,756,1483,3099 'land':1956 'languag':790,909,914,1021,1027,1039,1095,1102,1188,1314,1330,1545,3398 'language-specif':789,1094,3397 'larg':3166 'last':2925,3714,4331 'later':3722 'later-execut':3721 'layer':449,826 'least':3644 'level':785,1282,2694 'lib/handoff.sh':156,250,254,259,321 'lib/phase-skip.sh':138,175,181,213 'light':991 'line':3302,3449,4565 'linux/mac':3951,3959 'list':1077,1511,2588,2603,4107,4181 'live':963 'll':4492 'load':1189 'log':3865,4301 'logic':464,650,1935,2023,2085,2162,2185,2194,2222,2288,2300,2333,2344,2353,2367,2387,2394,2413,2428,2438,2825,2862,3146,3175,3254,3298 'look':360,617 'loop':9,49,80,2256,2298,3310,3929,3963,4500 'ls':114 'm':3899,3984 'machin':29,62 'machine-read':28,61 'maintain':1582 'make':74 'mandat':3213,3225 'mandatori':304 'manual':712 'markdown':2173,3261 'match':1291 'materi':827,1007 'max':3948,3956,3995 'max-iter':3947,3994 'max-parallel':3955 'maxattempt':3541 'maxiter':3965 'may':2456,4112,4425 'md':117,368 'measur':2770 'merg':3749,3793,3835 'messag':1143 'metadata':42,3765 'method':890,1463,1652,1677,1684,1686 'migrat':2166,2239,2243,3140,3241 'minimum':3383 'minut':38,2791,3120,4411,4422 'mismatch':709 'miss':703,1535,1987 'model':458 'modif':2052 'modifi':1599,2249,2842,2917,2957,4143,4208,4532 'modul':2279,2471,2881,2963,3157,4539,4542 'multi':1206 'multi-consum':1205 'multipl':371,1080,3572,4365 'must':272,611,981,1702,1770,1941,2504,2517,2532,2539,2598,2800,2885,2950,3058,3280,3336 'n':126,399,1468,1471,1476,1479,1482,3896,3981 'name':422,629,632,634,639,642,657,662,666,668,677,679,685,722,851,886,893,895,979,1306,1443,1447,1453,1457,1558,3433,3443,3560,3660 'nan':3349 'natur':448,4511 'need':2032,3610,4390,4438,4467,4476,4482,4526 'negat':3351 'neither':3695 'never':2907,2916 'new':337,2182,2277,2470,2497,2530,2880,2962,3156,4372,4538 'newli':3022 'newth':2520,2521 'nnn':391,3026 'nobodi':4549 'non':405,2027 'non-break':2026 'non-goal':404 'none':1146,1320 'none/null':3346 'note':343,344,2086,3283,3290,3544,4158,4257 'noth':701 'npm':3518 'null':2733,3467,3531,3537 'number':3352,3666 'nycrc':2715 'object':779,2480 'obvious':996,4434,4444 'old':1850,1892,1928 'omitempti':1167 'one':378,3125,3128,3135,3142,3150,3448,3645 'one-lin':3447 'openai':751,754 'openai-api-key':753 'option':715,1129,1144,1577,2037,2057,2064,2071,2094 'order':1076,1248,3759 'organ':647 'origin':4315 'output':934,1117,1140,1159,1162,1454,1477,1509,2551,2586,4318 'over-classifi':2434 'overlap':4355 'overnight':3916 'overrid':1365 'overwrit':3833 'owner':917,952,1433,1498 'p2.3':226 'p2.4':92 'package.json':417,2167,2246,3242,3435 'pair':1181 'parallel':346,609,1630,2899,3693,3788,3954,3957,3960,4515 'param':894 'paramet':1603,1661,1665,1667,1670,2039,2055,2066,2073,2095 'paraphras':3634 'parseresult':1872,1904,1913 'part':4,528 'pass':1115,1138,1451,1474,2942,3050,3131,3414,3499,4056,4249 'password':766,769 'patch':1982 'path':204,208,433,637,675,957,967,1222,1235,1299,1367,3417,3456,3462,3651,4061,4065,4392,4406 'path/to/caller.ts':2516 'path/to/file.ts':3516 'path/to/test.ts':3520 'pattern':716,726,736,757,1423,1578,1590,3029,3400 'pend':1114,1137,1450,1473,2868,3503,3524,3528,3534,3593,3658 'percent':2730 'perform':2819 'ph':192,207 'phase':84,87,90,224 'phase-skip':86 'pipelin':12,2991,3060,3086 'plan':3,17,50,140,145,158,215,273,323,338,3070,3089,3094,3733,3790,3891,3976,4090 'planner':3279,4171 'point':1484 'pollut':3390 'post':3407 'post-implement':3406 'powershel':3969 'pp':189,205 'prd':26,58,96,107,113,127,129,151,172,177,190,193,230,358,365,385,3453,3459,3623,4064,4185 'prdpath':3455,4187 'prds':372 'preced':1359 'prefix':3551,3663,4155,4254 'prerequisit':218 'present':3859 'preserv':3630 'prevent':408,1627,1776,2655 'previous':1355,3803 'primari':1026,1508 'primarili':922 'print':4089,4319 'prior':100,221,234 'prior-stag':220,233 'prioriti':772,775,1072,1247,1493,3500,3561,3665,3720 'process':2198,2337 'produc':4401 'product':55 'progress':3545 'project':415,421,907,1020,1024,1035,1238,1269,1273,1277,1408,2712,2751,3431,3432,3799,3875 'project-root':1272 'prompt':4175 'properti':883,1442 'protocol':1057 'prove':2981 'provid':510,1520,1537 'ps1':3964 'pure':2172,2229,3245,3293 'py':1317,1336 'pyproject.toml':418,1051,2717 'python':1054,1121,1285,1334 'ql':2,3440,3553,3662,3861,3913,3990 'ql-execut':3912,3989 'ql-plan':1 'ql-wt':3860 'qualiti':2741 'quality-review':2740 'quantum':8,48,3864,3928,3962 'quantum-log':3863 'quantum-loop':7,47,3927,3961 'quantum-loop.sh':3870,3938,3971 'quantum.json':31,64,111,165,341,781,2698,3422,3426,3731,3764,3796,3804,3844,3894,3979,4004,4060,4139,4191,4232,4278,4338 'quantum.json.tmp':3866 'queri':2305 'radius':1724 'ration':971,2322,3301,4383 'raw.githubusercontent.com':3934,3942 'raw.githubusercontent.com/andyzengmath/quantum-loop/main/templates/quantum-loop.ps1':3941 'raw.githubusercontent.com/andyzengmath/quantum-loop/main/templates/quantum-loop.sh':3933 're':281,2663,4137,4168 're-impl':2662 're-introduc':280 're-invok':4167 're-read':4136 'react':3143 'read':94,157,219,228,255,260,356,382,414,488,796,2409,4138,4183 'readabl':30,63 'readm':3259 'readon':888,1461 'real':832 'realiti':4386 'reason':1000 'receiv':4098 'recent':364 'recommend':3910 'reconcil':3708 'reconcili':3742 'record':168,214 'redund':2579 'refactor':1900,2001 'refer':620,942,975,1170,1191,1516,2621 'references/contract-shapes.md':797,1174 'references/edge-cases.md':3395 'refin':2392,2395 'regex':727 'regress':1628,1743,1760,1960,1973,1998 'reject':239,331,3072 'remain':342,1591,4086 'remov':1666,4251,4272,4292 'renam':1683 'render':503,3148 'reorder':2457,2463 'repeat':619 'replac':2653 'repo':3930 'report':2735,4119,4305,4324 'repres':3625 'represent':877,1523 'requir':56,396,711,1623,1664,2797,3329,4028 'resolv':1742 'respons':2563 'restructur':2137,2449 'result':1420,2943,4099 'retri':3538 'retries.maxattempts':3602 'return':897,1601,1647,1865,1893,1903,1908,1929,2014,4079,4104,4131 'revert':4259,4313 'review':21,1720,2742,2748,2757,3525,4337 'reviewedat':3530,3536 'right':3116 'right-siz':3115 'risk':242,310,332,339,3777,4354 'root':1036,1274,1281,3800,3876 'rout':636,672,2302,3152 'rule':484,690,1814,2491,2608,2873,3548,4219 'run':102,1356,1783,1832,1845,1951,2992,3744,3849,3945,3987,4023,4426 'runner':3840,3889,3918,3923 'runtim':734,2161,2221,2376,2398,2417,3297,3740 'safe':2139,2432 'satisfi':2687 'save':3615,3617,3794,3843,3892,3977 'say':3068,3085,4554 'scaffold':4463 'scaffold/config-only':2164 'scalar':3355 'scale':3380,3393 'scan':589,840 'scenario':3368 'schedul':1764,1782 'schema':451,461,2155,2383,2390 'scope':409,4174 'script':3841,3890,3919,3924 'secret':627,652,749 'secret/config':655 'section':4342 'see':910,964,1173,1800,3394,3776,4335,4519 'separ':3272 'sequenti':2803,3668,3784,3952,4345 'servic':2310 'set':350,1344,1634,1637,1698,1727,1729,2090,2236,2425,2690,2731,3323,3838,4048 'setup.py':1053 'sever':4368 'sh':200,211 'sha256':206,210 'shape':792,874,983,994,1016,1179,1211,1441,1519,1566 'shape-on':1210 'share':606,654,663,682,770,803,817,838,870,1193,1284,1391,1417,1553,1674,1859,3700,4374 'shared-util':4373 'shift':3100 'short':2812 'show':3391,3403 'side':2227 'signal':2674 'signatur':1607,1682 'singl':1215 'single-consum':1214 'site':1984,2006 'size':3113,3117,4215 'skill':4222 'skill-ql-plan' 'skip':88,139,144,1002,2759,4084,4095,4493 'skippermiss':3967 'small':2406,3195 'someon':4545 'someth':2665,2997 'sourc':2183,2278,3373 'source-andyzengmath' 'sp':196,209 'spawn':4005,4029,4039 'spec':15,108,122,131,134,152,178,183,197,201,261 'spec.decided':264 'spec.rejected':275 'spec.remaining':283 'spec.risks':302 'speccompli':3526 'specif':791,1096,1254,1739,1969,2824,3361,3399 'specifi':2801,2951,4404,4440,4453 'split':576,3167,4417,4430 'src/interfaces':1262 'src/shared':1335 'src/shared/types':1250,1332 'src/types':1256,1413,1491 'src/types/task-result.ts':1432,2219 'stack':425 'stage':222,235 'start':3563 'stateless':4451 'statement':2254,3205 'status':1113,1135,1155,1158,1448,1472,2866,3502,3523,3527,3533,3591,3656 'stay':4568 'step':354,436,835,911,1017,1091,1168,1218,2771,2817,3419,3514,3611,3836,3998,4088 'stop':555 'stori':308,388,445,486,495,501,508,514,522,525,563,578,596,626,708,842,862,919,928,939,949,974,1501,1514,1550,1562,1598,1613,1642,1658,1692,1700,1736,1749,1757,1762,1766,1790,1830,1839,2108,2124,2147,2165,2175,2191,2326,2357,2379,2400,2458,2488,2558,2561,2592,2606,2610,2616,2633,2638,2658,2764,2774,2779,2806,2876,2910,2923,2995,3005,3012,3031,3037,3043,3053,3108,3476,3481,3573,3577,3587,3596,3608,3620,3641,3673,3681,3694,3724,3747,3755,3769,3897,3982,4110,4133,4151,4180,4211,4229,4275,4279,4285,4359,4366,4376,4525 'storytyp':1934,2022,2084,2120,2142,2426 'str':1134,1136,1141,1145 'string':904,1106,1112,1118,1120,1152,1156,1160,1164,1184,1446,1456,1460,1470,1478,1481,1541,1870,1911,2537,3348,4121 'struct':854,1070,1150 'structur':428,800,805,821,865,876,1003,1242,1522,2230,3429,4317 'stub':4109,4122,4132,4148,4154,4179,4196,4233,4241,4248,4253,4264,4274,4290,4294,4306,4370 'style':1041 'subag':4046 'succeed':81 'success':2769 'suffici':1580 'suggest':3228 'summar':3632 'surfac':289 'tabl':491,499 'tag':2110 'take':1358,2788 'task':39,435,600,847,1419,2150,2212,2240,2267,2269,2292,2295,2329,2467,2494,2549,2577,2584,2597,2631,2642,2776,2784,2786,2796,2799,2839,2889,2926,2949,3015,3112,3221,3258,3265,3273,3277,3305,3334,3505,3510,3598,3646,3648,3711,3715,3726,3743,3901,3986,4162,4198,4214,4268,4387,4400,4408,4457,4464,4479,4481,4530,4553 'taskresult':1110,1132,1149,1389,1422,1467,2210 'tasks.length':4242 'tasks/prd-':116,367 'tdd':3222 'tech':424 'technic':400 'test':516,2174,2179,2260,2265,2272,2283,2721,2855,2988,3052,3076,3123,3133,3177,3264,3268,3328,3342,3418,3519,4468 'testfirst':2851,3212,3214,3235,3288,3291,3324,3331,3521,4202,4216,4460 'tests/task-filter.test.ts':2275 'text':2940,4120 'thing':4332 'three':1187 'threshold':2707,2726,2746 'tiebreak':1090,3568 'timestamp':3471,3475,4083,4094 'titl':1899,1995,2062,2811,3454,3480,3482,3509,3511 'token':688 'tool':1526,2755,4037 'tool.coverage':2718 'top':784,2693 'top-level':2692 'topic-agent-skills' 'topic-agentskills' 'topic-claude-code' 'topic-claude-code-plugin' 'topic-claude-code-skill' 'topic-skillsmp' 'total':3900,3985 'touch':526,3688,4363 'transform':2259,3313 'trap':2355 'treat':263 'true':1636,1639,1769,1932,2860,3215,3325,3332,3522 'ts':1316,1333,2215 'tsconfig':3243 'tsconfig.json':1042 'two':524,3692,4057 'type':456,469,664,665,771,804,818,828,839,850,871,880,887,896,925,947,960,977,1049,1064,1068,1127,1148,1194,1208,1217,1271,1279,1305,1380,1390,1418,1445,1449,1455,1459,1505,1518,1554,1557,1602,1604,1648,1662,1671,1866,1894,1909,1930,2015,2109,2145,2152,2205,2231,2319,2347,2370,2444,3246,3249,3294,3353,3362,4047 'type/class':633 'typecheck':3498 'types-on':2144,2204,2346,2369,2443 'typescript':1043,1107,1251,1331,1407,1546 'typescript/general':1260 'typic':3386 'typo':3208 'u2192':14,16,18,20,22 'ui':471 'unaffect':2080 'unchang':154 'under-classifi':2439 'understand':1721 'unexpect':1990 'union':299 'unit':2264,3051 'unless':2481 'unrel':527 'unsur':2424 'unus':697 'up-to-d':147 'updat':2245 'updatedat':3472 'upstream':335 'us':390,1393,1399,1434,1437,1439,1732,1861,1873,1876,1897,1918,1921,1936,1939,1943,1965,1976,1993,2010,2017,2020,2033,2060,2082,2207,2234,2261,2289,2627,3025,3065,3082,3478,3580,3582,3770,3772 'us-b':2626 'us-nnn':389,3024 'us-xxx':1731 'use':43,990,1084,1294,1528,2128,2352,2567,3566,4034 'user':292,376,387,559,1351,2702,3437,3486,3775,3830,3847,3885,4026,4327,4334 'usual':574,926 'util':2407,2415,4375 'vagu':4399,4402 'valid':732,999,1592,2133,2386,2454,3069,3088,3101,3183,3613,4001,4009,4022,4033,4043,4053,4078,4081,4087,4092,4097,4103,4130,4141,4234,4239,4250,4266,4380 'valu':591,670,719,752,767,774,1421,1575,1588,2043,2099,2141,3345 'var':659 'variabl':631,661 'variat':3354 'verbatim':902,1539 'verbos':2038,2065,2072 'verif':2465,2479,2514,2572,2846,2978,3028,3653,4472 'verifi':23,544,3096,3164,3618,4486 'version':1803 'via':2489,3757 'view':479 'visibl':1687 'vs':1209,3356,3358,3365 'wait':4066 'want':3488 'wave':329,1787 'way':4484 'whether':77,98,3831 'whose':1759,4286 'window':3968 'wire':2464,2478,2482,2513,2571,2872,2891,2928,2948,2983,3001,3097,3103,3154,3684,4218,4508,4529 'within':2804 'without':1012,2051,2737,2897 'won':4513 'work':2050,2984,4488,4523 'worth':4416 'write':164,317,322,3121,4224 'written':2857,3728 'wt':3862 'x':1046,1050,1056,1061,1065,1069,3019,3937,4557 'xxx':1733 'y':4560 'yaml':2171 'z':739,760,1426,1430,4566 'z0':742,763 'za':1429 'zero':3350 'zod':2389","prices":[{"id":"116643bb-2496-4484-a450-02e6665f1e2d","listingId":"b538d362-599f-498a-828b-3e538ee1a380","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"andyzengmath","category":"quantum-loop","install_from":"skills.sh"},"createdAt":"2026-04-18T23:04:46.289Z"}],"sources":[{"listingId":"b538d362-599f-498a-828b-3e538ee1a380","source":"github","sourceId":"andyzengmath/quantum-loop/ql-plan","sourceUrl":"https://github.com/andyzengmath/quantum-loop/tree/master/skills/ql-plan","isPrimary":false,"firstSeenAt":"2026-04-18T23:04:46.289Z","lastSeenAt":"2026-04-24T13:02:29.158Z"}],"details":{"listingId":"b538d362-599f-498a-828b-3e538ee1a380","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"andyzengmath","slug":"ql-plan","github":{"repo":"andyzengmath/quantum-loop","stars":22,"topics":["agent-skills","agentskills","claude-code","claude-code-plugin","claude-code-skill","skillsmp"],"license":"mit","html_url":"https://github.com/andyzengmath/quantum-loop","pushed_at":"2026-04-24T12:53:22Z","description":"Spec-driven autonomous development loop for Claude Code. Combines structured PRD generation, dependency DAG execution, two-stage review gates, and Iron Law verification.","skill_md_sha":"2a789ee5574ce3d44865e96e716258ce05069fd8","skill_md_path":"skills/ql-plan/SKILL.md","default_branch":"master","skill_tree_url":"https://github.com/andyzengmath/quantum-loop/tree/master/skills/ql-plan"},"layout":"multi","source":"github","category":"quantum-loop","frontmatter":{"name":"ql-plan","description":"Part of the quantum-loop autonomous development pipeline (brainstorm \\u2192 spec \\u2192 plan \\u2192 execute \\u2192 review \\u2192 verify). Convert a PRD into machine-readable quantum.json with dependency DAG, granular 2-5 minute tasks, and execution metadata. Use after creating a spec with /quantum-loop:spec. Triggers on: create plan, convert to json, plan tasks, generate quantum json, ql-plan."},"skills_sh_url":"https://skills.sh/andyzengmath/quantum-loop/ql-plan"},"updatedAt":"2026-04-24T13:02:29.158Z"}}