@cratis/pi 7.104.0 → 7.105.1

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.
@@ -40,7 +40,7 @@ pin updates use ordinary dependency maintenance; CI changes use the
40
40
 
41
41
  Execute [scripts/cratis-local-packages.sh](scripts/cratis-local-packages.sh), not
42
42
  an improvised replacement. Run `bash "$local" <command> --help` for inputs and
43
- errors. Requires bash and git; add dotnet for NuGet, node and Yarn for npm, Docker
43
+ errors. Requires bash, git and node for package registry operations; add dotnet for NuGet, Yarn and npm for npm packages, Docker
44
44
  for images, or the selected language toolchain. Check availability first:
45
45
 
46
46
  ```bash
@@ -67,13 +67,14 @@ commands before choosing the build, regression spec and full gate commands.
67
67
  - [ ] Read [references/dependency-map.md](references/dependency-map.md) for the chain between the named repositories, generate one stamp, then pack each producer in upstream order.
68
68
  - [ ] If needed, publish the kernel and assets, then build a matching local image.
69
69
  - [ ] Run `closure` for the consumer and producers, follow the printed commands, and run its one `verify-pack` after the last pack.
70
- - [ ] Activate the consumer overlay and select the local image.
70
+ - [ ] Set a task ID (`--task ID` or `CRATIS_LOCAL_TASK`, convention `owner/repo#number`), activate the consumer overlay and select the local image.
71
+ - [ ] Run `list` (or `list --json`) to inspect recorded producers, tasks and live consumers.
71
72
  - [ ] Build the consumer, run its regression specs/app action and required gates.
72
73
  - [ ] On failure, diagnose, fix the producer, create a distinct stamp and repeat.
73
74
  - [ ] Run `check` before every consumer commit and push, and on the producer; it must report 0 leaks.
74
75
  - [ ] Upstream first: a downstream ships only after the upstream has released and its pin is bumped to the released version.
75
76
  - [ ] Restore overlays, unset environment overrides, and run `check` again.
76
- - [ ] Review stamp-scoped `clean` dry-run targets, then apply cleanup.
77
+ - [ ] Review `finish --task ID`, mark completed work with `--apply`, then review `clean --expired` (or explicit `--stamp`) targets before applying cleanup.
77
78
 
78
79
  ### 1. Stamp
79
80
 
@@ -110,7 +111,11 @@ separately. The package IDs a producer should ship are listed in
110
111
  the stamp, every overlay, one `pack-*` command per map row (with its `--property` arguments) and
111
112
  ONE `verify-pack` for the whole plan (see [references/dependency-map.md](references/dependency-map.md)).
112
113
  Run the printed commands in order. A successful pack alone does not prove dependency closure;
113
- `verify-pack` does.
114
+ `verify-pack` does. After successful packing, the helper atomically records package IDs,
115
+ producer worktree, branch and HEAD in `FEED/stamps/STAMP/record.json` (mode `0600`).
116
+ Pass `--task ID` to `pack-*` and `use-*`, or set `CRATIS_LOCAL_TASK`; without either,
117
+ the recorded task is null. IDs match `^[A-Za-z0-9][A-Za-z0-9._#:/-]{0,127}$` and
118
+ are JSON values, never paths. Prefer `owner/repo#number`.
114
119
 
115
120
  ### 3. Build an image when needed
116
121
 
@@ -201,17 +206,58 @@ build output, not pre-existing work.
201
206
 
202
207
  ### 8. Clean
203
208
 
209
+ `list [--json] [--stamp STAMP]` is a lock-free, read-only inventory, including legacy
210
+ artifacts without records. It shows producer ownership, task state, live/total consumers
211
+ and age, plus recorded state. Invalid records appear as `invalid` rows (JSON includes
212
+ `error`); listing continues and exits `1`. `use-*` records each consumer, including every
213
+ composition member stamp. `restore` restores overlays first, then updates only those
214
+ stamps' consumer entries; an invalid selected record warns with its path and exits `1`.
215
+ A registry-write failure after activation warns and exits `1`, keeping the overlay for restoration.
216
+
217
+ ```bash
218
+ bash "$local" list
219
+ bash "$local" finish --task owner/repo#number
220
+ bash "$local" finish --task owner/repo#number --apply
221
+ ```
222
+
223
+ `finish` is dry-run by default, marks task completion only, and succeeds with a message
224
+ if no record names the task and all records are valid. It warns and skips invalid records
225
+ without rewriting them, continues with valid matches, and exits `1` if any were skipped.
226
+ It never restores consumers or cleans packages automatically.
227
+
204
228
  ```bash
205
229
  bash "$local" clean "$consumer" --stamp "$stamp"
206
230
  # Review listed subjects and stop task-owned containers first.
207
231
  bash "$local" clean "$consumer" --stamp "$stamp" --apply
208
232
  ```
