@microwiseai/snapshot 0.6.0 → 0.8.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.
Files changed (50) hide show
  1. package/dist/commands/current.d.ts +5 -1
  2. package/dist/commands/current.d.ts.map +1 -1
  3. package/dist/commands/current.js +89 -2
  4. package/dist/commands/current.js.map +1 -1
  5. package/dist/commands/doctor.d.ts.map +1 -1
  6. package/dist/commands/doctor.js +46 -0
  7. package/dist/commands/doctor.js.map +1 -1
  8. package/dist/commands/install.d.ts +41 -0
  9. package/dist/commands/install.d.ts.map +1 -1
  10. package/dist/commands/install.js +328 -10
  11. package/dist/commands/install.js.map +1 -1
  12. package/dist/commands/publish.d.ts.map +1 -1
  13. package/dist/commands/publish.js +44 -24
  14. package/dist/commands/publish.js.map +1 -1
  15. package/dist/index.js +5 -2
  16. package/dist/index.js.map +1 -1
  17. package/dist/lib/access-sync.d.ts.map +1 -1
  18. package/dist/lib/access-sync.js +4 -0
  19. package/dist/lib/access-sync.js.map +1 -1
  20. package/dist/lib/config.d.ts +12 -0
  21. package/dist/lib/config.d.ts.map +1 -1
  22. package/dist/lib/config.js +38 -5
  23. package/dist/lib/config.js.map +1 -1
  24. package/dist/lib/core-floor.d.ts +49 -0
  25. package/dist/lib/core-floor.d.ts.map +1 -0
  26. package/dist/lib/core-floor.js +78 -0
  27. package/dist/lib/core-floor.js.map +1 -0
  28. package/dist/lib/install-verify.d.ts +101 -0
  29. package/dist/lib/install-verify.d.ts.map +1 -0
  30. package/dist/lib/install-verify.js +143 -0
  31. package/dist/lib/install-verify.js.map +1 -0
  32. package/dist/lib/ledger.d.ts +212 -0
  33. package/dist/lib/ledger.d.ts.map +1 -0
  34. package/dist/lib/ledger.js +266 -0
  35. package/dist/lib/ledger.js.map +1 -0
  36. package/dist/lib/pin-override.d.ts +53 -0
  37. package/dist/lib/pin-override.d.ts.map +1 -0
  38. package/dist/lib/pin-override.js +77 -0
  39. package/dist/lib/pin-override.js.map +1 -0
  40. package/dist/lib/skit-adapter.d.ts.map +1 -1
  41. package/dist/lib/skit-adapter.js +54 -20
  42. package/dist/lib/skit-adapter.js.map +1 -1
  43. package/dist/lib/transitive-resolver.d.ts.map +1 -1
  44. package/dist/lib/transitive-resolver.js +14 -3
  45. package/dist/lib/transitive-resolver.js.map +1 -1
  46. package/dist/lib/version-validator.d.ts +9 -0
  47. package/dist/lib/version-validator.d.ts.map +1 -1
  48. package/dist/lib/version-validator.js +69 -0
  49. package/dist/lib/version-validator.js.map +1 -1
  50. package/package.json +13 -2
