@getpipher/armory-todo 0.5.5 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
  </p>
17
17
 
18
18
  <p align="center">
19
- <strong>lifecycle boxes</strong> · <strong>title + notes</strong> · <strong>auto-prune</strong> · <strong>interactive panel</strong> · <strong>health diagnostics</strong> · <strong>hard-prune gate</strong>
19
+ <strong>lifecycle boxes</strong> · <strong>title + notes</strong> · <strong>auto-prune</strong> · <strong>source-aware reap safety</strong> · <strong>interactive panel</strong> · <strong>health diagnostics</strong> · <strong>hard-prune gate</strong>
20
20
  </p>
21
21
 
22
22
  ---
@@ -25,8 +25,9 @@
25
25
 
26
26
  The package `exports` entry (`./src/index.ts`) is the **stable public surface** —
27
27
  `addTodo`, `listTodos`, `updateTodo`, `getTodo`, `completeTodo`, `parkTodo`,
28
- `deleteTodo`, and the `Todo` / `AddInput` / `UpdateInput` / `ListFilter` /
29
- `Priority` / `Status` / `Store` types (plus `TodoError`). Other `src/*` paths
28
+ `deleteTodo`, `loadStore`, `saveStore`, and the `Todo` / `AddInput` /
29
+ `UpdateInput` / `ListFilter` / `Priority` / `Status` / `Store` /
30
+ `SaveStoreOptions` types (plus `TodoError`). Other `src/*` paths
30
31
  are internal and may change without notice. Depend on `@getpipher/armory-todo`
31
32
  (the public entry), never deep-import `src/*`.
32
33
 
@@ -77,6 +78,17 @@ reports what moved (`auto-pruned N stale done (>7d): …` + a `restore` hint);
77
78
  it's a transient message, not a prompt injection. Reversible via `restore <id>`.
78
79
  `prune --all` (move fresh done too) and `prune --hard` (irreversible) stay manual.
79
80
 
81
+ **Source-aware stale-active reap (v0.6.0):** producers can leave tracked todos
82
+ `open`/`in_progress` forever when a worker dies before reporting a terminal
83
+ status. On `session_start`, armory-todo now self-heals configured producer
84
+ sources: stale `armory-fleet` todos (default: untouched for 2d) become
85
+ `cancelled` and move directly to the archive, where `restore <id>` works
86
+ immediately. Real/manual todos are never auto-mutated; non-policy active todos
87
+ untouched for 14d get an advisory `ORPHAN` health flag and ⌛ panel marker.
88
+ Both thresholds are editable in the Config tab. Expected live→archive drops
89
+ keep rolling backup, drop-snapshot, and audit protection without emitting a
90
+ false wipe alert.
91
+
80
92
  The only irreversible action is `prune --hard` (hard-prune) — it requires an
81
93
  explicit `confirm: true` and is always user-confirmed. See **Self-awareness**
82
94
  below.
@@ -87,7 +99,7 @@ below.
87
99
  ~/.pi/agent/todo/
88
100
  todo.json # active + parked
89
101
  todo-archive.json # done + cancelled (sealed history)