209
233
 
234
+ `clean --stamp STAMP` validates only that stamp's record; default clean and `--all`
235
+ validate all selected records. An invalid selected record refuses cleanup (`2`).
236
+
237
+ Use `clean --expired` for retention-based cleanup, then add `--apply` after review.
238
+ It keeps unrecorded stamps, active compositions and live manifest/overlay references
239
+ (in registered sessions or recorded consumer worktrees). Otherwise, a stamp expires
240
+ when every non-null producing task is finished (at least one required), all recorded
241
+ consumers are gone (at least one required), or a real release at or above its base exists,
242
+ in that order. Offline evidence is NuGet `.nupkg.metadata` in the shared or registered
243
+ private caches; npm has no offline release check. `--online` opts into NuGet/npm
244
+ registry checks with a 10-second timeout; failures provide no evidence. Each stamp
245
+ prints `expired STAMP: REASON` or `kept STAMP: REASON`; kept stamps succeed (`0`).
246
+ `list --json` reports the same offline decision in `expiry:{expired,reasons,kept}`.
247
+ `--expired` cannot combine with `--stamp` or `--all`. It retains the same lock, fuse
248
+ and dry-run default. Applying also prunes gone consumers and missing session registrations.
249
+
210
250
  Pass: expected subjects listed, then removed without force. Cleanup covers local
211
251
  feed packages, NuGet version folders, discoverable Yarn cache entries, local image
212
- tags and registered sessions; unresolved npm backups block it. Missing Docker/Yarn
252
+ tags, stamp record directories and registered sessions; unresolved npm backups block it. Missing Docker/Yarn
213
253
  probes are reported as skipped cleanup, not proof those stores are empty. Default
214
254
  fuse: 500 subjects; investigate an unexpectedly large list instead of raising it.
255
+ NuGet cleanup scans the active shared cache and every registered private cache.
256
+ It removes only recognized local/train version folders. Missing or mismatched
257
+ private-cache markers, symlinks and paths outside the consumer's Git directory
258
+ refuse the entire request. `restore` keeps private caches. After restoring overlays
259
+ and removing live stamps, use `clean "$consumer" --private-cache` to review whole-cache
260
+ removal, then add `--apply` to remove the marked cache and its session registration.
215
261
  Prefer `--stamp` to `--all`. Legacy cleanup refuses the entire request (exit `2`,
216
262
  also in dry-run) for registered live overlay/manifest references; it reports kept
217
263
  stamps and paths. Restore/remove references, then retry. This is not an ownership
@@ -229,7 +275,9 @@ is sourced before defaults. Do not put credentials in it. Environment settings:
229
275
  | --- | --- |
230
276
  | `CRATIS_LOCAL_FEED` | `${XDG_CACHE_HOME:-$HOME/.cache}/cratis/local-feed`; outside tracked files |
231
277
  | `CRATIS_LOCAL_SESSION_DIR` | `<absolute-git-dir>/cratis-local`; per-worktree overlays/backups |
232
- | `NUGET_PACKAGES` | `$HOME/.nuget/packages`; opt-in per-worktree cache via `use-nuget` hint |
278
+ | `NUGET_PACKAGES` | `$HOME/.nuget/packages`; active cache scanned by `clean` |
279
+ | `CRATIS_LOCAL_TASK` | Optional task ID, convention `owner/repo#number`; `--task ID` on pack/use/finish overrides it |
280
+ | `CRATIS_LOCAL_PRIVATE_CACHE` | `0`; `1` opts `use-nuget` into a marked worktree cache, also available with `--private-cache` |
233
281
  | `CRATIS_LOCAL_CLEAN_MAX` | `500`; cleanup subject fuse |
234
282
  | `CRATIS_LOCAL_RUN` | Optional executable wrapper receiving `build <label> -- <command...>` |
235
283
 
