@lannguyensi/harness 0.41.0 → 0.42.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 (103) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +9 -0
  3. package/dist/cli/adopt/derive.d.ts +15 -0
  4. package/dist/cli/adopt/derive.js +34 -7
  5. package/dist/cli/adopt/derive.js.map +1 -1
  6. package/dist/cli/adopt/index.d.ts +30 -0
  7. package/dist/cli/adopt/index.js +23 -3
  8. package/dist/cli/adopt/index.js.map +1 -1
  9. package/dist/cli/apply/generate-settings.d.ts +14 -1
  10. package/dist/cli/apply/generate-settings.js +7 -3
  11. package/dist/cli/apply/generate-settings.js.map +1 -1
  12. package/dist/cli/approve/stdin-report.js +2 -0
  13. package/dist/cli/approve/stdin-report.js.map +1 -1
  14. package/dist/cli/doctor/claude-mcp.d.ts +50 -0
  15. package/dist/cli/doctor/claude-mcp.js +170 -0
  16. package/dist/cli/doctor/claude-mcp.js.map +1 -0
  17. package/dist/cli/doctor/format.js +37 -0
  18. package/dist/cli/doctor/format.js.map +1 -1
  19. package/dist/cli/doctor/index.d.ts +10 -0
  20. package/dist/cli/doctor/index.js +24 -0
  21. package/dist/cli/doctor/index.js.map +1 -1
  22. package/dist/cli/doctor/npm-bin-path.js +42 -0
  23. package/dist/cli/doctor/npm-bin-path.js.map +1 -1
  24. package/dist/cli/doctor/types.d.ts +11 -0
  25. package/dist/cli/doctor/types.js.map +1 -1
  26. package/dist/cli/index.js +253 -5
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/cli/init/agent-tasks-auth.js +32 -0
  29. package/dist/cli/init/agent-tasks-auth.js.map +1 -1
  30. package/dist/cli/init/composer.js +3 -9
  31. package/dist/cli/init/composer.js.map +1 -1
  32. package/dist/cli/init/dependencies.js +21 -0
  33. package/dist/cli/init/dependencies.js.map +1 -1
  34. package/dist/cli/init/detect.d.ts +20 -3
  35. package/dist/cli/init/detect.js +34 -36
  36. package/dist/cli/init/detect.js.map +1 -1
  37. package/dist/cli/init/interactive.d.ts +33 -0
  38. package/dist/cli/init/interactive.js +399 -5
  39. package/dist/cli/init/interactive.js.map +1 -1
  40. package/dist/cli/init/profiles.d.ts +1 -1
  41. package/dist/cli/init/profiles.js +1 -1
  42. package/dist/cli/init/templates.d.ts +1 -1
  43. package/dist/cli/init/templates.js +64 -5
  44. package/dist/cli/init/templates.js.map +1 -1
  45. package/dist/cli/main.js +10 -0
  46. package/dist/cli/main.js.map +1 -1
  47. package/dist/cli/pack/hook-post-merge-gate-record.d.ts +30 -0
  48. package/dist/cli/pack/hook-post-merge-gate-record.js +153 -0
  49. package/dist/cli/pack/hook-post-merge-gate-record.js.map +1 -0
  50. package/dist/cli/pack/hook-post-merge-gate.d.ts +28 -0
  51. package/dist/cli/pack/hook-post-merge-gate.js +244 -0
  52. package/dist/cli/pack/hook-post-merge-gate.js.map +1 -0
  53. package/dist/cli/pack/hook-solution-acceptance-writeguard.js +148 -2
  54. package/dist/cli/pack/hook-solution-acceptance-writeguard.js.map +1 -1
  55. package/dist/cli/pack/understanding-report-schema-hint.js +1 -1
  56. package/dist/cli/pack/understanding-report-schema-hint.js.map +1 -1
  57. package/dist/cli/record/index.d.ts +64 -0
  58. package/dist/cli/record/index.js +211 -0
  59. package/dist/cli/record/index.js.map +1 -0
  60. package/dist/cli/session-start/index.d.ts +7 -0
  61. package/dist/cli/session-start/index.js +133 -38
  62. package/dist/cli/session-start/index.js.map +1 -1
  63. package/dist/cli/session-start/toolchain-parity.d.ts +149 -0
  64. package/dist/cli/session-start/toolchain-parity.js +618 -0
  65. package/dist/cli/session-start/toolchain-parity.js.map +1 -0
  66. package/dist/cli/uninstall/index.d.ts +73 -1
  67. package/dist/cli/uninstall/index.js +134 -2
  68. package/dist/cli/uninstall/index.js.map +1 -1
  69. package/dist/io/claude-mcp.d.ts +258 -0
  70. package/dist/io/claude-mcp.js +544 -0
  71. package/dist/io/claude-mcp.js.map +1 -0
  72. package/dist/policies/ledger-client.d.ts +34 -1
  73. package/dist/policies/ledger-client.js +21 -16
  74. package/dist/policies/ledger-client.js.map +1 -1
  75. package/dist/policy-packs/builtin/post-merge-gate-runtime.d.ts +195 -0
  76. package/dist/policy-packs/builtin/post-merge-gate-runtime.js +290 -0
  77. package/dist/policy-packs/builtin/post-merge-gate-runtime.js.map +1 -0
  78. package/dist/policy-packs/builtin/post-merge-gate.d.ts +56 -0
  79. package/dist/policy-packs/builtin/post-merge-gate.js +291 -0
  80. package/dist/policy-packs/builtin/post-merge-gate.js.map +1 -0
  81. package/dist/policy-packs/builtin/solution-acceptance-runtime.js +28 -13
  82. package/dist/policy-packs/builtin/solution-acceptance-runtime.js.map +1 -1
  83. package/dist/policy-packs/registry.d.ts +1 -1
  84. package/dist/policy-packs/registry.js +12 -0
  85. package/dist/policy-packs/registry.js.map +1 -1
  86. package/dist/runtime/git-context.d.ts +50 -0
  87. package/dist/runtime/git-context.js +108 -1
  88. package/dist/runtime/git-context.js.map +1 -1
  89. package/dist/runtime/hermetic-spawn-guard.d.ts +25 -0
  90. package/dist/runtime/hermetic-spawn-guard.js +136 -0
  91. package/dist/runtime/hermetic-spawn-guard.js.map +1 -0
  92. package/dist/runtime/ledger-writer.d.ts +27 -0
  93. package/dist/runtime/ledger-writer.js +46 -0
  94. package/dist/runtime/ledger-writer.js.map +1 -0
  95. package/dist/runtime/read-only-bash.js +118 -0
  96. package/dist/runtime/read-only-bash.js.map +1 -1
  97. package/dist/schema/index.d.ts +41 -0
  98. package/dist/schema/index.js +5 -0
  99. package/dist/schema/index.js.map +1 -1
  100. package/dist/schema/toolchain-parity.d.ts +18 -0
  101. package/dist/schema/toolchain-parity.js +35 -0
  102. package/dist/schema/toolchain-parity.js.map +1 -0
  103. package/package.json +4 -2