90
- todo.config.json # prune ages + health thresholds
102
+ todo.config.json # prune/health/reap thresholds + notify settings
91
103
  ```
92
104
 
93
105
  A v1 single-file store at `~/.pi/agent/todo.json` is migrated automatically on
@@ -136,6 +148,47 @@ Three caps keep the store (and its auto-injected prompt block) from bloating sil
136
148
 
137
149
  **Backwards-compat:** zero migration (store v3, config v1, registry v1 unchanged in shape). Oversize notes grandfathered. The `maxOpen` advisory→enforced graduation is a documented behavior change for any v0.4.0 user who set a slot (the block message tells them how to raise/clear).
138
150
 
151
+ ## Agent-validated triage (`/todo triage`)
152
+
153
+ Rules alone can't clean a store that accretes agent-run debris, stale backlog,
154
+ and prune hesitation. Triage adds judgment: one command that gathers
155
+ candidates, has the agent validate each against a versioned rubric, and closes
156
+ nothing without an explicit batch approval.
157
+
158
+ ```
159
+ /todo triage [scope] [--yes]
160
+ 1. GATHER stale(30d) + orphans(14d) + over-cap projects + agent-source items
161
+ 2. VALIDATE agent checks each candidate (read-only git/gh/npm probes — rubric ships in-package: src/triage-prompt.ts)
162
+ 3. PROPOSE table: verdict + evidence + confidence
163
+ 4. APPROVE one batch confirm — nothing mutates before it (the load-bearing gate)
164
+ 5. EXECUTE close(cancel) / park / keep → one prune --all sweep (reversible)
165
+ 6. FILE each closed item as a CLOSED issue in the private getpipher/todo-ledger
166
+ 7. REPORT before/after counts, filed links, anything deferred
167
+ ```
168
+
169
+ Safety rails (the point of the feature):
170
+
171
+ - **No silent close, ever.** The agent classifies; only the user's batch
172
+ approval mutates. `--yes` (`autoSafe:true`) executes ONLY the mechanical safe
173
+ class — fleet-run prompt debris (prompt-shaped title + agent context) — and
174
+ still reports what it closed. Unverifiable items stay proposals; zero
175
+ false-closes is the success metric.
176
+ - **The ledger never blocks.** Issues are matched by client-side title search
177
+ (idempotent — GitHub's search index lags fresh issues), created then PATCHed
178
+ closed, labeled `todo-archive` + `project/<name>` + `verdict/cancel`, and
179
+ embed the full original note. gh down → items archive locally anyway and the
180
+ skip is reported; `TODO_TRIAGE_SKIP_FILING=1` forces that path (air-gapped
181
+ runs). `TODO_LEDGER_REPO` overrides the repo for scratch runs.
182
+ - **The rubric is versioned** (`triage-rubric/v1`) and ships in the package —
183
+ judgment quality evolves deliberately, not per-session.
184
+ - Composes with the existing machinery: thresholds come from
185
+ `health.activeStaleDays` / `reap.orphanFlagAfterDays`, over-cap from the
186
+ registry, and reap-policy sources stay owned by the v0.6.0 auto-reap.
187
+
188
+ A Triage tab in the interactive panel is planned for v2; today the loop runs
189
+ through the agent (the tool returns the candidates + rubric, the agent
190
+ validates and proposes, you approve, one `approve:[…]` call executes + files).
191
+
139
192
  ## Interactive panel (SPEC-3)
140
193
 
141
194
  Run `/todo` (no arg) in a TUI session to open the interactive triage panel:
@@ -177,6 +230,7 @@ Typed subcommands (`/todo park <id>`, `/todo prune`, etc.) all still work alongs
177
230
  /todo prune --hard permanent deletion (interactive confirm prompt)
178
231
  /todo archive [filter] archive summary, or filtered slice (project:X / text:Y)
179
232
  /todo health bloat report across all boxes + flags + suggestions
233
+ /todo triage [scope] [--yes] agent-validated prune: gather → validate → propose → approve → close/park → file to ledger
180
234
  /todo clean clear all done (deprecated — use prune)
181
235
  /todo path show the store file path
182
236
  ```
@@ -196,6 +250,7 @@ Typed subcommands (`/todo park <id>`, `/todo prune`, etc.) all still work alongs
196
250
  | `restore` | `id` | bring an archived TODO back as open |
197
251
  | `health` | (none) | bloat report across active/parked/archive + flags + suggestions |
198
252
  | `prune` (hard) | `hard:true`, `confirm:true`, `box?`, `olderThan?`, `project?`, `tag?` | PERMANENT deletion — the only irreversible action |
253
+ | `triage` | `scope?`, `autoSafe?`, `approve?: [{id, verdict, reason?, evidence?, confidence?, survivorId?}]` | two-phase agent-validated prune: bare call gathers candidates + returns the versioned rubric (nothing mutates); `autoSafe` executes ONLY mechanical debris; `approve` executes the user-approved batch, sweeps the archive, and files closed items to the private ledger
199
254
  | `clear` | `status?` (default `done`) | bulk-clear a status (deprecated — use prune) |
200
255
 
201
256
  Each TODO carries `id, title (≤120 chars), notes (any length), project, tags, priority (low|med|high|critical), status (open|in_progress|parked|done|cancelled), source, createdAt, updatedAt, closedAt`. The auto-injected block + list/panel show `title` only; `notes` is read via `get` and never injected.
