@holmes-lab/holmes-kit 0.3.9 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,28 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ <!-- @implements A-SPEC-209 -->
8
+ ## [0.3.11] - 2026-09-01
9
+
10
+ ### Fixed
11
+
12
+ - **push gate: tag refs are names, not baselines** (dogfooded): pushing `--tags` sends
13
+ `refs/tags` lines whose shas are usually ancestors of the evidenced tip, and the exact-head
14
+ rule refused the release-tag push of the very version that shipped the gate. Only
15
+ `refs/heads` lines are judged now — a tag merely names an existing commit.
16
+
17
+ <!-- @implements A-SPEC-209 -->
18
+ ## [0.3.10] - 2026-09-01
19
+
20
+ ### Fixed
21
+
22
+ - **`test_run` false red on large suites** (measured on this repo, twice): every runner spawn
23
+ used `execFileSync`'s default 1MB `maxBuffer`, so a full `jest --json` for 289 suites
24
+ (>2MB) died with ENOBUFS and a GREEN suite reported `passed: false` with no failing test
25
+ named — the baseline never recorded, and the new push gate could never be satisfied. All six
26
+ runner spawns (jest/pytest/cargo/java/dotnet/go) now share a 256MB ceiling; regression pinned
27
+ with a >1MB green-output fixture (mutant-checked both ways).
28
+
7
29
  <!-- @implements A-SPEC-209 -->
8
30
  ## [0.3.9] - 2026-09-01
9
31
 
package/dist/.build-id CHANGED
@@ -1 +1 @@
1
- ab67afc-mti0dz4k
1
+ 3d14357-mti358ve
@@ -32,6 +32,9 @@ export declare function judgePush(input: PushJudgeInput): PushVerdict;
32
32
  /**
33
33
  * The pre-push stdin format: `<local ref> <local sha> <remote ref> <remote sha>` per line.
34
34
  * A deletion push (all-zero local sha) deletes a remote ref — there is nothing to vouch for.
35
+ * Only BRANCH refs (refs/heads/) are judged: the gate guards the moment a code line becomes
36
+ * someone's baseline, and a tag merely NAMES an existing commit — dogfooded 2026-09-01, pushing
37
+ * v0.3.9 (an ancestor of the evidenced tip) was refused by the exact-head rule until this line.
35
38
  */