@@ -0,0 +1,618 @@
1
+ // `harness session-start toolchain-parity` — SessionStart hook entrypoint,
2
+ // third sibling of `harness session-start preflight` / `branch-check`.
3
+ //
4
+ // Anlass: the 2026-07-22 PATH-shim incident, where a machine ran an entire
5
+ // session unnoticed on Node 22 + understanding-gate 0.4.6 instead of the
6
+ // intended Node 26 + 0.4.9 — nothing on that machine ever compared its own
7
+ // toolchain against any other machine's. This producer closes that gap,
8
+ // purely advisorily:
9
+ //
10
+ // (a) writes a toolchain snapshot of THIS machine to
11
+ // `<machineStateDir>/<ownProfile>.json` (owner-writes-only — every
12
+ // OTHER `*.json` in that directory is read-only input, never
13
+ // touched);
14
+ // (b) compares the local LIVE toolchain state against every peer
15
+ // snapshot file already in that directory;
16
+ // (c) reports drift as stderr warning lines plus a single
17
+ // `toolchain-parity:ok` / `toolchain-parity:drift:<n>` ledger fact.
18
+ //
19
+ // Transport of the snapshot files BETWEEN machines is entirely
20
+ // agent-memory-sync's job (agent-memory PR #64, already shipped) — this
21
+ // module only ever reads/writes the local directory.
22
+ //
23
+ // SessionStart contract, same as the two siblings: `blocking:false`. Every
24
+ // failure path (not configured, mkdir/write/read failure, a broken peer
25
+ // file, a spawn timeout, a ledger-write failure) logs one line to stderr
26
+ // and exits 0. There is no "gate" this producer can leave closed — it is
27
+ // purely advisory, so degrading silently (well, LOUDLY on stderr, just
28
+ // never blocking) is always the right move.
29
+ import { execFile } from "node:child_process";
30
+ import * as fs from "node:fs";
31
+ import * as os from "node:os";
32
+ import * as path from "node:path";
33
+ import { readTopLevelMcpServers, resolveClaudeUserRegistryPath, } from "../../io/claude-mcp.js";
34
+ import { assertNoRealSpawnInTests } from "../../runtime/hermetic-spawn-guard.js";
35
+ import { resolveManifestLedgerWriter } from "../../runtime/ledger-writer.js";
36
+ import { resolveReadSessionId, } from "../../runtime/session-id.js";
37
+ import { loadManifest } from "../loader.js";
38
+ const FALLBACK_SESSION = "default";
39
+ const LEDGER_SOURCE = "harness-session-start-toolchain-parity";
40
+ const SNAPSHOT_SCHEMA_VERSION = 1;
41
+ // Individual spawn ceilings, not the expected duration: `node --version`
42
+ // and `npm ls -g --depth=0 --json` run IN PARALLEL (Promise.all in
43
+ // collectLocalSnapshot below), so the wall-time contribution of the two
44
+ // spawns together is max(nodeTimeoutMs, npmTimeoutMs), not their sum.
45
+ // Combined with two near-instant fs reads (OW-Kit version, MCP registry)
46
+ // and a ledger write, normal-case wall time targets well under 5s, matching
47
+ // the fast-path budget the `branch-check` sibling runs at (git-preflight's
48
+ // 70s budget is the outlier — it wraps a full external test-suite run,
49
+ // which this producer never does).
50
+ const DEFAULT_NODE_TIMEOUT_MS = 2_000;
51
+ const DEFAULT_NPM_GLOBALS_TIMEOUT_MS = 4_000;
52
+ async function readStdin(stream) {
53
+ return new Promise((resolve, reject) => {
54
+ let data = "";
55
+ stream.setEncoding("utf8");
56
+ stream.on("data", (chunk) => {
57
+ data += chunk;
58
+ });
59
+ stream.on("end", () => resolve(data));
60
+ stream.on("error", reject);
61
+ });
62
+ }
63
+ /** Profile names land in a filename; strip anything not filename-safe. */
64
+ function sanitizeProfileName(value) {
65
+ const cleaned = value.replace(/[^a-zA-Z0-9._-]/g, "-");
66
+ return cleaned.length > 0 ? cleaned : "profile";
67
+ }
68
+ function isRecordOfStrings(x) {
69
+ return (typeof x === "object" &&
70
+ x !== null &&
71
+ !Array.isArray(x) &&
72
+ Object.values(x).every((v) => typeof v === "string"));
73
+ }
74
+ /**
75
+ * Parse a stored snapshot JSON. Rejects (`ok:false`) only on the shapes
76
+ * that make comparison meaningless — not valid JSON, not an object,
77
+ * missing/invalid `profile` or `timestamp`. Every other field degrades
78
+ * leniently (missing/malformed -> empty/absent) rather than rejecting the
79
+ * whole file, since a peer snapshot written by a future schema version
80
+ * should still compare on the fields this version understands.
81
+ */
82
+ export function parseSnapshotJson(raw) {
83
+ let parsed;
84
+ try {
85
+ parsed = JSON.parse(raw);
86
+ }
87
+ catch (err) {
88
+ return { ok: false, reason: `not valid JSON: ${err.message}` };
89
+ }
90
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
91
+ return { ok: false, reason: "not a JSON object" };
92
+ }
93
+ const p = parsed;
94
+ if (typeof p["profile"] !== "string" || p["profile"].length === 0) {
95
+ return { ok: false, reason: "missing or invalid `profile` field" };
96
+ }
97
+ if (typeof p["timestamp"] !== "string" || Number.isNaN(Date.parse(p["timestamp"]))) {
98
+ return { ok: false, reason: "missing or invalid `timestamp` field" };
99
+ }
100
+ const snapshot = {
101
+ schemaVersion: SNAPSHOT_SCHEMA_VERSION,
102
+ profile: p["profile"],
103
+ timestamp: p["timestamp"],
104
+ npmGlobals: isRecordOfStrings(p["npmGlobals"]) ? p["npmGlobals"] : {},
105
+ mcpServers: Array.isArray(p["mcpServers"]) && p["mcpServers"].every((v) => typeof v === "string")
106
+ ? p["mcpServers"]
107
+ : [],
108
+ };
109
+ if (typeof p["node"] === "string")
110
+ snapshot.node = p["node"];
111
+ if (typeof p["nodeError"] === "string")
112
+ snapshot.nodeError = p["nodeError"];
113
+ if (typeof p["npmGlobalsError"] === "string")
114
+ snapshot.npmGlobalsError = p["npmGlobalsError"];
115
+ if (typeof p["owKitVersion"] === "string")
116
+ snapshot.owKitVersion = p["owKitVersion"];
117
+ if (typeof p["owKitError"] === "string")
118
+ snapshot.owKitError = p["owKitError"];
119
+ if (typeof p["mcpServersError"] === "string")
120
+ snapshot.mcpServersError = p["mcpServersError"];
121
+ return { ok: true, snapshot };
122
+ }
123
+ /**
124
+ * Hermetic guard (mirrors `realNpmExec` in src/cli/doctor/npm-bin-path.ts):
125
+ * asserts BEFORE touching `child_process` that we are not running under
126
+ * vitest without a test having injected `runNodeVersion`. This function has
127
+ * no try/catch around the assertion, and its only caller,
128
+ * `collectLocalSnapshot`, calls it (via the `runNodeVersion` param, defaulted
129
+ * to this function in `runSessionStartToolchainParity`) with no surrounding
130
+ * try/catch either — see src/runtime/hermetic-spawn-guard.ts for why that
131
+ * matters (a thrown `HermeticSpawnViolationError` must propagate, not be
132
+ * folded into an ordinary "collection failed" outcome).
133
+ *
134
+ * PATH-resolved deliberately: `execFile("node", ...)` does a PATH lookup for
135
+ * the literal string "node", NOT `process.execPath` — the entire point of
136
+ * this collector is capturing the PATH state of the *shell* the session
137
+ * runs in (the PATH-shim incident this task follows up on was exactly a
138
+ * PATH pointing at the wrong node), which `process.version` (the node
139
+ * running THIS harness process) would silently paper over.
140
+ */
141
+ function realNodeVersionSpawn(timeoutMs) {
142
+ assertNoRealSpawnInTests("node --version", "Inject a fake `runNodeVersion` (SessionStartToolchainParityOptions.runNodeVersion) instead of exercising the real spawn path.");
143
+ return new Promise((resolve) => {
144
+ execFile("node", ["--version"], { timeout: timeoutMs, encoding: "utf8" }, (err, stdout) => {
145
+ const text = (stdout ?? "").trim();
146
+ if (text.length > 0) {
147
+ resolve({ ok: true, version: text });
148
+ return;
149
+ }
150
+ if (err) {
151
+ const e = err;
152
+ if (e.code === "ENOENT") {
153
+ resolve({ ok: false, reason: "`node` not on PATH" });
154
+ return;
155
+ }
156
+ if (e.killed) {
157
+ resolve({ ok: false, reason: `\`node --version\` timed out after ${timeoutMs}ms` });
158
+ return;
159
+ }
160
+ resolve({ ok: false, reason: `\`node --version\` failed: ${e.message}` });
161
+ return;
162
+ }
163
+ resolve({ ok: false, reason: "`node --version` produced no output" });
164
+ });
165
+ });
166
+ }
167
+ /**
168
+ * Hermetic guard, same shape/rationale as {@link realNodeVersionSpawn} —
169
+ * see that function's doc. Tolerant of a non-zero exit the same way
170
+ * `spawnPreflight` (session-start/index.ts) is tolerant of `preflight run`'s
171
+ * exit code: `npm ls -g` can exit non-zero on an unrelated extraneous/
172
+ * invalid global entry while still emitting a perfectly parseable
173
+ * `dependencies` JSON block, so a parseable stdout wins over the exit code.
174
+ */
175
+ function realNpmGlobalsSpawn(timeoutMs) {
176
+ assertNoRealSpawnInTests("npm ls -g --depth=0 --json", "Inject a fake `runNpmGlobals` (SessionStartToolchainParityOptions.runNpmGlobals) instead of exercising the real spawn path.");
177
+ return new Promise((resolve) => {
178
+ execFile("npm", ["ls", "-g", "--depth=0", "--json"], { timeout: timeoutMs, maxBuffer: 8 * 1024 * 1024, encoding: "utf8" }, (err, stdout) => {
179
+ const text = (stdout ?? "").trim();
180
+ if (text.length > 0) {
181
+ try {
182
+ const parsed = JSON.parse(text);
183
+ const packages = {};
184
+ for (const [name, entry] of Object.entries(parsed.dependencies ?? {})) {
185
+ if (typeof entry?.version === "string")
186
+ packages[name] = entry.version;
187
+ }
188
+ resolve({ ok: true, packages });
189
+ return;
190
+ }
191
+ catch {
192
+ /* fall through to the error path */
193
+ }
194
+ }
195
+ if (err) {
196
+ const e = err;
197
+ if (e.code === "ENOENT") {
198
+ resolve({ ok: false, reason: "`npm` not on PATH" });
199
+ return;
200
+ }
201
+ if (e.killed) {
202
+ resolve({
203
+ ok: false,
204
+ reason: `\`npm ls -g --depth=0 --json\` timed out after ${timeoutMs}ms`,
205
+ });
206
+ return;
207
+ }
208
+ resolve({ ok: false, reason: `\`npm ls -g\` failed: ${e.message}` });
209
+ return;
210
+ }
211
+ resolve({ ok: false, reason: "`npm ls -g --depth=0 --json` produced no parseable JSON" });
212
+ });
213
+ });
214
+ }
215
+ /**
216
+ * Read `<workspaceRoot>/.ai/workflow/manifest.json`'s `version` field
217
+ * (the orchestrator-workflow kit's own version marker). A missing file is
218
+ * the expected common case (most repos are not OW-kit-managed) and is
219
+ * NOT an error — it degrades silently to `{}`. Malformed JSON or a
220
+ * non-string `version` field on a manifest that DOES exist is noteworthy
221
+ * (something is there but broken), so that degrades to `{ error }`.
222
+ */
223
+ function realReadOwKitVersion(workspaceRoot) {
224
+ const manifestPath = path.join(workspaceRoot, ".ai", "workflow", "manifest.json");
225
+ let raw;
226
+ try {
227
+ raw = fs.readFileSync(manifestPath, "utf8");
228
+ }
229
+ catch (err) {
230
+ const e = err;
231
+ if (e.code === "ENOENT")
232
+ return {};
233
+ return { error: `cannot read ${manifestPath}: ${e.message}` };
234
+ }
235
+ let parsed;
236
+ try {
237
+ parsed = JSON.parse(raw);
238
+ }
239
+ catch (err) {
240
+ return { error: `${manifestPath} is not valid JSON: ${err.message}` };
241
+ }
242
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
243
+ return { error: `${manifestPath} is not a JSON object` };
244
+ }
245
+ const version = parsed["version"];
246
+ if (typeof version !== "string" || version.length === 0) {
247
+ return { error: `${manifestPath} has no string \`version\` field` };
248
+ }
249
+ return { version };
250
+ }
251
+ /**
252
+ * MCP server names from Claude Code's user-scope registry — a pure FILE
253
+ * READ (never a spawn), reusing the exact primitive `harness doctor`'s
254
+ * claude-mcp check ultimately compares against
255
+ * (`resolveClaudeUserRegistryPath` + `readTopLevelMcpServers` in
256
+ * src/io/claude-mcp.ts — the same functions `adopt`/`detect` use for the
257
+ * same "read the effective registration from outside io/claude-mcp.ts"
258
+ * purpose). Deliberately NOT `claude mcp list` (a spawn): the brief calls
259
+ * for a file-read source for the NAMES here, and this is it.
260
+ */
261
+ function realReadMcpServerNames() {
262
+ const registryPath = resolveClaudeUserRegistryPath();
263
+ const { servers, error } = readTopLevelMcpServers(registryPath);
264
+ if (error !== null)
265
+ return { names: [], error };
266
+ return { names: Object.keys(servers).sort() };
267
+ }
268
+ /**
269
+ * Collect the local, LIVE toolchain snapshot. Never throws (every
270
+ * collector above degrades to `{ok:false,reason}` / `{error}` instead of
271
+ * rejecting/throwing) — a collection failure is reported both inline on
272
+ * the returned snapshot (the matching `*Error` field) AND as a `notes`
273
+ * line for the caller to log, but never stops the other collectors from
274
+ * running. node/npm run in PARALLEL (see the timeout constants' comment
275
+ * above for why).
276
+ */
277
+ async function collectLocalSnapshot(opts) {
278
+ const notes = [];
279
+ const [nodeResult, npmResult] = await Promise.all([
280
+ opts.runNodeVersion(opts.nodeTimeoutMs),
281
+ opts.runNpmGlobals(opts.npmTimeoutMs),
282
+ ]);
283
+ const owKit = opts.readOwKitVersion(opts.workspaceRoot);
284
+ const mcp = opts.readMcpServerNames();
285
+ const snapshot = {
286
+ schemaVersion: SNAPSHOT_SCHEMA_VERSION,
287
+ profile: opts.profile,
288
+ timestamp: opts.now.toISOString(),
289
+ npmGlobals: {},
290
+ mcpServers: [],
291
+ };
292
+ if (nodeResult.ok) {
293
+ snapshot.node = nodeResult.version;
294
+ }
295
+ else {
296
+ snapshot.nodeError = nodeResult.reason;
297
+ notes.push(`node --version: ${nodeResult.reason}`);
298
+ }
299
+ if (npmResult.ok) {
300
+ snapshot.npmGlobals = npmResult.packages;
301
+ }
302
+ else {
303
+ snapshot.npmGlobalsError = npmResult.reason;
304
+ notes.push(`npm ls -g: ${npmResult.reason}`);
305
+ }
306
+ if (owKit.version !== undefined)
307
+ snapshot.owKitVersion = owKit.version;
308
+ if (owKit.error !== undefined) {
309
+ snapshot.owKitError = owKit.error;
310
+ notes.push(`OW-Kit version: ${owKit.error}`);
311
+ }
312
+ if (mcp.error !== undefined) {
313
+ snapshot.mcpServersError = mcp.error;
314
+ notes.push(`MCP server names: ${mcp.error}`);
315
+ }
316
+ else {
317
+ snapshot.mcpServers = mcp.names;
318
+ }
319
+ return { snapshot, notes };
320
+ }
321
+ // ---------------------------------------------------------------------
322
+ // Snapshot write (own profile only) + peer comparison
323
+ // ---------------------------------------------------------------------
324
+ /**
325
+ * Write ONLY `<machineStateDir>/<ownFileName>` (mkdir -p first). Never
326
+ * touches any other file in the directory — the caller passes exactly
327
+ * `sanitizeProfileName(profile) + ".json"`, so there is no path this
328
+ * function could take that reaches a peer's file.
329
+ */
330
+ function writeOwnSnapshot(machineStateDir, ownFileName, snapshot) {
331
+ const filePath = path.join(machineStateDir, ownFileName);
332
+ try {
333
+ fs.writeFileSync(filePath, `${JSON.stringify(snapshot, null, 2)}\n`, "utf8");
334
+ return { ok: true, path: filePath };
335
+ }
336
+ catch (err) {
337
+ return { ok: false, reason: err.message };
338
+ }
339
+ }
340
+ /** `"just now"` / `"<n>m"` / `"<n>h"` / `"<n>d"` — coarse, human-scannable. */
341
+ export function formatSnapshotAge(ageMs) {
342
+ if (ageMs < 60_000)
343
+ return "just now";
344
+ const minutes = Math.floor(ageMs / 60_000);
345
+ if (minutes < 60)
346
+ return `${minutes}m`;
347
+ const hours = Math.floor(minutes / 60);
348
+ if (hours < 48)
349
+ return `${hours}h`;
350
+ return `${Math.floor(hours / 24)}d`;
351
+ }
352
+ /**
353
+ * Compare the local LIVE snapshot against one peer's stored snapshot.
354
+ * Node / OW-Kit drift only fires when BOTH sides collected that field
355
+ * successfully (an unavailable field reads as "unknown", not "match" or
356
+ * "drift"). The npm-globals and MCP-name comparisons additionally gate on
357
+ * the WHOLE field having collected without error on both sides — an
358
+ * `npmGlobalsError`/`mcpServersError` on either side means that side's map
359
+ * is "unknown", not "empty", and treating it as empty would fabricate a
360
+ * wall of "missing on N packages" drift instead of the real gap (which the
361
+ * caller's own note()s already surface separately, from collectLocalSnapshot's
362
+ * `notes` and the peer-unreadable path).
363
+ */
364
+ export function compareToPeer(local, peer, now) {
365
+ const drift = [];
366
+ const peerProfile = peer.profile;
367
+ if (local.node !== undefined && peer.node !== undefined && local.node !== peer.node) {
368
+ drift.push({
369
+ kind: "node",
370
+ message: `node version: local ${local.node} vs peer ${peerProfile} ${peer.node}`,
371
+ });
372
+ }
373
+ if (local.owKitVersion !== undefined &&
374
+ peer.owKitVersion !== undefined &&
375
+ local.owKitVersion !== peer.owKitVersion) {
376
+ drift.push({
377
+ kind: "ow_kit",
378
+ message: `orchestrator-workflow kit version: local ${local.owKitVersion} vs peer ${peerProfile} ${peer.owKitVersion}`,
379
+ });
380
+ }
381
+ if (local.npmGlobalsError === undefined && peer.npmGlobalsError === undefined) {
382
+ const names = [...new Set([...Object.keys(local.npmGlobals), ...Object.keys(peer.npmGlobals)])].sort();
383
+ for (const name of names) {
384
+ const lv = local.npmGlobals[name];
385
+ const pv = peer.npmGlobals[name];
386
+ if (lv !== undefined && pv !== undefined) {
387
+ if (lv !== pv) {
388
+ drift.push({
389
+ kind: "npm_package_version",
390
+ message: `npm global \`${name}\`: local ${lv} vs peer ${peerProfile} ${pv}`,
391
+ });
392
+ }
393
+ }
394
+ else if (lv !== undefined) {
395
+ drift.push({
396
+ kind: "npm_package_missing_peer",
397
+ message: `npm global \`${name}\`: local ${lv}, missing on peer ${peerProfile}`,
398
+ });
399
+ }
400
+ else if (pv !== undefined) {
401
+ drift.push({
402
+ kind: "npm_package_missing_local",
403
+ message: `npm global \`${name}\`: missing locally, peer ${peerProfile} has ${pv}`,
404
+ });
405
+ }
406
+ }
407
+ }
408
+ if (local.mcpServersError === undefined && peer.mcpServersError === undefined) {
409
+ const localSet = new Set(local.mcpServers);
410
+ const peerSet = new Set(peer.mcpServers);
411
+ const names = [...new Set([...localSet, ...peerSet])].sort();
412
+ for (const name of names) {
413
+ if (localSet.has(name) && !peerSet.has(name)) {
414
+ drift.push({
415
+ kind: "mcp_missing_peer",
416
+ message: `mcp server \`${name}\`: registered locally, missing on peer ${peerProfile}`,
417
+ });
418
+ }
419
+ else if (!localSet.has(name) && peerSet.has(name)) {
420
+ drift.push({
421
+ kind: "mcp_missing_local",
422
+ message: `mcp server \`${name}\`: missing locally, registered on peer ${peerProfile}`,
423
+ });
424
+ }
425
+ }
426
+ }
427
+ const peerTimeMs = Date.parse(peer.timestamp);
428
+ const ageMs = Number.isFinite(peerTimeMs) ? Math.max(0, now.getTime() - peerTimeMs) : 0;
429
+ return { peerProfile, ageMs, drift };
430
+ }
431
+ function defaultMachineStateDir() {
432
+ return path.join(os.homedir(), ".harness", "machine-state");
433
+ }
434
+ export async function runSessionStartToolchainParity(opts = {}) {
435
+ const stdin = opts.stdin ?? process.stdin;
436
+ const stderr = opts.stderr ?? process.stderr;
437
+ const now = opts.now ?? new Date();
438
+ const nodeTimeoutMs = opts.nodeTimeoutMs ?? DEFAULT_NODE_TIMEOUT_MS;
439
+ const npmTimeoutMs = opts.npmTimeoutMs ?? DEFAULT_NPM_GLOBALS_TIMEOUT_MS;
440
+ const note = (msg) => {
441
+ stderr.write(`harness session-start toolchain-parity: ${msg}\n`);
442
+ };
443
+ const done = (wrote, profile, peersCompared, driftCount, sessionId, sessionSource, reason) => ({
444
+ exitCode: 0,
445
+ wrote,
446
+ profile,
447
+ peersCompared,
448
+ driftCount,
449
+ sessionId,
450
+ sessionSource,
451
+ ...(reason !== undefined && { reason }),
452
+ });
453
+ let event;
454
+ try {
455
+ event = JSON.parse((await readStdin(stdin)).trim() || "{}");
456
+ }
457
+ catch (err) {
458
+ const reason = `malformed event JSON: ${err.message}`;
459
+ note(reason);
460
+ return done(false, "", 0, 0, FALLBACK_SESSION, "default", reason);
461
+ }
462
+ const cwd = typeof opts.cwd === "string" && opts.cwd.length > 0
463
+ ? opts.cwd
464
+ : typeof event.cwd === "string" && event.cwd.length > 0
465
+ ? event.cwd
466
+ : process.cwd();
467
+ // Session id resolution: same precedence chain as the two siblings, so
468
+ // all three producers stay symmetric.
469
+ const explicit = typeof opts.session === "string" && opts.session.length > 0
470
+ ? opts.session
471
+ : typeof event.session_id === "string" && event.session_id.length > 0
472
+ ? event.session_id
473
+ : undefined;
474
+ const resolveSession = opts.resolveSession ?? resolveReadSessionId;
475
+ const sessionId = resolveSession(explicit, {});
476
+ const sessionSource = typeof opts.session === "string" && opts.session.length > 0
477
+ ? "flag"
478
+ : typeof event.session_id === "string" && event.session_id.length > 0
479
+ ? "stdin"
480
+ : sessionId === FALLBACK_SESSION
481
+ ? "default"
482
+ : (typeof process.env.CLAUDE_CODE_SESSION_ID === "string" &&
483
+ process.env.CLAUDE_CODE_SESSION_ID === sessionId) ||
484
+ (typeof process.env.CLAUDE_SESSION_ID === "string" &&
485
+ process.env.CLAUDE_SESSION_ID === sessionId)
486
+ ? "env"
487
+ : "transcript";
488
+ let manifest;
489
+ if (opts.manifest) {
490
+ manifest = opts.manifest;
491
+ }
492
+ else {
493
+ try {
494
+ manifest = loadManifest(opts).manifest;
495
+ }
496
+ catch (err) {
497
+ const reason = `manifest load failed: ${err.message}`;
498
+ note(reason);
499
+ return done(false, "", 0, 0, sessionId, sessionSource, reason);
500
+ }
501
+ }
502
+ const config = manifest.toolchain_parity;
503
+ if (!config.enabled) {
504
+ const reason = "not configured (add `toolchain_parity: { enabled: true }` to harness.yaml); skipping";
505
+ note(reason);
506
+ return done(false, "", 0, 0, sessionId, sessionSource, reason);
507
+ }
508
+ const machineStateDir = config.machine_state_dir ?? defaultMachineStateDir();
509
+ const profile = config.profile ?? sanitizeProfileName(os.hostname());
510
+ const workspaceRoot = config.workspace_root ?? cwd;
511
+ const ownFileName = `${sanitizeProfileName(profile)}.json`;
512
+ try {
513
+ fs.mkdirSync(machineStateDir, { recursive: true });
514
+ }
515
+ catch (err) {
516
+ const reason = `cannot create/access machine-state dir ${machineStateDir}: ${err.message}`;
517
+ note(reason);
518
+ return done(false, profile, 0, 0, sessionId, sessionSource, reason);
519
+ }
520
+ const runNodeVersion = opts.runNodeVersion ?? realNodeVersionSpawn;
521
+ const runNpmGlobals = opts.runNpmGlobals ?? realNpmGlobalsSpawn;
522
+ const readOwKitVersion = opts.readOwKitVersion ?? realReadOwKitVersion;
523
+ const readMcpServerNames = opts.readMcpServerNames ?? realReadMcpServerNames;
524
+ const { snapshot: localSnapshot, notes } = await collectLocalSnapshot({
525
+ profile,
526
+ now,
527
+ workspaceRoot,
528
+ nodeTimeoutMs,
529
+ npmTimeoutMs,
530
+ runNodeVersion,
531
+ runNpmGlobals,
532
+ readOwKitVersion,
533
+ readMcpServerNames,
534
+ });
535
+ for (const n of notes)
536
+ note(n);
537
+ const written = writeOwnSnapshot(machineStateDir, ownFileName, localSnapshot);
538
+ if (!written.ok) {
539
+ note(`could not write own snapshot: ${written.reason}`);
540
+ }
541
+ let entries;
542
+ try {
543
+ entries = fs.readdirSync(machineStateDir);
544
+ }
545
+ catch (err) {
546
+ const reason = `cannot list machine-state dir ${machineStateDir}: ${err.message}`;
547
+ note(reason);
548
+ return done(false, profile, 0, 0, sessionId, sessionSource, reason);
549
+ }
550
+ const peerFiles = entries.filter((name) => name.endsWith(".json") && name !== ownFileName).sort();
551
+ if (peerFiles.length === 0) {
552
+ const reason = `no peer snapshots found in ${machineStateDir}; nothing to compare (normal for the first machine, or before any peer has run this companion)`;
553
+ note(reason);
554
+ return done(false, profile, 0, 0, sessionId, sessionSource, reason);
555
+ }
556
+ let peersCompared = 0;
557
+ let driftTotal = 0;
558
+ for (const fileName of peerFiles) {
559
+ const filePath = path.join(machineStateDir, fileName);
560
+ let raw;
561
+ try {
562
+ raw = fs.readFileSync(filePath, "utf8");
563
+ }
564
+ catch (err) {
565
+ note(`peer snapshot ${fileName} unreadable: ${err.message}`);
566
+ continue;
567
+ }
568
+ const parsed = parseSnapshotJson(raw);
569
+ if (!parsed.ok) {
570
+ note(`peer snapshot ${fileName} is corrupt: ${parsed.reason}`);
571
+ continue;
572
+ }
573
+ const comparison = compareToPeer(localSnapshot, parsed.snapshot, now);
574
+ peersCompared += 1;
575
+ driftTotal += comparison.drift.length;
576
+ const age = formatSnapshotAge(comparison.ageMs);
577
+ if (comparison.drift.length === 0) {
578
+ note(`ok against ${comparison.peerProfile} (snapshot age ${age})`);
579
+ }
580
+ else {
581
+ note(`drift:${comparison.drift.length} against ${comparison.peerProfile} (snapshot age ${age})`);
582
+ for (const item of comparison.drift)
583
+ note(`drift — ${item.message}`);
584
+ }
585
+ }
586
+ if (peersCompared === 0) {
587
+ const reason = `no comparable peer snapshots (all ${peerFiles.length} peer file(s) in ${machineStateDir} were unreadable/corrupt)`;
588
+ note(reason);
589
+ return done(false, profile, 0, 0, sessionId, sessionSource, reason);
590
+ }
591
+ const content = driftTotal === 0 ? "toolchain-parity:ok" : `toolchain-parity:drift:${driftTotal}`;
592
+ let writeLedger = opts.writeLedger;
593
+ if (!writeLedger) {
594
+ const resolved = resolveManifestLedgerWriter(manifest, {
595
+ ...(opts.ledgerTimeoutMs !== undefined ? { ledgerTimeoutMs: opts.ledgerTimeoutMs } : {}),
596
+ });
597
+ if (!resolved.ok) {
598
+ const reason = `${resolved.reason}; cannot record ${content}`;
599
+ note(reason);
600
+ return done(false, profile, peersCompared, driftTotal, sessionId, sessionSource, reason);
601
+ }
602
+ writeLedger = resolved.write;
603
+ }
604
+ const result = await writeLedger({ sessionId, content, source: LEDGER_SOURCE });
605
+ if (!result.ok) {
606
+ const reason = `ledger write failed: ${result.reason ?? "unknown error"}`;
607
+ note(reason);
608
+ return done(false, profile, peersCompared, driftTotal, sessionId, sessionSource, reason);
609
+ }
610
+ note(`recorded ${content} for session ${sessionId}`);
611
+ if (sessionSource === "default") {
612
+ note("WARNING: session resolved to the literal \"default\". This tag is audit-only (no gate " +
613
+ "consumes toolchain-parity: yet), but pipe SessionStart event JSON on stdin, export " +
614
+ "$CLAUDE_SESSION_ID, or pass --session <id> for manual / scripted use to keep the audit trail useful.");
615
+ }
616
+ return done(true, profile, peersCompared, driftTotal, sessionId, sessionSource);
617
+ }
618
+ //# sourceMappingURL=toolchain-parity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolchain-parity.js","sourceRoot":"","sources":["../../../src/cli/session-start/toolchain-parity.ts"],"names":[],"mappings":"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"}