@@ -206,9 +261,11 @@ Each TODO carries `id, title (≤120 chars), notes (any length), project, tags,
206
261
  - **`todo` tool** — model CRUD + lifecycle (above).
207
262
  - **`/todo` command** — human triage (above).
208
263
  - **Auto-inject** — on every `before_agent_start`, a compact `## Open TODOs (N)` block (titles + ids, sorted by priority) is appended to the system prompt, so the agent starts every turn already aware of pending work. The block is **cap-aware** (v0.5.0): under `health.activeMaxOpen` (default 15) it lists the rows; **over** the cap it collapses to a lean summary (counts + over-budget projects + a `todo list` pointer) so the prompt stays bounded when the store bloats. Only `open` + `in_progress` are injected — `parked` and archived todos are excluded (the lifecycle-box boundary). Mutations refresh it on the next turn.
264
+ - **Source-aware safety protocol** — on `session_start`, policy-source stale actives (default `armory-fleet` >2d) move live→archive as immediately-restorable `cancelled` records. Non-policy stale actives are flagged only; never mutated. The Archive tab reports the cumulative number of auto-reaped runs.
209
265
  - **Archive query** — `list` with `archived:true` is summary-first (counts by project + month) then filtered/paginated on demand, so a large archive never bloats a single query.
210
266
 
211
267
  Full design + decisions:
268
+ - v0.6.0 (source-aware reap safety protocol): [`docs/superpowers/specs/2026-07-29-reap-safety-protocol-design.md`](docs/superpowers/specs/2026-07-29-reap-safety-protocol-design.md)
212
269
  - v0.4.0 (project-scope management): [`docs/superpowers/specs/2026-07-21-project-scope-management-design.md`](docs/superpowers/specs/2026-07-21-project-scope-management-design.md)
213
270
  - v0.3.1 (auto-prune + unified Done view): [`docs/superpowers/specs/2026-07-21-auto-prune-done-view-design.md`](docs/superpowers/specs/2026-07-21-auto-prune-done-view-design.md)
214
271
  - v0.3.0 (title + notes split): [`docs/superpowers/specs/2026-07-21-title-notes-split-design.md`](docs/superpowers/specs/2026-07-21-title-notes-split-design.md)
@@ -230,15 +287,25 @@ Full design + decisions:
230
287
  "health": { "activeMaxOpen": 15, "activeStaleDays": 30, "parkedMax": 10,
231
288
  "parkedStaleDays": 60, "archiveMax": 200, "archiveOldDays": 180,
232
289
  "perProjectDefaultMax": 8, "maxNotesBytes": 8192 },
233
- "notify": { "sessionStartCount": true }
290
+ "notify": { "sessionStartCount": true },
291
+ "reap": {
292
+ "orphanFlagAfterDays": 14,
293
+ "policy": { "armory-fleet": { "reapAfterDays": 2, "reapTo": "cancelled" } }
294
+ }
234
295
  }
235
296
  ```
236
297
 
237
298
  | `notify.*` | default | purpose |
238
299
  |---|---|---|
239
- | `sessionStartCount` | `true` | Show the `armory-todo: N open TODOs` startup line. Set `false` to silence it — safety messages (wipe-recovery alert, auto-prune undo info) still surface. |
300
+ | `sessionStartCount` | `true` | Show the `armory-todo: N open TODOs` startup line. Set `false` to silence it — safety messages (wipe recovery, auto-prune, reap) still surface. |
301
+
302
+ | `reap.*` | default | purpose |
303
+ |---|---:|---|
304
+ | `orphanFlagAfterDays` | `14` | Advisory ORPHAN threshold for active todos whose source is not auto-reaped; never mutates them. |
305
+ | `policy.armory-fleet.reapAfterDays` | `2` | Move stale fleet-tracked active todos directly to archive as cancelled. |
306
+ | `policy.armory-fleet.reapTo` | `cancelled` | Fixed reversible terminal status; `done` is intentionally unsupported. |
240
307
 
241
- Run the store tests: `npm test` (315/315 across 11 suites).
308
+ Run the store tests: `npm test` (497/497 across 15 suites).
242
309
 
243
310
  ## Known issues
244
311