artshelf 0.4.1 → 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 +23 -0
- package/README.md +21 -13
- package/SPEC.md +37 -7
- package/dist/src/ledger.js +2 -2
- package/dist/src/registry.js +5 -5
- package/docs/agent-usage.html +94 -5
- package/docs/agent-usage.md +92 -4
- package/docs/examples/artshelf-review-report.json +116 -0
- package/docs/quickstart.html +2 -2
- package/docs/reference.html +10 -4
- package/docs/schemas/artshelf-review-report.schema.json +315 -0
- package/examples/artshelf-review-report.json +116 -0
- package/package.json +3 -1
- package/schemas/artshelf-review-report.schema.json +315 -0
- package/skills/artshelf/SKILL.md +90 -3
- package/skills/artshelf/examples/artshelf-review-report.json +116 -0
- package/skills/artshelf/schemas/artshelf-review-report.schema.json +315 -0
package/CHANGELOG.md
CHANGED
|
@@ -51,6 +51,29 @@
|
|
|
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))
|
|
69
|
+
|
|
70
|
+
## [0.5.0](https://github.com/calvinnwq/artshelf/compare/artshelf-v0.4.1...artshelf-v0.5.0) (2026-06-05)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### Features
|
|
74
|
+
|
|
75
|
+
* default storage to .artshelf paths ([95ef94e](https://github.com/calvinnwq/artshelf/commit/95ef94edef5862c45e5526a27c4adf0bf40306ca))
|
|
76
|
+
* default storage to .artshelf paths ([0da2cda](https://github.com/calvinnwq/artshelf/commit/0da2cda19ff56f78f203840ed71c2379f533750b))
|
|
54
77
|
|
|
55
78
|
## [0.4.1](https://github.com/calvinnwq/artshelf/compare/artshelf-v0.4.0...artshelf-v0.4.1) (2026-06-05)
|
|
56
79
|
|
package/README.md
CHANGED
|
@@ -116,8 +116,8 @@ This adds a separate approval boundary between quarantine and destructive deleti
|
|
|
116
116
|
|
|
117
117
|
## Explicit Ledgers
|
|
118
118
|
|
|
119
|
-
By default, Artshelf writes repo-local `.
|
|
120
|
-
`~/.
|
|
119
|
+
By default, Artshelf writes repo-local `.artshelf/ledger.jsonl` inside a git repo and
|
|
120
|
+
`~/.artshelf/ledger.jsonl` outside one. Use `--ledger <path>` and an isolated
|
|
121
121
|
`--registry <path>` for tests, demos, and unusual workflows:
|
|
122
122
|
|
|
123
123
|
```bash
|
|
@@ -126,16 +126,21 @@ artshelf list --ledger /tmp/artshelf-ledger.jsonl
|
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
Artshelf also keeps a small global registry of known ledgers at
|
|
129
|
-
`~/.
|
|
129
|
+
`~/.artshelf/ledgers.json`. Override it with `--registry <path>` or
|
|
130
130
|
`ARTSHELF_REGISTRY`; renamed installs still honor legacy `SHELF_REGISTRY` when
|
|
131
131
|
`ARTSHELF_REGISTRY` is unset. `put` registers its ledger automatically, and you
|
|
132
132
|
can register an existing ledger explicitly:
|
|
133
133
|
|
|
134
134
|
```bash
|
|
135
135
|
artshelf ledgers list
|
|
136
|
-
artshelf ledgers add --ledger /path/to/repo/.
|
|
136
|
+
artshelf ledgers add --ledger /path/to/repo/.artshelf/ledger.jsonl --name my-repo
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
+
Renamed installs before `0.5.0` used `.shelf` storage paths. Migrate by copying
|
|
140
|
+
each ledger directory to `.artshelf`, rewriting registry paths to the copied
|
|
141
|
+
ledgers, validating with `artshelf ledgers list --json`, and keeping the old
|
|
142
|
+
`.shelf` directories until rollback is no longer needed.
|
|
143
|
+
|
|
139
144
|
`artshelf ledgers list` validates each registered ledger by default — reporting
|
|
140
145
|
ok/missing/invalid status with entry counts, and exiting non-zero when the
|
|
141
146
|
registry or any ledger is broken — so it doubles as a stale-entry check. Add
|
|
@@ -238,15 +243,18 @@ quickstart, agent usage, and CLI reference. The source repo also keeps the
|
|
|
238
243
|
|
|
239
244
|
The package includes an agent-facing skill at `skills/artshelf/SKILL.md`. Agents
|
|
240
245
|
that support local skills can copy or reference this file to learn when to call
|
|
241
|
-
`artshelf put`, how to report Artshelf
|
|
242
|
-
`artshelf find` / `artshelf get` are the read-only idempotency
|
|
243
|
-
`cleanup --execute` requires explicit approval for a
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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
|
|
250
258
|
`skills/artshelf/SKILL.md` directly. Agents should ask where the user wants
|
|
251
259
|
Artshelf cloned before installing or linking it.
|
|
252
260
|
|
package/SPEC.md
CHANGED
|
@@ -428,8 +428,8 @@ Rules:
|
|
|
428
428
|
|
|
429
429
|
V1 supports two scopes:
|
|
430
430
|
|
|
431
|
-
- repo-local: `.
|
|
432
|
-
- user-global: `~/.
|
|
431
|
+
- repo-local: `.artshelf/ledger.jsonl`
|
|
432
|
+
- user-global: `~/.artshelf/ledger.jsonl`
|
|
433
433
|
|
|
434
434
|
Default behavior:
|
|
435
435
|
|
|
@@ -439,10 +439,14 @@ Default behavior:
|
|
|
439
439
|
|
|
440
440
|
V1 also supports a user-level registry of known ledgers:
|
|
441
441
|
|
|
442
|
-
- registry: `~/.
|
|
442
|
+
- registry: `~/.artshelf/ledgers.json`
|
|
443
443
|
- `--registry <path>` overrides the registry path. Without it,
|
|
444
444
|
`ARTSHELF_REGISTRY` is read first, then legacy `SHELF_REGISTRY`, then the
|
|
445
445
|
default registry path.
|
|
446
|
+
- Legacy `.shelf` ledgers are not deleted or moved automatically. Migration is
|
|
447
|
+
copy-first: copy ledger directories to `.artshelf`, rewrite registry entries,
|
|
448
|
+
validate the new registry, and retain the old `.shelf` directories for
|
|
449
|
+
rollback until the new paths are proven quiet.
|
|
446
450
|
- Retention and due calculations use wall-clock time by default. `ARTSHELF_NOW`
|
|
447
451
|
overrides it for tests and controlled runs; legacy `SHELF_NOW` is read only
|
|
448
452
|
when `ARTSHELF_NOW` is unset.
|
|
@@ -462,7 +466,7 @@ V1 also supports a user-level registry of known ledgers:
|
|
|
462
466
|
"ledgers": [
|
|
463
467
|
{
|
|
464
468
|
"name": "my-repo",
|
|
465
|
-
"path": "/absolute/path/to/repo/.
|
|
469
|
+
"path": "/absolute/path/to/repo/.artshelf/ledger.jsonl",
|
|
466
470
|
"scope": "repo",
|
|
467
471
|
"createdAt": "2026-06-01T05:42:00Z",
|
|
468
472
|
"updatedAt": "2026-06-01T05:42:00Z"
|
|
@@ -506,9 +510,9 @@ Handled records may include cleanup outcome fields:
|
|
|
506
510
|
```json
|
|
507
511
|
{
|
|
508
512
|
"cleanupPlanId": "plan_20260601_154200_cd34",
|
|
509
|
-
"receiptPath": "/absolute/path/.
|
|
513
|
+
"receiptPath": "/absolute/path/.artshelf/receipts/plan_20260601_154200_cd34.json",
|
|
510
514
|
"cleanedAt": "2026-06-01T05:45:00Z",
|
|
511
|
-
"targetPath": "/absolute/path/.
|
|
515
|
+
"targetPath": "/absolute/path/.artshelf/trash/plan_20260601_154200_cd34/shf_20260601_154200_ab12-artifact",
|
|
512
516
|
"cleanupReason": "delete is disabled in v1"
|
|
513
517
|
}
|
|
514
518
|
```
|
|
@@ -531,7 +535,7 @@ the purge provenance:
|
|
|
531
535
|
"resolutionReason": "trash purge completed",
|
|
532
536
|
"purgedAt": "2026-06-01T06:10:00Z",
|
|
533
537
|
"purgePlanId": "purge_20260601_061000_ef56",
|
|
534
|
-
"purgeReceiptPath": "/absolute/path/.
|
|
538
|
+
"purgeReceiptPath": "/absolute/path/.artshelf/purge-receipts/purge_20260601_061000_ef56.json"
|
|
535
539
|
}
|
|
536
540
|
```
|
|
537
541
|
|
|
@@ -593,11 +597,26 @@ Agents may run `artshelf find` and `artshelf get` before `put` to avoid duplicat
|
|
|
593
597
|
registrations. `find`/`get` are read-only ledger queries; they must not be used
|
|
594
598
|
as permission to clean up or resolve a record.
|
|
595
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
|
+
|
|
596
608
|
Agents may run `artshelf resolve <id> --status resolved --reason <text>` only
|
|
597
609
|
after explicit confirmation that the record has been handled, is missing, or is
|
|
598
610
|
no longer needed. The reason must be specific; resolve does not move or delete
|
|
599
611
|
files.
|
|
600
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
|
+
|
|
601
620
|
Scheduled jobs may run:
|
|
602
621
|
|
|
603
622
|
```bash
|
|
@@ -622,6 +641,15 @@ registered-ledger discovery and should include trashed record counts and target
|
|
|
622
641
|
ages. Purge dry-runs stay scoped to one explicit ledger and should report any
|
|
623
642
|
plan id, matching entries, and skipped entries.
|
|
624
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
|
+
|
|
625
653
|
Scheduled jobs must never run `artshelf cleanup --execute` or
|
|
626
654
|
`artshelf trash purge --execute`; they may only dry-run and report plans for later
|
|
627
655
|
human review.
|
|
@@ -662,6 +690,8 @@ human review.
|
|
|
662
690
|
- CLI can list trashed records (single ledger or `--all`) and purge them through
|
|
663
691
|
an approval-first, ledger-scoped dry-run/execute boundary that writes a purge
|
|
664
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.
|
|
665
695
|
- All core commands support `--json`.
|
|
666
696
|
- Tests cover record/list/find/get/status-filter/due/validate/resolve/registry,
|
|
667
697
|
`artshelf doctor`, the `artshelf status` dashboard, `--all` review, stale-registry,
|
package/dist/src/ledger.js
CHANGED
|
@@ -18,8 +18,8 @@ const RESOLVE_STATUSES = new Set(["resolved"]);
|
|
|
18
18
|
export function defaultLedgerPath(cwd = process.cwd()) {
|
|
19
19
|
const repoRoot = findGitRoot(cwd);
|
|
20
20
|
if (repoRoot)
|
|
21
|
-
return join(repoRoot, ".
|
|
22
|
-
return join(homedir(), ".
|
|
21
|
+
return join(repoRoot, ".artshelf", "ledger.jsonl");
|
|
22
|
+
return join(homedir(), ".artshelf", "ledger.jsonl");
|
|
23
23
|
}
|
|
24
24
|
export function normalizeLedgerPath(path) {
|
|
25
25
|
return resolve(path ?? defaultLedgerPath());
|
package/dist/src/registry.js
CHANGED
|
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { basename, dirname, join, resolve } from "node:path";
|
|
4
4
|
import { now, toIso } from "./time.js";
|
|
5
5
|
export function defaultRegistryPath() {
|
|
6
|
-
return process.env.ARTSHELF_REGISTRY ?? process.env.SHELF_REGISTRY ?? join(homedir(), ".
|
|
6
|
+
return process.env.ARTSHELF_REGISTRY ?? process.env.SHELF_REGISTRY ?? join(homedir(), ".artshelf", "ledgers.json");
|
|
7
7
|
}
|
|
8
8
|
export function normalizeRegistryPath(path) {
|
|
9
9
|
return resolve(path ?? defaultRegistryPath());
|
|
@@ -116,17 +116,17 @@ function normalizeName(name) {
|
|
|
116
116
|
}
|
|
117
117
|
function inferLedgerName(ledgerPath) {
|
|
118
118
|
const normalized = resolve(ledgerPath);
|
|
119
|
-
if (normalized === join(homedir(), ".
|
|
119
|
+
if (normalized === join(homedir(), ".artshelf", "ledger.jsonl"))
|
|
120
120
|
return "global";
|
|
121
|
-
if (basename(dirname(normalized)) === ".
|
|
121
|
+
if (basename(dirname(normalized)) === ".artshelf")
|
|
122
122
|
return basename(dirname(dirname(normalized))) || "repo";
|
|
123
123
|
return basename(dirname(normalized)) || "ledger";
|
|
124
124
|
}
|
|
125
125
|
function inferLedgerScope(ledgerPath) {
|
|
126
126
|
const normalized = resolve(ledgerPath);
|
|
127
|
-
if (normalized.startsWith(join(homedir(), ".
|
|
127
|
+
if (normalized.startsWith(join(homedir(), ".artshelf")))
|
|
128
128
|
return "user";
|
|
129
|
-
if (basename(dirname(normalized)) === ".
|
|
129
|
+
if (basename(dirname(normalized)) === ".artshelf")
|
|
130
130
|
return "repo";
|
|
131
131
|
return "other";
|
|
132
132
|
}
|
package/docs/agent-usage.html
CHANGED
|
@@ -143,16 +143,22 @@ artshelf get <id> --json</code></pre>
|
|
|
143
143
|
<section>
|
|
144
144
|
<h2>Ledger Registry</h2>
|
|
145
145
|
<p>
|
|
146
|
-
Artshelf keeps a user-level registry at `~/.
|
|
146
|
+
Artshelf keeps a user-level registry at `~/.artshelf/ledgers.json` so one CLI can
|
|
147
147
|
review all known ledgers without moving project records into one global file.
|
|
148
148
|
<code>put</code> registers the ledger it writes to.
|
|
149
149
|
</p>
|
|
150
|
-
<pre><code>artshelf ledgers add --ledger <repo>/.
|
|
150
|
+
<pre><code>artshelf ledgers add --ledger <repo>/.artshelf/ledger.jsonl --name <project> --scope repo
|
|
151
151
|
artshelf ledgers list --json
|
|
152
152
|
artshelf review --all --json
|
|
153
153
|
artshelf status --all --json
|
|
154
154
|
artshelf find --all --owner <agent-or-runtime> --json
|
|
155
155
|
artshelf trash list --all --json</code></pre>
|
|
156
|
+
<p>
|
|
157
|
+
Renamed installs before <code>0.5.0</code> used <code>.shelf</code> paths. For migration,
|
|
158
|
+
copy the old ledger directories into <code>.artshelf</code>, rewrite registry entries,
|
|
159
|
+
validate the new registry, and keep the <code>.shelf</code> copies until rollback is no
|
|
160
|
+
longer needed.
|
|
161
|
+
</p>
|
|
156
162
|
<p>
|
|
157
163
|
<code>artshelf ledgers list --json</code> validates each registered ledger and reports
|
|
158
164
|
ok/missing/invalid status with entry and warning/error counts, so agents can detect
|
|
@@ -187,8 +193,79 @@ artshelf trash list --all --json</code></pre>
|
|
|
187
193
|
<pre><code>artshelf trash list --ledger <ledger-path>
|
|
188
194
|
artshelf trash purge --older-than 7d --dry-run --ledger <ledger-path> --json
|
|
189
195
|
artshelf trash purge --execute --plan-id <purge-plan-id> --ledger <ledger-path> --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: <ok|attention needed>; registry <ok|attention>
|
|
222
|
+
|
|
223
|
+
✅ Ready for approval: <n>
|
|
224
|
+
👀 Needs review first: <n>
|
|
225
|
+
⚠️ Blocked: <n>
|
|
226
|
+
|
|
227
|
+
Recommendation
|
|
228
|
+
<one short sentence with the next safest action>.
|
|
229
|
+
|
|
230
|
+
Ready for approval
|
|
231
|
+
1. <short item label>
|
|
232
|
+
Why: <short reason>
|
|
233
|
+
Action: <what approval will do>
|
|
234
|
+
approve artshelf cleanup ledger <ledger-path> plan <plan-id>
|
|
235
|
+
|
|
236
|
+
2. <short item label>
|
|
237
|
+
Why: <short reason>
|
|
238
|
+
Action: <ledger-only update, no file changes>
|
|
239
|
+
approve artshelf resolve missing ledger <ledger-path> ids <id...>
|
|
240
|
+
|
|
241
|
+
Needs review first
|
|
242
|
+
1. <short item label>
|
|
243
|
+
Why: <short reason>
|
|
244
|
+
Suggested next step: inspect path, then choose keep, change retention, resolve, or clean up later
|
|
245
|
+
Path: <path>
|
|
246
|
+
|
|
247
|
+
Blocked
|
|
248
|
+
<none, or the registry/refused/missing-path blocker and next repair step>
|
|
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>
|
|
190
266
|
<pre><code>approve artshelf cleanup ledger <ledger-path> plan <plan-id>
|
|
191
|
-
approve artshelf trash purge ledger <ledger-path> plan <purge-plan-id>
|
|
267
|
+
approve artshelf trash purge ledger <ledger-path> plan <purge-plan-id>
|
|
268
|
+
approve artshelf resolve missing ledger <ledger-path> ids <id...></code></pre>
|
|
192
269
|
<div class="note">
|
|
193
270
|
Never execute from a read-only preview id. Never generate a fresh plan and execute
|
|
194
271
|
it in the same step. <code>trash</code> moves artifacts into Artshelf trash; physical
|
|
@@ -210,6 +287,12 @@ approve artshelf trash purge ledger <ledger-path> plan <purge-plan-id&g
|
|
|
210
287
|
skipped instead of registered, include the brief skip reason from the
|
|
211
288
|
completion checklist.
|
|
212
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 <artifact-path> as <artshelf-id>; reason: <short reason>; due: <YYYY-MM-DD|manual-review>; cleanup=<cleanup-mode>.</code></pre>
|
|
213
296
|
</section>
|
|
214
297
|
|
|
215
298
|
<section>
|
|
@@ -244,8 +327,14 @@ artshelf trash purge --execute --plan-id <purge-plan-id> --ledger <ledg
|
|
|
244
327
|
<pre><code>artshelf resolve <id> --status resolved --reason <text></code></pre>
|
|
245
328
|
<p>
|
|
246
329
|
Use a specific reason. <code>resolve</code> only updates the ledger; it does not
|
|
247
|
-
move or delete files.
|
|
248
|
-
|
|
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 <ledger-path> ids <id...></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
|
|
249
338
|
<code>artshelf list --status resolved</code>.
|
|
250
339
|
</p>
|
|
251
340
|
</section>
|
package/docs/agent-usage.md
CHANGED
|
@@ -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
|
|
|
@@ -110,16 +117,20 @@ returns no entries, call `put` and record the new id.
|
|
|
110
117
|
|
|
111
118
|
## Ledger Registry
|
|
112
119
|
|
|
113
|
-
Artshelf keeps a user-level registry at `~/.
|
|
120
|
+
Artshelf keeps a user-level registry at `~/.artshelf/ledgers.json` so one CLI can
|
|
114
121
|
review all known ledgers without moving project records into one global file.
|
|
115
122
|
`put` registers the ledger it writes to. Register existing ledgers explicitly
|
|
116
123
|
when adopting Artshelf for an existing project:
|
|
117
124
|
|
|
118
125
|
```bash
|
|
119
|
-
artshelf ledgers add --ledger <repo>/.
|
|
126
|
+
artshelf ledgers add --ledger <repo>/.artshelf/ledger.jsonl --name <project> --scope repo
|
|
120
127
|
artshelf ledgers list --json
|
|
121
128
|
```
|
|
122
129
|
|
|
130
|
+
Renamed installs before `0.5.0` used `.shelf` paths. For migration, copy the old
|
|
131
|
+
ledger directories into `.artshelf`, rewrite registry entries, validate the new
|
|
132
|
+
registry, and keep the `.shelf` copies until rollback is no longer needed.
|
|
133
|
+
|
|
123
134
|
`artshelf ledgers list --json` validates each registered ledger and reports
|
|
124
135
|
ok/missing/invalid status with entry and warning/error counts, so agents can
|
|
125
136
|
detect stale registry entries without a separate validate pass. Add `--plain`
|
|
@@ -190,11 +201,79 @@ artshelf trash purge --execute --plan-id <purge-plan-id> --ledger <ledger-path>
|
|
|
190
201
|
`artshelf review --all --json`, plus `artshelf trash list --ledger <ledger-path> --json`
|
|
191
202
|
and purge receipt evidence after purge, or explain what remains.
|
|
192
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
|
+
|
|
193
271
|
Approval wording should be exact:
|
|
194
272
|
|
|
195
273
|
```text
|
|
196
274
|
approve artshelf cleanup ledger <ledger-path> plan <plan-id>
|
|
197
275
|
approve artshelf trash purge ledger <ledger-path> plan <purge-plan-id>
|
|
276
|
+
approve artshelf resolve missing ledger <ledger-path> ids <id...>
|
|
198
277
|
```
|
|
199
278
|
|
|
200
279
|
Never execute from a read-only preview id. Never generate a fresh plan and
|
|
@@ -305,8 +384,17 @@ artshelf resolve <id> --status resolved --reason <text>
|
|
|
305
384
|
```
|
|
306
385
|
|
|
307
386
|
Use a specific reason. `resolve` only updates the ledger; it does not move or
|
|
308
|
-
delete files.
|
|
309
|
-
|
|
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`.
|
|
310
398
|
|
|
311
399
|
## Scheduled Review
|
|
312
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
|
+
}
|
package/docs/quickstart.html
CHANGED
|
@@ -94,7 +94,7 @@ artshelf validate --ledger /tmp/artshelf-ledger.jsonl --json
|
|
|
94
94
|
artshelf due --ledger /tmp/artshelf-ledger.jsonl --json
|
|
95
95
|
artshelf cleanup --dry-run --ledger /tmp/artshelf-ledger.jsonl --json</code></pre>
|
|
96
96
|
<p>
|
|
97
|
-
Dry-run writes a plan under the ledger's `.
|
|
97
|
+
Dry-run writes a plan under the ledger's `.artshelf` directory only when
|
|
98
98
|
cleanup entries exist. If there is nothing to clean up, it reports
|
|
99
99
|
<code>not-created</code> and writes no plan file. Review any generated
|
|
100
100
|
plan id before an execute step.
|
|
@@ -119,7 +119,7 @@ artshelf cleanup --dry-run --ledger /tmp/artshelf-ledger.jsonl --json</code></pr
|
|
|
119
119
|
<h2>4. Purge old trashed records explicitly</h2>
|
|
120
120
|
<p>
|
|
121
121
|
After cleanup execution, trashed files are quarantined under the ledger's
|
|
122
|
-
<code>.
|
|
122
|
+
<code>.artshelf/trash</code> folder. Before physical deletion, run an explicit
|
|
123
123
|
reviewed trash purge plan:
|
|
124
124
|
</p>
|
|
125
125
|
<pre><code>artshelf trash list --ledger /tmp/artshelf-ledger.jsonl
|