From bdfeb50b81f04cb219a205a36c129814b4c0ed86 Mon Sep 17 00:00:00 2001 From: Patrick Dahlke Date: Tue, 7 Apr 2026 19:51:04 +0200 Subject: [PATCH 1/7] chore: add .worktrees/ to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2f9d482..f892327 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.pyc __pycache__/ .DS_Store +.worktrees/ From ecaba9900a8473014d48075c5c6025378bcd3d78 Mon Sep 17 00:00:00 2001 From: Patrick Dahlke Date: Tue, 7 Apr 2026 19:59:16 +0200 Subject: [PATCH 2/7] feat: add decision need type to test fixture Add decision type with decided_by, alternatives, rationale fields and decides link type. Include example decisions in decisions.rst. --- .../fixtures/basic-project/docs/decisions.rst | 24 +++++++++++++++++++ tests/fixtures/basic-project/ubproject.toml | 14 +++++++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/fixtures/basic-project/docs/decisions.rst diff --git a/tests/fixtures/basic-project/docs/decisions.rst b/tests/fixtures/basic-project/docs/decisions.rst new file mode 100644 index 0000000..2836521 --- /dev/null +++ b/tests/fixtures/basic-project/docs/decisions.rst @@ -0,0 +1,24 @@ +Decisions +========= + +.. decision:: Use CAN bus for brake pedal sensor + :id: DEC_001 + :status: accepted + :decides: REQ_001, SPEC_001 + :decided_by: engineer-a + :alternatives: SPI at 1MHz; Direct analog input + :rationale: CAN bus provides noise immunity required for safety-critical braking and reuses existing vehicle bus + + Selected CAN bus over SPI and direct analog based on EMC requirements + and existing bus infrastructure in the brake ECU. + +.. decision:: Use proportional algorithm for force distribution + :id: DEC_002 + :status: accepted + :decides: REQ_002, SPEC_002 + :decided_by: claude + :alternatives: Fixed ratio front/rear; Adaptive ML-based distribution + :rationale: Proportional distribution is deterministic and certifiable under ISO 26262 ASIL-D + + Proportional axle-load-based distribution chosen over fixed ratio (insufficient for varying loads) + and ML-based (not certifiable at ASIL-D). diff --git a/tests/fixtures/basic-project/ubproject.toml b/tests/fixtures/basic-project/ubproject.toml index 4614024..7b5a5db 100644 --- a/tests/fixtures/basic-project/ubproject.toml +++ b/tests/fixtures/basic-project/ubproject.toml @@ -9,8 +9,22 @@ types = [ {directive = "spec", title = "Specification", prefix = "SPEC_", color = "#FEDCD2", style = "node"}, {directive = "impl", title = "Implementation", prefix = "IMPL_", color = "#DF744A", style = "node"}, {directive = "test", title = "Test Case", prefix = "TEST_", color = "#DCB239", style = "node"}, + {directive = "decision", title = "Decision", prefix = "DEC_", color = "#9B59B6", style = "artifact"}, ] [needs.extra_links] implements = {incoming = "is implemented by", outgoing = "implements"} tests = {incoming = "is tested by", outgoing = "tests"} +decides = {incoming = "is decided by", outgoing = "decides for"} + +[needs.fields.decided_by] +description = "Who made the decision (human name or 'claude')" +schema.type = "string" + +[needs.fields.alternatives] +description = "Rejected alternatives, semicolon-separated" +schema.type = "string" + +[needs.fields.rationale] +description = "Why this option was chosen over alternatives" +schema.type = "string" From ec83555685afe90f8fcb715210956b0b8a361e75 Mon Sep 17 00:00:00 2001 From: Patrick Dahlke Date: Tue, 7 Apr 2026 20:02:35 +0200 Subject: [PATCH 3/7] feat: add pharaoh:decide skill for recording design decisions --- skills/pharaoh-decide/SKILL.md | 350 +++++++++++++++++++++++++++++++++ 1 file changed, 350 insertions(+) create mode 100644 skills/pharaoh-decide/SKILL.md diff --git a/skills/pharaoh-decide/SKILL.md b/skills/pharaoh-decide/SKILL.md new file mode 100644 index 0000000..4c0a16f --- /dev/null +++ b/skills/pharaoh-decide/SKILL.md @@ -0,0 +1,350 @@ +--- +name: pharaoh-decide +description: "Use when recording a design decision as a traceable sphinx-needs object with alternatives, rationale, and links to affected requirements" +--- + +# pharaoh-decide + +Record design decisions as traceable sphinx-needs `decision` directives. Each decision captures the chosen option, rejected alternatives, rationale, and explicit links to the requirements or specifications it affects. This skill ensures every decision has proper `decided_by`, `alternatives`, and `rationale` fields, and delegates RST generation to `pharaoh:author` to avoid duplicating directive-writing logic. + +--- + +## When to Use + +- When a design choice has been made and must be recorded for traceability. +- When comparing alternatives for a requirement or specification and committing to one. +- When `pharaoh:spec` identifies a gap and calls this skill programmatically to record the resolution. +- When superseding an earlier decision with a new one. + +## Prerequisites + +- The workspace must contain at least one sphinx-needs project with a `decision` type configured. +- No workflow gates. This skill runs freely in both advisory and enforcing modes. + +--- + +## Process + +Execute the following steps in order. + +--- + +### Step 1: Get Project Data + +Follow the full detection and data access algorithm defined in `skills/shared/data-access.md`. + +1. Detect project structure (project roots, source directories, configuration). +2. Read project configuration (need types, link types, ID settings). +3. Build the needs index using the best available data tier (ubc CLI, ubCode MCP, or raw file parsing). +4. Read `pharaoh.toml` for strictness level and workflow settings. + +Present the detection summary before proceeding: + +``` +Project: () +Types: +Links: +Data source: +Needs found: +Strictness: +``` + +#### Verify `decision` type exists + +After reading the project configuration, confirm that a type with directive name `decision` is present in the types list. + +If `decision` is not configured, show the user the exact TOML to add: + +```toml +[[needs.types]] +directive = "decision" +title = "Decision" +prefix = "DEC_" +color = "#E8D0A9" +style = "node" +``` + +Also verify that these extra options are configured: + +```toml +[needs.fields.decided_by] +description = "Who made the decision" + +[needs.fields.alternatives] +description = "Rejected alternatives, semicolon-separated" + +[needs.fields.rationale] +description = "Why this option was chosen" +``` + +And verify the `decides` link type exists: + +```toml +[needs.extra_links.decides] +incoming = "is decided by" +outgoing = "decides for" +``` + +Ask the user to confirm before proceeding if any of these are missing. + +--- + +### Step 2: Gather Decision Context + +Determine what to record. The following pieces of information are required: + +- **Title**: What is being decided (e.g., "Use CAN bus for brake pedal sensor"). +- **Affected needs**: Need IDs for the `:decides:` link (e.g., `REQ_001, SPEC_001`). +- **decided_by**: Who made this decision. Default to `claude` when the AI is generating the decision autonomously. Ask the user otherwise. +- **alternatives**: Rejected alternatives, semicolon-separated (e.g., `SPI at 1MHz; Direct analog input`). +- **rationale**: Why this option was chosen over the alternatives. +- **status**: One of `proposed`, `accepted`, `superseded`, `rejected`. + +#### When called standalone + +Prompt the user for each missing piece. Do not proceed until all five fields (title, affected needs, decided_by, alternatives, rationale) are populated. If the user omits any field, ask for it explicitly. + +#### When called by `pharaoh:spec` + +Accept all context programmatically. Do not prompt. All required fields must be provided by the calling skill. + +#### Status defaults + +- **Standalone invocation**: Default status to `proposed`. +- **Called by `pharaoh:spec`**: Default status to `accepted`. + +The user may override the default in either case. + +--- + +### Step 3: Generate ID + +Reuse `pharaoh:author` ID generation logic (Step 3 of pharaoh-author). + +1. Check `pharaoh.toml` for `[pharaoh.id_scheme]`. If a pattern exists, apply it with `{TYPE}` resolving to `DEC`. +2. If no id_scheme is configured, infer the pattern from existing `decision` needs in the index. Look for `DEC_*` IDs and determine the numbering scheme. +3. If no existing decisions exist, use the prefix from the type configuration (e.g., `DEC_`) and start at `001`, padded to match `id_length`. +4. Validate uniqueness against the full needs index. If the generated ID already exists, increment until a unique ID is found. + +--- + +### Step 4: Write the Need + +Delegate to `pharaoh:author` with all fields populated. Provide the following directive structure to author: + +```rst +.. decision:: + :id: <generated_id> + :status: <proposed|accepted> + :decides: <need_id1>, <need_id2> + :decided_by: <name or claude> + :alternatives: <alt1>; <alt2> + :rationale: <why this option> + + <expanded description> +``` + +The expanded description should summarize the decision in one to three sentences, covering what was chosen and why the alternatives were rejected. + +#### Superseding an existing decision + +When a new decision replaces an old one: + +1. Set the old decision's status to `superseded` using `pharaoh:author` modification logic. +2. On the new decision, add `:links: <old_dec_id>` to establish the supersession chain. +3. The new decision's description should reference the old decision ID and explain why it is being replaced. + +--- + +### Step 5: File Placement + +Place the decision in `decisions.rst` in the same directory as the affected requirements. + +1. Identify the directory of the first need listed in `:decides:`. Use the needs index to find its file path. +2. Check if `decisions.rst` exists in that directory. If it does, append the new decision after the last existing `decision` directive in the file. +3. If `decisions.rst` does not exist, create it with a proper RST title: + +```rst +Decisions +========= + +.. decision:: <title> + :id: <id> + ... +``` + +4. If no `:decides:` links are specified (rare case), fall back to `pharaoh:author` file placement logic (Step 6 of pharaoh-author). + +Delegate the actual file writing to `pharaoh:author`. + +--- + +### Step 6: Update Session State + +After successfully writing the decision: + +1. Read `.pharaoh/session.json` (or initialize if it does not exist). +2. Create the `.pharaoh/` directory if it does not exist. +3. For the decision need ID, set `changes.<dec_id>.authored = true`: + +```json +{ + "<dec_id>": { + "change_analysis": null, + "acknowledged": false, + "authored": true, + "verified": false + } +} +``` + +4. Set `updated` to the current ISO 8601 timestamp. +5. Write the updated JSON back to `.pharaoh/session.json`. + +--- + +### Step 7: Follow-up + +#### Standalone invocation + +After writing the decision, suggest the next step: + +``` +Next step: Run pharaoh:verify to validate the decision against its linked requirements. +``` + +#### Called by `pharaoh:spec` + +Return the decision ID silently. Do not print follow-up suggestions. The calling skill manages the workflow. + +--- + +## Strictness Behavior + +Follow the instructions in `skills/shared/strictness.md`. + +### Advisory mode + +Execute freely. No gates. Decisions have no prerequisites and do not gate other skills. Do not show tips -- decisions can be recorded at any time without prior analysis. + +### Enforcing mode + +Execute freely. No gates. Decisions can be recorded at any time regardless of strictness level. This skill is gate-free in both modes. + +Strictness has no effect on decision recording. Both modes follow the same process. + +--- + +## Key Constraints + +1. **All three fields are mandatory.** Always populate `decided_by`, `alternatives`, and `rationale`. If the user omits any of them, ask explicitly. Do not write a decision with missing fields. +2. **Default `decided_by` to `claude`** when the AI is making the decision autonomously (e.g., during `pharaoh:spec` execution). +3. **Default `status` to `proposed`** when standalone, `accepted` when called by `pharaoh:spec`. +4. **Superseding requires two writes.** When replacing an old decision, update the old decision's status to `superseded` AND add `:links:` on the new decision referencing the old one. +5. **Reuse `pharaoh:author` for RST writing.** Do not duplicate directive generation, file placement, or ID generation logic. Delegate to author for all file operations. +6. **Validate `:decides:` targets exist.** Every need ID in the `:decides:` field must exist in the needs index. If a target does not exist, warn the user and ask whether to proceed. +7. **Semicolons for alternatives.** Separate rejected alternatives with semicolons, not commas. Commas are reserved for need ID lists. + +--- + +## Examples + +### Example 1: Standalone decision recording + +**User request**: "Record a decision that we chose PostgreSQL over MongoDB for the data store" + +**Step 1** -- Data access detects: + +``` +Project: Backend Service (ubproject.toml) +Types: req, spec, impl, test, decision +Links: links, implements, tests, decides +Data source: Tier 3 (raw file parsing) +Needs found: 12 +Strictness: advisory +``` + +**Step 2** -- Gather context. The user provided the title and one alternative. Prompt for missing fields: + +``` +Recording decision: "Use PostgreSQL for the data store" + +Which requirements or specs does this decision affect? +> REQ_003, SPEC_005 + +Who is making this decision? +> engineering-lead + +Any other rejected alternatives besides MongoDB? +> Redis as primary store + +Why was PostgreSQL chosen over the alternatives? +> PostgreSQL provides ACID transactions and mature JSON support, + which MongoDB and Redis cannot guarantee for our consistency requirements. +``` + +**Step 3** -- Generate ID. Existing decisions: DEC_001, DEC_002. Next ID: `DEC_003`. + +**Step 4** -- Delegate to `pharaoh:author`. Directive written: + +```rst +.. decision:: Use PostgreSQL for the data store + :id: DEC_003 + :status: proposed + :decides: REQ_003, SPEC_005 + :decided_by: engineering-lead + :alternatives: MongoDB; Redis as primary store + :rationale: PostgreSQL provides ACID transactions and mature JSON support required for data consistency + + Selected PostgreSQL over MongoDB and Redis. MongoDB lacks full ACID transaction + support across collections. Redis does not provide durable storage guarantees + suitable for a primary data store. PostgreSQL meets the consistency requirements + defined in REQ_003. +``` + +**Step 5** -- Written to `docs/decisions.rst` (same directory as REQ_003). + +**Step 6** -- Session state updated: `DEC_003.authored = true`. + +**Step 7** -- Follow-up: + +``` +Next step: Run pharaoh:verify to validate the decision against its linked requirements. +``` + +--- + +### Example 2: Decision during spec generation (programmatic call) + +`pharaoh:spec` identifies that no specification covers the communication protocol for subsystem X. It calls `pharaoh:decide` with all context provided: + +- **Title**: "Use CAN bus for brake pedal sensor communication" +- **decides**: `REQ_001, SPEC_001` +- **decided_by**: `claude` +- **alternatives**: `SPI at 1MHz; Direct analog input` +- **rationale**: "CAN bus provides noise immunity required for safety-critical braking" +- **status**: `accepted` + +`pharaoh:decide` executes without prompting: + +1. Verifies `decision` type exists in configuration. +2. Generates ID: `DEC_004`. +3. Delegates to `pharaoh:author`: + +```rst +.. decision:: Use CAN bus for brake pedal sensor communication + :id: DEC_004 + :status: accepted + :decides: REQ_001, SPEC_001 + :decided_by: claude + :alternatives: SPI at 1MHz; Direct analog input + :rationale: CAN bus provides noise immunity required for safety-critical braking + + Selected CAN bus over SPI and direct analog based on EMC requirements. + SPI at 1MHz lacks sufficient noise immunity for the safety-critical braking + subsystem. Direct analog input introduces unacceptable signal degradation + over the required cable lengths. +``` + +4. Updates session state: `DEC_004.authored = true`. +5. Returns `DEC_004` to `pharaoh:spec`. No follow-up message printed. From bba6d31898e5a5f9fe2cf97990f9f88a2c512369 Mon Sep 17 00:00:00 2001 From: Patrick Dahlke <patrick.dahlke@pichu.io> Date: Tue, 7 Apr 2026 20:15:16 +0200 Subject: [PATCH 4/7] feat: add pharaoh:spec skill for generating specs from sphinx-needs --- skills/pharaoh-spec/SKILL.md | 522 +++++++++++++++++++++++++++++++++++ 1 file changed, 522 insertions(+) create mode 100644 skills/pharaoh-spec/SKILL.md diff --git a/skills/pharaoh-spec/SKILL.md b/skills/pharaoh-spec/SKILL.md new file mode 100644 index 0000000..d2138dd --- /dev/null +++ b/skills/pharaoh-spec/SKILL.md @@ -0,0 +1,522 @@ +--- +name: pharaoh-spec +description: "Use when generating a Superpowers-compatible spec and plan document from sphinx-needs requirements, bridging requirements to implementation" +--- + +# pharaoh-spec + +Generate a self-contained specification and plan document from one or more sphinx-needs +requirements. The spec bridges the gap between requirements (the "what") and +implementation (the "how") by pulling full requirement text, mapping existing downstream +coverage, identifying gaps, recording design decisions via `pharaoh:decide`, and +producing a plan table that feeds directly into `pharaoh:plan`. + +The output is a markdown document in `docs/superpowers/specs/` containing requirements, +coverage analysis, gap list, decisions, and an actionable plan table. + +## When to Use + +- You have one or more requirement IDs and need a structured spec before implementation begins. +- You want to understand what downstream coverage already exists for a set of requirements (specs, impls, tests) and what gaps remain. +- You need to record design decisions for uncovered areas before authoring new needs. +- You want a single document that a team can review before executing changes via `pharaoh:plan`. +- A new feature has been captured as requirements and you need to decompose it into specifications, implementations, and test cases with full traceability. + +## Prerequisites + +- The workspace must contain at least one sphinx-needs project. +- No workflow gates. This skill runs freely in both advisory and enforcing modes. +- If decisions need to be recorded, the project must have a `decision` type configured (see `pharaoh:decide` Step 1). + +--- + +## Process + +Execute the following steps in order. + +--- + +### Step 1: Get Project Data + +Follow the full detection and data access algorithm defined in `skills/shared/data-access.md`. + +1. Detect project structure (project roots, source directories, configuration). +2. Read project configuration (need types, link types, ID settings). +3. Build the needs index using the best available data tier (ubc CLI, ubCode MCP, or raw file parsing). +4. Build the link graph with all relationships in both directions (outgoing and incoming for every link type including extra_links). +5. Read `pharaoh.toml` for strictness level, workflow gates, traceability requirements, and `required_links` chains. + +Present the detection summary before proceeding: + +``` +Project: <name> (<config source>) +Types: <list of directive names> +Links: <list of link type names> +Data source: <tier used> +Needs found: <count> +Strictness: <advisory|enforcing> +``` + +If detection fails (no project found, no needs in source files), report the issue and ask the user for guidance. Do not proceed with empty data. + +--- + +### Step 2: Parse Input + +Accept one or more requirement IDs from the user's request. + +#### When the user provides IDs directly + +Validate each ID against the needs index. If an ID does not exist: + +1. Report that the ID was not found. +2. Suggest possible matches (typo correction, similar IDs). +3. Ask the user to confirm or provide the correct ID. + +#### When the user provides natural language + +Resolve to IDs using the needs index. Match by: + +1. Exact title match (case-insensitive). +2. Substring match in title. +3. Substring match in content. +4. Tag match. + +If multiple needs match, present candidates and ask the user to choose: + +``` +Multiple matches found: +1. REQ_001 (Requirement: Brake response time) [open] +2. REQ_007 (Requirement: Brake pedal response) [approved] +Which requirement(s) should be included in the spec? Enter numbers or IDs. +``` + +If exactly one matches, proceed with it and inform the user of the resolved ID. + +#### Multiple requirements + +When called with multiple requirement IDs, produce a single combined spec document covering all of them. Do not produce separate documents per requirement. + +--- + +### Step 3: Resolve Requirements Scope + +For each input requirement, build a complete scope tree. + +#### 3a: Pull full requirement text + +For each input requirement, retrieve all available fields: + +- ID, title, type, status +- Full content text +- Tags +- All link fields (links, implements, tests, and any extra_links) +- Any custom fields defined in the project configuration + +This is the **full text** -- requirements are the source of truth and must appear verbatim in the spec document. + +#### 3b: Trace downstream coverage + +Starting from each input requirement, follow the link graph recursively to find all downstream needs. Follow all link types (links, implements, tests, and all extra_links) in both directions. Continue until the full downstream tree is mapped. + +For each downstream need, collect **references only** (ID, type, title, status, link type to parent). Do NOT pull full content for downstream needs -- they are resolvable via `ubc` or source files if needed later. + +#### 3c: Build the scope tree + +Assemble a tree showing the requirement at the root with all downstream coverage: + +``` +REQ_042 (full text) ++-- SPEC_010 (ref) -- exists, status: open ++-- SPEC_011 (ref) -- exists, status: approved +| +-- IMPL_005 (ref) -- exists, status: open ++-- [gap] -- no spec covers subsystem X + +-- [gap] -- no impl for subsystem X + +-- [gap] -- no test for subsystem X +``` + +#### 3d: Identify gaps + +Determine what downstream coverage is missing using `pharaoh.toml` `required_links` chains. If `required_links` is configured, follow the chain (e.g., `req -> spec -> impl -> test`). If not configured, infer expected chains from configured types and link types. + +Gaps include: requirements with no spec, specs with no impl, impls with no test, and requirements whose content suggests multiple subsystems with only partial spec coverage. + +For each gap, record the parent need ID, what is missing, and whether it represents a decision point (ambiguity in decomposition or approach). + +--- + +### Step 4: Present Scope Summary + +Before generating the spec document, present a summary for the user to review: + +``` +Scope for REQ_042: + Requirements: 1 (full text included) + Specifications: 2 (references only) + Implementations: 1 (reference only) + Test cases: 0 + Gaps: 2 (no spec for subsystem X, no test for IMPL_005) + Decisions needed: 2 +``` + +For multiple requirements, show a combined summary with the same format. + +If the scope is unexpectedly large (more than 30 downstream needs), warn the user and suggest splitting into separate specs per requirement. + +Wait for user confirmation before proceeding to Step 5. + +--- + +### Step 5: Make Design Decisions + +For each gap or ambiguity identified in Step 3d, determine whether a design decision is needed. + +#### When decisions are needed + +Decisions are needed when: + +- **Missing spec coverage**: How should the requirement be decomposed into specifications? What design approach should be taken? +- **Multiple implementation approaches**: Which technology, algorithm, or architecture should be used? +- **Missing test coverage**: What verification method is appropriate (unit test, integration test, manual review)? +- **Conflicting constraints**: Two requirements impose contradictory constraints on a shared specification. + +#### Recording decisions + +For each decision, invoke `pharaoh:decide` programmatically with all context: + +- **Title**: A clear statement of the decision (e.g., "Decompose REQ_042 into timing and protocol specifications"). +- **decides**: The need IDs affected by this decision. +- **decided_by**: `claude` (since the AI is generating the spec). +- **alternatives**: At least two alternatives considered, semicolon-separated. +- **rationale**: Why this option was chosen. +- **status**: `accepted` (decisions made during spec generation are accepted by default). + +`pharaoh:decide` will generate the decision ID, write the RST directive, and return the ID. Collect all decision IDs for use in Step 6. + +**Important**: Write all decisions BEFORE generating the spec document. The spec must reference stable decision IDs, not placeholders. + +#### When no decisions are needed + +If all gaps are straightforward (e.g., a missing test case for an existing implementation where the test strategy is obvious), skip decision recording. Note in the spec that no design decisions were required. + +--- + +### Step 6: Generate the Spec Document + +Write the spec document to `docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md`. + +- `YYYY-MM-DD` is the current date. +- `<topic>` is a short kebab-case slug derived from the requirement title(s) (e.g., `brake-response-time`). +- The user may override the file path. If they specify a different location, use it. + +Create the `docs/superpowers/specs/` directory if it does not exist. + +#### Document structure + +The spec document MUST contain these sections in this order: + +```markdown +# Spec: <Requirement title(s)> + +Generated from sphinx-needs on YYYY-MM-DD. +Source requirements: REQ_042, REQ_043 + +## Requirements (source of truth) + +### REQ_042: <title> +**Status:** <status> | **Tags:** <tag1>; <tag2> + +<Full requirement content text pulled verbatim from sphinx-needs.> + +### REQ_043: <title> +**Status:** <status> | **Tags:** <tag1>; <tag2> + +<Full requirement content text pulled verbatim from sphinx-needs.> + +## Existing coverage + +| Need | Type | Title | Status | Links | +|------|------|-------|--------|-------| +| SPEC_010 | spec | Signal timing | open | REQ_042 | +| SPEC_011 | spec | Protocol design | approved | REQ_042 | +| IMPL_005 | impl | CAN driver | open | SPEC_011 | + +## Gaps + +- [ ] No specification covers subsystem X of REQ_042 +- [ ] No test case for IMPL_005 +- [ ] No implementation for SPEC_010 + +## Decisions + +- DEC_001: Decompose REQ_042 into timing and protocol specifications +- DEC_002: Use CAN bus for sensor communication + +> If no decisions were needed, write: "No design decisions required. All gaps are +> covered by straightforward additions." + +## Implementation scope + +### Needs to create +| Type | Purpose | Links to | File | +|------|---------|----------|------| +| spec | Subsystem X timing | REQ_042 | specifications.rst | +| test | CAN driver verification | IMPL_005 | test_cases.rst | + +### Needs to modify +| Need | Change | Reason | +|------|--------|--------| +| SPEC_010 | Update timing constraints | REQ_042 timing budget changed | + +> If no needs to create or modify, write "None" for the respective subsection. + +## Plan table + +| # | Task | Skill | Target | Detail | Required | +|---|------|-------|--------|--------|----------| +| 1 | Analyze impact | pharaoh:change | REQ_042 | Trace downstream effects | yes | +| 2 | Author spec | pharaoh:author | (new) | Subsystem X timing | yes | +| 3 | Author test | pharaoh:author | (new) | CAN driver verification | yes | +| 4 | Update spec | pharaoh:author | SPEC_010 | Timing constraints | yes | +| 5 | Verify | pharaoh:verify | (all) | Check traceability | yes | +``` + +#### Section rules + +1. **Requirements**: Full verbatim text. The spec must be self-contained for requirement content. +2. **Existing coverage**: Reference table only, sorted by type (specs, impls, tests). +3. **Gaps**: Checkbox list (unchecked). One item per gap from Step 3d. +4. **Decisions**: List each by ID and title, referencing the decision need written in Step 5. +5. **Implementation scope**: "Needs to create" (with suggested target files) and "Needs to modify" (with change description and reason). Write "None" if a subsection is empty. +6. **Plan table**: Built in Step 7. Same columns and format as `pharaoh:plan` Step 5. + +--- + +### Step 7: Build the Plan Table + +Construct the plan table following `pharaoh:plan` task sequencing rules. + +#### Task ordering + +1. **Change analysis first** (if modifying existing needs): One `pharaoh:change` task per modified need, or a single task covering all modifications. +2. **Author needs top-down**: Requirements before specifications, specifications before implementations, implementations before test cases. New needs before modifications at each level. +3. **Verify after all authoring**: One `pharaoh:verify` task covering all created and modified needs. +4. **MECE check if configured**: Include a `pharaoh:mece` task if `require_mece_on_release = true` in `pharaoh.toml`, or if the scope involves creating needs at multiple hierarchy levels. + +#### Task format + +Each task row must specify: + +- **#**: Sequential number starting from 1. +- **Task**: Concise description of what the task does. +- **Skill**: The exact Pharaoh skill to invoke (e.g., `pharaoh:change`, `pharaoh:author`, `pharaoh:verify`, `pharaoh:mece`). +- **Target**: The need ID being acted on, or `(new)` for needs to create, or `(all)` for verification tasks. +- **Detail**: A specific description of the change or action. Not vague -- name the exact property or content being changed. +- **Required**: `yes`, `no`, or `recommended` based on strictness mode. + +#### Required field rules + +- **Enforcing mode**: Tasks mandated by workflow gates are marked `yes`. Optional tasks (like MECE check when not required) are marked `recommended`. +- **Advisory mode**: All tasks are marked `recommended`. No task is strictly required. + +#### Plan table constraints + +- The plan table MUST use the exact same format and column names as `pharaoh:plan` Step 5. This ensures the plan can be handed off to `pharaoh:plan` for execution without reformatting. +- One skill invocation per task. Do not combine multiple skill calls into a single row. +- Every task must have a concrete target. Vague tasks like "update related specs" are not acceptable. + +--- + +### Step 8: Handoff + +After generating the spec document, present the file path and offer next steps: + +``` +Spec document written to: docs/superpowers/specs/2026-04-07-brake-response-time-design.md + +Options: + 1. Execute the plan via pharaoh:plan + 2. Review or modify the spec first + 3. Execute later (plan is saved in the spec document) +``` + +- **Option 1**: Invoke `pharaoh:plan` with the plan table from the spec document. +- **Option 2**: Allow edits to any section, regenerate affected parts, then re-offer options. +- **Option 3**: Confirm the spec is saved. No further action. + +**Never auto-execute.** Always present the spec and wait for explicit user approval. + +--- + +## Strictness Behavior + +Follow the instructions in `skills/shared/strictness.md`. + +### Advisory mode + +- Execute freely. No gates. This skill has no prerequisites. +- All plan table tasks are marked `recommended` instead of `yes`. +- Decisions are still recorded (they provide traceability regardless of strictness). +- After generating the spec, show a tip if the user skips review: + ``` + Tip: Consider reviewing the spec before executing the plan. + The spec captures design decisions that affect downstream authoring. + ``` + +### Enforcing mode + +- Execute freely. No gates. This skill has no prerequisites. +- Plan table tasks mandated by workflow gates are marked `yes`: + - `pharaoh:change` tasks are required if `require_change_analysis = true`. + - `pharaoh:verify` tasks are required if `require_verification = true`. + - `pharaoh:mece` tasks are required if `require_mece_on_release = true`. +- Decisions are recorded with status `accepted` (same as advisory mode). +- The spec document clearly marks which plan tasks are mandatory. + +### Strictness has no effect on analysis depth + +Both advisory and enforcing modes perform the same scope resolution, gap analysis, and decision recording. Strictness only affects the `Required` column in the plan table and whether downstream skills gate on prerequisites. + +--- + +## Key Constraints + +1. **Requirements get full text, downstream needs get references only.** The spec is self-contained for requirements but does not duplicate downstream content. Downstream details are resolvable via `ubc` or by reading source files. + +2. **Decisions are written as sphinx-needs objects before the spec references them.** Never reference a decision ID that has not been written. Always invoke `pharaoh:decide` first, collect the ID, then use it in the spec. + +3. **Plan table format must match `pharaoh:plan` exactly.** Same column names, same task granularity, same required-field semantics. The plan table in the spec must be directly executable by `pharaoh:plan`. + +4. **Spec doc location defaults to `docs/superpowers/specs/` but is overridable.** If the user specifies a different path, use it without question. + +5. **Never auto-execute.** Always present the complete spec document and wait for explicit user approval before invoking any downstream skill. This applies even if the plan has only one task. + +6. **When called with multiple requirement IDs, produce a single combined spec.** Do not generate separate documents per requirement. The scope tree, gap analysis, and plan table cover all input requirements together. + +7. **Keep the spec document focused.** Do not include implementation details, code snippets, or design elaborations beyond what the decisions capture. The spec is a bridge document -- it connects requirements to a plan, not a detailed design document. + +8. **No session state changes from spec generation alone.** Generating and writing the spec document does not modify `.pharaoh/session.json`. Only decision recording (via `pharaoh:decide`) and plan execution (via `pharaoh:plan`) update session state. + +--- + +## Examples + +### Example 1: Single requirement with gaps + +**User request**: `pharaoh:spec REQ_001` + +**Step 1** -- Data access detects: + +``` +Project: Brake System (ubproject.toml) +Types: req, spec, impl, test, decision +Links: links, implements, tests, decides +Data source: Tier 3 (raw file parsing) +Needs found: 12 +Strictness: advisory +``` + +**Step 2** -- Input: `REQ_001`. Validated against needs index. Found: `REQ_001` (Brake response time). + +**Step 3** -- Scope resolution: + +Full text retrieved for REQ_001: +- Title: "Brake response time" +- Status: approved +- Tags: safety; braking +- Content: "The brake system shall respond within 100ms of pedal input under all operating conditions." + +Downstream trace: +``` +REQ_001 (full text) ++-- SPEC_001 (ref) -- Signal timing, status: open +| +-- IMPL_001 (ref) -- CAN driver, status: open ++-- [gap] -- no spec for subsystem X (pedal sensor interface) + +-- [gap] -- no impl + +-- [gap] -- no test ++-- [gap] -- no test for IMPL_001 +``` + +Gaps identified: +1. No specification covers the pedal sensor interface subsystem. +2. No test case for IMPL_001 (CAN driver). + +**Step 4** -- Scope summary presented: + +``` +Scope for REQ_001: + Requirements: 1 (full text included) + Specifications: 1 (reference only) + Implementations: 1 (reference only) + Test cases: 0 + Gaps: 2 (no spec for pedal sensor interface, no test for IMPL_001) + Decisions needed: 2 +``` + +User confirms: proceed. + +**Step 5** -- Decisions recorded via `pharaoh:decide`: + +1. `DEC_003`: "Decompose pedal sensor interface into separate specification" + - decides: REQ_001 + - alternatives: Include in SPEC_001; Create standalone spec + - rationale: Pedal sensor interface is safety-critical and warrants independent review + - Result: DEC_003 written to decisions.rst + +2. `DEC_004`: "Use hardware-in-the-loop testing for CAN driver verification" + - decides: IMPL_001 + - alternatives: Unit test with mock CAN; HIL testing; Manual bench test + - rationale: Safety-critical braking path requires realistic signal conditions + - Result: DEC_004 written to decisions.rst + +**Step 6** -- Spec document generated at `docs/superpowers/specs/2026-04-07-brake-response-time-design.md` with: +- Full text of REQ_001 in Requirements section +- Coverage table: SPEC_001 (open), IMPL_001 (open) +- Gaps: no spec for pedal sensor interface, no test for IMPL_001 +- Decisions: DEC_003, DEC_004 +- Implementation scope: create 1 spec (pedal sensor timing) and 1 test (CAN driver HIL) +- Plan table (advisory mode, all `recommended`): + +| # | Task | Skill | Target | Detail | Required | +|---|------|-------|--------|--------|----------| +| 1 | Analyze impact | pharaoh:change | REQ_001 | Trace downstream effects of new spec | recommended | +| 2 | Author spec | pharaoh:author | (new) | Pedal sensor interface timing spec | recommended | +| 3 | Author test | pharaoh:author | (new) | CAN driver HIL test case | recommended | +| 4 | Verify coverage | pharaoh:verify | (all) | Check REQ_001 traceability chain | recommended | + +**Step 8** -- Handoff: + +``` +Spec document written to: docs/superpowers/specs/2026-04-07-brake-response-time-design.md + +Options: + 1. Execute the plan via pharaoh:plan + 2. Review or modify the spec first + 3. Execute later (plan is saved in the spec document) +``` + +--- + +### Example 2: Multiple requirements, full coverage + +**User request**: `pharaoh:spec REQ_001 REQ_002` + +**Step 1** -- Same detection as Example 1. + +**Steps 2-3** -- Both IDs validated. Scope resolution finds full downstream coverage for both requirements (each has spec, impl, and test in approved status). No gaps, no decisions needed. + +**Step 4** -- Scope summary: + +``` +Scope for REQ_001, REQ_002: + Requirements: 2 (full text included) + Specifications: 2 (references only) + Implementations: 2 (references only) + Test cases: 2 (references only) + Gaps: 0 + Decisions needed: 0 +``` + +**Steps 5-6** -- Decisions skipped. Spec document generated at `docs/superpowers/specs/2026-04-07-brake-system-design.md` with both requirements in full text, a complete coverage table (6 downstream needs), empty gaps section ("No gaps identified"), empty decisions section, and no plan table ("No tasks required. All requirements have complete traceability chains."). + +**Step 8** -- Handoff offers: review the spec, run `pharaoh:verify` to confirm traceability, or done. From fe8e6647b5ff4a2492625ff221568cd5a1afbeb9 Mon Sep 17 00:00:00 2001 From: Patrick Dahlke <patrick.dahlke@pichu.io> Date: Tue, 7 Apr 2026 20:20:46 +0200 Subject: [PATCH 5/7] fix: add missing File column to plan tables in pharaoh:spec --- skills/pharaoh-spec/SKILL.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/skills/pharaoh-spec/SKILL.md b/skills/pharaoh-spec/SKILL.md index d2138dd..06cca42 100644 --- a/skills/pharaoh-spec/SKILL.md +++ b/skills/pharaoh-spec/SKILL.md @@ -272,13 +272,13 @@ Source requirements: REQ_042, REQ_043 ## Plan table -| # | Task | Skill | Target | Detail | Required | -|---|------|-------|--------|--------|----------| -| 1 | Analyze impact | pharaoh:change | REQ_042 | Trace downstream effects | yes | -| 2 | Author spec | pharaoh:author | (new) | Subsystem X timing | yes | -| 3 | Author test | pharaoh:author | (new) | CAN driver verification | yes | -| 4 | Update spec | pharaoh:author | SPEC_010 | Timing constraints | yes | -| 5 | Verify | pharaoh:verify | (all) | Check traceability | yes | +| # | Task | Skill | Target | Detail | File | Required | +|---|------|-------|--------|--------|------|----------| +| 1 | Analyze impact | pharaoh:change | REQ_042 | Trace downstream effects | docs/requirements.rst | yes | +| 2 | Author spec | pharaoh:author | (new) | Subsystem X timing | docs/specifications.rst | yes | +| 3 | Author test | pharaoh:author | (new) | CAN driver verification | docs/test_cases.rst | yes | +| 4 | Update spec | pharaoh:author | SPEC_010 | Timing constraints | docs/specifications.rst | yes | +| 5 | Verify | pharaoh:verify | (all) | Check traceability | -- | yes | ``` #### Section rules @@ -312,6 +312,7 @@ Each task row must specify: - **Skill**: The exact Pharaoh skill to invoke (e.g., `pharaoh:change`, `pharaoh:author`, `pharaoh:verify`, `pharaoh:mece`). - **Target**: The need ID being acted on, or `(new)` for needs to create, or `(all)` for verification tasks. - **Detail**: A specific description of the change or action. Not vague -- name the exact property or content being changed. +- **File**: The target file path for the task (e.g., `docs/requirements.rst`, `docs/specifications.rst`), or `--` if not applicable. - **Required**: `yes`, `no`, or `recommended` based on strictness mode. #### Required field rules @@ -477,12 +478,12 @@ User confirms: proceed. - Implementation scope: create 1 spec (pedal sensor timing) and 1 test (CAN driver HIL) - Plan table (advisory mode, all `recommended`): -| # | Task | Skill | Target | Detail | Required | -|---|------|-------|--------|--------|----------| -| 1 | Analyze impact | pharaoh:change | REQ_001 | Trace downstream effects of new spec | recommended | -| 2 | Author spec | pharaoh:author | (new) | Pedal sensor interface timing spec | recommended | -| 3 | Author test | pharaoh:author | (new) | CAN driver HIL test case | recommended | -| 4 | Verify coverage | pharaoh:verify | (all) | Check REQ_001 traceability chain | recommended | +| # | Task | Skill | Target | Detail | File | Required | +|---|------|-------|--------|--------|------|----------| +| 1 | Analyze impact | pharaoh:change | REQ_001 | Trace downstream effects of new spec | docs/requirements.rst | recommended | +| 2 | Author spec | pharaoh:author | (new) | Pedal sensor interface timing spec | docs/specifications.rst | recommended | +| 3 | Author test | pharaoh:author | (new) | CAN driver HIL test case | docs/test_cases.rst | recommended | +| 4 | Verify coverage | pharaoh:verify | (all) | Check REQ_001 traceability chain | -- | recommended | **Step 8** -- Handoff: From 965b85b2eff10b8719fba02476c5b9adcc1ce8db Mon Sep 17 00:00:00 2001 From: Patrick Dahlke <patrick.dahlke@pichu.io> Date: Tue, 7 Apr 2026 20:32:24 +0200 Subject: [PATCH 6/7] feat: add Copilot agent mirrors for spec and decide skills --- .github/agents/pharaoh.decide.agent.md | 118 +++++++++++++++++++++++ .github/agents/pharaoh.spec.agent.md | 124 +++++++++++++++++++++++++ 2 files changed, 242 insertions(+) create mode 100644 .github/agents/pharaoh.decide.agent.md create mode 100644 .github/agents/pharaoh.spec.agent.md diff --git a/.github/agents/pharaoh.decide.agent.md b/.github/agents/pharaoh.decide.agent.md new file mode 100644 index 0000000..5657f99 --- /dev/null +++ b/.github/agents/pharaoh.decide.agent.md @@ -0,0 +1,118 @@ +--- +description: Record a design decision as a traceable sphinx-needs object with alternatives, rationale, and links to affected requirements. +handoffs: + - label: Verify Decision + agent: pharaoh.verify + prompt: Verify the decision need has valid links and fields + - label: Trace Decision + agent: pharaoh.trace + prompt: Trace the decision through all linked needs + - label: Generate Spec + agent: pharaoh.spec + prompt: Generate a spec document from the affected requirements +--- + +# @pharaoh.decide + +Record design decisions as `decision` needs with `decided_by`, `alternatives`, `rationale` fields and `:decides:` links. Delegates RST writing to @pharaoh.author to avoid duplicating directive-writing logic. + +## Data Access + +1. **ubc CLI**: `ubc build needs --format json` for index, `ubc config` for schema. +2. **ubCode MCP**: Pre-indexed needs data. +3. **Raw file parsing**: Read `ubproject.toml`/`conf.py` for types, extra_links, ID settings. Grep for directives. Parse needs. + +Read `pharaoh.toml` for strictness level and workflow settings. + +## Process + +### Step 1: Get Project Data + +Build needs index. Present detection summary. Verify that a `decision` type is configured. If missing, show the user the TOML to add: + +```toml +[[needs.types]] +directive = "decision" +title = "Decision" +prefix = "DEC_" +color = "#E8D0A9" +style = "node" +``` + +Also verify `decided_by`, `alternatives`, `rationale` extra options and the `decides` extra link type exist. Ask user to confirm before proceeding if anything is missing. + +### Step 2: Gather Decision Context + +Collect all required fields: + +- **Title**: What is being decided. +- **Affected needs**: Need IDs for the `:decides:` link. +- **decided_by**: Who made the decision. Default to `claude` when AI decides autonomously. +- **alternatives**: Rejected alternatives, semicolon-separated. +- **rationale**: Why this option was chosen. +- **status**: One of `proposed`, `accepted`, `superseded`, `rejected`. + +**Standalone**: Prompt the user for each missing piece. Do not proceed until all five fields are populated. + +**Called by @pharaoh.spec**: Accept all context programmatically. Do not prompt. + +**Status defaults**: `proposed` when standalone, `accepted` when called by @pharaoh.spec. User may override. + +### Step 3: Generate ID + +Reuse @pharaoh.author ID generation logic: + +1. Check `pharaoh.toml` for `[pharaoh.id_scheme]`. Apply pattern with `{TYPE}` resolving to `DEC`. +2. If no scheme, infer from existing `decision` needs (look for `DEC_*` numbering). +3. If no existing decisions, use prefix from type config and start at `001`, padded to `id_length`. +4. Validate uniqueness against the full needs index. + +### Step 4: Write the Need + +Delegate to @pharaoh.author with all fields: + +```rst +.. decision:: <title> + :id: <generated_id> + :status: <proposed|accepted> + :decides: <need_id1>, <need_id2> + :decided_by: <name or claude> + :alternatives: <alt1>; <alt2> + :rationale: <why this option> + + <expanded description> +``` + +**Superseding**: When replacing an old decision, set old status to `superseded` via @pharaoh.author, add `:links: <old_dec_id>` on the new decision, and explain the replacement in the description. + +### Step 5: File Placement + +Place in `decisions.rst` in the same directory as the first need in `:decides:`. Create the file with proper RST title if it does not exist. If no `:decides:` links, fall back to @pharaoh.author file placement. Delegate actual writing to @pharaoh.author. + +### Step 6: Update Session State + +Write to `.pharaoh/session.json`: set `changes.<dec_id>.authored = true` with current ISO 8601 timestamp. + +### Step 7: Follow-up + +**Standalone**: Suggest `Run @pharaoh.verify to validate the decision against its linked requirements.` + +**Called by @pharaoh.spec**: Return the decision ID silently. No follow-up. + +## Strictness Behavior + +**Advisory mode**: Execute freely. No gates. No tips needed -- decisions can be recorded at any time. + +**Enforcing mode**: Execute freely. No gates. Decisions are gate-free in both modes. + +Strictness has no effect on decision recording. Both modes follow the same process. + +## Constraints + +1. **All three fields mandatory.** Always populate `decided_by`, `alternatives`, `rationale`. Ask explicitly if any are missing. +2. **Default `decided_by` to `claude`** when the AI decides autonomously (e.g., during @pharaoh.spec). +3. **Default `status`** to `proposed` (standalone) or `accepted` (called by @pharaoh.spec). +4. **Superseding requires two writes.** Update old decision to `superseded` AND add `:links:` on the new decision. +5. **Reuse @pharaoh.author** for RST writing, file placement, and ID generation. Do not duplicate logic. +6. **Validate `:decides:` targets exist.** Warn if a target is missing from the needs index. +7. **Semicolons for alternatives.** Separate with semicolons, not commas. diff --git a/.github/agents/pharaoh.spec.agent.md b/.github/agents/pharaoh.spec.agent.md new file mode 100644 index 0000000..13e89a8 --- /dev/null +++ b/.github/agents/pharaoh.spec.agent.md @@ -0,0 +1,124 @@ +--- +description: Generate a Superpowers-compatible spec and plan document from sphinx-needs requirements, bridging requirements to implementation. +handoffs: + - label: Execute Plan + agent: pharaoh.plan + prompt: Execute the plan table from the generated spec + - label: Record Decision + agent: pharaoh.decide + prompt: Record a design decision for a gap in the requirements + - label: MECE Check + agent: pharaoh.mece + prompt: Check for traceability gaps in the spec scope +--- + +# @pharaoh.spec + +Generate a Superpowers-compatible spec document from sphinx-needs requirements. Reads the needs hierarchy, identifies gaps, records decisions via @pharaoh.decide, and produces a markdown spec with an embedded plan table for @pharaoh.plan. + +Output location: `docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md` (overridable by user). + +## Data Access + +1. **ubc CLI**: `ubc build needs --format json` for index, `ubc config` for schema. +2. **ubCode MCP**: Pre-indexed needs data. +3. **Raw file parsing**: Read `ubproject.toml`/`conf.py` for types, extra_links, ID settings. Grep for directives. Parse needs. + +Read `pharaoh.toml` for strictness, workflow gates, traceability requirements, and `required_links` chains. + +## Process + +### Step 1: Get Project Data + +Build needs index and full link graph (both directions for all link types). Present detection summary. If detection fails, report and ask for guidance. + +### Step 2: Parse Input + +Accept one or more requirement IDs. Validate against the needs index. + +- **IDs not found**: Report, suggest similar IDs, ask for confirmation. +- **Natural language**: Resolve by title match, substring, content, or tags. Present candidates if multiple match. +- **Multiple IDs**: Produce a single combined spec document. + +### Step 3: Resolve Requirements Scope + +For each input requirement: + +1. **Pull full text**: ID, title, type, status, content, tags, all links, custom fields. Requirements appear verbatim in the spec. +2. **Trace downstream**: Follow all link types recursively. Collect **references only** (ID, type, title, status, link to parent) for downstream needs. +3. **Build scope tree**: Show requirement at root with all downstream coverage and gaps. +4. **Identify gaps**: Use `required_links` chains from `pharaoh.toml` (or infer from types). Gaps: missing specs, impls, tests, or partial coverage. + +### Step 4: Present Scope Summary + +Show counts of requirements (full text), specs, impls, tests (references), gaps, and decisions needed. Warn if scope exceeds 30 downstream needs. Wait for user confirmation. + +### Step 5: Make Design Decisions + +For each gap needing a design choice (decomposition, technology, test strategy, conflicting constraints), invoke @pharaoh.decide programmatically with: + +- **decided_by**: `claude` +- **status**: `accepted` +- All other fields (title, decides, alternatives, rationale) populated from context. + +Write all decisions BEFORE generating the spec. The spec must reference stable decision IDs, not placeholders. + +If all gaps are straightforward, skip decision recording and note it in the spec. + +### Step 6: Generate the Spec Document + +Write to `docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md`. Create the directory if needed. + +**Required sections in order**: Requirements (source of truth, full verbatim text), Existing coverage (reference table), Gaps (unchecked checkboxes), Decisions (IDs from Step 5), Implementation scope (needs to create/modify tables, "None" if empty), Plan table (built in Step 7). + +Full text for requirements, ref-only for downstream. Decisions must reference stable IDs written in Step 5. + +### Step 7: Build the Plan Table + +Follow @pharaoh.plan task sequencing: + +1. **Change analysis first** (if modifying existing needs). +2. **Author top-down**: Requirements > specs > impls > tests. New before modifications. +3. **Verify after all authoring**. +4. **MECE check** if `require_mece_on_release = true` or multi-level scope. + +Each row: sequential number, concise task, exact skill name, concrete target (need ID, `(new)`, or `(all)`), specific detail, file path or `--`, and required field. + +### Step 8: Handoff + +Present the file path and options: + +``` +Spec document written to: docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md + +Options: + 1. Execute the plan via @pharaoh.plan + 2. Review or modify the spec first + 3. Execute later (plan is saved in the spec document) +``` + +Never auto-execute. Always wait for explicit user approval. + +## Strictness Behavior + +**Advisory mode**: Execute freely. No gates. All plan table tasks marked `recommended`. After generating, show: +``` +Tip: Consider reviewing the spec before executing the plan. +The spec captures design decisions that affect downstream authoring. +``` + +**Enforcing mode**: Execute freely. No gates. Plan table tasks mandated by workflow gates marked `yes`: +- `@pharaoh.change` if `require_change_analysis = true` +- `@pharaoh.verify` if `require_verification = true` +- `@pharaoh.mece` if `require_mece_on_release = true` + +Both modes perform identical analysis depth. Strictness only affects the `Required` column. + +## Constraints + +1. **Full text for requirements, references only for downstream.** Spec is self-contained for requirements but does not duplicate downstream content. +2. **Decisions written before the spec references them.** Always invoke @pharaoh.decide first, collect the ID, then use it. +3. **Plan table format matches @pharaoh.plan exactly.** Same columns, granularity, and semantics. +4. **Never auto-execute.** Present the complete spec and wait for approval before invoking downstream skills. +5. **Single combined spec for multiple requirements.** Do not produce separate documents. +6. **No session state changes from spec generation.** Only @pharaoh.decide and @pharaoh.plan update session state. From 60817210fb78e7493d7af52e142d2429a503e2d4 Mon Sep 17 00:00:00 2001 From: Patrick Dahlke <patrick.dahlke@pichu.io> Date: Tue, 7 Apr 2026 20:42:25 +0200 Subject: [PATCH 7/7] docs: add spec and decide skills to README, Copilot instructions, and config --- .claude-plugin/plugin.json | 2 +- .github/copilot-instructions.md | 11 ++++++++--- README.md | 11 ++++++++--- pharaoh.toml.example | 9 +++++++++ 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index f71dd1b..eb159fa 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -7,5 +7,5 @@ }, "repository": "https://github.com/patdhlk/pharaoh", "license": "MIT", - "keywords": ["sphinx-needs", "requirements", "traceability", "change-analysis", "mece", "safety-critical", "automotive"] + "keywords": ["sphinx-needs", "requirements", "traceability", "change-analysis", "mece", "safety-critical", "automotive", "decisions"] } diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 4ba3d51..ff9f389 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -20,13 +20,18 @@ Pharaoh is a skill-based AI assistant framework for sphinx-needs projects. It he | `@pharaoh.verify` | Validate implementations against requirements -- content-level satisfaction checks | | `@pharaoh.release` | Release management -- changelog from requirements, traceability coverage metrics | | `@pharaoh.plan` | Structured implementation planning -- break changes into tasks with workflow enforcement | +| `@pharaoh.spec` | Generate spec from requirements -- read needs hierarchy, record decisions, produce spec with plan table | +| `@pharaoh.decide` | Record design decisions -- create `decision` needs with alternatives, rationale, and traceability links | ## Recommended Workflow ``` -@pharaoh.change -> @pharaoh.author -> @pharaoh.verify -> @pharaoh.release - -> @pharaoh.mece (optional, for gap analysis) - -> @pharaoh.trace (optional, for exploration) +@pharaoh.spec -> @pharaoh.decide (for gaps) + -> produces spec doc with plan table + | +@pharaoh.plan -> @pharaoh.change -> @pharaoh.author -> @pharaoh.verify -> @pharaoh.release + -> @pharaoh.mece (optional, for gap analysis) + -> @pharaoh.trace (optional, for exploration) ``` ## Data Access Tiers diff --git a/README.md b/README.md index 4324bd7..20a4c07 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,18 @@ Pharaoh has no runtime binary or Python package. All analysis logic is encoded i | `pharaoh:verify` | `@pharaoh.verify` | Validate implementations against requirements -- content-level satisfaction checks | | `pharaoh:release` | `@pharaoh.release` | Release management -- changelog from requirements, traceability coverage metrics | | `pharaoh:plan` | `@pharaoh.plan` | Structured implementation planning -- break changes into tasks with workflow enforcement | +| `pharaoh:spec` | `@pharaoh.spec` | Generate spec from requirements -- read needs hierarchy, record decisions, produce Superpowers-compatible spec with plan table | +| `pharaoh:decide` | `@pharaoh.decide` | Record design decisions -- create `decision` needs with alternatives, rationale, and traceability links | ## Workflow ``` -pharaoh:change -> pharaoh:author -> pharaoh:verify -> pharaoh:release - -> pharaoh:mece (optional, for gap analysis) - -> pharaoh:trace (optional, for exploration) +pharaoh:spec -> pharaoh:decide (for gaps) + -> produces spec doc with plan table + | +pharaoh:plan -> pharaoh:change -> pharaoh:author -> pharaoh:verify -> pharaoh:release + -> pharaoh:mece (optional, for gap analysis) + -> pharaoh:trace (optional, for exploration) ``` ## Experience Tiers diff --git a/pharaoh.toml.example b/pharaoh.toml.example index 9cc2e5d..d58b4b9 100644 --- a/pharaoh.toml.example +++ b/pharaoh.toml.example @@ -33,3 +33,12 @@ required_links = [ [pharaoh.codelinks] # Follow sphinx-codelinks in change analysis enabled = true + +[pharaoh.decisions] +# Default file for new decision needs (relative to docs source root) +# If absent, decisions go to decisions.rst in same directory as affected requirement +default_file = "decisions.rst" +# Default status for decisions created standalone +default_status = "proposed" +# Default status for decisions created during pharaoh:spec +spec_status = "accepted"