@sentropic/llm-mesh 0.32.4 → 0.34.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 (73) hide show
  1. package/dist/enrollment/index.d.ts +4 -0
  2. package/dist/enrollment/index.d.ts.map +1 -1
  3. package/dist/enrollment/index.js +2 -0
  4. package/dist/enrollment/index.js.map +1 -1
  5. package/dist/enrollment/muse-code.d.ts +9 -0
  6. package/dist/enrollment/muse-code.d.ts.map +1 -1
  7. package/dist/enrollment/muse-code.js +22 -1
  8. package/dist/enrollment/muse-code.js.map +1 -1
  9. package/dist/enrollment/seat-onboarding-projections.d.ts +44 -0
  10. package/dist/enrollment/seat-onboarding-projections.d.ts.map +1 -0
  11. package/dist/enrollment/seat-onboarding-projections.js +113 -0
  12. package/dist/enrollment/seat-onboarding-projections.js.map +1 -0
  13. package/dist/enrollment/seat-onboarding.d.ts +161 -0
  14. package/dist/enrollment/seat-onboarding.d.ts.map +1 -0
  15. package/dist/enrollment/seat-onboarding.js +698 -0
  16. package/dist/enrollment/seat-onboarding.js.map +1 -0
  17. package/dist/node/index.d.ts +8 -0
  18. package/dist/node/index.d.ts.map +1 -1
  19. package/dist/node/index.js +4 -0
  20. package/dist/node/index.js.map +1 -1
  21. package/dist/node/seat-onboarding-capture.d.ts +47 -0
  22. package/dist/node/seat-onboarding-capture.d.ts.map +1 -0
  23. package/dist/node/seat-onboarding-capture.js +164 -0
  24. package/dist/node/seat-onboarding-capture.js.map +1 -0
  25. package/dist/node/seat-onboarding-cell-compose.d.ts +25 -0
  26. package/dist/node/seat-onboarding-cell-compose.d.ts.map +1 -0
  27. package/dist/node/seat-onboarding-cell-compose.js +117 -0
  28. package/dist/node/seat-onboarding-cell-compose.js.map +1 -0
  29. package/dist/node/seat-onboarding-erase.d.ts +8 -0
  30. package/dist/node/seat-onboarding-erase.d.ts.map +1 -0
  31. package/dist/node/seat-onboarding-erase.js +31 -0
  32. package/dist/node/seat-onboarding-erase.js.map +1 -0
  33. package/dist/node/seat-onboarding-materialize.d.ts +6 -0
  34. package/dist/node/seat-onboarding-materialize.d.ts.map +1 -0
  35. package/dist/node/seat-onboarding-materialize.js +11 -0
  36. package/dist/node/seat-onboarding-materialize.js.map +1 -0
  37. package/dist/node/seat-onboarding-record.d.ts +11 -0
  38. package/dist/node/seat-onboarding-record.d.ts.map +1 -0
  39. package/dist/node/seat-onboarding-record.js +86 -0
  40. package/dist/node/seat-onboarding-record.js.map +1 -0
  41. package/dist/node/seat-onboarding-stage1.d.ts +11 -0
  42. package/dist/node/seat-onboarding-stage1.d.ts.map +1 -0
  43. package/dist/node/seat-onboarding-stage1.js +121 -0
  44. package/dist/node/seat-onboarding-stage1.js.map +1 -0
  45. package/dist/node/seat-onboarding-stage2.d.ts +10 -0
  46. package/dist/node/seat-onboarding-stage2.d.ts.map +1 -0
  47. package/dist/node/seat-onboarding-stage2.js +110 -0
  48. package/dist/node/seat-onboarding-stage2.js.map +1 -0
  49. package/dist/node/seat-onboarding-types.d.ts +106 -0
  50. package/dist/node/seat-onboarding-types.d.ts.map +1 -0
  51. package/dist/node/seat-onboarding-types.js +6 -0
  52. package/dist/node/seat-onboarding-types.js.map +1 -0
  53. package/dist/node/seat-stage-write.d.ts +25 -0
  54. package/dist/node/seat-stage-write.d.ts.map +1 -0
  55. package/dist/node/seat-stage-write.js +93 -0
  56. package/dist/node/seat-stage-write.js.map +1 -0
  57. package/dist/service/custodian-refresh.d.ts +52 -0
  58. package/dist/service/custodian-refresh.d.ts.map +1 -0
  59. package/dist/service/custodian-refresh.js +51 -0
  60. package/dist/service/custodian-refresh.js.map +1 -0
  61. package/dist/service/facade.d.ts +28 -0
  62. package/dist/service/facade.d.ts.map +1 -1
  63. package/dist/service/facade.js +18 -1
  64. package/dist/service/facade.js.map +1 -1
  65. package/dist/service/local-account-transport-service.d.ts +127 -2
  66. package/dist/service/local-account-transport-service.d.ts.map +1 -1
  67. package/dist/service/local-account-transport-service.js +540 -10
  68. package/dist/service/local-account-transport-service.js.map +1 -1
  69. package/dist/service/reauth-alert.d.ts +29 -0
  70. package/dist/service/reauth-alert.d.ts.map +1 -0
  71. package/dist/service/reauth-alert.js +2 -0
  72. package/dist/service/reauth-alert.js.map +1 -0
  73. package/package.json +1 -1
