@cratis/pi 7.103.7 → 7.104.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/package/corpus/skills/cratis-engineering-local-cross-repo-verification/SKILL.md +30 -4
- package/package/corpus/skills/cratis-engineering-local-cross-repo-verification/references/dotnet-nuget.md +136 -11
- package/package/corpus/skills/cratis-engineering-local-cross-repo-verification/scripts/cratis-local-packages.sh +1143 -49
- package/package.json +1 -1
|
@@ -16,7 +16,16 @@ Use real locally built packages to prove a producer fix at its consumer's packag
|
|
|
16
16
|
boundary. A **producer** builds the changed library or image; a **consumer** is the
|
|
17
17
|
downstream repository that reproduces the bug. Start before opening the producer
|
|
18
18
|
PR whose purpose is that consumer bug, rather than publishing just to find out.
|
|
19
|
-
Also use this loop
|
|
19
|
+
Also use this loop for:
|
|
20
|
+
|
|
21
|
+
- Consumer-blocking fixes, dependency features, and breaking-change trials.
|
|
22
|
+
- Release candidates in their main consumer (Specifications in Fundamentals).
|
|
23
|
+
- Cross-repository bisects and build/test timing comparisons against lower-layer main.
|
|
24
|
+
- Chained upgrades (Specifications → Fundamentals → Arc/Chronicle) without releasing each hop.
|
|
25
|
+
- Release blockers: trying Specifications in Fundamentals can expose a generator bug before publishing.
|
|
26
|
+
|
|
27
|
+
Prefer a release/preview for trivial changes, external consumers unable to use
|
|
28
|
+
the local feed, or CI-only behavior this loop cannot reproduce.
|
|
20
29
|
|
|
21
30
|
**Local verification replaces waiting, not shipping.** After local proof, release
|
|
22
31
|
the producer through the normal authorized workflow and bump the consumer to the
|
|
@@ -78,6 +87,8 @@ Format: `<next-patch>-local.<12-digit-UTC-minute>.g<sha7>`, based on the highest
|
|
|
78
87
|
downgrades. Confirm tags cover the consumer's released constraints. With no tag,
|
|
79
88
|
the helper warns and falls back to a base that must be checked before proceeding.
|
|
80
89
|
The `g` prefix keeps even an all-digit SHA nonnumeric in SemVer.
|
|
90
|
+
On `release/5.0`, use `stamp --base-version 5.0.0 "$producer"` (also with `--train`);
|
|
91
|
+
the strict SemVer core overrides tag discovery verbatim. Ensure it meets consumer minima.
|
|
81
92
|
Use the identical stamp for packages and images. A changed build needs a distinct
|
|
82
93
|
stamp; do not overwrite a cached version (the minute and commit determine it).
|
|
83
94
|
|
|
@@ -126,9 +137,18 @@ export CHRONICLE_KERNEL_VERSION="$stamp" # Studio integration specs, if used
|
|
|
126
137
|
```
|
|
127
138
|
|
|
128
139
|
Pass: the helper reports overridden IDs and restore resolves them to local
|
|
129
|
-
artifacts.
|
|
140
|
+
artifacts. To isolate NuGet downloads per worktree, set the optional
|
|
141
|
+
`NUGET_PACKAGES` export printed by `use-nuget` before restore and keep it set through
|
|
142
|
+
`clean`; see [versions and cache](references/dotnet-nuget.md#versions-and-cache).
|
|
143
|
+
Follow any printed `--configfile` instruction. Run Yarn install after
|
|
130
144
|
`use-npm`; it adds file-tarball resolutions, not links to source folders.
|
|
131
145
|
|
|
146
|
+
For independent NuGet producer versions, explicitly opt in with
|
|
147
|
+
`verify-pack --composition FILE`, `use-nuget CONSUMER --composition FILE
|
|
148
|
+
[--pin-transitive]`, then `verify-assets CONSUMER --composition FILE`. See the
|
|
149
|
+
[manifest and native-validation workflow](references/dotnet-nuget.md#mixed-version-compositions-opt-in).
|
|
150
|
+
No producer is rebuilt; restore before changing a composition or an active legacy overlay.
|
|
151
|
+
|
|
132
152
|
### 5. Build and exercise the consumer
|
|
133
153
|
|
|
134
154
|
From the consumer root, with the printed NuGet environment sourced:
|
|
@@ -192,7 +212,13 @@ feed packages, NuGet version folders, discoverable Yarn cache entries, local ima
|
|
|
192
212
|
tags and registered sessions; unresolved npm backups block it. Missing Docker/Yarn
|
|
193
213
|
probes are reported as skipped cleanup, not proof those stores are empty. Default
|
|
194
214
|
fuse: 500 subjects; investigate an unexpectedly large list instead of raising it.
|
|
195
|
-
Prefer `--stamp` to `--all
|
|
215
|
+
Prefer `--stamp` to `--all`. Legacy cleanup refuses the entire request (exit `2`,
|
|
216
|
+
also in dry-run) for registered live overlay/manifest references; it reports kept
|
|
217
|
+
stamps and paths. Restore/remove references, then retry. This is not an ownership
|
|
218
|
+
registry; unregistered consumers need manual review. To retire a hand-rolled
|
|
219
|
+
`-local.N` feed, restore released pins/sources and switch to helper stamps; review
|
|
220
|
+
old artifacts separately because `clean` does not recognize them. See
|
|
221
|
+
[migration](references/dotnet-nuget.md#retire-a-hand-rolled-feed).
|
|
196
222
|
|
|
197
223
|
## Configuration and results
|
|
198
224
|
|
|
@@ -203,7 +229,7 @@ is sourced before defaults. Do not put credentials in it. Environment settings:
|
|
|
203
229
|
| --- | --- |
|
|
204
230
|
| `CRATIS_LOCAL_FEED` | `${XDG_CACHE_HOME:-$HOME/.cache}/cratis/local-feed`; outside tracked files |
|
|
205
231
|
| `CRATIS_LOCAL_SESSION_DIR` | `<absolute-git-dir>/cratis-local`; per-worktree overlays/backups |
|
|
206
|
-
| `NUGET_PACKAGES` | `$HOME/.nuget/packages`;
|
|
232
|
+
| `NUGET_PACKAGES` | `$HOME/.nuget/packages`; opt-in per-worktree cache via `use-nuget` hint |
|
|
207
233
|
| `CRATIS_LOCAL_CLEAN_MAX` | `500`; cleanup subject fuse |
|
|
208
234
|
| `CRATIS_LOCAL_RUN` | Optional executable wrapper receiving `build <label> -- <command...>` |
|
|
209
235
|
|
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
|
|
4
4
|
# .NET and NuGet
|
|
5
5
|
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- CPM overlay
|
|
9
|
+
- Source mapping
|
|
10
|
+
- Versions and cache
|
|
11
|
+
- Retire a hand-rolled feed
|
|
12
|
+
- Mixed-version compositions (opt-in)
|
|
13
|
+
- Non-CPM escape
|
|
14
|
+
- Restoration and drift
|
|
15
|
+
|
|
6
16
|
## CPM overlay
|
|
7
17
|
|
|
8
18
|
Execute the helper from the entry point. `pack-nuget PRODUCER STAMP TARGET...`
|
|
@@ -14,10 +24,11 @@ them from an accidental published fallback.
|
|
|
14
24
|
`use-nuget CONSUMER STAMP [ID...]` requires a root `Directory.Packages.props`.
|
|
15
25
|
Without IDs it selects every package with `<id>.<stamp>.nupkg` in the feed,
|
|
16
26
|
including transitive dependencies absent from the consumer props. The generated
|
|
17
|
-
overlay imports
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
overlay imports each project's nearest `Directory.Packages.props` and replaces
|
|
28
|
+
owned `PackageVersion` items only when CPM is enabled, honoring nested props files.
|
|
29
|
+
CPM opt-out projects get owned versions through late `PackageReference Update`
|
|
30
|
+
items in `CustomAfterMicrosoftCommonTargets`, chaining any existing targets import;
|
|
31
|
+
consumer files are never edited.
|
|
21
32
|
|
|
22
33
|
```bash
|
|
23
34
|
bash "$local" use-nuget "$consumer" "$stamp" Cratis.Chronicle Cratis.Chronicle.CodeAnalysis
|
|
@@ -31,8 +42,8 @@ dotnet build path/to/consumer.slnx -c Release --no-restore -warnaserror
|
|
|
31
42
|
Transitive pinning stays as the consumer sets it; `--pin-transitive` forces it on so stamped IDs the
|
|
32
43
|
consumer does not pin still take effect (it can raise NU1109 floors).
|
|
33
44
|
|
|
34
|
-
The printed properties
|
|
35
|
-
`RestoreAdditionalProjectSources`. For an IDE, launch it from that shell, or pass
|
|
45
|
+
The printed properties include `DirectoryPackagesPropsPath`,
|
|
46
|
+
`RestoreAdditionalProjectSources` and `CustomAfterMicrosoftCommonTargets`. For an IDE, launch it from that shell, or pass
|
|
36
47
|
the printed `-p:` properties explicitly to its build. Verify restore uses the
|
|
37
48
|
stamp in `obj/project.assets.json`; shell environment changes do not reconfigure
|
|
38
49
|
an already-running IDE. A config overlay printed below must also reach IDE restore.
|
|
@@ -59,11 +70,123 @@ A stale highest tag or dependency with a newer minimum needs investigation, not
|
|
|
59
70
|
warning suppression. The suffix is `-local.<12-digit-UTC-minute>.g<sha7>`; the `g` prefix makes an
|
|
60
71
|
all-digit SHA unambiguously nonnumeric in SemVer. Dirty edits are not encoded.
|
|
61
72
|
Wait for a distinct UTC minute or commit before repacking changed contents.
|
|
73
|
+
On a major-version branch, use `bash "$local" stamp --base-version 5.0.0 "$producer"`
|
|
74
|
+
(also with `--train`). It accepts only a SemVer core without leading zeros,
|
|
75
|
+
prerelease or metadata and uses it verbatim; no patch increment is added.
|
|
76
|
+
An explicit base still must meet the consumer's minimum.
|
|
77
|
+
|
|
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:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
export NUGET_PACKAGES="$(git -C "$consumer" rev-parse --absolute-git-dir)/cratis-local-nuget"
|
|
84
|
+
dotnet restore path/to/consumer.slnx
|
|
85
|
+
# After restoring overlays/removing live local references, keep this export for:
|
|
86
|
+
bash "$local" clean "$consumer" --stamp "$stamp"
|
|
87
|
+
bash "$local" clean "$consumer" --stamp "$stamp" --apply
|
|
88
|
+
unset NUGET_PACKAGES
|
|
89
|
+
```
|
|
90
|
+
|
|
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.
|
|
98
|
+
|
|
99
|
+
The helper uses a folder feed, so NuGet's HTTP cache is not involved. When diagnosing
|
|
100
|
+
an HTTP feed instead, `dotnet restore --no-http-cache` bypasses its HTTP cache only;
|
|
101
|
+
it does not bypass packages already in `NUGET_PACKAGES`. Use a fresh worktree cache
|
|
102
|
+
or review stamp-scoped cleanup too, and preserve any required `--configfile` option.
|
|
103
|
+
|
|
104
|
+
## Retire a hand-rolled feed
|
|
105
|
+
|
|
106
|
+
Stop packing new `-local.N` versions. Restore consumers' released pins and sources,
|
|
107
|
+
then use helper-generated stamps and overlays for the next trial. Confirm restore
|
|
108
|
+
resolves the helper stamp and run `check` before committing. Inventory the old
|
|
109
|
+
feed separately: `clean` recognizes only its local/train grammar, not `-local.N`.
|
|
110
|
+
Remove old artifacts only after checking all their consumers and reviewing exact
|
|
111
|
+
targets; never rename old packages into a helper stamp or clear a whole shared cache.
|
|
112
|
+
|
|
113
|
+
## Mixed-version compositions (opt-in)
|
|
114
|
+
|
|
115
|
+
Use a composition when products have independent local versions. It never packs
|
|
116
|
+
or rebuilds producers. Write a tab-separated manifest under `.ai-work/`:
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
# Separate fields with literal tabs.
|
|
120
|
+
producer Chronicle 22.138.1-local.202610240544.gd1ad215 /absolute/worktree/Chronicle
|
|
121
|
+
producer Screenplay 0.2.2-local.202610240544.g91916a3 /absolute/worktree/Screenplay
|
|
122
|
+
producer Stage 0.1.18-local.202610240544.g524bdce /absolute/worktree/Stage
|
|
123
|
+
package Chronicle Cratis.Chronicle.InProcess
|
|
124
|
+
package Screenplay Cratis.Screenplay
|
|
125
|
+
package Stage Cratis.Stage
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Each producer needs a valid local/train stamp, an existing absolute Git worktree
|
|
129
|
+
root and at least one package. Paths declare provenance, not cryptographic artifact
|
|
130
|
+
authenticity. Package IDs have one owner, case-insensitively.
|
|
131
|
+
Declare the complete local dependency closure. Only blank lines and lines starting
|
|
132
|
+
with `#` are ignored. No npm rows or implicit merging with an active overlay.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
bash "$local" verify-pack --composition .ai-work/composition.tsv --json
|
|
136
|
+
bash "$local" use-nuget "$consumer" --composition .ai-work/composition.tsv --pin-transitive
|
|
137
|
+
# Source the printed env; use the printed --configfile for consumer restore.
|
|
138
|
+
# Run the consumer's own restore/build/specs, then:
|
|
139
|
+
bash "$local" verify-assets "$consumer" --composition .ai-work/composition.tsv --json
|
|
140
|
+
bash "$local" restore "$consumer"
|
|
141
|
+
```
|
|
62
142
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
143
|
+
`verify-assets` reads every `obj/project.assets.json` under the consumer and fails
|
|
144
|
+
closed on any project that resolved an owned ID at another version, including stale
|
|
145
|
+
assets from an earlier restore. Restore every project under the consumer with the
|
|
146
|
+
printed config, or remove the `obj` folders of projects outside the build, before
|
|
147
|
+
running it.
|
|
148
|
+
|
|
149
|
+
Transitive pinning is optional. The overlay imports the consumer's CPM file and
|
|
150
|
+
removes/re-includes owned IDs at exact producer versions. Its generated NuGet
|
|
151
|
+
config gives local IDs exclusive exact source mappings, removes conflicting remote
|
|
152
|
+
exact mappings and preserves unrelated sources/mappings/settings. Remote wildcards
|
|
153
|
+
remain less specific. Always pass the printed config during restore. Consumer
|
|
154
|
+
files are never edited. Ambiguous or inherited-only source configuration fails
|
|
155
|
+
closed instead of guessing.
|
|
156
|
+
|
|
157
|
+
Validation requires Node, `unzip` and the selected .NET SDK. A scratch MSBuild task
|
|
158
|
+
loads its `NuGet.Versioning.dll`: `NuGetVersion.TryParse`, `VersionRange.TryParse`
|
|
159
|
+
and `VersionRange.Satisfies` supply native semantics, never a range approximation.
|
|
160
|
+
Its `NuGet.Frameworks.dll` supplies `NuGetFramework.Parse` and
|
|
161
|
+
`FrameworkReducer.GetNearest` for selecting the applicable dependency group.
|
|
162
|
+
Nuspec XML is parsed structurally, across dependency groups. For example,
|
|
163
|
+
`[22.136.4,23.0.0)` admits the selected Chronicle prerelease above. Missing/corrupt
|
|
164
|
+
packages, mismatched metadata, malformed/incompatible ranges and undeclared local
|
|
165
|
+
dependencies fail. Nothing is rebuilt to make a range pass.
|
|
166
|
+
|
|
167
|
+
Assets verification examines every `obj/project.assets.json` and target, checks
|
|
168
|
+
package versions against `libraries`, and validates dependency edges against their
|
|
169
|
+
resolved target. The nearest native framework group must have its owned dependencies
|
|
170
|
+
consumed and represented by target edges. Owned IDs must resolve at their producer's exact version. Unused
|
|
171
|
+
declared IDs need not appear, but at least one owned ID must be consumed. Malformed
|
|
172
|
+
or failed-restore assets, missing dependency nodes and undeclared local packages fail.
|
|
173
|
+
A range violation on an edge where neither end is an owned ID is NuGet's own NU1608
|
|
174
|
+
case and exists without the overlay too, so it is printed as a `WARNING:` on stderr
|
|
175
|
+
(and listed under `warnings` with `--json`) instead of refusing the composition.
|
|
176
|
+
Any violation on an edge to or from an owned ID still fails.
|
|
177
|
+
|
|
178
|
+
Activation stages the normalized manifest, props, config and env together. A shared
|
|
179
|
+
mutation lock and journal protect publication and registration. The next mutation
|
|
180
|
+
rolls back incomplete work or finishes committed work after interruption. Changed
|
|
181
|
+
files, unknown ownership and live locks are preserved and refused: inspect rather
|
|
182
|
+
than deleting a lock by age. Identical activation is a no-op; restore before changing
|
|
183
|
+
a composition. Incompatible legacy NuGet/npm sessions are refused with backups
|
|
184
|
+
untouched. Active compositions retain member artifacts against `clean`; restore
|
|
185
|
+
before cleaning any member. Repeated restore is safe and never edits consumer files.
|
|
186
|
+
|
|
187
|
+
Exit codes: `0` success; `1` findings; `2` invalid input, unavailable native validation
|
|
188
|
+
or unsafe state. Composition JSON is `{"packages":[{"id":...,"version":...,"producer":...}]}`,
|
|
189
|
+
with no global `stamp`. Legacy JSON and uniform-stamp commands remain unchanged.
|
|
67
190
|
|
|
68
191
|
## Non-CPM escape
|
|
69
192
|
|
|
@@ -75,12 +198,14 @@ graph. Never edit versions intended to ship merely to make local proof work.
|
|
|
75
198
|
|
|
76
199
|
## Restoration and drift
|
|
77
200
|
|
|
78
|
-
`restore` removes session props, generated config and env files, then runs `check`.
|
|
201
|
+
`restore` removes session props, targets, generated config and env files, then runs `check`.
|
|
79
202
|
It cannot unset variables in the calling shell:
|
|
80
203
|
|
|
81
204
|
```bash
|
|
82
205
|
bash "$local" restore "$consumer"
|
|
83
206
|
unset DirectoryPackagesPropsPath RestoreAdditionalProjectSources
|
|
207
|
+
export CustomAfterMicrosoftCommonTargets="${_CratisLocalPreviousAfterMicrosoftCommonTargets:-}"
|
|
208
|
+
unset _CratisLocalPreviousAfterMicrosoftCommonTargets
|
|
84
209
|
bash "$local" check "$consumer"
|
|
85
210
|
```
|
|
86
211
|
|