murmur8 4.1.1 → 4.3.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 (50) hide show
  1. package/.blueprint/agents/AGENT_SPECIFICATION_ALEX.md +33 -3
  2. package/.blueprint/features/feature_config-factory/FEATURE_SPEC.md +138 -0
  3. package/.blueprint/features/feature_config-factory/IMPLEMENTATION_PLAN.md +187 -0
  4. package/.blueprint/features/feature_config-factory/handoff-nigel.md +57 -0
  5. package/.blueprint/features/feature_export-history/FEATURE_SPEC.md +215 -0
  6. package/.blueprint/features/feature_export-history/IMPLEMENTATION_PLAN.md +48 -0
  7. package/.blueprint/features/feature_export-history/story-basic-export.md +48 -0
  8. package/.blueprint/features/feature_export-history/story-date-filter.md +42 -0
  9. package/.blueprint/features/feature_export-history/story-feature-filter.md +42 -0
  10. package/.blueprint/features/feature_export-history/story-file-output.md +48 -0
  11. package/.blueprint/features/feature_export-history/story-status-filter.md +42 -0
  12. package/.blueprint/features/feature_extract-prompt-util/FEATURE_SPEC.md +42 -0
  13. package/.blueprint/features/feature_fix-status-icons/FEATURE_SPEC.md +37 -0
  14. package/.blueprint/features/feature_murm-subagent/FEATURE_SPEC.md +137 -0
  15. package/.blueprint/features/feature_murm-subagent/SKILL_CHANGES.md +345 -0
  16. package/.blueprint/features/feature_split-cli-commands/FEATURE_SPEC.md +125 -0
  17. package/.blueprint/features/feature_split-cli-commands/IMPLEMENTATION_PLAN.md +119 -0
  18. package/.blueprint/features/feature_split-cli-commands/handoff-nigel.md +45 -0
  19. package/.blueprint/features/feature_theme-adoption/FEATURE_SPEC.md +143 -0
  20. package/.blueprint/features/feature_theme-adoption/IMPLEMENTATION_PLAN.md +68 -0
  21. package/.blueprint/features/feature_theme-adoption/handoff-nigel.md +35 -0
  22. package/.blueprint/templates/BACKLOG_TEMPLATE.md +46 -0
  23. package/README.md +26 -10
  24. package/SKILL.md +377 -3
  25. package/bin/cli.js +20 -384
  26. package/package.json +1 -1
  27. package/src/commands/feedback-config.js +32 -0
  28. package/src/commands/help.js +81 -0
  29. package/src/commands/history.js +42 -0
  30. package/src/commands/init.js +12 -0
  31. package/src/commands/insights.js +23 -0
  32. package/src/commands/murm-config.js +52 -0
  33. package/src/commands/murm.js +109 -0
  34. package/src/commands/queue.js +19 -0
  35. package/src/commands/retry-config.js +28 -0
  36. package/src/commands/stack-config.js +32 -0
  37. package/src/commands/update.js +12 -0
  38. package/src/commands/utils.js +24 -0
  39. package/src/commands/validate.js +15 -0
  40. package/src/config-factory.js +190 -0
  41. package/src/feedback.js +5 -2
  42. package/src/history.js +92 -1
  43. package/src/init.js +1 -15
  44. package/src/insights.js +19 -16
  45. package/src/retry.js +5 -2
  46. package/src/stack.js +4 -1
  47. package/src/theme.js +4 -4
  48. package/src/update.js +2 -15
  49. package/src/utils.js +26 -0
  50. package/src/validate.js +5 -12
@@ -8,6 +8,7 @@ inputs:
8
8
  outputs:
9
9
  - feature_spec
10
10
  - system_spec
11
+ - feature_backlog
11
12
  ---
12
13
 
13
14
  # Agent: Alex — System Specification & Chief-of-Staff
@@ -74,7 +75,36 @@ Once drafted, the feature specification is handed to **Cass** for user story ela
74
75
 
75
76
  ---
76
77
 
