artshelf 0.5.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -51,6 +51,21 @@
51
51
  available below the lead.
52
52
  - Tightened the portable agent skill description so the completion-gate trigger
53
53
  is visible before final responses, status updates, handoffs, and done reports.
54
+ - Added packaged `ArtshelfReviewReport` schema and canonical example files for
55
+ deterministic agent review reports, plus deterministic footnote guidance for
56
+ `artshelf put --json` registrations.
57
+
58
+ ## [0.6.0](https://github.com/calvinnwq/artshelf/compare/artshelf-v0.5.0...artshelf-v0.6.0) (2026-06-07)
59
+
60
+
61
+ ### Features
62
+
63
+ * **artshelf:** add public review report assets ([6bc89ae](https://github.com/calvinnwq/artshelf/commit/6bc89ae78150bbb161a387f844f32c7ac23f30da))
64
+
65
+
66
+ ### Bug Fixes
67
+
68
+ * **docs:** constrain review approval targets ([eccc16d](https://github.com/calvinnwq/artshelf/commit/eccc16d019f1245a9ab052db51137654a2c3363b))
54
69
 
55
70
  ## [0.5.0](https://github.com/calvinnwq/artshelf/compare/artshelf-v0.4.1...artshelf-v0.5.0) (2026-06-05)
56
71
 
package/README.md CHANGED
@@ -243,15 +243,18 @@ quickstart, agent usage, and CLI reference. The source repo also keeps the
243
243
 
244
244
  The package includes an agent-facing skill at `skills/artshelf/SKILL.md`. Agents
245
245
  that support local skills can copy or reference this file to learn when to call
246
- `artshelf put`, how to report Artshelf ids in handoffs and issue comments, why
247
- `artshelf find` / `artshelf get` are the read-only idempotency lookup surface, why
248
- `cleanup --execute` requires explicit approval for a reviewed plan id, how to
249
- review trashed records with `artshelf trash list` before a separately approved trash
250
- purge, and when `artshelf resolve <id> --status resolved --reason <text>` may mark
251
- confirmed handled, missing, or no-longer-needed records without moving or
252
- deleting files.
253
-
254
- The same skill ships in the npm package. From a source checkout, use
246
+ `artshelf put`, how to report deterministic Artshelf footnotes after JSON
247
+ registration, why `artshelf find` / `artshelf get` are the read-only idempotency
248
+ lookup surface, why `cleanup --execute` requires explicit approval for a
249
+ reviewed plan id, how to render dry-run cleanup and trash purge plans as
250
+ review-report decision packets, how to review trashed records with
251
+ `artshelf trash list` before a separately approved trash purge, and when
252
+ `artshelf resolve <id> --status resolved --reason <text>` may mark confirmed
253
+ handled, missing, or no-longer-needed records without moving or deleting files.
254
+
255
+ The same skill ships in the npm package alongside
256
+ `schemas/artshelf-review-report.schema.json` and the canonical
257
+ `examples/artshelf-review-report.json` packet. From a source checkout, use
255
258
  `skills/artshelf/SKILL.md` directly. Agents should ask where the user wants
256
259
  Artshelf cloned before installing or linking it.
257
260
 
package/SPEC.md CHANGED
@@ -597,11 +597,26 @@ Agents may run `artshelf find` and `artshelf get` before `put` to avoid duplicat
597
597
  registrations. `find`/`get` are read-only ledger queries; they must not be used
598
598
  as permission to clean up or resolve a record.
599
599
 
600
+ When `artshelf put --json` succeeds, agents should include a deterministic
601
+ Artshelf footnote in the same handoff, status, final response, or run summary
602
+ that mentions the artifact:
603
+
604
+ ```text
605
+ Artshelf footnote: registered <artifact-path> as <artshelf-id>; reason: <short reason>; due: <YYYY-MM-DD|manual-review>; cleanup=<cleanup-mode>.
606
+ ```
607
+
600
608
  Agents may run `artshelf resolve <id> --status resolved --reason <text>` only
601
609
  after explicit confirmation that the record has been handled, is missing, or is
602
610
  no longer needed. The reason must be specific; resolve does not move or delete
603
611
  files.
604
612
 
613
+ For batches of missing-path records, agents should ask for exact approval before
614
+ resolving:
615
+
616
+ ```text
617
+ approve artshelf resolve missing ledger <ledger-path> ids <id...>
618
+ ```
619
+
605
620
  Scheduled jobs may run:
606
621
 
607
622
  ```bash
@@ -626,6 +641,15 @@ registered-ledger discovery and should include trashed record counts and target
626
641
  ages. Purge dry-runs stay scoped to one explicit ledger and should report any
627
642
  plan id, matching entries, and skipped entries.
628
643
 
644
+ When a scheduled review or dry-run produces cleanup or trash purge plans,
645
+ deterministic integrations should build an `ArtshelfReviewReport` packet first,
646
+ then render a compact decision report from it. The packet schema is
647
+ `schemas/artshelf-review-report.schema.json`, the canonical example is
648
+ `examples/artshelf-review-report.json`, and packaged docs/skills carry matching
649
+ copies for browsable docs and portable agent installs. The report groups
650
+ decisions into ready-for-approval, needs-review-first, and blocked sections, and
651
+ must still include exact approval targets in the message body.
652
+
629
653
  Scheduled jobs must never run `artshelf cleanup --execute` or
630
654
  `artshelf trash purge --execute`; they may only dry-run and report plans for later
631
655
  human review.
@@ -666,6 +690,8 @@ human review.
666
690
  - CLI can list trashed records (single ledger or `--all`) and purge them through
667
691
  an approval-first, ledger-scoped dry-run/execute boundary that writes a purge
668
692
  receipt; purge refuses `--all` and never deletes without a reviewed plan id.
693
+ - Package includes the deterministic `ArtshelfReviewReport` schema and canonical
694
+ example for agent-rendered review reports.
669
695
  - All core commands support `--json`.
670
696
  - Tests cover record/list/find/get/status-filter/due/validate/resolve/registry,
671
697
  `artshelf doctor`, the `artshelf status` dashboard, `--all` review, stale-registry,
@@ -193,8 +193,79 @@ artshelf trash list --all --json</code></pre>
193
193
  <pre><code>artshelf trash list --ledger &lt;ledger-path&gt;
194
194
  artshelf trash purge --older-than 7d --dry-run --ledger &lt;ledger-path&gt; --json
195
195
  artshelf trash purge --execute --plan-id &lt;purge-plan-id&gt; --ledger &lt;ledger-path&gt; --json</code></pre>
196
+ <h3>Review Plan Report Schema</h3>
197
+ <p>
198
+ When a dry-run creates or reuses a cleanup or trash purge plan, surface the
199
+ plan in a compact human-readable report. The report should let the user
200
+ approve, ask for changes, or request alternatives without opening the plan
201
+ file.
202
+ </p>
203
+ <p>
204
+ For deterministic agent integrations, construct an
205
+ <code>ArtshelfReviewReport</code> JSON object first, then render it to text.
206
+ Use <a href="schemas/artshelf-review-report.schema.json">schemas/artshelf-review-report.schema.json</a>
207
+ for the packet shape and
208
+ <a href="examples/artshelf-review-report.json">examples/artshelf-review-report.json</a>
209
+ as the canonical example. The schema locks report structure; the CLI output
210
+ and approval rules still define cleanup safety.
211
+ </p>
212
+ <p>
213
+ Render the JSON packet as a compact decision card using
214
+ <code>decisionSummary</code> and <code>decisionGroups</code>. Lead with
215
+ counts, then show exactly what is ready for approval and what needs review
216
+ first. Emojis are encouraged when the host renders them well because they
217
+ make review groups scannable; omit them only for plain-text or
218
+ accessibility-constrained surfaces.
219
+ </p>
220
+ <pre><code>Artshelf daily review
221
+ Status: &lt;ok|attention needed&gt;; registry &lt;ok|attention&gt;
222
+
223
+ ✅ Ready for approval: &lt;n&gt;
224
+ 👀 Needs review first: &lt;n&gt;
225
+ ⚠️ Blocked: &lt;n&gt;
226
+
227
+ Recommendation
228
+ &lt;one short sentence with the next safest action&gt;.
229
+
230
+ Ready for approval
231
+ 1. &lt;short item label&gt;
232
+ Why: &lt;short reason&gt;
233
+ Action: &lt;what approval will do&gt;
234
+ approve artshelf cleanup ledger &lt;ledger-path&gt; plan &lt;plan-id&gt;
235
+
236
+ 2. &lt;short item label&gt;
237
+ Why: &lt;short reason&gt;
238
+ Action: &lt;ledger-only update, no file changes&gt;
239
+ approve artshelf resolve missing ledger &lt;ledger-path&gt; ids &lt;id...&gt;
240
+
241
+ Needs review first
242
+ 1. &lt;short item label&gt;
243
+ Why: &lt;short reason&gt;
244
+ Suggested next step: inspect path, then choose keep, change retention, resolve, or clean up later
245
+ Path: &lt;path&gt;
246
+
247
+ Blocked
248
+ &lt;none, or the registry/refused/missing-path blocker and next repair step&gt;
249
+
250
+ Safety
251
+ Dry-run only. No execute, resolve, or delete ran.</code></pre>
252
+ <p>
253
+ Keep the full <code>ArtshelfReviewReport</code> JSON as the audit packet
254
+ and include it as an attachment, linked file, or expandable detail when the
255
+ host supports that. Do not paste the whole packet into chat unless the user
256
+ asks for it. For long plans, show only the first 3 to 5 decisions under
257
+ each visible group, then state the hidden count by group and classification.
258
+ Do not hide refused, registry-problem, or missing-path items.
259
+ </p>
260
+ <p>
261
+ If the host supports buttons, menus, or other interactive controls, they
262
+ should emit exact text commands such as the approval targets below. Always
263
+ include the exact approval target in the message body as a fallback for
264
+ clients where those controls do not render.
265
+ </p>
196
266
  <pre><code>approve artshelf cleanup ledger &lt;ledger-path&gt; plan &lt;plan-id&gt;
197
- approve artshelf trash purge ledger &lt;ledger-path&gt; plan &lt;purge-plan-id&gt;</code></pre>
267
+ approve artshelf trash purge ledger &lt;ledger-path&gt; plan &lt;purge-plan-id&gt;
268
+ approve artshelf resolve missing ledger &lt;ledger-path&gt; ids &lt;id...&gt;</code></pre>
198
269
  <div class="note">
199
270
  Never execute from a read-only preview id. Never generate a fresh plan and execute
200
271
  it in the same step. <code>trash</code> moves artifacts into Artshelf trash; physical
@@ -216,6 +287,12 @@ approve artshelf trash purge ledger &lt;ledger-path&gt; plan &lt;purge-plan-id&g
216
287
  skipped instead of registered, include the brief skip reason from the
217
288
  completion checklist.
218
289
  </p>
290
+ <p>
291
+ When <code>artshelf put --json</code> succeeds, include a deterministic Artshelf
292
+ footnote in the same handoff, status, final response, or run summary that
293
+ mentions the artifact.
294
+ </p>
295
+ <pre><code>Artshelf footnote: registered &lt;artifact-path&gt; as &lt;artshelf-id&gt;; reason: &lt;short reason&gt;; due: &lt;YYYY-MM-DD|manual-review&gt;; cleanup=&lt;cleanup-mode&gt;.</code></pre>
219
296
  </section>
220
297
 
221
298
  <section>
@@ -250,8 +327,14 @@ artshelf trash purge --execute --plan-id &lt;purge-plan-id&gt; --ledger &lt;ledg
250
327
  <pre><code>artshelf resolve &lt;id&gt; --status resolved --reason &lt;text&gt;</code></pre>
251
328
  <p>
252
329
  Use a specific reason. <code>resolve</code> only updates the ledger; it does not
253
- move or delete files. Resolved records stop reappearing in future due and
254
- dry-run cleanup output while remaining visible through
330
+ move or delete files. For batches of missing-path records, ask for approval that
331
+ names the exact ledger and ids.
332
+ </p>
333
+ <pre><code>approve artshelf resolve missing ledger &lt;ledger-path&gt; ids &lt;id...&gt;</code></pre>
334
+ <p>
335
+ After resolution, verify with <code>artshelf review --all --json</code> and report
336
+ whether the review is quiet or what remains. Resolved records stop reappearing
337
+ in future due and dry-run cleanup output while remaining visible through
255
338
  <code>artshelf list --status resolved</code>.
256
339
  </p>
257
340
  </section>
@@ -92,6 +92,13 @@ Useful defaults for agents:
92
92
  repo, PR, issue, workflow id, or run id.
93
93
 
94
94
  Use `--json` when another tool needs to capture the Artshelf entry id.
95
+ When `artshelf put --json` succeeds, include a deterministic Artshelf footnote in
96
+ the same handoff, status, final response, or run summary that mentions the
97
+ artifact:
98
+
99
+ ```text
100
+ Artshelf footnote: registered <artifact-path> as <artshelf-id>; reason: <short reason>; due: <YYYY-MM-DD|manual-review>; cleanup=<cleanup-mode>.
101
+ ```
95
102
 
96
103
  ## Idempotent Lookup
97
104
 
@@ -194,11 +201,79 @@ artshelf trash purge --execute --plan-id <purge-plan-id> --ledger <ledger-path>
194
201
  `artshelf review --all --json`, plus `artshelf trash list --ledger <ledger-path> --json`
195
202
  and purge receipt evidence after purge, or explain what remains.
196
203
 
204
+ ### Review Plan Report Schema
205
+
206
+ When a dry-run creates or reuses a cleanup or trash purge plan, surface the plan
207
+ in a compact human-readable report. The report should let the user approve, ask
208
+ for changes, or request alternatives without opening the plan file.
209
+
210
+ For deterministic agent integrations, construct an `ArtshelfReviewReport` JSON
211
+ object first, then render it to text. Use
212
+ [`schemas/artshelf-review-report.schema.json`](schemas/artshelf-review-report.schema.json)
213
+ for the packet shape and
214
+ [`examples/artshelf-review-report.json`](examples/artshelf-review-report.json)
215
+ as the canonical example. The schema locks report structure; the CLI output and
216
+ approval rules still define cleanup safety.
217
+
218
+ Render the JSON packet as a compact decision card using `decisionSummary` and
219
+ `decisionGroups`. Lead with counts, then show exactly what is ready for approval
220
+ and what needs review first. Emojis are encouraged when the host renders them
221
+ well because they make the groups scannable; omit them only for plain-text or
222
+ accessibility-constrained surfaces.
223
+
224
+ ```text
225
+ Artshelf daily review
226
+ Status: <ok|attention needed>; registry <ok|attention>
227
+
228
+ ✅ Ready for approval: <n>
229
+ 👀 Needs review first: <n>
230
+ ⚠️ Blocked: <n>
231
+
232
+ Recommendation
233
+ <one short sentence with the next safest action>.
234
+
235
+ Ready for approval
236
+ 1. <short item label>
237
+ Why: <short reason>
238
+ Action: <what approval will do>
239
+ approve artshelf cleanup ledger <ledger-path> plan <plan-id>
240
+
241
+ 2. <short item label>
242
+ Why: <short reason>
243
+ Action: <ledger-only update, no file changes>
244
+ approve artshelf resolve missing ledger <ledger-path> ids <id...>
245
+
246
+ Needs review first
247
+ 1. <short item label>
248
+ Why: <short reason>
249
+ Suggested next step: inspect path, then choose keep, change retention, resolve, or clean up later
250
+ Path: <path>
251
+
252
+ Blocked
253
+ <none, or the registry/refused/missing-path blocker and next repair step>
254
+
255
+ Safety
256
+ Dry-run only. No execute, resolve, or delete ran.
257
+ ```
258
+
259
+ Keep the full `ArtshelfReviewReport` JSON as the audit packet and include it as
260
+ an attachment, linked file, or expandable detail when the host supports that.
261
+ Do not paste the whole packet into chat unless the user asks for it. For long
262
+ plans, show only the first 3 to 5 decisions under each visible group, then state
263
+ the hidden count by group and classification. Do not hide refused,
264
+ registry-problem, or missing-path items.
265
+
266
+ If the host supports buttons, menus, or other interactive controls, they should
267
+ emit exact text commands such as the approval targets below. Always include the
268
+ exact approval target in the message body as a fallback for clients where those
269
+ controls do not render.
270
+
197
271
  Approval wording should be exact:
198
272
 
199
273
  ```text
200
274
  approve artshelf cleanup ledger <ledger-path> plan <plan-id>
201
275
  approve artshelf trash purge ledger <ledger-path> plan <purge-plan-id>
276
+ approve artshelf resolve missing ledger <ledger-path> ids <id...>
202
277
  ```
203
278
 
204
279
  Never execute from a read-only preview id. Never generate a fresh plan and
@@ -309,8 +384,17 @@ artshelf resolve <id> --status resolved --reason <text>
309
384
  ```
310
385
 
311
386
  Use a specific reason. `resolve` only updates the ledger; it does not move or
312
- delete files. Resolved records stop reappearing in future due and dry-run
313
- cleanup output while remaining visible in `artshelf list --status resolved`.
387
+ delete files. For batches of missing-path records, ask for approval that names
388
+ the exact ledger and ids:
389
+
390
+ ```text
391
+ approve artshelf resolve missing ledger <ledger-path> ids <id...>
392
+ ```
393
+
394
+ After resolution, verify with `artshelf review --all --json` and report whether
395
+ the review is quiet or what remains. Resolved records stop reappearing in future
396
+ due and dry-run cleanup output while remaining visible in
397
+ `artshelf list --status resolved`.
314
398
 
315
399
  ## Scheduled Review
316
400
 
@@ -0,0 +1,116 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "scope": {
4
+ "registryPath": "~/.artshelf/ledgers.json",
5
+ "ledgerCount": 3,
6
+ "health": "attention",
7
+ "registryHealth": "ok",
8
+ "affectedLedgers": [
9
+ {
10
+ "name": "example-project",
11
+ "ledgerPath": "/path/to/example-project/.artshelf/ledger.jsonl",
12
+ "validationStatus": "ok"
13
+ }
14
+ ]
15
+ },
16
+ "plans": [
17
+ {
18
+ "type": "cleanup",
19
+ "ledgerPath": "/path/to/example-project/.artshelf/ledger.jsonl",
20
+ "planId": "plan_20260606_120000_ab12",
21
+ "planPath": "/path/to/example-project/.artshelf/plans/plan_20260606_120000_ab12.json",
22
+ "approvalTarget": "approve artshelf cleanup ledger /path/to/example-project/.artshelf/ledger.jsonl plan plan_20260606_120000_ab12"
23
+ }
24
+ ],
25
+ "summary": {
26
+ "executable": 1,
27
+ "skipped": 2,
28
+ "refused": 0,
29
+ "manualReview": 1,
30
+ "missingPath": 1,
31
+ "trashed": 0
32
+ },
33
+ "decisionSummary": {
34
+ "readyForApproval": 2,
35
+ "needsReviewFirst": 1,
36
+ "blocked": 0
37
+ },
38
+ "decisionGroups": {
39
+ "readyForApproval": [
40
+ {
41
+ "label": "Clean up temp debug output",
42
+ "itemIds": ["shf_20260606_120000_ab12"],
43
+ "actionType": "cleanup",
44
+ "approvalTarget": "approve artshelf cleanup ledger /path/to/example-project/.artshelf/ledger.jsonl plan plan_20260606_120000_ab12",
45
+ "reason": "Disposable temp artifact has a reviewed cleanup plan.",
46
+ "nextStep": "Approve the exact cleanup plan to move the artifact into Artshelf trash."
47
+ },
48
+ {
49
+ "label": "Resolve missing report record",
50
+ "itemIds": ["shf_20260606_120500_cd34"],
51
+ "actionType": "resolve-missing",
52
+ "approvalTarget": "approve artshelf resolve missing ledger /path/to/example-project/.artshelf/ledger.jsonl ids shf_20260606_120500_cd34",
53
+ "reason": "The report path is already missing.",
54
+ "nextStep": "Approve the ledger-only resolve command after confirming the report is no longer needed."
55
+ }
56
+ ],
57
+ "needsReviewFirst": [
58
+ {
59
+ "label": "Inspect lifecycle smoke report",
60
+ "itemIds": ["shf_20260606_121000_ef56"],
61
+ "actionType": "inspect",
62
+ "approvalTarget": null,
63
+ "reason": "cleanup=review means the artifact should be inspected before closing.",
64
+ "nextStep": "Inspect the path, then choose keep, change retention, resolve, or clean up later."
65
+ }
66
+ ],
67
+ "blocked": []
68
+ },
69
+ "recommendation": "Approve the reviewed cleanup plan for the disposable temp directory, then resolve the missing record after confirming it is no longer needed.",
70
+ "items": [
71
+ {
72
+ "id": "shf_20260606_120000_ab12",
73
+ "path": "/tmp/example-debug-output",
74
+ "classification": "trash-safe",
75
+ "proposedAction": "execute reviewed cleanup plan",
76
+ "dueStatus": "due",
77
+ "reason": "temporary debug output retained for 3 days",
78
+ "note": "The path exists, cleanup=trash, and the dry-run plan moves it into Artshelf trash."
79
+ },
80
+ {
81
+ "id": "shf_20260606_120500_cd34",
82
+ "path": "/tmp/missing-report.json",
83
+ "classification": "resolve-candidate",
84
+ "proposedAction": "resolve ledger-only after confirmation",
85
+ "dueStatus": "missing-path",
86
+ "reason": "report path is already missing",
87
+ "note": "Resolution updates only the ledger and does not move or delete files."
88
+ },
89
+ {
90
+ "id": "shf_20260606_121000_ef56",
91
+ "path": "/tmp/lifecycle-smoke-report.json",
92
+ "classification": "needs-human-review",
93
+ "proposedAction": "inspect before choosing cleanup or retention",
94
+ "dueStatus": "manual-review",
95
+ "reason": "cleanup=review artifact retained for manual inspection",
96
+ "note": "No approval target is shown until the review decision is known."
97
+ }
98
+ ],
99
+ "alternatives": [
100
+ "keep the artifact and change retention",
101
+ "inspect the path before approving cleanup",
102
+ "regenerate the plan after edits",
103
+ "resolve missing records ledger-only"
104
+ ],
105
+ "safety": {
106
+ "dryRunOnly": true,
107
+ "executeAllRefused": true,
108
+ "noExecuteRan": true,
109
+ "noResolveRan": true,
110
+ "noDeleteRan": true
111
+ },
112
+ "verification": {
113
+ "command": "artshelf review --all --json",
114
+ "successCondition": "no due, manual-review, missing-path, executable, or refused entries remain unless explicitly reported"
115
+ }
116
+ }