@@ -242,7 +290,7 @@ doing read-only discovery.
242
290
  Helper exit codes: `0` success, `1` findings/failed operation, `2` cannot run or
243
291
  invalid input. Neither `1` nor `2` is a pass. After script changes, execute
244
292
  `bash "$local" --self-test`; pass requires printed passed/skipped counts and exit
245
- `0`. npm overlay/restore tests run when node is on the inherited PATH; real packing
293
+ `0`. Registry tests require node; npm overlay/restore tests use the inherited PATH. Real packing
246
294
  is not exercised by this hermetic self-test. Report any unrun ecosystem checks.
247
295
 
248
296
  ## Why the local loop
@@ -6,6 +6,7 @@
6
6
  ## Contents
7
7
 
8
8
  - CPM overlay
9
+ - Registry and list
9
10
  - Source mapping
10
11
  - Versions and cache
11
12
  - Retire a hand-rolled feed
@@ -51,6 +52,55 @@ an already-running IDE. A config overlay printed below must also reach IDE resto
51
52
  The `CRATIS_LOCAL_RUN` adapter applies to pack steps, not these restore/build
52
53
  commands; route each heavy command separately through the host's build queue.
53
54
 
55
+ ## Registry and list
56
+
57
+ Package operations require node for the stamp registry. Successful `pack-nuget` and
58
+ `pack-npm` calls record package IDs, producer repo/worktree, branch, HEAD and UTC time
59
+ in `FEED/stamps/STAMP/record.json` (schema `1`, mode `0600`). `--task ID` on pack/use
60
+ commands overrides `CRATIS_LOCAL_TASK`; otherwise task is null. Prefer `owner/repo#number`.
61
+ IDs match `^[A-Za-z0-9][A-Za-z0-9._#:/-]{0,127}$`; they are JSON values, never paths.
62
+
63
+ `list [--json] [--stamp STAMP]` joins feed artifacts with records without locking or
64
+ writing. Legacy stamps appear with `recorded:false`. Text shows stamp, ecosystem,
65
+ package count, producer `repo@branch`, task state, live/total consumers, age and recorded state. JSON
66
+ has top-level `schema:1`, `feed` and `stamps`; each stamp includes packages, producers,
67
+ tasks, consumer states (`live`, `restored`, `gone`), creation time and age in seconds.
68
+ Its `expiry:{expired,reasons,kept}` uses the same offline decision as `clean --expired`:
69
+ keep unrecorded stamps, active compositions and live manifest/overlay references first;
70
+ otherwise expire finished producing tasks, all consumers gone, or a release at or above
71
+ the stamp's base, in that order. A taskless pack alone never expires by task completion;
72
+ a stamp without consumers never expires by consumers gone. Live references include
73
+ registered sessions and recorded consumer worktrees, even after task completion.
74
+ A live consumer must still be a Git root and retain an env, overlay, backup or composition.
75
+ `use-*` records consumers after activation (every composition member stamp); `restore`
76
+ restores overlays first, then marks only the session's stamps restored without erasing
77
+ history. An invalid selected record prints a `WARNING:` naming its path and exits `1`;
78
+ unrelated records are not read. A registry error after activation warns, exits `1` and
79
+ leaves the overlay intact. Pack/use still refuse invalid target records (`2`); dry runs
80
+ write no records. `list` keeps listing invalid records as `recorded:"invalid"` with an
81
+ `error` string in JSON (text: `RECORDED` is `invalid`) and exits `1` if any are invalid.
82
+
83
+ ```bash
84
+ bash "$local" list --json
85
+ bash "$local" finish --task owner/repo#number
86
+ bash "$local" finish --task owner/repo#number --apply
87
+ ```
88
+
89
+ `finish` previews by default; `--apply` marks that task finished in every matching
90
+ record. Invalid records are skipped with a `WARNING:` naming each path, never rewritten;
91
+ valid matches are still marked, and any skipped record makes the exit code `1`. No match
92
+ with all records valid is a successful no-op with a message. It does not restore overlays
93
+ or delete packages. Stamp-scoped `clean --apply` reads only the selected record and removes
94
+ its directory with its artifacts; invalid selected records refuse cleanup (`2`). Default
95
+ clean and `--all` validate all selected records and fail closed (`2`) on any invalid one.
96
+ Review the dry run first. For retention-based cleanup, run `clean --expired`, then
97
+ `clean --expired --apply` after reviewing `expired STAMP: REASON` and `kept STAMP: REASON`.
98
+ Kept stamps are success (`0`); invalid records or scan errors refuse cleanup (`2`).
99
+ `--expired` is exclusive with `--stamp` and `--all`, uses the same lock and fuse, and
100
+ never removes an unrecorded stamp. Apply also prunes gone consumers from remaining
101
+ records and removes missing session directories' registrations. A consumer is gone
102
+ when its worktree is missing/not a Git root or its session directory is missing.
103
+
54
104
  ## Source mapping