@@ -0,0 +1,86 @@
1
+ //
2
+ // Stage-2 seat-record read: re-read and re-validate the stage-1 seat record
3
+ // (bundle + onboarding + binding + versions) and re-derive the launch gate.
4
+ // A stored gate that disagrees with the derivation is a tampered record.
5
+ // Internal module: not exported from the package entry points.
6
+ import { lstat, readFile } from 'node:fs/promises';
7
+ import { join } from 'node:path';
8
+ import { validateSeatBundle } from '../enrollment/seat-bundle.js';
9
+ import { seatLaunchGate, validateSeatOnboarding, } from '../enrollment/seat-onboarding.js';
10
+ import { SEAT_RECORD_REL_PATH, fail, isRecord } from './seat-stage-write.js';
11
+ /**
12
+ * Read and re-validate the seat record of a staged seat directory. Throws a
13
+ * StageRefusal (via `fail`) on any mismatch, missing or symlinked record.
14
+ */
15
+ export async function readSeatRecord(input) {
16
+ const { seatDir } = input;
17
+ const seatSt = await lstat(seatDir).catch(() => null);
18
+ if (!seatSt || seatSt.isSymbolicLink() || !seatSt.isDirectory()) {
19
+ fail('onboarding-shape-unverified', 'seatDir must be an existing directory');
20
+ }
21
+ const recordPath = join(seatDir, SEAT_RECORD_REL_PATH);
22
+ const recordSt = await lstat(recordPath).catch(() => null);
23
+ if (!recordSt || recordSt.isSymbolicLink() || !recordSt.isFile()) {
24
+ fail('onboarding-shape-unverified', 'seat record missing or not a regular file');
25
+ }
26
+ let record;
27
+ try {
28
+ record = JSON.parse(await readFile(recordPath, 'utf8'));
29
+ }
30
+ catch {
31
+ fail('onboarding-shape-unverified', 'seat record is not JSON');
32
+ }
33
+ if (!isRecord(record))
34
+ fail('onboarding-shape-unverified', 'seat record must be an object');
35
+ const badRecordKey = Object.keys(record).find((k) => !['version', 'bundle', 'onboarding', 'launchGate', 'authFiles'].includes(k));
36
+ if (badRecordKey)
37
+ fail('onboarding-unknown-field', `unknown seat record field: ${badRecordKey}`);
38
+ if (record['version'] !== 1)
39
+ fail('onboarding-schema-mismatch', 'seat record version must be 1');
40
+ const bundleResult = validateSeatBundle(record['bundle'], { trustedAuthority: 'consumer' });
41
+ if (!bundleResult.ok)
42
+ fail(bundleResult.code, bundleResult.detail);
43
+ const bundle = bundleResult.bundle;
44
+ const cli = bundle.identity.cli;
45
+ let onboarding = null;
46
+ let onboardingStatus = 'absent';
47
+ if (record['onboarding'] !== null && record['onboarding'] !== undefined) {
48
+ const blockResult = validateSeatOnboarding(record['onboarding']);
49
+ if (!blockResult.ok)
50
+ fail(blockResult.code, blockResult.detail);
51
+ onboarding = blockResult.block;
52
+ onboardingStatus = 'present';
53
+ const lifecycle = bundle.lifecycle;
54
+ if (onboarding.cli !== cli ||
55
+ onboarding.seatRef !== bundle.identity.seatRef ||
56
+ onboarding.accountBinding !== bundle.provenance.accountBinding ||
57
+ onboarding.consent.ownerScope !== bundle.identity.ownerScope ||
58
+ onboarding.lineage.epoch !== lifecycle.epoch ||
59
+ onboarding.lineage.generation !== lifecycle.generation ||
60
+ onboarding.lineage.operationId !== lifecycle.operationId) {
61
+ fail('onboarding-lineage-mismatch', 'seat record binding mismatch');
62
+ }
63
+ if (bundle.identity.nativeCliVersion !== onboarding.nativeCliVersion) {
64
+ fail('onboarding-version-mismatch', 'record version mismatch');
65
+ }
66
+ }
67
+ if (bundle.identity.ownerScope !== input.ownerScope) {
68
+ fail('onboarding-lineage-mismatch', 'ownerScope does not match the seat record');
69
+ }
70
+ if (bundle.identity.nativeCliVersion !== undefined && bundle.identity.nativeCliVersion !== input.expectedNativeCliVersion) {
71
+ fail('onboarding-version-mismatch', 'bundle nativeCliVersion does not match the expected version');
72
+ }
73
+ if (onboarding && onboarding.nativeCliVersion !== input.expectedNativeCliVersion) {
74
+ fail('onboarding-version-mismatch', 'block nativeCliVersion does not match the expected version');
75
+ }
76
+ const derivedGate = seatLaunchGate(cli, onboardingStatus);
77
+ if (JSON.stringify(record['launchGate']) !== JSON.stringify(derivedGate)) {
78
+ fail('onboarding-lineage-mismatch', 'stored launchGate disagrees with the re-derived gate');
79
+ }
80
+ const authFiles = record['authFiles'];
81
+ if (!Array.isArray(authFiles) || authFiles.some((n) => typeof n !== 'string')) {
82
+ fail('onboarding-schema-mismatch', 'seat record authFiles must be a string list');
83
+ }
84
+ return { bundle, onboarding, onboardingStatus, launchGate: derivedGate, authFiles: authFiles };
85
+ }
86
+ //# sourceMappingURL=seat-onboarding-record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-onboarding-record.js","sourceRoot":"","sources":["../../src/node/seat-onboarding-record.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { SeatStageInput, SeatStageResult } from './seat-onboarding-types.js';
2
+ /**
3
+ * Stage 1, batch and two-phase: phase 1 validates every envelope (bundle,
4
+ * agy tuple, auth allowlist, onboarding binding, versions, digests, size
5
+ * bounds, claude minimized projection) and refuses the whole batch on the
6
+ * first failure with zero bytes written; an absent block is valid and
7
+ * stages with a closed launch gate. Phase 2 writes auth files at their
8
+ * storage names plus the seat record, per seat.
9
+ */
10
+ export declare function materialiseSeatEnvelopes(input: SeatStageInput): Promise<SeatStageResult>;
11
+ //# sourceMappingURL=seat-onboarding-stage1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-onboarding-stage1.d.ts","sourceRoot":"","sources":["../../src/node/seat-onboarding-stage1.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,cAAc,EAGd,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAkCpC;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAoF9F"}
@@ -0,0 +1,121 @@
1
+ //
2
+ // Stage 1 (seat stage): batch two-phase materialization of validated seat
3
+ // envelopes into per-seat directories, plus the library-owned seat record.
4
+ import { chmod, lstat, mkdir } from 'node:fs/promises';
5
+ import { join, resolve } from 'node:path';
6
+ import { validateSeatEnvelope, } from '../enrollment/seat-onboarding.js';
7
+ import { SEAT_RECORD_REL_PATH, asResult, decodeBase64, fail, isRecord, sha256Hex, utf8, writeExclusive, assertCleanAncestors, DIR_MODE, } from './seat-stage-write.js';
8
+ /** Auth `.claude.json` minimized-projection key set (stage-1 check, §3.3). */
9
+ const CLAUDE_AUTH_MINIMIZED_KEYS = ['oauthAccount', 'hasCompletedOnboarding', 'lastOnboardingVersion'];
10
+ function checkClaudeAuthMinimized(files) {
11
+ const raw = files['.claude.json'];
12
+ if (raw === undefined)
13
+ return;
14
+ let obj;
15
+ try {
16
+ obj = JSON.parse(new TextDecoder().decode(decodeBase64(raw)));
17
+ }
18
+ catch {
19
+ fail('onboarding-shape-unverified', 'auth .claude.json is not JSON');
20
+ }
21
+ if (!isRecord(obj))
22
+ fail('onboarding-shape-unverified', 'auth .claude.json must be an object');
23
+ for (const key of Object.keys(obj)) {
24
+ if (!CLAUDE_AUTH_MINIMIZED_KEYS.includes(key)) {
25
+ fail('onboarding-shape-unverified', `non-minimized auth .claude.json key: ${key}`);
26
+ }
27
+ }
28
+ }
29
+ /**
30
+ * Stage 1, batch and two-phase: phase 1 validates every envelope (bundle,
31
+ * agy tuple, auth allowlist, onboarding binding, versions, digests, size
32
+ * bounds, claude minimized projection) and refuses the whole batch on the
33
+ * first failure with zero bytes written; an absent block is valid and
34
+ * stages with a closed launch gate. Phase 2 writes auth files at their
35
+ * storage names plus the seat record, per seat.
36
+ */
37
+ export async function materialiseSeatEnvelopes(input) {
38
+ try {
39
+ if (!isRecord(input) || !Array.isArray(input['seats']) || input['seats'].length === 0) {
40
+ fail('schema-mismatch', 'seats must be a non-empty array');
41
+ }
42
+ const ownerScope = input['ownerScope'];
43
+ if (typeof ownerScope !== 'string' || ownerScope.length === 0)
44
+ fail('schema-mismatch', 'ownerScope is required');
45
+ const expectedVersions = (input['expectedNativeCliVersions'] ?? {});
46
+ const validated = [];
47
+ const seenDirs = new Set();
48
+ for (const seat of input['seats']) {
49
+ if (!isRecord(seat) || typeof seat['seatDir'] !== 'string' || seat['seatDir'].length === 0) {
50
+ fail('schema-mismatch', 'each seat needs a seatDir');
51
+ }
52
+ const seatDir = resolve(seat['seatDir']);
53
+ if (seenDirs.has(seatDir))
54
+ fail('schema-mismatch', 'duplicate seatDir in batch');
55
+ seenDirs.add(seatDir);
56
+ const env = validateSeatEnvelope(seat['envelope'], { trustedAuthority: 'consumer' });
57
+ if (!env.ok)
58
+ fail(env.code, env.detail);
59
+ const { bundle, files, onboarding, onboardingStatus, launchGate } = env;
60
+ if (bundle.identity.ownerScope !== ownerScope) {
61
+ fail('onboarding-lineage-mismatch', 'bundle ownerScope does not match the stage ownerScope');
62
+ }
63
+ const expected = expectedVersions[bundle.identity.cli];
64
+ if (expected !== undefined && bundle.identity.nativeCliVersion !== expected) {
65
+ fail('onboarding-version-mismatch', 'bundle nativeCliVersion does not match the expected version');
66
+ }
67
+ if (bundle.identity.cli === 'claude')
68
+ checkClaudeAuthMinimized(files);
69
+ const existing = await lstat(seatDir).catch(() => null);
70
+ if (existing)
71
+ fail('onboarding-shape-unverified', `seatDir already exists: ${seatDir}`);
72
+ await assertCleanAncestors(seatDir);
73
+ validated.push({ seatDir, bundle, files, onboarding, onboardingStatus, launchGate });
74
+ }
75
+ const seats = [];
76
+ for (const v of validated) {
77
+ await mkdir(v.seatDir, { recursive: true, mode: DIR_MODE });
78
+ await chmod(v.seatDir, DIR_MODE);
79
+ const authFiles = Object.keys(v.files).sort();
80
+ for (const name of authFiles) {
81
+ await writeExclusive([v.seatDir], join(v.seatDir, name), decodeBase64(v.files[name]));
82
+ }
83
+ const record = {
84
+ version: 1,
85
+ bundle: v.bundle,
86
+ onboarding: v.onboarding,
87
+ launchGate: v.launchGate,
88
+ authFiles,
89
+ };
90
+ const recordBytes = utf8(`${JSON.stringify(record, null, 2)}\n`);
91
+ await writeExclusive([v.seatDir], join(v.seatDir, SEAT_RECORD_REL_PATH), recordBytes);
92
+ seats.push({
93
+ seatRef: v.bundle.identity.seatRef,
94
+ cli: v.bundle.identity.cli,
95
+ authFiles,
96
+ seatRecordSha256: sha256Hex(recordBytes),
97
+ onboardingStatus: v.onboardingStatus,
98
+ launchGate: v.launchGate,
99
+ onboarding: v.onboarding
100
+ ? {
101
+ files: v.onboarding.files.map((f) => ({
102
+ destKey: f.destKey,
103
+ format: f.format,
104
+ sha256: f.sha256,
105
+ byteLength: f.byteLength,
106
+ })),
107
+ nativeCliVersion: v.onboarding.nativeCliVersion,
108
+ capturedAt: v.onboarding.capturedAt,
109
+ lineage: v.onboarding.lineage,
110
+ ...(v.onboarding.reboundFrom ? { reboundFrom: v.onboarding.reboundFrom } : {}),
111
+ }
112
+ : null,
113
+ });
114
+ }
115
+ return { ok: true, receipt: { seats } };
116
+ }
117
+ catch (error) {
118
+ return asResult(error);
119
+ }
120
+ }
121
+ //# sourceMappingURL=seat-onboarding-stage1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-onboarding-stage1.js","sourceRoot":"","sources":["../../src/node/seat-onboarding-stage1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { SeatCellInput, SeatCellResult } from './seat-onboarding-types.js';
2
+ /**
3
+ * Stage 2, one seat into one fresh cell HOME. Re-reads and re-validates the
4
+ * seat record (binding + versions), re-derives the launch gate (a stored
5
+ * gate that disagrees is a tampered record), refuses a closed gate with
6
+ * `onboarding-required` before any write, then writes as single writer per
7
+ * owned destination. The seatDir is opened read-only and never mutated.
8
+ */
9
+ export declare function materialiseCellHome(input: SeatCellInput): Promise<SeatCellResult>;
10
+ //# sourceMappingURL=seat-onboarding-stage2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-onboarding-stage2.d.ts","sourceRoot":"","sources":["../../src/node/seat-onboarding-stage2.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAEV,aAAa,EACb,cAAc,EAEf,MAAM,4BAA4B,CAAC;AAUpC;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAiFvF"}
@@ -0,0 +1,110 @@
1
+ //
2
+ // Stage 2 (cell stage): seed one fresh cell HOME from a staged seat record.
3
+ // Single writer per owned destination; the seatDir is opened read-only.
4
+ import { lstat, readdir, readFile } from 'node:fs/promises';
5
+ import { join, resolve } from 'node:path';
6
+ import { SEAT_ENVELOPE_AUTH_FILES } from '../enrollment/seat-onboarding.js';
7
+ import { authCellDest, planOnboardingWrites, receiptRelPath } from './seat-onboarding-cell-compose.js';
8
+ import { readSeatRecord } from './seat-onboarding-record.js';
9
+ import { asResult, fail, isRecord, sha256Hex, writeExclusive, assertCleanAncestors, } from './seat-stage-write.js';
10
+ /**
11
+ * Stage 2, one seat into one fresh cell HOME. Re-reads and re-validates the
12
+ * seat record (binding + versions), re-derives the launch gate (a stored
13
+ * gate that disagrees is a tampered record), refuses a closed gate with
14
+ * `onboarding-required` before any write, then writes as single writer per
15
+ * owned destination. The seatDir is opened read-only and never mutated.
16
+ */
17
+ export async function materialiseCellHome(input) {
18
+ try {
19
+ if (!isRecord(input))
20
+ fail('schema-mismatch', 'input must be an object');
21
+ for (const key of ['seatDir', 'cellHome', 'workspaceDir', 'expectedNativeCliVersion', 'ownerScope']) {
22
+ if (typeof input[key] !== 'string' || input[key].length === 0)
23
+ fail('schema-mismatch', `${key} is required`);
24
+ }
25
+ if (!isRecord(input['configDirs']))
26
+ fail('schema-mismatch', 'configDirs is required');
27
+ const seatDir = resolve(input.seatDir);
28
+ const cellHome = resolve(input.cellHome);
29
+ const workspaceDir = resolve(input.workspaceDir);
30
+ const configDirs = {
31
+ claudeConfigDir: resolve(input.configDirs['claudeConfigDir']),
32
+ codexHome: resolve(input.configDirs['codexHome']),
33
+ xdgConfigHome: resolve(input.configDirs['xdgConfigHome']),
34
+ };
35
+ const record = await readSeatRecord({
36
+ seatDir,
37
+ expectedNativeCliVersion: input.expectedNativeCliVersion,
38
+ ownerScope: input.ownerScope,
39
+ });
40
+ const { bundle, onboarding, launchGate } = record;
41
+ const cli = bundle.identity.cli;
42
+ if (!launchGate.eligible)
43
+ fail('onboarding-required', 'launch gate is closed for this seat');
44
+ const wsSt = await lstat(workspaceDir).catch(() => null);
45
+ if (!wsSt || wsSt.isSymbolicLink() || !wsSt.isDirectory()) {
46
+ fail('onboarding-shape-unverified', 'workspaceDir must be an existing directory');
47
+ }
48
+ if (onboarding && onboarding.cellSynthesis.length > 0) {
49
+ // Q2: the trust write is allowed only for the bench-created empty workspace.
50
+ const entries = await readdir(workspaceDir);
51
+ if (entries.length > 0) {
52
+ fail('onboarding-shape-unverified', 'trust write is limited to the empty bench-created workspace (Q2)');
53
+ }
54
+ }
55
+ const cellSt = await lstat(cellHome).catch(() => null);
56
+ if (cellSt)
57
+ fail('onboarding-shape-unverified', 'cellHome must be fresh (not pre-existing)');
58
+ for (const dir of Object.values(configDirs)) {
59
+ const st = await lstat(dir).catch(() => null);
60
+ if (st)
61
+ fail('onboarding-shape-unverified', `configDir must be fresh: ${dir}`);
62
+ }
63
+ const roots = [cellHome, configDirs.claudeConfigDir, configDirs.codexHome, configDirs.xdgConfigHome];
64
+ for (const root of roots)
65
+ await assertCleanAncestors(root);
66
+ // plan every write before writing any byte
67
+ const writes = [];
68
+ const allowlist = SEAT_ENVELOPE_AUTH_FILES[cli];
69
+ for (const name of record.authFiles) {
70
+ if (!allowlist.includes(name))
71
+ fail('unknown-field', `auth file not allowlisted for ${cli}: ${name}`);
72
+ const src = join(seatDir, name);
73
+ const st = await lstat(src).catch(() => null);
74
+ if (!st || st.isSymbolicLink() || !st.isFile()) {
75
+ fail('onboarding-shape-unverified', `auth file missing in seatDir: ${name}`);
76
+ }
77
+ const bytes = new Uint8Array(await readFile(src));
78
+ if (cli === 'claude' && name === '.claude.json')
79
+ continue; // composed below
80
+ writes.push({ path: authCellDest(name, cellHome, configDirs), bytes, cls: 'auth' });
81
+ }
82
+ if (onboarding) {
83
+ writes.push(...await planOnboardingWrites({
84
+ cli,
85
+ onboarding,
86
+ seatDir,
87
+ cellHome,
88
+ workspaceDir,
89
+ configDirs,
90
+ claudeMcpConfig: input.claudeMcpConfig,
91
+ codexMcpServers: input.codexMcpServers,
92
+ }));
93
+ }
94
+ for (const w of writes)
95
+ await writeExclusive(roots, w.path, w.bytes);
96
+ const files = writes
97
+ .map((w) => ({
98
+ cellRelPath: receiptRelPath(w.path, cellHome, configDirs),
99
+ class: w.cls,
100
+ sha256: sha256Hex(w.bytes),
101
+ byteLength: w.bytes.length,
102
+ }))
103
+ .sort((a, b) => a.cellRelPath.localeCompare(b.cellRelPath));
104
+ return { ok: true, receipt: { files } };
105
+ }
106
+ catch (error) {
107
+ return asResult(error);
108
+ }
109
+ }
110
+ //# sourceMappingURL=seat-onboarding-stage2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-onboarding-stage2.js","sourceRoot":"","sources":["../../src/node/seat-onboarding-stage2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ import type { SeatBundleV1, SeatCli, SeatLineageTuple } from '../enrollment/seat-bundle.js';
2
+ import type { SeatLaunchGate, SeatOnboardingDestKey, SeatOnboardingFormat, SeatOnboardingStatus, SeatOnboardingV1 } from '../enrollment/seat-onboarding.js';
3
+ import type { StageCode } from './seat-stage-write.js';
4
+ export interface SeatStageInputSeat {
5
+ envelope: unknown;
6
+ seatDir: string;
7
+ }
8
+ export interface SeatStageInput {
9
+ seats: readonly SeatStageInputSeat[];
10
+ ownerScope: string;
11
+ expectedNativeCliVersions: Partial<Record<SeatCli, string>>;
12
+ }
13
+ export interface SeatStageReceiptOnboarding {
14
+ files: Array<{
15
+ destKey: SeatOnboardingDestKey;
16
+ format: SeatOnboardingFormat;
17
+ sha256: string;
18
+ byteLength: number;
19
+ }>;
20
+ nativeCliVersion: string;
21
+ capturedAt: string;
22
+ lineage: SeatLineageTuple;
23
+ reboundFrom?: SeatLineageTuple;
24
+ }
25
+ export interface SeatStageReceiptEntry {
26
+ seatRef: string;
27
+ cli: SeatCli;
28
+ authFiles: string[];
29
+ seatRecordSha256: string;
30
+ onboardingStatus: SeatOnboardingStatus;
31
+ launchGate: SeatLaunchGate;
32
+ onboarding: SeatStageReceiptOnboarding | null;
33
+ }
34
+ export interface SeatStageReceipt {
35
+ seats: SeatStageReceiptEntry[];
36
+ }
37
+ export type SeatStageResult = {
38
+ ok: true;
39
+ receipt: SeatStageReceipt;
40
+ } | {
41
+ ok: false;
42
+ code: StageCode;
43
+ detail: string;
44
+ };
45
+ export interface SeatCellConfigDirs {
46
+ claudeConfigDir: string;
47
+ codexHome: string;
48
+ xdgConfigHome: string;
49
+ }
50
+ export interface SeatCodexMcpServer {
51
+ name: string;
52
+ command: string;
53
+ args: readonly string[];
54
+ defaultToolsApprovalMode?: 'approve';
55
+ }
56
+ export interface SeatCellInput {
57
+ seatDir: string;
58
+ cellHome: string;
59
+ workspaceDir: string;
60
+ configDirs: SeatCellConfigDirs;
61
+ expectedNativeCliVersion: string;
62
+ ownerScope: string;
63
+ claudeMcpConfig?: Record<string, unknown>;
64
+ codexMcpServers?: readonly SeatCodexMcpServer[];
65
+ }
66
+ export type SeatCellFileClass = 'auth' | 'onboarding' | 'synthesized' | 'composed';
67
+ export interface SeatCellReceiptFile {
68
+ cellRelPath: string;
69
+ class: SeatCellFileClass;
70
+ sha256: string;
71
+ byteLength: number;
72
+ }
73
+ export interface SeatCellReceipt {
74
+ files: SeatCellReceiptFile[];
75
+ }
76
+ export type SeatCellResult = {
77
+ ok: true;
78
+ receipt: SeatCellReceipt;
79
+ } | {
80
+ ok: false;
81
+ code: StageCode;
82
+ detail: string;
83
+ };
84
+ export type SeatEraseResult = {
85
+ ok: true;
86
+ survivingPaths: string[];
87
+ } | {
88
+ ok: false;
89
+ code: StageCode;
90
+ detail: string;
91
+ };
92
+ /** One planned exclusive write, staged before any byte is written. */
93
+ export interface PlannedWrite {
94
+ path: string;
95
+ bytes: Uint8Array;
96
+ cls: SeatCellFileClass;
97
+ }
98
+ /** Re-validated stage-1 seat record (stage 2 reads it, never trusts it). */
99
+ export interface SeatRecordView {
100
+ bundle: SeatBundleV1;
101
+ onboarding: SeatOnboardingV1 | null;
102
+ onboardingStatus: SeatOnboardingStatus;
103
+ launchGate: SeatLaunchGate;
104
+ authFiles: string[];
105
+ }
106
+ //# sourceMappingURL=seat-onboarding-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-onboarding-types.d.ts","sourceRoot":"","sources":["../../src/node/seat-onboarding-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ //
2
+ // Shared input / receipt types for the two-stage seat materialization and
3
+ // erasure. Types only: no IO, imported by every sibling stage module and
4
+ // re-exported from the public barrel.
5
+ export {};
6
+ //# sourceMappingURL=seat-onboarding-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-onboarding-types.js","sourceRoot":"","sources":["../../src/node/seat-onboarding-types.ts"],"names":[],"mappings":"AAAA,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,sCAAsC"}
@@ -0,0 +1,25 @@
1
+ import type { SeatValidationCode } from '../enrollment/seat-bundle.js';
2
+ import { type SeatOnboardingCode } from '../enrollment/seat-onboarding.js';
3
+ export declare const SEAT_RECORD_REL_PATH: string;
4
+ export declare const DIR_MODE = 448;
5
+ export type StageCode = SeatOnboardingCode | SeatValidationCode;
6
+ export declare function fail(code: StageCode, detail: string): never;
7
+ export declare const asResult: (error: unknown) => {
8
+ ok: false;
9
+ code: StageCode;
10
+ detail: string;
11
+ };
12
+ export declare const isRecord: (value: unknown) => value is Record<string, unknown>;
13
+ export declare const utf8: (text: string) => Uint8Array;
14
+ export declare const sha256Hex: (bytes: Uint8Array) => string;
15
+ export declare const decodeBase64: (value: string) => Uint8Array;
16
+ export declare const withinRoot: (root: string, path: string) => boolean;
17
+ /** Walk every existing ancestor of `path` and refuse any symlink in the chain. */
18
+ export declare function assertCleanAncestors(path: string): Promise<void>;
19
+ /**
20
+ * Single-writer exclusive write: the resolved path must stay inside one of
21
+ * `roots`, no component of the chain may be a symlink, the target must not
22
+ * pre-exist, parents are created 0700 and the file 0600 with `wx`.
23
+ */
24
+ export declare function writeExclusive(roots: readonly string[], absPath: string, bytes: Uint8Array): Promise<void>;
25
+ //# sourceMappingURL=seat-stage-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-stage-write.d.ts","sourceRoot":"","sources":["../../src/node/seat-stage-write.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAEhG,eAAO,MAAM,oBAAoB,QAAiD,CAAC;AAEnF,eAAO,MAAM,QAAQ,MAAQ,CAAC;AAG9B,MAAM,MAAM,SAAS,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAWhE,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAE3D;AAED,eAAO,MAAM,QAAQ,UAAW,OAAO,KAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAIrF,CAAC;AAEF,eAAO,MAAM,QAAQ,UAAW,OAAO,qCAC+B,CAAC;AAEvE,eAAO,MAAM,IAAI,SAAU,MAAM,KAAG,UAA4C,CAAC;AAEjF,eAAO,MAAM,SAAS,UAAW,UAAU,KAAG,MAA0D,CAAC;AAEzG,eAAO,MAAM,YAAY,UAAW,MAAM,KAAG,UAA0D,CAAC;AAExG,eAAO,MAAM,UAAU,SAAU,MAAM,QAAQ,MAAM,KAAG,OAGvD,CAAC;AAEF,kFAAkF;AAClF,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBtE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBhH"}
@@ -0,0 +1,93 @@
1
+ //
2
+ // Shared fail-closed write primitives for the seat materialization stages.
3
+ // Internal module: not exported from the package entry points.
4
+ import { chmod, lstat, mkdir, writeFile } from 'node:fs/promises';
5
+ import { createHash } from 'node:crypto';
6
+ import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
7
+ import { SeatOnboardingError } from '../enrollment/seat-onboarding.js';
8
+ export const SEAT_RECORD_REL_PATH = join('.sentropic-seat', 'seat-record.v1.json');
9
+ export const DIR_MODE = 0o700;
10
+ const FILE_MODE = 0o600;
11
+ class StageRefusal extends Error {
12
+ code;
13
+ constructor(code, detail) {
14
+ super(detail);
15
+ this.name = 'StageRefusal';
16
+ this.code = code;
17
+ }
18
+ }
19
+ export function fail(code, detail) {
20
+ throw new StageRefusal(code, detail);
21
+ }
22
+ export const asResult = (error) => {
23
+ if (error instanceof StageRefusal)
24
+ return { ok: false, code: error.code, detail: error.message };
25
+ if (error instanceof SeatOnboardingError)
26
+ return { ok: false, code: error.code, detail: error.message };
27
+ throw error;
28
+ };
29
+ export const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
30
+ export const utf8 = (text) => new TextEncoder().encode(text);
31
+ export const sha256Hex = (bytes) => createHash('sha256').update(bytes).digest('hex');
32
+ export const decodeBase64 = (value) => new Uint8Array(Buffer.from(value, 'base64'));
33
+ export const withinRoot = (root, path) => {
34
+ const rel = relative(resolve(root), resolve(path));
35
+ return rel === '' || (rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel));
36
+ };
37
+ /** Walk every existing ancestor of `path` and refuse any symlink in the chain. */
38
+ export async function assertCleanAncestors(path) {
39
+ let current = resolve(path);
40
+ for (;;) {
41
+ let st;
42
+ try {
43
+ st = await lstat(current);
44
+ }
45
+ catch {
46
+ const parent = dirname(current);
47
+ if (parent === current)
48
+ return;
49
+ current = parent;
50
+ continue;
51
+ }
52
+ if (st.isSymbolicLink())
53
+ fail('onboarding-shape-unverified', `symlinked ancestor: ${current}`);
54
+ const parent = dirname(current);
55
+ if (parent === current)
56
+ return;
57
+ current = parent;
58
+ }
59
+ }
60
+ /**
61
+ * Single-writer exclusive write: the resolved path must stay inside one of
62
+ * `roots`, no component of the chain may be a symlink, the target must not
63
+ * pre-exist, parents are created 0700 and the file 0600 with `wx`.
64
+ */
65
+ export async function writeExclusive(roots, absPath, bytes) {
66
+ const resolved = resolve(absPath);
67
+ const root = roots.find((r) => withinRoot(r, resolved));
68
+ if (!root)
69
+ fail('onboarding-shape-unverified', `path escapes the stage root: ${absPath}`);
70
+ const rel = relative(resolve(root), resolved);
71
+ const parts = rel.split(sep);
72
+ let current = resolve(root);
73
+ for (let i = 0; i < parts.length; i += 1) {
74
+ current = join(current, parts[i]);
75
+ let st;
76
+ try {
77
+ st = await lstat(current);
78
+ }
79
+ catch {
80
+ break; // this component and everything below it do not exist yet
81
+ }
82
+ if (st.isSymbolicLink())
83
+ fail('onboarding-shape-unverified', `symlink in path: ${current}`);
84
+ if (i === parts.length - 1)
85
+ fail('onboarding-shape-unverified', `pre-existing target: ${current}`);
86
+ if (!st.isDirectory())
87
+ fail('onboarding-shape-unverified', `non-directory in path: ${current}`);
88
+ }
89
+ await mkdir(dirname(resolved), { recursive: true, mode: DIR_MODE });
90
+ await writeFile(resolved, bytes, { flag: 'wx', mode: FILE_MODE });
91
+ await chmod(resolved, FILE_MODE);
92
+ }
93
+ //# sourceMappingURL=seat-stage-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat-stage-write.js","sourceRoot":"","sources":["../../src/node/seat-stage-write.ts"],"names":[],"mappings":"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"}