@mriekki/lean 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -6,12 +6,7 @@ Canonical engineering remains in the private platform repositories. Before publi
|
|
|
6
6
|
|
|
7
7
|
## Current `greenfield-poc` profile
|
|
8
8
|
|
|
9
|
-
The
|
|
10
|
-
|
|
11
|
-
- Lean Agentic Core `1.11.1` from commit `e3a8a994d1e95923d629af7640d3b3a0a4f098d4`, distribution `greenfield-workspace`;
|
|
12
|
-
- Lean POC Deployment Kit commit `4c23140576b39608a3ef285cad4abe53dccb9c47`, distribution `greenfield-poc`.
|
|
13
|
-
|
|
14
|
-
Core `1.11.1` tightens `/lean-update` for Bootstrap-generated package-managed consumers: it keeps `POC_BOOTSTRAP.json`, umbrella/component baselines, exact registry integrity, and generated package-verification surfaces coherent while retaining `/core-sync` as the compatibility/router path for component-only Core consumers.
|
|
9
|
+
The profile bundles Lean Agentic Core's `greenfield-workspace` distribution and the Lean POC Deployment Kit's `greenfield-poc` distribution. The package version and exact canonical component commits are recorded in [`assets/components.json`](./assets/components.json), which is the source of truth for each release.
|
|
15
10
|
|
|
16
11
|
## Developer experience
|
|
17
12
|
|
|
@@ -38,7 +33,7 @@ npx @mriekki/lean@latest status
|
|
|
38
33
|
npx @mriekki/lean@latest check
|
|
39
34
|
```
|
|
40
35
|
|
|
41
|
-
The umbrella package writes `LEAN_BASELINE.json` while preserving component-native `CORE_BASELINE.json` and `DEPLOYMENT_BASELINE.json` ledgers. Updates refuse managed drift/conflicts before modifying any component.
|
|
36
|
+
The umbrella package writes `LEAN_BASELINE.json` while preserving component-native `CORE_BASELINE.json` and `DEPLOYMENT_BASELINE.json` ledgers. Updates refuse managed drift/conflicts before modifying any component. An unchanged retired managed path can be removed safely; a locally modified retired Core path stops the update until the operator explicitly transfers ownership with `--accept-retired core:<path>`.
|
|
42
37
|
|
|
43
38
|
## Safety and ownership
|
|
44
39
|
|
|
@@ -58,16 +53,16 @@ The package currently starts with the `greenfield-poc` consumer profile. Existin
|
|
|
58
53
|
For normal releases in the Lean Platform VS Code workspace, use:
|
|
59
54
|
|
|
60
55
|
```text
|
|
61
|
-
/release-lean
|
|
56
|
+
/release-lean
|
|
62
57
|
```
|
|
63
58
|
|
|
64
|
-
The repo-local skill resolves accepted component commits, prepares the version/pin/descriptor update, runs local verification, creates the release PR, waits for the package-PR merge gate, verifies post-merge `main` CI, then stops once at the exact npm publication gate.
|
|
59
|
+
The repo-local skill resolves accepted component commits, automatically selects the package version from the observed consumer-visible changes, prepares the version/pin/descriptor update, runs local verification, creates the release PR, waits for the package-PR merge gate, verifies post-merge `main` CI, then stops once at the exact npm publication gate. Explicit bump or exact-version arguments remain available only as unusual overrides.
|
|
65
60
|
|
|
66
61
|
After publication approval it triggers `.github/workflows/npm-publish.yml`. The workflow reconstructs the package from the exact private component pins, runs the deterministic release preparation, publishes the exact tarball directly with npm Trusted Publishing (OIDC), and automatically verifies the registry identity plus a neutral-directory `npx` smoke check.
|
|
67
62
|
|
|
68
63
|
The normal flow does not use staged npm publication or a long-lived npm publish token. An existing stage-only trusted publisher must be migrated once to allow direct `npm publish` from `npm-publish.yml`; `/release-lean` guides that bounded one-time setup.
|
|
69
64
|
|
|
70
|
-
|
|
65
|
+
Routine releases do not require local npm authentication: GitHub Actions publishes through OIDC. npm login and trusted-publisher inspection are only needed for initial setup, migration, or troubleshooting a trust error. See `docs/RELEASE_PROCESS.md` for details.
|
|
71
66
|
|
|
72
67
|
The underlying release-candidate command remains available for diagnostics:
|
|
73
68
|
|
package/assets/components.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"package": "@mriekki/lean",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.2",
|
|
5
5
|
"defaultProfile": "greenfield-poc",
|
|
6
6
|
"profiles": {
|
|
7
7
|
"greenfield-poc": {
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"components": {
|
|
15
15
|
"core": {
|
|
16
16
|
"repository": "mriekki/lean-agentic-core",
|
|
17
|
-
"commit": "
|
|
18
|
-
"version": "1.12.
|
|
17
|
+
"commit": "bcc3836b50713504aea1dc47b8ad26bf483315dd",
|
|
18
|
+
"version": "1.12.1",
|
|
19
19
|
"distribution": "greenfield-workspace",
|
|
20
20
|
"descriptor": "assets/core/distribution.json",
|
|
21
21
|
"sourceRoot": "assets/generated/core",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"package": "@mriekki/lean",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.2",
|
|
5
5
|
"components": {
|
|
6
6
|
"core": {
|
|
7
7
|
"repository": "mriekki/lean-agentic-core",
|
|
8
|
-
"commit": "
|
|
9
|
-
"version": "1.12.
|
|
8
|
+
"commit": "bcc3836b50713504aea1dc47b8ad26bf483315dd",
|
|
9
|
+
"version": "1.12.1",
|
|
10
10
|
"distribution": "greenfield-workspace",
|
|
11
11
|
"files": [
|
|
12
12
|
{
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
{
|
|
83
83
|
"source": "core/skills/lean-update/SKILL.md",
|
|
84
84
|
"destination": ".github/skills/lean-update/SKILL.md",
|
|
85
|
-
"sha256": "
|
|
85
|
+
"sha256": "50bfa181bb9a6abc1d0bb6533ef0b29fe729a8a96924a34a7796c0cbb80061fc"
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
"source": "core/skills/core-sync/SKILL.md",
|
|
@@ -109,9 +109,11 @@ Stop on unsafe states such as:
|
|
|
109
109
|
- `LOCAL_MISSING`;
|
|
110
110
|
- `UNTRACKED_CONFLICT`;
|
|
111
111
|
- path collisions/conflicts;
|
|
112
|
-
-
|
|
112
|
+
- Core `RETIRED_DRIFT` when the retired file no longer matches its recorded managed hash.
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
A package-managed retired path that is unchanged from its recorded baseline may be classified as `REMOVE` and deleted safely; an already-missing retired path may be classified as `RETIRED_MISSING`. These states do not require a separate ownership decision because the baseline proves there is no consumer edit to preserve.
|
|
115
|
+
|
|
116
|
+
A modified retired Core path is different: never auto-add `--accept-retired core:<path>` merely to make the update pass. Explain that the file differs from its recorded Core-managed hash and require a separate explicit ownership-transfer decision before re-previewing it. When that exact transfer is accepted, the package updater preserves the file as consumer-owned content and drops it from the new Core baseline.
|
|
115
117
|
|
|
116
118
|
For a Bootstrap-generated consumer, also preview the companion generated-consumer changes:
|
|
117
119
|
|
|
@@ -145,6 +147,7 @@ Choosing option 1 authorizes only:
|
|
|
145
147
|
|
|
146
148
|
- creation/switch to one repository-appropriate short-lived update branch when needed;
|
|
147
149
|
- exact target package apply;
|
|
150
|
+
- removal of unchanged retired package-managed files that the reviewed preview classified as `REMOVE`;
|
|
148
151
|
- when `POC_BOOTSTRAP.json` is present, update of its exact `generation.lean.version` and `generation.lean.integrity` to the reviewed target while preserving package/profile;
|
|
149
152
|
- migration of a recognized Bootstrap-generated package-verification block from duplicated current literals to the accepted manifest-driven form, only when the existing block still exactly matches the current approved metadata;
|
|
150
153
|
- package/baseline/generated-consumer verification;
|
|
@@ -168,7 +171,7 @@ Apply using the same exact package version that was previewed, for example:
|
|
|
168
171
|
npx --yes @mriekki/lean@<target-version> update --apply
|
|
169
172
|
```
|
|
170
173
|
|
|
171
|
-
If explicit Core retired-path ownership transfer was separately approved, pass only the exact reviewed paths using the package's `--accept-retired core:<path>` contract. Never widen that set implicitly.
|
|
174
|
+
If explicit Core retired-path ownership transfer was separately approved, pass only the exact reviewed modified paths using the package's `--accept-retired core:<path>` contract. Never widen that set implicitly. Unchanged retired managed paths do not need this flag; the package updater removes them according to the reviewed `REMOVE` plan.
|
|
172
175
|
|
|
173
176
|
For a Bootstrap-generated consumer, complete the reviewed companion metadata changes in the same bounded update before declaring success. Preserve every unrelated `POC_BOOTSTRAP.json` field. Never change package identity or profile as an incidental version update.
|
|
174
177
|
|
|
@@ -195,11 +198,12 @@ Confirm:
|
|
|
195
198
|
- `LEAN_BASELINE.json` records the exact target package/version/profile;
|
|
196
199
|
- component baseline commits/distributions match the umbrella baseline;
|
|
197
200
|
- package check passes for the whole profile;
|
|
201
|
+
- unchanged retired managed files shown as `REMOVE` in the preview are actually absent after apply, while any explicitly transferred modified retired Core file remains present and is no longer Core-managed;
|
|
198
202
|
- when `POC_BOOTSTRAP.json` exists, its package/version/profile agree with `LEAN_BASELINE.json` and its integrity equals the exact reviewed target registry integrity;
|
|
199
203
|
- when the repository contains `tools/lean-package/check-managed-baselines.py`, that generated baseline checker passes after all companion metadata changes;
|
|
200
204
|
- generated package-verification surfaces no longer contradict the approved manifest metadata;
|
|
201
205
|
- consumer-owned content was not overwritten;
|
|
202
|
-
- only intended package-managed changes, reviewed generated-consumer companion changes, and reviewed ownership transfers occurred.
|
|
206
|
+
- only intended package-managed changes, reviewed generated-consumer companion changes, reviewed removals, and reviewed ownership transfers occurred.
|
|
203
207
|
|
|
204
208
|
If generated CI still embeds a different package version/integrity after the update, report `GENERATED LEAN VERIFICATION DRIFT` and stop before delivery.
|
|
205
209
|
|
|
@@ -213,7 +217,7 @@ Present the meaningful diff for human review. After acceptance, recommend `/deli
|
|
|
213
217
|
- uses a different package version for apply than the reviewed preview;
|
|
214
218
|
- performs a downgrade/rollback as an ordinary update;
|
|
215
219
|
- overwrites unexplained managed drift;
|
|
216
|
-
- auto-accepts Core retired-path ownership transfer;
|
|
220
|
+
- auto-accepts Core retired-path ownership transfer for a modified retired file;
|
|
217
221
|
- silently repairs a pre-existing mismatch between `POC_BOOTSTRAP.json` and `LEAN_BASELINE.json`;
|
|
218
222
|
- changes a generated consumer's package identity/profile or regenerates the repository as an incidental version update;
|
|
219
223
|
- guesses at locally modified/unrecognized Bootstrap-generated verification logic;
|
package/package.json
CHANGED
package/src/engine.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import fs from 'node:fs';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { readJson } from './package-data.mjs';
|
|
5
5
|
|
|
6
|
-
const CORE_SAFE = new Set(['SAME', 'ADD', 'CORE_UPDATE', 'UNTRACKED_MATCH', 'BASELINE_STALE']);
|
|
6
|
+
const CORE_SAFE = new Set(['SAME', 'ADD', 'CORE_UPDATE', 'UNTRACKED_MATCH', 'BASELINE_STALE', 'REMOVE', 'RETIRED_MISSING']);
|
|
7
7
|
const DEPLOYMENT_SAFE = new Set(['SAME', 'ADD', 'KIT_UPDATE', 'UNTRACKED_MATCH', 'BASELINE_STALE', 'REMOVE', 'RETIRED_MISSING']);
|
|
8
8
|
|
|
9
9
|
export function safeRelative(value, label = 'path') {
|
|
@@ -123,22 +123,24 @@ export function planComponent(packageData, componentId, targetRoot, acceptedReti
|
|
|
123
123
|
for (const [retiredPath, item] of [...baseMap.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
124
124
|
if (desired.has(retiredPath)) continue;
|
|
125
125
|
const dst = resolveUnder(targetRoot, retiredPath, 'retired destination');
|
|
126
|
-
if (componentId === 'core') {
|
|
127
|
-
retired.push({ path: retiredPath, item, state: acceptedRetired.has(retiredPath) ? 'RETIRED_ACCEPTED' : 'RETIRED_PATH' });
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
126
|
if (!fs.existsSync(dst)) {
|
|
131
127
|
retired.push({ path: retiredPath, item, state: 'RETIRED_MISSING' });
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const stat = fs.lstatSync(dst);
|
|
131
|
+
const currentHash = stat.isFile() && !stat.isSymbolicLink() ? sha256File(dst) : null;
|
|
132
|
+
if (currentHash === item.sha256) {
|
|
133
|
+
retired.push({ path: retiredPath, item, currentHash, state: 'REMOVE' });
|
|
134
|
+
} else if (componentId === 'core' && acceptedRetired.has(retiredPath)) {
|
|
135
|
+
retired.push({ path: retiredPath, item, currentHash, state: 'RETIRED_ACCEPTED' });
|
|
132
136
|
} else {
|
|
133
|
-
|
|
134
|
-
const currentHash = stat.isFile() && !stat.isSymbolicLink() ? sha256File(dst) : null;
|
|
135
|
-
retired.push({ path: retiredPath, item, currentHash, state: currentHash === item.sha256 ? 'REMOVE' : 'RETIRED_DRIFT' });
|
|
137
|
+
retired.push({ path: retiredPath, item, currentHash, state: 'RETIRED_DRIFT' });
|
|
136
138
|
}
|
|
137
139
|
}
|
|
138
140
|
const safe = componentId === 'core' ? CORE_SAFE : DEPLOYMENT_SAFE;
|
|
139
141
|
const unsafe = rows.filter((row) => !safe.has(row.state)).map((row) => ({ state: row.state, path: row.path }));
|
|
140
142
|
for (const item of retired) {
|
|
141
|
-
const isSafe =
|
|
143
|
+
const isSafe = item.state === 'RETIRED_ACCEPTED' || safe.has(item.state);
|
|
142
144
|
if (!isSafe) unsafe.push({ state: item.state, path: item.path });
|
|
143
145
|
}
|
|
144
146
|
return {
|
|
@@ -202,10 +204,8 @@ export function applyProfile(packageData, profilePlan, targetRoot, consumer, con
|
|
|
202
204
|
fs.mkdirSync(path.dirname(dst), { recursive: true });
|
|
203
205
|
fs.copyFileSync(row.bundlePath, dst);
|
|
204
206
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if (retired.state === 'REMOVE') fs.unlinkSync(resolveUnder(targetRoot, retired.path, 'retired destination'));
|
|
208
|
-
}
|
|
207
|
+
for (const retired of plan.retired) {
|
|
208
|
+
if (retired.state === 'REMOVE') fs.unlinkSync(resolveUnder(targetRoot, retired.path, 'retired destination'));
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
211
|
for (const plan of profilePlan.plans) {
|