55
105
 
56
106
  If a tracked root NuGet config has `packageSourceMapping`, the helper prints an
@@ -75,26 +125,44 @@ On a major-version branch, use `bash "$local" stamp --base-version 5.0.0 "$produ
75
125
  prerelease or metadata and uses it verbatim; no patch increment is added.
76
126
  An explicit base still must meet the consumer's minimum.
77
127
 
78
- Prefer a private cache per consumer worktree so another checkout's cached package
79
- cannot mask a same-version repack. The optional `use-nuget` hint uses a sibling of
80
- the session directory, not a tracked path:
128
+ Opt into a private cache when a shared cached package could mask a same-version
129
+ repack. `use-nuget --private-cache` creates a marked cache at
130
+ `<absolute-git-dir>/cratis-local-nuget` and records it in the session's `nuget-cache`
131
+ file. The printed env file exports `NUGET_PACKAGES`. This works with both stamps
132
+ and `--composition`. Set `CRATIS_LOCAL_PRIVATE_CACHE=1` to opt in through configuration.
133
+ Without either option, activation keeps its default behavior.
81
134
 
82
135
  ```bash
83
- export NUGET_PACKAGES="$(git -C "$consumer" rev-parse --absolute-git-dir)/cratis-local-nuget"
136
+ bash "$local" use-nuget "$consumer" "$stamp" --private-cache
137
+ # Source the env path printed by use-nuget, then restore and verify.
84
138
  dotnet restore path/to/consumer.slnx
85
- # After restoring overlays/removing live local references, keep this export for:
139
+ bash "$local" restore "$consumer"
140
+ # Remove any remaining live manifest references before cleanup.
86
141
  bash "$local" clean "$consumer" --stamp "$stamp"
87
142
  bash "$local" clean "$consumer" --stamp "$stamp" --apply
88
143
  unset NUGET_PACKAGES
89
144
  ```
90
145
 
91
- A private cache still reuses its own downloads: changed bits need a distinct stamp,
92
- or reviewed cleanup of that stamp before repacking. It does not make same-version
93
- repacking safe. `clean` honors the active `NUGET_PACKAGES`, touches only recognized
94
- `-local`/`-train` version folders there, and leaves released versions alone. With
95
- no export, it uses the shared `$HOME/.nuget/packages` cache; never clear that whole
96
- cache. Restore local overlays and remove live manifest references before cleanup;
97
- registered live references refuse the entire request even in dry-run.
146
+ A private cache still reuses its own downloads. Changed bits need a distinct stamp
147
+ or reviewed stamp-scoped cleanup before repacking. `clean` scans the active
148
+ `NUGET_PACKAGES` (or `$HOME/.nuget/packages`) and every registered private cache,
149
+ even after the env export is unset. It removes only recognized `-local`/`-train`
150
+ version folders and keeps released versions. A missing or mismatched marker,
151
+ symlink or cache path outside the consumer's Git directory stops the entire clean
152
+ with exit `2`. Registered live references also refuse cleanup, even in dry-run.
153
+
154
+ `restore` keeps the private cache. To remove it entirely, restore overlays and
155
+ remove all live stamp references first. Review `clean "$consumer" --private-cache`,
156
+ then add `--apply`. This removes the marked cache and its `nuget-cache` registration.
157
+ Never remove an entire shared cache.
158
+
159
+ `clean --expired` also scans `$HOME/.nuget/packages` when `NUGET_PACKAGES` is set.
160
+ Offline release evidence is a non-prerelease `lowercase-id/X.Y.Z/.nupkg.metadata`
161
+ at or above the record's base in the shared or any registered private cache, for
162
+ any recorded NuGet ID. Released folders are evidence only, never cleanup targets.
163
+ Add `--online` to opt into NuGet flat-container and npm registry release checks
164
+ with a 10-second timeout; missing evidence and network failures simply keep that
165
+ expiry reason from applying. `list` never checks online.
98
166
 
99
167
  The helper uses a folder feed, so NuGet's HTTP cache is not involved. When diagnosing
100
168
  an HTTP feed instead, `dotnet restore --no-http-cache` bypasses its HTTP cache only;
@@ -14,6 +14,11 @@ stamp=$(bash "$local" stamp "$producer")
14
14
  bash "$local" pack-npm "$producer" "$stamp"
15
15
  ```