77
- ### 3. Living Collaboration with Cass (BA)
78
+ ### 3. Feature Backlog Ownership
79
+
80
+ Alex owns the **Feature Backlog** at `.blueprint/features/BACKLOG.md` — a prioritised list of features ready for implementation.
81
+
82
+ **Template:** `.blueprint/templates/BACKLOG_TEMPLATE.md`
83
+
84
+ **Format (token-efficient table):**
85
+ ```markdown
86
+ | Status | P | E | Slug | Description |
87
+ |--------|---|---|------|-------------|
88
+ | ⏳ | P1 | M | user-auth | Login and registration flow |
89
+ ```
90
+
91
+ **When to create/update:**
92
+ - After creating a system spec — propose initial feature breakdown
93
+ - After completing a feature — pipeline removes entry automatically
94
+ - When scope changes — reprioritise and update descriptions
95
+
96
+ **Prioritisation criteria:**
97
+ - Business value and user impact
98
+ - Dependencies (what must come first?)
99
+ - Technical risk (surface unknowns early)
100
+
101
+ **Status icons:** ⏳ ready, 🚧 in progress, ❓ needs clarification
102
+
103
+ Alex keeps the backlog aligned with the system specification. If a proposed feature contradicts the system design, Alex flags it rather than adding it silently.
104
+
105
+ ---
106
+
107
+ ### 4. Living Collaboration with Cass (BA)
78
108
  Alex and Cass operate in a **continuous, collaborative loop**:
79
109
  - Cass may query, challenge, or request refinement of a specification before writing stories
80
110
  - Alex clarifies intent, resolves ambiguities, or adjusts the specification where appropriate
@@ -89,7 +119,7 @@ Alex does **not** silently accept spec drift.
89
119
 
90
120
  ---
91
121
 
92
- ### 4. Conceptual Coherence Guardian (Hover Mode)
122
+ ### 5. Conceptual Coherence Guardian (Hover Mode)
93
123
  After initial specification and story creation, Alex remains active as a **conceptual coherence guardian**.
94
124
 
95
125
  Alex reacts to:
@@ -109,7 +139,7 @@ When meaningful change is detected, Alex:
109
139
 
110
140
  ---
111
141
 
112
- ### 5. Managing Evolution & Breaking Change Proposals
142
+ ### 6. Managing Evolution & Breaking Change Proposals
113
143
  When a feature exposes a flaw or limitation in the system specification:
114
144
  - Alex may propose a **breaking or structural change** to the system spec
115
145
  - Alex must clearly articulate:
