murmur8 4.5.1 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/.blueprint/features/feature_pipeline-telemetry/FEATURE_SPEC.md +297 -0
  2. package/.blueprint/features/feature_pipeline-telemetry/IMPLEMENTATION_PLAN.md +34 -0
  3. package/.blueprint/features/feature_pipeline-telemetry/handoff-alex.md +21 -0
  4. package/.blueprint/features/feature_pipeline-telemetry/handoff-cass.md +25 -0
  5. package/.blueprint/features/feature_pipeline-telemetry/handoff-nigel.md +20 -0
  6. package/.blueprint/features/feature_pipeline-telemetry/story-failed-queue-retry.md +53 -0
  7. package/.blueprint/features/feature_pipeline-telemetry/story-identifiers.md +47 -0
  8. package/.blueprint/features/feature_pipeline-telemetry/story-init-integration.md +48 -0
  9. package/.blueprint/features/feature_pipeline-telemetry/story-payload-send.md +54 -0
  10. package/.blueprint/features/feature_pipeline-telemetry/story-telemetry-activation.md +54 -0
  11. package/.blueprint/features/feature_pipeline-telemetry/story-telemetry-config-command.md +52 -0
  12. package/.blueprint/features/feature_refine-feature-skill/FEATURE_SPEC.md +180 -0
  13. package/.blueprint/features/feature_refine-feature-skill/IMPLEMENTATION_PLAN.md +47 -0
  14. package/.blueprint/features/feature_refine-feature-skill/handoff-alex.md +19 -0
  15. package/.blueprint/features/feature_refine-feature-skill/handoff-cass.md +26 -0
  16. package/.blueprint/features/feature_refine-feature-skill/handoff-nigel.md +30 -0
  17. package/.blueprint/features/feature_refine-feature-skill/story-codey-confirmation.md +41 -0
  18. package/.blueprint/features/feature_refine-feature-skill/story-conversation-approval.md +41 -0
  19. package/.blueprint/features/feature_refine-feature-skill/story-initiation.md +42 -0
  20. package/.blueprint/features/feature_refine-feature-skill/story-story-propagation.md +42 -0
  21. package/.blueprint/features/feature_refine-feature-skill/story-telemetry-lineage.md +47 -0
  22. package/.blueprint/features/feature_refine-feature-skill/story-test-propagation.md +42 -0
  23. package/README.md +98 -7
  24. package/bin/cli.js +2 -1
  25. package/package.json +1 -1
  26. package/src/commands/refine.js +37 -0
  27. package/src/commands/telemetry-config.js +16 -0
  28. package/src/index.js +38 -1
  29. package/src/init.js +5 -0
  30. package/src/refine.js +172 -0
  31. package/src/telemetry.js +198 -0
