openplanr 1.21.2 → 1.23.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 (132) hide show
  1. package/CHANGELOG.md +1388 -0
  2. package/dist/cli/commands/config.d.ts.map +1 -1
  3. package/dist/cli/commands/config.js +52 -0
  4. package/dist/cli/commands/config.js.map +1 -1
  5. package/dist/cli/commands/doctor.d.ts.map +1 -1
  6. package/dist/cli/commands/doctor.js +11 -1
  7. package/dist/cli/commands/doctor.js.map +1 -1
  8. package/dist/cli/commands/operate.d.ts.map +1 -1
  9. package/dist/cli/commands/operate.js +91 -2
  10. package/dist/cli/commands/operate.js.map +1 -1
  11. package/dist/cli/commands/upgrade.d.ts +9 -0
  12. package/dist/cli/commands/upgrade.d.ts.map +1 -0
  13. package/dist/cli/commands/upgrade.js +149 -0
  14. package/dist/cli/commands/upgrade.js.map +1 -0
  15. package/dist/cli/index.js +28 -2
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/models/schema.d.ts +12 -0
  18. package/dist/models/schema.d.ts.map +1 -1
  19. package/dist/models/schema.js +9 -0
  20. package/dist/models/schema.js.map +1 -1
  21. package/dist/models/types.d.ts +8 -0
  22. package/dist/models/types.d.ts.map +1 -1
  23. package/dist/services/claude-plugin-service.d.ts +9 -0
  24. package/dist/services/claude-plugin-service.d.ts.map +1 -1
  25. package/dist/services/claude-plugin-service.js +22 -0
  26. package/dist/services/claude-plugin-service.js.map +1 -1
  27. package/dist/services/migration-registry.d.ts +94 -0
  28. package/dist/services/migration-registry.d.ts.map +1 -0
  29. package/dist/services/migration-registry.js +106 -0
  30. package/dist/services/migration-registry.js.map +1 -0
  31. package/dist/services/operate/advisors.d.ts +63 -0
  32. package/dist/services/operate/advisors.d.ts.map +1 -1
  33. package/dist/services/operate/advisors.js +68 -4
  34. package/dist/services/operate/advisors.js.map +1 -1
  35. package/dist/services/operate/artifacts.d.ts +9 -3
  36. package/dist/services/operate/artifacts.d.ts.map +1 -1
  37. package/dist/services/operate/artifacts.js +126 -5
  38. package/dist/services/operate/artifacts.js.map +1 -1
  39. package/dist/services/operate/citation-resolution.d.ts +14 -0
  40. package/dist/services/operate/citation-resolution.d.ts.map +1 -1
  41. package/dist/services/operate/citation-resolution.js +9 -0
  42. package/dist/services/operate/citation-resolution.js.map +1 -1
  43. package/dist/services/operate/completion.d.ts +80 -0
  44. package/dist/services/operate/completion.d.ts.map +1 -0
  45. package/dist/services/operate/completion.js +279 -0
  46. package/dist/services/operate/completion.js.map +1 -0
  47. package/dist/services/operate/config.d.ts +7 -0
  48. package/dist/services/operate/config.d.ts.map +1 -1
  49. package/dist/services/operate/config.js +7 -0
  50. package/dist/services/operate/config.js.map +1 -1
  51. package/dist/services/operate/context-research.d.ts +43 -0
  52. package/dist/services/operate/context-research.d.ts.map +1 -1
  53. package/dist/services/operate/context-research.js +219 -1
  54. package/dist/services/operate/context-research.js.map +1 -1
  55. package/dist/services/operate/decision-brief.d.ts +90 -1
  56. package/dist/services/operate/decision-brief.d.ts.map +1 -1
  57. package/dist/services/operate/decision-brief.js +175 -1
  58. package/dist/services/operate/decision-brief.js.map +1 -1
  59. package/dist/services/operate/doctor.d.ts +58 -0
  60. package/dist/services/operate/doctor.d.ts.map +1 -1
  61. package/dist/services/operate/doctor.js +395 -21
  62. package/dist/services/operate/doctor.js.map +1 -1
  63. package/dist/services/operate/engine.d.ts +75 -2
  64. package/dist/services/operate/engine.d.ts.map +1 -1
  65. package/dist/services/operate/engine.js +504 -33
  66. package/dist/services/operate/engine.js.map +1 -1
  67. package/dist/services/operate/event-store.d.ts +22 -0
  68. package/dist/services/operate/event-store.d.ts.map +1 -1
  69. package/dist/services/operate/event-store.js +35 -0
  70. package/dist/services/operate/event-store.js.map +1 -1
  71. package/dist/services/operate/evidence-cache.d.ts.map +1 -1
  72. package/dist/services/operate/evidence-cache.js +41 -5
  73. package/dist/services/operate/evidence-cache.js.map +1 -1
  74. package/dist/services/operate/index.d.ts.map +1 -1
  75. package/dist/services/operate/index.js +98 -1
  76. package/dist/services/operate/index.js.map +1 -1
  77. package/dist/services/operate/interaction/question-engine.d.ts.map +1 -1
  78. package/dist/services/operate/interaction/question-engine.js +36 -8
  79. package/dist/services/operate/interaction/question-engine.js.map +1 -1
  80. package/dist/services/operate/interaction/question-registry.d.ts +8 -0
  81. package/dist/services/operate/interaction/question-registry.d.ts.map +1 -1
  82. package/dist/services/operate/interaction/question-registry.js +21 -2
  83. package/dist/services/operate/interaction/question-registry.js.map +1 -1
  84. package/dist/services/operate/lifecycle-driver.d.ts +309 -0
  85. package/dist/services/operate/lifecycle-driver.d.ts.map +1 -0
  86. package/dist/services/operate/lifecycle-driver.js +434 -0
  87. package/dist/services/operate/lifecycle-driver.js.map +1 -0
  88. package/dist/services/operate/maintenance.d.ts +65 -1
  89. package/dist/services/operate/maintenance.d.ts.map +1 -1
  90. package/dist/services/operate/maintenance.js +718 -24
  91. package/dist/services/operate/maintenance.js.map +1 -1
  92. package/dist/services/operate/mission-dispatch.d.ts +61 -1
  93. package/dist/services/operate/mission-dispatch.d.ts.map +1 -1
  94. package/dist/services/operate/mission-dispatch.js +78 -5
  95. package/dist/services/operate/mission-dispatch.js.map +1 -1
  96. package/dist/services/operate/profile-migration.d.ts +69 -0
  97. package/dist/services/operate/profile-migration.d.ts.map +1 -0
  98. package/dist/services/operate/profile-migration.js +462 -0
  99. package/dist/services/operate/profile-migration.js.map +1 -0
  100. package/dist/services/operate/projection-persistence.d.ts.map +1 -1
  101. package/dist/services/operate/projection-persistence.js +24 -5
  102. package/dist/services/operate/projection-persistence.js.map +1 -1
  103. package/dist/services/operate/projection.d.ts.map +1 -1
  104. package/dist/services/operate/projection.js +9 -0
  105. package/dist/services/operate/projection.js.map +1 -1
  106. package/dist/services/operate/protocol.d.ts +1 -0
  107. package/dist/services/operate/protocol.d.ts.map +1 -1
  108. package/dist/services/operate/protocol.js.map +1 -1
  109. package/dist/services/operate/scratch.d.ts +81 -0
  110. package/dist/services/operate/scratch.d.ts.map +1 -0
  111. package/dist/services/operate/scratch.js +190 -0
  112. package/dist/services/operate/scratch.js.map +1 -0
  113. package/dist/services/operate/types.d.ts +3 -2
  114. package/dist/services/operate/types.d.ts.map +1 -1
  115. package/dist/services/operate/types.js.map +1 -1
  116. package/dist/services/operate/workspace.d.ts +1 -0
  117. package/dist/services/operate/workspace.d.ts.map +1 -1
  118. package/dist/services/operate/workspace.js +2 -0
  119. package/dist/services/operate/workspace.js.map +1 -1
  120. package/dist/services/runtime-manager-service.d.ts +49 -0
  121. package/dist/services/runtime-manager-service.d.ts.map +1 -1
  122. package/dist/services/runtime-manager-service.js +69 -5
  123. package/dist/services/runtime-manager-service.js.map +1 -1
  124. package/dist/services/upgrade-offer-service.d.ts +89 -0
  125. package/dist/services/upgrade-offer-service.d.ts.map +1 -0
  126. package/dist/services/upgrade-offer-service.js +256 -0
  127. package/dist/services/upgrade-offer-service.js.map +1 -0
  128. package/dist/services/upgrade-service.d.ts +156 -0
  129. package/dist/services/upgrade-service.d.ts.map +1 -0
  130. package/dist/services/upgrade-service.js +510 -0
  131. package/dist/services/upgrade-service.js.map +1 -0
  132. package/package.json +3 -2