@@ -0,0 +1,266 @@
1
+ import { execSync } from 'child_process';
2
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
3
+ import { dirname, join } from 'path';
4
+ import { getConfig } from './config.js';
5
+ /**
6
+ * ============================================================
7
+ * Install Ledger (S3 — beta-pipeline-robustness-2026-08-30 §4)
8
+ * ============================================================
9
+ *
10
+ * Records, at the END of an install, the provenance of every npm package that
11
+ * was installed: the manifest pin we asked for (`expected`), the version that
12
+ * actually landed on disk (`resolved`), the tarball URL it came from, the
13
+ * installer/step that produced it, and the ordered list of install steps.
14
+ *
15
+ * Goal (AC3.1): after any install, "이 버전이 어디서 왔나" ("where did this
16
+ * version come from?") is answerable from the ledger ALONE — no reverse
17
+ * engineering of the global node_modules.
18
+ *
19
+ * SCHEMA OWNERSHIP (manager freeze 2026-08-30): this file is the SSOT for the
20
+ * ledger schema; ledger.json is owned by S3 (this worker). Field names follow
21
+ * the 기획서. S1 (verify) and FB (pin override) live in verify-owned libs and
22
+ * do NOT own this schema. Dependency direction is one-way (verify → ledger):
23
+ * ledger.ts imports NOTHING from install-verify.ts / pin-override.ts.
24
+ *
25
+ * Writing the ledger MUST NOT break an install — every entry point here is
26
+ * best-effort and swallows its own errors.
27
+ */
28
+ /** Current ledger schema version. Bump on breaking field changes. */
29
+ export const LEDGER_SCHEMA_VERSION = 1;
30
+ /**
31
+ * Accumulates install steps in execution order. One instance per install;
32
+ * threaded through installSnapshot via InstallSnapshotOptions.recorder.
33
+ */
34
+ export class StepRecorder {
35
+ steps = [];
36
+ record(step) {
37
+ this.steps.push({ order: this.steps.length + 1, ...step });
38
+ }
39
+ getSteps() {
40
+ return this.steps.slice();
41
+ }
42
+ }
43
+ /** Path to the ledger file (sits next to current.json). */
44
+ export function getLedgerPath() {
45
+ const config = getConfig();
46
+ return join(config.configDir, 'ledger.json');
47
+ }
48
+ /**
49
+ * Query the globally-installed version + tarball URL for the given package
50
+ * names via a single `npm ls -g ... --json` call, and return the raw tree too.
51
+ * Best-effort: on total failure returns an all-null map and raw=null.
52
+ *
53
+ * NOTE: this is provenance extraction (version + tarball + raw tree), NOT the
54
+ * verify worker's single-name readInstalledNpmVersion(). No duplication of
55
+ * that helper — S3 never imports install-verify.
56
+ */
57
+ export function queryResolvedVersions(names) {
58
+ const map = new Map();
59
+ if (names.length === 0)
60
+ return { map, raw: null };
61
+ const parse = (text) => {
62
+ const data = JSON.parse(text);
63
+ const deps = data.dependencies || {};
64
+ for (const name of names) {
65
+ const node = deps[name];
66
+ map.set(name, { version: node?.version ?? null, tarballUrl: node?.resolved ?? null });
67
+ }
68
+ lastRaw = data;
69
+ return true;
70
+ };
71
+ let lastRaw = null;
72
+ try {
73
+ // --json gives { dependencies: { "<name>": { version, resolved } } }.
74
+ // depth=0 keeps the tree shallow (top-level globals only).
75
+ const cmd = `npm ls -g ${names.map((n) => JSON.stringify(n)).join(' ')} --json --depth=0`;
76
+ const out = execSync(cmd, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
77
+ parse(out);
78
+ return { map, raw: lastRaw };
79
+ }
80
+ catch (err) {
81
+ // `npm ls` exits non-zero on peer/extraneous warnings yet still prints valid
82
+ // JSON on stdout — recover it before giving up.
83
+ const stdout = err?.stdout;
84
+ if (stdout) {
85
+ try {
86
+ parse(stdout.toString());
87
+ return { map, raw: lastRaw };
88
+ }
89
+ catch {
90
+ /* fall through */
91
+ }
92
+ }
93
+ for (const name of names)
94
+ map.set(name, { version: null, tarballUrl: null });
95
+ return { map, raw: null };
96
+ }
97
+ }
98
+ /**
99
+ * Derive the canonical npm tarball URL for a resolved package.
100
+ *
101
+ * npm 7+ does NOT persist the fetched tarball URL for global installs
102
+ * (`npm ls -g --json` omits `resolved`, package.json is stripped of `_resolved`,
103
+ * and there is no global lockfile). So when the authoritative URL is missing we
104
+ * reconstruct the standard registry path — the same one npm would fetch from the
105
+ * scope's configured registry: `<registry>/<name>/-/<unscoped>-<version>.tgz`.
106
+ *
107
+ * Returns null when the version is unknown (nothing to point at). Best-effort:
108
+ * the registry is the one configured for the scope during install (registry-proxy).
109
+ */
110
+ export function deriveTarballUrl(registry, name, version) {
111
+ if (!version)
112
+ return null;
113
+ if (!registry)
114
+ return null;
115
+ const base = registry.replace(/\/+$/, '');
116
+ // Scoped "@ist/sesh" → unscoped "sesh"; unscoped "foo" → "foo".
117
+ const unscoped = name.includes('/') ? name.slice(name.indexOf('/') + 1) : name;
118
+ return `${base}/${name}/-/${unscoped}-${version}.tgz`;
119
+ }
120
+ /**
121
+ * Capture a DEEP dependency tree (`npm ls -g <names> --json --all`) for the
122
+ * ledger's `dependencyTreeRaw` and for coreFloorAssert (AC1.4).
123
+ *
124
+ * ★ Deliberately NOT `--depth=0`: nested copies must be visible (an old
125
+ * @ist/adapters-core buried under another package is exactly what re-fragments
126
+ * the registry). To avoid the cost of dumping the ENTIRE global tree, we scope
127
+ * the query to the install's npm packages + the singleton package — with filter
128
+ * args, `npm ls` prunes to the paths that reach those names (full depth), which
129
+ * is bounded yet still surfaces every nested copy of the targets.
130
+ *
131
+ * Best-effort: returns null on failure (ledger writing never fails an install).
132
+ */
133
+ export function queryDependencyTree(names) {
134
+ if (names.length === 0)
135
+ return null;
136
+ const args = names.map((n) => JSON.stringify(n)).join(' ');
137
+ const cmd = `npm ls -g ${args} --json --all`;
138
+ try {
139
+ const out = execSync(cmd, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
140
+ return JSON.parse(out);
141
+ }
142
+ catch (err) {
143
+ // `npm ls` exits non-zero on peer/extraneous warnings yet still prints valid
144
+ // JSON on stdout — recover it before giving up.
145
+ const stdout = err?.stdout;
146
+ if (stdout) {
147
+ try {
148
+ return JSON.parse(stdout.toString());
149
+ }
150
+ catch {
151
+ /* fall through */
152
+ }
153
+ }
154
+ return null;
155
+ }
156
+ }
157
+ /** Derive the registry host label from a tarball URL, for resolutionSource. */
158
+ function registryHostOf(tarballUrl, fallback) {
159
+ if (!tarballUrl)
160
+ return fallback;
161
+ try {
162
+ return new URL(tarballUrl).host;
163
+ }
164
+ catch {
165
+ return fallback;
166
+ }
167
+ }
168
+ /** Find the step (if any) whose specs targeted this package name. */
169
+ function findInstallingStep(name, steps) {
170
+ // Prefer the LAST step that targeted the package: fallbacks run after a failed
171
+ // batch, so the later step is the authoritative one.
172
+ let found;
173
+ for (const step of steps) {
174
+ if (step.specs.some((s) => s === name || s.startsWith(`${name}@`))) {
175
+ found = step;
176
+ }
177
+ }
178
+ return found;
179
+ }
180
+ /**
181
+ * Assemble the ledger: query disk for resolved versions/tarballs, then join
182
+ * against the expected pins and install steps to explain each package's origin.
183
+ * `now` is injected (callers stamp the timestamp) to keep this pure/testable.
184
+ * `resolver` is injectable for tests; defaults to the real `npm ls -g` query.
185
+ */
186
+ export function buildLedger(input, now, resolver = queryResolvedVersions) {
187
+ const names = Object.keys(input.expected);
188
+ const { map: resolvedMap, raw } = resolver(names);
189
+ // Prefer the injected DEEP tree (nested-visible) for dependencyTreeRaw; the
190
+ // resolver's shallow (--depth=0) tree is only a fallback for provenance.
191
+ const dependencyTreeRaw = input.dependencyTreeRaw !== undefined ? input.dependencyTreeRaw : raw;
192
+ const packages = [...names].sort().map((name) => {
193
+ const expected = input.expected[name] ?? null;
194
+ const resolvedInfo = resolvedMap.get(name) ?? { version: null, tarballUrl: null };
195
+ const resolved = resolvedInfo.version;
196
+ // Prefer the authoritative tarball URL from `npm ls` if present; npm 7+ does
197
+ // not persist it for globals, so fall back to the canonical registry path
198
+ // derived from the configured registry + resolved version (provenance
199
+ // completeness). null only when the version itself is unknown.
200
+ const tarballUrl = resolvedInfo.tarballUrl ?? deriveTarballUrl(input.registry, name, resolved);
201
+ const step = findInstallingStep(name, input.steps);
202
+ const host = registryHostOf(tarballUrl, registryHostOf(input.registry, input.registry));
203
+ const parts = [];
204
+ parts.push(resolved
205
+ ? `resolved ${resolved} from ${host}`
206
+ : `not found on disk (expected ${expected ?? 'unknown'})`);
207
+ if (step) {
208
+ parts.push(`via ${step.installer} (${step.phase} step #${step.order}, ${step.result})`);
209
+ }
210
+ else {
211
+ parts.push(`via ${input.installer}`);
212
+ }
213
+ if (expected && resolved && expected !== resolved) {
214
+ parts.push(`⚠ manifest expected ${expected} — DIVERGED`);
215
+ }
216
+ else if (expected) {
217
+ parts.push(`manifest pin ${expected}`);
218
+ }
219
+ return {
220
+ name,
221
+ expected,
222
+ resolved,
223
+ tarballUrl,
224
+ resolutionSource: parts.join('; '),
225
+ installer: step?.installer ?? input.installer,
226
+ };
227
+ });
228
+ return {
229
+ schemaVersion: LEDGER_SCHEMA_VERSION,
230
+ snapshot: { name: input.snapshotName, version: input.snapshotVersion },
231
+ recordedAt: now,
232
+ cliVersion: input.cliVersion,
233
+ registry: input.registry,
234
+ packages,
235
+ installSteps: input.steps,
236
+ overrides: input.overrides ?? {},
237
+ dependencyTreeRaw,
238
+ };
239
+ }
240
+ /** Write the ledger to disk. Best-effort — never throws into the caller. */
241
+ export function writeLedger(ledger) {
242
+ try {
243
+ const path = getLedgerPath();
244
+ const dir = dirname(path);
245
+ if (!existsSync(dir))
246
+ mkdirSync(dir, { recursive: true });
247
+ writeFileSync(path, JSON.stringify(ledger, null, 2));
248
+ return true;
249
+ }
250
+ catch {
251
+ return false;
252
+ }
253
+ }
254
+ /** Read the ledger from disk, or null if absent/unreadable. */
255
+ export function readLedger() {
256
+ try {
257
+ const path = getLedgerPath();
258
+ if (!existsSync(path))
259
+ return null;
260
+ return JSON.parse(readFileSync(path, 'utf-8'));
261
+ }
262
+ catch {
263
+ return null;
264
+ }
265
+ }
266
+ //# sourceMappingURL=ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../src/lib/ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * FB — Pin override fallback (hotfix path).
3
+ *
4
+ * `snapshot install @ist/beta --pin @ist/sesh@0.4.0` (repeatable) lets an owner
5
+ * override a single package's version WITHOUT re-publishing the whole manifest.
6
+ * This is the "1-package hotfix / pullback" lever from
7
+ * architecture/beta-pipeline-robustness-2026-08-30 §4 (FB).
8
+ *
9
+ * Overrides are exact-pin only (same reproducibility rule as publish) and are
10
+ * recorded in the install ledger so the override leaves a trace (AC FB.2).
11
+ */
12
+ export interface PinOverride {
13
+ name: string;
14
+ version: string;
15
+ }
16
+ /** Thrown when a --pin spec is malformed (fail-loud; never silently ignored). */
17
+ export declare class PinParseError extends Error {
18
+ }
19
+ /**
20
+ * Parse a single `--pin` spec of the form `<name>@<exact-version>`.
21
+ *
22
+ * Handles scoped names ("@ist/sesh@0.4.0") by splitting on the LAST '@'. The
23
+ * version must be an exact semver — ranges/tags/wildcards are rejected so an
24
+ * override cannot re-introduce the non-determinism it exists to fix.
25
+ */
26
+ export declare function parsePin(spec: string): PinOverride;
27
+ /**
28
+ * Parse a repeatable list of `--pin` specs into an override map (name → version).
29
+ * A later spec for the same name wins (last-write). Throws on the first invalid
30
+ * spec (fail-loud).
31
+ */
32
+ export declare function parsePins(specs: string[] | undefined): Record<string, string>;
33
+ /**
34
+ * Apply pin overrides to an install map, returning a NEW map (input untouched).
35
+ * Only overrides packages that are already present in the map — an override for
36
+ * a package the snapshot doesn't declare is surfaced by the caller (see
37
+ * `unmatchedOverrides`) rather than silently injected.
38
+ */
39
+ export declare function applyPinOverrides(installMap: Record<string, string>, overrides: Record<string, string>): Record<string, string>;
40
+ /**
41
+ * Return the override names that did NOT match any package in the install map.
42
+ * The caller warns on these (a --pin for a package not in the snapshot is almost
43
+ * always a typo).
44
+ */
45
+ export declare function unmatchedOverrides(installMap: Record<string, string>, overrides: Record<string, string>): string[];
46
+ /**
47
+ * The effective version for a package given a set of overrides — the override
48
+ * if one exists, otherwise the manifest version. Used to thread overrides
49
+ * through the recursive installer so a base-snapshot layer cannot clobber an
50
+ * override with its original pin.
51
+ */
52
+ export declare function effectiveVersion(name: string, version: string, overrides: Record<string, string>): string;
53
+ //# sourceMappingURL=pin-override.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pin-override.d.ts","sourceRoot":"","sources":["../../src/lib/pin-override.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,iFAAiF;AACjF,qBAAa,aAAc,SAAQ,KAAK;CAAG;AAE3C;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAqBlD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ7E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,EAAE,CAEV;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAER"}
@@ -0,0 +1,77 @@
1
+ import { isExactSemver } from './version-validator.js';
2
+ /** Thrown when a --pin spec is malformed (fail-loud; never silently ignored). */
3
+ export class PinParseError extends Error {
4
+ }
5
+ /**
6
+ * Parse a single `--pin` spec of the form `<name>@<exact-version>`.
7
+ *
8
+ * Handles scoped names ("@ist/sesh@0.4.0") by splitting on the LAST '@'. The
9
+ * version must be an exact semver — ranges/tags/wildcards are rejected so an
10
+ * override cannot re-introduce the non-determinism it exists to fix.
11
+ */
12
+ export function parsePin(spec) {
13
+ const trimmed = spec.trim();
14
+ const atIdx = trimmed.lastIndexOf('@');
15
+ // atIdx <= 0 → no version separator, or only the leading scope '@'.
16
+ if (atIdx <= 0) {
17
+ throw new PinParseError(`Invalid --pin "${spec}": expected <name>@<version> (e.g. @ist/sesh@0.4.0)`);
18
+ }
19
+ const name = trimmed.substring(0, atIdx);
20
+ const version = trimmed.substring(atIdx + 1);
21
+ if (!name) {
22
+ throw new PinParseError(`Invalid --pin "${spec}": missing package name`);
23
+ }
24
+ if (!isExactSemver(version)) {
25
+ throw new PinParseError(`Invalid --pin "${spec}": "${version}" is not an exact semver ` +
26
+ `(ranges, tags, and wildcards are not allowed for overrides)`);
27
+ }
28
+ return { name, version };
29
+ }
30
+ /**
31
+ * Parse a repeatable list of `--pin` specs into an override map (name → version).
32
+ * A later spec for the same name wins (last-write). Throws on the first invalid
33
+ * spec (fail-loud).
34
+ */
35
+ export function parsePins(specs) {
36
+ const overrides = {};
37
+ if (!specs)
38
+ return overrides;
39
+ for (const spec of specs) {
40
+ const { name, version } = parsePin(spec);
41
+ overrides[name] = version;
42
+ }
43
+ return overrides;
44
+ }
45
+ /**
46
+ * Apply pin overrides to an install map, returning a NEW map (input untouched).
47
+ * Only overrides packages that are already present in the map — an override for
48
+ * a package the snapshot doesn't declare is surfaced by the caller (see
49
+ * `unmatchedOverrides`) rather than silently injected.
50
+ */
51
+ export function applyPinOverrides(installMap, overrides) {
52
+ const out = { ...installMap };
53
+ for (const [name, version] of Object.entries(overrides)) {
54
+ if (name in out) {
55
+ out[name] = version;
56
+ }
57
+ }
58
+ return out;
59
+ }
60
+ /**
61
+ * Return the override names that did NOT match any package in the install map.
62
+ * The caller warns on these (a --pin for a package not in the snapshot is almost
63
+ * always a typo).
64
+ */
65
+ export function unmatchedOverrides(installMap, overrides) {
66
+ return Object.keys(overrides).filter((name) => !(name in installMap));
67
+ }
68
+ /**
69
+ * The effective version for a package given a set of overrides — the override
70
+ * if one exists, otherwise the manifest version. Used to thread overrides
71
+ * through the recursive installer so a base-snapshot layer cannot clobber an
72
+ * override with its original pin.
73
+ */
74
+ export function effectiveVersion(name, version, overrides) {
75
+ return overrides[name] ?? version;
76
+ }
77
+ //# sourceMappingURL=pin-override.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pin-override.js","sourceRoot":"","sources":["../../src/lib/pin-override.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAmBvD,iFAAiF;AACjF,MAAM,OAAO,aAAc,SAAQ,KAAK;CAAG;AAE3C;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACvC,oEAAoE;IACpE,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,aAAa,CACrB,kBAAkB,IAAI,qDAAqD,CAC5E,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC7C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,aAAa,CAAC,kBAAkB,IAAI,yBAAyB,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,aAAa,CACrB,kBAAkB,IAAI,OAAO,OAAO,2BAA2B;YAC7D,6DAA6D,CAChE,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,KAA2B;IACnD,MAAM,SAAS,GAA2B,EAAE,CAAC;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QACzC,SAAS,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;IAC5B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAAkC,EAClC,SAAiC;IAEjC,MAAM,GAAG,GAA2B,EAAE,GAAG,UAAU,EAAE,CAAC;IACtD,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACxD,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YAChB,GAAG,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAAkC,EAClC,SAAiC;IAEjC,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC;AACxE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,OAAe,EACf,SAAiC;IAEjC,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;AACpC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"skit-adapter.d.ts","sourceRoot":"","sources":["../../src/lib/skit-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,MAAM,WAAW,kBAAkB;IACjC,wBAAwB;IACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,sCAAsC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8DD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAGzC;AA+DD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAyD5B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAG3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAO5C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC;IACnD,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;CACnC,CAAC,CASD"}
1
+ {"version":3,"file":"skit-adapter.d.ts","sourceRoot":"","sources":["../../src/lib/skit-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,MAAM,WAAW,kBAAkB;IACjC,wBAAwB;IACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,sCAAsC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8DD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAGzC;AAgFD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CA8E5B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAG3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAO5C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC;IACnD,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;CACnC,CAAC,CASD"}
@@ -10,7 +10,7 @@
10
10
  * - SKIT_REGISTRY: registry-proxy URL
11
11
  */
12
12
  import { execSync } from 'child_process';
13
- import { REGISTRY_PROXY_URL } from './config.js';
13
+ import { REGISTRY_PROXY_URL, getInstallerGroupFromEnv } from './config.js';
14
14
  // ============================================================
15
15
  // Lib Loader
16
16
  // ============================================================
@@ -85,13 +85,28 @@ function installSkitViaCli(spec, options) {
85
85
  if (!options?.silent) {
86
86
  options?.onProgress?.(`[skit-cli] ${command}`);
87
87
  }
88
- // Build environment variables for skit CLI
89
- // SKIT_SESSION_ID: registry-proxy session (skit doesn't know LICENSE_KEY)
90
- // SKIT_REGISTRY: registry-proxy URL
88
+ // Build environment variables for skit CLI. Two independent injection groups
89
+ // (generality-contract-r1):
91
90
  const env = {};
91
+ // Group A — registry/proxy: sessionId-GATED (licensing-entangled; behavior
92
+ // unchanged). Also forward the common-env name IST_REGISTRY_URL alongside the
93
+ // existing SKIT_REGISTRY. Both carry the same resolved URL.
92
94
  if (options?.sessionId) {
93
95
  env['SKIT_SESSION_ID'] = options.sessionId;
94
96
  env['SKIT_REGISTRY'] = REGISTRY_PROXY_URL;
97
+ env['IST_REGISTRY_URL'] = REGISTRY_PROXY_URL;
98
+ }
99
+ // Group B — host/group routing: PASSTHROUGH-ONLY, sessionId-INDEPENDENT.
100
+ // Forward only values originating from env/manifest, NEVER snapshot's own
101
+ // built-in owner fallback (each tool's fallback is its single authority).
102
+ // - IST_GITLAB_HOST: snapshot owns no host; forward only when env is present.
103
+ // - IST_GITLAB_GROUP: forward only the env-origin value (getInstallerGroupFromEnv).
104
+ if (process.env.IST_GITLAB_HOST) {
105
+ env['IST_GITLAB_HOST'] = process.env.IST_GITLAB_HOST;
106
+ }
107
+ const groupFromEnv = getInstallerGroupFromEnv();
108
+ if (groupFromEnv) {
109
+ env['IST_GITLAB_GROUP'] = groupFromEnv;
95
110
  }
96
111
  const result = runSkitCli(command, Object.keys(env).length > 0 ? env : undefined);
97
112
  return {
@@ -118,18 +133,40 @@ export async function installSkitPackage(name, version, options) {
118
133
  const lib = await loadSkitLib();
119
134
  if (lib) {
120
135
  try {
121
- // Set session environment variables for lib call
122
- // skit lib reads SKIT_SESSION_ID and SKIT_REGISTRY from process.env
123
- const prevSessionId = process.env.SKIT_SESSION_ID;
124
- const prevRegistry = process.env.SKIT_REGISTRY;
136
+ // Set routing environment variables for the in-process lib call. skit lib
137
+ // reads these from process.env. Same two-group split as the CLI path
138
+ // (generality-contract-r1). Snapshot every key we may touch up-front and
139
+ // restore ALL of them in finally — no leak into the host process.
140
+ const TOUCHED_ENV_KEYS = [
141
+ 'SKIT_SESSION_ID',
142
+ 'SKIT_REGISTRY',
143
+ 'IST_REGISTRY_URL',
144
+ 'IST_GITLAB_HOST',
145
+ 'IST_GITLAB_GROUP',
146
+ ];
147
+ const savedEnv = {};
148
+ for (const key of TOUCHED_ENV_KEYS) {
149
+ savedEnv[key] = process.env[key];
150
+ }
151
+ // Group A — registry/proxy: sessionId-GATED (behavior unchanged) + common
152
+ // env name IST_REGISTRY_URL.
125
153
  if (options?.sessionId) {
126
154
  process.env.SKIT_SESSION_ID = options.sessionId;
127
155
  process.env.SKIT_REGISTRY = REGISTRY_PROXY_URL;
156
+ process.env.IST_REGISTRY_URL = REGISTRY_PROXY_URL;
128
157
  console.log(`[skit-adapter] Using session: ${options.sessionId.substring(0, 8)}...`);
129
158
  }
130
159
  else {
131
160
  console.log(`[skit-adapter] No sessionId provided`);
132
161
  }
162
+ // Group B — host/group routing: PASSTHROUGH-ONLY, sessionId-INDEPENDENT.
163
+ // IST_GITLAB_HOST needs no assignment in-process (the lib reads the same
164
+ // process.env passthrough directly); forward only env-origin group, never
165
+ // snapshot's own built-in owner fallback.
166
+ const groupFromEnv = getInstallerGroupFromEnv();
167
+ if (groupFromEnv) {
168
+ process.env.IST_GITLAB_GROUP = groupFromEnv;
169
+ }
133
170
  try {
134
171
  const libResult = await lib.installSkit(spec, {
135
172
  onProgress: options?.silent ? undefined : options?.onProgress,
@@ -143,18 +180,15 @@ export async function installSkitPackage(name, version, options) {
143
180
  };
144
181
  }
145
182
  finally {
146
- // Restore previous environment
147
- if (prevSessionId !== undefined) {
148
- process.env.SKIT_SESSION_ID = prevSessionId;
149
- }
150
- else {
151
- delete process.env.SKIT_SESSION_ID;
152
- }
153
- if (prevRegistry !== undefined) {
154
- process.env.SKIT_REGISTRY = prevRegistry;
155
- }
156
- else {
157
- delete process.env.SKIT_REGISTRY;
183
+ // Restore previous environment for EVERY touched key (no omissions).
184
+ for (const key of TOUCHED_ENV_KEYS) {
185
+ const prev = savedEnv[key];
186
+ if (prev !== undefined) {
187
+ process.env[key] = prev;
188
+ }
189
+ else {
190
+ delete process.env[key];
191
+ }
158
192
  }
159
193
  }
160
194
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skit-adapter.js","sourceRoot":"","sources":["../../src/lib/skit-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skit-adapter.js","sourceRoot":"","sources":["../../src/lib/skit-adapter.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"transitive-resolver.d.ts","sourceRoot":"","sources":["../../src/lib/transitive-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE;QACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,GAAG,CAAC,EAAE,KAAK,CAAC;YACV,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC,CAAC;KACJ,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,YAAY,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,0BAA0B;IACzC,uCAAuC;IACvC,GAAG,EAAE,eAAe,EAAE,CAAC;IACvB,sBAAsB;IACtB,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,kBAAkB;IAClB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAYD;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAmWD,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,0BAA0B,CAAC,CAqDrC;AAMD,MAAM,WAAW,6BAA6B;IAC5C,iEAAiE;IACjE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,6BAA6B,CAAC,CAiGxC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
1
+ {"version":3,"file":"transitive-resolver.d.ts","sourceRoot":"","sources":["../../src/lib/transitive-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE;QACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,GAAG,CAAC,EAAE,KAAK,CAAC;YACV,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC,CAAC;KACJ,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,YAAY,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,0BAA0B;IACzC,uCAAuC;IACvC,GAAG,EAAE,eAAe,EAAE,CAAC;IACvB,sBAAsB;IACtB,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,kBAAkB;IAClB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAYD;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAmWD,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,0BAA0B,CAAC,CA+DrC;AAMD,MAAM,WAAW,6BAA6B;IAC5C,iEAAiE;IACjE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,6BAA6B,CAAC,CAiGxC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
@@ -294,7 +294,12 @@ async function resolveNpmTransitiveDeps(packages, scopes, groupId) {
294
294
  * options.scopes가 지정되면 해당 값 사용, 아니면 수집된 scopeGroups 사용
295
295
  */
296
296
  export async function resolveAllDependencies(snapshotName, options = {}) {
297
- const { resolveTransitive = true, scopes: providedScopes, groupId = GITLAB_GROUP_ID, } = options;
297
+ const { resolveTransitive = true, scopes: providedScopes,
298
+ // NOTE: do NOT default to GITLAB_GROUP_ID here. Pre-filling the installer
299
+ // group as the default masked the author group (manifest registry[scope].group)
300
+ // at the call-site below. Per generality-contract, group precedence is
301
+ // author-first → installer → owner fallback (see effectiveGroupId).
302
+ groupId: explicitGroupId, } = options;
298
303
  const ctx = {
299
304
  visitedSnapshots: new Set(),
300
305
  visitedSkits: new Set(),
@@ -312,8 +317,14 @@ export async function resolveAllDependencies(snapshotName, options = {}) {
312
317
  const effectiveScopes = providedScopes || Array.from(ctx.scopeGroups.keys());
313
318
  // 추적 대상 스코프의 패키지만 transitive 해석
314
319
  const trackedPackages = npmPackages.filter(p => effectiveScopes.some(scope => p.name.startsWith(scope)));
315
- // snapshot.registry에서 수집한 group 또는 옵션에서 제공된 groupId 사용
316
- const effectiveGroupId = groupId || Array.from(ctx.scopeGroups.values())[0] || '';
320
+ // Group precedence (generality-contract): author-first → installer → owner.
321
+ // 1. explicitGroupId — per-invocation override (highest)
322
+ // 2. author group — manifest registry[scope].group (ctx.scopeGroups)
323
+ // 3. installer/owner — GITLAB_GROUP_ID const (IST_GITLAB_GROUP env →
324
+ // GITLAB_GROUP_ID legacy → owner fallback)
325
+ // Owner manifests declare the owner group, so no-config runs stay identical.
326
+ const authorGroup = Array.from(ctx.scopeGroups.values())[0];
327
+ const effectiveGroupId = explicitGroupId || authorGroup || GITLAB_GROUP_ID || '';
317
328
  if (trackedPackages.length > 0 && effectiveGroupId && effectiveScopes.length > 0) {
318
329
  const resolved = await resolveNpmTransitiveDeps(trackedPackages, effectiveScopes, effectiveGroupId);
319
330
  // 기존 수집된 것과 merge