@@ -0,0 +1,54 @@
1
+ # Story — Telemetry Activation & Configuration
2
+
3
+ ### User story
4
+ As a platform administrator, I want to activate pipeline telemetry by setting a URL in `.env` so that murmur8 sends structured execution data to my observability endpoint without requiring code changes.
5
+
6
+ ---
7
+
8
+ ### Context / scope
9
+ - Configuration via `.env` file at project root and/or real environment variables
10
+ - Activation is determined solely by the presence of `MURMUR8_TELEMETRY_URL`
11
+ - Absence of the URL means telemetry is fully inactive — no output, no side effects
12
+
13
+ ---
14
+
15
+ ### Acceptance criteria
16
+
17
+ **AC-1 — Telemetry inactive when URL is absent**
18
+ - Given `MURMUR8_TELEMETRY_URL` is not set in `.env` or in the process environment,
19
+ - When a pipeline run completes,
20
+ - Then no HTTP request is made, no queue file is created, and no output is produced.
21
+
22
+ **AC-2 — Telemetry active when URL is set in `.env`**
23
+ - Given `MURMUR8_TELEMETRY_URL` is set to a valid URL in `.env`,
24
+ - When a pipeline run completes,
25
+ - Then `src/telemetry.js` POSTs the payload to that URL.
26
+
27
+ **AC-3 — Real environment variable takes precedence over `.env`**
28
+ - Given `MURMUR8_TELEMETRY_URL` is set to `https://env-value.example.com` in the process environment,
29
+ - And `.env` contains `MURMUR8_TELEMETRY_URL=https://dotenv-value.example.com`,
30
+ - When telemetry resolves the endpoint,
31
+ - Then the request is sent to `https://env-value.example.com` (the process env value).
32
+
33
+ **AC-4 — API key sent as Authorization header when set**
34
+ - Given `MURMUR8_TELEMETRY_KEY` is set (in `.env` or environment),
35
+ - When the telemetry POST is made,
36
+ - Then the request includes the header `Authorization: Bearer <key>`.
37
+
38
+ **AC-5 — Authorization header omitted when key is absent**
39
+ - Given `MURMUR8_TELEMETRY_KEY` is not set,
40
+ - When the telemetry POST is made,
41
+ - Then no `Authorization` header is included in the request.
42
+
43
+ **AC-6 — Same precedence rule applies to API key**
44
+ - Given `MURMUR8_TELEMETRY_KEY` is set in both the process environment and `.env` with different values,
45
+ - When telemetry resolves the key,
46
+ - Then the process environment value is used.
47
+
48
+ ---
49
+
50
+ ### Out of scope
51
+ - Opt-out flag (absence of URL is the opt-out mechanism)
52
+ - Validating or enforcing HTTPS on the configured URL
53
+ - Telemetry for non-pipeline CLI commands (`history`, `queue`, etc.)
54
+ - Any third-party `.env` parsing library (manual parsing only)
@@ -0,0 +1,52 @@
1
+ # Story — telemetry-config CLI Command
2
+
3
+ ### User story
4
+ As a platform administrator, I want to run `murmur8 telemetry-config` to view the current telemetry configuration so that I can confirm the endpoint is configured correctly and check the failed-send queue depth — without exposing the API key in plaintext.
5
+
6
+ ---
7
+
8
+ ### Context / scope
9
+ - New CLI command: `murmur8 telemetry-config` (registered in `bin/cli.js`, handled by `src/commands/telemetry-config.js`)
10
+ - Reads configuration from `.env` and process environment (same precedence rules as telemetry module)
11
+ - Displays configured URL; masks the API key; shows failed queue depth
12
+
13
+ ---
14
+
15
+ ### Acceptance criteria
16
+
17
+ **AC-1 — Command displays configured URL**
18
+ - Given `MURMUR8_TELEMETRY_URL` is set,
19
+ - When `murmur8 telemetry-config` is run,
20
+ - Then the output includes the full configured URL.
21
+
22
+ **AC-2 — API key is masked in output**
23
+ - Given `MURMUR8_TELEMETRY_KEY` is set to a non-empty value,
24
+ - When `murmur8 telemetry-config` is run,
25
+ - Then the output displays the key in masked form (e.g. `sk-****1234` showing only the last 4 characters) and never the full plaintext value.
26
+
27
+ **AC-3 — Key shown as "not set" when absent**
28
+ - Given `MURMUR8_TELEMETRY_KEY` is not configured,
29
+ - When `murmur8 telemetry-config` is run,
30
+ - Then the output indicates no key is configured (e.g. `not set`).
31
+
32
+ **AC-4 — Command shows telemetry as inactive when URL is absent**
33
+ - Given `MURMUR8_TELEMETRY_URL` is not set,
34
+ - When `murmur8 telemetry-config` is run,
35
+ - Then the output clearly indicates telemetry is inactive (e.g. `status: inactive`).
36
+
37
+ **AC-5 — Failed queue depth is displayed**
38
+ - Given `.claude/telemetry-failed.json` exists with N entries,
39
+ - When `murmur8 telemetry-config` is run,
40
+ - Then the output includes the number of queued failed sends (e.g. `failed queue: 3 entries`).
41
+
42
+ **AC-6 — Failed queue shown as zero when file is absent**
43
+ - Given `.claude/telemetry-failed.json` does not exist,
44
+ - When `murmur8 telemetry-config` is run,
45
+ - Then the output shows a failed queue depth of 0.
46
+
47
+ ---
48
+
49
+ ### Out of scope
50
+ - A `--test` flag to send a synthetic ping to the endpoint
51
+ - Editing or clearing configuration via this command (read-only display)
52
+ - Displaying the full contents of the failed send queue
@@ -0,0 +1,180 @@
1
+ # Feature Specification — Refine Feature Skill
2
+
3
+ ## 1. Feature Intent
4
+ **Why this feature exists.**
5
+
6
+ - After running `/implement-feature`, the result may not match user intent — tests pass but behaviour is wrong, scope was misunderstood, or new information changes requirements
7
+ - Users need a structured path to refine an existing feature without starting from scratch
8
+ - This supports the system purpose of iterative, AI-assisted feature development
9
+
10
+ ---
11
+
12
+ ## 2. Scope
13
+ ### In Scope
14
+ - New `/refine-feature [slug]` skill that initiates a refinement pipeline
15
+ - Alex reads existing spec, stories, and test output to build context, then converses with the user to identify changes
16
+ - Alex presents a proposed spec diff; user approves before changes are applied
17
+ - Cass updates affected story files and produces `story-changes.md`
18
+ - Nigel updates affected tests and produces `test-changes.md`
19
+ - Mandatory pause before Codey implements — user must confirm
20
+ - Codey implements changes using the same test-first approach
21
+ - Telemetry: `parentRunId` field linking this run to the run being refined; artifact diffs instead of full files
22
+ - SKILL.md written to project root; copied to `.claude/commands/refine-feature.md` on `murmur8 init`
23
+
24
+ ### Out of Scope
25
+ - Branching or forking a feature into two separate features
26
+ - Rolling back a feature (separate concern)
27
+ - Bulk-refining multiple features in one invocation
28
+ - Changing the featureId (it must be preserved across refinements)
29
+
30
+ ---
31
+
32
+ ## 3. Actors Involved
33
+
34
+ **User**
35
+ - Provides the slug of the feature to refine
36
+ - Engages in freeform conversation with Alex about what needs to change (feedback, error logs, test output)
37
+ - Reviews and approves/rejects the proposed spec diff
38
+ - Confirms before Codey implements
39
+
40
+ **Alex**
41
+ - Reads existing FEATURE_SPEC.md, story-*.md, test output, and pipeline history
42
+ - Converses with user to understand what changed or was wrong
43
+ - Identifies minimal set of spec changes needed
44
+ - Presents diff; updates FEATURE_SPEC.md only after approval
45
+
46
+ **Cass**
47
+ - Reads `story-changes.md` produced by Alex
48
+ - Updates only affected story files (not all stories)
49
+ - Produces `story-changes.md` summarising what changed and why
50
+
51
+ **Nigel**
52
+ - Reads `story-changes.md` to understand scope of change
53
+ - Updates only affected test cases
54
+ - Produces `test-changes.md` summarising what changed
55
+
56
+ **Codey**
57
+ - Receives explicit user confirmation before starting
58
+ - Implements changes to pass updated tests
59
+ - Uses the same test-first incremental approach as the main pipeline
60
+
61
+ ---
62
+
63
+ ## 4. Behaviour Overview
64
+
65
+ ### Happy Path
66
+ 1. User runs `/refine-feature [slug]`
67
+ 2. Alex reads existing artifacts and presents a brief summary of current state
68
+ 3. Alex asks: "What needs to change?"
69
+ 4. User provides feedback (freeform: description, logs, error output, screenshots)
70
+ 5. Alex identifies changes and presents a proposed diff to FEATURE_SPEC.md
71
+ 6. User approves → Alex writes updated FEATURE_SPEC.md (featureId preserved)
72
+ 7. Cass updates affected stories and writes `story-changes.md`
73
+ 8. Nigel updates affected tests and writes `test-changes.md`
74
+ 9. Pipeline pauses: user sees summary of changes across spec/stories/tests
75
+ 10. User confirms → Codey implements, runs tests, iterates until passing
76
+ 11. Pipeline commits (unless `--no-commit`) and records refinement in history
77
+
78
+ ### Key Alternatives
79
+ - User rejects Alex's proposed diff → Alex revises and re-presents
80
+ - User aborts at any stage → clean exit, no partial writes
81
+ - No stories exist (technical feature) → Cass stage skipped; Nigel works from spec diff directly
82
+ - Tests already pass after spec change → Codey stage skipped with note
83
+
84
+ ---
85
+
86
+ ## 5. State & Lifecycle Interactions
87
+
88
+ - State-transitioning: moves an existing feature from a completed/deployed state back into active refinement
89
+ - Reads but does not replace existing artifacts until user approves diff
90
+ - After refinement, artifacts reflect the refined state; originals not preserved (git history provides rollback)
91
+ - Refinement history is a chain: each run's `parentRunId` points to the previous run's `runId`
92
+
93
+ ---
94
+
95
+ ## 6. Rules & Decision Logic
96
+
97
+ **R1: featureId preservation**
98
+ - The existing `featureId` in FEATURE_SPEC.md YAML frontmatter must never be changed
99
+ - Input: existing spec; Output: updated spec with same featureId
100
+
101
+ **R2: parentRunId linkage**
102
+ - Every refinement run must include `parentRunId` = the `runId` of the run being refined
103
+ - If no prior run exists in history for this slug, `parentRunId` = null (graceful)
104
+ - Input: pipeline history for slug; Output: parentRunId in telemetry payload
105
+
106
+ **R3: Mandatory pause before Codey**
107
+ - Codey must never run without explicit user confirmation
108
+ - Applies regardless of flags (no `--yes` bypass for this gate)
109
+
110
+ **R4: Cass skipped for technical features**
111
+ - If the original feature was classified as technical (no stories exist), Cass is skipped
112
+ - Nigel works from the spec diff directly
113
+
114
+ **R5: Artifact diff in telemetry**
115
+ - Refinement telemetry sends diffs (before/after) rather than full artifact content
116
+ - Keeps payload size proportional to the change, not the total feature size
117
+
118
+ ---
119
+
120
+ ## 7. Dependencies
121
+
122
+ - `src/telemetry.js` — existing telemetry module; refinements add `parentRunId` field
123
+ - `src/history.js` — existing history module; refinements are recorded with `type: "refinement"`
124
+ - `src/classifier.js` — determines whether Cass stage runs
125
+ - `src/diff-preview.js` — used for pre-commit diff review
126
+ - `src/feedback.js` — quality gates between stages (same thresholds)
127
+ - `.blueprint/agents/AGENT_SPECIFICATION_ALEX.md` — Alex agent spec
128
+ - `.blueprint/agents/AGENT_BA_CASS.md` — Cass agent spec
129
+ - `.blueprint/agents/AGENT_TESTER_NIGEL.md` — Nigel agent spec
130
+ - `.blueprint/agents/AGENT_DEVELOPER_CODEY.md` — Codey agent spec
131
+
132
+ ---
133
+
134
+ ## 8. Non-Functional Considerations
135
+
136
+ - **Token efficiency**: Alex reads existing artifacts selectively — handoff summaries first, full spec only if needed
137
+ - **Audit**: all refinements recorded in pipeline history; parentRunId chain enables full lineage
138
+ - **Safety**: mandatory pause before Codey prevents accidental overwrites on approval
139
+
140
+ ---
141
+
142
+ ## 9. Assumptions & Open Questions
143
+
144
+ **Assumptions:**
145
+ - The feature being refined already has a FEATURE_SPEC.md
146
+ - featureId exists in YAML frontmatter (if not, it should be added before refinement proceeds)
147
+ - Git is available for diff display and commit
148
+
149
+ **Open Questions:**
150
+ - Should a `--no-pause` flag be allowed to skip the Codey confirmation? (Current decision: no, always pause)
151
+ - Should `story-changes.md` and `test-changes.md` be committed alongside the updated files, or deleted after? (Current decision: commit them as refinement audit trail)
152
+
153
+ ---
154
+
155
+ ## 10. Impact on System Specification
156
+
157
+ This feature reinforces the system's core model of iterative, agent-assisted development. It stretches the pipeline slightly by adding a conversation phase (Alex ↔ user) before spec writing, but does not contradict any existing system assumptions.
158
+
159
+ No system spec changes required.
160
+
161
+ ---
162
+
163
+ ## 11. Handover to BA (Cass)
164
+
165
+ Story themes:
166
+ - Initiating a refinement: user provides slug, Alex reads context
167
+ - Conversation and approval: user provides feedback, Alex proposes diff, user approves
168
+ - Story propagation: Cass updates affected stories, produces story-changes.md
169
+ - Test propagation: Nigel updates affected tests, produces test-changes.md
170
+ - Implementation confirmation: mandatory pause, user confirms, Codey implements
171
+ - Telemetry lineage: parentRunId chain, artifact diffs
172
+
173
+ Story boundaries: each stage transition (user→Alex, Alex→Cass, Cass→Nigel, Nigel→pause, pause→Codey) is a natural story boundary.
174
+
175
+ ---
176
+
177
+ ## 12. Change Log (Feature-Level)
178
+ | Date | Change | Reason | Raised By |
179
+ |------|--------|--------|-----------|
180
+ | 2026-05-19 | Initial spec | New feature design | Steve Newman |
@@ -0,0 +1,47 @@
1
+ # Implementation Plan — refine-feature-skill
2
+
3
+ ## Summary
4
+ Create `src/refine.js` exporting 10 pure helper functions tested by Nigel's 25-test suite. Add `src/commands/refine.js` CLI handler and wire the command into `bin/cli.js` and `src/index.js`. Write `REFINE_SKILL.md` at project root.
5
+
6
+ ## Files to Create/Modify
7
+
8
+ | Path | Action | Purpose |
9
+ |------|--------|---------|
10
+ | `src/refine.js` | Create | All 10 pure helper functions |
11
+ | `src/commands/refine.js` | Create | CLI handler for `murm refine` / `refine-feature` command |
12
+ | `src/index.js` | Modify | Export refine module functions |
13
+ | `bin/cli.js` | Modify | Register `refine-feature` command |
14
+ | `REFINE_SKILL.md` | Create | Skill definition for /refine-feature |
15
+
16
+ ## Implementation Steps
17
+
18
+ 1. **Create `src/refine.js`** — implement all 10 functions:
19
+ - `parseRefinementArgs(argv)` → `{ slug }` from argv[3] or null
20
+ - `loadRefinementContext(slug, baseDir)` → reads FEATURE_SPEC.md (throws if missing), story-*.md files, .claude/pipeline-history.json; extracts/writes featureId; returns `{ spec, stories, history, featureId, slug }`
21
+ - `applySpecDiff(specPath, newContent, featureId)` → throws on null; writes spec with YAML frontmatter containing featureId
22
+ - `buildRefinementPayload(opts)` → returns plain object with storyChangesPath, testChangesPath, specDiff, commitSkipped
23
+ - `linkParentRun(slug, history)` → finds most recent entry for slug by completedAt; returns `{ parentRunId, type: 'refinement', featureId }`
24
+ - `isTechnicalFeature(stories)` → returns `stories.length === 0`
25
+ - `filterAffectedStories(stories, changedSlugs)` → filters by slug contained in filename
26
+ - `buildStoryChanges(entries)` → returns entries array (passthrough with validation)
27
+ - `buildChangeSummary(opts)` → returns `{ specPath, affectedStories, testChangesPath }`
28
+ - `isPauseBypassable(_flags)` → always returns `false`
29
+
30
+ 2. **Run tests** after writing src/refine.js — expect 25/25 to pass
31
+
32
+ 3. **Create `src/commands/refine.js`** — CLI handler that calls loadRefinementContext and orchestrates the pipeline flow (stub-level for now; skill handles orchestration)
33
+
34
+ 4. **Modify `src/index.js`** — add require + exports for refine module
35
+
36
+ 5. **Modify `bin/cli.js`** — register `refine-feature` command routing to `src/commands/refine.js`
37
+
38
+ 6. **Create `REFINE_SKILL.md`** — skill definition with full `/refine-feature` pipeline documented
39
+
40
+ 7. **Run full test suite** — `node --test` to verify no regressions
41
+
42
+ ## Key Implementation Notes
43
+
44
+ - `loadRefinementContext`: use `fs.readdirSync` to find `story-*.md` files; parse YAML frontmatter with simple regex (no deps); if no featureId in frontmatter, generate UUID v4 and write it back (same pattern as telemetry's `ensureFeatureId`)
45
+ - `applySpecDiff`: ensure YAML frontmatter block always starts the file; preserve featureId even if newContent doesn't include it
46
+ - `linkParentRun`: sort history by `completedAt` descending, take first matching slug; if no match, parentRunId = null
47
+ - UUID generation: use `crypto.randomUUID()` (Node 18+, no deps needed)
@@ -0,0 +1,19 @@
1
+ ## Handoff Summary
2
+ **For:** Cass
3
+ **Feature:** refine-feature-skill
4
+
5
+ ### Key Decisions
6
+ - Skill is `/refine-feature [slug]` — a separate skill from `/implement-feature`, not a flag
7
+ - Alex stage is conversation-based (reads existing artifacts, chats with user, proposes diff) rather than fresh spec creation
8
+ - Hard pause before Codey is mandatory — no `--yes` bypass
9
+ - Telemetry uses `parentRunId` to form a linked chain of refinements; `featureId` is preserved
10
+ - Cass skipped if original feature had no stories (technical classification)
11
+
12
+ ### Files Created
13
+ - .blueprint/features/feature_refine-feature-skill/FEATURE_SPEC.md
14
+
15
+ ### Open Questions
16
+ - None
17
+
18
+ ### Critical Context
19
+ The six story themes map cleanly to pipeline stages: (1) initiation, (2) conversation + approval, (3) story propagation via Cass, (4) test propagation via Nigel, (5) mandatory pause + Codey confirmation, (6) telemetry lineage. Each story should have testable ACs focused on the observable behaviour at that stage boundary.
@@ -0,0 +1,26 @@
1
+ ## Handoff Summary
2
+ **For:** Nigel
3
+ **Feature:** refine-feature-skill
4
+
5
+ ### Stories Written (6)
6
+ - story-initiation.md — skill invocation, artifact loading, featureId capture/creation
7
+ - story-conversation-approval.md — freeform feedback, diff proposal loop, approval gate, clean abort
8
+ - story-story-propagation.md — Cass updates affected stories only, produces story-changes.md, skipped for technical features
9
+ - story-test-propagation.md — Nigel updates affected tests only, produces test-changes.md, uses spec diff when Cass skipped
10
+ - story-codey-confirmation.md — mandatory pre-Codey pause, no flag bypass, test-first implementation, conditional commit
11
+ - story-telemetry-lineage.md — parentRunId chain, type:"refinement", artifact diffs in telemetry, change files committed as audit trail
12
+
13
+ ### Key Constraints for Nigel
14
+ - Every AC is independently testable; prefer unit/integration tests over end-to-end
15
+ - featureId preservation (AC-6 in initiation, AC-6 in conversation-approval, AC-4 in telemetry) must be verified as a cross-cutting invariant
16
+ - The no-flag-bypass rule (AC-2 in codey-confirmation) is safety-critical — test it explicitly with `--yes` and similar flags
17
+ - Cass-skip path (technical features) is tested in both story-propagation and test-propagation stories
18
+ - parentRunId = null graceful path (AC-2 in telemetry) must be a distinct test case
19
+
20
+ ### Files Created
21
+ - story-initiation.md
22
+ - story-conversation-approval.md
23
+ - story-story-propagation.md
24
+ - story-test-propagation.md
25
+ - story-codey-confirmation.md
26
+ - story-telemetry-lineage.md
@@ -0,0 +1,30 @@
1
+ ## Handoff Summary
2
+ **For:** Codey
3
+ **Feature:** refine-feature-skill
4
+
5
+ ### Tests Written
6
+ - File: `test/feature_refine-feature-skill.test.js`
7
+ - Spec: `test/artifacts/feature_refine-feature-skill/test-spec.md`
8
+ - Total tests: 25 across 6 describe blocks (one per story)
9
+
10
+ ### Coverage
11
+ | Story | ACs covered | Test IDs |
12
+ |---|---|---|
13
+ | story-initiation.md | AC-1,2,3,4,5,6 | RF-IN-1…6 |
14
+ | story-conversation-approval.md | AC-3,5,6 | RF-CA-3,5,6 |
15
+ | story-story-propagation.md | AC-1,3,4,5,6 | RF-SP-1,3,4,5,6 |
16
+ | story-test-propagation.md | AC-1,3,5 | RF-TP-1,3,5 |
17
+ | story-codey-confirmation.md | AC-2,4,6 | RF-CC-2,4,6 |
18
+ | story-telemetry-lineage.md | AC-1,2,3,4,7 | RF-TL-1,2,3,4,7 |
19
+
20
+ ### Key Assumptions for Codey
21
+ - `src/refine.js` exports all 10 pure functions listed in test-spec.md
22
+ - `loadRefinementContext(slug, baseDir)` accepts a base directory for testability
23
+ - `applySpecDiff(specPath, newContent, featureId)` — null newContent = abort (throws)
24
+ - `linkParentRun(slug, historyArray)` is pure; no file I/O
25
+ - `isPauseBypassable` always returns `false`; no flags override it
26
+
27
+ ### Files to Create
28
+ - `src/refine.js` — all pure helper functions
29
+ - `src/commands/refine.js` — CLI handler wiring
30
+ - `REFINE_SKILL.md` and `.claude/commands/refine-feature.md`
@@ -0,0 +1,41 @@
1
+ # Story: Mandatory Pause and Codey Confirmation
2
+
3
+ **As a** developer reviewing the proposed changes to spec, stories, and tests
4
+ **I want** to see a consolidated summary of all changes before Codey begins implementation, and to give explicit confirmation before any code is touched
5
+ **So that** I retain full control and cannot accidentally trigger implementation via a flag or shortcut
6
+
7
+ ## Acceptance Criteria
8
+
9
+ ### AC-1: Pipeline pauses before Codey with a change summary
10
+ **Given** Nigel has produced `test-changes.md`
11
+ **When** the pipeline reaches the pre-Codey gate
12
+ **Then** the pipeline displays a summary showing: files changed in spec, stories affected, and tests added/modified, then waits for explicit user input before proceeding
13
+
14
+ ### AC-2: No flag or option bypasses the pre-Codey pause
15
+ **Given** the pre-Codey gate is active
16
+ **When** the user invokes `/refine-feature` with any combination of flags (including `--yes`, `--no-pause`, or any other flag)
17
+ **Then** the pipeline still pauses and requires explicit confirmation; no flag silently bypasses this gate
18
+
19
+ ### AC-3: User confirmation triggers Codey implementation
20
+ **Given** the pre-Codey change summary is displayed
21
+ **When** the user confirms (e.g., types "yes" or "proceed")
22
+ **Then** Codey begins implementation using the updated tests as its acceptance target
23
+
24
+ ### AC-4: User abort at pre-Codey gate exits cleanly
25
+ **Given** the pre-Codey change summary is displayed
26
+ **When** the user aborts (e.g., types "cancel" or "no")
27
+ **Then** the pipeline exits cleanly; all spec, story, and test file writes that have already occurred are preserved; no code changes are made
28
+
29
+ ### AC-5: Codey uses test-first incremental approach
30
+ **Given** the user has confirmed at the pre-Codey gate
31
+ **When** Codey implements changes
32
+ **Then** Codey runs the updated tests first, implements code changes incrementally to make them pass, and iterates until all updated tests pass
33
+
34
+ ### AC-6: Pipeline commits after successful implementation unless --no-commit
35
+ **Given** Codey has completed implementation and all tests pass
36
+ **When** the pipeline finishes
37
+ **Then** changes are committed to git unless the `--no-commit` flag was supplied, in which case the pipeline exits with a message indicating commit was skipped
38
+
39
+ ## Out of Scope
40
+ - Codey making spec or story changes (those are locked before this gate)
41
+ - Any automated or timed confirmation; confirmation must be an explicit user action
@@ -0,0 +1,41 @@
1
+ # Story: Conversation and Spec Diff Approval
2
+
3
+ **As a** developer providing feedback on a completed feature
4
+ **I want** to describe what is wrong or what has changed to Alex in freeform language, then review a proposed diff before anything is written
5
+ **So that** spec changes are driven by my intent and I cannot accidentally overwrite existing work
6
+
7
+ ## Acceptance Criteria
8
+
9
+ ### AC-1: Alex accepts freeform feedback input
10
+ **Given** Alex has presented the current-state summary
11
+ **When** the user provides feedback in any form (plain text, error logs, test output, screenshots)
12
+ **Then** Alex accepts the input without requiring a specific format and proceeds to analyse it
13
+
14
+ ### AC-2: Alex presents a proposed diff to FEATURE_SPEC.md
15
+ **Given** Alex has analysed the user's feedback
16
+ **When** Alex has identified the minimal set of spec changes required
17
+ **Then** Alex presents the proposed changes as a clearly labelled before/after diff and asks the user to approve or reject
18
+
19
+ ### AC-3: User approval triggers spec write
20
+ **Given** Alex has presented the proposed diff
21
+ **When** the user explicitly approves the diff
22
+ **Then** Alex writes the updated `FEATURE_SPEC.md` with the changes applied, preserving the original featureId
23
+
24
+ ### AC-4: User rejection triggers revision loop
25
+ **Given** Alex has presented the proposed diff
26
+ **When** the user rejects the diff or requests changes
27
+ **Then** Alex revises the proposed diff based on the user's clarification and presents an updated version; no files are written until approval is given
28
+
29
+ ### AC-5: User abort exits cleanly with no writes
30
+ **Given** the conversation is in progress at any point before approval
31
+ **When** the user aborts (e.g., types "cancel" or "abort")
32
+ **Then** the pipeline exits cleanly, no files are modified, and the user receives confirmation that no changes were made
33
+
34
+ ### AC-6: featureId is unchanged after spec write
35
+ **Given** the user has approved the proposed diff
36
+ **When** Alex writes the updated `FEATURE_SPEC.md`
37
+ **Then** the featureId in the YAML frontmatter is identical to the value read at initiation
38
+
39
+ ## Out of Scope
40
+ - Automated approval via a `--yes` flag for this gate
41
+ - Approving changes to story or test files at this stage (those are handled by Cass and Nigel)
@@ -0,0 +1,42 @@
1
+ # Story: Refinement Initiation
2
+
3
+ **As a** developer who has run `/implement-feature` and found the result does not fully match intent
4
+ **I want** to run `/refine-feature [slug]` and have Alex load all existing artifacts for that feature
5
+ **So that** I can start a targeted refinement without duplicating work already done
6
+
7
+ ## Acceptance Criteria
8
+
9
+ ### AC-1: Skill exists and accepts a slug argument
10
+ **Given** murmur8 has been initialised in a project
11
+ **When** the user runs `/refine-feature some-feature`
12
+ **Then** the `/refine-feature` skill is recognised as a valid command and begins execution with `some-feature` as the target slug
13
+
14
+ ### AC-2: Missing FEATURE_SPEC.md produces a clear error
15
+ **Given** no `FEATURE_SPEC.md` exists for the given slug
16
+ **When** the user runs `/refine-feature missing-slug`
17
+ **Then** the pipeline exits with a message indicating the spec was not found and no files are modified
18
+
19
+ ### AC-3: Alex reads existing artifacts before engaging the user
20
+ **Given** a feature with an existing `FEATURE_SPEC.md`, one or more `story-*.md` files, and pipeline history
21
+ **When** the refinement skill starts
22
+ **Then** Alex reads the spec, all story files, and the most recent pipeline history entry for the slug before prompting the user
23
+
24
+ ### AC-4: Alex presents a current-state summary before asking for feedback
25
+ **Given** Alex has loaded all existing artifacts
26
+ **When** the context-loading phase completes
27
+ **Then** Alex presents a brief summary (feature name, current scope, last run status) and then asks: "What needs to change?"
28
+
29
+ ### AC-5: featureId is read from YAML frontmatter
30
+ **Given** `FEATURE_SPEC.md` contains a `featureId` in its YAML frontmatter
31
+ **When** Alex initialises the refinement session
32
+ **Then** the featureId value is captured and preserved for all subsequent writes in this run
33
+
34
+ ### AC-6: Missing featureId is added before refinement proceeds
35
+ **Given** `FEATURE_SPEC.md` exists but has no `featureId` in its YAML frontmatter
36
+ **When** the refinement skill starts
37
+ **Then** Alex adds a new featureId to the frontmatter before proceeding, and logs that it was added
38
+
39
+ ## Out of Scope
40
+ - Running refinement on multiple features in a single invocation
41
+ - Forking or branching a feature into two separate features
42
+ - Rolling back a feature to a previous state
@@ -0,0 +1,42 @@
1
+ # Story: Story Propagation via Cass
2
+
3
+ **As a** developer who has approved a spec diff
4
+ **I want** Cass to update only the affected user story files and produce a `story-changes.md` summary
5
+ **So that** stories stay in sync with the refined spec without unnecessary churn to unchanged stories
6
+
7
+ ## Acceptance Criteria
8
+
9
+ ### AC-1: Cass is skipped for technical features
10
+ **Given** the original feature was classified as technical (no `story-*.md` files exist for the slug)
11
+ **When** the refinement pipeline reaches the Cass stage
12
+ **Then** the Cass stage is skipped and the pipeline proceeds directly to Nigel; a note is recorded in the run output
13
+
14
+ ### AC-2: Cass reads the spec diff not the full spec
15
+ **Given** Alex has written an updated `FEATURE_SPEC.md`
16
+ **When** Cass starts
17
+ **Then** Cass reads `story-changes.md` (produced by Alex) to understand the scope of change before reading the full spec
18
+
19
+ ### AC-3: Only affected story files are updated
20
+ **Given** a feature with multiple existing `story-*.md` files
21
+ **When** Cass has identified which stories are affected by the spec diff
22
+ **Then** Cass updates only those story files; stories not affected by the diff are left unchanged
23
+
24
+ ### AC-4: Cass produces a `story-changes.md` file
25
+ **Given** Cass has completed updating stories
26
+ **When** the Cass stage finishes
27
+ **Then** a `story-changes.md` file exists in the feature directory listing which stories were changed and a brief reason for each change
28
+
29
+ ### AC-5: Cass does not delete existing stories without cause
30
+ **Given** an existing story that is unaffected by the spec diff
31
+ **When** Cass completes
32
+ **Then** that story file is present and unmodified
33
+
34
+ ### AC-6: New stories are created if the spec diff adds new scope
35
+ **Given** the approved diff introduces new user-facing behaviour not covered by any existing story
36
+ **When** Cass processes the diff
37
+ **Then** Cass creates a new `story-[slug].md` file for the new scope and lists it in `story-changes.md`
38
+
39
+ ## Out of Scope
40
+ - Cass making changes to test files (that is Nigel's responsibility)
41
+ - Cass engaging in conversation with the user about story scope
42
+ - Bulk-updating all stories regardless of diff scope
@@ -0,0 +1,47 @@
1
+ # Story: Telemetry Lineage via parentRunId
2
+
3
+ **As a** developer or team lead reviewing a feature's evolution over multiple refinements
4
+ **I want** each refinement run to record a `parentRunId` linking it to the run it refines
5
+ **So that** I can trace the full chain of refinements for any feature from pipeline history
6
+
7
+ ## Acceptance Criteria
8
+
9
+ ### AC-1: Refinement run records parentRunId in history
10
+ **Given** a pipeline history entry exists for the slug being refined
11
+ **When** the refinement run completes
12
+ **Then** the history entry for this refinement run contains a `parentRunId` field set to the `runId` of the most recent prior run for that slug
13
+
14
+ ### AC-2: parentRunId is null when no prior history exists
15
+ **Given** no pipeline history entry exists for the slug being refined
16
+ **When** the refinement run records its history entry
17
+ **Then** the `parentRunId` field is present and set to `null`; the run is not aborted or errored because of missing history
18
+
19
+ ### AC-3: Refinement run is recorded with type "refinement"
20
+ **Given** a refinement run completes (successfully or with user abort)
21
+ **When** the history entry is written
22
+ **Then** the entry contains `"type": "refinement"` to distinguish it from original `"type": "implementation"` runs
23
+
24
+ ### AC-4: featureId is identical to the original run's featureId
25
+ **Given** an original implementation run recorded a featureId for a slug
26
+ **When** a refinement run for the same slug records its history entry
27
+ **Then** the featureId in the refinement history entry is the same value as in the original run
28
+
29
+ ### AC-5: Telemetry payload uses artifact diffs, not full files
30
+ **Given** spec, story, and test files were updated during the refinement
31
+ **When** telemetry is emitted
32
+ **Then** the payload contains before/after diffs for each changed artifact rather than the full file contents
33
+
34
+ ### AC-6: story-changes.md and test-changes.md are committed as audit trail
35
+ **Given** Cass produced `story-changes.md` and/or Nigel produced `test-changes.md`
36
+ **When** the pipeline commits at the end of a successful refinement
37
+ **Then** both change summary files are included in the commit alongside the updated spec, story, and test files
38
+
39
+ ### AC-7: parentRunId chain is traversable across multiple refinements
40
+ **Given** a feature has been refined three times, each run recording a parentRunId pointing to the previous
41
+ **When** a developer queries the history for that slug
42
+ **Then** the history entries can be ordered into a chain: run-1 ← run-2 ← run-3 ← run-4 via parentRunId links
43
+
44
+ ## Out of Scope
45
+ - Visualising the refinement chain in the CLI (a future feature)
46
+ - Preserving original artifact files alongside refined versions (git history provides rollback)
47
+ - Changing the featureId at any point in the chain