36
39
  export declare function parsePushLines(stdinText: string): Array<{
37
40
  localSha: string;
@@ -50,6 +50,9 @@ function flatSubject(s) {
50
50
  /**
51
51
  * The pre-push stdin format: `<local ref> <local sha> <remote ref> <remote sha>` per line.
52
52
  * A deletion push (all-zero local sha) deletes a remote ref — there is nothing to vouch for.
53
+ * Only BRANCH refs (refs/heads/) are judged: the gate guards the moment a code line becomes
54
+ * someone's baseline, and a tag merely NAMES an existing commit — dogfooded 2026-09-01, pushing
55
+ * v0.3.9 (an ancestor of the evidenced tip) was refused by the exact-head rule until this line.
53
56
  */
54
57
  function parsePushLines(stdinText) {
55
58
  const out = [];
@@ -57,7 +60,9 @@ function parsePushLines(stdinText) {
57
60
  const parts = line.trim().split(/\s+/);
58
61
  if (parts.length !== 4)
59
62
  continue;
60
- const [, localSha, , remoteSha] = parts;
63
+ const [localRef, localSha, , remoteSha] = parts;
64
+ if (!localRef.startsWith('refs/heads/'))
65
+ continue; // tags/notes: names, not baselines
61
66
  if (!/^[0-9a-f]{40}$/.test(localSha))
62
67
  continue;
63
68
  if (/^0{40}$/.test(localSha))
@@ -52,6 +52,12 @@ const fs = __importStar(require("node:fs"));
52
52
  const os = __importStar(require("node:os"));
53
53
  const path = __importStar(require("node:path"));
54
54
  const python_env_1 = require("./python-env");
55
+ // Runner stdout ceiling. Measured 2026-09-01 on this repo: a full `jest --json` for 289 suites /
56
+ // 4568 tests emits >2MB, and execFileSync's DEFAULT maxBuffer (1MB) kills the child with ENOBUFS —
57
+ // so a GREEN suite reported `passed: false`, twice, with no failing test named (the baseline never
58
+ // recorded and the push gate could never be satisfied). Every runner spawn shares this ceiling:
59
+ // evidence-bearing output must never be truncated into a false red.
60
+ const RUNNER_MAX_BUFFER = 256 * 1024 * 1024;
55
61
  function planTestRun(scope) {
56
62
  if (scope.tier === 'full') {
57
63
  return { mode: 'full', testFiles: [], reason: 'full regression — run the entire suite' };
@@ -233,7 +239,7 @@ function runJest(files, mode, cwd) {
233
239
  ? [...pre, '--silent', '--json', '--runTestsByPath', '--', ...safeFiles]
234
240
  : [...pre, '--silent', '--json'];
235
241
  try {
236
- const out = (0, node_child_process_1.execFileSync)(cmd, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
242
+ const out = (0, node_child_process_1.execFileSync)(cmd, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], maxBuffer: RUNNER_MAX_BUFFER });
237
243
  return { passed: true, tail: tailOf(out), executed: parseExecutedCounts(out, cwd) };
238
244
  }
239
245
  catch (e) {
@@ -271,7 +277,7 @@ function runPytest(files, mode, cwd) {
271
277
  }
272
278
  };
273
279
  try {
274
- const out = (0, node_child_process_1.execFileSync)(python, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
280
+ const out = (0, node_child_process_1.execFileSync)(python, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], maxBuffer: RUNNER_MAX_BUFFER });
275
281
  return { passed: true, tail: tailOf(out), executed: read() };
276
282
  }
277
283
  catch (e) {
@@ -326,7 +332,7 @@ function runCargo(files, _mode, cwd, opts) {
326
332
  let out = '';
327
333
  let ok = true;
328
334
  try {
329
- out = (0, node_child_process_1.execFileSync)('cargo', ['test'], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
335
+ out = (0, node_child_process_1.execFileSync)('cargo', ['test'], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], maxBuffer: RUNNER_MAX_BUFFER });
330
336
  }
331
337
  catch (e) {
332
338
  const err = e;
@@ -419,7 +425,7 @@ function runGradle(files, _mode, cwd, opts) {
419
425
  }
420
426
  let ok = true;
421
427
  try {
422
- (0, node_child_process_1.execFileSync)(cmd, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
428
+ (0, node_child_process_1.execFileSync)(cmd, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], maxBuffer: RUNNER_MAX_BUFFER });
423
429
  }
424
430
  catch {
425
431
  ok = false;
@@ -451,7 +457,7 @@ function runDotnet(files, _mode, cwd, opts) {
451
457
  const report = path.join(dir, 'junit.xml');
452
458
  let ok = true;
453
459
  try {
454
- (0, node_child_process_1.execFileSync)('dotnet', ['test', '--logger', `junit;LogFilePath=${report}`], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
460
+ (0, node_child_process_1.execFileSync)('dotnet', ['test', '--logger', `junit;LogFilePath=${report}`], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], maxBuffer: RUNNER_MAX_BUFFER });
455
461
  }
456
462
  catch {
457
463
  ok = false;
@@ -498,7 +504,7 @@ function runGo(files, mode, cwd, opts) {
498
504
  const runDir = (dirArg, creditFiles) => {
499
505
  let out = '';
500
506
  try {
501
- out = (0, node_child_process_1.execFileSync)('go', ['test', '-json', dirArg], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
507
+ out = (0, node_child_process_1.execFileSync)('go', ['test', '-json', dirArg], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], maxBuffer: RUNNER_MAX_BUFFER });
502
508
  }
503
509
  catch (e) {
504
510
  const err = e;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "//": "@implements A-SPEC-209",
3
3
  "name": "@holmes-lab/holmes-kit",
4
- "version": "0.3.9",
4
+ "version": "0.3.11",
5
5
  "description": "Holmes-Kit — deterministic Agentic Software Engineering (ASE) harness with causal traceability (spec chain + D-CPG + RTM + phase guardrail)",
6
6
  "main": "dist/holmes/mcp/server.js",
7
7
  "types": "dist/holmes/mcp/server.d.ts",