@@ -0,0 +1,138 @@
1
+ # Feature Specification — Config Factory
2
+
3
+ ## 1. Feature Intent
4
+ **Why this feature exists.**
5
+
6
+ - Four config modules (retry, feedback, murm, stack) share identical patterns
7
+ - Each implements: `getDefaultConfig()`, `readConfig()`, `writeConfig()`, `displayConfig()`, `setConfigValue()`, `resetConfig()`
8
+ - ~80 lines of boilerplate duplicated 4 times (~320 lines total)
9
+ - Inconsistent validation and error handling across modules
10
+ - Adding a new config module requires copying boilerplate
11
+
12
+ > Technical refactoring feature — consolidate to a factory pattern.
13
+
14
+ ---
15
+
16
+ ## 2. Scope
17
+ ### In Scope
18
+ - Create `src/config-factory.js` with `createConfigModule(options)` factory
19
+ - Refactor retry.js, feedback.js, stack.js to use the factory
20
+ - Refactor murm.js config functions to use the factory
21
+ - Standardize validation, error messages, and display formatting
22
+ - Preserve all existing config behaviour exactly
23
+
24
+ ### Out of Scope
25
+ - Adding new config modules
26
+ - Changing config file locations or formats
27
+ - Modifying default values
28
+ - Adding new config keys
29
+
30
+ ---
31
+
32
+ ## 3. Actors Involved
33
+ **Who interacts with this feature.**
34
+
35
+ - **Developer**: Creates new config modules with minimal boilerplate
36
+ - **CLI User**: No change in experience — all config commands work identically
37
+
38
+ ---
39
+
40
+ ## 4. Behaviour Overview
41
+ **What the feature does, conceptually.**
42
+
43
+ The factory creates a config module with standard methods:
44
+
45
+ ```javascript
46
+ const myConfig = createConfigModule({
47
+ name: 'my-config',
48
+ file: '.claude/my-config.json',
49
+ defaults: { key1: 'value1', key2: 42 },
50
+ validators: {
51
+ key1: (v) => typeof v === 'string',
52
+ key2: (v) => Number.isInteger(v) && v > 0
53
+ },
54
+ formatters: {
55
+ key2: (v) => `${v} items`
56
+ }
57
+ });
58
+
59
+ // Returns: { read, write, reset, display, setValue, getDefault, CONFIG_FILE }
60
+ ```
61
+
62
+ Each existing config module becomes a thin wrapper calling the factory.
63
+
64
+ ---
65
+
66
+ ## 5. State & Lifecycle Interactions
67
+ **How this feature touches the system lifecycle.**
68
+
69
+ - No state changes — pure refactoring
70
+ - Config files remain in same locations
71
+ - No runtime behaviour differences
72
+
73
+ ---
74
+
75
+ ## 6. Rules & Decision Logic
76
+ **New or exercised rules.**
77
+
78
+ | Rule | Description |
79
+ |------|-------------|
80
+ | Default merging | Factory merges missing keys from defaults on read |
81
+ | Validation | Factory validates values before write using validators map |
82
+ | Display format | Factory uses formatters map or falls back to default display |
83
+ | Error messages | Standardized format: `Invalid value for {key}: {value}. {reason}` |
84
+ | Array handling | Arrays validated and displayed consistently (JSON parse for set) |
85
+
86
+ ---
87
+
88
+ ## 7. Dependencies
89
+ **What this feature relies on.**
90
+
91
+ - Node.js `fs` module (already used)
92
+ - No new external dependencies
93
+
94
+ ---
95
+
96
+ ## 8. Non-Functional Considerations
97
+
98
+ - **Code reduction**: ~200+ lines removed across 4 modules
99
+ - **Consistency**: Identical error messages and validation across all configs
100
+ - **Extensibility**: New config modules require ~10 lines instead of ~80
101
+
102
+ ---
103
+
104
+ ## 9. Assumptions & Open Questions
105
+
106
+ **Assumptions:**
107
+ - All four config modules can use the same factory pattern
108
+ - Specialized validation (like feedback's issueMappings) can be handled via validators
109
+
110
+ **Open Questions:**
111
+ - Should murm.js config functions be split to a separate file or remain inline?
112
+ - Should the factory support nested config objects (like retry's `strategies`)?
113
+
114
+ ---
115
+
116
+ ## 10. Impact on System Specification
117
+
118
+ - No impact — internal refactoring only
119
+ - Public APIs of all config modules remain unchanged
120
+
121
+ ---
122
+
123
+ ## 11. Handover to BA (Cass)
124
+
125
+ **Skip Cass stage** — this is a technical refactoring feature with no user stories needed.
126
+
127
+ Direct handover to Nigel for test creation:
128
+ - Tests should verify all config commands work after refactoring
129
+ - Tests should verify validation errors are consistent
130
+ - Tests should verify display output format is preserved
131
+ - Tests should verify default values are unchanged
132
+
133
+ ---
134
+
135
+ ## 12. Change Log (Feature-Level)
136
+ | Date | Change | Reason | Raised By |
137
+ |------|--------|--------|-----------|
138
+ | 2026-03-03 | Initial spec | DRY up config modules | Alex |
@@ -0,0 +1,187 @@
1
+ # Implementation Plan: Config Factory
2
+
3
+ ## Overview
4
+ Create a factory function to eliminate ~320 lines of duplicated boilerplate across four config modules (retry.js, feedback.js, stack.js, murm.js).
5
+
6
+ ## Step 1: Create `src/config-factory.js`
7
+
8
+ Create the factory module with the following structure:
9
+
10
+ ```js
11
+ function createConfigModule(options) {
12
+ const { name, file, defaults, validators = {}, formatters = {}, arrayKeys = [] } = options;
13
+
14
+ return {
15
+ CONFIG_FILE: file,
16
+ getDefault: () => ({ ...defaults }),
17
+ read: () => { /* merge defaults, handle errors */ },
18
+ write: (config) => { /* ensure dir, write JSON */ },
19
+ reset: () => { /* write defaults */ },
20
+ setValue: (key, value) => { /* validate, write */ },
21
+ display: () => { /* format and log */ }
22
+ };
23
+ }
24
+ ```
25
+
26
+ ### Factory Methods Detail
27
+
28
+ | Method | Behavior |
29
+ |--------|----------|
30
+ | `getDefault()` | Return shallow copy of defaults |
31
+ | `read()` | Return defaults if missing/corrupted, merge missing keys |
32
+ | `write(config)` | Create dir if needed, write JSON with 2-space indent |
33
+ | `reset()` | Call write(getDefault()) |
34
+ | `setValue(key, value)` | Validate key exists, parse arrays, run validator, write |
35
+ | `display()` | Log name header, iterate keys with formatters |
36
+
37
+ ### Validation Logic
38
+ ```js
39
+ setValue(key, value) {
40
+ if (!(key in defaults)) throw Error(`Unknown config key: ${key}. Valid keys: ...`);
41
+
42
+ let parsed = value;
43
+ if (arrayKeys.includes(key)) {
44
+ parsed = JSON.parse(value); // throws on invalid
45
+ if (!Array.isArray(parsed)) throw Error(`${key} must be a JSON array`);
46
+ } else if (typeof defaults[key] === 'number') {
47
+ parsed = parseFloat(value);
48
+ } else if (typeof defaults[key] === 'boolean') {
49
+ parsed = value === 'true';
50
+ }
51
+
52
+ if (validators[key]) {
53
+ const result = validators[key](parsed);
54
+ if (result !== true) {
55
+ throw Error(`Invalid value for ${key}: ${value}. ${result}`);
56
+ }
57
+ }
58
+
59
+ const config = read();
60
+ config[key] = parsed;
61
+ write(config);
62
+ }
63
+ ```
64
+
65
+ ## Step 2: Refactor retry.js
66
+
67
+ Keep existing business logic functions (calculateFailureRate, recommendStrategy, etc.).
68
+ Replace config boilerplate with factory:
69
+
70
+ ```js
71
+ const { createConfigModule } = require('./config-factory');
72
+
73
+ const configModule = createConfigModule({
74
+ name: 'Retry',
75
+ file: '.claude/retry-config.json',
76
+ defaults: {
77
+ maxRetries: 3,
78
+ windowSize: 10,
79
+ highFailureThreshold: 0.2,
80
+ strategies: { /* ... */ }
81
+ },
82
+ validators: {
83
+ maxRetries: (v) => Number.isInteger(v) && v >= 0 ? true : 'must be a non-negative integer',
84
+ windowSize: (v) => Number.isInteger(v) && v >= 1 ? true : 'must be a positive integer',
85
+ highFailureThreshold: (v) => v >= 0 && v <= 1 ? true : 'must be between 0 and 1'
86
+ }
87
+ });
88
+
89
+ // Re-export with same names for backward compatibility
90
+ const {
91
+ CONFIG_FILE,
92
+ getDefault: getDefaultConfig,
93
+ read: readConfig,
94
+ write: writeConfig,
95
+ reset: resetConfig,
96
+ display: displayConfig,
97
+ setValue: setConfigValue
98
+ } = configModule;
99
+ ```
100
+
101
+ ## Step 3: Refactor feedback.js
102
+
103
+ Similar pattern. Keep validateFeedback, shouldPause, parseFeedbackFromOutput, normalizeFeedbackKeys.
104
+
105
+ ```js
106
+ const configModule = createConfigModule({
107
+ name: 'Feedback',
108
+ file: '.claude/feedback-config.json',
109
+ defaults: {
110
+ minRatingThreshold: 3.0,
111
+ enabled: true,
112
+ issueMappings: { /* ... */ }
113
+ },
114
+ validators: {
115
+ minRatingThreshold: (v) => v >= 1.0 && v <= 5.0 ? true : 'must be between 1.0 and 5.0',
116
+ enabled: (v) => typeof v === 'boolean' ? true : 'must be true or false'
117
+ }
118
+ });
119
+ ```
120
+
121
+ ## Step 4: Refactor stack.js
122
+
123
+ Keep detectStackConfig. Note: stack uses `*StackConfig` naming convention.
124
+
125
+ ```js
126
+ const configModule = createConfigModule({
127
+ name: 'Stack',
128
+ file: '.claude/stack-config.json',
129
+ defaults: {
130
+ language: '', runtime: '', packageManager: '',
131
+ frameworks: [], testRunner: '', testCommand: '',
132
+ linter: '', tools: []
133
+ },
134
+ arrayKeys: ['frameworks', 'tools']
135
+ });
136
+
137
+ // Alias exports with Stack suffix for backward compatibility
138
+ const getDefaultStackConfig = configModule.getDefault;
139
+ const readStackConfig = configModule.read;
140
+ // etc.
141
+ ```
142
+
143
+ ## Step 5: Refactor murm.js Config Functions
144
+
145
+ Murm.js has additional complexity (migrations, special merge logic). Keep using factory for core operations but preserve migration logic.
146
+
147
+ ```js
148
+ const configModule = createConfigModule({
149
+ name: 'Murmuration',
150
+ file: '.claude/murm-config.json',
151
+ defaults: {
152
+ maxConcurrency: 3, maxFeatures: 10, timeout: 30,
153
+ minDiskSpaceMB: 500, cli: 'npx claude',
154
+ skill: '/implement-feature', skillFlags: '--no-commit',
155
+ worktreeDir: '.claude/worktrees', queueFile: '.claude/murm-queue.json'
156
+ },
157
+ validators: {
158
+ maxConcurrency: (v) => Number.isInteger(v) && v >= 1 ? true : 'must be a positive integer',
159
+ timeout: (v) => Number.isInteger(v) && v >= 1 ? true : 'must be a positive integer'
160
+ },
161
+ formatters: {
162
+ timeout: (v) => `${v} min`
163
+ }
164
+ });
165
+ ```
166
+
167
+ Note: readMurmConfig needs to preserve migration logic for legacy files.
168
+
169
+ ## Step 6: Run Tests
170
+
171
+ ```bash
172
+ node --test test/feature_config-factory.test.js
173
+ ```
174
+
175
+ Fix any failures, iterate until all 19 tests pass.
176
+
177
+ ## Files Modified
178
+ - `src/config-factory.js` (new)
179
+ - `src/retry.js` (refactored)
180
+ - `src/feedback.js` (refactored)
181
+ - `src/stack.js` (refactored)
182
+ - `src/murm.js` (refactored config functions)
183
+
184
+ ## Risk Mitigation
185
+ - All existing exports preserved with same names
186
+ - Business logic functions untouched
187
+ - Tests verify backward compatibility
@@ -0,0 +1,57 @@
1
+ # Nigel Handoff: Config Factory
2
+
3
+ ## Summary
4
+ Created test suite for the config-factory feature with 19 test cases covering:
5
+ - Factory core functions (7 tests)
6
+ - Validation (5 tests)
7
+ - Display formatting (3 tests)
8
+ - Backward compatibility (4 tests)
9
+ - Error message consistency (2 tests)
10
+
11
+ ## Test Files Created
12
+ - `test/artifacts/feature_config-factory/test-spec.md` - Test mapping document
13
+ - `test/feature_config-factory.test.js` - Executable test file
14
+
15
+ ## Key Test Coverage
16
+
17
+ ### Factory API
18
+ - Factory returns: read, write, reset, display, setValue, getDefault, CONFIG_FILE
19
+ - getDefault returns provided defaults unchanged
20
+ - read handles missing/corrupted files gracefully
21
+ - read merges missing keys from defaults
22
+ - write/reset operations
23
+
24
+ ### Validation System
25
+ - Validators map prevents invalid values
26
+ - Array keys parsed from JSON strings
27
+ - Unknown keys rejected with helpful error
28
+
29
+ ### Backward Compatibility
30
+ - retry.js exports unchanged
31
+ - feedback.js exports unchanged
32
+ - stack.js (with Stack prefix) exports unchanged
33
+ - murm.js config functions unchanged
34
+
35
+ ## Implementation Notes for Codey
36
+
37
+ 1. **Create `src/config-factory.js`** with `createConfigModule(options)` factory
38
+ 2. **Options object shape**:
39
+ ```js
40
+ {
41
+ name: string, // Config name for display
42
+ file: string, // Path like '.claude/foo.json'
43
+ defaults: object, // Default config values
44
+ validators?: object, // Key -> validator function
45
+ formatters?: object, // Key -> display formatter
46
+ arrayKeys?: string[] // Keys that accept JSON array values
47
+ }
48
+ ```
49
+ 3. **Validator functions** return `true` for valid, or error string for invalid
50
+ 4. **Error format**: `Invalid value for {key}: {value}. {reason}`
51
+ 5. **Refactor existing modules** to use factory while preserving all exports
52
+
53
+ ## Running Tests
54
+ ```bash
55
+ cd .claude/worktrees/feat-config-factory
56
+ node --test test/feature_config-factory.test.js
57
+ ```
@@ -0,0 +1,215 @@
1
+ # Feature Specification — Export Pipeline History
2
+
3
+ ## 1. Feature Intent
4
+
5
+ **Why this feature exists.**
6
+
7
+ Users need to extract pipeline history data for analysis, reporting, and integration with external tools. The existing `history` and `insights` commands provide on-demand viewing, but teams often require:
8
+
9
+ - **Spreadsheet analysis** — CSV export for pivot tables, charts, and ad-hoc queries
10
+ - **Custom dashboards** — JSON export for ingestion into monitoring tools or team portals
11
+ - **Filtered exports** — Ability to slice data by date range, status, or specific features
12
+
13
+ This feature supports the system purpose of **observability** (System Spec Section 8) by making pipeline execution data portable and actionable beyond the CLI.
14
+
15
+ ---
16
+
17
+ ## 2. Scope
18
+
19
+ ### In Scope
20
+
21
+ - New `export` subcommand under `murmur8 history`
22
+ - Export formats: CSV and JSON
23
+ - Filtering options: `--since`, `--until`, `--status`, `--feature`
24
+ - Output to stdout (default) or file via `--output`
25
+
26
+ ### Out of Scope
27
+
28
+ - Export of queue state (`.claude/implement-queue.json`) — separate concern
29
+ - Scheduled/automated exports — users can integrate via shell scripts
30
+ - Direct integration with external services (Slack, email, dashboards)
31
+ - Aggregated statistics export — `--stats` output remains display-only
32
+
33
+ ---
34
+
35
+ ## 3. Actors Involved
36
+
37
+ ### Human User
38
+
39
+ - **Can:** Export history data in CSV or JSON format, apply filters, redirect to file
40
+ - **Cannot:** Export queue state or insights aggregations through this command
41
+
42
+ ---
43
+
44
+ ## 4. Behaviour Overview
45
+
46
+ **Happy Path:**
47
+
48
+ 1. User runs `murmur8 history export --format=csv`
49
+ 2. System reads `.claude/pipeline-history.json`
50
+ 3. System converts entries to CSV format
51
+ 4. System outputs to stdout
52
+
53
+ **With Filters:**
54
+
55
+ 1. User runs `murmur8 history export --format=json --since=2024-01-01 --status=failed`
56
+ 2. System reads history, filters by date and status
57
+ 3. System outputs filtered JSON to stdout
58
+
59
+ **To File:**
60
+
61
+ 1. User runs `murmur8 history export --format=csv --output=report.csv`
62
+ 2. System writes CSV to specified file
63
+ 3. System prints confirmation message
64
+
65
+ **Edge Cases:**
66
+
67
+ - Empty history: Output empty array/CSV header with no data rows
68
+ - Corrupted history file: Warn and exit with non-zero status
69
+ - No matches for filters: Output empty result (not an error)
70
+ - Invalid date format: Error with usage hint
71
+
72
+ ---
73
+
74
+ ## 5. State & Lifecycle Interactions
75
+
76
+ This feature is **state-reading only**. It does not modify pipeline state.
77
+
78
+ - **Reads:** `.claude/pipeline-history.json`
79
+ - **Does not modify:** Any state files or artifacts
80
+
81
+ ---
82
+
83
+ ## 6. Rules & Decision Logic
84
+
85
+ ### Format Selection Rule
86
+
87
+ | `--format` value | Output |
88
+ |------------------|--------|
89
+ | `csv` (default) | Comma-separated values with header row |
90
+ | `json` | Pretty-printed JSON array |
91
+
92
+ ### Date Filtering Rules
93
+
94
+ - `--since=YYYY-MM-DD`: Include entries where `completedAt >= since`
95
+ - `--until=YYYY-MM-DD`: Include entries where `completedAt <= until`
96
+ - Both can be combined for a range
97
+ - Dates are interpreted as start of day (00:00:00) in local timezone
98
+
99
+ ### Status Filtering Rule
100
+
101
+ - `--status=success|failed|paused`: Include only entries with matching status
102
+ - Multiple values not supported in v1 (e.g., no `--status=success,failed`)
103
+
104
+ ### Feature Filtering Rule
105
+
106
+ - `--feature=<slug>`: Include only entries matching the feature slug
107
+ - Exact match (not substring)
108
+
109
+ ### Output Destination Rule
110
+
111
+ - No `--output`: Write to stdout
112
+ - `--output=<path>`: Write to file, creating parent directories if needed
113
+
114
+ ---
115
+
116
+ ## 7. Dependencies
117
+
118
+ ### System Components
119
+
120
+ - `src/history.js` — Existing `readHistoryFile()` function for reading history
121
+ - `src/theme.js` — Optional colorization for confirmation messages
122
+
123
+ ### Data Format
124
+
125
+ Relies on existing history entry structure:
126
+
127
+ ```javascript
128
+ {
129
+ slug: string,
130
+ status: 'success' | 'failed' | 'paused',
131
+ startedAt: ISO8601,
132
+ completedAt: ISO8601,
133
+ totalDurationMs: number,
134
+ stages: { [stage]: { durationMs, feedback? } },
135
+ failedStage?: string,
136
+ pausedAfter?: string
137
+ }
138
+ ```
139
+
140
+ ---
141
+
142
+ ## 8. Non-Functional Considerations
143
+
144
+ ### Performance
145
+
146
+ - History files are typically small (<1MB). No streaming required for v1.
147
+ - If performance becomes an issue with large histories, consider streaming JSON output.
148
+
149
+ ### Error Handling
150
+
151
+ - Invalid date format: Exit with code 1, print usage hint
152
+ - Missing history file: Treat as empty (not an error)
153
+ - Corrupted history file: Exit with code 1, suggest `history clear`
154
+ - File write error: Exit with code 1 with descriptive message
155
+
156
+ ---
157
+
158
+ ## 9. Assumptions & Open Questions
159
+
160
+ ### Assumptions
161
+
162
+ - History file structure is stable (no migration needed)
163
+ - Users have write permissions for `--output` destination
164
+ - Date parsing uses native JavaScript Date (ISO 8601 format expected)
165
+
166
+ ### Open Questions
167
+
168
+ - **Q:** Should we support `--limit` to cap exported rows?
169
+ - **A:** Defer to v2. Users can pipe to `head` for now.
170
+ - **Q:** Should CSV include nested stage data?
171
+ - **A:** v1 exports top-level fields only. Stage details available in JSON.
172
+
173
+ ---
174
+
175
+ ## 10. Impact on System Specification
176
+
177
+ This feature **reinforces** existing system assumptions:
178
+
179
+ - Aligns with observability cross-cutting concern (System Spec Section 8)
180
+ - Builds on existing history module without modifying its behavior
181
+ - Does not introduce new state, lifecycle, or invariant changes
182
+
183
+ No system spec changes required.
184
+
185
+ ---
186
+
187
+ ## 11. Handover to BA (Cass)
188
+
189
+ ### Story Themes
190
+
191
+ 1. **Basic Export** — Export history to CSV or JSON format
192
+ 2. **Date Filtering** — Filter exports by date range
193
+ 3. **Status Filtering** — Filter exports by pipeline status
194
+ 4. **Feature Filtering** — Filter exports by feature slug
195
+ 5. **File Output** — Write exports to a file instead of stdout
196
+
197
+ ### Expected Story Boundaries
198
+
199
+ - Each filter type should be a separate story for independent testing
200
+ - File output can be combined with basic export
201
+ - Error handling can be implicit in each story's acceptance criteria
202
+
203
+ ### Areas Needing Careful Story Framing
204
+
205
+ - CSV field ordering and escaping rules (commas, quotes in slugs)
206
+ - Empty result behavior (should still output valid CSV/JSON structure)
207
+ - Date parsing edge cases (timezone handling, invalid formats)
208
+
209
+ ---
210
+
211
+ ## 12. Change Log (Feature-Level)
212
+
213
+ | Date | Change | Reason | Raised By |
214
+ |------|--------|--------|-----------|
215
+ | 2026-03-03 | Initial feature specification | Implement export-history from backlog | Alex |