package/CHANGELOG.md ADDED
@@ -0,0 +1,1388 @@
1
+ # Changelog
2
+
3
+ ## 1.23.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`4353b7d`](https://github.com/openplanr/OpenPlanr/commit/4353b7d727cf5312ee684eb4dc96252ccc9f5f43) Installed-tuple reconciliation and a safe, honest upgrade path (SPEC-006).
8
+
9
+ Until now the CLI could tell you your install had drifted and then leave you to
10
+ derive the fix yourself across two package managers. `doctor` already computed
11
+ component, digest, adapter, and CLI drift correctly — nothing acted on it, and
12
+ nothing read back the compatibility ranges the ecosystem manifest already
13
+ publishes.
14
+
15
+ **Reconcile the installed tuple, not "is something newer".** A new
16
+ `planr upgrade status [--json]` reads the published compatibility manifest,
17
+ compares it against the real installed tuple — this CLI plus both host-plugin
18
+ versions — and reports `aligned`, `upgrade-available`, `incompatible`, or
19
+ `unknown`. The warn-versus-fail distinction is not re-derived: `doctor`'s inline
20
+ lock-drift classification is extracted into a single exported
21
+ `classifyComponentDrift` that both surfaces call, so a CLI merely trailing an
22
+ upgrade stays a warning while a genuinely incompatible tuple fails. Every
23
+ pre-existing `doctor` assertion passes unchanged as proof the extraction
24
+ preserved its behaviour. An absent plugin is recorded as absent, never as a
25
+ violation, so a planning-only install does not read as broken.
26
+
27
+ **Offline capability is preserved by construction.** The manifest fetch trusts a
28
+ short-TTL cache without any network round-trip, carries a hard timeout that wins
29
+ even when a fetch hangs, falls back to a stale cache when the network fails, and
30
+ reports `unknown` when there is neither — so a captive portal, a VPN, or an
31
+ airplane can never make `planr` block. Proven by offline and hung-network tests
32
+ and by a packed-install end-to-end test that reads the real installed version
33
+ rather than a fixture.
34
+
35
+ **Execute the half it owns; prescribe the half it cannot.**
36
+ `planr upgrade apply [--yes] [--json]` performs `npm install -g openplanr@<target>`
37
+ and prints the plugin commands it structurally cannot run — plugin installation is
38
+ a host command, not something a CLI can own. The prescription is rendered from the
39
+ plugin integration's own operation list, so the printed commands can never drift
40
+ from what an apply would really run, and the marketplace-refresh command is always
41
+ placed first: without it the installer reinstalls the stale version and the user
42
+ believes they upgraded. A grep gate proves the upgrade service never imports the
43
+ plugin-apply path, and an end-to-end test proves no mutating plugin command is
44
+ ever spawned.
45
+
46
+ **A partially-upgraded install can never report success.** The previously
47
+ installed version is captured as a restorable backup before any mutation, and the
48
+ on-disk version is re-read afterwards. A clean exit that did not land the target
49
+ restores the previous version automatically and states exactly what was restored
50
+ and how to retry. On success, the changelog entries strictly between the old and
51
+ new version are summarised verbatim — never inventing a change the changelog does
52
+ not carry — and `CHANGELOG.md` now ships in the package so that summary works on a
53
+ real installation rather than only in-repo.
54
+
55
+ **The offer comes to you.** An available upgrade now surfaces on an ordinary
56
+ interactive command as a four-way choice — upgrade now · always keep me current ·
57
+ not now · never ask — so nobody has to run a diagnostic to discover they are
58
+ stale; accepting resumes the command you originally invoked. "Not now" snoozes
59
+ with escalating backoff (24 hours, then 48, then a week) so it never nags.
60
+ `auto_upgrade` and `update_check` are real settings, neither inferred from a bare
61
+ invocation, and "never ask again" is a permanent opt-out that always states the
62
+ exact command reversing it. A snooze, a never-ask, or a disabled check
63
+ short-circuits before any reconcile, so a command that already declined touches no
64
+ network and adds no delay; the state file is read fail-open, and the offer never
65
+ surfaces for machine-readable or non-interactive invocations.
66
+
67
+ **Upgrades can now carry state forward.** Idempotent migrations keyed to a version
68
+ run automatically when an upgrade crosses that version, for state a reinstall
69
+ cannot repair — stale config, orphaned files, a changed on-disk layout. A strict
70
+ lower bound means a migration at or below the installed version never re-runs, and
71
+ one migration failing neither aborts the others nor is swallowed into an overall
72
+ success. The legacy operating-profile migration is registered as the proving case
73
+ by delegating to the existing implementation, reusing its exact-backup, journalled
74
+ write with rollback, and idempotency guarantees rather than forking them; the
75
+ standalone `operate profiles migrate` command keeps working unchanged. A migration
76
+ failure reports failure while still reporting the npm step's real success, so a
77
+ half-migrated install can never claim to be clean.
78
+
79
+ ## 1.22.0
80
+
81
+ ### Minor Changes
82
+
83
+ - [`5b525e2`](https://github.com/openplanr/OpenPlanr/commit/5b525e29c4843535f68a013c4d658b91ad9ed0d6) Operate durable orchestration (SPEC-005): per-role durability, honest state, and a
84
+ one-invocation review gate. Bundled pipeline dependency pinned to
85
+ `planr-pipeline@0.39.0`. Every claim below is backed by a named passing test;
86
+ coordinated sibling releases still in flight under this same version are described
87
+ as landing with the release, never as a phase this repository has already verified.
88
+
89
+ **The field fix that matters most: the advisor fan-out no longer deadlocks on a
90
+ hung lens.** The pre-driver fan-out awaited every advisor together, so one lens
91
+ stalling left the whole `Promise.all` unresolved while completed analyses sat
92
+ unrecorded and the shared lease expired underneath them. Dispatch now runs through
93
+ a deterministic lifecycle driver with bounded per-role retry, a per-attempt
94
+ timeout, and an automatic lease heartbeat that renews independently of any role
95
+ recording. A stalled non-required lens is resolved `not_evaluated` with a governed
96
+ gap while its siblings record and the cycle reaches Chair. Proven by
97
+ `tests/integration/operate-lifecycle-chair-wiring.test.ts` ("terminates a stalled
98
+ lens not_evaluated while siblings record, renews the lease, and reaches Chair") and
99
+ `tests/unit/operate-lifecycle-driver.test.ts` ("resolves a role past its retry
100
+ budget to not_evaluated with a governed gap without blocking siblings" and "renews
101
+ the lease as the window approaches without any role completing").
102
+
103
+ **Immediate per-role commit and an engine-managed heartbeat lease.** Each advisor
104
+ result is validated, recorded, persisted, and reflected in cycle progress the
105
+ moment it returns, and survives a sibling stalling; recording never waits on the
106
+ batch. Proven by the lifecycle-driver state-machine and heartbeat suites in
107
+ `tests/unit/operate-lifecycle-driver.test.ts`.
108
+
109
+ **Partial validated progress and honest status/report.** Every recorded lens is
110
+ inspectable before Chair finalizes, and a mid-cycle report renders recorded lenses
111
+ with their real analysis plus the exact recovery action for pending roles — an
112
+ active advising cycle is never described as quiet. Proven by
113
+ `tests/integration/operate-partial-report.test.ts` ("renders recorded lenses with
114
+ their real analysis and the exact recovery action for pending roles").
115
+
116
+ **Chair works with partial valid boards.** Chair consolidates the recorded,
117
+ verified board and surfaces an absent lens as an explicit gap; it never invents a
118
+ missing lens's conclusions, and it stays closed while a structurally-required role
119
+ is only `not_evaluated`. Proven by `tests/unit/operate-lifecycle-driver.test.ts`
120
+ ("holds the Chair closed while a structurally-required role is only
121
+ not_evaluated") and the chair-wiring happy-path test above ("records a five-lens
122
+ board and reaches Chair with no fabricated gap on the happy path").
123
+
124
+ **Owned scratch storage with a `doctor --fix` cleanup.** Operate scratch lives
125
+ under an OpenPlanr-owned, project-and-machine-keyed path recorded in an ownership
126
+ manifest, cleaned automatically after record/finalize, detected by `doctor` when
127
+ abandoned, and removed by the FR7-named `planr doctor --fix` — which acts only on
128
+ scratch a valid ownership manifest confirms is ours, never on an unrelated file
129
+ under the scratch tree. Proven by `tests/unit/operate-doctor-staleness.test.ts`
130
+ ("warns on abandoned owned scratch and removes only it, leaving other
131
+ machine-local caches") and `tests/unit/operate-doctor-fix-wiring.test.ts`
132
+ ("removes abandoned OpenPlanr-owned scratch and leaves an unrelated file
133
+ untouched").
134
+
135
+ **Completion discipline.** Completion requires on-disk verification of every
136
+ phase-F artifact and flips to incomplete when any is removed or abandoned owned
137
+ scratch remains. Proven by `tests/unit/operate-completion.test.ts` ("reports
138
+ complete only with every phase-F artifact, and flips when any is removed").
139
+
140
+ **Legacy operating-profile migration.** `planr operate profiles migrate
141
+ inspect|apply` detects a legacy profile, previews and converts the supported
142
+ subset, writes an exact pre-migration backup, and is idempotent — the CLI never
143
+ suggests a profile it will reject. Proven by
144
+ `tests/unit/operate-profile-migration.test.ts` ("writes an exact pre-migration
145
+ backup and rewrites the profile to the supported subset" and "is idempotent: a
146
+ second apply reports already-applied and makes no further change").
147
+
148
+ **Bundled pipeline pin.** The packed CLI carries
149
+ `optionalDependencies.planr-pipeline = 0.39.0`, asserted by
150
+ `tests/e2e/operate-packed-install.test.ts` and
151
+ `tests/e2e/operate-guided-packed-install.test.ts`.
152
+
153
+ Coordinated, not yet released with this changeset: `@openplanr/skills@1.24.0`
154
+ (thin workflow regeneration) and the marketplace ledger and real-runtime canary
155
+ land only after `planr-pipeline@0.39.0` and this `openplanr` version publish.
156
+
157
+ ## 1.21.2
158
+
159
+ ### Patch Changes
160
+
161
+ - [`2bc31c4`](https://github.com/openplanr/OpenPlanr/commit/2bc31c48c46912f542c1a52a143492d81e013e48) Align the bundled pipeline dependency with planr-pipeline 0.38.0.
162
+
163
+ ## 1.21.1
164
+
165
+ ### Patch Changes
166
+
167
+ - [`3c1101b`](https://github.com/openplanr/OpenPlanr/commit/3c1101b6699d1b7f0bdaedce3a41f37941228811) Align the bundled pipeline with planr-pipeline 0.37.2 so released Operate canaries execute correctly through the Windows command shim.
168
+
169
+ ## 1.21.0
170
+
171
+ ### Minor Changes
172
+
173
+ - [`fd81cd9`](https://github.com/openplanr/OpenPlanr/commit/fd81cd94ca4a13c3b590544b242cf7fe21078824) Rebuild `planr operate` around agent-native, runtime-bound research, six advisory roles, expressive cited reports, and approval-gated canonical proposal drafts across Claude Code, Codex, and Cursor.
174
+
175
+ ## 1.20.0
176
+
177
+ ### Minor Changes
178
+
179
+ - [`9a536c4`](https://github.com/openplanr/OpenPlanr/commit/9a536c47b36430bf0d8700d63fc11d3259b97bc7) The Operating Board harness pivot for `planr operate` (SPEC-004), the `openplanr` minor
180
+ bump 1.19.0 → 1.20.0 — the agent is the engine; the CLI harnesses, verifies, and records.
181
+ Every landed claim below is backed by a named proof; coordinated sibling work still
182
+ completing under this same version is described as landing with the release, never as a
183
+ phase this repository has already verified.
184
+
185
+ **The mandate replaces the collector as the unit of dispatch.** A per-role operating
186
+ mandate carries the lens question, declared read boundaries (workspace roots — including
187
+ the `.planr/` tree — a sensitivity ceiling, and forbidden paths), a required response
188
+ schema, and a citation requirement, and it carries no evidence bodies and no evidence
189
+ index — structurally forbidden rather than merely omitted. Proven by
190
+ `tests/unit/operate-adapter-mission-dispatch.test.ts` ("prepares a mandate (not a pack)
191
+ with declared boundaries and no evidence body ..."), whose fixture fails if any file body
192
+ ever leaks into the body-free, index-free mandate.
193
+
194
+ **Evidence is an output, not an input, and citation resolution is the universal gate.**
195
+ `adapter record` resolves every citation in a response fail-closed and mints the
196
+ evidence-of-record from what was actually cited. A fabricated path, a wrong line range, a
197
+ moved revision, or a citation above the role's sensitivity ceiling each becomes a governed
198
+ gap — on every dispatch path and every source — and a response resolving zero citations
199
+ records its role `not_evaluated` with a governed gap naming the empty grounding. Proven by
200
+ `tests/unit/operate-citation-resolution.test.ts` ("rejects a fabricated path, a wrong line
201
+ range, and a moved revision with distinct reasons and one gap each" and "commits a role
202
+ not_evaluated with a governed gap when its citations resolve zero evidence") and by the
203
+ above-ceiling refusal in `tests/unit/operate-mission-honeytoken-isolation.test.ts`
204
+ ("refuses a read above the sensitivity ceiling inside a granted root").
205
+
206
+ **Hard-blocked secrets in cited content are rejected, not redacted-and-accepted.** A
207
+ citation whose snapshot contains a hard-blocked secret category is refused as an
208
+ unresolvable citation gap instead of being persisted in redacted form. Proven by
209
+ `tests/unit/operate-citation-resolution.test.ts` ("rejects a citation into
210
+ HARD-blocked-secret content as unresolvable, never redacted-and-accepted"), with a
211
+ soft-secret assignment still redacted-and-accepted so the distinction is exercised both
212
+ ways.
213
+
214
+ **A gitignored `.planr/` tree is fully citable — by architecture.** The dispatched agent
215
+ reads the filesystem directly rather than `git ls-files`, so a project that gitignores its
216
+ `.planr/` control surface can still ground the three lenses (CPO, CMO, COO) that the
217
+ fourth field audit found unsatisfiable when candidates came only from tracked files — the
218
+ defect that starved three of six lenses is gone by construction, not by repair. Proven by
219
+ `tests/unit/operate-mission-honeytoken-isolation.test.ts` ("reads a gitignored .planr/
220
+ tree — the mission tool walks the filesystem, not git ls-files (finding 2)").
221
+
222
+ **Guided init has no livelock, no dead-end advice, and a revise path.** An answer envelope
223
+ is accepted on its binding validity (session id, questionnaire digest, project head)
224
+ rather than on wall-clock ordering, a transiently stale session un-latches when the tree
225
+ is restored, a genuinely terminal rejection names the resumable session id and its exact
226
+ `--resume` command, a previously answered question can be re-answered before apply, and the
227
+ questionnaire advertises `--answers-file` as a stdin-parity transport alternate with
228
+ per-question renderability metadata. Proven by
229
+ `tests/unit/operate-question-session.test.ts` ("accepts an answer envelope whose
230
+ submittedAt predates the session (livelock regression)" and "un-latches a transiently
231
+ stale session when the tree is restored"),
232
+ `tests/integration/operate-question-resume.test.ts` (the resume command surfaced in the
233
+ next actions), and `tests/unit/operate-question-engine.test.ts` ("advertises
234
+ --answers-file as a stdin-parity transport alternate with its exact argv" and "carries
235
+ repeated-text renderability metadata sufficient to present without improvisation").
236
+
237
+ **Completing the pivot in the same coordinated release.** Sibling work landing under this
238
+ version retires the now-dead evidence collector — its walks and budgets, role packs,
239
+ mission packets, and the `pack|mission` dispatch-mode split — behind the mandate contract;
240
+ renders cycle integrity (citation rejections, boundary refusals, `not_evaluated` roles) as
241
+ a first-class section of the readable tree and a `doctor` check; makes the persisted
242
+ `cycles/<id>/report.md` a self-contained record with complete registers; corrects the
243
+ "commit-safe root" claim to an honest, redaction-based statement; and collapses runtime
244
+ classification to mandate-capable-or-unsupported with no silent structured fallback. On the
245
+ same schedule, the CLI's own structured-provider advisor path and its `--ai` planning
246
+ surfaces are deprecated (FR4) — functional this release, pointed at the harness flow, and
247
+ scheduled for removal, never broken and never silently removed. These items land with this
248
+ release rather than ahead of it; their per-task proofs live under
249
+ `.planr/specs/SPEC-004-operate-agent-harness-architecture/`.
250
+
251
+ **Pins the optional `planr-pipeline` runtime to the exact `0.36.1`** — the build that
252
+ publishes the additive operating-mandate schema (the same additive pattern as
253
+ `create-quick-task`/`create-epic`), the regenerated mandate-flow command/skill
254
+ instructions, the registry investigation mandates, and the reclassified adapter capability
255
+ rows this release dispatches against. Verified:
256
+ `optionalDependencies["planr-pipeline"] === "0.36.1"`, the three workflow `ref: v0.36.1`
257
+ pins, and both packed-install e2e assertions.
258
+
259
+ ## Unreleased
260
+
261
+ ### Deprecations
262
+
263
+ - CLI-managed Operating Board structured-provider dispatch and the legacy
264
+ `--ai` planning surfaces remain functional in this release, but now emit one
265
+ shared deprecation notice. Agentic investigation and advisory work belongs in
266
+ the native runtime harness through Protocol v1.3 mandates. Both legacy surfaces
267
+ are scheduled for removal in OpenPlanr 2.0.0; see
268
+ https://openplanr.dev/docs/operate/agent-harness.
269
+
270
+ ## 1.19.0
271
+
272
+ ### Minor Changes
273
+
274
+ - [`acbdfed`](https://github.com/openplanr/OpenPlanr/commit/acbdfed8ab0fce13a65f7fd9c4ff58dc705c62ea) Operating Board outputs and epic-loop release for `planr operate` (SPEC-003), the
275
+ `openplanr` minor bump 1.18.0 → 1.19.0. Every claim below is backed by a named proof;
276
+ nothing describes a phase this repository has not actually reached.
277
+
278
+ Cycle reports and boards are now persisted as truthful on-disk artifacts: a single rich
279
+ assembly drives both `cycles/<id>/report.md` and every `board/<role>.md`, so `report.md`
280
+ is byte-identical to the review rendering and each evaluated board file carries its lens
281
+ recommendations with impact/confidence/ease (I/C/E) scores — proven by
282
+ `tests/unit/operate-projection-persistence.test.ts` ("renders cycles/<id>/report.md and
283
+ rich board files from the assembled lens artifacts"). The readable tree is consolidated:
284
+ the legacy `projections/` directory is retired (never written), the parked-findings
285
+ `backlog.md` is promoted to the top level, and `state.json` moves under `.state/` —
286
+ proven by `tests/integration/operate-preview-boundaries.test.ts` and the persistence
287
+ suite's asserted paths (`.planr/operate/backlog.md`, `.planr/operate/.state/state.json`,
288
+ no `projections/`).
289
+
290
+ Evidence loss is never silent. A capped repository walk names the last path it reached
291
+ and the top-level directories it never scanned, mission-index drops are counted and
292
+ surfaced as cycle warnings, sensitivity narrowing is scoped to the offending items, and a
293
+ starved role is gated not-ready with a governed data gap while every ready role still
294
+ dispatches — proven by `tests/integration/operate-evidence-recovery.test.ts` ("gates a
295
+ starved repository role with a governed gap while other roles still dispatch (FR2)").
296
+ Collection is prioritized and fair: per-top-level-directory round-robin plus git-recency
297
+ ordering, with split repository/planr file budgets replacing the shared `maxFiles`
298
+ counter — proven by `tests/integration/operate-evidence-monorepo-fairness.test.ts`
299
+ ("samples every product top-level directory under a cap the tree exceeds combined" and its
300
+ deterministic re-selection check).
301
+
302
+ Mission budgets are sized for real repositories: the derived mission-budget clamp ceiling
303
+ rises from 9 to 32 KiB against real index-item costs, per-role `maxEvidenceItems` caps are
304
+ enforced, and an oversized index is truncated to fit with the drop reported as a cycle
305
+ warning — never a silent drop and never an unexplained fail-closed on a healthy repo —
306
+ proven by `tests/unit/operate-mission-packet.test.ts` ("truncates a monorepo-scale index
307
+ to the cap, fits the budget, and reports the drop (FR4)" and "leaves a healthy repository
308
+ under its cap untouched — no warning, no fail-closed (FR4)"), with the field-scale pack
309
+ path still failing closed with no provider invocation in
310
+ `tests/unit/operate-advisor-pack-scale.test.ts`.
311
+
312
+ Re-initialization preserves machine-local preferences: a no-flag re-init carries
313
+ `dispatchModeOverrides`, `adapterLeaseDurationMs`, and `lastRunAt` forward, and the init
314
+ preview names exactly which preference a re-init will change — proven by
315
+ `tests/unit/operate-initialization-replay.test.ts` ("carries dispatchModeOverrides,
316
+ adapterLeaseDurationMs, and lastRunAt forward on a re-init with no flags (field repro)")
317
+ and `tests/integration/operate-guided-init.test.ts` ("names exactly which machine-local
318
+ preferences a re-init will change in the preview").
319
+
320
+ The epic loop closes: the report groups related accepted findings into a ready-to-run
321
+ `planr epic create --title …` suggestion naming the member findings, and the `create-epic`
322
+ route applies a real `.planr/epics/EPIC-NNN-<slug>.md` artifact through the write-ahead
323
+ journal with byte-exact rollback while never invoking PLAN or SHIP (R1 intact) — proven by
324
+ `tests/integration/operate-decision-brief-render.test.ts` ("renders one planr epic create
325
+ suggestion naming both accepted findings") and `tests/integration/operate-route-lanes.test.ts`
326
+ ("elects, applies, and byte-exact rolls back a grouped-finding epic without ever invoking
327
+ PLAN or SHIP").
328
+
329
+ Pins the optional `planr-pipeline` runtime to the exact `0.35.0` — the build that ships the
330
+ FR4 packet-enforcement half, the additive FR8 `create-epic` operating-route-plan schema,
331
+ the reviewed registry role budgets, and the regenerated operate assets this release proves
332
+ against (`optionalDependencies["planr-pipeline"] === "0.35.0"`, mirrored by the three
333
+ workflow `ref: v0.35.0` pins and both packed-install e2e assertions).
334
+
335
+ ## 1.18.0
336
+
337
+ ### Minor Changes
338
+
339
+ - [`0bd9c2a`](https://github.com/openplanr/OpenPlanr/commit/0bd9c2a8859631085c121bcd819e6cf45a4c33d1) Field-fix release for the `planr operate` Operating Board (SPEC-002), hardening the
340
+ Protocol v1.3 agentic engine against issues found once real field incidents drove the
341
+ board. Native mission dispatch is now wired end to end: a bound role prepares a mission
342
+ packet (not a v1.2 pack) and hands back a v1.3 mission record action on a claude-code
343
+ runtime, threading v1.3 citation-bearing responses through the recorded-proposal gate,
344
+ while codex/cursor fail closed to the pack path — proven by
345
+ `tests/unit/operate-adapter-mission-dispatch.test.ts` ("native mission dispatch reaches
346
+ the record action"). Advisor pack budgets now fail closed at field-incident scale:
347
+ `createOperatingAdvisorPack` throws before returning a field-scale pack, and both the
348
+ dispatch and adapter-lifecycle prepare call sites refuse with no provider invocation and
349
+ persist no session, with checkpoints holding at 10,000 events. The human review renderer
350
+ presents the write-free `review` stage — question, evidence, options, and blockers —
351
+ before any initialization is applied. Guided continuations return `ok: true` and hand the
352
+ runner a directly executable `confirmArgv` on a digest-confirmable action. Adapter sessions
353
+ bind to board identity so a re-inited board never collides with a prior generation, and
354
+ `doctor` gains two staleness diagnostics (FR11): a stale adapter session bound to a
355
+ superseded board generation and a stale incremental baseline whose `workspaceDigest`
356
+ drifted, each with a scoped fix. Provider bootstrap failures surface as typed
357
+ `E_OPERATE_ADVISOR_FAILED` errors with a remedy, the readiness preflight names a missing
358
+ provider key before a cycle starts, and runtime detection resolves the real host from env
359
+ markers instead of stamping `unknown`/`none`. The init questionnaire is on a diet with
360
+ preselection (only unanswered canonical questions are returned; the decision owner is
361
+ suggested from the git user) and accepts `--answers-file` as a bounded stdin-parity alias
362
+ under the same 64 KiB cap. Adapter leases surface their expiry and remaining time in prepare
363
+ output and the handoff (default 15 minutes), refresh on each successful record, and honor a
364
+ machine-local configured lease duration. Pins the optional `planr-pipeline` runtime to
365
+ `0.34.0`, the build that ships the regenerated v1.3 templates this release proves against.
366
+
367
+ ## 1.17.0
368
+
369
+ ### Minor Changes
370
+
371
+ - [`5e2fac8`](https://github.com/openplanr/OpenPlanr/commit/5e2fac89bd61d4095acb421fa26b987113573c65) Advance `planr operate` to the Protocol v1.3 agentic engine (OPERATE-SPEC-004):
372
+ automatic, lossless `.state/` layout migration that is journal-driven
373
+ (crash-safe) and byte-exactly reversible; a live evidence index with
374
+ digest-bound mission packets; bounded, read-only native dispatch guarded by a
375
+ mission honeytoken refusal suite and per-role `pack`/`mission` dispatch-mode
376
+ overrides; citation resolution as the audit mechanism, fail-closed and reporting
377
+ a distinct dirty-working-tree outcome; quick-task routing; self-contained
378
+ offline decision briefs that fail closed on any non-local reference; cadence
379
+ status that only reports and never requests an action; a skill-first operate
380
+ cycle; and v1.3 doctor checks. Pins the optional `planr-pipeline` runtime to
381
+ 0.33.1, the build that ships the `schemas/v1.3.0` mission-packet surface.
382
+
383
+ ## 1.16.2
384
+
385
+ ### Patch Changes
386
+
387
+ - [`7d85669`](https://github.com/openplanr/OpenPlanr/commit/7d8566968e6e75aa7f5d2fce05157b0257498e08) Manage compatible Claude Code marketplace plugins during confirmed setup and
388
+ runtime updates, and diagnose stale versions or invalid plugin identities.
389
+
390
+ ## 1.16.1
391
+
392
+ ### Patch Changes
393
+
394
+ - [`935e43b`](https://github.com/openplanr/OpenPlanr/commit/935e43b2ca4c07b2053a728ae2f90af24a151e6d) Complete bare Planr Operate invocations through the native runtime cycle, prevent Unicode evidence truncation from corrupting state, quarantine advisor-ineligible excerpts before readiness, make cancellation retry-safe, and diagnose stale questionnaire-first runtime skills.
395
+
396
+ ## 1.16.0
397
+
398
+ ### Minor Changes
399
+
400
+ - [`e1f5127`](https://github.com/openplanr/OpenPlanr/commit/e1f5127d7250ca785723c91cdf03c2ab08a2e614) Run Operating Board cycles through bounded native runtime advisors, quarantine unsafe evidence without blocking unrelated lenses, and add actionable Markdown/JSON executive reports.
401
+
402
+ ## 1.15.1
403
+
404
+ ### Patch Changes
405
+
406
+ - [`656b673`](https://github.com/openplanr/OpenPlanr/commit/656b673f5506c49e18b5ca3759027d6150cd7c9c) Make direct Operating Board initialization previews return a self-contained, digest-bound replay command that applies without restarting the questionnaire, and route focused integration gates through their executable Vitest configuration.
407
+
408
+ ## 1.15.0
409
+
410
+ ### Minor Changes
411
+
412
+ - [`1b829e8`](https://github.com/openplanr/OpenPlanr/commit/1b829e8ccd8b025a214811ecf02cc2ac9adb1b89) Add CLI-owned guided Operating Board questionnaires, resumable typed-answer
413
+ sessions, digest-scoped actions, deterministic charter assistance, value-free
414
+ evidence recovery, runtime-native presentation contracts, and setup/doctor
415
+ diagnostics without weakening PLAN, SHIP, provider, or route authority gates.
416
+
417
+ ## 1.14.4
418
+
419
+ ### Patch Changes
420
+
421
+ - [`e4fdfb3`](https://github.com/openplanr/OpenPlanr/commit/e4fdfb3ba9c44ac7da13de9ae9fbab52836048d6) Prevent Operating Board evidence redaction from quarantining safe assignments or reprocessing its own redaction sentinels.
422
+
423
+ ## 1.14.3
424
+
425
+ ### Patch Changes
426
+
427
+ - [`e986fc0`](https://github.com/openplanr/OpenPlanr/commit/e986fc02e552f6c9741bd9117bc02a1503335953) Derive Operating Board producer provenance from the installed OpenPlanr package version instead of a copied release literal.
428
+
429
+ - [`08349b3`](https://github.com/openplanr/OpenPlanr/commit/08349b3be8aa8acdc1b5c636f279550b291a4703) Report a missing OpenPlanr configuration as the actionable advisor error instead
430
+ of an unexpected internal failure. `planr operate init` writes
431
+ `.planr/operate/config.json`, not the project-wide `.planr/config.json`, so a
432
+ project that ran only the operate initializer reached the structured adapter
433
+ with no config at all and surfaced "an unexpected internal Operating Board
434
+ error" on the primary first-run path.
435
+
436
+ ## 1.14.2
437
+
438
+ ### Patch Changes
439
+
440
+ - [`0e792eb`](https://github.com/openplanr/OpenPlanr/commit/0e792ebed92f0d7e4a424388390236bb96b0e78e) Reject secrets in native Operating Board advisor results before any commit-safe event or projection is persisted, and pin Changesets' development-only YAML parsers to patched versions.
441
+
442
+ ## 1.14.1
443
+
444
+ ### Patch Changes
445
+
446
+ - [`c0136af`](https://github.com/openplanr/OpenPlanr/commit/c0136afcadef87fe9d3795e6223fea0cb5f559f0) Point `test:operate:packed` at the config that owns the packed-install suite.
447
+ The suite moved out of the default vitest project so it could not saturate the
448
+ shared worker pool, but the script still used the default config, where the file
449
+ is now excluded — so it exited "No test files found" instead of running.
450
+
451
+ - [`5c7c05b`](https://github.com/openplanr/OpenPlanr/commit/5c7c05b5188312e461e3464e8c7c27bf5d100ff8) Stabilize the native Operating Board lifecycle under parallel CI load and close
452
+ the operating lock file safely when its initial durable write fails.
453
+
454
+ ## 1.14.0
455
+
456
+ ### Minor Changes
457
+
458
+ - [`8e95efb`](https://github.com/openplanr/OpenPlanr/commit/8e95efbfedc0e23e341de1d130ab9df558d6a9d5) Add `planr operate`, an evidence-to-decision operating control plane with safe
459
+ workspace initialization, event-sourced cycles, isolated advisory lenses,
460
+ separate finding acceptance and route application, typed outcomes, recovery,
461
+ strict JSON automation, and cross-runtime workflow support.
462
+
463
+ ## 1.13.3
464
+
465
+ ### Patch Changes
466
+
467
+ - [`a4c61dc`](https://github.com/openplanr/OpenPlanr/commit/a4c61dc2bb09527783f44ed51d3cfabce3027cc2) Bundle artifacts from their own directory by default, and report safely vendored remote assets in local review output.
468
+
469
+ ## 1.13.2
470
+
471
+ ### Patch Changes
472
+
473
+ - [`d3e9314`](https://github.com/openplanr/OpenPlanr/commit/d3e9314bd0d3655a65b645d7a63c6dae23f45972) Update the optional `planr-pipeline` runtime to 0.29.0 so `planr artifact`
474
+ uses the released minimal document review chrome with the floating comments rail.
475
+
476
+ ## 1.13.1
477
+
478
+ ### Patch Changes
479
+
480
+ - [`ace659d`](https://github.com/openplanr/OpenPlanr/commit/ace659d7afcf55834e0a6f4610881863a4947b7c) Update the bundled pipeline to 0.28.5 so document artifacts use a single outer scrollbar instead of competing iframe scrolling.
481
+
482
+ ## 1.13.0
483
+
484
+ ### Minor Changes
485
+
486
+ - [`004ca3f`](https://github.com/openplanr/OpenPlanr/commit/004ca3f16451ceb7a47dd95ae897c473587a2ec4) Allow Linear setup to configure one, several, or all accessible teams, select a default, and target configured teams per push with `--team`.
487
+
488
+ ## 1.12.4
489
+
490
+ ### Patch Changes
491
+
492
+ - [`4f6c4c5`](https://github.com/openplanr/OpenPlanr/commit/4f6c4c51c62ad93447fc0caed64d20ad11fd30c5) Update the bundled pipeline to 0.28.4 for stable live-room sharing, clearer fragment limits, visible copy confirmation, reviewer identity feedback, and keyboard comment submission.
493
+
494
+ ## 1.12.3
495
+
496
+ ### Patch Changes
497
+
498
+ - [`ed010b3`](https://github.com/openplanr/OpenPlanr/commit/ed010b35fa57c855af89432fb622d1a31f34594d) Make `planr doctor --fix` preview and safely remove stale Planr-owned design and dashboard daemon state. Missing runtimes are now informational unless the current setup selected them.
499
+
500
+ ## 1.12.2
501
+
502
+ ### Patch Changes
503
+
504
+ - [`0784dbd`](https://github.com/openplanr/OpenPlanr/commit/0784dbd1d311a46f56451188199ab12c4f080407) Decode feedback from existing encrypted live artifact review rooms whose persisted events predate the room-event version field.
505
+
506
+ ## 1.12.1
507
+
508
+ ### Patch Changes
509
+
510
+ - [`a2b22ec`](https://github.com/openplanr/OpenPlanr/commit/a2b22ec0bbeb5131b6f2a2d5f6d0a99be3558dfa) Use planr-pipeline 0.28.1 so live collaborative rooms encrypt the compressed artifact payload correctly, including rooms created from legacy artifact shares.
511
+
512
+ ## 1.12.0
513
+
514
+ ### Minor Changes
515
+
516
+ - [`60fd19c`](https://github.com/openplanr/OpenPlanr/commit/60fd19cccd15fecf3cb00c189b8719dc92ee6fcf) Make encrypted live artifact review rooms the default sharing workflow, retain
517
+ immutable snapshots behind `--snapshot`, support live-room feedback imports,
518
+ and bundle `planr-pipeline` 0.28.0.
519
+
520
+ ## 1.11.0
521
+
522
+ ### Minor Changes
523
+
524
+ - [`0c14c9b`](https://github.com/openplanr/OpenPlanr/commit/0c14c9bbe05909da130d5e0bb03aa143444a7b56) Add headless document and zoomable canvas presentations to `planr artifact`,
525
+ including `--presentation auto|document|canvas`, resolved JSON output, and the
526
+ planr-pipeline 0.27.1 compatibility update.
527
+
528
+ ## 1.10.0
529
+
530
+ ### Minor Changes
531
+
532
+ - [`4438a9a`](https://github.com/openplanr/OpenPlanr/commit/4438a9a046beeaa1a0ac9201fc24fa635c36b470) Add `planr artifact` for secure local HTML review, private fragment or encrypted short-link sharing, returned-review import, and live-session export.
533
+
534
+ ## 1.9.1
535
+
536
+ ### Patch Changes
537
+
538
+ - [`392b50c`](https://github.com/openplanr/OpenPlanr/commit/392b50c26d31d4d3bc680471e7864ec1f1d8beca) Make installation quiet and configuration explicit, add guided runtime setup with safe user-scope defaults, prevent accidental project writes outside Git or initialized OpenPlanr projects, and diagnose legacy home-directory setup files.
539
+
540
+ ## 1.9.0
541
+
542
+ ### Minor Changes
543
+
544
+ - [`05a3088`](https://github.com/openplanr/OpenPlanr/commit/05a3088ef0af8628f0a38562062192c62fbbbf66) Add the unified cross-runtime distribution flow: `planr setup`, runtime adapter
545
+ lifecycle management, pipeline routing, unified doctor diagnostics, exact
546
+ runtime locks, and append-only planning provenance. The full
547
+ `planr-pipeline` package is installed by default with `--minimal` as the
548
+ planning-only escape hatch. Codex skills and Cursor rules now come from the
549
+ shared portable registries, while migrations preserve hand-written content,
550
+ back up exact bytes, retain shared user assets safely, and support conflict-safe
551
+ rollback and removal.
552
+
553
+ ## 1.8.1
554
+
555
+ ### Patch Changes
556
+
557
+ - [`29e89e6`](https://github.com/openplanr/OpenPlanr/commit/29e89e684c915a98603a715030f71ae8c2c7dc2b) Update generated rule templates to reference **Sonnet 5** (was Sonnet 4.6) for the analysis/decomposition tier, matching planr-pipeline v0.24.10. The cursor (`planr-pipeline.mdc.hbs`, `agents/designer-agent.md`, `agents/qa-agent.md`, `agents/specification-agent.md`) and codex (`_pipeline-section.md.hbs`) rule-generator templates now render the current analysis-tier model. The DEV/codegen tier stays on Opus 4.8.
558
+
559
+ ## 1.8.0
560
+
561
+ ### Minor Changes
562
+
563
+ - Add `planr graph --json`, a read-only artifact graph export for dashboard and
564
+ ecosystem conformance. The command emits the shared OpenPlanr Protocol graph
565
+ shape `{ nodes, edges }`, namespaces spec-local story/task ids, and preserves
566
+ `contains` and `depends_on` edges from frontmatter.
567
+
568
+ ## 1.7.2
569
+
570
+ ### Patch Changes
571
+
572
+ - [`e60983c`](https://github.com/openplanr/OpenPlanr/commit/e60983c02d49106d11c61c11719788ed1aace7eb) `planr status` is now the **whole-project delivery report**. With no argument it rolls up every Spec / Backlog item / Quick Task (or the agile epic→task tree) by status — **done** · **promoted/superseded** (addressed, never counted as done or outstanding) · **outstanding** — cross-referenced with the GitHub issue/PR and Linear identifiers recorded in frontmatter, ending with a Summary and an **Outstanding work** section. New: an optional `[scope]` argument (one spec/epic/feature id or slug), `--md` (paste-ready markdown report), `--json` (machine-readable for agents/CI), and `--github` / `--linear` to live-resolve PR + issue states (offline frontmatter by default). Powered by the new `delivery-status-service` (deterministic aggregation over the existing artifact/GitHub/Linear services); the previous truncated tree view is superseded by the delivery view (`--all` still controls terminal truncation).
573
+
574
+ ## 1.7.1
575
+
576
+ ### Patch Changes
577
+
578
+ - [`1c7b70a`](https://github.com/openplanr/OpenPlanr/commit/1c7b70a6d115f43389c3477d01aa8f895e505b25) Align generated rule templates and the spec-schema reference to **Opus 4.8** (was Opus 4.7). The cursor (`planr-pipeline.mdc.hbs`, `agents/specification-agent.md`) and codex (`_pipeline-section.md.hbs`) rule-generator templates, plus `docs/reference/spec-schema.md`, now render the current DEV-tier codegen model — matching the planr-pipeline plugin v0.10.0 bump to `claude-opus-4-8[1m]`.
579
+
580
+ ## 1.7.0
581
+
582
+ ### Minor Changes
583
+
584
+ - [`2a97c04`](https://github.com/openplanr/OpenPlanr/commit/2a97c04042591e4195bb4b84a4ae3486812877ed) feat: artifact integrity + rules generator managed-block markers
585
+
586
+ ### Managed-block markers for `rules generate` (fixes AGENTS.md clobber bug)
587
+
588
+ `planr rules generate --scope pipeline` no longer overwrites the entire AGENTS.md / CLAUDE.md. Generated content is now wrapped in `<!-- ##planr-pipeline:begin## -->` / `<!-- ##planr-pipeline:end## -->` HTML comment markers. On regeneration, only the content between markers is replaced — project headers, agile content, and hand-written sections are preserved. Same treatment for `--scope agile` via `<!-- ##planr-agile:begin## -->` markers.
589
+
590
+ ### Write-time artifact validation
591
+
592
+ `updateArtifact()` now validates structural invariants before writing: frontmatter fences present, YAML parses, `id:` field unchanged, and checkbox IDs preserved. On violation, throws `ArtifactInvariantError` with the specific violation. This stops AI-driven corruption from `planr refine` / `planr revise` at the door — the file on disk is never poisoned by malformed AI output.
593
+
594
+ ### AI contract: structured deltas for `planr refine`
595
+
596
+ `planr refine` now asks the AI for structured deltas (`frontmatterChanges` + `bodyChanges`) instead of a whole-file `improvedMarkdown` blob. Our code applies deltas deterministically — the AI never holds a pen on raw bytes. Legacy `improvedMarkdown` responses are validated and rejected if they break structural invariants.
597
+
598
+ ### Migration
599
+
600
+ - First run of `planr rules generate` on an existing project wraps content in markers automatically (non-destructive).
601
+ - `planr refine` change is transparent to users (AI contract is an implementation detail).
602
+ - Files previously corrupted by refine must be manually repaired or restored via `git checkout`.
603
+
604
+ ## 1.6.0
605
+
606
+ ### Minor Changes
607
+
608
+ - [`d56c9a7`](https://github.com/openplanr/OpenPlanr/commit/d56c9a73a68a302eb0bc10aaa6a00c72630fc3ef) feat(types): widen `TaskStatus` to include `'blocked'` for v0.8.0 plugin alignment
609
+
610
+ The planr-pipeline v0.8.0 task schema enum is `['pending', 'in-progress', 'done', 'blocked']`. Prior CLI versions silently coerced `blocked` → `pending` via `asTaskStatus()`, dropping the R6-failure signal that the pipeline writes alongside `T-NNN-error-report.md`.
611
+
612
+ Changes:
613
+
614
+ - `TaskStatus` union now includes `'blocked'` (`src/models/types.ts`)
615
+ - All four `asTaskStatus()` normalizers accept and preserve `'blocked'` (linear-pull, linear-push, scope-loaders)
616
+ - `DEFAULT_LINEAR_STATE_TO_OP` adds `['blocked', 'blocked']` so a Linear "Blocked" workflow state pulls back into a blocked task file
617
+ - `buildNameToStatusMap` accepts `'blocked'` from user `linear.statusMap` overrides
618
+ - `aggregateTaskStatus()` adds top-precedence rule: any blocked child → blocked parent (escalation, not averaging)
619
+
620
+ Migration: zero-friction. Tasks that don't carry `blocked` are unaffected. The CLI no longer demotes blocked back to pending on Linear pull.
621
+
622
+ ## 1.5.2
623
+
624
+ ### Patch Changes
625
+
626
+ - [`1eec762`](https://github.com/openplanr/OpenPlanr/commit/1eec7627c6d95167644d88f884716a1537a1fb0f) Fix a leftover `OpenPlanr-pipeline-aware` phrase in the cursor master rule template that the v1.5.1 rename sed missed (mixed-case compound adjective). After upgrade, regenerated `.cursor/rules/planr-pipeline.mdc` files use `planr-pipeline-aware` consistently with the renamed plugin.
627
+
628
+ No behavioural change. Run `planr rules generate --target cursor --scope pipeline` to refresh existing projects.
629
+
630
+ ## 1.5.1
631
+
632
+ ### Patch Changes
633
+
634
+ - [`03aa928`](https://github.com/openplanr/OpenPlanr/commit/03aa9289be7e784c3cd5b904af7459f7ee185dfa) Plugin rename: `openplanr-pipeline` → `planr-pipeline`. Brand convergence on the `planr` CLI binary. The CLI's TypeScript API is unchanged — only generated artifact names + slash command identifiers.
635
+
636
+ **What changes for users:**
637
+
638
+ - Generated cursor rule filenames: `openplanr-pipeline.mdc` → `planr-pipeline.mdc` (also `-plan.mdc` and `-ship.mdc` variants)
639
+ - Claude sibling reference card: `openplanr-pipeline.md` → `planr-pipeline.md`
640
+ - Slash commands: `/openplanr-pipeline:plan` → `/planr-pipeline:plan` (same for `:ship`)
641
+
642
+ **Migration:** re-run `planr rules generate` to pick up the new files. Legacy filenames trigger a one-line cleanup hint pointing at safe-to-delete paths — never auto-deleted.
643
+
644
+ **Pairs with:** `planr-pipeline` Claude Code plugin v0.7.0 (renamed from `openplanr-pipeline` v0.6.0); `openplanr` skill v1.4.0; marketplace pin updated to v0.7.0.
645
+
646
+ ## 1.5.0
647
+
648
+ ### Minor Changes
649
+
650
+ - [`b8e018c`](https://github.com/openplanr/OpenPlanr/commit/b8e018c895907bdb9bf69052d55552e3efec0229) Multi-runtime rules: extend `planr rules generate` with a `--scope` flag for cross-runtime pipeline support.
651
+
652
+ `planr rules generate` now accepts `--scope <agile|pipeline|all>` (default: `agile` — preserves existing behaviour byte-for-byte). The new `pipeline` scope generates rule files that drive the openplanr-pipeline two-phase spec-driven flow on the chosen runtime, giving Cursor and Codex first-class parity with the Claude Code plugin.
653
+
654
+ **Cursor (`--target cursor --scope pipeline`):**
655
+
656
+ - `.cursor/rules/openplanr-pipeline.mdc` — master rule (mode detection, R1 human gate, runtime parity notes)
657
+ - `.cursor/rules/openplanr-pipeline-plan.mdc` — PO Phase orchestration (Composer subagent dispatch)
658
+ - `.cursor/rules/openplanr-pipeline-ship.mdc` — DEV Phase orchestration (parallel subagents, qa gate, snapshot, marker)
659
+ - `.cursor/rules/agents/{db,designer,specification,frontend,backend,qa,devops,doc-gen}-agent.md` — 8 role bodies vendored verbatim from `openplanr-pipeline/agents/` (frontmatter stripped; Cursor uses different permission model)
660
+
661
+ **Codex (`--target codex --scope pipeline`):**
662
+
663
+ - `AGENTS.md` extended with a `## OpenPlanr Pipeline Orchestration` section. Roles modelled as personas (Codex doesn't have separate subagent processes); R1, R2, R5, R6, R8, R9 declared at prompt level with conformance-test enforcement.
664
+
665
+ **Claude (`--target claude --scope pipeline`):**
666
+
667
+ - `CLAUDE.md` gets a conditional `## OpenPlanr Pipeline (Path A)` block under `{{#if pipelineScope}}`
668
+ - Sibling `openplanr-pipeline.md` reference card with install commands, slash command list, and cross-runtime pointer
669
+
670
+ `--scope all` produces both agile and pipeline rules side-by-side.
671
+
672
+ **Compatibility matrix and OpenPlanr Protocol v1.0.0** documented in `openplanr-pipeline/docs/protocol/` and `openplanr-pipeline/docs/compatibility-matrix.md` (pipeline plugin v0.6.0+).
673
+
674
+ **`planr init` now auto-generates pipeline rules by default.** The init flow asks "Generate openplanr-pipeline rules?" with default `Yes` — meaning a single `planr init` produces a complete, ready-to-use cross-runtime project (Cursor + Codex pipeline rules pre-installed; Claude Code skill activates the same workflow via the plugin). Opt out with `planr init --no-pipeline-rules` to preserve the previous agile-only behaviour. This closes the cross-runtime DX gap so each tool (Cursor, Codex, Claude Code) is self-sufficient after a single command — no manual `planr rules generate --scope pipeline` step required for the common case.
675
+
676
+ **Migration:** none. Existing projects can either re-run `planr init` (it auto-detects existing config and asks to overwrite) or run `planr rules generate --scope all` to add pipeline rules without touching config. `--scope agile` (the previous default for `planr rules generate`) keeps producing the existing 6 Cursor `.mdc` files, single CLAUDE.md, single AGENTS.md outputs unchanged.
677
+
678
+ ## 1.4.3
679
+
680
+ ### Patch Changes
681
+
682
+ - [`e625a3b`](https://github.com/openplanr/OpenPlanr/commit/e625a3b69c331a45806fc3ff8197b0115f14b1f0) Four improvements that close real workflow gaps in `planr linear push`, `planr linear tasklist-sync`, and the per-type `update` commands.
683
+
684
+ **Granular push scope (BL-012).** `planr linear push` adds `--no-cascade` and redefines `--push-parents` to be upward-attachment only.
685
+
686
+ - `--no-cascade` on EPIC/FEAT pushes skips descendants (stories, tasklists, linked QT/BL). No-op for leaves.
687
+ - `--push-parents` no longer drags in the parent's other children. Pushing `TASK-004 --push-parents` now creates EPIC + parent FEAT + this tasklist only — not the feature's sibling stories.
688
+
689
+ **TASK status now propagates to Linear (BL-014).** `planr linear push` resolves a workflow stateId for the merged TaskList issue using an aggregation rule across all task files under the feature: all `done` → Linear Done, any `in-progress` → Linear In Progress, mix of done+pending → In Progress, all `pending` → Linear Todo. Closes the gap where `TASK-006 status: done` locally left Linear's TaskList in Backlog.
690
+
691
+ **Bulk subtask completion (BL-015).** `planr task update`, `planr quick update`, and `planr update` add `--all-done` and `--all-pending` flags that set the frontmatter status AND flip every `N.M` task checkbox in the body in one operation. Replaces the manual `sed`-or-edit-each-box workflow when shipping a feature.
692
+
693
+ **tasklist-sync no longer skips healthy issue UUIDs (BL-016).** `planr linear tasklist-sync` previously rejected every task file whose `linearIssueId` was a UUIDv4 — the entire population of healthy task files — because a shape-based pre-screen flagged them as "looks like a workflow state UUID." Linear issue ids and workflow-state ids are both UUIDv4 and indistinguishable by shape, so the pre-screen has been removed; the existing `isLikelyLinearIssueId` check still rejects truly malformed values like `ENG42`.
694
+
695
+ Backward-compat note: scripts that relied on `--push-parents` cascading downward will see fewer entities pushed.
696
+
697
+ ## 1.4.2
698
+
699
+ ### Patch Changes
700
+
701
+ - [`45f2714`](https://github.com/openplanr/OpenPlanr/commit/45f2714c45a8148f23de32ec10c6a07b04ae30cc) Spec-driven workflow polish: clearer errors, schema reference, readiness check.
702
+
703
+ - **Friendlier `planr spec decompose` error** when AI is unavailable — surfaces two actionable paths (configure AI, or hand-author from the schema reference) instead of one terse line.
704
+ - **`planr config show` now includes a "Spec-driven readiness" section** — at-a-glance view of whether `planr spec decompose` can run given the current AI config.
705
+ - **`planr init --no-ai` prints a warning** listing the AI-dependent commands (`spec decompose`, `refine`, `backlog prioritize`) that will be unavailable, with a one-liner to re-enable later.
706
+ - **Canonical schema reference at `docs/reference/spec-schema.md`** — single source of truth for spec / story / task frontmatter, body sections, lifecycle states, and the `.pipeline-shipped` marker. To be hosted at `openplanr.dev/docs/reference/spec-schema`.
707
+ - Spec template footnote updated with concrete pipeline / CLI handoff routes.
708
+
709
+ ## 1.4.1
710
+
711
+ ### Patch Changes
712
+
713
+ - [`2e36aee`](https://github.com/openplanr/OpenPlanr/commit/2e36aeec579dcac0e212eaabdce24a578f51f9c4) Fix `planr spec shape` UX — replace `$EDITOR`-opening prompts with single-line prompts.
714
+
715
+ Previously, `planr spec shape <SPEC-id>` opened `$EDITOR` (vim by default for many users) for the Context, Business Rules, and Decomposition Notes questions. This was hostile UX — users unfamiliar with vim couldn't navigate, and a single accidental Enter on an empty buffer aborted the entire interactive flow.
716
+
717
+ **v1.4.1 changes:**
718
+
719
+ - **Question 1 (Context)** is now three single-line prompts: primary user, problem solved, expected outcome. Each is optional; provide what you can. The shape skill composes the Context section from your answers using markdown subheadings.
720
+ - **Question 3 (Business Rules)** is now a single line. Hint guides the user to edit the spec markdown file directly for longer-form rules.
721
+ - **Optional Decomposition Notes** is now a single line. Same guidance — edit file directly for longer prose.
722
+ - Functional Requirements (Q2) and Acceptance Criteria (Q4) are unchanged — they were already comma-separated lists.
723
+
724
+ Net effect: the entire shape flow now runs in the terminal with single-line prompts only. No `$EDITOR` open. No accidentally-empty-buffer aborts.
725
+
726
+ For users who genuinely want long-form prose, the recommended path is: run `planr spec shape` for quick capture, then edit `.planr/specs/SPEC-NNN-{slug}/SPEC-NNN-{slug}.md` directly in your editor of choice afterward.
727
+
728
+ Origin: surfaced by real-world testing where a user pressed Enter past the vim buffer without writing anything and lost the entire shape flow.
729
+
730
+ ## 1.4.0
731
+
732
+ ### Minor Changes
733
+
734
+ - [`00e91df`](https://github.com/openplanr/OpenPlanr/commit/00e91dfc5020826bc9c180f057082daab4ebf14f) Add spec-driven planning mode — third planning posture alongside agile + QT, designed for humans planning _for_ AI coding agents.
735
+
736
+ A new `planr spec` command namespace authors specs that decompose into User Stories and Tasks with the **same artifact contract as the [openplanr-pipeline](https://github.com/openplanr/openplanr-pipeline) Claude Code plugin** — file Create/Modify/Preserve lists, Type=UI|Tech, agent assignment, DoD with build/test commands. The two products share one schema; no conversion adapter ever.
737
+
738
+ **Subcommands shipped:**
739
+
740
+ - `planr spec init` — Activate spec-driven mode in the current project
741
+ - `planr spec create [title]` — Create a self-contained `.planr/specs/SPEC-NNN-{slug}/` directory
742
+ - `planr spec shape <id>` — Interactive 4-question SPEC authoring (Context, Functional Requirements, Business Rules, Acceptance Criteria)
743
+ - `planr spec decompose <id>` — AI-driven generation of User Stories + Tasks; matches openplanr-pipeline schema; works with all 3 AI providers (Anthropic, OpenAI, Ollama). Flags: `--force`, `--no-code-context`, `--max-stories <n>`
744
+ - `planr spec sync [id]` — Validate spec integrity (orphaned tasks, stories without tasks, missing `specId`, schema drift); auto-fixes safe issues; `--dry-run` reports without writing
745
+ - `planr spec list` — List all specs with status + decomposition counts
746
+ - `planr spec show <id>` — Print a spec + its US/Task tree
747
+ - `planr spec status [id]` — Decomposition state across one or all specs
748
+ - `planr spec destroy <id>` — `rm -rf` of a single self-contained spec directory
749
+ - `planr spec attach-design <id> --files <png>...` — Attach UI mockups for the pipeline's designer-agent
750
+ - `planr spec promote <id>` — Validate completeness, mark `ready-for-pipeline`, print the `/openplanr-pipeline:plan {slug}` handoff command
751
+
752
+ **Directory layout (per spec, self-contained):**
753
+
754
+ ```
755
+ .planr/specs/SPEC-NNN-{slug}/
756
+ ├── SPEC-NNN-{slug}.md # the spec document
757
+ ├── design/ # PNG mockups + design-spec.md (written by pipeline's designer-agent)
758
+ ├── stories/US-NNN-{slug}.md # US-NNN scoped to this spec
759
+ └── tasks/T-NNN-{slug}.md # T-NNN scoped to this spec
760
+ ```
761
+
762
+ **ID scoping:** US-NNN and T-NNN are scoped to their parent SPEC (not project-globally unique). Two specs can each have their own US-001. Disambiguate via path or via `specId` frontmatter.
763
+
764
+ **Coexistence:** purely additive — agile (epic/feature/story/task) and QT modes work unchanged. Activate spec mode per project via `planr spec init`. Modes are independent; pick the posture that fits the work.
765
+
766
+ **Decompose AI behavior:**
767
+
768
+ - Always scans the project codebase via the existing `buildCodebaseContext()` so generated tasks reference real file paths matching the user's stack
769
+ - Reads `input/tech/stack.md` (best-effort) for stack-specific hints
770
+ - Detects `ui_files` in SPEC frontmatter to drive 1-vs-2 tasks per US (per openplanr-pipeline rule R2)
771
+ - Refuses to overwrite an existing decomposition unless `--force` is passed
772
+ - Status: pending|shaping → decomposing → decomposed
773
+
774
+ **Pipeline integration:** When this CLI marks a spec `ready-for-pipeline`, the openplanr-pipeline Claude Code plugin (v0.3.0+) reads `.planr/specs/SPEC-NNN-{slug}/` directly — no conversion. See `docs/proposals/spec-driven-mode.md` for the full design proposal and BL-011 for the original strategic feedback.
775
+
776
+ ## 1.3.0
777
+
778
+ ### Minor Changes
779
+
780
+ - [`61dc183`](https://github.com/openplanr/OpenPlanr/commit/61dc183e2a1ef7397682b6d7ba871c37c82c2c7a) **`planr linear`** — full Linear.app integration for OpenPlanr (EPIC-004).
781
+
782
+ ### Subcommands
783
+
784
+ - `planr linear init` — validate a Linear PAT, pick a team, save settings.
785
+ - `planr linear push <artifactId>` — create/update Linear entities at any scope:
786
+ - `EPIC-XXX` → project + features + stories + tasklists
787
+ - `FEAT-XXX` → feature + its stories + its tasklist
788
+ - `US-XXX` → one story sub-issue
789
+ - `TASK-XXX` → one tasklist sub-issue
790
+ - `QT-XXX` → quick task in the standalone project
791
+ - `BL-XXX` → backlog item (auto-labeled) in the standalone project
792
+ - `planr linear sync` — pull workflow status + bidirectional task checkboxes.
793
+ - `planr linear tasklist-sync` — sync TASK checkbox lines with Linear issue bodies.
794
+ - `planr linear status` — local mapping table (no API calls).
795
+
796
+ ### Flags on `push`
797
+
798
+ `--dry-run`, `--update-only`, `--push-parents`, `--as <strategy>`.
799
+
800
+ ### Epic mapping strategies (chosen once, stored in `linearMappingStrategy`)
801
+
802
+ - `project` (default) — Epic = Linear Project, one-to-one.
803
+ - `milestone-of:<projectId>` — Epic becomes a `ProjectMilestone` in an existing project; descendants carry `projectMilestoneId`.
804
+ - `label-on:<projectId>` — Epic becomes a team-scoped label; descendants carry `labelIds` (merged with user-added labels, never stomped).
805
+
806
+ First-time push prompts interactively. CI consumers use `--as` or `linear.defaultEpicStrategy`.
807
+
808
+ ### Parent-chain pre-flight
809
+
810
+ Granular pushes (`FEAT-/US-/TASK-`) refuse to run when the parent chain is not yet in Linear — unless `--push-parents` is set, which cascades up. Unsupported prefixes (`ADR-/SPRINT-/checklist-`) error with a pointer to the parent epic.
811
+
812
+ ### Standalone project for `QT-` / `BL-`
813
+
814
+ Quick tasks and backlog items push as top-level issues in a user-chosen Linear project (`linear.standaloneProjectId`, set once via an interactive first-push prompt). Backlog items auto-apply a team-scoped `backlog` label for filtering.
815
+
816
+ ### Security & reliability
817
+
818
+ - Linear IDs validated before every API call — accepts UUID or `ENG-42` identifier; corrupted frontmatter falls through to create instead of 404-ing.
819
+ - Frontmatter writer preserves regex-special sequences (`$1`, `$&`, `$$`) literally — Linear values can contain them.
820
+ - SDK error fallback sanitizes raw GraphQL bodies; known error types keep their user-friendly guidance.
821
+ - Rate-limit retries honor Linear's `Retry-After` (never retry sooner than the server asked, never faster than our exponential backoff).
822
+ - Non-interactive conflict decisions audited to `.planr/reports/`.
823
+ - Three-way checkbox merge warns when a baseline looks corrupted.
824
+ - PATs stored via keychain-first credentials service, never in `config.json`.
825
+
826
+ ### Bidirectional status sync with three-way merge (fixes silent data loss)
827
+
828
+ `planr linear sync` now reconciles workflow status in **both directions** via a three-way merge:
829
+
830
+ - **Local changed, Linear unchanged** → pushes local to Linear (fixes the data-loss bug where `planr quick update --status done` followed by `planr linear sync` silently reverted local back to Linear's stale state).
831
+ - **Linear changed, local unchanged** → pulls Linear to local (existing behavior, preserved).
832
+ - **Both changed** → conflict resolved per `--on-conflict prompt|local|linear`. Interactive runs prompt per artifact; CI/non-interactive runs auto-resolve to `linear` and log the decision to `.planr/reports/linear-sync-conflicts-<date>.md`.
833
+
834
+ Baseline is stored per-artifact in new frontmatter fields `linearStatusReconciled` and `linearStatusSyncedAt`, written on every successful sync. `planr quick update --status` and `planr backlog update --status` automatically clear `linearStatusReconciled` so the next sync recognizes the local change and pushes it up.
835
+
836
+ `--on-conflict` now applies to both status and checkbox conflicts (previously checkbox-only). Applies to FEAT / US / QT / BL. TASK stays deferred (aggregate issue, needs its own aggregation rules).
837
+
838
+ ### Status sync now covers QT + BL (zero-config)
839
+
840
+ `planr linear push QT-XXX` and `planr linear push BL-XXX` now write local status to Linear's workflow state. `planr linear sync` pulls state changes back into QT and BL frontmatter alongside features and stories.
841
+
842
+ - **Zero-config:** push auto-derives the status→stateId map from Linear's canonical state types (`backlog` / `unstarted` / `started` / `completed` / `canceled`) on every run. `linear.pushStateIds` is now an optional override, not a requirement.
843
+ - Quick tasks use the task vocabulary (`pending` / `in-progress` / `done`), plus transparent aliases for Linear-native wording (`completed` / `cancelled` / `canceled` / `todo`).
844
+ - Backlog items use their own vocabulary (`open` / `closed` / `promoted`). Pull is asymmetric by design: any Linear "in flight" state maps to `open`, `Done`/`Cancelled` maps to `closed`, and local `promoted` is never overwritten (it implies a target pointer Linear can't know about).
845
+ - TASK status sync stays on the TODO list. One Linear TaskList issue aggregates many task files, so a 1:1 status mapping doesn't apply; use `planr linear tasklist-sync` for per-checkbox state.
846
+
847
+ **Fix:** Linear's API rejects `stateId: null` on update (`InvalidInput`). All push paths — feature, story, QT, BL — now omit the `stateId` field entirely when unmapped instead of sending an explicit null, so pushes without any state configuration continue to succeed.
848
+
849
+ ### `planr revise` — unchanged-content short-circuit
850
+
851
+ Revise now detects when the agent returns content that is effectively identical to the original (byte-exact, or differs only in trailing whitespace that LLM markdown serializers routinely strip). Behavior in that case:
852
+
853
+ - No file write, no backup sidecar produced, no confirm prompt.
854
+ - New audit outcome `unchanged-by-agent` (distinct from `skipped-by-agent` / `flagged`).
855
+ - UI renders "(no changes — agent's revised output matches the current file; nothing to apply)" in place of an empty diff block.
856
+
857
+ Prevents the confusing `Outcome: applied` report when the only on-disk delta was a trailing newline strip.
858
+
859
+ ### `planr linear status` — full URLs, no truncation
860
+
861
+ Reordered the table so the URL column is last and never truncated. Clickable URLs are the primary value of the table; the previous 28-char ellipsis made them useless for copy-paste.
862
+
863
+ ### Estimate sync for FEAT / US / QT / BL
864
+
865
+ `planr linear push` now writes local `estimatedPoints` (from `planr estimate --save`, or hand-edited `storyPoints`) to Linear's native Issue estimation field, snapped to the team's configured scale:
866
+
867
+ - **Fibonacci** — snap to `{0, 1, 2, 3, 5, 8, 13, 21}` (e.g. `4 → 5`, `7 → 8`).
868
+ - **Linear** — snap to `{0, 1, 2, 3, 4, 5}`.
869
+ - **Exponential** — snap to `{0, 1, 2, 4, 8, 16}`.
870
+ - **tShirt** — skipped with one-per-run warning (no reliable numeric → XS/S/M/L/XL mapping).
871
+ - **notUsed** — skipped silently.
872
+
873
+ Zero-config: the team's `issueEstimationType` is auto-detected per push run (one extra API round-trip, cached). TASK is deferred — one Linear TaskList issue aggregates multiple task files, so 1:1 estimate mapping doesn't apply.
874
+
875
+ ### Story body fixes
876
+
877
+ - **Empty role/goal/benefit no longer renders `As a \*\***, I want \***\* so that \*\***.`\*\* Suppresses the "As a" sentence entirely when any of the three fields is blank (or whitespace-only).
878
+ - **Gherkin scenarios now push to Linear.** Stories following the OpenPlanr convention store acceptance criteria as Gherkin in a sibling `<storyId>-gherkin.feature` file. Before this fix the push path never loaded the `.feature` content and Linear stories rendered empty for convention-following teams.
879
+ - **Epic project description trims whitespace-only fields** — no more empty `**Risks**` headers.
880
+
881
+ ### Linear label case + workspace-scope fix
882
+
883
+ `ensureIssueLabel` lookup is now **case-insensitive and workspace-wide** (matching Linear's own uniqueness rule). Previously a workspace with a `Feature` label blocked creation of `feature` with an `InvalidInput: Label already exists` error. Push now adopts the existing cross-team label instead of failing.
884
+
885
+ ### Revise — next-step guidance + rejected-proposal preservation
886
+
887
+ - Flagged outcomes now print actionable next steps (read the audit log, hand-edit, re-run with `--scope-to prose`, re-run with `--no-code-context`) instead of leaving users in a dead end.
888
+ - Demoted `revise → flag` decisions preserve the agent's rejected rewrite in the audit log as a `REJECTED by verifier` diff so users can inspect and hand-apply the parts that make sense. The file is still not written (action remains `flag`); the markdown is kept for audit purposes only.
889
+
890
+ ### BL → QT promote is now AI-driven
891
+
892
+ `planr backlog promote BL-XXX --quick` feeds the full BL markdown body (description, acceptance criteria, notes, threat models) through the same AI pipeline used by `planr quick create`, producing a realistic task breakdown instead of a single checkbox that restates the title. The new QT carries `sourceBacklog: "BL-XXX"` as provenance and inherits `epicId` from the BL (or an explicit `--epic` override) so `planr linear push EPIC-XXX` cascades to it. Use `--manual` to opt out of AI and keep the legacy single-task behavior.
893
+
894
+ ### Config additions
895
+
896
+ ```jsonc
897
+ {
898
+ "linear": {
899
+ "teamId": "UUID",
900
+ "teamKey": "ENG",
901
+ "defaultProjectLead": "UUID",
902
+ "pushStateIds": {
903
+ "pending": "UUID",
904
+ "in-progress": "UUID",
905
+ "done": "UUID"
906
+ },
907
+ "statusMap": { "In Review": "in-progress" },
908
+ "standaloneProjectId": "UUID",
909
+ "standaloneProjectName": "Planr",
910
+ "defaultEpicStrategy": "project"
911
+ }
912
+ }
913
+ ```
914
+
915
+ ## 1.2.8
916
+
917
+ ### Patch Changes
918
+
919
+ - [`2d9c113`](https://github.com/openplanr/OpenPlanr/commit/2d9c113627c0eae69611af7ee2adbde366c2799f) Add `planr revise` — agent-driven alignment of planning artifacts with codebase reality
920
+
921
+ New command complementing `planr refine` (prose polish) with a focus on _factual_ alignment:
922
+
923
+ - `planr revise <ID>` — revise a single artifact (epic / feature / story / task)
924
+ - `planr revise <ID> --cascade` — top-down revision of an artifact and its descendants (epic → features → stories → tasks); children see the _revised_ parent in their context
925
+ - `planr revise --all` — revise every epic in the project, with a content-hash cache that skips unchanged artifacts
926
+ - `--dry-run`, `--yes`, `--allow-dirty`, `--scope-to prose|references|paths|all`, `--no-code-context`, `--no-sibling-context`, `--audit-format md|json`, `--max-writes-per-run`
927
+
928
+ Four-layer safety pipeline (every run):
929
+
930
+ 1. **Clean-tree gate** — refuses to run on a dirty git working tree (override with `--allow-dirty`)
931
+ 2. **Evidence verification** — every AI citation uses a typed kind (`file_exists`, `file_absent`, `grep_match`, `sibling_artifact`, `source_quote`, `pattern_rule`); unverifiable citations are dropped. When a majority of evidence fails to verify, the decision is demoted from `revise` to `flag` so a human reviews instead of silently applying
932
+ 3. **Diff preview + confirmation** — per-artifact menu: `[a]pply / [s]kip / [e]dit rationale / [d]iff again / [q]uit`; `--yes` still requires typed "YES" at start in an interactive TTY, skipped in non-TTY (CI) environments
933
+ 4. **Post-flight graph-integrity check + git rollback** — after writes, `syncParentChildLinks` runs; if any cross-reference broke, affected artifact paths are restored via `git checkout`. This is the only v1 mechanism allowed to use the word "rollback"; atomic writes are called atomicity
934
+
935
+ Template-conformance guardrail:
936
+
937
+ - Revise is taught the canonical `## Section` set for each artifact type (from the Handlebars templates) and instructed to flag rather than add sections outside it. Prevents task-level conventions like `## Relevant Files` from leaking into epics
938
+ - Existing user-maintained custom sections are preserved byte-for-byte
939
+
940
+ Other safety properties:
941
+
942
+ - **Atomic writes** with sidecar backups (`.planr/reports/revise-<scope>-<date>/backup/`) — no partial files ever on disk
943
+ - **Facts win from code, plan wins on intent** — concrete paths and symbols are rewritten to match the repo; what the feature is _supposed to do_ is never rewritten (intent conflicts surface as `flag` with ambiguous entries)
944
+ - **Graceful mid-cascade interrupt** — Ctrl+C and `[q]uit` let any in-flight atomic write complete, stop cleanly, and flush the audit log immediately; already-applied artifacts stay applied
945
+ - **SIGINT closes the audit log cleanly** with an `interrupted: sigint` footer, so Ctrl+C at the confirmation prompt doesn't leave a half-written log
946
+
947
+ Every run emits a Markdown or JSON audit log under `.planr/reports/` capturing applied / skipped / flagged / failed artifacts with rationale, evidence, ambiguities, and unified diffs — dry-run included.
948
+
949
+ After a successful apply, revise prints:
950
+
951
+ ```
952
+ git commit -am "chore(plan): revise <SCOPE> against codebase"
953
+ ```
954
+
955
+ See the [README section on `planr revise`](https://github.com/openplanr/OpenPlanr/blob/main/README.md#planr-revise--align-planning-with-reality) for workflow examples.
956
+
957
+ ## 1.2.7
958
+
959
+ ### Patch Changes
960
+
961
+ - [`57d07b3`](https://github.com/openplanr/OpenPlanr/commit/57d07b324cd34bc8461d09ae3fc2225dc5da610f) Add stakeholder reporting & PM intelligence layer
962
+
963
+ New commands:
964
+
965
+ - `planr report <type>` — generate `sprint`, `weekly`, `executive`, `standup`, `retro`, or `release` reports from `.planr/` artifacts and (optionally) recent GitHub commits/PRs, written as Markdown + HTML under `.planr/reports/`
966
+ - `planr report-linter [file]` — validate stakeholder markdown against configurable rules (vague language, evidence density, required sections per report type) with coaching hints
967
+ - `planr context` — emit the report context pack (artifacts + sprint state + GitHub signals + flat evidence index) as JSON for piping
968
+ - `planr voice standup` — convert a transcript file or stdin into a structured Yesterday / Today / Blockers standup, with optional `--lint`, `--edit`, `--reload-file`, and `--append-story`
969
+ - `planr story standup --story <ID>` — append linted standup notes onto an existing user story
970
+
971
+ Reporting features:
972
+
973
+ - `--lint` and `--strict-evidence` quality gates so vague or unsupported claims do not ship
974
+ - `--push slack` via [Incoming Webhooks](https://api.slack.com/messaging/webhooks) (`distribution.slackWebhookUrl` in `.planr/config.json`); `--dry-run` works without a webhook configured
975
+ - `--push github` archives the report as a `planr:report` GitHub issue via the local `gh` CLI
976
+ - Optional org branding and extra sections via the `reports` block in config; optional rule overrides via the `reportLinter` block
977
+
978
+ Out of scope for this release (deferred):
979
+
980
+ - Bundled PDF rendering (`--format pdf` exits with a clear "not in this build" message)
981
+ - SMTP email delivery (the email path is a documented stub)
982
+ - Live microphone capture and bundled speech-to-text — pair `planr voice standup` with any STT or OS dictation tool
983
+ - Per-segment audio replay, Slack OAuth / multi-channel routing, native git-tree report commits, persistent cross-session coaching history
984
+
985
+ See [docs/EPIC-PM-REPORTING-LAYER.md](https://github.com/openplanr/OpenPlanr/blob/main/docs/EPIC-PM-REPORTING-LAYER.md) for the design and shipped-vs-deferred matrix.
986
+
987
+ ## 1.2.6
988
+
989
+ ### Patch Changes
990
+
991
+ - [`4cf5bcc`](https://github.com/openplanr/OpenPlanr/commit/4cf5bcc5e6e4f56bb0d59cda9cb9ba7f57115277) Replace gray-matter with yaml package to eliminate eval() vulnerability
992
+
993
+ - Remove gray-matter dependency (+ 6 transitive deps including js-yaml with eval)
994
+ - Add yaml package (zero deps, YAML 1.2 spec, no eval, maintained by YAML spec editors)
995
+ - Custom frontmatter parse/stringify in ~15 lines with robust regex handling
996
+
997
+ ## 1.2.5
998
+
999
+ ### Patch Changes
1000
+
1001
+ - [`97e34be`](https://github.com/openplanr/OpenPlanr/commit/97e34bee794585c50d6ba774d1ba0b586a130030) Add artifact update commands and GitHub issue type auto-assignment
1002
+
1003
+ - Add `planr update <ids...>` top-level command with batch support, status validation, and `--force` override
1004
+ - Add `update` subcommand to all artifact types: epic, feature, story, task, quick, backlog
1005
+ - Supported fields: `--status` (all types), `--owner` (epic/feature), `--priority` (backlog)
1006
+ - Auto-set GitHub issue types (Task, Feature) via GraphQL when pushing with `planr github push`
1007
+ - Extract shared `updateArtifactFields()` using regex-based replacement to preserve file formatting
1008
+ - Harden environment variable access with explicit allowlist in credentials-service
1009
+
1010
+ ## 1.2.4
1011
+
1012
+ ### Patch Changes
1013
+
1014
+ - [`64a0f80`](https://github.com/openplanr/OpenPlanr/commit/64a0f80fda6d6d44faff957d7064a55d6833682c) Code quality and performance improvements
1015
+
1016
+ - Faster sprint and sync commands via parallelized artifact loading
1017
+ - Consistent error messages across all AI-powered commands
1018
+ - Shared formatting utilities to reduce internal code duplication
1019
+ - JSDoc documentation added to all core service functions
1020
+
1021
+ ## 1.2.3
1022
+
1023
+ ### Patch Changes
1024
+
1025
+ - [`5551aea`](https://github.com/openplanr/OpenPlanr/commit/5551aea8113ae17af67306219c9eb22bd5405667) Add prompt injection protection with input boundary delimiters and file size validation for --file arguments
1026
+
1027
+ ## 1.2.2
1028
+
1029
+ - [`45836f9`](https://github.com/openplanr/OpenPlanr/commit/45836f99ad88605ba4aac5fab4f318b20badf5b0) Reduce AI over-engineering in plan generation with scope discipline rules, count guidance per artifact level, and anti-enumeration batching ([#62](https://github.com/openplanr/OpenPlanr/pull/62))
1030
+
1031
+ ## 1.2.1
1032
+
1033
+ - [`696da73`](https://github.com/openplanr/OpenPlanr/commit/696da735d7cdb88c3d11022233d2b17bb274ca02) Fix project root resolution for monorepos — planr now walks up the directory tree to find `.planr/config.json`, so commands work from any subdirectory ([#55](https://github.com/openplanr/OpenPlanr/pull/55))
1034
+
1035
+ ## 1.2.0
1036
+
1037
+ - [`3f47e3c`](https://github.com/openplanr/OpenPlanr/commit/3f47e3c7524cd54827cc4e63830de4bacb9f2df6) Add agent-friendly non-interactive mode and API key UX improvements
1038
+ - Add `--yes`/`-y` flag for fully unattended planning workflows (Claude Code, Cursor, Codex)
1039
+ - Auto-detect non-interactive terminals via TTY detection
1040
+ - All prompts return sensible defaults when non-interactive
1041
+ - Add `planr config remove-key` command to delete stored API keys
1042
+ - Show clear multi-line guidance when API key is not configured
1043
+ - Detect existing API keys (env var, OS keychain, encrypted file) during init
1044
+ - Replace magic numbers with named CHECKLIST constants
1045
+ - Fix TOCTOU race condition in checklist reads
1046
+
1047
+ All notable changes to this project will be documented in this file.
1048
+
1049
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
1050
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1051
+
1052
+ ## [1.1.0] - 2026-04-06
1053
+
1054
+ ### Added
1055
+
1056
+ - **`.planr/` directory** — all config and planning artifacts now live under `.planr/` instead of polluting the project root with `planr.config.json` and `docs/agile/`. IDE-required files (`CLAUDE.md`, `AGENTS.md`, `.cursor/rules/`) remain at their mandated locations
1057
+ - **Auto-generate AI agent rules on `planr init`** — creates `CLAUDE.md`, `AGENTS.md`, and `.cursor/rules/` immediately so users get working agent rules without a separate `planr rules generate` step
1058
+ - **`planr checklist toggle 1 3 5`** — direct argument support alongside interactive mode, with validation of item indices
1059
+ - **Auto-check checklist items** — `checkItem()` automatically marks checklist items as done when relevant commands complete (epic→1, feature→2, story→3, task→10)
1060
+
1061
+ ### Changed
1062
+
1063
+ - **Config path** — `planr.config.json` → `.planr/config.json`
1064
+ - **Artifact root** — `docs/agile/` → `.planr/`
1065
+ - **Cursor rule templates** — renamed from numeric prefixes (`2000-agile-checklist.mdc`) to clean descriptive names (`agile-checklist.mdc`) to avoid colliding with user's existing rule files
1066
+
1067
+ ### Fixed
1068
+
1069
+ - **Broken checklist paths** — `{{agilePath}}` template variable was missing from `createChecklist()` template data, producing broken file references
1070
+ - **Checklist toggle reporting** — direct-args mode now validates indices against actual checklist items and reports accurate update counts
1071
+
1072
+ ### Breaking Changes
1073
+
1074
+ - Existing v1.0.x projects need to re-run `planr init`
1075
+
1076
+ ## [1.0.0] - 2026-04-05
1077
+
1078
+ ### Added
1079
+
1080
+ - **`planr backlog`** — capture, prioritize, and promote work items from a lightweight backlog
1081
+ - `planr backlog add` — capture ideas with priority and tags without breaking your flow
1082
+ - `planr backlog list` — filter by tag, priority, or status; sorted by priority
1083
+ - `planr backlog prioritize` — AI scores items by impact/effort and reorders them
1084
+ - `planr backlog promote` — promote to quick task (`--quick`) or story (`--story --feature`)
1085
+ - `planr backlog close` — archive completed or irrelevant items
1086
+ - **`planr sprint`** — time-boxed iterations with velocity tracking
1087
+ - `planr sprint create` — create a sprint with name and duration (1–4 weeks); enforces one-active-at-a-time
1088
+ - `planr sprint add` — assign tasks manually or with `--auto` AI selection based on priority and velocity
1089
+ - `planr sprint status` — progress dashboard with per-task completion, progress bars, and days remaining
1090
+ - `planr sprint close` — archive sprint, list incomplete tasks, optional retrospective
1091
+ - `planr sprint list` — all sprints with status badges and task counts
1092
+ - `planr sprint history` — velocity chart with bar visualization across closed sprints
1093
+ - **`planr template`** — reusable task templates for common development workflows
1094
+ - `planr template list` — list built-in and custom templates with task counts
1095
+ - `planr template show` — preview template contents and variables
1096
+ - `planr template use` — generate task list from a template with variable substitution
1097
+ - `planr template save` — save an existing task list as a reusable custom template
1098
+ - `planr template delete` — remove a custom template
1099
+ - **5 built-in task templates** — `rest-endpoint`, `react-component`, `database-migration`, `api-integration`, `auth-flow`
1100
+ - **User-defined AI rules** — `.planr/rules.md` injected into AI prompts as mandatory project rules
1101
+ - **Auto-extracted pattern rules** — 5 heuristic detectors (generic CRUD, command registration, central types, ID generation, template rendering) produce explicit rules from architecture files
1102
+ - **Post-generation validation** — warns about modify-on-missing, create-on-existing, dependency gaps, and unknown directories before user accepts AI output
1103
+ - **Dependency chain detection** — import-based file dependency hints injected into AI context
1104
+ - **`display` utility** — 13 methods for formatted user-facing output (tables, progress bars, key-value pairs, status badges)
1105
+ - **`ArtifactFrontmatter` type** — shared typed interface for artifact frontmatter across all parsers
1106
+ - **Shared task-creation helpers** — extracted `buildTaskItems`, `displayTaskPreview`, `displayValidationWarnings`, and related helpers into reusable module
1107
+ - **ESM `exports` field** — `package.json` now declares explicit ESM entry point
1108
+ - **Dynamic CLI version** — `planr --version` reads version from `package.json` at runtime instead of hardcoding
1109
+
1110
+ ### Changed
1111
+
1112
+ - **Version** — bumped to 1.0.0
1113
+ - **Package description** — updated to reflect full planning platform: backlog, sprints, task templates, estimation, GitHub sync, and AI agent rules
1114
+ - **README** — complete rewrite with expanded feature list, backlog/sprint/template quick start, and organized command tables
1115
+ - **CLI.md** — added backlog, sprint, template, and quick task command sections; updated ID convention table, config example, workflow diagram
1116
+ - **`planr status`** — now shows backlog items with priority badges and active sprint with days remaining
1117
+ - **`planr search`** — now searches backlog and sprint artifacts
1118
+ - **Codebase context builder** — dynamic `src/` subdirectory discovery instead of hardcoded directory list; pattern rules and dependency hints injected into AI prompts
1119
+ - **Rules templates rewritten** — Cursor, Claude Code, and Codex templates replaced with 4-step context-gathering protocol (read task → walk parent chain → read ADRs → scan codebase)
1120
+ - **Sprint task entries** — now include task title and relative file link (`- [ ] **TASK-001** title — [view](...)`)
1121
+ - **Sprint auto-select** — sends subtask counts and parent feature context to AI for smarter velocity-aware selection
1122
+ - **Bare catch blocks eliminated** — 39 bare `catch {}` blocks converted to `catch (err) { logger.debug(..., err) }` for `--verbose` debuggability
1123
+ - **Strict Biome rules** — enabled `noExplicitAny`, `noNonNullAssertion`, `noConsole` as errors
1124
+ - **`@anthropic-ai/sdk`** — bumped from 0.80.0 to 0.81.0
1125
+
1126
+ ### Removed
1127
+
1128
+ - **`planr task implement` and `planr quick implement`** — coding agents (Claude Code, Cursor, Codex) handle implementation directly via generated rules
1129
+ - **`planr task fix` and `planr quick fix`** — replaced by iterative agent workflows
1130
+ - **8 agent adapter files** (~1,150 lines) — `agent-factory`, `claude-agent`, `codex-agent`, `cursor-agent`, `implementation-bridge`, `progress`, `prompt-composer`, `types`
1131
+ - **Orphaned retry utilities** — dead `MAX_RETRIES`, `isRetryableError`, `sleep` removed after agent deletion
1132
+ - **Duplicate `CodingAgentName` type** — consolidated to single definition in `models/types.ts`
1133
+
1134
+ ### Fixed
1135
+
1136
+ - **Hardcoded source inventory directories** — replaced 7-directory list with dynamic `readdir` discovery that expands into leaf directories
1137
+ - **Source inventory listing directories as files** — uses `readdir` with `withFileTypes` and `.isFile()` filter
1138
+ - **`countInventoryMatches` counting lines** — now parses comma-separated file names per inventory line
1139
+ - **Dependency chain warning wording** — "modified but" changed to "referenced but" for accuracy
1140
+ - **`displayValidationWarnings` loose typing** — `action?: string` replaced with `action: 'modify' | 'create'`
1141
+ - **`--file` flag error handling** — stack trace on bad file path replaced with user-friendly error message in quick.ts and epic.ts
1142
+ - **Rules reader empty vs missing** — `!content` replaced with explicit `content === null` check
1143
+ - **Slugify `ENAMETOOLONG` crash** — filenames truncated at 80 chars with word-boundary trimming
1144
+ - **Backlog title triplication** — title no longer repeated three times in generated backlog items
1145
+ - **Task parser bold ID regex** — fixed regex that caused empty template saves when IDs were bold-formatted
1146
+ - **Sprint "untitled" filename** — sprint creation now uses sprint name for slug instead of falling back to "untitled"
1147
+ - **Plan summary overcounting** — reports only artifacts created in current run; task generation failures no longer miscounted
1148
+ - **`truncateTitle` empty input** — guards against empty description producing empty artifact titles
1149
+ - **`progressBar` percent clamping** — clamps to [0,100] to prevent `String.repeat()` with negative count
1150
+ - **`logger.debug` Error formatting** — formats Error instances with stack traces instead of `[object Object]`
1151
+ - **Safer Map access patterns** — guarded `Map.get()` returns in sync and dependency-chains to prevent silent no-ops
1152
+
1153
+ ### Developer Experience
1154
+
1155
+ - **47 new tests** — display utility (22), task-creation helpers (21), E2E smoke (4), edge cases
1156
+ - **Coverage thresholds raised** — from 3% to 14% (lines, functions, branches, statements)
1157
+ - **`display.*` / `logger.*` separation** — formatted user-facing output vs operational messages
1158
+
1159
+ ## [0.9.0] - 2026-04-01
1160
+
1161
+ ### Added
1162
+
1163
+ - **`planr github push`** — push planning artifacts to GitHub Issues. Supports single artifact (`planr github push EPIC-001`), all artifacts under an epic (`--epic EPIC-001`), or everything (`--all`). Creates labeled issues with type-aware formatting, metadata tables, and collapsible artifact sources. Stores the GitHub issue number in artifact frontmatter for bi-directional linking
1164
+ - **`planr github sync`** — bi-directional status sync between local artifacts and GitHub Issues. Supports `--direction pull` (GitHub→local), `push` (local→GitHub), or `both` (interactive conflict resolution). Detects open/closed state changes and maps them to artifact status fields
1165
+ - **`planr github status`** — show sync status of all linked artifacts (local status vs GitHub issue state)
1166
+ - **`planr export`** — generate consolidated planning reports in markdown (`--format markdown`), JSON (`--format json`), or HTML (`--format html`). Supports epic scoping (`--scope EPIC-001`) and custom output path (`--output ./reports`). HTML reports are self-contained with collapsible sections, status badges, and inline CSS
1167
+ - **`planr epic create --file <path>`** — read epic description from a file (e.g., a PRD or requirements document) instead of single-line input. Supports multi-line documents of any size
1168
+ - **Type-aware GitHub issue formatting** — different body builders for task, epic, feature, and story artifacts with metadata tables, section reordering, and collapsible details
1169
+ - **Temp file body delivery** — uses `--body-file` for GitHub issue creation/update to avoid OS argument length limits on large artifacts
1170
+ - **Graceful deleted issue handling** — when a linked GitHub issue has been deleted, falls back to creating a new one instead of failing
1171
+ - **HTML export template** — self-contained Handlebars template with collapsible `<details>` sections, color-coded status badges, and full hierarchy rendering
1172
+
1173
+ ### Changed
1174
+
1175
+ - **Epic prompt framing** — `buildEpicPrompt()` detects detailed input (>5 lines) and uses document extraction framing instead of "brief description" framing, so AI faithfully processes large PRDs
1176
+ - **Epic system prompt** — updated to explicitly handle detailed PRD input: "extract and incorporate ALL sections — do not summarize or ignore content"
1177
+ - **Epic token budget** — increased from 4096 to 8192 to support richer output from detailed PRD input
1178
+
1179
+ ## [0.8.0] - 2026-03-31
1180
+
1181
+ ### Added
1182
+
1183
+ - **`planr estimate <id>`** — AI-powered effort estimation for any artifact (task, story, feature, epic, quick). Returns story points (Fibonacci 1-21), estimated hours, complexity, risk factors, and reasoning
1184
+ - **`planr estimate --epic <id>`** — Estimates all tasks under an epic and produces a rollup table with total points and hours
1185
+ - **`planr estimate --calibrate`** — Accuracy report from past estimates on completed artifacts
1186
+ - **`planr estimate --save`** — Persists estimate to artifact frontmatter (`estimatedPoints`, `estimatedHours`, `complexity`) and appends a full `## Estimate` section to the artifact body
1187
+ - **Interactive estimate prompt** — After displaying results, prompts to save, re-estimate, or discard (single artifact) or save all / discard all (epic rollup)
1188
+ - **`planr search <query>`** — Full-text search across all artifact types with highlighted snippets and 1 line of context
1189
+ - **`planr search --type <type>`** — Filter search by artifact type (epic, feature, story, task, quick, adr)
1190
+ - **`planr search --status <status>`** — Filter search results by artifact status
1191
+ - **`docs/agile/ESTIMATION.md`** — Estimation rubric generated by `planr init` with the full Fibonacci scale, complexity levels, risk categories, and team calibration guidance
1192
+
1193
+ ### Fixed
1194
+
1195
+ - **Estimate save preserves frontmatter formatting** — Injects estimate fields directly into raw YAML without re-serializing through gray-matter, so original quoting and structure is preserved
1196
+ - **Legacy `estimatedEffort` field cleanup** — Free-text `estimatedEffort` fields added by AI during task generation are removed when saving a structured estimate
1197
+
1198
+ ### Changed
1199
+
1200
+ - **Estimation AI prompt** — Embeds the full story point rubric (Fibonacci scale definitions, complexity levels, risk categories) for consistent and calibrated scoring across all artifacts
1201
+
1202
+ ## [0.7.0] - 2026-03-31
1203
+
1204
+ ### Added
1205
+
1206
+ - **`planr quick`** — standalone task lists without the full agile hierarchy (Epic → Feature → Story → Task). Ideal for prototyping, bug fixes, hackathons, or any work that doesn't need agile ceremony
1207
+ - **`planr quick create`** — AI generates a structured task list from a one-line description, with codebase-aware context and relevant file detection
1208
+ - **`planr quick --manual`** — interactive task entry without AI
1209
+ - **`planr quick list`** — list all quick task lists
1210
+ - **`planr quick promote`** — graduate a quick task into the agile hierarchy by attaching to a story or feature
1211
+ - **Auto-mark subtasks as done** — after a coding agent completes successfully, implemented subtask checkboxes are automatically checked off in the task markdown
1212
+ - **Quick tasks in `planr status`** — standalone quick tasks shown in their own section with completion metrics
1213
+
1214
+ ### Fixed
1215
+
1216
+ - **Claude retry for stdout API errors** — "API Error: 400 due to tool use concurrency" was emitted via stdout (stream-json) rather than stderr, so the retry logic never caught it. Now checks both streams for retryable errors
1217
+
1218
+ ### Type System
1219
+
1220
+ - Added `'quick'` to `ArtifactType` union
1221
+ - Made `TaskList.storyId` optional (quick tasks have no parent story)
1222
+ - Added `QT` prefix to ID system and `quick/` directory to artifact mapping
1223
+
1224
+ ## [0.6.0] - 2026-03-29
1225
+
1226
+ ### Added
1227
+
1228
+ - **Error context helper** — truncates large build logs for clearer failure output
1229
+
1230
+ ### Fixed
1231
+
1232
+ - **Agent hangs on large prompts** — implementation prompt is delivered via temp file + stdin pipe instead of a giant CLI argument (avoids OS argv limits and interactive “wait forever” behavior)
1233
+ - **Stream backpressure** — prompt delivery uses `createReadStream` → `stdin` pipe instead of buffered `stdin.write`
1234
+ - **Codex sandbox** — `--full-auto` and `--json` so Codex can write files and emit structured events (matches Claude-style progress output)
1235
+ - **Claude stderr** — retryable 400/429/5xx errors detected while still showing output in real time
1236
+
1237
+ ### Changed
1238
+
1239
+ - **Agent stdout/stderr** — `stdio: inherit` for live agent output where applicable
1240
+ - **Safety** — system prompt guidance to reduce destructive cross-project commands
1241
+
1242
+ ### Developer Experience
1243
+
1244
+ - **Linting and formatting** — ESLint and Prettier replaced with [Biome](https://biomejs.dev/) (`biome check` / `biome format`)
1245
+
1246
+ ## [0.5.0] - 2026-03-28
1247
+
1248
+ ### Added
1249
+
1250
+ - **Secure credential storage** — API keys are now stored in the OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service) via `@napi-rs/keyring`, with AES-256-GCM encrypted file fallback for environments without a keychain (CI, Docker, SSH)
1251
+ - **Automatic credential migration** — existing plaintext `~/.planr/credentials.json` keys are migrated to the secure backend on first access, then the plaintext file is deleted
1252
+ - **Credential source display** — `planr config show` now shows where the API key is stored: `(OS keychain)`, `(encrypted file)`, or `(env: ANTHROPIC_API_KEY)`
1253
+ - **Per-command token budgets** — each command uses a tuned `maxTokens` limit (epic: 4K, feature/story/refine: 8K, task: 16K, task --feature: 32K) instead of a one-size-fits-all default
1254
+ - **Definitive truncation detection** — uses `stop_reason` (Anthropic) / `finish_reason` (OpenAI) to detect truncated responses instead of heuristic token thresholds
1255
+ - **8 new truncation unit tests** covering skip-retry, per-attempt token reporting, and streaming truncation
1256
+
1257
+ ### Changed
1258
+
1259
+ - **`planr config set-key`** now shows the storage backend: `"saved to OS keychain"` or `"saved to encrypted file"`
1260
+ - **AI service refactored** — `generateJSON` and `generateStreamingJSON` now share a common `generateCore()` function, eliminating duplicated validation/retry/truncation logic
1261
+ - **GitHub Actions** updated to v6 (checkout, setup-node) and v7 (upload-artifact) with Node.js 24
1262
+
1263
+ ### Fixed
1264
+
1265
+ - **Task generation from features failing** — `planr task create --feature` was truncating AI responses at 4,096 tokens, producing invalid JSON. Now uses 32K budget
1266
+ - **Spinner not stopping on API errors** — spinner animation no longer mixes with error messages when the AI provider throws
1267
+ - **Spinner showing ✓ before validation** — `succeed()` now only fires after successful parse/validation, not before
1268
+ - **Truncation error over-reporting tokens** — error messages now show per-attempt output tokens instead of cumulative totals
1269
+ - **Keychain write failures crashing** — `saveCredential` now catches keychain errors and falls back to encrypted file
1270
+ - **Migration flag set before completion** — `migrateCredentials` now resets the flag on failure so it retries next invocation
1271
+ - **`resolveApiKeySource` skipping migration** — `config show` now properly triggers legacy credential migration
1272
+
1273
+ ### Security
1274
+
1275
+ - API keys no longer stored in plaintext on disk
1276
+ - Encrypted file uses AES-256-GCM with machine-derived key (hostname + username + per-installation salt via scrypt)
1277
+ - File permissions set to `0o600` on all credential files
1278
+
1279
+ ### Developer Experience
1280
+
1281
+ - Test coverage: 261 → 269 tests across 23 test files
1282
+ - Added `tests/unit/ai-service-truncation.test.ts` (8 tests)
1283
+ - Added `tests/unit/credential-backends.test.ts` (8 tests)
1284
+ - Expanded `tests/unit/credentials-service.test.ts` with mocked backends (13 tests)
1285
+
1286
+ ## [0.4.0] - 2026-03-28
1287
+
1288
+ ### Added
1289
+
1290
+ - **Token usage display** — shows input/output token counts after every AI call (`✓ Done (1,240 in → 860 out tokens)`)
1291
+ - **`planr refine --cascade`** — refines an artifact then cascades to all children down the full hierarchy (epic → features → stories → tasks)
1292
+ - **Parent-aligned refinements** — child refinements receive updated parent content as context so AI aligns changes with the parent
1293
+ - **Post-refine next steps** — after applying without `--cascade`, suggests which children may need re-alignment
1294
+ - **Cumulative token usage** for cascade operations (`Cascade complete: 7 artifacts refined (12,400 in → 8,200 out tokens total)`)
1295
+ - **Spinner `succeed()` method** — shows green checkmark with completion message instead of silently clearing
1296
+
1297
+ ### Changed
1298
+
1299
+ - **Updated all dependencies** to latest major versions: `@anthropic-ai/sdk` 0.80, `openai` 6.x, `zod` 4.x, `commander` 14.x, `@inquirer/prompts` 8.x, `typescript` 6.x, `vitest` 4.x
1300
+ - **Removed `fs-extra`** dependency — replaced with Node.js built-in `fs/promises`
1301
+ - **Removed `ora`** dependency — replaced with lightweight built-in spinner
1302
+ - **Dropped Node 18 support** — minimum Node version is now 20
1303
+ - **Refine prompt** now preserves existing cross-reference links instead of adding phantom references
1304
+ - **"Suggestions" renamed to "Improvements"** in refine output for clearer UX
1305
+
1306
+ ### Fixed
1307
+
1308
+ - **Refine command** no longer adds feature/story references that don't exist on disk
1309
+ - **CI publish workflow** — fixed npm trusted publishing with bypass 2FA token
1310
+
1311
+ ## [0.3.0] - 2026-03-28
1312
+
1313
+ ### Added
1314
+
1315
+ - **`planr story create --epic <ID>`** — batch-generate stories for all features under an epic
1316
+ - **`planr checklist toggle`** — interactively toggle checklist items with multi-select prompt
1317
+ - **`planr config set-provider/set-key/set-model/set-agent`** — full AI configuration commands
1318
+ - **`--verbose` global flag** — debug logging across all commands
1319
+ - **`--all` flag on `planr status`** — show all items without truncation
1320
+ - **`--manual` flag** on epic, feature, story, and task create commands
1321
+ - **`--feature` filter** on `planr story list`
1322
+ - **Integration test suite** with real file system tests for artifact lifecycle and sync
1323
+ - **Test helpers** (`createTestProject`, `writeSampleEpic/Feature/Story`) for integration testing
1324
+ - **Pre-commit hooks** with husky + lint-staged (runs related tests on commit)
1325
+ - **Coverage reporting** with `@vitest/coverage-v8` and CI artifact upload
1326
+ - **CODEOWNERS** file for automatic review assignment
1327
+ - **Architecture guide** (`docs/ARCHITECTURE.md`)
1328
+ - **Troubleshooting guide** (`docs/TROUBLESHOOTING.md`)
1329
+ - **Security policy**, issue templates, and PR template
1330
+
1331
+ ### Changed
1332
+
1333
+ - **`planr status`** — enhanced with tree view (epic → features → stories), task completion metrics with color-coded progress, and overall completion summary
1334
+ - **`planr refine`** — apply action now works: writes improved markdown to disk with view/apply/skip options
1335
+ - **`planr checklist show`** — now displays color-coded completion progress
1336
+ - **Documentation** — CLI.md now covers all 25 command variants with complete option tables
1337
+ - **README commands table** — expanded from 19 to 25 entries
1338
+
1339
+ ### Fixed
1340
+
1341
+ - **Refine command** returning JSON instead of markdown in `improvedMarkdown` field — added explicit prompt instructions and JSON-detection fallback
1342
+ - **ID gap-filling** — `getNextId()` now reuses gaps (e.g., TASK-001 if only TASK-002 exists)
1343
+ - **npm bin paths** — added `./` prefix to suppress publish warnings
1344
+
1345
+ ### Security
1346
+
1347
+ - Bumped `handlebars` from 4.7.8 to 4.7.9 (fixes critical vulnerability)
1348
+ - Dropped Node 18 support (EOL) — minimum Node 20
1349
+
1350
+ ### Developer Experience
1351
+
1352
+ - Test coverage: 3 → 15 test files, 167 tests passing
1353
+ - Unit tests for: task-parser, markdown, fs, id-service, artifact-service, config-service, template-service, prompt-builder, logger, checklist-service
1354
+ - Integration tests for: artifact lifecycle, sync command
1355
+ - CI runs coverage on Node 22 with summary artifact upload
1356
+ - Upgraded to vitest 4.x
1357
+
1358
+ ## [0.2.0] - 2026-03-27
1359
+
1360
+ ### Added
1361
+
1362
+ - **`planr plan`** — full automated flow (Epic → Features → Stories → Tasks)
1363
+ - **`planr refine <ID>`** — AI-powered review and improvement suggestions
1364
+ - **`planr sync`** — validate and fix cross-references across artifacts
1365
+ - **`planr config show`** — display current configuration
1366
+ - **`planr task create --feature <ID>`** — AI task list from every story under the feature, with parent feature and epic, all Gherkin files for those stories, all ADRs, and codebase-derived context (higher output token budget than per-story task create)
1367
+ - Feature-level task generation shares the same rich context model as `--story`, aggregated across the feature
1368
+
1369
+ ## [0.1.0] - 2026-03-26
1370
+
1371
+ ### Added
1372
+
1373
+ - **CLI tool** with `planr` command (alias: `opr`)
1374
+ - **`planr init`** — initialize project with config and agile directory structure
1375
+ - **`planr epic create/list`** — create and list epics
1376
+ - **`planr feature create/list`** — create features from epics
1377
+ - **`planr story create/list`** — create user stories with Gherkin acceptance criteria
1378
+ - **`planr task create/list`** — task lists from a story or from all stories in a feature (AI mode includes epic, feature, Gherkin, ADRs, codebase context)
1379
+ - **`planr checklist show/reset`** — agile development checklist
1380
+ - **`planr rules generate`** — generate AI agent rule files
1381
+ - Cursor (`.cursor/rules/*.mdc`)
1382
+ - Claude Code (`CLAUDE.md`)
1383
+ - Codex (`AGENTS.md`)
1384
+ - **`planr status`** — project planning progress overview
1385
+ - Handlebars template system for all artifact generation
1386
+ - Zod schema validation for configuration
1387
+ - Auto-incrementing ID system (EPIC-001, FEAT-001, US-001, TASK-001)
1388
+ - Full agile hierarchy enforcement (epic > feature > story > task)