16
16
 
17
+ Pass `--task ID` to pack/use, or set `CRATIS_LOCAL_TASK` (convention `owner/repo#number`),
18
+ to associate the stamp with work. Successful packing records package IDs and producer
19
+ HEAD; activation records the consumer after publication. See
20
+ [Registry and list](dotnet-nuget.md#registry-and-list) for inventory and task completion.
21
+
17
22
  It requires clean tracked workspace manifests, temporarily changes all non-private
18
23
  workspace versions and packs actual tarballs. It restores those manifests on
19
24
  success and failure. Tarballs are named `<scope>-<name>-<version>.tgz` (`@cratis/foo` becomes
@@ -78,3 +83,12 @@ consumer manifests. Reinstall released dependencies after restoration, then run
78
83
  Review `clean "$consumer" --stamp "$stamp"` before `--apply`. Passing the consumer
79
84
  allows Yarn cache discovery; no consumer or unavailable Yarn yields a reported
80
85
  skip. Unresolved backups block cleanup rather than silently losing recovery data.
86
+ `restore` retains consumer history in the registry; stamp-scoped `clean --apply`
87
+ removes the stamp's record directory together with its artifacts.
88
+ Alternatively review `clean "$consumer" --expired`, then add `--apply`. Live manifest
89
+ or overlay references and active compositions always retain the stamp; unrecorded
90
+ stamps require explicit `--stamp`. Finished producing tasks or all consumers gone
91
+ can expire npm stamps. npm has no offline release evidence: `--online` opts into
92
+ registry release checks (10-second timeout); failed checks never remove a stamp.
93
+ Kept stamps succeed (`0`). Applying also prunes gone consumers and missing sessions;
94
+ `--expired` cannot combine with `--stamp` or `--all`.
@@ -32,6 +32,13 @@ sorts above the released pin like a local stamp does.
32
32
 
33
33
  ## Recording consumed versions
34
34
 
35
+ `pack-*` and `use-*` accept `--task ID` (or `CRATIS_LOCAL_TASK`, convention
36
+ `owner/repo#number`). Successful packs record producer HEADs and IDs in the stamp
37
+ registry; use records consumers. `list [--json]` includes train stamps and their
38
+ owners, tasks and consumers. `finish --task ID` previews completion; add `--apply`
39
+ to mark the task finished without removing artifacts. See
40
+ [Registry and list](dotnet-nuget.md#registry-and-list).
41
+
35
42
  `verify-pack STAMP --consumer C --producer P... --json` and
36
43
  `verify-assets CONSUMER STAMP [--npm] [--consumer C --producer P...] --json` print one line:
37
44
  `{"stamp":"...","packages":[{"id":"...","version":"..."}]}`. Findings go to stderr and the exit status
@@ -41,3 +48,12 @@ is unchanged, so a train tool can record the consumed versions without scraping
41
48
 
42
49
  `clean --stamp STAMP` lists and removes the feed files, cache folders and Yarn cache entries of
43
50
  that one train stamp; a local stamp is not matched. Review the dry run before `--apply`.
51
+ Applying also removes `FEED/stamps/STAMP`, including its registry record.
52
+
53
+ For retention-based cleanup of both local and train stamps, review `clean --expired`
54
+ before adding `--apply`. Unrecorded stamps, active compositions and live references
55
+ are kept; otherwise finished producing tasks, all consumers gone, or a real release
56
+ at or above the base can expire a stamp. Offline evidence uses NuGet shared/private
57
+ caches; `--online` opts into NuGet/npm registry checks with a 10-second timeout.
58
+ Network failure is not evidence. Kept stamps succeed (`0`); apply also prunes gone
59
+ consumers and missing sessions. `--expired` cannot combine with `--stamp` or `--all`.