@event4u/agent-config 9.36.0 → 10.1.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 (89) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +117 -2
  3. package/agents/templates/.ai-council.yml.example +31 -51
  4. package/dist/agent-src/commands/analyze/conformance.md +15 -4
  5. package/dist/agent-src/rules/session-canary.md +28 -0
  6. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +17 -0
  7. package/dist/agent-src/skills/adr-create/SKILL.md +5 -0
  8. package/dist/agent-src/skills/check-refs/SKILL.md +5 -0
  9. package/dist/agent-src/skills/lint-skills/SKILL.md +5 -0
  10. package/dist/agent-src/skills/md-language-check/SKILL.md +5 -0
  11. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  12. package/dist/cli-delegate/{chunk-SFGARMAB.js → chunk-2H5SE7DU.js} +24 -4
  13. package/dist/cli-delegate/{chunk-U7CMAIOC.js → chunk-3JUTT26I.js} +1 -1
  14. package/dist/cli-delegate/{chunk-JP53LNVT.js → chunk-HJSKTMIF.js} +6 -14
  15. package/dist/cli-delegate/{chunk-QEEB4LHO.js → chunk-LRXJK6GN.js} +1 -1
  16. package/dist/cli-delegate/{chunk-NR7HSN3P.js → chunk-NX5AXSLD.js} +3 -3
  17. package/dist/cli-delegate/{chunk-AG47LAGQ.js → chunk-TVGXH7VA.js} +1 -1
  18. package/dist/cli-delegate/{chunk-55RI5UXK.js → chunk-XT2YTJCZ.js} +22 -18
  19. package/dist/cli-delegate/{chunk-JEJABGKB.js → chunk-XTC5ARB6.js} +16 -12
  20. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  21. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  22. package/dist/cli-delegate/cmd_conformance.js +1037 -196
  23. package/dist/cli-delegate/cmd_doctor.js +3 -3
  24. package/dist/cli-delegate/cmd_explain.js +2 -2
  25. package/dist/cli-delegate/cmd_export.js +4 -4
  26. package/dist/cli-delegate/cmd_handoff.js +3 -3
  27. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  28. package/dist/cli-delegate/cmd_migrate.js +2 -2
  29. package/dist/cli-delegate/cmd_packs_active.js +2 -2
  30. package/dist/cli-delegate/cmd_prune.js +4 -4
  31. package/dist/cli-delegate/cmd_route_audit.js +2 -2
  32. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  33. package/dist/cli-delegate/cmd_session_recycle.js +1 -1
  34. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  35. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  36. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  37. package/dist/cli-delegate/cmd_sync.js +4 -4
  38. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  39. package/dist/cli-delegate/cmd_update.js +1 -1
  40. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  41. package/dist/cli-delegate/cmd_validate.js +4 -4
  42. package/dist/cli-delegate/cmd_versions.js +1 -1
  43. package/dist/discovery/deprecation-report.md +1 -1
  44. package/dist/discovery/discovery-manifest.json +8 -8
  45. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  46. package/dist/discovery/discovery-manifest.summary.md +1 -1
  47. package/dist/discovery/dormancy-report.md +1 -1
  48. package/dist/discovery/orphan-report.md +1 -1
  49. package/dist/discovery/packs.json +2 -2
  50. package/dist/discovery/trust-report.md +1 -1
  51. package/dist/discovery/workspaces.json +2 -2
  52. package/dist/hooks/dispatch.js +125 -89
  53. package/dist/install/install.mjs +22 -26
  54. package/dist/mcp/registry-manifest.json +1 -1
  55. package/dist/mcp/server.json +2 -2
  56. package/dist/mcp/server.mjs +1579 -616
  57. package/dist/scripts/_lib/agent_settings.js +39 -25
  58. package/dist/scripts/_lib/agent_settings.js.map +1 -1
  59. package/dist/scripts/condense.js +15 -2
  60. package/dist/scripts/condense.js.map +1 -1
  61. package/dist/server/routes/wizard.js +23 -3
  62. package/dist/server/routes/wizard.js.map +1 -1
  63. package/dist/server/schemas/settings.js +6 -6
  64. package/dist/server/schemas/settings.js.map +1 -1
  65. package/docs/contracts/settings-classes.md +14 -9
  66. package/package.json +1 -1
  67. package/src/agent-src/scripts/archive_completed_roadmaps.ts +17 -0
  68. package/src/config/agent-settings.template.yml +6 -36
  69. package/src/config/ci-local-parity.yml +44 -0
  70. package/src/scripts/_lib/agent_settings.ts +39 -25
  71. package/src/scripts/_lib/environment_detector.ts +52 -1
  72. package/src/scripts/_lib/untrusted_content.test.ts +175 -0
  73. package/src/scripts/_lib/untrusted_content.ts +184 -0
  74. package/src/scripts/ai_council/config.ts +62 -24
  75. package/src/scripts/before_complete_hook.ts +39 -0
  76. package/src/scripts/check_bridge_derivation.ts +89 -3
  77. package/src/scripts/check_ci_local_parity.ts +74 -0
  78. package/src/scripts/check_references.ts +15 -1
  79. package/src/scripts/condense.ts +16 -2
  80. package/src/scripts/conformance_scan.ts +200 -9
  81. package/src/scripts/council_cli.ts +95 -3
  82. package/src/scripts/hook_manifest.yaml +12 -6
  83. package/src/scripts/hooks/block_no_verify.ts +82 -9
  84. package/src/scripts/hooks/turn_end_gate_hook.ts +138 -105
  85. package/src/scripts/probe_promissory_closing.ts +180 -0
  86. package/src/scripts/probe_session_canary.ts +180 -0
  87. package/src/scripts/schemas/skill.schema.json +42 -0
  88. package/src/scripts/skill_linter.ts +57 -2
  89. package/src/server/schemas/settings.ts +6 -14
@@ -591,15 +591,15 @@ function _readDottedSettingsPath(root, dotted) {
591
591
  return node;
592
592
  }
593
593
  function _warn_removed_always_on_keys(merged) {
594
- for (const key of REMOVED_ALWAYS_ON_KEYS) {
595
- if (_warnedRemovedAlwaysOnKeys.has(key)) {
594
+ for (const [key, reason] of REMOVED_KEYS) {
595
+ if (_warnedRemovedKeys.has(key)) {
596
596
  continue;
597
597
  }
598
598
  if (_readDottedSettingsPath(merged, key) === void 0) {
599
599
  continue;
600
600
  }
601
- _warnedRemovedAlwaysOnKeys.add(key);
602
- process.stderr.write(`${key} was removed (always-on orchestration); ignored.
601
+ _warnedRemovedKeys.add(key);
602
+ process.stderr.write(`${key} was removed (${reason}); ignored.
603
603
  `);
604
604
  }
605
605
  }
@@ -877,7 +877,7 @@ function _relative_to(child, root) {
877
877
  function _posix_join(a, b) {
878
878
  return `${a.split(path3.sep).join("/")}/${b}`;
879
879
  }
880
- var _require, Logger, logger, DEFAULT_PROJECT_FILE, LOCAL_PROJECT_FILE, LOCAL_PROJECT_SUBDIR, DEFAULT_TEAM_FILE, USER_GLOBAL_FILENAME, USER_GLOBAL_CANONICAL_RELATIVE, MERGEABLE_KEYS, TEMPLATE_RELATIVE, _PACKAGE_ROOT, _template_defaults_cache, MODULES_DEFAULTS, ANCHOR_AGENT_SETTINGS, ANCHOR_AGENTS_DIR, ANCHOR_GIT, _AGENTS_DIR_MARKERS, _LEGACY_ANCHOR_ENV, ORIGIN_ROOT_FLAG, ORIGIN_EXPLICIT, ORIGIN_ENV, ORIGIN_CWD_FALLBACK, PROJECT_ROOT_ENV, ROOT_OVERRIDE_ENV, ProjectRootError, REMOVED_ALWAYS_ON_KEYS, _warnedRemovedAlwaysOnKeys;
880
+ var _require, Logger, logger, DEFAULT_PROJECT_FILE, LOCAL_PROJECT_FILE, LOCAL_PROJECT_SUBDIR, DEFAULT_TEAM_FILE, USER_GLOBAL_FILENAME, USER_GLOBAL_CANONICAL_RELATIVE, MERGEABLE_KEYS, TEMPLATE_RELATIVE, _PACKAGE_ROOT, _template_defaults_cache, MODULES_DEFAULTS, ANCHOR_AGENT_SETTINGS, ANCHOR_AGENTS_DIR, ANCHOR_GIT, _AGENTS_DIR_MARKERS, _LEGACY_ANCHOR_ENV, ORIGIN_ROOT_FLAG, ORIGIN_EXPLICIT, ORIGIN_ENV, ORIGIN_CWD_FALLBACK, PROJECT_ROOT_ENV, ROOT_OVERRIDE_ENV, ProjectRootError, REMOVED_KEYS, _warnedRemovedKeys;
881
881
  var init_agent_settings = __esm({
882
882
  "src/scripts/_lib/agent_settings.ts"() {
883
883
  "use strict";
@@ -970,14 +970,18 @@ var init_agent_settings = __esm({
970
970
  this.name = "ProjectRootError";
971
971
  }
972
972
  };
973
- REMOVED_ALWAYS_ON_KEYS = [
974
- "subagents.enabled",
975
- "subagents.auto",
976
- "subagents.host_capabilities",
977
- "subagents.budget_routing",
978
- "ai_team.enabled"
979
- ];
980
- _warnedRemovedAlwaysOnKeys = /* @__PURE__ */ new Set();
973
+ REMOVED_KEYS = /* @__PURE__ */ new Map([
974
+ ["subagents.enabled", "always-on orchestration"],
975
+ ["subagents.auto", "always-on orchestration"],
976
+ ["subagents.host_capabilities", "always-on orchestration"],
977
+ ["subagents.budget_routing", "always-on orchestration"],
978
+ ["ai_team.enabled", "always-on orchestration"],
979
+ ["hooks.turn_end_gate.enabled", "the turn-end gate is always armed"],
980
+ ["hooks.turn_end_gate.promissory", "the turn-end gate is always armed"],
981
+ ["hooks.turn_end_gate.language", "the turn-end gate is always armed"],
982
+ ["hooks.turn_end_gate.verification", "the turn-end gate is always armed"]
983
+ ]);
984
+ _warnedRemovedKeys = /* @__PURE__ */ new Set();
981
985
  }
982
986
  });
983
987
 
@@ -1831,17 +1835,17 @@ var require_visit = __commonJS({
1831
1835
  visit.BREAK = BREAK;
1832
1836
  visit.SKIP = SKIP;
1833
1837
  visit.REMOVE = REMOVE;
1834
- function visit_(key, node, visitor, path71) {
1835
- const ctrl = callVisitor(key, node, visitor, path71);
1838
+ function visit_(key, node, visitor, path73) {
1839
+ const ctrl = callVisitor(key, node, visitor, path73);
1836
1840
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
1837
- replaceNode(key, path71, ctrl);
1838
- return visit_(key, ctrl, visitor, path71);
1841
+ replaceNode(key, path73, ctrl);
1842
+ return visit_(key, ctrl, visitor, path73);
1839
1843
  }
1840
1844
  if (typeof ctrl !== "symbol") {
1841
1845
  if (identity.isCollection(node)) {
1842
- path71 = Object.freeze(path71.concat(node));
1846
+ path73 = Object.freeze(path73.concat(node));
1843
1847
  for (let i = 0; i < node.items.length; ++i) {
1844
- const ci = visit_(i, node.items[i], visitor, path71);
1848
+ const ci = visit_(i, node.items[i], visitor, path73);
1845
1849
  if (typeof ci === "number")
1846
1850
  i = ci - 1;
1847
1851
  else if (ci === BREAK)
@@ -1852,13 +1856,13 @@ var require_visit = __commonJS({
1852
1856
  }
1853
1857
  }
1854
1858
  } else if (identity.isPair(node)) {
1855
- path71 = Object.freeze(path71.concat(node));
1856
- const ck = visit_("key", node.key, visitor, path71);
1859
+ path73 = Object.freeze(path73.concat(node));
1860
+ const ck = visit_("key", node.key, visitor, path73);
1857
1861
  if (ck === BREAK)
1858
1862
  return BREAK;
1859
1863
  else if (ck === REMOVE)
1860
1864
  node.key = null;
1861
- const cv = visit_("value", node.value, visitor, path71);
1865
+ const cv = visit_("value", node.value, visitor, path73);
1862
1866
  if (cv === BREAK)
1863
1867
  return BREAK;
1864
1868
  else if (cv === REMOVE)
@@ -1879,17 +1883,17 @@ var require_visit = __commonJS({
1879
1883
  visitAsync.BREAK = BREAK;
1880
1884
  visitAsync.SKIP = SKIP;
1881
1885
  visitAsync.REMOVE = REMOVE;
1882
- async function visitAsync_(key, node, visitor, path71) {
1883
- const ctrl = await callVisitor(key, node, visitor, path71);
1886
+ async function visitAsync_(key, node, visitor, path73) {
1887
+ const ctrl = await callVisitor(key, node, visitor, path73);
1884
1888
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
1885
- replaceNode(key, path71, ctrl);
1886
- return visitAsync_(key, ctrl, visitor, path71);
1889
+ replaceNode(key, path73, ctrl);
1890
+ return visitAsync_(key, ctrl, visitor, path73);
1887
1891
  }
1888
1892
  if (typeof ctrl !== "symbol") {
1889
1893
  if (identity.isCollection(node)) {
1890
- path71 = Object.freeze(path71.concat(node));
1894
+ path73 = Object.freeze(path73.concat(node));
1891
1895
  for (let i = 0; i < node.items.length; ++i) {
1892
- const ci = await visitAsync_(i, node.items[i], visitor, path71);
1896
+ const ci = await visitAsync_(i, node.items[i], visitor, path73);
1893
1897
  if (typeof ci === "number")
1894
1898
  i = ci - 1;
1895
1899
  else if (ci === BREAK)
@@ -1900,13 +1904,13 @@ var require_visit = __commonJS({
1900
1904
  }
1901
1905
  }
1902
1906
  } else if (identity.isPair(node)) {
1903
- path71 = Object.freeze(path71.concat(node));
1904
- const ck = await visitAsync_("key", node.key, visitor, path71);
1907
+ path73 = Object.freeze(path73.concat(node));
1908
+ const ck = await visitAsync_("key", node.key, visitor, path73);
1905
1909
  if (ck === BREAK)
1906
1910
  return BREAK;
1907
1911
  else if (ck === REMOVE)
1908
1912
  node.key = null;
1909
- const cv = await visitAsync_("value", node.value, visitor, path71);
1913
+ const cv = await visitAsync_("value", node.value, visitor, path73);
1910
1914
  if (cv === BREAK)
1911
1915
  return BREAK;
1912
1916
  else if (cv === REMOVE)
@@ -1933,23 +1937,23 @@ var require_visit = __commonJS({
1933
1937
  }
1934
1938
  return visitor;
1935
1939
  }
1936
- function callVisitor(key, node, visitor, path71) {
1940
+ function callVisitor(key, node, visitor, path73) {
1937
1941
  if (typeof visitor === "function")
1938
- return visitor(key, node, path71);
1942
+ return visitor(key, node, path73);
1939
1943
  if (identity.isMap(node))
1940
- return visitor.Map?.(key, node, path71);
1944
+ return visitor.Map?.(key, node, path73);
1941
1945
  if (identity.isSeq(node))
1942
- return visitor.Seq?.(key, node, path71);
1946
+ return visitor.Seq?.(key, node, path73);
1943
1947
  if (identity.isPair(node))
1944
- return visitor.Pair?.(key, node, path71);
1948
+ return visitor.Pair?.(key, node, path73);
1945
1949
  if (identity.isScalar(node))
1946
- return visitor.Scalar?.(key, node, path71);
1950
+ return visitor.Scalar?.(key, node, path73);
1947
1951
  if (identity.isAlias(node))
1948
- return visitor.Alias?.(key, node, path71);
1952
+ return visitor.Alias?.(key, node, path73);
1949
1953
  return void 0;
1950
1954
  }
1951
- function replaceNode(key, path71, node) {
1952
- const parent = path71[path71.length - 1];
1955
+ function replaceNode(key, path73, node) {
1956
+ const parent = path73[path73.length - 1];
1953
1957
  if (identity.isCollection(parent)) {
1954
1958
  parent.items[key] = node;
1955
1959
  } else if (identity.isPair(parent)) {
@@ -2559,10 +2563,10 @@ var require_Collection = __commonJS({
2559
2563
  var createNode = require_createNode();
2560
2564
  var identity = require_identity();
2561
2565
  var Node = require_Node();
2562
- function collectionFromPath(schema, path71, value) {
2566
+ function collectionFromPath(schema, path73, value) {
2563
2567
  let v = value;
2564
- for (let i = path71.length - 1; i >= 0; --i) {
2565
- const k = path71[i];
2568
+ for (let i = path73.length - 1; i >= 0; --i) {
2569
+ const k = path73[i];
2566
2570
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
2567
2571
  const a = [];
2568
2572
  a[k] = v;
@@ -2581,7 +2585,7 @@ var require_Collection = __commonJS({
2581
2585
  sourceObjects: /* @__PURE__ */ new Map()
2582
2586
  });
2583
2587
  }
2584
- var isEmptyPath = (path71) => path71 == null || typeof path71 === "object" && !!path71[Symbol.iterator]().next().done;
2588
+ var isEmptyPath = (path73) => path73 == null || typeof path73 === "object" && !!path73[Symbol.iterator]().next().done;
2585
2589
  var Collection = class extends Node.NodeBase {
2586
2590
  constructor(type, schema) {
2587
2591
  super(type);
@@ -2611,11 +2615,11 @@ var require_Collection = __commonJS({
2611
2615
  * be a Pair instance or a `{ key, value }` object, which may not have a key
2612
2616
  * that already exists in the map.
2613
2617
  */
2614
- addIn(path71, value) {
2615
- if (isEmptyPath(path71))
2618
+ addIn(path73, value) {
2619
+ if (isEmptyPath(path73))
2616
2620
  this.add(value);
2617
2621
  else {
2618
- const [key, ...rest] = path71;
2622
+ const [key, ...rest] = path73;
2619
2623
  const node = this.get(key, true);
2620
2624
  if (identity.isCollection(node))
2621
2625
  node.addIn(rest, value);
@@ -2629,8 +2633,8 @@ var require_Collection = __commonJS({
2629
2633
  * Removes a value from the collection.
2630
2634
  * @returns `true` if the item was found and removed.
2631
2635
  */
2632
- deleteIn(path71) {
2633
- const [key, ...rest] = path71;
2636
+ deleteIn(path73) {
2637
+ const [key, ...rest] = path73;
2634
2638
  if (rest.length === 0)
2635
2639
  return this.delete(key);
2636
2640
  const node = this.get(key, true);
@@ -2644,8 +2648,8 @@ var require_Collection = __commonJS({
2644
2648
  * scalar values from their surrounding node; to disable set `keepScalar` to
2645
2649
  * `true` (collections are always returned intact).
2646
2650
  */
2647
- getIn(path71, keepScalar) {
2648
- const [key, ...rest] = path71;
2651
+ getIn(path73, keepScalar) {
2652
+ const [key, ...rest] = path73;
2649
2653
  const node = this.get(key, true);
2650
2654
  if (rest.length === 0)
2651
2655
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -2663,8 +2667,8 @@ var require_Collection = __commonJS({
2663
2667
  /**
2664
2668
  * Checks if the collection includes a value with the key `key`.
2665
2669
  */
2666
- hasIn(path71) {
2667
- const [key, ...rest] = path71;
2670
+ hasIn(path73) {
2671
+ const [key, ...rest] = path73;
2668
2672
  if (rest.length === 0)
2669
2673
  return this.has(key);
2670
2674
  const node = this.get(key, true);
@@ -2674,8 +2678,8 @@ var require_Collection = __commonJS({
2674
2678
  * Sets a value in this collection. For `!!set`, `value` needs to be a
2675
2679
  * boolean to add/remove the item from the set.
2676
2680
  */
2677
- setIn(path71, value) {
2678
- const [key, ...rest] = path71;
2681
+ setIn(path73, value) {
2682
+ const [key, ...rest] = path73;
2679
2683
  if (rest.length === 0) {
2680
2684
  this.set(key, value);
2681
2685
  } else {
@@ -2699,13 +2703,13 @@ var require_Collection = __commonJS({
2699
2703
  var require_stringifyComment = __commonJS({
2700
2704
  "node_modules/yaml/dist/stringify/stringifyComment.js"(exports) {
2701
2705
  "use strict";
2702
- var stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#");
2706
+ var stringifyComment = (str3) => str3.replace(/^(?!$)(?: $)?/gm, "#");
2703
2707
  function indentComment(comment, indent) {
2704
2708
  if (/^\n+$/.test(comment))
2705
2709
  return comment.substring(1);
2706
2710
  return indent ? comment.replace(/^(?! *$)/gm, indent) : comment;
2707
2711
  }
2708
- var lineComment = (str, indent, comment) => str.endsWith("\n") ? indentComment(comment, indent) : comment.includes("\n") ? "\n" + indentComment(comment, indent) : (str.endsWith(" ") ? "" : " ") + comment;
2712
+ var lineComment = (str3, indent, comment) => str3.endsWith("\n") ? indentComment(comment, indent) : comment.includes("\n") ? "\n" + indentComment(comment, indent) : (str3.endsWith(" ") ? "" : " ") + comment;
2709
2713
  exports.indentComment = indentComment;
2710
2714
  exports.lineComment = lineComment;
2711
2715
  exports.stringifyComment = stringifyComment;
@@ -2859,16 +2863,16 @@ var require_stringifyString = __commonJS({
2859
2863
  lineWidth: ctx.options.lineWidth,
2860
2864
  minContentWidth: ctx.options.minContentWidth
2861
2865
  });
2862
- var containsDocumentMarker = (str) => /^(%|---|\.\.\.)/m.test(str);
2863
- function lineLengthOverLimit(str, lineWidth, indentLength) {
2866
+ var containsDocumentMarker = (str3) => /^(%|---|\.\.\.)/m.test(str3);
2867
+ function lineLengthOverLimit(str3, lineWidth, indentLength) {
2864
2868
  if (!lineWidth || lineWidth < 0)
2865
2869
  return false;
2866
2870
  const limit = lineWidth - indentLength;
2867
- const strLen = str.length;
2871
+ const strLen = str3.length;
2868
2872
  if (strLen <= limit)
2869
2873
  return false;
2870
2874
  for (let i = 0, start = 0; i < strLen; ++i) {
2871
- if (str[i] === "\n") {
2875
+ if (str3[i] === "\n") {
2872
2876
  if (i - start > limit)
2873
2877
  return true;
2874
2878
  start = i + 1;
@@ -2885,11 +2889,11 @@ var require_stringifyString = __commonJS({
2885
2889
  const { implicitKey } = ctx;
2886
2890
  const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength;
2887
2891
  const indent = ctx.indent || (containsDocumentMarker(value) ? " " : "");
2888
- let str = "";
2892
+ let str3 = "";
2889
2893
  let start = 0;
2890
2894
  for (let i = 0, ch = json[i]; ch; ch = json[++i]) {
2891
2895
  if (ch === " " && json[i + 1] === "\\" && json[i + 2] === "n") {
2892
- str += json.slice(start, i) + "\\ ";
2896
+ str3 += json.slice(start, i) + "\\ ";
2893
2897
  i += 1;
2894
2898
  start = i;
2895
2899
  ch = "\\";
@@ -2898,38 +2902,38 @@ var require_stringifyString = __commonJS({
2898
2902
  switch (json[i + 1]) {
2899
2903
  case "u":
2900
2904
  {
2901
- str += json.slice(start, i);
2905
+ str3 += json.slice(start, i);
2902
2906
  const code = json.substr(i + 2, 4);
2903
2907
  switch (code) {
2904
2908
  case "0000":
2905
- str += "\\0";
2909
+ str3 += "\\0";
2906
2910
  break;
2907
2911
  case "0007":
2908
- str += "\\a";
2912
+ str3 += "\\a";
2909
2913
  break;
2910
2914
  case "000b":
2911
- str += "\\v";
2915
+ str3 += "\\v";
2912
2916
  break;
2913
2917
  case "001b":
2914
- str += "\\e";
2918
+ str3 += "\\e";
2915
2919
  break;
2916
2920
  case "0085":
2917
- str += "\\N";
2921
+ str3 += "\\N";
2918
2922
  break;
2919
2923
  case "00a0":
2920
- str += "\\_";
2924
+ str3 += "\\_";
2921
2925
  break;
2922
2926
  case "2028":
2923
- str += "\\L";
2927
+ str3 += "\\L";
2924
2928
  break;
2925
2929
  case "2029":
2926
- str += "\\P";
2930
+ str3 += "\\P";
2927
2931
  break;
2928
2932
  default:
2929
2933
  if (code.substr(0, 2) === "00")
2930
- str += "\\x" + code.substr(2);
2934
+ str3 += "\\x" + code.substr(2);
2931
2935
  else
2932
- str += json.substr(i, 6);
2936
+ str3 += json.substr(i, 6);
2933
2937
  }
2934
2938
  i += 5;
2935
2939
  start = i + 1;
@@ -2939,14 +2943,14 @@ var require_stringifyString = __commonJS({
2939
2943
  if (implicitKey || json[i + 2] === '"' || json.length < minMultiLineLength) {
2940
2944
  i += 1;
2941
2945
  } else {
2942
- str += json.slice(start, i) + "\n\n";
2946
+ str3 += json.slice(start, i) + "\n\n";
2943
2947
  while (json[i + 2] === "\\" && json[i + 3] === "n" && json[i + 4] !== '"') {
2944
- str += "\n";
2948
+ str3 += "\n";
2945
2949
  i += 2;
2946
2950
  }
2947
- str += indent;
2951
+ str3 += indent;
2948
2952
  if (json[i + 2] === " ")
2949
- str += "\\";
2953
+ str3 += "\\";
2950
2954
  i += 1;
2951
2955
  start = i + 1;
2952
2956
  }
@@ -2955,8 +2959,8 @@ var require_stringifyString = __commonJS({
2955
2959
  i += 1;
2956
2960
  }
2957
2961
  }
2958
- str = start ? str + json.slice(start) : json;
2959
- return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));
2962
+ str3 = start ? str3 + json.slice(start) : json;
2963
+ return implicitKey ? str3 : foldFlowLines.foldFlowLines(str3, indent, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));
2960
2964
  }
2961
2965
  function singleQuotedString(value, ctx) {
2962
2966
  if (ctx.options.singleQuote === false || ctx.implicitKey && value.includes("\n") || /[ \t]\n|\n[ \t]/.test(value))
@@ -3084,15 +3088,15 @@ ${indent}${start}${value}${end}`;
3084
3088
  return quotedString(value, ctx);
3085
3089
  }
3086
3090
  }
3087
- const str = value.replace(/\n+/g, `$&
3091
+ const str3 = value.replace(/\n+/g, `$&
3088
3092
  ${indent}`);
3089
3093
  if (actualString) {
3090
- const test = (tag) => tag.default && tag.tag !== "tag:yaml.org,2002:str" && tag.test?.test(str);
3094
+ const test = (tag) => tag.default && tag.tag !== "tag:yaml.org,2002:str" && tag.test?.test(str3);
3091
3095
  const { compat, tags } = ctx.doc.schema;
3092
3096
  if (tags.some(test) || compat?.some(test))
3093
3097
  return quotedString(value, ctx);
3094
3098
  }
3095
- return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
3099
+ return implicitKey ? str3 : foldFlowLines.foldFlowLines(str3, indent, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
3096
3100
  }
3097
3101
  function stringifyString(item, ctx, onComment, onChompKeep) {
3098
3102
  const { implicitKey, inFlow } = ctx;
@@ -3244,11 +3248,11 @@ var require_stringify = __commonJS({
3244
3248
  const props = stringifyProps(node, tagObj, ctx);
3245
3249
  if (props.length > 0)
3246
3250
  ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;
3247
- const str = typeof tagObj.stringify === "function" ? tagObj.stringify(node, ctx, onComment, onChompKeep) : identity.isScalar(node) ? stringifyString.stringifyString(node, ctx, onComment, onChompKeep) : node.toString(ctx, onComment, onChompKeep);
3251
+ const str3 = typeof tagObj.stringify === "function" ? tagObj.stringify(node, ctx, onComment, onChompKeep) : identity.isScalar(node) ? stringifyString.stringifyString(node, ctx, onComment, onChompKeep) : node.toString(ctx, onComment, onChompKeep);
3248
3252
  if (!props)
3249
- return str;
3250
- return identity.isScalar(node) || str[0] === "{" || str[0] === "[" ? `${props} ${str}` : `${props}
3251
- ${ctx.indent}${str}`;
3253
+ return str3;
3254
+ return identity.isScalar(node) || str3[0] === "{" || str3[0] === "[" ? `${props} ${str3}` : `${props}
3255
+ ${ctx.indent}${str3}`;
3252
3256
  }
3253
3257
  exports.createStringifyContext = createStringifyContext;
3254
3258
  exports.stringify = stringify;
@@ -3283,8 +3287,8 @@ var require_stringifyPair = __commonJS({
3283
3287
  });
3284
3288
  let keyCommentDone = false;
3285
3289
  let chompKeep = false;
3286
- let str = stringify.stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true);
3287
- if (!explicitKey && !ctx.inFlow && str.length > 1024) {
3290
+ let str3 = stringify.stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true);
3291
+ if (!explicitKey && !ctx.inFlow && str3.length > 1024) {
3288
3292
  if (simpleKeys)
3289
3293
  throw new Error("With simple keys, single line scalar must not span more than 1024 characters");
3290
3294
  explicitKey = true;
@@ -3293,27 +3297,27 @@ var require_stringifyPair = __commonJS({
3293
3297
  if (allNullValues || value == null) {
3294
3298
  if (keyCommentDone && onComment)
3295
3299
  onComment();
3296
- return str === "" ? "?" : explicitKey ? `? ${str}` : str;
3300
+ return str3 === "" ? "?" : explicitKey ? `? ${str3}` : str3;
3297
3301
  }
3298
3302
  } else if (allNullValues && !simpleKeys || value == null && explicitKey) {
3299
- str = `? ${str}`;
3303
+ str3 = `? ${str3}`;
3300
3304
  if (keyComment && !keyCommentDone) {
3301
- str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
3305
+ str3 += stringifyComment.lineComment(str3, ctx.indent, commentString(keyComment));
3302
3306
  } else if (chompKeep && onChompKeep)
3303
3307
  onChompKeep();
3304
- return str;
3308
+ return str3;
3305
3309
  }
3306
3310
  if (keyCommentDone)
3307
3311
  keyComment = null;
3308
3312
  if (explicitKey) {
3309
3313
  if (keyComment)
3310
- str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
3311
- str = `? ${str}
3314
+ str3 += stringifyComment.lineComment(str3, ctx.indent, commentString(keyComment));
3315
+ str3 = `? ${str3}
3312
3316
  ${indent}:`;
3313
3317
  } else {
3314
- str = `${str}:`;
3318
+ str3 = `${str3}:`;
3315
3319
  if (keyComment)
3316
- str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
3320
+ str3 += stringifyComment.lineComment(str3, ctx.indent, commentString(keyComment));
3317
3321
  }
3318
3322
  let vsb, vcb, valueComment;
3319
3323
  if (identity.isNode(value)) {
@@ -3329,7 +3333,7 @@ ${indent}:`;
3329
3333
  }
3330
3334
  ctx.implicitKey = false;
3331
3335
  if (!explicitKey && !keyComment && identity.isScalar(value))
3332
- ctx.indentAtStart = str.length + 1;
3336
+ ctx.indentAtStart = str3.length + 1;
3333
3337
  chompKeep = false;
3334
3338
  if (!indentSeq && indentStep.length >= 2 && !ctx.inFlow && !explicitKey && identity.isSeq(value) && !value.flow && !value.tag && !value.anchor) {
3335
3339
  ctx.indent = ctx.indent.substring(2);
@@ -3373,16 +3377,16 @@ ${ctx.indent}`;
3373
3377
  } else if (valueStr === "" || valueStr[0] === "\n") {
3374
3378
  ws = "";
3375
3379
  }
3376
- str += ws + valueStr;
3380
+ str3 += ws + valueStr;
3377
3381
  if (ctx.inFlow) {
3378
3382
  if (valueCommentDone && onComment)
3379
3383
  onComment();
3380
3384
  } else if (valueComment && !valueCommentDone) {
3381
- str += stringifyComment.lineComment(str, ctx.indent, commentString(valueComment));
3385
+ str3 += stringifyComment.lineComment(str3, ctx.indent, commentString(valueComment));
3382
3386
  } else if (chompKeep && onChompKeep) {
3383
3387
  onChompKeep();
3384
3388
  }
3385
- return str;
3389
+ return str3;
3386
3390
  }
3387
3391
  exports.stringifyPair = stringifyPair;
3388
3392
  }
@@ -3609,31 +3613,31 @@ var require_stringifyCollection = __commonJS({
3609
3613
  }
3610
3614
  }
3611
3615
  chompKeep = false;
3612
- let str2 = stringify.stringify(item, itemCtx, () => comment2 = null, () => chompKeep = true);
3616
+ let str4 = stringify.stringify(item, itemCtx, () => comment2 = null, () => chompKeep = true);
3613
3617
  if (comment2)
3614
- str2 += stringifyComment.lineComment(str2, itemIndent, commentString(comment2));
3618
+ str4 += stringifyComment.lineComment(str4, itemIndent, commentString(comment2));
3615
3619
  if (chompKeep && comment2)
3616
3620
  chompKeep = false;
3617
- lines.push(blockItemPrefix + str2);
3621
+ lines.push(blockItemPrefix + str4);
3618
3622
  }
3619
- let str;
3623
+ let str3;
3620
3624
  if (lines.length === 0) {
3621
- str = flowChars.start + flowChars.end;
3625
+ str3 = flowChars.start + flowChars.end;
3622
3626
  } else {
3623
- str = lines[0];
3627
+ str3 = lines[0];
3624
3628
  for (let i = 1; i < lines.length; ++i) {
3625
3629
  const line = lines[i];
3626
- str += line ? `
3630
+ str3 += line ? `
3627
3631
  ${indent}${line}` : "\n";
3628
3632
  }
3629
3633
  }
3630
3634
  if (comment) {
3631
- str += "\n" + stringifyComment.indentComment(commentString(comment), indent);
3635
+ str3 += "\n" + stringifyComment.indentComment(commentString(comment), indent);
3632
3636
  if (onComment)
3633
3637
  onComment();
3634
3638
  } else if (chompKeep && onChompKeep)
3635
3639
  onChompKeep();
3636
- return str;
3640
+ return str3;
3637
3641
  }
3638
3642
  function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
3639
3643
  const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;
@@ -3676,21 +3680,21 @@ ${indent}${line}` : "\n";
3676
3680
  }
3677
3681
  if (comment)
3678
3682
  reqNewline = true;
3679
- let str = stringify.stringify(item, itemCtx, () => comment = null);
3680
- reqNewline || (reqNewline = lines.length > linesAtValue || str.includes("\n"));
3683
+ let str3 = stringify.stringify(item, itemCtx, () => comment = null);
3684
+ reqNewline || (reqNewline = lines.length > linesAtValue || str3.includes("\n"));
3681
3685
  if (i < items.length - 1) {
3682
- str += ",";
3686
+ str3 += ",";
3683
3687
  } else if (ctx.options.trailingComma) {
3684
3688
  if (ctx.options.lineWidth > 0) {
3685
- reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + (str.length + 2) > ctx.options.lineWidth);
3689
+ reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + (str3.length + 2) > ctx.options.lineWidth);
3686
3690
  }
3687
3691
  if (reqNewline) {
3688
- str += ",";
3692
+ str3 += ",";
3689
3693
  }
3690
3694
  }
3691
3695
  if (comment)
3692
- str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
3693
- lines.push(str);
3696
+ str3 += stringifyComment.lineComment(str3, itemIndent, commentString(comment));
3697
+ lines.push(str3);
3694
3698
  linesAtValue = lines.length;
3695
3699
  }
3696
3700
  const { start, end } = flowChars;
@@ -3702,11 +3706,11 @@ ${indent}${line}` : "\n";
3702
3706
  reqNewline = ctx.options.lineWidth > 0 && len > ctx.options.lineWidth;
3703
3707
  }
3704
3708
  if (reqNewline) {
3705
- let str = start;
3709
+ let str3 = start;
3706
3710
  for (const line of lines)
3707
- str += line ? `
3711
+ str3 += line ? `
3708
3712
  ${indentStep}${indent}${line}` : "\n";
3709
- return `${str}
3713
+ return `${str3}
3710
3714
  ${indent}${end}`;
3711
3715
  } else {
3712
3716
  return `${start}${fcPadding}${lines.join(" ")}${fcPadding}${end}`;
@@ -4038,7 +4042,7 @@ var require_string = __commonJS({
4038
4042
  identify: (value) => typeof value === "string",
4039
4043
  default: true,
4040
4044
  tag: "tag:yaml.org,2002:str",
4041
- resolve: (str) => str,
4045
+ resolve: (str3) => str3,
4042
4046
  stringify(item, ctx, onComment, onChompKeep) {
4043
4047
  ctx = Object.assign({ actualString: true }, ctx);
4044
4048
  return stringifyString.stringifyString(item, ctx, onComment, onChompKeep);
@@ -4076,7 +4080,7 @@ var require_bool = __commonJS({
4076
4080
  default: true,
4077
4081
  tag: "tag:yaml.org,2002:bool",
4078
4082
  test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,
4079
- resolve: (str) => new Scalar.Scalar(str[0] === "t" || str[0] === "T"),
4083
+ resolve: (str3) => new Scalar.Scalar(str3[0] === "t" || str3[0] === "T"),
4080
4084
  stringify({ source, value }, ctx) {
4081
4085
  if (source && boolTag.test.test(source)) {
4082
4086
  const sv = source[0] === "t" || source[0] === "T";
@@ -4128,7 +4132,7 @@ var require_float = __commonJS({
4128
4132
  default: true,
4129
4133
  tag: "tag:yaml.org,2002:float",
4130
4134
  test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
4131
- resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
4135
+ resolve: (str3) => str3.slice(-3).toLowerCase() === "nan" ? NaN : str3[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
4132
4136
  stringify: stringifyNumber.stringifyNumber
4133
4137
  };
4134
4138
  var floatExp = {
@@ -4137,7 +4141,7 @@ var require_float = __commonJS({
4137
4141
  tag: "tag:yaml.org,2002:float",
4138
4142
  format: "EXP",
4139
4143
  test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,
4140
- resolve: (str) => parseFloat(str),
4144
+ resolve: (str3) => parseFloat(str3),
4141
4145
  stringify(node) {
4142
4146
  const num = Number(node.value);
4143
4147
  return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);
@@ -4148,11 +4152,11 @@ var require_float = __commonJS({
4148
4152
  default: true,
4149
4153
  tag: "tag:yaml.org,2002:float",
4150
4154
  test: /^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/,
4151
- resolve(str) {
4152
- const node = new Scalar.Scalar(parseFloat(str));
4153
- const dot = str.indexOf(".");
4154
- if (dot !== -1 && str[str.length - 1] === "0")
4155
- node.minFractionDigits = str.length - dot - 1;
4155
+ resolve(str3) {
4156
+ const node = new Scalar.Scalar(parseFloat(str3));
4157
+ const dot = str3.indexOf(".");
4158
+ if (dot !== -1 && str3[str3.length - 1] === "0")
4159
+ node.minFractionDigits = str3.length - dot - 1;
4156
4160
  return node;
4157
4161
  },
4158
4162
  stringify: stringifyNumber.stringifyNumber
@@ -4169,7 +4173,7 @@ var require_int = __commonJS({
4169
4173
  "use strict";
4170
4174
  var stringifyNumber = require_stringifyNumber();
4171
4175
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
4172
- var intResolve = (str, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str.substring(offset), radix);
4176
+ var intResolve = (str3, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str3) : parseInt(str3.substring(offset), radix);
4173
4177
  function intStringify(node, radix, prefix) {
4174
4178
  const { value } = node;
4175
4179
  if (intIdentify(value) && value >= 0)
@@ -4182,7 +4186,7 @@ var require_int = __commonJS({
4182
4186
  tag: "tag:yaml.org,2002:int",
4183
4187
  format: "OCT",
4184
4188
  test: /^0o[0-7]+$/,
4185
- resolve: (str, _onError, opt) => intResolve(str, 2, 8, opt),
4189
+ resolve: (str3, _onError, opt) => intResolve(str3, 2, 8, opt),
4186
4190
  stringify: (node) => intStringify(node, 8, "0o")
4187
4191
  };
4188
4192
  var int = {
@@ -4190,7 +4194,7 @@ var require_int = __commonJS({
4190
4194
  default: true,
4191
4195
  tag: "tag:yaml.org,2002:int",
4192
4196
  test: /^[-+]?[0-9]+$/,
4193
- resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),
4197
+ resolve: (str3, _onError, opt) => intResolve(str3, 0, 10, opt),
4194
4198
  stringify: stringifyNumber.stringifyNumber
4195
4199
  };
4196
4200
  var intHex = {
@@ -4199,7 +4203,7 @@ var require_int = __commonJS({
4199
4203
  tag: "tag:yaml.org,2002:int",
4200
4204
  format: "HEX",
4201
4205
  test: /^0x[0-9a-fA-F]+$/,
4202
- resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
4206
+ resolve: (str3, _onError, opt) => intResolve(str3, 2, 16, opt),
4203
4207
  stringify: (node) => intStringify(node, 16, "0x")
4204
4208
  };
4205
4209
  exports.int = int;
@@ -4252,7 +4256,7 @@ var require_schema2 = __commonJS({
4252
4256
  identify: (value) => typeof value === "string",
4253
4257
  default: true,
4254
4258
  tag: "tag:yaml.org,2002:str",
4255
- resolve: (str) => str,
4259
+ resolve: (str3) => str3,
4256
4260
  stringify: stringifyJSON
4257
4261
  },
4258
4262
  {
@@ -4269,7 +4273,7 @@ var require_schema2 = __commonJS({
4269
4273
  default: true,
4270
4274
  tag: "tag:yaml.org,2002:bool",
4271
4275
  test: /^true$|^false$/,
4272
- resolve: (str) => str === "true",
4276
+ resolve: (str3) => str3 === "true",
4273
4277
  stringify: stringifyJSON
4274
4278
  },
4275
4279
  {
@@ -4277,7 +4281,7 @@ var require_schema2 = __commonJS({
4277
4281
  default: true,
4278
4282
  tag: "tag:yaml.org,2002:int",
4279
4283
  test: /^-?(?:0|[1-9][0-9]*)$/,
4280
- resolve: (str, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str, 10),
4284
+ resolve: (str3, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str3) : parseInt(str3, 10),
4281
4285
  stringify: ({ value }) => intIdentify(value) ? value.toString() : JSON.stringify(value)
4282
4286
  },
4283
4287
  {
@@ -4285,7 +4289,7 @@ var require_schema2 = __commonJS({
4285
4289
  default: true,
4286
4290
  tag: "tag:yaml.org,2002:float",
4287
4291
  test: /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,
4288
- resolve: (str) => parseFloat(str),
4292
+ resolve: (str3) => parseFloat(str3),
4289
4293
  stringify: stringifyJSON
4290
4294
  }
4291
4295
  ];
@@ -4293,9 +4297,9 @@ var require_schema2 = __commonJS({
4293
4297
  default: true,
4294
4298
  tag: "",
4295
4299
  test: /^/,
4296
- resolve(str, onError) {
4297
- onError(`Unresolved plain scalar ${JSON.stringify(str)}`);
4298
- return str;
4300
+ resolve(str3, onError) {
4301
+ onError(`Unresolved plain scalar ${JSON.stringify(str3)}`);
4302
+ return str3;
4299
4303
  }
4300
4304
  };
4301
4305
  var schema = [map.map, seq.seq].concat(jsonScalars, jsonError);
@@ -4327,10 +4331,10 @@ var require_binary = __commonJS({
4327
4331
  if (typeof node_buffer.Buffer === "function") {
4328
4332
  return node_buffer.Buffer.from(src, "base64");
4329
4333
  } else if (typeof atob === "function") {
4330
- const str = atob(src.replace(/[\n\r]/g, ""));
4331
- const buffer = new Uint8Array(str.length);
4332
- for (let i = 0; i < str.length; ++i)
4333
- buffer[i] = str.charCodeAt(i);
4334
+ const str3 = atob(src.replace(/[\n\r]/g, ""));
4335
+ const buffer = new Uint8Array(str3.length);
4336
+ for (let i = 0; i < str3.length; ++i)
4337
+ buffer[i] = str3.charCodeAt(i);
4334
4338
  return buffer;
4335
4339
  } else {
4336
4340
  onError("This environment does not support reading binary tags; either Buffer or atob is required");
@@ -4341,28 +4345,28 @@ var require_binary = __commonJS({
4341
4345
  if (!value)
4342
4346
  return "";
4343
4347
  const buf = value;
4344
- let str;
4348
+ let str3;
4345
4349
  if (typeof node_buffer.Buffer === "function") {
4346
- str = buf instanceof node_buffer.Buffer ? buf.toString("base64") : node_buffer.Buffer.from(buf.buffer).toString("base64");
4350
+ str3 = buf instanceof node_buffer.Buffer ? buf.toString("base64") : node_buffer.Buffer.from(buf.buffer).toString("base64");
4347
4351
  } else if (typeof btoa === "function") {
4348
4352
  let s = "";
4349
4353
  for (let i = 0; i < buf.length; ++i)
4350
4354
  s += String.fromCharCode(buf[i]);
4351
- str = btoa(s);
4355
+ str3 = btoa(s);
4352
4356
  } else {
4353
4357
  throw new Error("This environment does not support writing binary tags; either Buffer or btoa is required");
4354
4358
  }
4355
4359
  type ?? (type = Scalar.Scalar.BLOCK_LITERAL);
4356
4360
  if (type !== Scalar.Scalar.QUOTE_DOUBLE) {
4357
4361
  const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth);
4358
- const n = Math.ceil(str.length / lineWidth);
4362
+ const n = Math.ceil(str3.length / lineWidth);
4359
4363
  const lines = new Array(n);
4360
4364
  for (let i = 0, o = 0; i < n; ++i, o += lineWidth) {
4361
- lines[i] = str.substr(o, lineWidth);
4365
+ lines[i] = str3.substr(o, lineWidth);
4362
4366
  }
4363
- str = lines.join(type === Scalar.Scalar.BLOCK_LITERAL ? "\n" : " ");
4367
+ str3 = lines.join(type === Scalar.Scalar.BLOCK_LITERAL ? "\n" : " ");
4364
4368
  }
4365
- return stringifyString.stringifyString({ comment, type, value: str }, ctx, onComment, onChompKeep);
4369
+ return stringifyString.stringifyString({ comment, type, value: str3 }, ctx, onComment, onChompKeep);
4366
4370
  }
4367
4371
  };
4368
4372
  exports.binary = binary;
@@ -4568,7 +4572,7 @@ var require_float2 = __commonJS({
4568
4572
  default: true,
4569
4573
  tag: "tag:yaml.org,2002:float",
4570
4574
  test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
4571
- resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
4575
+ resolve: (str3) => str3.slice(-3).toLowerCase() === "nan" ? NaN : str3[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
4572
4576
  stringify: stringifyNumber.stringifyNumber
4573
4577
  };
4574
4578
  var floatExp = {
@@ -4577,7 +4581,7 @@ var require_float2 = __commonJS({
4577
4581
  tag: "tag:yaml.org,2002:float",
4578
4582
  format: "EXP",
4579
4583
  test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,
4580
- resolve: (str) => parseFloat(str.replace(/_/g, "")),
4584
+ resolve: (str3) => parseFloat(str3.replace(/_/g, "")),
4581
4585
  stringify(node) {
4582
4586
  const num = Number(node.value);
4583
4587
  return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);
@@ -4588,11 +4592,11 @@ var require_float2 = __commonJS({
4588
4592
  default: true,
4589
4593
  tag: "tag:yaml.org,2002:float",
4590
4594
  test: /^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/,
4591
- resolve(str) {
4592
- const node = new Scalar.Scalar(parseFloat(str.replace(/_/g, "")));
4593
- const dot = str.indexOf(".");
4595
+ resolve(str3) {
4596
+ const node = new Scalar.Scalar(parseFloat(str3.replace(/_/g, "")));
4597
+ const dot = str3.indexOf(".");
4594
4598
  if (dot !== -1) {
4595
- const f = str.substring(dot + 1).replace(/_/g, "");
4599
+ const f = str3.substring(dot + 1).replace(/_/g, "");
4596
4600
  if (f[f.length - 1] === "0")
4597
4601
  node.minFractionDigits = f.length;
4598
4602
  }
@@ -4612,34 +4616,34 @@ var require_int2 = __commonJS({
4612
4616
  "use strict";
4613
4617
  var stringifyNumber = require_stringifyNumber();
4614
4618
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
4615
- function intResolve(str, offset, radix, { intAsBigInt }) {
4616
- const sign = str[0];
4619
+ function intResolve(str3, offset, radix, { intAsBigInt }) {
4620
+ const sign = str3[0];
4617
4621
  if (sign === "-" || sign === "+")
4618
4622
  offset += 1;
4619
- str = str.substring(offset).replace(/_/g, "");
4623
+ str3 = str3.substring(offset).replace(/_/g, "");
4620
4624
  if (intAsBigInt) {
4621
4625
  switch (radix) {
4622
4626
  case 2:
4623
- str = `0b${str}`;
4627
+ str3 = `0b${str3}`;
4624
4628
  break;
4625
4629
  case 8:
4626
- str = `0o${str}`;
4630
+ str3 = `0o${str3}`;
4627
4631
  break;
4628
4632
  case 16:
4629
- str = `0x${str}`;
4633
+ str3 = `0x${str3}`;
4630
4634
  break;
4631
4635
  }
4632
- const n2 = BigInt(str);
4636
+ const n2 = BigInt(str3);
4633
4637
  return sign === "-" ? BigInt(-1) * n2 : n2;
4634
4638
  }
4635
- const n = parseInt(str, radix);
4639
+ const n = parseInt(str3, radix);
4636
4640
  return sign === "-" ? -1 * n : n;
4637
4641
  }
4638
4642
  function intStringify(node, radix, prefix) {
4639
4643
  const { value } = node;
4640
4644
  if (intIdentify(value)) {
4641
- const str = value.toString(radix);
4642
- return value < 0 ? "-" + prefix + str.substr(1) : prefix + str;
4645
+ const str3 = value.toString(radix);
4646
+ return value < 0 ? "-" + prefix + str3.substr(1) : prefix + str3;
4643
4647
  }
4644
4648
  return stringifyNumber.stringifyNumber(node);
4645
4649
  }
@@ -4649,7 +4653,7 @@ var require_int2 = __commonJS({
4649
4653
  tag: "tag:yaml.org,2002:int",
4650
4654
  format: "BIN",
4651
4655
  test: /^[-+]?0b[0-1_]+$/,
4652
- resolve: (str, _onError, opt) => intResolve(str, 2, 2, opt),
4656
+ resolve: (str3, _onError, opt) => intResolve(str3, 2, 2, opt),
4653
4657
  stringify: (node) => intStringify(node, 2, "0b")
4654
4658
  };
4655
4659
  var intOct = {
@@ -4658,7 +4662,7 @@ var require_int2 = __commonJS({
4658
4662
  tag: "tag:yaml.org,2002:int",
4659
4663
  format: "OCT",
4660
4664
  test: /^[-+]?0[0-7_]+$/,
4661
- resolve: (str, _onError, opt) => intResolve(str, 1, 8, opt),
4665
+ resolve: (str3, _onError, opt) => intResolve(str3, 1, 8, opt),
4662
4666
  stringify: (node) => intStringify(node, 8, "0")
4663
4667
  };
4664
4668
  var int = {
@@ -4666,7 +4670,7 @@ var require_int2 = __commonJS({
4666
4670
  default: true,
4667
4671
  tag: "tag:yaml.org,2002:int",
4668
4672
  test: /^[-+]?[0-9][0-9_]*$/,
4669
- resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),
4673
+ resolve: (str3, _onError, opt) => intResolve(str3, 0, 10, opt),
4670
4674
  stringify: stringifyNumber.stringifyNumber
4671
4675
  };
4672
4676
  var intHex = {
@@ -4675,7 +4679,7 @@ var require_int2 = __commonJS({
4675
4679
  tag: "tag:yaml.org,2002:int",
4676
4680
  format: "HEX",
4677
4681
  test: /^[-+]?0x[0-9a-fA-F_]+$/,
4678
- resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
4682
+ resolve: (str3, _onError, opt) => intResolve(str3, 2, 16, opt),
4679
4683
  stringify: (node) => intStringify(node, 16, "0x")
4680
4684
  };
4681
4685
  exports.int = int;
@@ -4779,9 +4783,9 @@ var require_timestamp = __commonJS({
4779
4783
  "node_modules/yaml/dist/schema/yaml-1.1/timestamp.js"(exports) {
4780
4784
  "use strict";
4781
4785
  var stringifyNumber = require_stringifyNumber();
4782
- function parseSexagesimal(str, asBigInt) {
4783
- const sign = str[0];
4784
- const parts = sign === "-" || sign === "+" ? str.substring(1) : str;
4786
+ function parseSexagesimal(str3, asBigInt) {
4787
+ const sign = str3[0];
4788
+ const parts = sign === "-" || sign === "+" ? str3.substring(1) : str3;
4785
4789
  const num = (n) => asBigInt ? BigInt(n) : Number(n);
4786
4790
  const res = parts.replace(/_/g, "").split(":").reduce((res2, p) => res2 * num(60) + num(p), num(0));
4787
4791
  return sign === "-" ? num(-1) * res : res;
@@ -4818,7 +4822,7 @@ var require_timestamp = __commonJS({
4818
4822
  tag: "tag:yaml.org,2002:int",
4819
4823
  format: "TIME",
4820
4824
  test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/,
4821
- resolve: (str, _onError, { intAsBigInt }) => parseSexagesimal(str, intAsBigInt),
4825
+ resolve: (str3, _onError, { intAsBigInt }) => parseSexagesimal(str3, intAsBigInt),
4822
4826
  stringify: stringifySexagesimal
4823
4827
  };
4824
4828
  var floatTime = {
@@ -4827,7 +4831,7 @@ var require_timestamp = __commonJS({
4827
4831
  tag: "tag:yaml.org,2002:float",
4828
4832
  format: "TIME",
4829
4833
  test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*$/,
4830
- resolve: (str) => parseSexagesimal(str, false),
4834
+ resolve: (str3) => parseSexagesimal(str3, false),
4831
4835
  stringify: stringifySexagesimal
4832
4836
  };
4833
4837
  var timestamp = {
@@ -4838,8 +4842,8 @@ var require_timestamp = __commonJS({
4838
4842
  // may be omitted altogether, resulting in a date format. In such a case, the time part is
4839
4843
  // assumed to be 00:00:00Z (start of day, UTC).
4840
4844
  test: RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})(?:(?:t|T|[ \\t]+)([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$"),
4841
- resolve(str) {
4842
- const match = str.match(timestamp.test);
4845
+ resolve(str3) {
4846
+ const match = str3.match(timestamp.test);
4843
4847
  if (!match)
4844
4848
  throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");
4845
4849
  const [, year, month, day, hour, minute, second] = match.map(Number);
@@ -5190,9 +5194,9 @@ var require_Document = __commonJS({
5190
5194
  this.contents.add(value);
5191
5195
  }
5192
5196
  /** Adds a value to the document. */
5193
- addIn(path71, value) {
5197
+ addIn(path73, value) {
5194
5198
  if (assertCollection(this.contents))
5195
- this.contents.addIn(path71, value);
5199
+ this.contents.addIn(path73, value);
5196
5200
  }
5197
5201
  /**
5198
5202
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -5267,14 +5271,14 @@ var require_Document = __commonJS({
5267
5271
  * Removes a value from the document.
5268
5272
  * @returns `true` if the item was found and removed.
5269
5273
  */
5270
- deleteIn(path71) {
5271
- if (Collection.isEmptyPath(path71)) {
5274
+ deleteIn(path73) {
5275
+ if (Collection.isEmptyPath(path73)) {
5272
5276
  if (this.contents == null)
5273
5277
  return false;
5274
5278
  this.contents = null;
5275
5279
  return true;
5276
5280
  }
5277
- return assertCollection(this.contents) ? this.contents.deleteIn(path71) : false;
5281
+ return assertCollection(this.contents) ? this.contents.deleteIn(path73) : false;
5278
5282
  }
5279
5283
  /**
5280
5284
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -5289,10 +5293,10 @@ var require_Document = __commonJS({
5289
5293
  * scalar values from their surrounding node; to disable set `keepScalar` to
5290
5294
  * `true` (collections are always returned intact).
5291
5295
  */
5292
- getIn(path71, keepScalar) {
5293
- if (Collection.isEmptyPath(path71))
5296
+ getIn(path73, keepScalar) {
5297
+ if (Collection.isEmptyPath(path73))
5294
5298
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
5295
- return identity.isCollection(this.contents) ? this.contents.getIn(path71, keepScalar) : void 0;
5299
+ return identity.isCollection(this.contents) ? this.contents.getIn(path73, keepScalar) : void 0;
5296
5300
  }
5297
5301
  /**
5298
5302
  * Checks if the document includes a value with the key `key`.
@@ -5303,10 +5307,10 @@ var require_Document = __commonJS({
5303
5307
  /**
5304
5308
  * Checks if the document includes a value at `path`.
5305
5309
  */
5306
- hasIn(path71) {
5307
- if (Collection.isEmptyPath(path71))
5310
+ hasIn(path73) {
5311
+ if (Collection.isEmptyPath(path73))
5308
5312
  return this.contents !== void 0;
5309
- return identity.isCollection(this.contents) ? this.contents.hasIn(path71) : false;
5313
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path73) : false;
5310
5314
  }
5311
5315
  /**
5312
5316
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -5323,13 +5327,13 @@ var require_Document = __commonJS({
5323
5327
  * Sets a value in this document. For `!!set`, `value` needs to be a
5324
5328
  * boolean to add/remove the item from the set.
5325
5329
  */
5326
- setIn(path71, value) {
5327
- if (Collection.isEmptyPath(path71)) {
5330
+ setIn(path73, value) {
5331
+ if (Collection.isEmptyPath(path73)) {
5328
5332
  this.contents = value;
5329
5333
  } else if (this.contents == null) {
5330
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path71), value);
5334
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path73), value);
5331
5335
  } else if (assertCollection(this.contents)) {
5332
- this.contents.setIn(path71, value);
5336
+ this.contents.setIn(path73, value);
5333
5337
  }
5334
5338
  }
5335
5339
  /**
@@ -7289,9 +7293,9 @@ var require_cst_visit = __commonJS({
7289
7293
  visit.BREAK = BREAK;
7290
7294
  visit.SKIP = SKIP;
7291
7295
  visit.REMOVE = REMOVE;
7292
- visit.itemAtPath = (cst, path71) => {
7296
+ visit.itemAtPath = (cst, path73) => {
7293
7297
  let item = cst;
7294
- for (const [field, index] of path71) {
7298
+ for (const [field, index] of path73) {
7295
7299
  const tok = item?.[field];
7296
7300
  if (tok && "items" in tok) {
7297
7301
  item = tok.items[index];
@@ -7300,23 +7304,23 @@ var require_cst_visit = __commonJS({
7300
7304
  }
7301
7305
  return item;
7302
7306
  };
7303
- visit.parentCollection = (cst, path71) => {
7304
- const parent = visit.itemAtPath(cst, path71.slice(0, -1));
7305
- const field = path71[path71.length - 1][0];
7307
+ visit.parentCollection = (cst, path73) => {
7308
+ const parent = visit.itemAtPath(cst, path73.slice(0, -1));
7309
+ const field = path73[path73.length - 1][0];
7306
7310
  const coll = parent?.[field];
7307
7311
  if (coll && "items" in coll)
7308
7312
  return coll;
7309
7313
  throw new Error("Parent collection not found");
7310
7314
  };
7311
- function _visit(path71, item, visitor) {
7312
- let ctrl = visitor(item, path71);
7315
+ function _visit(path73, item, visitor) {
7316
+ let ctrl = visitor(item, path73);
7313
7317
  if (typeof ctrl === "symbol")
7314
7318
  return ctrl;
7315
7319
  for (const field of ["key", "value"]) {
7316
7320
  const token = item[field];
7317
7321
  if (token && "items" in token) {
7318
7322
  for (let i = 0; i < token.items.length; ++i) {
7319
- const ci = _visit(Object.freeze(path71.concat([[field, i]])), token.items[i], visitor);
7323
+ const ci = _visit(Object.freeze(path73.concat([[field, i]])), token.items[i], visitor);
7320
7324
  if (typeof ci === "number")
7321
7325
  i = ci - 1;
7322
7326
  else if (ci === BREAK)
@@ -7327,10 +7331,10 @@ var require_cst_visit = __commonJS({
7327
7331
  }
7328
7332
  }
7329
7333
  if (typeof ctrl === "function" && field === "key")
7330
- ctrl = ctrl(item, path71);
7334
+ ctrl = ctrl(item, path73);
7331
7335
  }
7332
7336
  }
7333
- return typeof ctrl === "function" ? ctrl(item, path71) : ctrl;
7337
+ return typeof ctrl === "function" ? ctrl(item, path73) : ctrl;
7334
7338
  }
7335
7339
  exports.visit = visit;
7336
7340
  }
@@ -8632,14 +8636,14 @@ var require_parser = __commonJS({
8632
8636
  case "scalar":
8633
8637
  case "single-quoted-scalar":
8634
8638
  case "double-quoted-scalar": {
8635
- const fs74 = this.flowScalar(this.type);
8639
+ const fs76 = this.flowScalar(this.type);
8636
8640
  if (atNextItem || it.value) {
8637
- map.items.push({ start, key: fs74, sep: [] });
8641
+ map.items.push({ start, key: fs76, sep: [] });
8638
8642
  this.onKeyLine = true;
8639
8643
  } else if (it.sep) {
8640
- this.stack.push(fs74);
8644
+ this.stack.push(fs76);
8641
8645
  } else {
8642
- Object.assign(it, { key: fs74, sep: [] });
8646
+ Object.assign(it, { key: fs76, sep: [] });
8643
8647
  this.onKeyLine = true;
8644
8648
  }
8645
8649
  return;
@@ -8767,13 +8771,13 @@ var require_parser = __commonJS({
8767
8771
  case "scalar":
8768
8772
  case "single-quoted-scalar":
8769
8773
  case "double-quoted-scalar": {
8770
- const fs74 = this.flowScalar(this.type);
8774
+ const fs76 = this.flowScalar(this.type);
8771
8775
  if (!it || it.value)
8772
- fc.items.push({ start: [], key: fs74, sep: [] });
8776
+ fc.items.push({ start: [], key: fs76, sep: [] });
8773
8777
  else if (it.sep)
8774
- this.stack.push(fs74);
8778
+ this.stack.push(fs76);
8775
8779
  else
8776
- Object.assign(it, { key: fs74, sep: [] });
8780
+ Object.assign(it, { key: fs76, sep: [] });
8777
8781
  return;
8778
8782
  }
8779
8783
  case "flow-map-end":
@@ -15252,7 +15256,7 @@ function lint_wing4_boundaries(text) {
15252
15256
  }
15253
15257
  return issues;
15254
15258
  }
15255
- function lint_execution_metadata(execution) {
15259
+ function lint_execution_metadata(execution, frontmatter) {
15256
15260
  const issues = [];
15257
15261
  const execType = execution.type;
15258
15262
  if (execType !== void 0) {
@@ -15354,6 +15358,15 @@ function lint_execution_metadata(execution) {
15354
15358
  issues.push(new Issue("error", "empty_command", "command must not be empty"));
15355
15359
  }
15356
15360
  }
15361
+ if (typeof handler === "string" && EXTERNAL_EXECUTION_HANDLERS.has(handler) && Array.isArray(command) && command.length > 0 && !RUNTIME_REQUIRES_BLOCK_PATTERN.test(frontmatter)) {
15362
+ issues.push(
15363
+ new Issue(
15364
+ "error",
15365
+ "missing_runtime_requires",
15366
+ `execution.handler '${handler}' declares a command but the skill has no top-level 'runtime_requires:' block \u2014 declare bins/env/network so doctor and preflight can verify the runtime before the command runs`
15367
+ )
15368
+ );
15369
+ }
15357
15370
  const unknown = Object.keys(execution).filter((k) => !VALID_EXECUTION_FIELDS.has(k));
15358
15371
  for (const field of unknown.sort()) {
15359
15372
  issues.push(
@@ -15489,7 +15502,7 @@ function lint_skill(p, text, absPath = null) {
15489
15502
  }
15490
15503
  const execution = parseExecutionBlock(frontmatter);
15491
15504
  if (execution !== null) {
15492
- issues.push(...lint_execution_metadata(execution));
15505
+ issues.push(...lint_execution_metadata(execution, frontmatter));
15493
15506
  }
15494
15507
  const tierMatch = TIER_PATTERN.exec(frontmatter);
15495
15508
  if (tierMatch && tierMatch[1] === "senior") {
@@ -18011,7 +18024,7 @@ function _isCliEntry7() {
18011
18024
  return false;
18012
18025
  }
18013
18026
  }
18014
- var _HERE4, REQUIRED_PERSONA_SECTIONS_CORE, REQUIRED_PERSONA_SECTIONS_SPECIALIST, VALID_PERSONA_TIERS, PERSONA_LINE_BUDGETS, REQUIRED_USERTYPE_SECTIONS, USERTYPE_LINE_BUDGET, VALID_PERSONA_WINGS, PERSONA_LINE_BUDGETS_BY_WING, REQUIRED_SKILL_SECTIONS, SECTION_ALIASES, RECOMMENDED_SKILL_SECTIONS, CONDITIONAL_SKILL_SECTIONS, RULE_BAD_SIGNS, FRUGALITY_WRITER_SKILLS, FRUGALITY_CHARTER_RELPATH, FRUGALITY_CHARTER_INDEX_RULES, VAGUE_VALIDATION_PATTERNS, TRIGGER_WARNING_PATTERNS, ORDERED_STEP_PATTERN, SECTION_PATTERN, FRONTMATTER_PATTERN, DESCRIPTION_PATTERN, STATUS_PATTERN, REPLACED_BY_PATTERN, TIER_PATTERN, TYPE_PATTERN, SOURCE_PATTERN, SENIOR_RELATED_SKILLS_PATTERN, SENIOR_RELATED_WHEN_PATTERN, SENIOR_RELATED_WHEN_NOT_PATTERN, SENIOR_PROACTIVE_PATTERN, SENIOR_OUTPUT_PATTERN, H1_PATTERN, DOUBLE_BLANK_PATTERN, VALID_RULE_TYPES, VALID_RULE_SOURCES, ROUTER_ALLOWED_TRIGGER_KEYS, KERNEL_RULE_IDS2, VALID_EXECUTION_TYPES, VALID_EXECUTION_HANDLERS, VALID_EXECUTION_SAFETY_MODES, VALID_EXECUTION_FIELDS, WING3_SPINE_SLOTS, CONTEXT_SPINE_INLINE_PATTERN, WING3_SAAS_URL_PATTERN, WING3_VENDOR_BLACKLIST, WING3_STACK_LOCKED_PATTERN, WING3_CHANNEL_TACTIC_PATTERN, WING4_SPINE_SLOTS, WING4_SAAS_URL_PATTERN, WING4_VENDOR_BLACKLIST, WING4_STAGE_AGNOSTIC_PATTERN, Issue, LintResult, _ROLE_CONTRACT_CANDIDATES, _ROLE_CONTRACT_SLUGS_CACHE, _ROLE_CONTRACT_REF_PATTERN, PROCEDURE_HEADING_PATTERN, COMMAND_FRONTMATTER_DELEGATION_KEYS, MD_LINK_PATTERN_G, NAME_PATTERN, DISABLE_MODEL_PATTERN, _INSPECT_VERB_PATTERN, last_changed_scope_reason, last_changed_base_diff_ok, _INTERACTION_NAME_PATTERNS, _INTERACTION_CONTENT_KEYWORDS, _EXEC_FILE_SIGNALS, _EXEC_CONTENT_SIGNALS, _TASK_TYPE_SIGNALS, _VERIFICATION_TOOLS, _FRUGALITY_STANDARDS_PATTERN, _FRUGALITY_CHARTER_LINK_PATTERN, _MD_LINK_PATTERN, _MALICE_CRED_EXFIL, _MALICE_REMOTE_EXEC, _MALICE_FORCE_PUSH, _MALICE_CHMOD_SECRETS, _MALICE_SHELL_INJECT, _MALICE_PATTERNS, _NAG_UPDATE_CHECK, _NAG_STAY_CURRENT, _NAG_SELF_PROMO, _NAG_BEST_SKILL, _NAG_MUST_USE, _NAG_ALWAYS_USE, _NAG_PATTERNS, _OUTPUT_SCHEMA_KEY_PATTERN, _SCHEMA_ARTEFACT_TYPES, ArgError, isCliEntry2;
18027
+ var _HERE4, REQUIRED_PERSONA_SECTIONS_CORE, REQUIRED_PERSONA_SECTIONS_SPECIALIST, VALID_PERSONA_TIERS, PERSONA_LINE_BUDGETS, REQUIRED_USERTYPE_SECTIONS, USERTYPE_LINE_BUDGET, VALID_PERSONA_WINGS, PERSONA_LINE_BUDGETS_BY_WING, REQUIRED_SKILL_SECTIONS, SECTION_ALIASES, RECOMMENDED_SKILL_SECTIONS, CONDITIONAL_SKILL_SECTIONS, RULE_BAD_SIGNS, FRUGALITY_WRITER_SKILLS, FRUGALITY_CHARTER_RELPATH, FRUGALITY_CHARTER_INDEX_RULES, VAGUE_VALIDATION_PATTERNS, TRIGGER_WARNING_PATTERNS, ORDERED_STEP_PATTERN, SECTION_PATTERN, FRONTMATTER_PATTERN, DESCRIPTION_PATTERN, STATUS_PATTERN, REPLACED_BY_PATTERN, TIER_PATTERN, TYPE_PATTERN, SOURCE_PATTERN, SENIOR_RELATED_SKILLS_PATTERN, SENIOR_RELATED_WHEN_PATTERN, SENIOR_RELATED_WHEN_NOT_PATTERN, SENIOR_PROACTIVE_PATTERN, SENIOR_OUTPUT_PATTERN, H1_PATTERN, DOUBLE_BLANK_PATTERN, VALID_RULE_TYPES, VALID_RULE_SOURCES, ROUTER_ALLOWED_TRIGGER_KEYS, KERNEL_RULE_IDS2, VALID_EXECUTION_TYPES, VALID_EXECUTION_HANDLERS, VALID_EXECUTION_SAFETY_MODES, EXTERNAL_EXECUTION_HANDLERS, RUNTIME_REQUIRES_BLOCK_PATTERN, VALID_EXECUTION_FIELDS, WING3_SPINE_SLOTS, CONTEXT_SPINE_INLINE_PATTERN, WING3_SAAS_URL_PATTERN, WING3_VENDOR_BLACKLIST, WING3_STACK_LOCKED_PATTERN, WING3_CHANNEL_TACTIC_PATTERN, WING4_SPINE_SLOTS, WING4_SAAS_URL_PATTERN, WING4_VENDOR_BLACKLIST, WING4_STAGE_AGNOSTIC_PATTERN, Issue, LintResult, _ROLE_CONTRACT_CANDIDATES, _ROLE_CONTRACT_SLUGS_CACHE, _ROLE_CONTRACT_REF_PATTERN, PROCEDURE_HEADING_PATTERN, COMMAND_FRONTMATTER_DELEGATION_KEYS, MD_LINK_PATTERN_G, NAME_PATTERN, DISABLE_MODEL_PATTERN, _INSPECT_VERB_PATTERN, last_changed_scope_reason, last_changed_base_diff_ok, _INTERACTION_NAME_PATTERNS, _INTERACTION_CONTENT_KEYWORDS, _EXEC_FILE_SIGNALS, _EXEC_CONTENT_SIGNALS, _TASK_TYPE_SIGNALS, _VERIFICATION_TOOLS, _FRUGALITY_STANDARDS_PATTERN, _FRUGALITY_CHARTER_LINK_PATTERN, _MD_LINK_PATTERN, _MALICE_CRED_EXFIL, _MALICE_REMOTE_EXEC, _MALICE_FORCE_PUSH, _MALICE_CHMOD_SECRETS, _MALICE_SHELL_INJECT, _MALICE_PATTERNS, _NAG_UPDATE_CHECK, _NAG_STAY_CURRENT, _NAG_SELF_PROMO, _NAG_BEST_SKILL, _NAG_MUST_USE, _NAG_ALWAYS_USE, _NAG_PATTERNS, _OUTPUT_SCHEMA_KEY_PATTERN, _SCHEMA_ARTEFACT_TYPES, ArgError, isCliEntry2;
18015
18028
  var init_skill_linter = __esm({
18016
18029
  "src/scripts/skill_linter.ts"() {
18017
18030
  "use strict";
@@ -18150,6 +18163,8 @@ var init_skill_linter = __esm({
18150
18163
  VALID_EXECUTION_TYPES = /* @__PURE__ */ new Set(["manual", "assisted", "automated"]);
18151
18164
  VALID_EXECUTION_HANDLERS = /* @__PURE__ */ new Set(["none", "shell", "php", "node", "internal"]);
18152
18165
  VALID_EXECUTION_SAFETY_MODES = /* @__PURE__ */ new Set(["strict"]);
18166
+ EXTERNAL_EXECUTION_HANDLERS = /* @__PURE__ */ new Set(["shell", "php", "node"]);
18167
+ RUNTIME_REQUIRES_BLOCK_PATTERN = /^runtime_requires:[ \t]*(\{.*)?$/m;
18153
18168
  VALID_EXECUTION_FIELDS = /* @__PURE__ */ new Set([
18154
18169
  "type",
18155
18170
  "handler",
@@ -19678,6 +19693,15 @@ function archive_completed(root, opts) {
19678
19693
  if (stats.open_ !== 0 || stats.deferred !== 0) {
19679
19694
  continue;
19680
19695
  }
19696
+ const open_blockers = stats.open_blockers;
19697
+ if (open_blockers.length > 0) {
19698
+ const ids = open_blockers.map((b) => b.id).join(", ");
19699
+ process9.stderr.write(
19700
+ ` \u26A0\uFE0F ${stats.rel}: all steps closed but ${open_blockers.length} blocker(s) still open (${ids}) \u2014 not archived. Resolve them, or record the decision, then re-run the sweep.
19701
+ `
19702
+ );
19703
+ continue;
19704
+ }
19681
19705
  const old_rel = `agents/roadmaps/${stats.rel}`;
19682
19706
  if (changed_only && !touched.has(old_rel)) {
19683
19707
  continue;
@@ -21641,8 +21665,8 @@ function lockfile_path(env) {
21641
21665
  }
21642
21666
  return write_target("installed.lock", { env: env ?? null });
21643
21667
  }
21644
- function read_lockfile(path71) {
21645
- const target = path71 ?? lockfile_path();
21668
+ function read_lockfile(path73) {
21669
+ const target = path73 ?? lockfile_path();
21646
21670
  let text;
21647
21671
  try {
21648
21672
  text = fs31.readFileSync(target, { encoding: "utf-8" });
@@ -21852,18 +21876,18 @@ function manifest_path(project_root, env) {
21852
21876
  }
21853
21877
  return fsPath.join(project_root, DEFAULT_MANIFEST_RELATIVE);
21854
21878
  }
21855
- function read_manifest(path71) {
21879
+ function read_manifest(path73) {
21856
21880
  let text;
21857
21881
  try {
21858
- text = require_read_text(path71);
21882
+ text = require_read_text(path73);
21859
21883
  } catch {
21860
21884
  return null;
21861
21885
  }
21862
21886
  const data = _parse_manual(text);
21863
21887
  return _normalise_v2_shape(data);
21864
21888
  }
21865
- function require_read_text(path71) {
21866
- return fs33.readFileSync(path71, { encoding: "utf-8" });
21889
+ function require_read_text(path73) {
21890
+ return fs33.readFileSync(path73, { encoding: "utf-8" });
21867
21891
  }
21868
21892
  function _normalise_v2_shape(data) {
21869
21893
  if (data["tools"] === void 0 || data["tools"] === null) {
@@ -22044,9 +22068,9 @@ function stable_sort(items, key) {
22044
22068
  return a.index - b.index;
22045
22069
  }).map((entry) => entry.item);
22046
22070
  }
22047
- function write_manifest(path71, version, tools, options = {}) {
22071
+ function write_manifest(path73, version, tools, options = {}) {
22048
22072
  const rendered = _render(version, tools, { deploy_roots: options.deploy_roots ?? null });
22049
- return write_atomic(path71, rendered);
22073
+ return write_atomic(path73, rendered);
22050
22074
  }
22051
22075
  function upsert_tool(existing, options) {
22052
22076
  const {
@@ -27842,7 +27866,11 @@ function _build_config(raw, source_path) {
27842
27866
  if (!_isBool(enabled)) {
27843
27867
  throw new CouncilConfigError("`enabled` must be a bool.");
27844
27868
  }
27845
- const defaults = _build_defaults(_asDict(_getOr(raw, "defaults", {})));
27869
+ const ignored_transport_keys = [];
27870
+ const defaults = _build_defaults(
27871
+ _asDict(_getOr(raw, "defaults", {})),
27872
+ ignored_transport_keys
27873
+ );
27846
27874
  const cost_budget = _build_cost_budget(
27847
27875
  _asDict(_getOr(raw, "cost_budget", {}))
27848
27876
  );
@@ -27854,7 +27882,12 @@ function _build_config(raw, source_path) {
27854
27882
  for (const [name, cfg] of Object.entries(members_raw)) {
27855
27883
  members.set(
27856
27884
  name,
27857
- _build_member(name, _asDict(_orEmpty(cfg)), defaults.mode)
27885
+ _build_member(
27886
+ name,
27887
+ _asDict(_orEmpty(cfg)),
27888
+ defaults.mode,
27889
+ ignored_transport_keys
27890
+ )
27858
27891
  );
27859
27892
  }
27860
27893
  const advisors_raw = _getOr(raw, "advisors", {});
@@ -27953,7 +27986,8 @@ function _build_config(raw, source_path) {
27953
27986
  routing,
27954
27987
  low_impact,
27955
27988
  lens_overrides,
27956
- source_path
27989
+ source_path,
27990
+ ignored_transport_keys
27957
27991
  };
27958
27992
  }
27959
27993
  function _orEmpty(value) {
@@ -28406,16 +28440,14 @@ function _build_consensus_scoring(d) {
28406
28440
  lenses: lenses_raw
28407
28441
  };
28408
28442
  }
28409
- function _build_defaults(d) {
28443
+ function _build_defaults(d, ignored = []) {
28410
28444
  if (!_isDict(d)) {
28411
28445
  throw new CouncilConfigError("`defaults` must be a mapping.");
28412
28446
  }
28413
- const mode = _get(d, "mode", "auto");
28414
- if (!(_isStr(mode) && _VALID_MODES.has(mode))) {
28415
- throw new CouncilConfigError(
28416
- `defaults.mode=${_pyRepr6(mode)} not in ${_sortedListRepr(_VALID_MODES)}.`
28417
- );
28447
+ if (_get(d, "mode", null) !== null) {
28448
+ ignored.push("defaults.mode");
28418
28449
  }
28450
+ const mode = "auto";
28419
28451
  const member_mode = _get(d, "member_mode", "cli");
28420
28452
  if (!(_isStr(member_mode) && _VALID_MEMBER_MODES.has(member_mode))) {
28421
28453
  throw new CouncilConfigError(
@@ -28571,7 +28603,7 @@ function _build_cost_budget(d) {
28571
28603
  }
28572
28604
  return cb;
28573
28605
  }
28574
- function _build_member(name, cfg, default_mode = "auto") {
28606
+ function _build_member(name, cfg, default_mode = "auto", ignored = []) {
28575
28607
  if (!_VALID_PROVIDERS.has(name)) {
28576
28608
  throw new CouncilConfigError(
28577
28609
  `members.${name}: unknown provider; valid: ${_sortedListRepr(_VALID_PROVIDERS)}.`
@@ -28582,14 +28614,11 @@ function _build_member(name, cfg, default_mode = "auto") {
28582
28614
  const model = _pyTruthy3(modelVal) ? modelVal : "";
28583
28615
  const api_key_ref_raw = _get(cfg, "api_key_ref", null);
28584
28616
  const api_key_ref = api_key_ref_raw === void 0 ? null : api_key_ref_raw;
28585
- const member_mode_raw = _get(cfg, "mode", null);
28586
- const member_mode = member_mode_raw === void 0 ? null : member_mode_raw;
28587
- if (member_mode !== null && !(_isStr(member_mode) && _VALID_MODES.has(member_mode))) {
28588
- throw new CouncilConfigError(
28589
- `members.${name}.mode=${_pyRepr6(member_mode)} not in ${_sortedListRepr(_VALID_MODES)}.`
28590
- );
28617
+ if (_get(cfg, "mode", null) !== null) {
28618
+ ignored.push(`members.${name}.mode`);
28591
28619
  }
28592
- const effective_mode = member_mode !== null ? member_mode : default_mode;
28620
+ const member_mode = null;
28621
+ const effective_mode = default_mode;
28593
28622
  const binary_raw = _get(cfg, "binary", null);
28594
28623
  const binary = binary_raw === void 0 ? null : binary_raw;
28595
28624
  if (binary !== null) {
@@ -28868,7 +28897,7 @@ function _pyTruthy3(value) {
28868
28897
  }
28869
28898
  return Object.keys(value).length > 0;
28870
28899
  }
28871
- var import_yaml5, _VALID_PROVIDERS, _VALID_MODES, _RAW_KEY_PREFIXES, CouncilConfigError, _Float, _VALID_NECESSITY_MODES, _VALID_DISCLOSURE_MODES, _VALID_CHAIRMAN_MODES, COUNCIL_CONFIG_RELNAME, COUNCIL_CONFIG_USER_GLOBAL_REL, COUNCIL_CONFIG_ENV, _VALID_CRITIC_PROTOCOLS, _VALID_RESOLUTION_MODES, _IMPACT_CLASSES, _LOCKED_IMPACT_CLASSES, _DEFAULT_RESOLUTION_MODES, _VALID_MEMBER_MODES, _VALID_DISPATCH_MODES, _DEFAULT_CLI_CALLS_PER_DAY;
28900
+ var import_yaml5, _VALID_PROVIDERS, _RAW_KEY_PREFIXES, CouncilConfigError, _Float, _VALID_NECESSITY_MODES, _VALID_DISCLOSURE_MODES, _VALID_CHAIRMAN_MODES, COUNCIL_CONFIG_RELNAME, COUNCIL_CONFIG_USER_GLOBAL_REL, COUNCIL_CONFIG_ENV, _VALID_CRITIC_PROTOCOLS, _VALID_RESOLUTION_MODES, _IMPACT_CLASSES, _LOCKED_IMPACT_CLASSES, _DEFAULT_RESOLUTION_MODES, _VALID_MEMBER_MODES, _VALID_DISPATCH_MODES, _DEFAULT_CLI_CALLS_PER_DAY;
28872
28901
  var init_config = __esm({
28873
28902
  "src/scripts/ai_council/config.ts"() {
28874
28903
  "use strict";
@@ -28882,7 +28911,6 @@ var init_config = __esm({
28882
28911
  "xai",
28883
28912
  "perplexity"
28884
28913
  ]);
28885
- _VALID_MODES = /* @__PURE__ */ new Set(["api", "manual", "cli", "auto"]);
28886
28914
  _RAW_KEY_PREFIXES = [
28887
28915
  "sk-",
28888
28916
  "sk-ant-",
@@ -29079,6 +29107,21 @@ function homeOf(env) {
29079
29107
  const injected = (map["HOME"] ?? "").trim();
29080
29108
  return injected !== "" ? injected : os9.homedir();
29081
29109
  }
29110
+ function defaultProbeKeychain(service) {
29111
+ if (process.platform !== "darwin") return false;
29112
+ try {
29113
+ const res = spawnSync8("security", ["find-generic-password", "-s", service], {
29114
+ timeout: VERSION_PROBE_TIMEOUT_MS,
29115
+ encoding: "utf-8",
29116
+ windowsHide: true,
29117
+ env: hardenedSpawnEnv()
29118
+ });
29119
+ if (res.error !== void 0 || res.signal !== null) return false;
29120
+ return res.status === 0;
29121
+ } catch {
29122
+ return false;
29123
+ }
29124
+ }
29082
29125
  function defaultProbeVersion(binary) {
29083
29126
  try {
29084
29127
  const res = spawnSync8(binary, ["--version"], {
@@ -29124,13 +29167,16 @@ function classifyCodexAuth(authPath) {
29124
29167
  if (hasOauth) return "cli-subscription";
29125
29168
  return "cli-api-key";
29126
29169
  }
29127
- function cliSubscriptionEvidence(provider, home, env, claudeConfigDir) {
29170
+ function cliSubscriptionEvidence(provider, home, env, claudeConfigDir, probeKeychain) {
29128
29171
  if (provider === "anthropic") {
29129
29172
  const configDir = claudeConfigDir;
29130
29173
  for (const rel of [".credentials.json", "credentials.json"]) {
29131
29174
  const p = path47.join(configDir, rel);
29132
29175
  if (isFile2(p)) return { source: "cli-subscription", evidence: p };
29133
29176
  }
29177
+ if (probeKeychain(CLAUDE_KEYCHAIN_SERVICE)) {
29178
+ return { source: "cli-subscription", evidence: `keychain:${CLAUDE_KEYCHAIN_SERVICE}` };
29179
+ }
29134
29180
  return null;
29135
29181
  }
29136
29182
  if (provider === "openai") {
@@ -29172,10 +29218,11 @@ function detectAuth(opts) {
29172
29218
  const env = opts.env ?? process.env;
29173
29219
  const home = opts.home ?? homeOf(opts.env);
29174
29220
  const claudeConfigDir = opts.home === void 0 && opts.env === void 0 ? claude_config_dir() : (env["CLAUDE_CONFIG_DIR"] ?? "").trim() || path47.join(home, ".claude");
29221
+ const probeKeychain = opts.probeKeychain ?? defaultProbeKeychain;
29175
29222
  const auth = [];
29176
29223
  const keys = [];
29177
29224
  for (const provider of knownProviders()) {
29178
- const cli = cliSubscriptionEvidence(provider, home, env, claudeConfigDir);
29225
+ const cli = cliSubscriptionEvidence(provider, home, env, claudeConfigDir, probeKeychain);
29179
29226
  if (cli !== null) {
29180
29227
  auth.push({ provider, source: cli.source, evidence: cli.evidence });
29181
29228
  }
@@ -29222,7 +29269,7 @@ function detectEnvironment(opts = {}) {
29222
29269
  if (isDefaultCall) _cached = report2;
29223
29270
  return report2;
29224
29271
  }
29225
- var PROVIDER_CLI_META, PROVIDER_ENV_KEY, PROVIDER_KEY_FILE, VERSION_PROBE_TIMEOUT_MS, _cached;
29272
+ var PROVIDER_CLI_META, PROVIDER_ENV_KEY, PROVIDER_KEY_FILE, VERSION_PROBE_TIMEOUT_MS, CLAUDE_KEYCHAIN_SERVICE, _cached;
29226
29273
  var init_environment_detector = __esm({
29227
29274
  "src/scripts/_lib/environment_detector.ts"() {
29228
29275
  "use strict";
@@ -29253,6 +29300,7 @@ var init_environment_detector = __esm({
29253
29300
  perplexity: "perplexity.key"
29254
29301
  };
29255
29302
  VERSION_PROBE_TIMEOUT_MS = 2e3;
29303
+ CLAUDE_KEYCHAIN_SERVICE = "Claude Code-credentials";
29256
29304
  _cached = null;
29257
29305
  }
29258
29306
  });
@@ -33134,9 +33182,9 @@ function detectToolPresence(root) {
33134
33182
  agentsMd: existsSync25(join49(root, "AGENTS.md"))
33135
33183
  };
33136
33184
  }
33137
- function isDir3(path71) {
33185
+ function isDir3(path73) {
33138
33186
  try {
33139
- return statSync32(path71).isDirectory();
33187
+ return statSync32(path73).isDirectory();
33140
33188
  } catch {
33141
33189
  return false;
33142
33190
  }
@@ -34095,6 +34143,14 @@ function _empty_state() {
34095
34143
  verified_this_turn: false,
34096
34144
  ci_saw_pending: false,
34097
34145
  nonevidence_this_turn: 0,
34146
+ // Round 7 § Phase 1 — the last CI read, SESSION-scoped on purpose. Every
34147
+ // other counter here is turn-scoped because a stale POSITIVE would wrongly
34148
+ // vouch ("I verified"). This one is a NEGATIVE ("CI was not settled"), and a
34149
+ // stale negative only ever refuses more often — so surviving the turn
34150
+ // boundary preserves the freshness invariant rather than bypassing it. It
34151
+ // has to survive it: the measured failure is a completion claim in a LATER
34152
+ // turn than the poll it rests on.
34153
+ ci_last: null,
34098
34154
  checked_at: _now2()
34099
34155
  };
34100
34156
  }
@@ -34207,6 +34263,7 @@ function _update(state, event, envelope) {
34207
34263
  if (session_id && session_id !== state["session_id"]) {
34208
34264
  state["session_id"] = session_id;
34209
34265
  state["verifications_this_session"] = 0;
34266
+ state["ci_last"] = null;
34210
34267
  state = _reset_turn(state, session_id);
34211
34268
  }
34212
34269
  let payload = envelope["payload"];
@@ -34232,6 +34289,12 @@ function _update(state, event, envelope) {
34232
34289
  } else {
34233
34290
  counts = false;
34234
34291
  }
34292
+ state["ci_last"] = {
34293
+ at: _now2(),
34294
+ command: cmd.slice(0, 512),
34295
+ pending,
34296
+ settled: pending === 0 && counts === true
34297
+ };
34235
34298
  }
34236
34299
  state["last_verification"] = {
34237
34300
  command: cmd.slice(0, 512),
@@ -34389,12 +34452,785 @@ var init_before_complete_hook = __esm({
34389
34452
  }
34390
34453
  });
34391
34454
 
34392
- // src/scripts/hooks/evidence_independence.ts
34393
- import crypto7 from "node:crypto";
34394
- import fs57 from "node:fs";
34395
- import path58 from "node:path";
34455
+ // src/scripts/_lib/review_skipped_record.ts
34456
+ function isNonNegInt(n) {
34457
+ return typeof n === "number" && Number.isFinite(n) && Number.isInteger(n) && n >= 0;
34458
+ }
34459
+ function buildReviewSkippedLine(input) {
34460
+ const errors = [];
34461
+ if (!isNonNegInt(input.diff_lines)) {
34462
+ errors.push("diff_lines must be a non-negative integer");
34463
+ }
34464
+ if (input.mutation_measure !== "exact" && input.mutation_measure !== "capped_approximation") {
34465
+ errors.push('mutation_measure must be "exact" or "capped_approximation"');
34466
+ }
34467
+ if (!input.ts) errors.push("ts (ISO-8601 UTC) is required");
34468
+ if (!input.id) errors.push("id (ULID, UUID, or content hash) is required");
34469
+ if (errors.length) return { line: null, errors };
34470
+ const line = {
34471
+ schema_version: 1,
34472
+ id: input.id,
34473
+ ts: input.ts,
34474
+ work_id: input.work_id ?? `review-skipped-${input.ts}`,
34475
+ phase: "report",
34476
+ outcome: "skipped",
34477
+ confidence_band: "medium",
34478
+ risk_class: input.diff_lines >= HIGH_RISK_DIFF_LINES ? "high" : "medium",
34479
+ memory: { asks: 0, hits: 0 },
34480
+ verify: { claims: 0, first_try_passes: 0 },
34481
+ rules_applied: ["delegation-policy"],
34482
+ persona: null,
34483
+ input_kind: "prompt",
34484
+ type: "note",
34485
+ review_skipped: { diff_lines: input.diff_lines, mutation_measure: input.mutation_measure }
34486
+ };
34487
+ return { line, errors: [] };
34488
+ }
34489
+ var HIGH_RISK_DIFF_LINES;
34490
+ var init_review_skipped_record = __esm({
34491
+ "src/scripts/_lib/review_skipped_record.ts"() {
34492
+ "use strict";
34493
+ HIGH_RISK_DIFF_LINES = 200;
34494
+ }
34495
+ });
34496
+
34497
+ // src/scripts/hooks/envelope.ts
34498
+ function _isObject5(obj) {
34499
+ return typeof obj === "object" && obj !== null && !Array.isArray(obj);
34500
+ }
34501
+ function looks_like_envelope(obj) {
34502
+ if (!_isObject5(obj)) {
34503
+ return false;
34504
+ }
34505
+ return ENVELOPE_KEYS.every((key) => key in obj);
34506
+ }
34507
+ function unwrap(stdin_text, default_platform = "generic") {
34508
+ const text = (stdin_text ?? "").trim();
34509
+ if (!text) {
34510
+ return [{}, {}, default_platform];
34511
+ }
34512
+ let decoded;
34513
+ try {
34514
+ decoded = JSON.parse(text);
34515
+ } catch {
34516
+ return [{}, {}, default_platform];
34517
+ }
34518
+ if (looks_like_envelope(decoded)) {
34519
+ const env = decoded;
34520
+ let payload2 = env["payload"];
34521
+ if (!payload2 || !_isObject5(payload2)) {
34522
+ payload2 = {};
34523
+ }
34524
+ const platRaw = env["platform"];
34525
+ const platform = String(platRaw || default_platform);
34526
+ return [env, payload2, platform];
34527
+ }
34528
+ const payload = _isObject5(decoded) ? decoded : {};
34529
+ return [
34530
+ {
34531
+ schema_version: 1,
34532
+ platform: default_platform,
34533
+ event: "",
34534
+ native_event: "",
34535
+ session_id: "",
34536
+ workspace_root: "",
34537
+ payload,
34538
+ settings: {}
34539
+ },
34540
+ payload,
34541
+ default_platform
34542
+ ];
34543
+ }
34544
+ var ENVELOPE_KEYS;
34545
+ var init_envelope = __esm({
34546
+ "src/scripts/hooks/envelope.ts"() {
34547
+ "use strict";
34548
+ ENVELOPE_KEYS = [
34549
+ "schema_version",
34550
+ "platform",
34551
+ "event",
34552
+ "payload"
34553
+ ];
34554
+ }
34555
+ });
34556
+
34557
+ // src/scripts/hooks/end_review_nudge_hook.ts
34558
+ import { spawnSync as spawnSync9 } from "node:child_process";
34559
+ import * as crypto7 from "node:crypto";
34560
+ import * as fs57 from "node:fs";
34561
+ import * as os12 from "node:os";
34562
+ import * as path58 from "node:path";
34396
34563
  import { fileURLToPath as fileURLToPath34, pathToFileURL as pathToFileURL23 } from "node:url";
34397
- function _isObject5(v) {
34564
+ function isSafeTranscriptPath(rawPath, opts = {}) {
34565
+ if (!rawPath || !/\.jsonl$/i.test(rawPath)) return false;
34566
+ const homeDir = opts.homeDir ?? os12.homedir();
34567
+ const maxBytes = opts.maxBytes ?? TRANSCRIPT_SCAN_MAX_BYTES;
34568
+ try {
34569
+ const realHome = fs57.realpathSync(homeDir);
34570
+ const realPath = fs57.realpathSync(rawPath);
34571
+ const relative16 = path58.relative(realHome, realPath);
34572
+ if (relative16 === "" || relative16.startsWith("..") || path58.isAbsolute(relative16)) {
34573
+ return false;
34574
+ }
34575
+ const { size } = fs57.statSync(realPath);
34576
+ return size <= maxBytes;
34577
+ } catch {
34578
+ return false;
34579
+ }
34580
+ }
34581
+ function parseNumstat(raw) {
34582
+ const rows = [];
34583
+ for (const line of raw.split("\n")) {
34584
+ const m = /^(\d+|-)\t(\d+|-)\t(.+)$/.exec(line);
34585
+ if (!m) continue;
34586
+ const addedStr = m[1];
34587
+ const deletedStr = m[2];
34588
+ rows.push({
34589
+ added: addedStr === "-" ? 0 : Number(addedStr),
34590
+ deleted: deletedStr === "-" ? 0 : Number(deletedStr),
34591
+ path: m[3]
34592
+ });
34593
+ }
34594
+ return rows;
34595
+ }
34596
+ function isDocPath(p) {
34597
+ return DOC_PATH_RE.test(p);
34598
+ }
34599
+ function nonDocMutatedLines(rows) {
34600
+ return rows.filter((r) => !isDocPath(r.path)).reduce((sum, r) => sum + r.added + r.deleted, 0);
34601
+ }
34602
+ function gitNumstatRows(cwd) {
34603
+ try {
34604
+ const r = spawnSync9("git", ["diff", "--numstat", "HEAD"], {
34605
+ cwd,
34606
+ encoding: "utf8",
34607
+ maxBuffer: 16 * 1024 * 1024
34608
+ });
34609
+ if (r.status !== 0) return [];
34610
+ return parseNumstat(r.stdout ?? "");
34611
+ } catch {
34612
+ return [];
34613
+ }
34614
+ }
34615
+ function untrackedNonDocFiles(cwd) {
34616
+ try {
34617
+ const r = spawnSync9("git", ["ls-files", "--others", "--exclude-standard"], {
34618
+ cwd,
34619
+ encoding: "utf8",
34620
+ maxBuffer: 16 * 1024 * 1024
34621
+ });
34622
+ if (r.status !== 0) return [];
34623
+ return (r.stdout ?? "").split("\n").map((l) => l.trim()).filter((l) => l.length > 0 && !isDocPath(l));
34624
+ } catch {
34625
+ return [];
34626
+ }
34627
+ }
34628
+ function untrackedFileLineCount(cwd, relPath) {
34629
+ try {
34630
+ const r = spawnSync9("git", ["diff", "--numstat", "--no-index", "/dev/null", relPath], {
34631
+ cwd,
34632
+ encoding: "utf8",
34633
+ maxBuffer: 16 * 1024 * 1024
34634
+ });
34635
+ return parseNumstat(r.stdout ?? "").reduce((sum, row) => sum + row.added + row.deleted, 0);
34636
+ } catch {
34637
+ return 0;
34638
+ }
34639
+ }
34640
+ function totalNonDocMutatedLinesWithMeasure(cwd) {
34641
+ const trackedLines = nonDocMutatedLines(gitNumstatRows(cwd));
34642
+ const untracked = untrackedNonDocFiles(cwd);
34643
+ if (untracked.length > UNTRACKED_FILE_CAP) {
34644
+ return { lines: MUTATION_LINE_THRESHOLD + 1 + trackedLines, measure: "capped_approximation" };
34645
+ }
34646
+ const untrackedLines = untracked.reduce(
34647
+ (sum, relPath) => sum + untrackedFileLineCount(cwd, relPath),
34648
+ 0
34649
+ );
34650
+ return { lines: trackedLines + untrackedLines, measure: "exact" };
34651
+ }
34652
+ function isObject(v) {
34653
+ return typeof v === "object" && v !== null && !Array.isArray(v);
34654
+ }
34655
+ function str(v) {
34656
+ return typeof v === "string" ? v : "";
34657
+ }
34658
+ function scanTranscriptForReviewer(transcriptText) {
34659
+ for (const raw of transcriptText.split("\n")) {
34660
+ const line = raw.trim();
34661
+ if (!line) continue;
34662
+ let obj;
34663
+ try {
34664
+ obj = JSON.parse(line);
34665
+ } catch {
34666
+ continue;
34667
+ }
34668
+ if (!isObject(obj) || obj["type"] !== "assistant") continue;
34669
+ const msg = obj["message"];
34670
+ if (!isObject(msg)) continue;
34671
+ const content = msg["content"];
34672
+ if (!Array.isArray(content)) continue;
34673
+ for (const blk of content) {
34674
+ if (!isObject(blk) || blk["type"] !== "tool_use") continue;
34675
+ const name = str(blk["name"]);
34676
+ const input = blk["input"];
34677
+ const inputObj = isObject(input) ? input : {};
34678
+ if (DISPATCH_TOOL_RE.test(name)) {
34679
+ const label = [
34680
+ str(inputObj["description"]),
34681
+ str(inputObj["subagent_type"])
34682
+ ].filter(Boolean).join(" ");
34683
+ if (REVIEW_SHAPED_LABEL_RE.test(label)) return true;
34684
+ const prompt = str(inputObj["prompt"]);
34685
+ if (REVIEW_SHAPED_PROMPT_RE.test(prompt)) return true;
34686
+ continue;
34687
+ }
34688
+ if (/^skill$/i.test(name)) {
34689
+ const skillName = str(inputObj["skill"]) || str(inputObj["name"]) || str(inputObj["command"]);
34690
+ if (REVIEW_SKILL_NAME_RE.test(skillName)) return true;
34691
+ continue;
34692
+ }
34693
+ if (REVIEW_SKILL_NAME_RE.test(name)) return true;
34694
+ }
34695
+ }
34696
+ return false;
34697
+ }
34698
+ function buildAdvisoryLine(diffLines) {
34699
+ return `this session mutated ${diffLines} lines without a neutral review; spawn a cross-model reviewer before claiming done (delegation-policy / verify-budget)`;
34700
+ }
34701
+ function appendReviewSkippedTelemetry(workspaceRoot, diffLines, mutationMeasure) {
34702
+ if (is_replay_mode()) return;
34703
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
34704
+ const { line, errors } = buildReviewSkippedLine({
34705
+ diff_lines: diffLines,
34706
+ mutation_measure: mutationMeasure,
34707
+ ts,
34708
+ id: crypto7.randomUUID()
34709
+ });
34710
+ if (errors.length || line === null) return;
34711
+ try {
34712
+ const dir = path58.join(workspaceRoot, "agents", "runtime", "state", "audit");
34713
+ fs57.mkdirSync(dir, { recursive: true });
34714
+ const file = path58.join(dir, `${ts.slice(0, 7)}.jsonl`);
34715
+ fs57.appendFileSync(file, `${JSON.stringify(line)}
34716
+ `, "utf8");
34717
+ } catch {
34718
+ }
34719
+ }
34720
+ function sessionStateDir(workspaceRoot) {
34721
+ return path58.join(workspaceRoot, "agents", "runtime", "state", "end-review-nudge");
34722
+ }
34723
+ function sessionStateFile(workspaceRoot, sessionKey) {
34724
+ return path58.join(sessionStateDir(workspaceRoot), `${sessionKey}.json`);
34725
+ }
34726
+ function deriveSessionKey(envelope, payload) {
34727
+ const raw = str(envelope["session_id"]) || str(payload["transcript_path"] ?? payload["transcriptPath"]);
34728
+ const material = raw || "unknown-session";
34729
+ return crypto7.createHash("sha256").update(material).digest("hex");
34730
+ }
34731
+ function hasFiredThisSession(workspaceRoot, sessionKey) {
34732
+ try {
34733
+ return fs57.existsSync(sessionStateFile(workspaceRoot, sessionKey));
34734
+ } catch {
34735
+ return false;
34736
+ }
34737
+ }
34738
+ function markFiredThisSession(workspaceRoot, sessionKey, ts) {
34739
+ try {
34740
+ atomic_write_json(sessionStateFile(workspaceRoot, sessionKey), { fired_at: ts });
34741
+ } catch {
34742
+ }
34743
+ }
34744
+ function _read_stdin() {
34745
+ return readHookStdin();
34746
+ }
34747
+ function main23() {
34748
+ const [envelope, payload] = unwrap(_read_stdin(), "claude");
34749
+ const event = String(envelope["event"] ?? "");
34750
+ if (event !== "" && event !== "stop") {
34751
+ return 0;
34752
+ }
34753
+ const workspace_root = String(envelope["workspace_root"] ?? "").trim() || process.cwd();
34754
+ let diffLines;
34755
+ let mutationMeasure;
34756
+ try {
34757
+ const measured = totalNonDocMutatedLinesWithMeasure(workspace_root);
34758
+ diffLines = measured.lines;
34759
+ mutationMeasure = measured.measure;
34760
+ } catch {
34761
+ return 0;
34762
+ }
34763
+ if (diffLines <= MUTATION_LINE_THRESHOLD) {
34764
+ return 0;
34765
+ }
34766
+ const sessionKey = deriveSessionKey(envelope, payload);
34767
+ if (hasFiredThisSession(workspace_root, sessionKey)) {
34768
+ return 0;
34769
+ }
34770
+ const transcriptPath = str(
34771
+ payload["transcript_path"] ?? payload["transcriptPath"]
34772
+ ).trim();
34773
+ let reviewerRan = false;
34774
+ if (transcriptPath && isSafeTranscriptPath(transcriptPath)) {
34775
+ try {
34776
+ reviewerRan = scanTranscriptForReviewer(fs57.readFileSync(transcriptPath, "utf-8"));
34777
+ } catch {
34778
+ reviewerRan = false;
34779
+ }
34780
+ }
34781
+ if (reviewerRan) {
34782
+ return 0;
34783
+ }
34784
+ markFiredThisSession(workspace_root, sessionKey, (/* @__PURE__ */ new Date()).toISOString());
34785
+ try {
34786
+ appendReviewSkippedTelemetry(workspace_root, diffLines, mutationMeasure);
34787
+ } catch {
34788
+ }
34789
+ process.stdout.write(
34790
+ `${JSON.stringify({
34791
+ decision: "warn",
34792
+ reason: `end-review-nudge: session mutated ${diffLines} non-doc lines without a neutral review`,
34793
+ additional_context: buildAdvisoryLine(diffLines)
34794
+ })}
34795
+ `
34796
+ );
34797
+ return EXIT_WARN2;
34798
+ }
34799
+ function _isCliEntry21() {
34800
+ if (true) {
34801
+ return false;
34802
+ }
34803
+ if (process.argv[1] === void 0) {
34804
+ return false;
34805
+ }
34806
+ const argvUrl = pathToFileURL23(path58.resolve(process.argv[1])).href;
34807
+ if (import.meta.url === argvUrl) {
34808
+ return true;
34809
+ }
34810
+ try {
34811
+ const here = fs57.realpathSync(fileURLToPath34(import.meta.url));
34812
+ const argv = fs57.realpathSync(path58.resolve(process.argv[1]));
34813
+ return here === argv;
34814
+ } catch {
34815
+ return false;
34816
+ }
34817
+ }
34818
+ var MUTATION_LINE_THRESHOLD, UNTRACKED_FILE_CAP, TRANSCRIPT_SCAN_MAX_BYTES, EXIT_WARN2, DOC_PATH_RE, DISPATCH_TOOL_RE, REVIEW_SHAPED_LABEL_RE, REVIEW_SHAPED_PROMPT_RE, REVIEW_SKILL_NAME_RE;
34819
+ var init_end_review_nudge_hook = __esm({
34820
+ "src/scripts/hooks/end_review_nudge_hook.ts"() {
34821
+ "use strict";
34822
+ init_review_skipped_record();
34823
+ init_envelope();
34824
+ init_hook_stdin();
34825
+ init_state_io();
34826
+ MUTATION_LINE_THRESHOLD = 50;
34827
+ UNTRACKED_FILE_CAP = 20;
34828
+ TRANSCRIPT_SCAN_MAX_BYTES = 50 * 1024 * 1024;
34829
+ EXIT_WARN2 = 2;
34830
+ DOC_PATH_RE = /\.md$/i;
34831
+ DISPATCH_TOOL_RE = /^(agent|task)$/i;
34832
+ REVIEW_SHAPED_LABEL_RE = /\b(review|judge|adversarial|critique|second[- ]opinion|blind\s+(pass|review)|cross-model)\b/i;
34833
+ REVIEW_SHAPED_PROMPT_RE = /\b(code\s+review|neutral\s+review|adversarial|judge|critique|second[- ]opinion|blind\s+(pass|review)|cross-model)\b/i;
34834
+ REVIEW_SKILL_NAME_RE = /^(review[-:]changes|judge[-:][a-z0-9-]+|adversarial-review|code-review)$/i;
34835
+ if (_isCliEntry21()) {
34836
+ process.exit(main23());
34837
+ }
34838
+ }
34839
+ });
34840
+
34841
+ // src/scripts/hooks/turn_end_gate_hook.ts
34842
+ import * as crypto8 from "node:crypto";
34843
+ import * as fs58 from "node:fs";
34844
+ import * as path59 from "node:path";
34845
+ import { fileURLToPath as fileURLToPath35, pathToFileURL as pathToFileURL24 } from "node:url";
34846
+ function stripFencedBlocks(text) {
34847
+ const out = [];
34848
+ let open = null;
34849
+ for (const line of text.split("\n")) {
34850
+ const m = /^[ \t]{0,3}([`~]{3,})(.*)$/.exec(line);
34851
+ if (open === null) {
34852
+ if (m) {
34853
+ open = { ch: m[1][0], len: m[1].length };
34854
+ out.push(" ");
34855
+ continue;
34856
+ }
34857
+ out.push(line);
34858
+ continue;
34859
+ }
34860
+ if (m && m[1][0] === open.ch && m[1].length >= open.len && (m[2] ?? "").trim() === "") {
34861
+ open = null;
34862
+ }
34863
+ }
34864
+ return out.join("\n");
34865
+ }
34866
+ function visibleProse(reply) {
34867
+ let text = stripFencedBlocks(reply);
34868
+ text = text.replace(/`[^`\n]*`/g, " ");
34869
+ text = text.replace(/^[ \t]*>.*$/gm, " ");
34870
+ text = text.replace(/^[ \t]*\|.*\|[ \t]*$/gm, " ");
34871
+ text = text.replace(/\bhttps?:\/\/\S+/g, " ");
34872
+ text = text.replace(/\S*\/\S+/g, " ");
34873
+ text = text.replace(/\b[\w.-]+\.(ts|js|md|json|ya?ml|py|php|txt|sh)\b/g, " ");
34874
+ return text;
34875
+ }
34876
+ function finalParagraph(reply) {
34877
+ const prose = visibleProse(reply).trim();
34878
+ if (!prose) return "";
34879
+ const paragraphs = prose.split(/\n\s*\n/).map((p) => p.trim()).filter((p) => p.length > 0);
34880
+ return paragraphs.length === 0 ? "" : paragraphs[paragraphs.length - 1];
34881
+ }
34882
+ function detectPromissory(reply) {
34883
+ const tail = finalParagraph(reply);
34884
+ if (!tail) return null;
34885
+ if (/\?["'’)\]]*\s*$/.test(tail)) return null;
34886
+ if (HANDBACK.some((re) => re.test(tail))) return null;
34887
+ for (const re of PROMISSORY) {
34888
+ const m = tail.match(re);
34889
+ if (m) {
34890
+ return {
34891
+ detector: "promissory",
34892
+ evidence: m[0],
34893
+ reason: "the closing paragraph promises work that has not been performed, and the turn asks the user nothing \u2014 so nothing ends this turn but the promise itself"
34894
+ };
34895
+ }
34896
+ }
34897
+ return null;
34898
+ }
34899
+ function readCiSettled(workspaceRoot) {
34900
+ try {
34901
+ const raw = fs58.readFileSync(path59.join(workspaceRoot, STATE_FILE3), "utf-8");
34902
+ const decoded = JSON.parse(raw);
34903
+ if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
34904
+ const ci = decoded["ci_last"];
34905
+ if (typeof ci === "object" && ci !== null && !Array.isArray(ci)) {
34906
+ return { seen: true, settled: ci["settled"] === true };
34907
+ }
34908
+ }
34909
+ } catch {
34910
+ }
34911
+ return { seen: false, settled: false };
34912
+ }
34913
+ function detectCompletionClaim(reply, ci) {
34914
+ if (!ci.seen || ci.settled) return null;
34915
+ const prose = visibleProse(reply);
34916
+ const m = _COMPLETION_RE.exec(prose);
34917
+ if (!m) return null;
34918
+ const at = m.index;
34919
+ return {
34920
+ detector: "completion",
34921
+ evidence: prose.slice(at, at + 120).trim(),
34922
+ reason: "a completion claim while the last CI read was not settled \u2014 read the verdict, then claim it (verify-before-complete)"
34923
+ };
34924
+ }
34925
+ function readLanguagePin(workspaceRoot) {
34926
+ try {
34927
+ const raw = fs58.readFileSync(path59.join(workspaceRoot, STATE_FILE), "utf-8");
34928
+ const decoded = JSON.parse(raw);
34929
+ if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
34930
+ const lang = decoded["language"];
34931
+ if (lang === "de" || lang === "en") return lang;
34932
+ }
34933
+ } catch {
34934
+ }
34935
+ return "und";
34936
+ }
34937
+ function detectLanguage(reply, pinned) {
34938
+ if (pinned !== "de" && pinned !== "en") return null;
34939
+ const prose = visibleProse(reply);
34940
+ const verdict = classify(prose);
34941
+ if (verdict.language === "und") return null;
34942
+ if (verdict.language === pinned) return null;
34943
+ return {
34944
+ detector: "language",
34945
+ evidence: prose.trim().slice(0, 120),
34946
+ reason: `the pinned reply language is "${pinned}" but the reply classifies as "${verdict.language}" (${verdict.de_markers} de / ${verdict.en_markers} en markers; code, quotes, tables, URLs and paths excluded, then scored lead-first by the same classifier that sets the pin)`
34947
+ };
34948
+ }
34949
+ function isVerificationCommand(command) {
34950
+ return _VERIFY_RE.test(command);
34951
+ }
34952
+ function detectUnverifiedEdit(toolCalls) {
34953
+ let lastEdit = -1;
34954
+ for (let i = 0; i < toolCalls.length; i += 1) {
34955
+ if (_EDIT_TOOLS.has(toolCalls[i].name)) lastEdit = i;
34956
+ }
34957
+ if (lastEdit === -1) return null;
34958
+ for (let i = lastEdit + 1; i < toolCalls.length; i += 1) {
34959
+ const c = toolCalls[i];
34960
+ if (c.name === "Bash" && c.command !== void 0 && isVerificationCommand(c.command)) {
34961
+ return null;
34962
+ }
34963
+ }
34964
+ const edited = toolCalls[lastEdit].path;
34965
+ return {
34966
+ detector: "verification",
34967
+ // The path, never the diff: the evidence span is quoted into a refusal,
34968
+ // and `ToolCall` is shaped so a file body cannot reach it.
34969
+ evidence: edited ?? toolCalls[lastEdit].name,
34970
+ reason: "this turn changed a file and then ran no verification command \u2014 no test, type-check, lint or build call follows the last edit (verify-before-complete: a claim without a fresh run is unverified)"
34971
+ };
34972
+ }
34973
+ function stateDir(workspaceRoot) {
34974
+ return path59.join(workspaceRoot, "agents", "runtime", "state", "turn-end-gate");
34975
+ }
34976
+ function sessionStateFile2(workspaceRoot, sessionKey) {
34977
+ return path59.join(stateDir(workspaceRoot), `${sessionKey}.json`);
34978
+ }
34979
+ function deriveSessionKey2(sessionId) {
34980
+ return crypto8.createHash("sha256").update(sessionId).digest("hex").slice(0, 32);
34981
+ }
34982
+ function alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal) {
34983
+ try {
34984
+ const raw = fs58.readFileSync(sessionStateFile2(workspaceRoot, sessionKey), "utf-8");
34985
+ const decoded = JSON.parse(raw);
34986
+ if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
34987
+ return decoded["refused_turn"] === turnOrdinal;
34988
+ }
34989
+ } catch {
34990
+ }
34991
+ return false;
34992
+ }
34993
+ function markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, detector) {
34994
+ if (is_replay_mode()) return;
34995
+ try {
34996
+ atomic_write_json(sessionStateFile2(workspaceRoot, sessionKey), {
34997
+ refused_at: (/* @__PURE__ */ new Date()).toISOString(),
34998
+ refused_turn: turnOrdinal,
34999
+ detector
35000
+ });
35001
+ } catch {
35002
+ }
35003
+ }
35004
+ function readTranscriptTail(transcriptPath, opts = {}) {
35005
+ const empty = { lastAssistant: "", turnOrdinal: 0, toolCalls: [] };
35006
+ if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
35007
+ let lines;
35008
+ try {
35009
+ if (opts.maxBytes !== void 0 && fs58.statSync(transcriptPath).size > opts.maxBytes) {
35010
+ return empty;
35011
+ }
35012
+ lines = fs58.readFileSync(transcriptPath, "utf-8").split("\n");
35013
+ } catch {
35014
+ return empty;
35015
+ }
35016
+ let lastAssistant = "";
35017
+ let turnOrdinal = 0;
35018
+ let toolCalls = [];
35019
+ for (const rawLine of lines) {
35020
+ const line = rawLine.trim();
35021
+ if (!line) continue;
35022
+ let obj;
35023
+ try {
35024
+ obj = JSON.parse(line);
35025
+ } catch {
35026
+ continue;
35027
+ }
35028
+ if (typeof obj !== "object" || obj === null || Array.isArray(obj)) continue;
35029
+ const entry = obj;
35030
+ if (entry["isSidechain"] === true) continue;
35031
+ const role = entry["type"];
35032
+ if (role !== "assistant" && role !== "user") continue;
35033
+ const msg = entry["message"];
35034
+ if (typeof msg !== "object" || msg === null || Array.isArray(msg)) continue;
35035
+ const content = msg["content"];
35036
+ if (role === "assistant") {
35037
+ toolCalls.push(..._toolCalls(content));
35038
+ }
35039
+ const text = _messageText(content);
35040
+ if (text === null) continue;
35041
+ if (role === "assistant") {
35042
+ lastAssistant = text;
35043
+ } else if (!isSyntheticPrompt(text)) {
35044
+ turnOrdinal += 1;
35045
+ toolCalls = [];
35046
+ }
35047
+ }
35048
+ return { lastAssistant: lastAssistant.trim(), turnOrdinal, toolCalls };
35049
+ }
35050
+ function _toolCalls(content) {
35051
+ if (!Array.isArray(content)) return [];
35052
+ const out = [];
35053
+ for (const blk of content) {
35054
+ if (typeof blk !== "object" || blk === null || Array.isArray(blk)) continue;
35055
+ const b = blk;
35056
+ if (b["type"] !== "tool_use") continue;
35057
+ const name = b["name"];
35058
+ if (typeof name !== "string") continue;
35059
+ const input = b["input"];
35060
+ const call = { name };
35061
+ if (typeof input === "object" && input !== null && !Array.isArray(input)) {
35062
+ const inp = input;
35063
+ const cmd = inp["command"];
35064
+ if (typeof cmd === "string") call.command = cmd;
35065
+ const p = inp["file_path"] ?? inp["path"] ?? inp["notebook_path"];
35066
+ if (typeof p === "string") call.path = p;
35067
+ }
35068
+ out.push(call);
35069
+ }
35070
+ return out;
35071
+ }
35072
+ function _messageText(content) {
35073
+ if (typeof content === "string") return content;
35074
+ if (!Array.isArray(content)) return null;
35075
+ const parts = [];
35076
+ for (const blk of content) {
35077
+ if (typeof blk !== "object" || blk === null || Array.isArray(blk)) continue;
35078
+ const b = blk;
35079
+ if (b["type"] !== "text") continue;
35080
+ const t = b["text"];
35081
+ if (typeof t === "string") parts.push(t);
35082
+ }
35083
+ return parts.length > 0 ? parts.join("\n") : null;
35084
+ }
35085
+ function str2(v) {
35086
+ return typeof v === "string" ? v : "";
35087
+ }
35088
+ function main24() {
35089
+ let envelope;
35090
+ let payload;
35091
+ try {
35092
+ [envelope, payload] = unwrap(readHookStdin(), "claude");
35093
+ } catch {
35094
+ return EXIT_ALLOW4;
35095
+ }
35096
+ if (payload["stop_hook_active"] === true) return EXIT_ALLOW4;
35097
+ const workspaceRoot = str2(envelope["workspace_root"]) || process.cwd();
35098
+ const transcriptPath = str2(
35099
+ payload["transcript_path"] ?? payload["transcriptPath"]
35100
+ );
35101
+ const { lastAssistant, turnOrdinal, toolCalls } = readTranscriptTail(transcriptPath, {
35102
+ maxBytes: TRANSCRIPT_READ_MAX_BYTES
35103
+ });
35104
+ if (!lastAssistant) return EXIT_ALLOW4;
35105
+ const sessionKey = deriveSessionKey2(
35106
+ str2(envelope["session_id"]) || "unknown-session"
35107
+ );
35108
+ if (alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal)) return EXIT_ALLOW4;
35109
+ const findings = [];
35110
+ for (const f of [
35111
+ detectPromissory(lastAssistant),
35112
+ detectLanguage(lastAssistant, readLanguagePin(workspaceRoot)),
35113
+ detectUnverifiedEdit(toolCalls),
35114
+ // Round 7 § Phase 1 — detector D, in the same unconditional list as the
35115
+ // other three. It shipped with its own settings flag one commit earlier
35116
+ // and that flag is gone: `hooks.turn_end_gate.*` was deleted on
35117
+ // 2026-08-12 because a default-off safety gate is an absent one. Its
35118
+ // gating is where the comment above says gating belongs — inside the
35119
+ // detector: no CI observed, or a settled read, or no completion claim
35120
+ // ⇒ no finding.
35121
+ detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot))
35122
+ ]) {
35123
+ if (f) findings.push(f);
35124
+ }
35125
+ if (findings.length === 0) return EXIT_ALLOW4;
35126
+ markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, findings[0].detector);
35127
+ const lines = findings.map(
35128
+ (f) => ` \xB7 ${f.detector}: ${f.reason}
35129
+ evidence: ${JSON.stringify(f.evidence)}`
35130
+ );
35131
+ process.stderr.write(
35132
+ `turn-end-gate: REFUSED \u2014 this turn is not finished.
35133
+ ${lines.join("\n")}
35134
+ Do the promised work now, correct the language, run the verification the edit needs, or read the CI verdict before claiming it \u2014 then end the turn.
35135
+ This turn will not be refused a second time.
35136
+ `
35137
+ );
35138
+ return EXIT_BLOCK2;
35139
+ }
35140
+ function _isCliEntry22() {
35141
+ if (true) {
35142
+ return false;
35143
+ }
35144
+ if (process.argv[1] === void 0) {
35145
+ return false;
35146
+ }
35147
+ const argvUrl = pathToFileURL24(path59.resolve(process.argv[1])).href;
35148
+ if (import.meta.url === argvUrl) {
35149
+ return true;
35150
+ }
35151
+ try {
35152
+ const here = fs58.realpathSync(fileURLToPath35(import.meta.url));
35153
+ const argv = fs58.realpathSync(path59.resolve(process.argv[1]));
35154
+ return here === argv;
35155
+ } catch {
35156
+ return false;
35157
+ }
35158
+ }
35159
+ var EXIT_BLOCK2, EXIT_ALLOW4, TRANSCRIPT_READ_MAX_BYTES, PROMISSORY, HANDBACK, _COMPLETION_RE, _EDIT_TOOLS, _VERIFY_RE;
35160
+ var init_turn_end_gate_hook = __esm({
35161
+ "src/scripts/hooks/turn_end_gate_hook.ts"() {
35162
+ "use strict";
35163
+ init_language_mirror_hook();
35164
+ init_before_complete_hook();
35165
+ init_end_review_nudge_hook();
35166
+ init_envelope();
35167
+ init_hook_stdin();
35168
+ init_state_io();
35169
+ EXIT_BLOCK2 = 1;
35170
+ EXIT_ALLOW4 = 0;
35171
+ TRANSCRIPT_READ_MAX_BYTES = 8 * 1024 * 1024;
35172
+ PROMISSORY = [
35173
+ /\bich melde mich\b/i,
35174
+ /\bmelde ich (mich|dir|Dir)\b/i,
35175
+ /\bich melde\b/i,
35176
+ /\bich berichte\b/i,
35177
+ /\bich (sage|gebe) (dir |Dir )?Bescheid\b/i,
35178
+ /\bals n(ä|ae)chstes (werde|mache|baue|pr(ü|ue)fe) ich\b/i,
35179
+ // German puts the infinitive at the END of the clause ("ich werde jetzt
35180
+ // die Tests schreiben"), so the verb cannot be matched adjacent to
35181
+ // "werde" — it has to be looked for across the rest of the sentence.
35182
+ //
35183
+ // The lookahead excludes a stated REFUSAL to act: declining to do
35184
+ // something is not a promise to do it. R2 finding 4 reproduced four live
35185
+ // false refusals against the old `\bnicht\b`-only version — "Ich werde
35186
+ // nichts anfassen" (no word boundary after `nicht`), "keine Tests
35187
+ // schreiben", "niemals raten", and the passive non-promise "Ich werde
35188
+ // gefragt, ob …". Each was a false refusal on a BLOCKING guard, which is
35189
+ // the precision failure the council warning is about.
35190
+ // `\p{L}` with the `u` flag, NOT `\w`: R2 round 2, finding 15 verified that
35191
+ // `\b\w{3,}en\b` cannot reach an infinitive whose post-umlaut fragment is
35192
+ // short, because `ü`/`ö`/`ä` are not `\w` and create a word boundary — so
35193
+ // "prüfen" and "lösen" were silent while the comment above claimed the
35194
+ // verb-final construction was handled.
35195
+ //
35196
+ // Honest about what this proxy matches: any word of 3+ letters ending in
35197
+ // "en" within the clause, which is the infinitive in practice but also hits
35198
+ // a plural noun ("die Zeilen zählen" matches on "Zeilen"). That is
35199
+ // acceptable here — the clause already requires "ich werde" and excludes
35200
+ // negations and passives, so a forward commitment is what remains — but it
35201
+ // is a proxy for the infinitive, not a parse of one.
35202
+ new RegExp("\\bich werde\\b(?![^.!?\\n]*\\b(?:nicht|nichts|kein(?:e|en|em|er|es)?|niemals|nie)\\b)(?![^.!?\\n]*\\b(?:gefragt|gebeten|informiert|benachrichtigt)\\b)[^.!?\\n]*(?<!\\p{L})\\p{L}{3,}en(?!\\p{L})", "iu"),
35203
+ /\bI(?:'| wi)ll (report|let you know|update you|follow up)\b/i,
35204
+ /\bI(?:'| wi)ll (now |then )?\w+ (it|that|this|next)\b/i,
35205
+ /\bnext,? I(?:'| wi)ll\b/i,
35206
+ /\bI am going to\b/i
35207
+ ];
35208
+ HANDBACK = [
35209
+ /\bdas entscheidest (du|Du)\b/i,
35210
+ /\bdeine Entscheidung\b/i,
35211
+ /\bich fasse .{0,40}nicht ungefragt an\b/i,
35212
+ /\bsag (Bescheid|ein Wort)\b/i,
35213
+ /\bwarte auf (deine|Deine|dein|Dein)\b/i,
35214
+ /\byour call\b/i,
35215
+ /\byou decide\b/i,
35216
+ /\blet me know (which|if|whether)\b/i,
35217
+ /\bwaiting for your\b/i
35218
+ ];
35219
+ _COMPLETION_RE = /(^|\n)\s*(?:\*\*)?(?:fertig\b|damit ist alles erledigt|aufgabe erledigt|alles erledigt\b|komplett(?:er)? (?:auftrag|abgearbeitet)|der komplette auftrag ist durch|done[.!]|all done\b|task complete)/i;
35220
+ _EDIT_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
35221
+ _VERIFY_RE = /\b(test|tests|vitest|jest|pytest|phpunit|pest|tsc|eslint|ruff|mypy|pyright|clippy|typecheck|lint|build|ci|preflight|smoke[-_:a-z]*|check[-_:a-z]*|validate[-_:a-z]*)\b|\b(task|npm|pnpm|yarn|composer|cargo|go|make|php artisan|bun)\s+(run\s+)?\S*(test|check|lint|build|ci|typecheck)/i;
35222
+ if (_isCliEntry22()) {
35223
+ process.exit(main24());
35224
+ }
35225
+ }
35226
+ });
35227
+
35228
+ // src/scripts/hooks/evidence_independence.ts
35229
+ import crypto9 from "node:crypto";
35230
+ import fs59 from "node:fs";
35231
+ import path60 from "node:path";
35232
+ import { fileURLToPath as fileURLToPath36, pathToFileURL as pathToFileURL25 } from "node:url";
35233
+ function _isObject6(v) {
34398
35234
  return typeof v === "object" && v !== null && !Array.isArray(v);
34399
35235
  }
34400
35236
  function isDispatchTool(tool) {
@@ -34416,10 +35252,10 @@ function preloadedVerdict(prompt) {
34416
35252
  return null;
34417
35253
  }
34418
35254
  function extractDispatch(envelope) {
34419
- const payload = _isObject5(envelope["payload"]) ? envelope["payload"] : envelope;
35255
+ const payload = _isObject6(envelope["payload"]) ? envelope["payload"] : envelope;
34420
35256
  const toolRaw = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
34421
35257
  const tool = typeof toolRaw === "string" ? toolRaw : null;
34422
- const input = _isObject5(payload["tool_input"]) ? payload["tool_input"] : _isObject5(payload["toolInput"]) ? payload["toolInput"] : payload;
35258
+ const input = _isObject6(payload["tool_input"]) ? payload["tool_input"] : _isObject6(payload["toolInput"]) ? payload["toolInput"] : payload;
34423
35259
  for (const key of ["prompt", "instructions", "task", "description"]) {
34424
35260
  const v = input[key];
34425
35261
  if (typeof v === "string" && v.trim()) {
@@ -34430,8 +35266,8 @@ function extractDispatch(envelope) {
34430
35266
  }
34431
35267
  function _ledgerStamp(consumer_root) {
34432
35268
  try {
34433
- const raw = fs57.readFileSync(
34434
- path58.join(consumer_root, "agents", "state", "git-authorization.json"),
35269
+ const raw = fs59.readFileSync(
35270
+ path60.join(consumer_root, "agents", "state", "git-authorization.json"),
34435
35271
  "utf8"
34436
35272
  );
34437
35273
  const d = JSON.parse(raw);
@@ -34442,8 +35278,8 @@ function _ledgerStamp(consumer_root) {
34442
35278
  }
34443
35279
  function _load2(target) {
34444
35280
  try {
34445
- const decoded = JSON.parse(fs57.readFileSync(target, "utf8"));
34446
- if (_isObject5(decoded) && Array.isArray(decoded["evaluations"])) {
35281
+ const decoded = JSON.parse(fs59.readFileSync(target, "utf8"));
35282
+ if (_isObject6(decoded) && Array.isArray(decoded["evaluations"])) {
34447
35283
  return decoded;
34448
35284
  }
34449
35285
  } catch {
@@ -34452,12 +35288,12 @@ function _load2(target) {
34452
35288
  }
34453
35289
  function decide2(tool, prompt, priorEvaluations) {
34454
35290
  if (!isDispatchTool(tool) || !isEvaluationPrompt(prompt)) {
34455
- return { exit: EXIT_ALLOW4, stdout: "", stderr: "", evaluations: priorEvaluations };
35291
+ return { exit: EXIT_ALLOW5, stdout: "", stderr: "", evaluations: priorEvaluations };
34456
35292
  }
34457
35293
  const preloaded = preloadedVerdict(prompt);
34458
35294
  if (preloaded !== null) {
34459
35295
  return {
34460
- exit: EXIT_BLOCK2,
35296
+ exit: EXIT_BLOCK3,
34461
35297
  stdout: "",
34462
35298
  stderr: `Blocked: this evaluation prompt pre-loads its verdict ("${preloaded}"). That is the construct that produced a fabricated NO-FINDINGS committed as binding gate evidence, over a delta an unsteered pass then found a live critical in. Remove the expectation from the prompt and let the evaluator reach its own verdict.
34463
35299
  `,
@@ -34465,11 +35301,11 @@ function decide2(tool, prompt, priorEvaluations) {
34465
35301
  };
34466
35302
  }
34467
35303
  if (!isSelfScoped(prompt)) {
34468
- return { exit: EXIT_ALLOW4, stdout: "", stderr: "", evaluations: priorEvaluations };
35304
+ return { exit: EXIT_ALLOW5, stdout: "", stderr: "", evaluations: priorEvaluations };
34469
35305
  }
34470
35306
  if (priorEvaluations >= 1) {
34471
35307
  return {
34472
- exit: EXIT_BLOCK2,
35308
+ exit: EXIT_BLOCK3,
34473
35309
  stdout: "",
34474
35310
  stderr: `Blocked: second evaluation dispatch of your own work in this turn (verdict shopping). One evaluation has already run; commissioning another with a different prompt or scope selects the answer instead of measuring it. Report what the first pass returned, then re-plan.
34475
35311
  `,
@@ -34477,7 +35313,7 @@ function decide2(tool, prompt, priorEvaluations) {
34477
35313
  };
34478
35314
  }
34479
35315
  return {
34480
- exit: EXIT_ALLOW4,
35316
+ exit: EXIT_ALLOW5,
34481
35317
  stdout: `${JSON.stringify({ decision: "warn", reason: WARN_TEXT })}
34482
35318
  `,
34483
35319
  stderr: "",
@@ -34489,14 +35325,14 @@ function run5(stdin_text, options) {
34489
35325
  if (stdin_text.trim()) {
34490
35326
  try {
34491
35327
  const decoded = JSON.parse(stdin_text);
34492
- if (_isObject5(decoded)) {
35328
+ if (_isObject6(decoded)) {
34493
35329
  envelope = decoded;
34494
35330
  }
34495
35331
  } catch {
34496
- return EXIT_ALLOW4;
35332
+ return EXIT_ALLOW5;
34497
35333
  }
34498
35334
  }
34499
- const target = path58.join(options.consumer_root, STATE_FILE4);
35335
+ const target = path60.join(options.consumer_root, STATE_FILE4);
34500
35336
  const state = _load2(target);
34501
35337
  const session_id = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
34502
35338
  const turnMarker = `${session_id}:${_ledgerStamp(options.consumer_root)}`;
@@ -34510,7 +35346,7 @@ function run5(stdin_text, options) {
34510
35346
  if (decision.evaluations > state.evaluations.length) {
34511
35347
  state.evaluations.push({
34512
35348
  at: (/* @__PURE__ */ new Date()).toISOString(),
34513
- digest: crypto7.createHash("sha256").update(prompt).digest("hex").slice(0, 16),
35349
+ digest: crypto9.createHash("sha256").update(prompt).digest("hex").slice(0, 16),
34514
35350
  prompt_chars: prompt.length
34515
35351
  });
34516
35352
  try {
@@ -34526,7 +35362,7 @@ function run5(stdin_text, options) {
34526
35362
  }
34527
35363
  return decision.exit;
34528
35364
  }
34529
- function main23(argv) {
35365
+ function main25(argv) {
34530
35366
  const args = argv ?? process.argv.slice(2);
34531
35367
  let consumer_root = process.cwd();
34532
35368
  for (let i = 0; i < args.length; i += 1) {
@@ -34540,34 +35376,34 @@ function main23(argv) {
34540
35376
  }
34541
35377
  return run5(readHookStdin(), { consumer_root });
34542
35378
  }
34543
- function _isCliEntry21() {
35379
+ function _isCliEntry23() {
34544
35380
  if (true) {
34545
35381
  return false;
34546
35382
  }
34547
35383
  if (process.argv[1] === void 0) {
34548
35384
  return false;
34549
35385
  }
34550
- const argvUrl = pathToFileURL23(path58.resolve(process.argv[1])).href;
35386
+ const argvUrl = pathToFileURL25(path60.resolve(process.argv[1])).href;
34551
35387
  if (import.meta.url === argvUrl) {
34552
35388
  return true;
34553
35389
  }
34554
35390
  try {
34555
- const here = fs57.realpathSync(fileURLToPath34(import.meta.url));
34556
- const argv = fs57.realpathSync(path58.resolve(process.argv[1]));
35391
+ const here = fs59.realpathSync(fileURLToPath36(import.meta.url));
35392
+ const argv = fs59.realpathSync(path60.resolve(process.argv[1]));
34557
35393
  return here === argv;
34558
35394
  } catch {
34559
35395
  return false;
34560
35396
  }
34561
35397
  }
34562
- var EXIT_ALLOW4, EXIT_BLOCK2, STATE_FILE4, DISPATCH_TOOLS, EVALUATION_RE, PRELOADED_VERDICT_RE, SELF_SCOPE_RE, WARN_TEXT;
35398
+ var EXIT_ALLOW5, EXIT_BLOCK3, STATE_FILE4, DISPATCH_TOOLS, EVALUATION_RE, PRELOADED_VERDICT_RE, SELF_SCOPE_RE, WARN_TEXT;
34563
35399
  var init_evidence_independence = __esm({
34564
35400
  "src/scripts/hooks/evidence_independence.ts"() {
34565
35401
  "use strict";
34566
35402
  init_state_io();
34567
35403
  init_hook_stdin();
34568
- EXIT_ALLOW4 = 0;
34569
- EXIT_BLOCK2 = 1;
34570
- STATE_FILE4 = path58.join("agents", "state", "evidence-dispatch.json");
35404
+ EXIT_ALLOW5 = 0;
35405
+ EXIT_BLOCK3 = 1;
35406
+ STATE_FILE4 = path60.join("agents", "state", "evidence-dispatch.json");
34571
35407
  DISPATCH_TOOLS = /* @__PURE__ */ new Set([
34572
35408
  "Agent",
34573
35409
  "Task",
@@ -34600,19 +35436,36 @@ var init_evidence_independence = __esm({
34600
35436
  ];
34601
35437
  SELF_SCOPE_RE = /\b(my (work|change|diff|implementation|code|fix|patch|branch|pr)|this (diff|change|branch|pr|delta|implementation|patch)|the delta|the change i|what i (wrote|built|changed|implemented)|i just (wrote|built|changed|implemented))\b/i;
34602
35438
  WARN_TEXT = "First evaluation dispatch this turn. Two shapes fabricated a binding honest-null in the audited sessions \u2014 check your prompt for both before it goes out: (1) a verdict pre-loaded into the prompt, and (2) a scope narrowed to files you chose. A review you commissioned on your own work is admissible as gate evidence only when the prompt is recorded alongside the verdict.";
34603
- if (_isCliEntry21()) {
34604
- process.exit(main23());
35439
+ if (_isCliEntry23()) {
35440
+ process.exit(main25());
34605
35441
  }
34606
35442
  }
34607
35443
  });
34608
35444
 
34609
35445
  // src/scripts/conformance_scan.ts
34610
- import { createHash as createHash8 } from "node:crypto";
34611
- import fs58 from "node:fs";
34612
- import os12 from "node:os";
34613
- import path59 from "node:path";
34614
- import { fileURLToPath as fileURLToPath35, pathToFileURL as pathToFileURL24 } from "node:url";
34615
- function bandVerdict(rate_pct, assistant_turns) {
35446
+ import { createHash as createHash10 } from "node:crypto";
35447
+ import fs60 from "node:fs";
35448
+ import os13 from "node:os";
35449
+ import path61 from "node:path";
35450
+ import { fileURLToPath as fileURLToPath37, pathToFileURL as pathToFileURL26 } from "node:url";
35451
+ function spansCarrierChange(firstAts) {
35452
+ const stamps = firstAts.filter((s) => s !== "").sort();
35453
+ if (stamps.length === 0) {
35454
+ return { spans: false, what: "" };
35455
+ }
35456
+ const lo = stamps[0];
35457
+ const hi = stamps[stamps.length - 1];
35458
+ for (const c of CARRIER_CHANGES) {
35459
+ if (lo < c.at && hi >= c.at) {
35460
+ return { spans: true, what: c.what };
35461
+ }
35462
+ }
35463
+ return { spans: false, what: "" };
35464
+ }
35465
+ function bandVerdict(rate_pct, assistant_turns, opts = {}) {
35466
+ if (opts.spansCarrier === true) {
35467
+ return "era-spanning";
35468
+ }
34616
35469
  if (assistant_turns < BAND_MIN_TURNS) {
34617
35470
  return "corpus-too-small";
34618
35471
  }
@@ -34646,7 +35499,7 @@ function renderWhy(report2, id) {
34646
35499
  }
34647
35500
  return lines.join("\n");
34648
35501
  }
34649
- function _isObject6(v) {
35502
+ function _isObject7(v) {
34650
35503
  return typeof v === "object" && v !== null && !Array.isArray(v);
34651
35504
  }
34652
35505
  function userText(entry) {
@@ -34670,15 +35523,15 @@ function assistantText(entry) {
34670
35523
  }
34671
35524
  function toolUses2(entry) {
34672
35525
  const msg = entry["message"];
34673
- const content = _isObject6(msg) ? msg["content"] : void 0;
35526
+ const content = _isObject7(msg) ? msg["content"] : void 0;
34674
35527
  if (!Array.isArray(content)) {
34675
35528
  return [];
34676
35529
  }
34677
- return content.filter((b) => _isObject6(b) && b["type"] === "tool_use").map((b) => {
35530
+ return content.filter((b) => _isObject7(b) && b["type"] === "tool_use").map((b) => {
34678
35531
  const o = b;
34679
35532
  return {
34680
35533
  name: String(o["name"] ?? ""),
34681
- input: _isObject6(o["input"]) ? o["input"] : {}
35534
+ input: _isObject7(o["input"]) ? o["input"] : {}
34682
35535
  };
34683
35536
  });
34684
35537
  }
@@ -34693,7 +35546,9 @@ function scanSession(sessionId, lines) {
34693
35546
  session: sessionId,
34694
35547
  user_turns: 0,
34695
35548
  assistant_turns: 0,
34696
- violations: []
35549
+ violations: [],
35550
+ de_pin_turns: 0,
35551
+ first_at: ""
34697
35552
  };
34698
35553
  let pinned = null;
34699
35554
  let pendingPoll = null;
@@ -34702,6 +35557,8 @@ function scanSession(sessionId, lines) {
34702
35557
  let evaluationsThisTurn = 0;
34703
35558
  let turnsSincePrompt = 0;
34704
35559
  let compactionSincePrompt = false;
35560
+ let ciSeen = false;
35561
+ let ciSettled = false;
34705
35562
  for (const line of lines) {
34706
35563
  if (!line.trim()) {
34707
35564
  continue;
@@ -34712,6 +35569,9 @@ function scanSession(sessionId, lines) {
34712
35569
  } catch {
34713
35570
  continue;
34714
35571
  }
35572
+ if (report2.first_at === "" && typeof entry["timestamp"] === "string") {
35573
+ report2.first_at = entry["timestamp"];
35574
+ }
34715
35575
  if (entry["type"] === "user" && entry["toolUseResult"] !== void 0 && pendingPoll !== null) {
34716
35576
  const raw = entry["toolUseResult"];
34717
35577
  const out = typeof raw === "string" ? raw : JSON.stringify(raw);
@@ -34726,6 +35586,8 @@ function scanSession(sessionId, lines) {
34726
35586
  detail: `CI poll read as settled without an in-flight observation: ${out.slice(0, 90)}`
34727
35587
  });
34728
35588
  }
35589
+ ciSeen = true;
35590
+ ciSettled = pending === 0 && sawPending && !isVacuousOutput(out);
34729
35591
  pendingPoll = null;
34730
35592
  continue;
34731
35593
  }
@@ -34765,6 +35627,20 @@ function scanSession(sessionId, lines) {
34765
35627
  if (prose !== null) {
34766
35628
  report2.assistant_turns += 1;
34767
35629
  turnsSincePrompt += 1;
35630
+ if (pinned === "de") {
35631
+ report2.de_pin_turns += 1;
35632
+ }
35633
+ if (!HARNESS_TEXT.test((prose.split("\n").find((l) => l.trim()) ?? "").trim())) {
35634
+ const cc = detectCompletionClaim(prose, { seen: ciSeen, settled: ciSettled });
35635
+ if (cc !== null) {
35636
+ report2.violations.push({
35637
+ check: "completion-claim",
35638
+ session: sessionId,
35639
+ at,
35640
+ detail: `completion claimed over an unsettled CI read: "${cc.evidence.slice(0, 110)}"`
35641
+ });
35642
+ }
35643
+ }
34768
35644
  if (pinned === "de") {
34769
35645
  const first = prose.split("\n").find((l) => l.trim()) ?? "";
34770
35646
  if (HARNESS_TEXT.test(first.trim())) {
@@ -34827,7 +35703,7 @@ function scanSession(sessionId, lines) {
34827
35703
  }
34828
35704
  function defaultStore(projectDir) {
34829
35705
  const slug = projectDir.replace(/[/.]/g, "-");
34830
- return path59.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
35706
+ return path61.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
34831
35707
  }
34832
35708
  function _tokens(chars) {
34833
35709
  return Math.round(chars / 4);
@@ -34838,13 +35714,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
34838
35714
  return {
34839
35715
  project: {
34840
35716
  dir: projectRulesDir,
34841
- present: fs58.existsSync(projectRulesDir),
35717
+ present: fs60.existsSync(projectRulesDir),
34842
35718
  files: p.files,
34843
35719
  tokens: _tokens(p.chars)
34844
35720
  },
34845
35721
  global: {
34846
35722
  dir: globalRulesDir,
34847
- present: fs58.existsSync(globalRulesDir),
35723
+ present: fs60.existsSync(globalRulesDir),
34848
35724
  files: g.files,
34849
35725
  tokens: _tokens(g.chars)
34850
35726
  },
@@ -34852,13 +35728,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
34852
35728
  };
34853
35729
  }
34854
35730
  function storeKey(store) {
34855
- return createHash8("sha256").update(path59.resolve(store)).digest("hex").slice(0, 12);
35731
+ return createHash10("sha256").update(path61.resolve(store)).digest("hex").slice(0, 12);
34856
35732
  }
34857
35733
  function scanStore(store, limit) {
34858
- const files = fs58.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs58.statSync(path59.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
35734
+ const files = fs60.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs60.statSync(path61.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
34859
35735
  const per_session = [];
34860
35736
  for (const f of files) {
34861
- const lines = fs58.readFileSync(path59.join(store, f), "utf8").split("\n");
35737
+ const lines = fs60.readFileSync(path61.join(store, f), "utf8").split("\n");
34862
35738
  const r = scanSession(f.replace(/\.jsonl$/, "").slice(0, 8), lines);
34863
35739
  if (r.assistant_turns > 0) {
34864
35740
  per_session.push(r);
@@ -34868,7 +35744,8 @@ function scanStore(store, limit) {
34868
35744
  "language-pin": 0,
34869
35745
  "git-authorization": 0,
34870
35746
  "vacuous-evidence": 0,
34871
- "evidence-steering": 0
35747
+ "evidence-steering": 0,
35748
+ "completion-claim": 0
34872
35749
  };
34873
35750
  for (const s of per_session) {
34874
35751
  for (const v of s.violations) {
@@ -34878,11 +35755,14 @@ function scanStore(store, limit) {
34878
35755
  const assistant_turns = per_session.reduce((n, s) => n + s.assistant_turns, 0);
34879
35756
  const language_pin = totals["language-pin"] ?? 0;
34880
35757
  const rate_pct = assistant_turns === 0 ? 0 : Number((100 * language_pin / assistant_turns).toFixed(1));
35758
+ const de_pin_turns = per_session.reduce((n, s) => n + s.de_pin_turns, 0);
35759
+ const rate_pct_de_pin = de_pin_turns === 0 ? 0 : Number((100 * language_pin / de_pin_turns).toFixed(1));
35760
+ const era = spansCarrierChange(per_session.map((s) => s.first_at));
34881
35761
  const delivered = measureDelivered(
34882
- path59.join(REPO_ROOT6, ".claude", "rules"),
34883
- path59.join(process.env["HOME"] ?? os12.homedir(), ".claude", "rules")
35762
+ path61.join(REPO_ROOT6, ".claude", "rules"),
35763
+ path61.join(process.env["HOME"] ?? os13.homedir(), ".claude", "rules")
34884
35764
  );
34885
- const ownStore = path59.resolve(store) === path59.resolve(defaultStore(REPO_ROOT6));
35765
+ const ownStore = path61.resolve(store) === path61.resolve(defaultStore(REPO_ROOT6));
34886
35766
  return {
34887
35767
  scanned_at: (/* @__PURE__ */ new Date()).toISOString(),
34888
35768
  store,
@@ -34896,7 +35776,11 @@ function scanStore(store, limit) {
34896
35776
  assistant_turns,
34897
35777
  language_pin,
34898
35778
  rate_pct,
34899
- band: bandVerdict(rate_pct, assistant_turns),
35779
+ de_pin_turns,
35780
+ rate_pct_de_pin,
35781
+ era_spanning: era.spans,
35782
+ era_reason: era.what,
35783
+ band: bandVerdict(rate_pct, assistant_turns, { spansCarrier: era.spans }),
34900
35784
  // Only attach the carrier figures when the rate and the carriers describe
34901
35785
  // the same project.
34902
35786
  delivered_project_tokens: ownStore ? delivered.project.tokens : null,
@@ -34905,8 +35789,8 @@ function scanStore(store, limit) {
34905
35789
  };
34906
35790
  }
34907
35791
  function recordRate(file, scanned_at, rate) {
34908
- fs58.mkdirSync(path59.dirname(file), { recursive: true });
34909
- fs58.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
35792
+ fs60.mkdirSync(path61.dirname(file), { recursive: true });
35793
+ fs60.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
34910
35794
  `, "utf8");
34911
35795
  }
34912
35796
  function render2(report2) {
@@ -34937,7 +35821,26 @@ function render2(report2) {
34937
35821
  lines.push(
34938
35822
  ` language-pin rate ${report2.rate.rate_pct.toFixed(1)}% (${report2.rate.language_pin} of ${report2.rate.assistant_turns} assistant turns)`
34939
35823
  );
34940
- if (report2.rate.band === "corpus-too-small") {
35824
+ const dePinTurns = report2.rate.de_pin_turns;
35825
+ const dePinRate = report2.rate.rate_pct_de_pin;
35826
+ if (typeof dePinTurns === "number" && typeof dePinRate === "number") {
35827
+ lines.push(
35828
+ ` ${dePinRate.toFixed(1)}% (${report2.rate.language_pin} of ${dePinTurns} turns under a GERMAN pin \u2014 the only turns this check can fire on)`
35829
+ );
35830
+ lines.push(
35831
+ " The band (M5, n=3) was computed on the ALL-turns denominator, so the first figure"
35832
+ );
35833
+ lines.push(" is the comparable one and the second is the honest one. Both are printed.");
35834
+ }
35835
+ if (report2.rate.band === "era-spanning") {
35836
+ lines.push(
35837
+ ` Not compared: the corpus SPANS a carrier landing \u2014 ${report2.rate.era_reason || "see CARRIER_CHANGES"}.`
35838
+ );
35839
+ lines.push(" A rate pooled across it is a weighted average of two different systems, not");
35840
+ lines.push(" a reading about behaviour. Round 7 measured 23.1% before and 0.0% after that");
35841
+ lines.push(" exact carrier; the pooled 6.5% was announced as the falsifier firing.");
35842
+ lines.push(" Split the window at the carrier date and read each era on its own.");
35843
+ } else if (report2.rate.band === "corpus-too-small") {
34941
35844
  lines.push(
34942
35845
  ` Not compared: ${report2.rate.assistant_turns} turns is below the ${BAND_MIN_TURNS} of the`
34943
35846
  );
@@ -34959,11 +35862,22 @@ function render2(report2) {
34959
35862
  lines.push(" as new. Store novelty is not project novelty.");
34960
35863
  }
34961
35864
  lines.push("");
34962
- lines.push(" Scanned checks are exactly the mechanised ones. Ask-shape, session-canary,");
34963
- lines.push(" promissory closings and checkbox batching are left as prose and NOT measured.");
35865
+ lines.push(" Scanned checks are exactly the mechanised ones. What is NOT in the counts above:");
35866
+ lines.push(" ask-shape (trailing free-text offer) \u2014 measured NOWHERE. ~11 findings in round 7's");
35867
+ lines.push(" reading half; the discriminator needs judgement, so it stays advisory on purpose.");
35868
+ lines.push(" session-canary (opening greeting) \u2014 not here, but PROBEABLE:");
35869
+ lines.push(" `./scripts-run src/scripts/probe_session_canary`. Round 7: 25/28 sessions,");
35870
+ lines.push(" 24/25 post-carrier. The per-TASK instance is undecidable \u2014 no task boundary");
35871
+ lines.push(" is recorded in a transcript.");
35872
+ lines.push(" promissory closings \u2014 not here, but ALREADY GATED: `turn-end-gate`");
35873
+ lines.push(" ships a blocking `detectPromissory`. Round 7 probe: 1 of 120 hand-back turns");
35874
+ lines.push(" (the 163 this line first printed was the retracted denominator \u2014 it counted");
35875
+ lines.push(" synthetic user turns as hand-back closers).");
35876
+ lines.push(" `./scripts-run src/scripts/probe_promissory_closing`.");
35877
+ lines.push(" checkbox batching \u2014 measured NOWHERE. ~5 low-severity findings.");
34964
35878
  return lines.join("\n");
34965
35879
  }
34966
- function main24(argv) {
35880
+ function main26(argv) {
34967
35881
  const args = argv ?? process.argv.slice(2);
34968
35882
  let store = null;
34969
35883
  let limit = 30;
@@ -34995,14 +35909,14 @@ function main24(argv) {
34995
35909
  return 2;
34996
35910
  }
34997
35911
  const resolved = store ?? defaultStore(process.cwd());
34998
- if (!fs58.existsSync(resolved)) {
35912
+ if (!fs60.existsSync(resolved)) {
34999
35913
  process.stderr.write(`conformance:behavior: no transcript store at ${resolved}
35000
35914
  `);
35001
35915
  return 1;
35002
35916
  }
35003
35917
  const report2 = scanStore(resolved, Number.isFinite(limit) && limit > 0 ? limit : 30);
35004
35918
  if (out) {
35005
- fs58.writeFileSync(out, `${JSON.stringify(report2, null, 2)}
35919
+ fs60.writeFileSync(out, `${JSON.stringify(report2, null, 2)}
35006
35920
  `, "utf8");
35007
35921
  }
35008
35922
  if (record) {
@@ -35010,7 +35924,7 @@ function main24(argv) {
35010
35924
  }
35011
35925
  if (why !== null) {
35012
35926
  const id = why;
35013
- fs58.writeSync(
35927
+ fs60.writeSync(
35014
35928
  1,
35015
35929
  json ? `${JSON.stringify(
35016
35930
  {
@@ -35030,31 +35944,31 @@ function main24(argv) {
35030
35944
  );
35031
35945
  return 0;
35032
35946
  }
35033
- fs58.writeSync(1, json ? `${JSON.stringify(report2, null, 2)}
35947
+ fs60.writeSync(1, json ? `${JSON.stringify(report2, null, 2)}
35034
35948
  ` : `${render2(report2)}
35035
35949
  `);
35036
35950
  return 0;
35037
35951
  }
35038
- function _isCliEntry22() {
35952
+ function _isCliEntry24() {
35039
35953
  if (true) {
35040
35954
  return false;
35041
35955
  }
35042
35956
  if (process.argv[1] === void 0) {
35043
35957
  return false;
35044
35958
  }
35045
- const argvUrl = pathToFileURL24(path59.resolve(process.argv[1])).href;
35959
+ const argvUrl = pathToFileURL26(path61.resolve(process.argv[1])).href;
35046
35960
  if (import.meta.url === argvUrl) {
35047
35961
  return true;
35048
35962
  }
35049
35963
  try {
35050
- const here = fs58.realpathSync(fileURLToPath35(import.meta.url));
35051
- const argv = fs58.realpathSync(path59.resolve(process.argv[1]));
35964
+ const here = fs60.realpathSync(fileURLToPath37(import.meta.url));
35965
+ const argv = fs60.realpathSync(path61.resolve(process.argv[1]));
35052
35966
  return here === argv;
35053
35967
  } catch {
35054
35968
  return false;
35055
35969
  }
35056
35970
  }
35057
- var REPO_ROOT6, OBSERVED_BAND, BAND_MIN_TURNS, CHECK_IDS2, CHECK_MEANINGS, HARNESS_TEXT, EN_OPENER, DEFAULT_RATE_SERIES;
35971
+ var REPO_ROOT6, OBSERVED_BAND, BAND_MIN_TURNS, CARRIER_CHANGES, CHECK_IDS2, CHECK_MEANINGS, HARNESS_TEXT, EN_OPENER, DEFAULT_RATE_SERIES;
35058
35972
  var init_conformance_scan = __esm({
35059
35973
  "src/scripts/conformance_scan.ts"() {
35060
35974
  "use strict";
@@ -35065,46 +35979,52 @@ var init_conformance_scan = __esm({
35065
35979
  init_git_authorization_hook();
35066
35980
  init_block_unauthorized_git();
35067
35981
  init_before_complete_hook();
35982
+ init_turn_end_gate_hook();
35068
35983
  init_evidence_independence();
35069
- REPO_ROOT6 = path59.resolve(path59.dirname(fileURLToPath35(import.meta.url)), "..", "..");
35984
+ REPO_ROOT6 = path61.resolve(path61.dirname(fileURLToPath37(import.meta.url)), "..", "..");
35070
35985
  OBSERVED_BAND = { low: 9.1, high: 39.2 };
35071
35986
  BAND_MIN_TURNS = 1978;
35987
+ CARRIER_CHANGES = [
35988
+ { at: "2026-08-07T00:00:00Z", what: "language-pin bound on user_prompt_submit (round 5)" }
35989
+ ];
35072
35990
  CHECK_IDS2 = [
35073
35991
  "language-pin",
35074
35992
  "git-authorization",
35075
35993
  "vacuous-evidence",
35076
- "evidence-steering"
35994
+ "evidence-steering",
35995
+ "completion-claim"
35077
35996
  ];
35078
35997
  CHECK_MEANINGS = {
35079
35998
  "language-pin": "An assistant turn whose user-visible prose is not in the language that turn's own pin named. Carries provenance (turns_since_prompt, compaction_since_prompt) so a pin that was ABSENT because compaction removed it stays distinguishable from one that was present and ignored.",
35080
35999
  "git-authorization": "A gated git operation performed in a session where no authorization for that operation was observed. Authorization is per-operation and never carries from one to the next.",
35081
36000
  "vacuous-evidence": "A CI poll read as settled without ever observing an in-flight run \u2014 the poll gap that reports a green settle over a window in which nothing was pending yet.",
35082
- "evidence-steering": "A self-commissioned evaluation whose prompt pre-loaded its own verdict, or a second self-scoped evaluation of the same subject within one turn."
36001
+ "evidence-steering": "A self-commissioned evaluation whose prompt pre-loaded its own verdict, or a second self-scoped evaluation of the same subject within one turn.",
36002
+ "completion-claim": "An assistant turn claiming the work is complete while the last CI read in that session was NOT settled. Round 7 measured 14 instances by reading, each followed by the user handing the work back; this is the same predicate `turn-end-gate`'s completion detector refuses on, so the rate and the gate cannot disagree. A session that never polled CI can never hit."
35083
36003
  };
35084
36004
  HARNESS_TEXT = /^(API Error:|Request (timed out|was aborted)|\[Request interrupted|Error: |Credit balance is too low|You've hit your|Prompt is too long)/i;
35085
36005
  EN_OPENER = /^(let me|i'?ll |i'?m |found it|ok[,. ]|okay|alright|here'?s|now[,. ]|looking|checking|reading|running|the |this |that |there |we |you |good |right[,. ]|perfect|done[.,]|all |confirmed|correct)/i;
35086
- DEFAULT_RATE_SERIES = path59.join(
36006
+ DEFAULT_RATE_SERIES = path61.join(
35087
36007
  REPO_ROOT6,
35088
36008
  "agents",
35089
36009
  "runtime",
35090
36010
  "state",
35091
36011
  "conformance-rates.jsonl"
35092
36012
  );
35093
- if (_isCliEntry22()) {
35094
- process.exit(main24());
36013
+ if (_isCliEntry24()) {
36014
+ process.exit(main26());
35095
36015
  }
35096
36016
  }
35097
36017
  });
35098
36018
 
35099
36019
  // src/scripts/report_carrier_divergence.ts
35100
- import * as fs59 from "node:fs";
35101
- import * as os13 from "node:os";
35102
- import * as path60 from "node:path";
36020
+ import * as fs61 from "node:fs";
36021
+ import * as os14 from "node:os";
36022
+ import * as path62 from "node:path";
35103
36023
  import process16 from "node:process";
35104
- import { fileURLToPath as fileURLToPath36, pathToFileURL as pathToFileURL25 } from "node:url";
36024
+ import { fileURLToPath as fileURLToPath38, pathToFileURL as pathToFileURL27 } from "node:url";
35105
36025
  function _listRules(dir) {
35106
36026
  try {
35107
- return fs59.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
36027
+ return fs61.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
35108
36028
  } catch {
35109
36029
  return [];
35110
36030
  }
@@ -35112,7 +36032,7 @@ function _listRules(dir) {
35112
36032
  function _ruleType(file) {
35113
36033
  let text;
35114
36034
  try {
35115
- text = fs59.readFileSync(file, "utf-8");
36035
+ text = fs61.readFileSync(file, "utf-8");
35116
36036
  } catch {
35117
36037
  return "";
35118
36038
  }
@@ -35123,8 +36043,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
35123
36043
  const out = {
35124
36044
  projectDir,
35125
36045
  globalDir,
35126
- globalPresent: fs59.existsSync(globalDir),
35127
- projectPresent: fs59.existsSync(projectDir),
36046
+ globalPresent: fs61.existsSync(globalDir),
36047
+ projectPresent: fs61.existsSync(projectDir),
35128
36048
  shared: 0,
35129
36049
  identical: [],
35130
36050
  provenanceOnly: [],
@@ -35147,7 +36067,7 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
35147
36067
  }
35148
36068
  if (!inP && inG) {
35149
36069
  out.globalOnly.push(rule);
35150
- if (sourceDir !== void 0 && _ruleType(path60.join(sourceDir, rule)) === "manual") {
36070
+ if (sourceDir !== void 0 && _ruleType(path62.join(sourceDir, rule)) === "manual") {
35151
36071
  out.manualOnlyGlobal.push(rule);
35152
36072
  }
35153
36073
  continue;
@@ -35157,8 +36077,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
35157
36077
  let projectCopy;
35158
36078
  let globalCopy;
35159
36079
  try {
35160
- projectCopy = fs59.readFileSync(path60.join(projectDir, rule));
35161
- globalCopy = fs59.readFileSync(path60.join(globalDir, rule));
36080
+ projectCopy = fs61.readFileSync(path62.join(projectDir, rule));
36081
+ globalCopy = fs61.readFileSync(path62.join(globalDir, rule));
35162
36082
  verdict = comparePair(projectCopy, globalCopy);
35163
36083
  } catch {
35164
36084
  out.shared -= 1;
@@ -35303,11 +36223,11 @@ function render3(d) {
35303
36223
  }
35304
36224
  return lines.join("\n");
35305
36225
  }
35306
- function main25(argv) {
36226
+ function main27(argv) {
35307
36227
  const args = argv ?? process16.argv.slice(2);
35308
- let projectDir = path60.join(REPO_ROOT7, PROJECT_RULES);
35309
- let globalDir = path60.join(os13.homedir(), GLOBAL_RULES);
35310
- let sourceDir = path60.join(REPO_ROOT7, PROJECTION_SOURCE);
36228
+ let projectDir = path62.join(REPO_ROOT7, PROJECT_RULES);
36229
+ let globalDir = path62.join(os14.homedir(), GLOBAL_RULES);
36230
+ let sourceDir = path62.join(REPO_ROOT7, PROJECTION_SOURCE);
35311
36231
  const value = (i) => {
35312
36232
  const v = args[i + 1];
35313
36233
  return v === void 0 || v.startsWith("-") ? null : v;
@@ -35321,7 +36241,7 @@ function main25(argv) {
35321
36241
  `);
35322
36242
  return 1;
35323
36243
  }
35324
- const resolved = path60.resolve(v);
36244
+ const resolved = path62.resolve(v);
35325
36245
  if (a === "--project") projectDir = resolved;
35326
36246
  else if (a === "--global") globalDir = resolved;
35327
36247
  else sourceDir = resolved;
@@ -35341,11 +36261,11 @@ function main25(argv) {
35341
36261
  `);
35342
36262
  return 0;
35343
36263
  }
35344
- function _isCliEntry23() {
36264
+ function _isCliEntry25() {
35345
36265
  if (process16.argv[1] === void 0) return false;
35346
- if (import.meta.url === pathToFileURL25(path60.resolve(process16.argv[1])).href) return true;
36266
+ if (import.meta.url === pathToFileURL27(path62.resolve(process16.argv[1])).href) return true;
35347
36267
  try {
35348
- return fs59.realpathSync(_HERE17) === fs59.realpathSync(path60.resolve(process16.argv[1]));
36268
+ return fs61.realpathSync(_HERE17) === fs61.realpathSync(path62.resolve(process16.argv[1]));
35349
36269
  } catch {
35350
36270
  return false;
35351
36271
  }
@@ -35355,37 +36275,37 @@ var init_report_carrier_divergence = __esm({
35355
36275
  "src/scripts/report_carrier_divergence.ts"() {
35356
36276
  "use strict";
35357
36277
  init_carrier_divergence();
35358
- _HERE17 = fileURLToPath36(import.meta.url);
35359
- REPO_ROOT7 = path60.resolve(path60.dirname(_HERE17), "..", "..");
35360
- PROJECT_RULES = path60.join(".claude", "rules");
35361
- PROJECTION_SOURCE = path60.join("dist", "agent-src", "rules");
35362
- GLOBAL_RULES = path60.join(".claude", "rules");
35363
- if (_isCliEntry23()) {
35364
- process16.exit(main25());
36278
+ _HERE17 = fileURLToPath38(import.meta.url);
36279
+ REPO_ROOT7 = path62.resolve(path62.dirname(_HERE17), "..", "..");
36280
+ PROJECT_RULES = path62.join(".claude", "rules");
36281
+ PROJECTION_SOURCE = path62.join("dist", "agent-src", "rules");
36282
+ GLOBAL_RULES = path62.join(".claude", "rules");
36283
+ if (_isCliEntry25()) {
36284
+ process16.exit(main27());
35365
36285
  }
35366
36286
  }
35367
36287
  });
35368
36288
 
35369
36289
  // src/scripts/report_skill_activation.ts
35370
- import * as fs60 from "node:fs";
35371
- import * as os14 from "node:os";
35372
- import * as path61 from "node:path";
35373
- import { fileURLToPath as fileURLToPath37, pathToFileURL as pathToFileURL26 } from "node:url";
36290
+ import * as fs62 from "node:fs";
36291
+ import * as os15 from "node:os";
36292
+ import * as path63 from "node:path";
36293
+ import { fileURLToPath as fileURLToPath39, pathToFileURL as pathToFileURL28 } from "node:url";
35374
36294
  function censusSkills(root) {
35375
36295
  const out = { total: 0, withTriggerKey: [], withDeterministicObligation: [] };
35376
- if (!fs60.existsSync(root)) {
36296
+ if (!fs62.existsSync(root)) {
35377
36297
  return out;
35378
36298
  }
35379
- for (const entry of fs60.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
36299
+ for (const entry of fs62.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
35380
36300
  if (!entry.isDirectory()) {
35381
36301
  continue;
35382
36302
  }
35383
- const file = path61.join(root, entry.name, "SKILL.md");
35384
- if (!fs60.existsSync(file)) {
36303
+ const file = path63.join(root, entry.name, "SKILL.md");
36304
+ if (!fs62.existsSync(file)) {
35385
36305
  continue;
35386
36306
  }
35387
36307
  out.total += 1;
35388
- const text = fs60.readFileSync(file, "utf8");
36308
+ const text = fs62.readFileSync(file, "utf8");
35389
36309
  const fmEnd = text.startsWith("---") ? text.indexOf("\n---", 3) : -1;
35390
36310
  const fm = fmEnd === -1 ? "" : text.slice(0, fmEnd);
35391
36311
  if (TRIGGER_KEYS.some((k) => new RegExp(`^${k}`, "m").test(fm))) {
@@ -35399,17 +36319,17 @@ function censusSkills(root) {
35399
36319
  return out;
35400
36320
  }
35401
36321
  function defaultStore2(cwd) {
35402
- return path61.join(os14.homedir(), ".claude", "projects", cwd.replace(/[/.]/g, "-"));
36322
+ return path63.join(os15.homedir(), ".claude", "projects", cwd.replace(/[/.]/g, "-"));
35403
36323
  }
35404
36324
  function measureUsage(store, limit) {
35405
36325
  const rep = { store, sessions: 0, assistantTurns: 0, invocations: 0, bySkill: {} };
35406
- if (!fs60.existsSync(store)) {
36326
+ if (!fs62.existsSync(store)) {
35407
36327
  return rep;
35408
36328
  }
35409
- const files = fs60.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path61.join(store, f)).sort((a, b) => fs60.statSync(b).mtimeMs - fs60.statSync(a).mtimeMs).slice(0, limit);
36329
+ const files = fs62.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path63.join(store, f)).sort((a, b) => fs62.statSync(b).mtimeMs - fs62.statSync(a).mtimeMs).slice(0, limit);
35410
36330
  rep.sessions = files.length;
35411
36331
  for (const file of files) {
35412
- for (const line of fs60.readFileSync(file, "utf8").split("\n")) {
36332
+ for (const line of fs62.readFileSync(file, "utf8").split("\n")) {
35413
36333
  if (!line.trim()) {
35414
36334
  continue;
35415
36335
  }
@@ -35472,7 +36392,7 @@ function render4(census, usage) {
35472
36392
  }
35473
36393
  totalInv += u.invocations;
35474
36394
  lines.push(
35475
- ` ${path61.basename(u.store).slice(-38).padEnd(38)} sessions=${String(u.sessions).padStart(3)} asst=${String(u.assistantTurns).padStart(6)} Skill calls=${String(u.invocations).padStart(3)}`
36395
+ ` ${path63.basename(u.store).slice(-38).padEnd(38)} sessions=${String(u.sessions).padStart(3)} asst=${String(u.assistantTurns).padStart(6)} Skill calls=${String(u.invocations).padStart(3)}`
35476
36396
  );
35477
36397
  }
35478
36398
  lines.push("");
@@ -35497,7 +36417,7 @@ function render4(census, usage) {
35497
36417
  lines.push(" catalogue once per session, then count descriptions against bare names.");
35498
36418
  return lines.join("\n");
35499
36419
  }
35500
- function main26(argv) {
36420
+ function main28(argv) {
35501
36421
  let limit = 30;
35502
36422
  const stores = [];
35503
36423
  for (let i = 0; i < argv.length; i += 1) {
@@ -35520,7 +36440,7 @@ function main26(argv) {
35520
36440
  if (stores.length === 0) {
35521
36441
  stores.push(defaultStore2(REPO_ROOT8));
35522
36442
  }
35523
- const census = censusSkills(path61.join(REPO_ROOT8, SKILLS_ROOT));
36443
+ const census = censusSkills(path63.join(REPO_ROOT8, SKILLS_ROOT));
35524
36444
  const usage = stores.map((s) => measureUsage(s, limit));
35525
36445
  process.stdout.write(`${render4(census, usage)}
35526
36446
  `);
@@ -35530,23 +36450,23 @@ var _HERE18, REPO_ROOT8, SKILLS_ROOT, TRIGGER_KEYS, DETERMINISTIC_RE;
35530
36450
  var init_report_skill_activation = __esm({
35531
36451
  "src/scripts/report_skill_activation.ts"() {
35532
36452
  "use strict";
35533
- _HERE18 = fileURLToPath37(import.meta.url);
35534
- REPO_ROOT8 = path61.resolve(path61.dirname(_HERE18), "..", "..");
36453
+ _HERE18 = fileURLToPath39(import.meta.url);
36454
+ REPO_ROOT8 = path63.resolve(path63.dirname(_HERE18), "..", "..");
35535
36455
  SKILLS_ROOT = "src/skills";
35536
36456
  TRIGGER_KEYS = ["triggers:", "trigger_description:", "file_pattern:", "path_prefix:"];
35537
36457
  DETERMINISTIC_RE = /^\s*(?:[-*]\s*)?(?:\*\*)?(MUST|NEVER|ALWAYS)\b/m;
35538
- if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL26(path61.resolve(process.argv[1])).href) {
35539
- process.exit(main26(process.argv.slice(2)));
36458
+ if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL28(path63.resolve(process.argv[1])).href) {
36459
+ process.exit(main28(process.argv.slice(2)));
35540
36460
  }
35541
36461
  }
35542
36462
  });
35543
36463
 
35544
36464
  // src/scripts/report_skill_obligation_violations.ts
35545
- import * as fs61 from "node:fs";
35546
- import * as os15 from "node:os";
35547
- import * as path62 from "node:path";
36465
+ import * as fs63 from "node:fs";
36466
+ import * as os16 from "node:os";
36467
+ import * as path64 from "node:path";
35548
36468
  import process17 from "node:process";
35549
- import { fileURLToPath as fileURLToPath38, pathToFileURL as pathToFileURL27 } from "node:url";
36469
+ import { fileURLToPath as fileURLToPath40, pathToFileURL as pathToFileURL29 } from "node:url";
35550
36470
  function _verb(line) {
35551
36471
  const m = /\b(NEVER|MUST|ALWAYS)\b/.exec(line);
35552
36472
  return m?.[1] ?? "NEVER";
@@ -35565,7 +36485,7 @@ function _artefacts(line) {
35565
36485
  return out;
35566
36486
  }
35567
36487
  function extractObligations(repoRoot) {
35568
- const skillsRoot = path62.join(repoRoot, SKILLS_ROOT);
36488
+ const skillsRoot = path64.join(repoRoot, SKILLS_ROOT);
35569
36489
  const census = censusSkills(skillsRoot);
35570
36490
  const out = {
35571
36491
  skills: census.withDeterministicObligation,
@@ -35579,7 +36499,7 @@ function extractObligations(repoRoot) {
35579
36499
  for (const skill of census.withDeterministicObligation) {
35580
36500
  let text;
35581
36501
  try {
35582
- text = fs61.readFileSync(path62.join(skillsRoot, skill, "SKILL.md"), "utf-8");
36502
+ text = fs63.readFileSync(path64.join(skillsRoot, skill, "SKILL.md"), "utf-8");
35583
36503
  } catch {
35584
36504
  continue;
35585
36505
  }
@@ -35681,7 +36601,7 @@ function scanSessionForViolations(session, lines, forbidden, parsed) {
35681
36601
  return flags;
35682
36602
  }
35683
36603
  function defaultStore3(cwd) {
35684
- return path62.join(os15.homedir(), ".claude", "projects", cwd.replace(/[/.]/g, "-"));
36604
+ return path64.join(os16.homedir(), ".claude", "projects", cwd.replace(/[/.]/g, "-"));
35685
36605
  }
35686
36606
  function scanStore2(repoRoot, store, limit) {
35687
36607
  const census = extractObligations(repoRoot);
@@ -35694,14 +36614,14 @@ function scanStore2(repoRoot, store, limit) {
35694
36614
  };
35695
36615
  let files;
35696
36616
  try {
35697
- files = fs61.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path62.join(store, f), m: fs61.statSync(path62.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
36617
+ files = fs63.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path64.join(store, f), m: fs63.statSync(path64.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
35698
36618
  } catch {
35699
36619
  return report2;
35700
36620
  }
35701
36621
  report2.sessions = files.length;
35702
36622
  for (const file of files) {
35703
- const lines = fs61.readFileSync(file, "utf-8").split("\n");
35704
- const id = path62.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
36623
+ const lines = fs63.readFileSync(file, "utf-8").split("\n");
36624
+ const id = path64.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
35705
36625
  const entries = _parseSession(lines);
35706
36626
  if (loadedSkillsFrom(entries).size > 0) report2.sessionsWithASkill += 1;
35707
36627
  report2.flags.push(...scanSessionForViolations(id, lines, census.forbidden, entries));
@@ -35771,7 +36691,7 @@ function render5(r) {
35771
36691
  lines.push(" ships as detection-only, and this one says so.");
35772
36692
  return lines.join("\n");
35773
36693
  }
35774
- function main27(argv) {
36694
+ function main29(argv) {
35775
36695
  const args = argv ?? process17.argv.slice(2);
35776
36696
  let limit = 30;
35777
36697
  let json = false;
@@ -35824,11 +36744,11 @@ function main27(argv) {
35824
36744
  }
35825
36745
  return 0;
35826
36746
  }
35827
- function _isCliEntry24() {
36747
+ function _isCliEntry26() {
35828
36748
  if (process17.argv[1] === void 0) return false;
35829
- if (import.meta.url === pathToFileURL27(path62.resolve(process17.argv[1])).href) return true;
36749
+ if (import.meta.url === pathToFileURL29(path64.resolve(process17.argv[1])).href) return true;
35830
36750
  try {
35831
- return fs61.realpathSync(_HERE19) === fs61.realpathSync(path62.resolve(process17.argv[1]));
36751
+ return fs63.realpathSync(_HERE19) === fs63.realpathSync(path64.resolve(process17.argv[1]));
35832
36752
  } catch {
35833
36753
  return false;
35834
36754
  }
@@ -35839,8 +36759,8 @@ var init_report_skill_obligation_violations = __esm({
35839
36759
  "use strict";
35840
36760
  init_transcript_entry();
35841
36761
  init_report_skill_activation();
35842
- _HERE19 = fileURLToPath38(import.meta.url);
35843
- REPO_ROOT9 = path62.resolve(path62.dirname(_HERE19), "..", "..");
36762
+ _HERE19 = fileURLToPath40(import.meta.url);
36763
+ REPO_ROOT9 = path64.resolve(path64.dirname(_HERE19), "..", "..");
35844
36764
  OBLIGATION_LINE_RE = new RegExp(`${DETERMINISTIC_RE.source}.*`, "gm");
35845
36765
  PATH_RE = /`([A-Za-z0-9_./-]*\/[A-Za-z0-9_.-]+\.[a-z]{2,6})`/g;
35846
36766
  CMD_RE = /`([a-z][a-z0-9-]*(?: [a-z][a-z0-9:._-]*){1,3})`/g;
@@ -35874,31 +36794,31 @@ var init_report_skill_obligation_violations = __esm({
35874
36794
  SKILL_BODY_RE = /Base directory for this skill:\s*\S*?\/skills\/([A-Za-z0-9_-]+)/;
35875
36795
  PATH_FIELDS = ["file_path", "path", "filePath", "notebook_path", "target_file"];
35876
36796
  COMMAND_FIELDS = ["command", "cmd"];
35877
- if (_isCliEntry24()) {
35878
- process17.exit(main27());
36797
+ if (_isCliEntry26()) {
36798
+ process17.exit(main29());
35879
36799
  }
35880
36800
  }
35881
36801
  });
35882
36802
 
35883
36803
  // src/scripts/report_conformance_funnel.ts
35884
- import * as fs62 from "node:fs";
35885
- import * as os16 from "node:os";
35886
- import * as path63 from "node:path";
36804
+ import * as fs64 from "node:fs";
36805
+ import * as os17 from "node:os";
36806
+ import * as path65 from "node:path";
35887
36807
  import process18 from "node:process";
35888
- import { fileURLToPath as fileURLToPath39, pathToFileURL as pathToFileURL28 } from "node:url";
36808
+ import { fileURLToPath as fileURLToPath41, pathToFileURL as pathToFileURL30 } from "node:url";
35889
36809
  function buildFunnel(opts = {}) {
35890
36810
  const repoRoot = opts.repoRoot ?? REPO_ROOT10;
35891
- const projectRulesDir = opts.projectRulesDir ?? path63.join(repoRoot, PROJECT_RULES);
35892
- const globalRulesDir = opts.globalRulesDir ?? path63.join(os16.homedir(), GLOBAL_RULES);
35893
- const sourceDir = opts.sourceDir ?? path63.join(repoRoot, PROJECTION_SOURCE);
36811
+ const projectRulesDir = opts.projectRulesDir ?? path65.join(repoRoot, PROJECT_RULES);
36812
+ const globalRulesDir = opts.globalRulesDir ?? path65.join(os17.homedir(), GLOBAL_RULES);
36813
+ const sourceDir = opts.sourceDir ?? path65.join(repoRoot, PROJECTION_SOURCE);
35894
36814
  const store = opts.store ?? defaultStore(repoRoot);
35895
36815
  const limit = opts.limit ?? 30;
35896
36816
  return {
35897
36817
  delivered: measureDelivered(projectRulesDir, globalRulesDir),
35898
36818
  divergence: compareCarriers(projectRulesDir, globalRulesDir, sourceDir),
35899
- skills: censusSkills(path63.join(repoRoot, SKILLS_ROOT)),
36819
+ skills: censusSkills(path65.join(repoRoot, SKILLS_ROOT)),
35900
36820
  usage: measureUsage(store, limit),
35901
- storePresent: fs62.existsSync(store),
36821
+ storePresent: fs64.existsSync(store),
35902
36822
  sk2: scanStore2(repoRoot, store, limit)
35903
36823
  };
35904
36824
  }
@@ -36023,7 +36943,7 @@ function render6(r) {
36023
36943
  lines.push("workflow without a measured false-positive rate first (locked policy).");
36024
36944
  return lines.join("\n");
36025
36945
  }
36026
- function main28(argv) {
36946
+ function main30(argv) {
36027
36947
  const args = argv ?? process18.argv.slice(2);
36028
36948
  const opts = {};
36029
36949
  const value = (i) => {
@@ -36039,7 +36959,7 @@ function main28(argv) {
36039
36959
  `);
36040
36960
  return 1;
36041
36961
  }
36042
- const resolved = path63.resolve(v);
36962
+ const resolved = path65.resolve(v);
36043
36963
  if (a === "--store") opts.store = resolved;
36044
36964
  else if (a === "--project") opts.projectRulesDir = resolved;
36045
36965
  else if (a === "--global") opts.globalRulesDir = resolved;
@@ -36069,11 +36989,11 @@ function main28(argv) {
36069
36989
  `);
36070
36990
  return 0;
36071
36991
  }
36072
- function _isCliEntry25() {
36992
+ function _isCliEntry27() {
36073
36993
  if (process18.argv[1] === void 0) return false;
36074
- if (import.meta.url === pathToFileURL28(path63.resolve(process18.argv[1])).href) return true;
36994
+ if (import.meta.url === pathToFileURL30(path65.resolve(process18.argv[1])).href) return true;
36075
36995
  try {
36076
- return fs62.realpathSync(_HERE20) === fs62.realpathSync(path63.resolve(process18.argv[1]));
36996
+ return fs64.realpathSync(_HERE20) === fs64.realpathSync(path65.resolve(process18.argv[1]));
36077
36997
  } catch {
36078
36998
  return false;
36079
36999
  }
@@ -36086,10 +37006,10 @@ var init_report_conformance_funnel = __esm({
36086
37006
  init_report_carrier_divergence();
36087
37007
  init_report_skill_activation();
36088
37008
  init_report_skill_obligation_violations();
36089
- _HERE20 = fileURLToPath39(import.meta.url);
36090
- REPO_ROOT10 = path63.resolve(path63.dirname(_HERE20), "..", "..");
36091
- if (_isCliEntry25()) {
36092
- process18.exit(main28());
37009
+ _HERE20 = fileURLToPath41(import.meta.url);
37010
+ REPO_ROOT10 = path65.resolve(path65.dirname(_HERE20), "..", "..");
37011
+ if (_isCliEntry27()) {
37012
+ process18.exit(main30());
36093
37013
  }
36094
37014
  }
36095
37015
  });
@@ -36110,16 +37030,16 @@ __export(cmd_conformance_exports, {
36110
37030
  conformanceLogPath: () => conformanceLogPath,
36111
37031
  detectSmokePlatform: () => detectSmokePlatform,
36112
37032
  installLogPath: () => installLogPath,
36113
- main: () => main29,
37033
+ main: () => main31,
36114
37034
  routeTargetPaths: () => routeTargetPaths,
36115
37035
  runConformanceChecks: () => runConformanceChecks
36116
37036
  });
36117
- import * as fs63 from "node:fs";
36118
- import * as os17 from "node:os";
36119
- import * as path64 from "node:path";
37037
+ import * as fs65 from "node:fs";
37038
+ import * as os18 from "node:os";
37039
+ import * as path66 from "node:path";
36120
37040
  import process19 from "node:process";
36121
- import { spawnSync as spawnSync9 } from "node:child_process";
36122
- import { fileURLToPath as fileURLToPath40, pathToFileURL as pathToFileURL29 } from "node:url";
37041
+ import { spawnSync as spawnSync10 } from "node:child_process";
37042
+ import { fileURLToPath as fileURLToPath42, pathToFileURL as pathToFileURL31 } from "node:url";
36123
37043
  function print2(s = "") {
36124
37044
  process19.stdout.write(`${s}
36125
37045
  `);
@@ -36133,17 +37053,17 @@ function conformanceLogPath() {
36133
37053
  if (override && override.trim().length > 0) {
36134
37054
  return override;
36135
37055
  }
36136
- return path64.join(os17.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
37056
+ return path66.join(os18.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
36137
37057
  }
36138
37058
  function installLogPath() {
36139
37059
  const override = process19.env["AGENT_CONFIG_INSTALL_LOG"];
36140
37060
  if (override && override.trim().length > 0) {
36141
37061
  return override;
36142
37062
  }
36143
- return path64.join(os17.homedir(), ".event4u", "agent-config", "install-log.jsonl");
37063
+ return path66.join(os18.homedir(), ".event4u", "agent-config", "install-log.jsonl");
36144
37064
  }
36145
37065
  function _check_txlog_clean(logPath = installLogPath()) {
36146
- if (!fs63.existsSync(logPath)) {
37066
+ if (!fs65.existsSync(logPath)) {
36147
37067
  return {
36148
37068
  id: "txlog-clean",
36149
37069
  status: "ok",
@@ -36177,11 +37097,11 @@ function _check_txlog_clean(logPath = installLogPath()) {
36177
37097
  };
36178
37098
  }
36179
37099
  function routeTargetPaths(target) {
36180
- return routeTargetPathsPosix(target).map((rel) => path64.join(...rel.split("/")));
37100
+ return routeTargetPathsPosix(target).map((rel) => path66.join(...rel.split("/")));
36181
37101
  }
36182
37102
  function _check_router_pointers(packageRoot = PACKAGE_ROOT2) {
36183
- const routerPath = path64.join(packageRoot, "dist", "router.json");
36184
- if (!fs63.existsSync(routerPath)) {
37103
+ const routerPath = path66.join(packageRoot, "dist", "router.json");
37104
+ if (!fs65.existsSync(routerPath)) {
36185
37105
  return {
36186
37106
  id: "router-pointers",
36187
37107
  status: "fail",
@@ -36191,7 +37111,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT2) {
36191
37111
  }
36192
37112
  let router;
36193
37113
  try {
36194
- router = JSON.parse(fs63.readFileSync(routerPath, "utf8"));
37114
+ router = JSON.parse(fs65.readFileSync(routerPath, "utf8"));
36195
37115
  } catch (exc) {
36196
37116
  return {
36197
37117
  id: "router-pointers",
@@ -36200,13 +37120,13 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT2) {
36200
37120
  remedy: "reinstall the package \u2014 dist/router.json is corrupt"
36201
37121
  };
36202
37122
  }
36203
- const rulesDir = path64.join(packageRoot, "dist", "agent-src", "rules");
37123
+ const rulesDir = path66.join(packageRoot, "dist", "agent-src", "rules");
36204
37124
  const broken = [];
36205
37125
  let ids = 0;
36206
37126
  let targets = 0;
36207
37127
  for (const kernelId of router["kernel"] ?? []) {
36208
37128
  ids += 1;
36209
- if (!fs63.existsSync(path64.join(rulesDir, `${kernelId}.md`))) {
37129
+ if (!fs65.existsSync(path66.join(rulesDir, `${kernelId}.md`))) {
36210
37130
  broken.push(`kernel:${kernelId} \u2192 rules/${kernelId}.md missing`);
36211
37131
  }
36212
37132
  }
@@ -36214,7 +37134,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT2) {
36214
37134
  for (const entry of router[tier] ?? []) {
36215
37135
  const ruleId = String(entry["id"] ?? "");
36216
37136
  ids += 1;
36217
- if (!fs63.existsSync(path64.join(rulesDir, `${ruleId}.md`))) {
37137
+ if (!fs65.existsSync(path66.join(rulesDir, `${ruleId}.md`))) {
36218
37138
  broken.push(`${tier}:${ruleId} \u2192 rules/${ruleId}.md missing`);
36219
37139
  }
36220
37140
  for (const target of entry["routes_to"] ?? []) {
@@ -36224,7 +37144,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT2) {
36224
37144
  broken.push(`${ruleId} \u2192 unparseable routes_to ${JSON.stringify(target)}`);
36225
37145
  continue;
36226
37146
  }
36227
- if (!candidates.some((rel) => fs63.existsSync(path64.join(packageRoot, rel)))) {
37147
+ if (!candidates.some((rel) => fs65.existsSync(path66.join(packageRoot, rel)))) {
36228
37148
  broken.push(`${ruleId} \u2192 ${target} (${candidates[0]} missing)`);
36229
37149
  }
36230
37150
  }
@@ -36256,9 +37176,9 @@ function detectSmokePlatform(projectRoot) {
36256
37176
  return "claude";
36257
37177
  }
36258
37178
  function dispatcherRunner(packageRoot) {
36259
- const localTsx = path64.join(packageRoot, "node_modules", ".bin", "tsx");
36260
- const script = path64.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
36261
- if (fs63.existsSync(localTsx)) {
37179
+ const localTsx = path66.join(packageRoot, "node_modules", ".bin", "tsx");
37180
+ const script = path66.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
37181
+ if (fs65.existsSync(localTsx)) {
36262
37182
  return [localTsx, script];
36263
37183
  }
36264
37184
  return ["npx", "tsx", script];
@@ -36275,7 +37195,7 @@ function _check_hook_dispatcher(projectRoot, packageRoot = PACKAGE_ROOT2, opts =
36275
37195
  ...event === "stop" ? { stop_reason: "conformance-smoke" } : { source: "startup" }
36276
37196
  });
36277
37197
  const argv = [...runner, "--platform", platform, "--event", event];
36278
- const proc = spawnSync9(argv[0], argv.slice(1), {
37198
+ const proc = spawnSync10(argv[0], argv.slice(1), {
36279
37199
  input: payload,
36280
37200
  cwd: projectRoot,
36281
37201
  encoding: "utf8",
@@ -36308,12 +37228,12 @@ function _check_hook_dispatcher(projectRoot, packageRoot = PACKAGE_ROOT2, opts =
36308
37228
  };
36309
37229
  }
36310
37230
  function readSettingsMode(projectRoot) {
36311
- const settingsPath = path64.join(projectRoot, ".agent-settings.yml");
36312
- if (!fs63.existsSync(settingsPath)) {
37231
+ const settingsPath = path66.join(projectRoot, ".agent-settings.yml");
37232
+ if (!fs65.existsSync(settingsPath)) {
36313
37233
  return "eager-all";
36314
37234
  }
36315
37235
  try {
36316
- const parsed = YAML7.parse(fs63.readFileSync(settingsPath, "utf8"));
37236
+ const parsed = YAML7.parse(fs65.readFileSync(settingsPath, "utf8"));
36317
37237
  const lean = parsed?.["lean_projection"] ?? null;
36318
37238
  const mode = lean?.["mode"];
36319
37239
  return typeof mode === "string" && mode.length > 0 ? mode : "eager-all";
@@ -36324,7 +37244,7 @@ function readSettingsMode(projectRoot) {
36324
37244
  function kernelIdsFromRouter(packageRoot) {
36325
37245
  try {
36326
37246
  const router = JSON.parse(
36327
- fs63.readFileSync(path64.join(packageRoot, "dist", "router.json"), "utf8")
37247
+ fs65.readFileSync(path66.join(packageRoot, "dist", "router.json"), "utf8")
36328
37248
  );
36329
37249
  return new Set((router["kernel"] ?? []).map(String));
36330
37250
  } catch {
@@ -36341,8 +37261,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT2, projec
36341
37261
  remedy: "set lean_projection.mode to 'eager-all' or 'thin' in .agent-settings.yml"
36342
37262
  };
36343
37263
  }
36344
- const rulesDir = projectedRulesDir ?? path64.join(projectRoot, ".augment", "rules");
36345
- if (!fs63.existsSync(rulesDir)) {
37264
+ const rulesDir = projectedRulesDir ?? path66.join(projectRoot, ".augment", "rules");
37265
+ if (!fs65.existsSync(rulesDir)) {
36346
37266
  return {
36347
37267
  id: "lean-projection",
36348
37268
  status: "skipped",
@@ -36351,7 +37271,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT2, projec
36351
37271
  };
36352
37272
  }
36353
37273
  const kernel = kernelIdsFromRouter(packageRoot);
36354
- const files = fs63.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
37274
+ const files = fs65.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
36355
37275
  const nonKernel = files.filter((f) => !kernel.has(f.replace(/\.md$/, "")));
36356
37276
  if (nonKernel.length === 0) {
36357
37277
  return {
@@ -36365,7 +37285,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT2, projec
36365
37285
  for (const f of nonKernel) {
36366
37286
  let text = "";
36367
37287
  try {
36368
- text = fs63.readFileSync(path64.join(rulesDir, f), "utf8");
37288
+ text = fs65.readFileSync(path66.join(rulesDir, f), "utf8");
36369
37289
  } catch {
36370
37290
  continue;
36371
37291
  }
@@ -36396,8 +37316,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT2, projec
36396
37316
  function _check_host_manifest(projectRoot) {
36397
37317
  const detected = Object.entries(detectToolPresence(projectRoot)).filter(([, v]) => v === true).map(([k]) => k);
36398
37318
  const detectedNote = detected.length > 0 ? `detected surfaces: ${detected.join(", ")}` : "no surfaces detected";
36399
- const settingsPath = path64.join(projectRoot, ".agent-settings.yml");
36400
- if (!fs63.existsSync(settingsPath)) {
37319
+ const settingsPath = path66.join(projectRoot, ".agent-settings.yml");
37320
+ if (!fs65.existsSync(settingsPath)) {
36401
37321
  return {
36402
37322
  id: "host-manifest",
36403
37323
  status: "ok",
@@ -36407,7 +37327,7 @@ function _check_host_manifest(projectRoot) {
36407
37327
  }
36408
37328
  let parsed = null;
36409
37329
  try {
36410
- parsed = YAML7.parse(fs63.readFileSync(settingsPath, "utf8"));
37330
+ parsed = YAML7.parse(fs65.readFileSync(settingsPath, "utf8"));
36411
37331
  } catch (exc) {
36412
37332
  return {
36413
37333
  id: "host-manifest",
@@ -36505,7 +37425,7 @@ function _parse4(argv) {
36505
37425
  }
36506
37426
  return opts;
36507
37427
  }
36508
- function main29(argv = null) {
37428
+ function main31(argv = null) {
36509
37429
  const opts = _parse4(argv !== null ? Array.from(argv) : process19.argv.slice(2));
36510
37430
  if (opts.funnel) {
36511
37431
  print2(render6(buildFunnel()));
@@ -36576,17 +37496,17 @@ function main29(argv = null) {
36576
37496
  }
36577
37497
  return failed ? 1 : 0;
36578
37498
  }
36579
- function _isCliEntry26() {
37499
+ function _isCliEntry28() {
36580
37500
  if (process19.argv[1] === void 0) {
36581
37501
  return false;
36582
37502
  }
36583
- const argvUrl = pathToFileURL29(path64.resolve(process19.argv[1])).href;
37503
+ const argvUrl = pathToFileURL31(path66.resolve(process19.argv[1])).href;
36584
37504
  if (import.meta.url === argvUrl) {
36585
37505
  return true;
36586
37506
  }
36587
37507
  try {
36588
- const here = fs63.realpathSync(fileURLToPath40(import.meta.url));
36589
- const argv = fs63.realpathSync(path64.resolve(process19.argv[1]));
37508
+ const here = fs65.realpathSync(fileURLToPath42(import.meta.url));
37509
+ const argv = fs65.realpathSync(path66.resolve(process19.argv[1]));
36590
37510
  return here === argv;
36591
37511
  } catch {
36592
37512
  return false;
@@ -36605,7 +37525,7 @@ var init_cmd_conformance = __esm({
36605
37525
  init_router_target_paths();
36606
37526
  init_report_conformance_funnel();
36607
37527
  init_cmd_doctor();
36608
- _HERE21 = fileURLToPath40(import.meta.url);
37528
+ _HERE21 = fileURLToPath42(import.meta.url);
36609
37529
  PACKAGE_ROOT2 = resolvePackageRoot(import.meta.url);
36610
37530
  CONFORMANCE_CHECK_IDS = [
36611
37531
  "txlog-clean",
@@ -36616,9 +37536,9 @@ var init_cmd_conformance = __esm({
36616
37536
  ];
36617
37537
  THIN_STUB_MARKER = "Routed rule \u2014 load the body on trigger-match";
36618
37538
  USAGE3 = "usage: agent-config conformance [-h] [--project PROJECT] [--json]\n [--skip-dispatcher] [--funnel]\n";
36619
- if (_isCliEntry26() || process19.argv[1] === _HERE21) {
37539
+ if (_isCliEntry28() || process19.argv[1] === _HERE21) {
36620
37540
  try {
36621
- process19.exitCode = main29(process19.argv.slice(2));
37541
+ process19.exitCode = main31(process19.argv.slice(2));
36622
37542
  } catch (e) {
36623
37543
  if (e instanceof ArgparseExit4) {
36624
37544
  process19.exitCode = e.code;
@@ -36644,7 +37564,7 @@ __export(settings_exports, {
36644
37564
  read_tier_usage_settings: () => read_tier_usage_settings
36645
37565
  });
36646
37566
  import { createRequire as createRequire6 } from "node:module";
36647
- import * as fs64 from "node:fs";
37567
+ import * as fs66 from "node:fs";
36648
37568
  function _isPlainObject8(v) {
36649
37569
  return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Date);
36650
37570
  }
@@ -36681,7 +37601,7 @@ function _coerce_path(value, def) {
36681
37601
  }
36682
37602
  function _isFile13(p) {
36683
37603
  try {
36684
- return fs64.statSync(p).isFile();
37604
+ return fs66.statSync(p).isFile();
36685
37605
  } catch {
36686
37606
  return false;
36687
37607
  }
@@ -36692,7 +37612,7 @@ function read_settings(p) {
36692
37612
  if (_isFile13(p)) {
36693
37613
  let raw = {};
36694
37614
  try {
36695
- raw = YAML8.parse(fs64.readFileSync(p, "utf-8"), { version: "1.1" });
37615
+ raw = YAML8.parse(fs66.readFileSync(p, "utf-8"), { version: "1.1" });
36696
37616
  if (raw === null || raw === void 0) {
36697
37617
  raw = {};
36698
37618
  }
@@ -36726,7 +37646,7 @@ function read_tier_usage_settings(p) {
36726
37646
  if (_isFile13(p)) {
36727
37647
  let raw = {};
36728
37648
  try {
36729
- raw = YAML8.parse(fs64.readFileSync(p, "utf-8"), { version: "1.1" });
37649
+ raw = YAML8.parse(fs66.readFileSync(p, "utf-8"), { version: "1.1" });
36730
37650
  if (raw === null || raw === void 0) {
36731
37651
  raw = {};
36732
37652
  }
@@ -37264,7 +38184,7 @@ __export(aggregator_exports, {
37264
38184
  aggregate: () => aggregate2,
37265
38185
  rank_artefacts: () => rank_artefacts
37266
38186
  });
37267
- import * as fs65 from "node:fs";
38187
+ import * as fs67 from "node:fs";
37268
38188
  function _key(kind, artId) {
37269
38189
  return `${kind}\0${artId}`;
37270
38190
  }
@@ -37301,7 +38221,7 @@ function* _iter_events(log_path) {
37301
38221
  if (!_isFile14(log_path)) {
37302
38222
  return;
37303
38223
  }
37304
- const text = fs65.readFileSync(log_path, "utf-8");
38224
+ const text = fs67.readFileSync(log_path, "utf-8");
37305
38225
  const lines = _pyFileLines(text);
37306
38226
  let lineNo = 0;
37307
38227
  for (const line of lines) {
@@ -37335,7 +38255,7 @@ function _pyFileLines(text) {
37335
38255
  }
37336
38256
  function _isFile14(p) {
37337
38257
  try {
37338
- return fs65.statSync(p).isFile();
38258
+ return fs67.statSync(p).isFile();
37339
38259
  } catch {
37340
38260
  return false;
37341
38261
  }
@@ -37679,14 +38599,14 @@ function _pyRound5(value, ndigits = 0) {
37679
38599
  }
37680
38600
  const sign = value < 0 ? -1 : 1;
37681
38601
  const abs = Math.abs(value);
37682
- const str = abs.toPrecision(17);
37683
- if (str.includes("e") || str.includes("E")) {
38602
+ const str3 = abs.toPrecision(17);
38603
+ if (str3.includes("e") || str3.includes("E")) {
37684
38604
  const factor = 10 ** ndigits;
37685
38605
  return value > 0 ? Math.round(abs * factor) / factor * sign : -Math.round(abs * factor) / factor;
37686
38606
  }
37687
- const dot = str.indexOf(".");
37688
- const intPart = dot === -1 ? str : str.slice(0, dot);
37689
- let fracPart = dot === -1 ? "" : str.slice(dot + 1);
38607
+ const dot = str3.indexOf(".");
38608
+ const intPart = dot === -1 ? str3 : str3.slice(0, dot);
38609
+ let fracPart = dot === -1 ? "" : str3.slice(dot + 1);
37690
38610
  while (fracPart.length <= ndigits) {
37691
38611
  fracPart += "0";
37692
38612
  }
@@ -37714,13 +38634,13 @@ function _pyFixed(value, ndigits) {
37714
38634
  }
37715
38635
  const sign = value < 0 ? "-" : "";
37716
38636
  const abs = Math.abs(value);
37717
- const str = abs.toPrecision(17);
37718
- if (str.includes("e") || str.includes("E")) {
38637
+ const str3 = abs.toPrecision(17);
38638
+ if (str3.includes("e") || str3.includes("E")) {
37719
38639
  return sign + abs.toFixed(ndigits);
37720
38640
  }
37721
- const dot = str.indexOf(".");
37722
- const intPart = dot === -1 ? str : str.slice(0, dot);
37723
- let fracPart = dot === -1 ? "" : str.slice(dot + 1);
38641
+ const dot = str3.indexOf(".");
38642
+ const intPart = dot === -1 ? str3 : str3.slice(0, dot);
38643
+ let fracPart = dot === -1 ? "" : str3.slice(dot + 1);
37724
38644
  while (fracPart.length <= ndigits) {
37725
38645
  fracPart += "0";
37726
38646
  }
@@ -37849,7 +38769,7 @@ var init_report_renderer = __esm({
37849
38769
  });
37850
38770
 
37851
38771
  // src/scripts/ai_council/bundler.ts
37852
- import * as fs66 from "node:fs";
38772
+ import * as fs68 from "node:fs";
37853
38773
  function _context(mode, text, manifest = [], excluded = []) {
37854
38774
  return { mode, text, manifest, excluded };
37855
38775
  }
@@ -37907,10 +38827,10 @@ function bundle_prompt(text) {
37907
38827
  return _context("prompt", _enforceSize(redacted, "prompt"), ["<inline prompt>"]);
37908
38828
  }
37909
38829
  function bundle_roadmap(p) {
37910
- if (!fs66.existsSync(p)) {
38830
+ if (!fs68.existsSync(p)) {
37911
38831
  throw new FileNotFoundError2(`Roadmap not found: ${p}`);
37912
38832
  }
37913
- const raw = fs66.readFileSync(p, { encoding: "utf-8" });
38833
+ const raw = fs68.readFileSync(p, { encoding: "utf-8" });
37914
38834
  const redacted = redact(raw);
37915
38835
  return _context(
37916
38836
  "roadmap",
@@ -38521,8 +39441,8 @@ not. Cite the peer-reviewer label and the targeted response label
38521
39441
  });
38522
39442
 
38523
39443
  // src/scripts/ai_council/advisors.ts
38524
- import * as fs67 from "node:fs";
38525
- import * as path65 from "node:path";
39444
+ import * as fs69 from "node:fs";
39445
+ import * as path67 from "node:path";
38526
39446
  function _split_frontmatter2(raw) {
38527
39447
  const match = _FRONTMATTER_RE2.exec(raw);
38528
39448
  if (!match) {
@@ -38550,12 +39470,12 @@ function _display_name_from(advisor_name, frontmatter) {
38550
39470
  }
38551
39471
  function resolve_persona_text(persona_path, repo_root) {
38552
39472
  const candidates = [
38553
- path65.join(repo_root, "dist/agent-src", persona_path),
38554
- path65.join(repo_root, ".agent-src.uncondensed", persona_path)
39473
+ path67.join(repo_root, "dist/agent-src", persona_path),
39474
+ path67.join(repo_root, ".agent-src.uncondensed", persona_path)
38555
39475
  ];
38556
39476
  for (const candidate of candidates) {
38557
- if (fs67.existsSync(candidate)) {
38558
- const raw = fs67.readFileSync(candidate, "utf-8");
39477
+ if (fs69.existsSync(candidate)) {
39478
+ const raw = fs69.readFileSync(candidate, "utf-8");
38559
39479
  const [meta, body] = _split_frontmatter2(raw);
38560
39480
  return [body.trim(), meta];
38561
39481
  }
@@ -38859,7 +39779,7 @@ __export(low_impact_corpus_exports, {
38859
39779
  load_validated_phrases: () => load_validated_phrases,
38860
39780
  parse_corpus_strict: () => parse_corpus_strict
38861
39781
  });
38862
- import * as fs68 from "node:fs";
39782
+ import * as fs70 from "node:fs";
38863
39783
  function _entry(phrase, normalised, section, line_no, trailing_metadata = "") {
38864
39784
  return { phrase, normalised, section, line_no, trailing_metadata };
38865
39785
  }
@@ -39032,10 +39952,10 @@ function _checkHeadingDrift(text, title) {
39032
39952
  }
39033
39953
  function parse_corpus_strict(corpusPath) {
39034
39954
  const p = corpusPath;
39035
- if (!fs68.existsSync(p)) {
39955
+ if (!fs70.existsSync(p)) {
39036
39956
  return new CorpusParseResult();
39037
39957
  }
39038
- const text = fs68.readFileSync(p, { encoding: "utf-8" });
39958
+ const text = fs70.readFileSync(p, { encoding: "utf-8" });
39039
39959
  const allTitles = _SECTION_KEYS.map((k) => _SECTION_TITLES[k]);
39040
39960
  const resultSections = {
39041
39961
  validated: [],
@@ -39098,10 +40018,10 @@ function load_anti_example_phrases(corpusPath) {
39098
40018
  }
39099
40019
  function load_corpus_lock(yamlPath) {
39100
40020
  const p = yamlPath;
39101
- if (!fs68.existsSync(p)) {
40021
+ if (!fs70.existsSync(p)) {
39102
40022
  return new CorpusParseResult();
39103
40023
  }
39104
- const parsed = (0, import_yaml7.parse)(fs68.readFileSync(p, { encoding: "utf-8" }), { version: "1.1" });
40024
+ const parsed = (0, import_yaml7.parse)(fs70.readFileSync(p, { encoding: "utf-8" }), { version: "1.1" });
39105
40025
  const doc = parsed === null || parsed === void 0 ? {} : parsed;
39106
40026
  const schemaVersion = doc["schema_version"];
39107
40027
  if (schemaVersion !== 1) {
@@ -39163,7 +40083,7 @@ function _deriveLockPath(corpusPath) {
39163
40083
  }
39164
40084
  function _loadSectionFromLock(corpusPath, section) {
39165
40085
  const lockPath = _deriveLockPath(corpusPath);
39166
- if (!fs68.existsSync(lockPath)) {
40086
+ if (!fs70.existsSync(lockPath)) {
39167
40087
  return null;
39168
40088
  }
39169
40089
  try {
@@ -39175,10 +40095,10 @@ function _loadSectionFromLock(corpusPath, section) {
39175
40095
  }
39176
40096
  function _loadSectionLenient(corpusPath, section) {
39177
40097
  const p = corpusPath;
39178
- if (!fs68.existsSync(p)) {
40098
+ if (!fs70.existsSync(p)) {
39179
40099
  return [];
39180
40100
  }
39181
- const text = fs68.readFileSync(p, { encoding: "utf-8" });
40101
+ const text = fs70.readFileSync(p, { encoding: "utf-8" });
39182
40102
  const allTitles = _SECTION_KEYS.map((k) => _SECTION_TITLES[k]);
39183
40103
  const bounds = _sectionBounds(text, _SECTION_TITLES[section], allTitles);
39184
40104
  if (bounds === null) {
@@ -39958,8 +40878,8 @@ var init_necessity = __esm({
39958
40878
  });
39959
40879
 
39960
40880
  // src/scripts/ai_council/budget_guard.ts
39961
- import * as fs69 from "node:fs";
39962
- import * as path66 from "node:path";
40881
+ import * as fs71 from "node:fs";
40882
+ import * as path68 from "node:path";
39963
40883
  function _resolveLedgerPath(p) {
39964
40884
  if (p !== null) {
39965
40885
  return p;
@@ -39974,18 +40894,18 @@ function _nowUtcMs() {
39974
40894
  return Date.now();
39975
40895
  }
39976
40896
  function _ensureLedgerDir(p) {
39977
- const parent = path66.dirname(p);
40897
+ const parent = path68.dirname(p);
39978
40898
  try {
39979
- fs69.mkdirSync(parent, { recursive: true });
40899
+ fs71.mkdirSync(parent, { recursive: true });
39980
40900
  let mode;
39981
40901
  try {
39982
- mode = fs69.statSync(parent).mode & 511;
40902
+ mode = fs71.statSync(parent).mode & 511;
39983
40903
  } catch {
39984
40904
  mode = 448;
39985
40905
  }
39986
40906
  if (mode !== 448) {
39987
40907
  try {
39988
- fs69.chmodSync(parent, 448);
40908
+ fs71.chmodSync(parent, 448);
39989
40909
  } catch {
39990
40910
  }
39991
40911
  }
@@ -39997,18 +40917,18 @@ function _ensureLedgerDir(p) {
39997
40917
  }
39998
40918
  }
39999
40919
  function _ensureLedgerFileMode(p) {
40000
- if (!fs69.existsSync(p)) {
40920
+ if (!fs71.existsSync(p)) {
40001
40921
  return;
40002
40922
  }
40003
40923
  let current;
40004
40924
  try {
40005
- current = fs69.statSync(p).mode & 511;
40925
+ current = fs71.statSync(p).mode & 511;
40006
40926
  } catch {
40007
40927
  return;
40008
40928
  }
40009
40929
  if (current !== 384) {
40010
40930
  try {
40011
- fs69.chmodSync(p, 384);
40931
+ fs71.chmodSync(p, 384);
40012
40932
  } catch {
40013
40933
  }
40014
40934
  }
@@ -40160,11 +41080,11 @@ function pyNumToStr(n) {
40160
41080
  }
40161
41081
  function read_entries2(p = null) {
40162
41082
  const resolved = _resolveLedgerPath(p);
40163
- if (!fs69.existsSync(resolved)) {
41083
+ if (!fs71.existsSync(resolved)) {
40164
41084
  return [];
40165
41085
  }
40166
41086
  const out = [];
40167
- const text = fs69.readFileSync(resolved, "utf-8");
41087
+ const text = fs71.readFileSync(resolved, "utf-8");
40168
41088
  for (const rawLine of text.split(/\r\n|\r|\n/u)) {
40169
41089
  const line = rawLine.trim();
40170
41090
  if (line === "") {
@@ -40267,7 +41187,7 @@ function record_spend(usd, provider, model, options = {}) {
40267
41187
  )}
40268
41188
  `;
40269
41189
  try {
40270
- fs69.appendFileSync(p, entry, { encoding: "utf-8" });
41190
+ fs71.appendFileSync(p, entry, { encoding: "utf-8" });
40271
41191
  } catch (exc) {
40272
41192
  process.stderr.write(`[council:budget_guard] write failed: ${_errStr(exc)}
40273
41193
  `);
@@ -40283,12 +41203,12 @@ function _pyRound6(value) {
40283
41203
  const ndigits = 6;
40284
41204
  const sign = value < 0 ? -1 : 1;
40285
41205
  const abs = Math.abs(value);
40286
- const str = abs.toPrecision(17);
40287
- if (str.includes("e") || str.includes("E")) {
41206
+ const str3 = abs.toPrecision(17);
41207
+ if (str3.includes("e") || str3.includes("E")) {
40288
41208
  const factor = 10 ** ndigits;
40289
41209
  return value > 0 ? Math.round(abs * factor) / factor * sign : -Math.round(abs * factor) / factor;
40290
41210
  }
40291
- const [intPart, fracPartRaw = ""] = str.split(".");
41211
+ const [intPart, fracPartRaw = ""] = str3.split(".");
40292
41212
  let fracPart = fracPartRaw;
40293
41213
  while (fracPart.length <= ndigits) {
40294
41214
  fracPart += "0";
@@ -40329,12 +41249,12 @@ function pyRound(value, ndigits = 0) {
40329
41249
  }
40330
41250
  const sign = value < 0 ? -1 : 1;
40331
41251
  const abs = Math.abs(value);
40332
- let str = abs.toPrecision(17);
40333
- if (str.includes("e") || str.includes("E")) {
41252
+ let str3 = abs.toPrecision(17);
41253
+ if (str3.includes("e") || str3.includes("E")) {
40334
41254
  const factor2 = 10 ** ndigits;
40335
41255
  return value > 0 ? Math.round(abs * factor2) / factor2 * sign : -Math.round(abs * factor2) / factor2;
40336
41256
  }
40337
- let [intPart, fracPart = ""] = str.split(".");
41257
+ let [intPart, fracPart = ""] = str3.split(".");
40338
41258
  while (fracPart.length <= ndigits) {
40339
41259
  fracPart += "0";
40340
41260
  }
@@ -40390,8 +41310,8 @@ function aggregate_scores(findings, scores) {
40390
41310
  by_id.get(s.finding_id).push(s);
40391
41311
  }
40392
41312
  const out = /* @__PURE__ */ new Map();
40393
- for (const [fid, fs74] of by_id) {
40394
- if (fs74.length === 0) {
41313
+ for (const [fid, fs76] of by_id) {
41314
+ if (fs76.length === 0) {
40395
41315
  out.set(
40396
41316
  fid,
40397
41317
  new ConsensusMetadata({
@@ -40407,13 +41327,13 @@ function aggregate_scores(findings, scores) {
40407
41327
  );
40408
41328
  continue;
40409
41329
  }
40410
- const mean2 = fs74.reduce((acc, s) => acc + s.score, 0) / fs74.length;
40411
- const agree_rate = fs74.filter((s) => s.agree).length / fs74.length;
41330
+ const mean2 = fs76.reduce((acc, s) => acc + s.score, 0) / fs76.length;
41331
+ const agree_rate = fs76.filter((s) => s.agree).length / fs76.length;
40412
41332
  const strength = mean2 / 10 * agree_rate;
40413
- const dissent = fs74.filter((s) => !s.agree).length;
40414
- const concur = fs74.filter((s) => s.agree).length;
40415
- const scorers = fs74.map((s) => s.scorer);
40416
- const dissent_reasons = fs74.filter((s) => !s.agree).map((s) => [s.scorer, s.reason]);
41333
+ const dissent = fs76.filter((s) => !s.agree).length;
41334
+ const concur = fs76.filter((s) => s.agree).length;
41335
+ const scorers = fs76.map((s) => s.scorer);
41336
+ const dissent_reasons = fs76.filter((s) => !s.agree).map((s) => [s.scorer, s.reason]);
40417
41337
  const mean_rounded = pyRound(mean2, 2);
40418
41338
  out.set(
40419
41339
  fid,
@@ -40888,9 +41808,9 @@ var init_stance_tally = __esm({
40888
41808
  });
40889
41809
 
40890
41810
  // src/scripts/ai_council/blind_review.ts
40891
- import { createHash as createHash9 } from "node:crypto";
41811
+ import { createHash as createHash11 } from "node:crypto";
40892
41812
  function _sha256_hex(s) {
40893
- return createHash9("sha256").update(s, "utf-8").digest("hex");
41813
+ return createHash11("sha256").update(s, "utf-8").digest("hex");
40894
41814
  }
40895
41815
  function deterministic_shuffle_indices(seed, n) {
40896
41816
  const keyed = Array.from({ length: n }, (_, i) => ({ i, key: _sha256_hex(`${seed}\0${i}`) }));
@@ -42348,18 +43268,18 @@ __export(project_context_exports, {
42348
43268
  REPO_PURPOSE_MAX_CHARS: () => REPO_PURPOSE_MAX_CHARS,
42349
43269
  detect_project_context: () => detect_project_context
42350
43270
  });
42351
- import * as fs70 from "node:fs";
42352
- import * as path67 from "node:path";
43271
+ import * as fs72 from "node:fs";
43272
+ import * as path69 from "node:path";
42353
43273
  function _isPlainObject11(v) {
42354
43274
  return typeof v === "object" && v !== null && !Array.isArray(v);
42355
43275
  }
42356
43276
  function _read_json(p) {
42357
- if (!fs70.existsSync(p)) {
43277
+ if (!fs72.existsSync(p)) {
42358
43278
  return null;
42359
43279
  }
42360
43280
  let raw;
42361
43281
  try {
42362
- raw = fs70.readFileSync(p, "utf-8");
43282
+ raw = fs72.readFileSync(p, "utf-8");
42363
43283
  } catch {
42364
43284
  return null;
42365
43285
  }
@@ -42381,7 +43301,7 @@ function _name_from(composer, pkg, root) {
42381
43301
  }
42382
43302
  }
42383
43303
  try {
42384
- const base = path67.basename(root);
43304
+ const base = path69.basename(root);
42385
43305
  return base || null;
42386
43306
  } catch {
42387
43307
  return null;
@@ -42450,12 +43370,12 @@ function _splitlines10(text) {
42450
43370
  return parts;
42451
43371
  }
42452
43372
  function _purpose_from_readme(p) {
42453
- if (!fs70.existsSync(p)) {
43373
+ if (!fs72.existsSync(p)) {
42454
43374
  return null;
42455
43375
  }
42456
43376
  let text;
42457
43377
  try {
42458
- text = fs70.readFileSync(p, "utf-8");
43378
+ text = fs72.readFileSync(p, "utf-8");
42459
43379
  } catch {
42460
43380
  return null;
42461
43381
  }
@@ -42539,13 +43459,13 @@ function _rfind(haystack, needle) {
42539
43459
  return -1;
42540
43460
  }
42541
43461
  function detect_project_context(root) {
42542
- const resolvedRoot = path67.resolve(root ?? process.cwd());
42543
- const composer = _read_json(path67.join(resolvedRoot, "composer.json"));
42544
- const pkg = _read_json(path67.join(resolvedRoot, "package.json"));
43462
+ const resolvedRoot = path69.resolve(root ?? process.cwd());
43463
+ const composer = _read_json(path69.join(resolvedRoot, "composer.json"));
43464
+ const pkg = _read_json(path69.join(resolvedRoot, "package.json"));
42545
43465
  return new ProjectContext(
42546
43466
  _name_from(composer, pkg, resolvedRoot),
42547
43467
  _stack_from(composer, pkg),
42548
- _purpose_from_readme(path67.join(resolvedRoot, "README.md"))
43468
+ _purpose_from_readme(path69.join(resolvedRoot, "README.md"))
42549
43469
  );
42550
43470
  }
42551
43471
  var REPO_PURPOSE_MAX_CHARS, _HEADING_RE, _BADGE_RE, _HTML_RE, ProjectContext;
@@ -42815,8 +43735,8 @@ __export(shadow_dispatch_exports, {
42815
43735
  slo_banner: () => slo_banner,
42816
43736
  slo_status: () => slo_status
42817
43737
  });
42818
- import * as fs71 from "node:fs";
42819
- import { createHash as createHash10 } from "node:crypto";
43738
+ import * as fs73 from "node:fs";
43739
+ import { createHash as createHash12 } from "node:crypto";
42820
43740
  function should_shadow(sampleRate, opts = {}) {
42821
43741
  const rate = Math.max(0, Math.min(1, sampleRate));
42822
43742
  const rng = opts.rng ?? null;
@@ -42825,7 +43745,7 @@ function should_shadow(sampleRate, opts = {}) {
42825
43745
  }
42826
43746
  function _hashQuery(query) {
42827
43747
  const redacted = redact(query);
42828
- return createHash10("sha256").update(Buffer.from(redacted, "utf-8")).digest("hex").slice(0, 16);
43748
+ return createHash12("sha256").update(Buffer.from(redacted, "utf-8")).digest("hex").slice(0, 16);
42829
43749
  }
42830
43750
  function _privacyDropped(redacted) {
42831
43751
  const stripped = _strip7(redacted);
@@ -42853,7 +43773,7 @@ function record_shadow_decision(logPath, opts) {
42853
43773
  escalated,
42854
43774
  escalation_reason: escalationReason
42855
43775
  };
42856
- fs71.mkdirSync(_dirname2(logPath), { recursive: true });
43776
+ fs73.mkdirSync(_dirname2(logPath), { recursive: true });
42857
43777
  const row = _pyJsonDumps2({
42858
43778
  timestamp: decision.timestamp,
42859
43779
  query_hash: decision.query_hash,
@@ -42863,7 +43783,7 @@ function record_shadow_decision(logPath, opts) {
42863
43783
  escalated: decision.escalated,
42864
43784
  escalation_reason: decision.escalation_reason
42865
43785
  }) + "\n";
42866
- fs71.appendFileSync(logPath, row, { encoding: "utf-8" });
43786
+ fs73.appendFileSync(logPath, row, { encoding: "utf-8" });
42867
43787
  return decision;
42868
43788
  }
42869
43789
  function _isoNowSeconds() {
@@ -42872,10 +43792,10 @@ function _isoNowSeconds() {
42872
43792
  return `${pad(d.getUTCFullYear(), 4)}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())}T${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}+00:00`;
42873
43793
  }
42874
43794
  function* _iterLog(logPath) {
42875
- if (!fs71.existsSync(logPath)) {
43795
+ if (!fs73.existsSync(logPath)) {
42876
43796
  return;
42877
43797
  }
42878
- const content = fs71.readFileSync(logPath, { encoding: "utf-8" });
43798
+ const content = fs73.readFileSync(logPath, { encoding: "utf-8" });
42879
43799
  for (const rawLine of _splitlines11(content)) {
42880
43800
  const line = _strip7(rawLine);
42881
43801
  if (!line) {
@@ -43796,11 +44716,11 @@ __export(council_cli_exports, {
43796
44716
  cmd_status: () => cmd_status,
43797
44717
  format_estimate_table: () => format_estimate_table,
43798
44718
  load_settings: () => load_settings,
43799
- main: () => main30
44719
+ main: () => main32
43800
44720
  });
43801
- import * as fs72 from "node:fs";
43802
- import * as path68 from "node:path";
43803
- import { fileURLToPath as fileURLToPath41, pathToFileURL as pathToFileURL30 } from "node:url";
44721
+ import * as fs74 from "node:fs";
44722
+ import * as path70 from "node:path";
44723
+ import { fileURLToPath as fileURLToPath43, pathToFileURL as pathToFileURL32 } from "node:url";
43804
44724
  function _pyFixed6(x, ndigits) {
43805
44725
  if (!Number.isFinite(x)) {
43806
44726
  return String(x);
@@ -44008,7 +44928,7 @@ function _stderr2(s) {
44008
44928
  function load_settings(p = SETTINGS_FILE2, opts = {}) {
44009
44929
  const ai_council_path = opts.ai_council_path ?? AI_COUNCIL_FILE;
44010
44930
  const settings = load_agent_settings({ project_path: p });
44011
- if (fs72.existsSync(ai_council_path)) {
44931
+ if (fs74.existsSync(ai_council_path)) {
44012
44932
  const cfg = load_council_config(ai_council_path);
44013
44933
  settings["ai_council"] = _synthesize_ai_council_block(cfg);
44014
44934
  }
@@ -44188,11 +45108,11 @@ function _postRunQuorum(members, responses, ai_cfg) {
44188
45108
  for (let i = 0; i < members.length; i++) {
44189
45109
  const m = members[i];
44190
45110
  const r = responses[i];
44191
- if (r !== void 0 && !r.error) {
45111
+ if (r !== void 0 && !r.error && r.text.trim() !== "") {
44192
45112
  present += 1;
44193
45113
  continue;
44194
45114
  }
44195
- const raw = r?.error ?? "no response";
45115
+ const raw = r?.error ?? (r !== void 0 && r.text.trim() === "" ? "empty response body" : "no response");
44196
45116
  const failure = classifyCliFailure(raw);
44197
45117
  absent.push({
44198
45118
  member: m.name,
@@ -44204,7 +45124,8 @@ function _postRunQuorum(members, responses, ai_cfg) {
44204
45124
  }
44205
45125
  function _format_quorum_line(q) {
44206
45126
  const verdict = q.status === "concluded" ? "concluded" : "INCONCLUSIVE \u2014 release gate holds";
44207
- return `council:quorum \xB7 ${q.present}/${q.total} present, needed ${q.threshold} \u2014 ${verdict}.`;
45127
+ const degraded = q.present < q.total ? ` \u26A0\uFE0F DEGRADED \u2014 ${String(q.total - q.present)} member(s) did not answer; this is not convergence.` : "";
45128
+ return `council:quorum \xB7 ${q.present}/${q.total} present, needed ${q.threshold} \u2014 ${verdict}.${degraded}`;
44208
45129
  }
44209
45130
  function build_members(settings, opts = {}) {
44210
45131
  const invocation_mode = opts.invocation_mode ?? null;
@@ -44515,7 +45436,7 @@ function build_question(opts) {
44515
45436
  let ctx;
44516
45437
  let artefact;
44517
45438
  if (input_mode === "prompt") {
44518
- const text = fs72.readFileSync(input_path, "utf-8");
45439
+ const text = fs74.readFileSync(input_path, "utf-8");
44519
45440
  ctx = bundle_prompt(text);
44520
45441
  artefact = String(input_path);
44521
45442
  } else if (input_mode === "roadmap") {
@@ -44658,9 +45579,9 @@ function _maybe_write_decision_replay(opts) {
44658
45579
  include_member_arguments: include_args
44659
45580
  })
44660
45581
  );
44661
- const target = path68.join(path68.dirname(opts.out_path), "decision-replay.md");
44662
- fs72.mkdirSync(path68.dirname(target), { recursive: true });
44663
- fs72.writeFileSync(target, replay, { encoding: "utf-8" });
45582
+ const target = path70.join(path70.dirname(opts.out_path), "decision-replay.md");
45583
+ fs74.mkdirSync(path70.dirname(target), { recursive: true });
45584
+ fs74.writeFileSync(target, replay, { encoding: "utf-8" });
44664
45585
  return target;
44665
45586
  }
44666
45587
  function _peer_review_active(ai_cfg, args) {
@@ -45335,11 +46256,21 @@ function _emit_shadow_slo_banner() {
45335
46256
  return;
45336
46257
  }
45337
46258
  }
46259
+ function _resolvedTransportFor(name, member, report2) {
46260
+ return resolveMemberTransport({
46261
+ provider: name,
46262
+ report: report2 ?? detectEnvironment(),
46263
+ invocationMode: null,
46264
+ memberSettings: null,
46265
+ globalMode: "auto",
46266
+ binaryOverride: member.binary
46267
+ });
46268
+ }
45338
46269
  function cmd_status(args, opts = {}) {
45339
46270
  const env = opts.env ?? process.env;
45340
46271
  const override = env[COUNCIL_CONFIG_ENV];
45341
46272
  const path_ = resolve_config_path(REPO_ROOT11, { env });
45342
- const exists3 = fs72.existsSync(String(path_));
46273
+ const exists3 = fs74.existsSync(String(path_));
45343
46274
  const provenance = override ? `${COUNCIL_CONFIG_ENV} override` : "user-global";
45344
46275
  let cfg = null;
45345
46276
  let parse_error = null;
@@ -45363,6 +46294,21 @@ function cmd_status(args, opts = {}) {
45363
46294
  members_total: cfg === null ? null : cfg.members.size,
45364
46295
  members_enabled: cfg === null ? null : enabledMembers.length,
45365
46296
  member_names: enabledMembers.map(([n]) => n),
46297
+ transports: Object.fromEntries(
46298
+ enabledMembers.map(([n, m]) => {
46299
+ const t = _resolvedTransportFor(n, m);
46300
+ return [
46301
+ n,
46302
+ {
46303
+ available: t.available,
46304
+ transport: t.available ? t.transport : null,
46305
+ billing: t.available ? t.billing : null,
46306
+ reason: t.reason
46307
+ }
46308
+ ];
46309
+ })
46310
+ ),
46311
+ ignored_transport_keys: cfg?.ignored_transport_keys ?? [],
45366
46312
  parse_error,
45367
46313
  project_tree_consulted: false
45368
46314
  })}
@@ -45391,6 +46337,22 @@ function cmd_status(args, opts = {}) {
45391
46337
  _stdout2(` ${enabledMembers.map(([n]) => n).join(", ")}
45392
46338
  `);
45393
46339
  }
46340
+ for (const [name, member] of enabledMembers) {
46341
+ const t = _resolvedTransportFor(name, member);
46342
+ const billing = t.available ? ` \xB7 ${t.billing}` : "";
46343
+ const detail = t.available ? t.transport : `unavailable \u2014 ${t.reason ?? "no usable transport"}`;
46344
+ _stdout2(` transport ${name}: ${detail}${billing}
46345
+ `);
46346
+ }
46347
+ if (cfg.ignored_transport_keys.length > 0) {
46348
+ _stdout2("\n");
46349
+ _stdout2(" Ignored transport keys \u2014 transport is resolved, not configured:\n");
46350
+ for (const key of cfg.ignored_transport_keys) {
46351
+ _stdout2(` ${key}
46352
+ `);
46353
+ }
46354
+ _stdout2(" Safe to delete from the config file; they change nothing.\n");
46355
+ }
45394
46356
  }
45395
46357
  _stdout2("\n");
45396
46358
  _stdout2(" The project tree is NEVER consulted (ADR-104). No project file \u2014\n");
@@ -45573,6 +46535,7 @@ function cmd_run(args, opts = {}) {
45573
46535
  );
45574
46536
  return 0;
45575
46537
  }
46538
+ _validate_council_output_path(args.output, { kind: "responses", subcommand: "run" });
45576
46539
  const cost_cfg = ai_cfg["cost_budget"] || {};
45577
46540
  const budget = new CostBudget({
45578
46541
  max_input_tokens: _pyInt6(cost_cfg["max_input_tokens"] ?? 5e4, 5e4),
@@ -45716,8 +46679,8 @@ function cmd_run(args, opts = {}) {
45716
46679
  kind: "responses",
45717
46680
  subcommand: "run"
45718
46681
  });
45719
- fs72.mkdirSync(path68.dirname(_resolveTarget(out_path)), { recursive: true });
45720
- fs72.writeFileSync(_resolveTarget(out_path), _jsonDumpsIndent22(payload) + "\n", { encoding: "utf-8" });
46682
+ fs74.mkdirSync(path70.dirname(_resolveTarget(out_path)), { recursive: true });
46683
+ fs74.writeFileSync(_resolveTarget(out_path), _jsonDumpsIndent22(payload) + "\n", { encoding: "utf-8" });
45721
46684
  _stdout2(
45722
46685
  `
45723
46686
  council:run \xB7 wrote ${out_path} (estimated $${_pyFixed6(estimated_total, 4)} / actual $${_pyFixed6(actual_total, 4)})
@@ -45742,7 +46705,7 @@ function _debate_round_filename(round_number) {
45742
46705
  return `debate-round-${round_number}.json`;
45743
46706
  }
45744
46707
  function _write_debate_round(out_dir, round_number, responses, opts) {
45745
- fs72.mkdirSync(_resolveTarget(out_dir), { recursive: true });
46708
+ fs74.mkdirSync(_resolveTarget(out_dir), { recursive: true });
45746
46709
  let actual_total = 0;
45747
46710
  for (const r of responses) {
45748
46711
  if (r.error) {
@@ -45766,15 +46729,15 @@ function _write_debate_round(out_dir, round_number, responses, opts) {
45766
46729
  prompt_cache_round_gap_ms: opts.cache_gap_ms_since_previous_round ?? null,
45767
46730
  responses: _serialise_responses(responses)
45768
46731
  };
45769
- const out_path = path68.join(_resolveTarget(out_dir), _debate_round_filename(round_number));
45770
- fs72.writeFileSync(out_path, _jsonDumpsIndent22(payload) + "\n", { encoding: "utf-8" });
46732
+ const out_path = path70.join(_resolveTarget(out_dir), _debate_round_filename(round_number));
46733
+ fs74.writeFileSync(out_path, _jsonDumpsIndent22(payload) + "\n", { encoding: "utf-8" });
45771
46734
  return out_path;
45772
46735
  }
45773
46736
  function _load_debate_seed(p, expected_members) {
45774
- if (!fs72.existsSync(p)) {
46737
+ if (!fs74.existsSync(p)) {
45775
46738
  throw new FileNotFoundError3(`--continue-as-debate path not found: ${p}`);
45776
46739
  }
45777
- const payload = JSON.parse(fs72.readFileSync(p, "utf-8"));
46740
+ const payload = JSON.parse(fs74.readFileSync(p, "utf-8"));
45778
46741
  const source_members = (payload["members"] || []).slice();
45779
46742
  const expected_labels = expected_members.map((m) => `${m.name}/${m.model}`);
45780
46743
  if (!_listEq(source_members, expected_labels)) {
@@ -45820,7 +46783,7 @@ function _readStdinLine() {
45820
46783
  try {
45821
46784
  const buf = Buffer.alloc(4096);
45822
46785
  const fd = 0;
45823
- const n = fs72.readSync(fd, buf, 0, buf.length, null);
46786
+ const n = fs74.readSync(fd, buf, 0, buf.length, null);
45824
46787
  return buf.toString("utf-8", 0, n).split("\n")[0]?.trim().toLowerCase() ?? "";
45825
46788
  } catch {
45826
46789
  return "";
@@ -46049,7 +47012,7 @@ council:debate \xB7 ${all_rounds.length} round(s) complete \xB7 actual $${_pyFix
46049
47012
  return errors_last.length > 0 && errors_last.length === last.length ? 1 : 0;
46050
47013
  }
46051
47014
  function cmd_render(args) {
46052
- const payload = JSON.parse(fs72.readFileSync(args.responses, "utf-8"));
47015
+ const payload = JSON.parse(fs74.readFileSync(args.responses, "utf-8"));
46053
47016
  const items = payload["responses"] || [];
46054
47017
  const explicit = _getattr3(args, "prompt_mode", null);
46055
47018
  const mode = explicit || payload["prompt_mode"] || payload["mode"];
@@ -46078,8 +47041,8 @@ function cmd_render(args) {
46078
47041
  kind: "sessions",
46079
47042
  subcommand: "render"
46080
47043
  });
46081
- fs72.mkdirSync(path68.dirname(_resolveTarget(out_path)), { recursive: true });
46082
- fs72.writeFileSync(_resolveTarget(out_path), body + "\n", { encoding: "utf-8" });
47044
+ fs74.mkdirSync(path70.dirname(_resolveTarget(out_path)), { recursive: true });
47045
+ fs74.writeFileSync(_resolveTarget(out_path), body + "\n", { encoding: "utf-8" });
46083
47046
  _stdout2(`council:render \xB7 wrote ${out_path}
46084
47047
  `);
46085
47048
  return 0;
@@ -46090,15 +47053,15 @@ function cmd_render(args) {
46090
47053
  function _cmd_replay_low_impact_stats(args) {
46091
47054
  const li = low_impact_exports;
46092
47055
  const responses_path = args.responses;
46093
- const log_path = path68.join(path68.dirname(responses_path), "low-impact-resolutions.md");
46094
- if (!fs72.existsSync(log_path)) {
47056
+ const log_path = path70.join(path70.dirname(responses_path), "low-impact-resolutions.md");
47057
+ if (!fs74.existsSync(log_path)) {
46095
47058
  _stdout2(
46096
47059
  `council:replay \xB7 no low-impact-resolutions.md alongside ${responses_path} \u2014 session had no fast-path entries.
46097
47060
  `
46098
47061
  );
46099
47062
  return 0;
46100
47063
  }
46101
- const body = fs72.readFileSync(log_path, "utf-8");
47064
+ const body = fs74.readFileSync(log_path, "utf-8");
46102
47065
  const stats = li.parse_low_impact_log(body);
46103
47066
  const out = li.render_low_impact_stats(stats);
46104
47067
  if (_getattr3(args, "output", null)) {
@@ -46106,8 +47069,8 @@ function _cmd_replay_low_impact_stats(args) {
46106
47069
  kind: "sessions",
46107
47070
  subcommand: "replay"
46108
47071
  });
46109
- fs72.mkdirSync(path68.dirname(_resolveTarget(target)), { recursive: true });
46110
- fs72.writeFileSync(_resolveTarget(target), out, { encoding: "utf-8" });
47072
+ fs74.mkdirSync(path70.dirname(_resolveTarget(target)), { recursive: true });
47073
+ fs74.writeFileSync(_resolveTarget(target), out, { encoding: "utf-8" });
46111
47074
  _stdout2(`council:replay \xB7 wrote ${target}
46112
47075
  `);
46113
47076
  return 0;
@@ -46119,7 +47082,7 @@ function cmd_replay(args) {
46119
47082
  if (_getattr3(args, "low_impact_stats", false)) {
46120
47083
  return _cmd_replay_low_impact_stats(args);
46121
47084
  }
46122
- const payload = JSON.parse(fs72.readFileSync(args.responses, "utf-8"));
47085
+ const payload = JSON.parse(fs74.readFileSync(args.responses, "utf-8"));
46123
47086
  const consensus = _deserialise_consensus(payload["consensus"]);
46124
47087
  if (consensus === null) {
46125
47088
  _stderr2(
@@ -46144,8 +47107,8 @@ function cmd_replay(args) {
46144
47107
  kind: "sessions",
46145
47108
  subcommand: "replay"
46146
47109
  });
46147
- fs72.mkdirSync(path68.dirname(_resolveTarget(out_path)), { recursive: true });
46148
- fs72.writeFileSync(_resolveTarget(out_path), body, { encoding: "utf-8" });
47110
+ fs74.mkdirSync(path70.dirname(_resolveTarget(out_path)), { recursive: true });
47111
+ fs74.writeFileSync(_resolveTarget(out_path), body, { encoding: "utf-8" });
46149
47112
  _stdout2(`council:replay \xB7 wrote ${out_path}
46150
47113
  `);
46151
47114
  } else {
@@ -46202,8 +47165,8 @@ function cmd_quota(args, opts = {}) {
46202
47165
  }
46203
47166
  function _validate_council_output_path(path_str, opts) {
46204
47167
  const expected_rel = COUNCIL_CANONICAL_DIRS[opts.kind];
46205
- const expected_abs = _resolveReal(path68.join(REPO_ROOT11, expected_rel));
46206
- const target = path68.isAbsolute(path_str) ? path_str : path68.join(REPO_ROOT11, path_str);
47168
+ const expected_abs = _resolveReal(path70.join(REPO_ROOT11, expected_rel));
47169
+ const target = path70.isAbsolute(path_str) ? path_str : path70.join(REPO_ROOT11, path_str);
46207
47170
  const target_resolved = _resolveReal(target);
46208
47171
  if (!_isRelativeTo(target_resolved, expected_abs)) {
46209
47172
  throw new ArgumentTypeError(
@@ -46213,12 +47176,12 @@ function _validate_council_output_path(path_str, opts) {
46213
47176
  return path_str;
46214
47177
  }
46215
47178
  function _resolveTarget(path_str) {
46216
- return path68.isAbsolute(path_str) ? path_str : path68.join(REPO_ROOT11, path_str);
47179
+ return path70.isAbsolute(path_str) ? path_str : path70.join(REPO_ROOT11, path_str);
46217
47180
  }
46218
47181
  function _resolveReal(p) {
46219
- const abs = path68.resolve(p);
47182
+ const abs = path70.resolve(p);
46220
47183
  try {
46221
- return fs72.realpathSync(abs);
47184
+ return fs74.realpathSync(abs);
46222
47185
  } catch {
46223
47186
  return abs;
46224
47187
  }
@@ -46227,8 +47190,8 @@ function _isRelativeTo(target, base) {
46227
47190
  if (target === base) {
46228
47191
  return true;
46229
47192
  }
46230
- const rel = path68.relative(base, target);
46231
- return rel !== "" && !rel.startsWith("..") && !path68.isAbsolute(rel);
47193
+ const rel = path70.relative(base, target);
47194
+ return rel !== "" && !rel.startsWith("..") && !path70.isAbsolute(rel);
46232
47195
  }
46233
47196
  function _topError(message) {
46234
47197
  _stderr2(_TOP_USAGE2);
@@ -46553,7 +47516,7 @@ function _parse_siblings_overrides(items) {
46553
47516
  function _isFileNotFound(exc) {
46554
47517
  return exc instanceof FileNotFoundError3 || exc instanceof Error && exc.code === "ENOENT";
46555
47518
  }
46556
- function main30(argv = null) {
47519
+ function main32(argv = null) {
46557
47520
  const args = _parseArgs7(argv ?? process.argv.slice(2));
46558
47521
  try {
46559
47522
  if (args.cmd === "estimate") {
@@ -46595,17 +47558,17 @@ function main30(argv = null) {
46595
47558
  }
46596
47559
  return 1;
46597
47560
  }
46598
- function _isCliEntry27() {
47561
+ function _isCliEntry29() {
46599
47562
  if (process.argv[1] === void 0) {
46600
47563
  return false;
46601
47564
  }
46602
- const argvUrl = pathToFileURL30(path68.resolve(process.argv[1])).href;
47565
+ const argvUrl = pathToFileURL32(path70.resolve(process.argv[1])).href;
46603
47566
  if (import.meta.url === argvUrl) {
46604
47567
  return true;
46605
47568
  }
46606
47569
  try {
46607
- const here = fs72.realpathSync(fileURLToPath41(import.meta.url));
46608
- const argv = fs72.realpathSync(path68.resolve(process.argv[1]));
47570
+ const here = fs74.realpathSync(fileURLToPath43(import.meta.url));
47571
+ const argv = fs74.realpathSync(path70.resolve(process.argv[1]));
46609
47572
  return here === argv;
46610
47573
  } catch {
46611
47574
  return false;
@@ -46663,7 +47626,7 @@ var init_council_cli = __esm({
46663
47626
  "xai",
46664
47627
  "perplexity"
46665
47628
  ]);
46666
- _HERE22 = path68.dirname(fileURLToPath41(import.meta.url));
47629
+ _HERE22 = path70.dirname(fileURLToPath43(import.meta.url));
46667
47630
  [REPO_ROOT11] = resolve_project_root(null);
46668
47631
  SETTINGS_FILE2 = project_settings_path(REPO_ROOT11);
46669
47632
  AI_COUNCIL_FILE = resolve_config_path(REPO_ROOT11);
@@ -46696,9 +47659,9 @@ var init_council_cli = __esm({
46696
47659
  {estimate,run,debate,render,replay,quota,shadow-report,status}
46697
47660
  ...
46698
47661
  `;
46699
- if (_isCliEntry27()) {
47662
+ if (_isCliEntry29()) {
46700
47663
  try {
46701
- process.exitCode = main30(process.argv.slice(2));
47664
+ process.exitCode = main32(process.argv.slice(2));
46702
47665
  } catch (err) {
46703
47666
  if (!(err instanceof _ArgExit2)) {
46704
47667
  throw err;
@@ -46727,7 +47690,7 @@ function run_enveloped(spec) {
46727
47690
  if (cmd === void 0) {
46728
47691
  throw new Error("envelope argv must not be empty");
46729
47692
  }
46730
- return new Promise((resolve40) => {
47693
+ return new Promise((resolve42) => {
46731
47694
  execFile(
46732
47695
  cmd,
46733
47696
  args,
@@ -46750,7 +47713,7 @@ function run_enveloped(spec) {
46750
47713
  }
46751
47714
  const [out, outTrunc] = _truncate(String(stdout ?? ""), spec.max_output_bytes);
46752
47715
  const [err, errTrunc] = _truncate(String(stderr ?? ""), spec.max_output_bytes);
46753
- resolve40({
47716
+ resolve42({
46754
47717
  exit_code: timedOut ? null : exitCode,
46755
47718
  timed_out: timedOut,
46756
47719
  stdout: out,
@@ -46771,8 +47734,8 @@ var init_safety_envelope = __esm({
46771
47734
  });
46772
47735
 
46773
47736
  // src/scripts/mcp_server/__main__.ts
46774
- import * as path70 from "node:path";
46775
- import { fileURLToPath as fileURLToPath43 } from "node:url";
47737
+ import * as path72 from "node:path";
47738
+ import { fileURLToPath as fileURLToPath45 } from "node:url";
46776
47739
 
46777
47740
  // src/scripts/mcp_server/index.ts
46778
47741
  var __version__ = "0.1.0";
@@ -46819,9 +47782,9 @@ init_prompts();
46819
47782
  init_resources();
46820
47783
 
46821
47784
  // src/scripts/mcp_server/tools.ts
46822
- import * as fs73 from "node:fs";
46823
- import * as path69 from "node:path";
46824
- import { fileURLToPath as fileURLToPath42 } from "node:url";
47785
+ import * as fs75 from "node:fs";
47786
+ import * as path71 from "node:path";
47787
+ import { fileURLToPath as fileURLToPath44 } from "node:url";
46825
47788
 
46826
47789
  // src/scripts/chat_history.ts
46827
47790
  init_memory_lookup();
@@ -49054,9 +50017,9 @@ function _strip8(s) {
49054
50017
  }
49055
50018
  function _resolvePath2(p) {
49056
50019
  try {
49057
- return fs73.realpathSync(p);
50020
+ return fs75.realpathSync(p);
49058
50021
  } catch {
49059
- return path69.resolve(p);
50022
+ return path71.resolve(p);
49060
50023
  }
49061
50024
  }
49062
50025
  function _resolveConsumerRoot(override) {
@@ -49066,14 +50029,14 @@ function _resolveConsumerRoot(override) {
49066
50029
  return _resolvePath2(process.cwd());
49067
50030
  }
49068
50031
  function _relativeUnder(target, root) {
49069
- const rel = path69.relative(root, target);
50032
+ const rel = path71.relative(root, target);
49070
50033
  if (rel === "") {
49071
50034
  return "";
49072
50035
  }
49073
- if (rel.startsWith("..") || path69.isAbsolute(rel)) {
50036
+ if (rel.startsWith("..") || path71.isAbsolute(rel)) {
49074
50037
  return null;
49075
50038
  }
49076
- return rel.split(path69.sep).join("/");
50039
+ return rel.split(path71.sep).join("/");
49077
50040
  }
49078
50041
  function _reprStrList(values) {
49079
50042
  return `[${values.map((v) => `'${v}'`).join(", ")}]`;
@@ -49082,11 +50045,11 @@ function _validateInTreePath(raw, consumerRoot) {
49082
50045
  const root = _resolvePath2(consumerRoot);
49083
50046
  let target;
49084
50047
  if (raw === null || raw === void 0 || raw === "") {
49085
- target = path69.join(root, "agents", "runtime", ".agent-chat-history");
49086
- } else if (path69.isAbsolute(raw)) {
50048
+ target = path71.join(root, "agents", "runtime", ".agent-chat-history");
50049
+ } else if (path71.isAbsolute(raw)) {
49087
50050
  target = _resolvePath2(raw);
49088
50051
  } else {
49089
- target = _resolvePath2(path69.join(root, raw));
50052
+ target = _resolvePath2(path71.join(root, raw));
49090
50053
  }
49091
50054
  const rel = _relativeUnder(target, root);
49092
50055
  if (rel === null) {
@@ -49124,11 +50087,11 @@ async function _lintSkillsHandler(args, consumerRoot) {
49124
50087
  if (typeof raw !== "string") {
49125
50088
  throw new Error("'paths' entries must be strings");
49126
50089
  }
49127
- const resolved = path69.isAbsolute(raw) ? _resolvePath2(raw) : _resolvePath2(path69.join(root, raw));
50090
+ const resolved = path71.isAbsolute(raw) ? _resolvePath2(raw) : _resolvePath2(path71.join(root, raw));
49128
50091
  if (_relativeUnder(resolved, root) === null) {
49129
50092
  throw new Error(`path escapes consumer_root: ${resolved}`);
49130
50093
  }
49131
- if (fs73.existsSync(resolved)) {
50094
+ if (fs75.existsSync(resolved)) {
49132
50095
  paths.push(resolved);
49133
50096
  }
49134
50097
  }
@@ -49165,7 +50128,7 @@ async function _chatHistoryAppendHandler(args, consumerRoot) {
49165
50128
  if (typeof minSchema !== "number" || !Number.isInteger(minSchema) || typeof minSchema === "boolean") {
49166
50129
  throw new Error("'min_schema_version' must be an integer");
49167
50130
  }
49168
- const existingHeader = fs73.existsSync(target) ? _chReadHeader(target) : null;
50131
+ const existingHeader = fs75.existsSync(target) ? _chReadHeader(target) : null;
49169
50132
  const observed = existingHeader !== null && typeof existingHeader === "object" ? _pyInt7(existingHeader.v ?? 0) : SCHEMA_VERSION3;
49170
50133
  if (observed < minSchema) {
49171
50134
  throw new Error(`chat-history schema ${observed} below required ${minSchema}`);
@@ -49180,8 +50143,8 @@ async function _chatHistoryAppendHandler(args, consumerRoot) {
49180
50143
  session: session === void 0 ? null : session
49181
50144
  };
49182
50145
  }
49183
- if (!fs73.existsSync(target) || _chReadHeader(target) === null) {
49184
- fs73.mkdirSync(path69.dirname(target), { recursive: true });
50146
+ if (!fs75.existsSync(target) || _chReadHeader(target) === null) {
50147
+ fs75.mkdirSync(path71.dirname(target), { recursive: true });
49185
50148
  _chInit(target);
49186
50149
  }
49187
50150
  _chAppend(entry, target, session ?? null);
@@ -49225,7 +50188,7 @@ async function _chatHistoryReadHandler(args, consumerRoot) {
49225
50188
  if (detail !== "full" && detail !== "index") {
49226
50189
  throw new Error("'detail' must be 'index' or 'full'");
49227
50190
  }
49228
- if (!fs73.existsSync(target)) {
50191
+ if (!fs75.existsSync(target)) {
49229
50192
  return { path: target, entries: [], count: 0 };
49230
50193
  }
49231
50194
  if (around !== void 0 && around !== null) {
@@ -49327,8 +50290,8 @@ async function _memoryStatusHandler(_args, consumerRoot) {
49327
50290
  }
49328
50291
  return result;
49329
50292
  }
49330
- var _PACKAGE_ROOT3 = path69.resolve(
49331
- path69.dirname(fileURLToPath42(import.meta.url)),
50293
+ var _PACKAGE_ROOT3 = path71.resolve(
50294
+ path71.dirname(fileURLToPath44(import.meta.url)),
49332
50295
  "..",
49333
50296
  "..",
49334
50297
  ".."
@@ -49372,10 +50335,10 @@ async function _memorySignalHandler(args, consumerRoot) {
49372
50335
  async function _roadmapProgressHandler(args, consumerRoot) {
49373
50336
  const dryRun = _pyTruthy6(args.dry_run ?? false);
49374
50337
  const root = _resolvePath2(consumerRoot);
49375
- const roadmapRoot = path69.join(root, "agents", "roadmaps");
49376
- const target = path69.join(root, "agents", "roadmaps-progress.md");
50338
+ const roadmapRoot = path71.join(root, "agents", "roadmaps");
50339
+ const target = path71.join(root, "agents", "roadmaps-progress.md");
49377
50340
  const urp = await Promise.resolve().then(() => (init_update_roadmap_progress(), update_roadmap_progress_exports));
49378
- if (!fs73.existsSync(roadmapRoot)) {
50341
+ if (!fs75.existsSync(roadmapRoot)) {
49379
50342
  return {
49380
50343
  written: false,
49381
50344
  path: target,
@@ -49390,7 +50353,7 @@ async function _roadmapProgressHandler(args, consumerRoot) {
49390
50353
  const stepsDone = roadmaps.reduce((s, r) => s + r.done, 0);
49391
50354
  const stepsTotal = roadmaps.reduce((s, r) => s + r.total_active, 0);
49392
50355
  if (!dryRun) {
49393
- fs73.writeFileSync(target, content, "utf-8");
50356
+ fs75.writeFileSync(target, content, "utf-8");
49394
50357
  }
49395
50358
  return {
49396
50359
  written: !dryRun,
@@ -49411,11 +50374,11 @@ async function _roadmapArchiveHandler(_args, consumerRoot) {
49411
50374
  let dashboardRegenerated = false;
49412
50375
  if (archived.length > 0) {
49413
50376
  const urp = await Promise.resolve().then(() => (init_update_roadmap_progress(), update_roadmap_progress_exports));
49414
- const roadmapRoot = path69.join(root, "agents", "roadmaps");
49415
- if (fs73.existsSync(roadmapRoot)) {
50377
+ const roadmapRoot = path71.join(root, "agents", "roadmaps");
50378
+ if (fs75.existsSync(roadmapRoot)) {
49416
50379
  const roadmaps = urp.collect(roadmapRoot);
49417
- fs73.writeFileSync(
49418
- path69.join(root, "agents", "roadmaps-progress.md"),
50380
+ fs75.writeFileSync(
50381
+ path71.join(root, "agents", "roadmaps-progress.md"),
49419
50382
  urp.render(roadmaps, urp.collect_bundles(root)),
49420
50383
  "utf-8"
49421
50384
  );
@@ -49431,9 +50394,9 @@ async function _roadmapArchiveHandler(_args, consumerRoot) {
49431
50394
  async function _capabilitiesIndexHandler(args, consumerRoot) {
49432
50395
  const check = _pyTruthy6(args.check ?? false);
49433
50396
  const cap = await Promise.resolve().then(() => (init_generate_capabilities_index(), generate_capabilities_index_exports));
49434
- const out = path69.join(_PACKAGE_ROOT3, "CAPABILITIES.yaml");
50397
+ const out = path71.join(_PACKAGE_ROOT3, "CAPABILITIES.yaml");
49435
50398
  const content = cap.build();
49436
- const onDisk = fs73.existsSync(out) ? fs73.readFileSync(out, "utf-8") : "";
50399
+ const onDisk = fs75.existsSync(out) ? fs75.readFileSync(out, "utf-8") : "";
49437
50400
  const drift = onDisk !== content;
49438
50401
  if (check) {
49439
50402
  return { check: true, written: false, drift, path: out };
@@ -49444,7 +50407,7 @@ async function _capabilitiesIndexHandler(args, consumerRoot) {
49444
50407
  `CAPABILITIES.yaml path escapes consumer_root: ${out} not under ${root}`
49445
50408
  );
49446
50409
  }
49447
- fs73.writeFileSync(out, content, "utf-8");
50410
+ fs75.writeFileSync(out, content, "utf-8");
49448
50411
  return { check: false, written: true, drift, path: out };
49449
50412
  }
49450
50413
  async function _runDoctorLeg(consumerRoot) {
@@ -49544,11 +50507,11 @@ async function _councilEstimateHandler(args, consumerRoot) {
49544
50507
  throw new Error("'depth' must be 'shallow' or 'deep' when provided");
49545
50508
  }
49546
50509
  const root = _resolvePath2(consumerRoot);
49547
- const target = path69.isAbsolute(inputRaw) ? _resolvePath2(inputRaw) : _resolvePath2(path69.join(root, inputRaw));
50510
+ const target = path71.isAbsolute(inputRaw) ? _resolvePath2(inputRaw) : _resolvePath2(path71.join(root, inputRaw));
49548
50511
  if (_relativeUnder(target, root) === null) {
49549
50512
  throw new Error(`path escapes consumer_root: ${target}`);
49550
50513
  }
49551
- if (!fs73.existsSync(target)) {
50514
+ if (!fs75.existsSync(target)) {
49552
50515
  throw new Error(`input_path not found: ${target}`);
49553
50516
  }
49554
50517
  const cli = await Promise.resolve().then(() => (init_council_cli(), council_cli_exports));
@@ -49610,18 +50573,18 @@ async function _runTestsHandler(args, consumerRoot) {
49610
50573
  if (typeof relPathRaw !== "string" || !_strip8(relPathRaw)) {
49611
50574
  throw new Error("'path' must be a non-empty string when provided");
49612
50575
  }
49613
- const resolved = path69.isAbsolute(relPathRaw) ? _resolvePath2(relPathRaw) : _resolvePath2(path69.join(root, relPathRaw));
50576
+ const resolved = path71.isAbsolute(relPathRaw) ? _resolvePath2(relPathRaw) : _resolvePath2(path71.join(root, relPathRaw));
49614
50577
  const rel = _relativeUnder(resolved, root);
49615
50578
  if (rel === null) {
49616
50579
  throw new Error(`path escapes consumer_root: ${resolved}`);
49617
50580
  }
49618
- if (!fs73.existsSync(resolved)) {
50581
+ if (!fs75.existsSync(resolved)) {
49619
50582
  throw new Error(`path not found: ${resolved}`);
49620
50583
  }
49621
50584
  relArg = rel;
49622
50585
  }
49623
- const vitestEntry = path69.join(root, "node_modules", "vitest", "vitest.mjs");
49624
- if (!fs73.existsSync(vitestEntry)) {
50586
+ const vitestEntry = path71.join(root, "node_modules", "vitest", "vitest.mjs");
50587
+ if (!fs75.existsSync(vitestEntry)) {
49625
50588
  throw new Error(
49626
50589
  "run_tests pilot supports vitest projects only \u2014 node_modules/vitest/vitest.mjs not found under consumer_root"
49627
50590
  );
@@ -50227,8 +51190,8 @@ function _strCmp3(a, b) {
50227
51190
  return a < b ? -1 : a > b ? 1 : 0;
50228
51191
  }
50229
51192
  function _pathlibCompare3(a, b) {
50230
- const pa = a.split(path69.sep);
50231
- const pb = b.split(path69.sep);
51193
+ const pa = a.split(path71.sep);
51194
+ const pb = b.split(path71.sep);
50232
51195
  const n = Math.min(pa.length, pb.length);
50233
51196
  for (let i = 0; i < n; i++) {
50234
51197
  const c = _strCmp3(pa[i], pb[i]);
@@ -50447,18 +51410,18 @@ async function _serveOverSdk(server) {
50447
51410
  const transport = new StdioServerTransport();
50448
51411
  await sdkServer.connect(transport);
50449
51412
  }
50450
- function main31() {
51413
+ function main33() {
50451
51414
  void run_stdio();
50452
51415
  }
50453
51416
 
50454
51417
  // src/scripts/mcp_server/__main__.ts
50455
- var _selfPath = fileURLToPath43(import.meta.url);
50456
- var _invokedDirectly2 = globalThis.__AC_MCP_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path70.resolve(process.argv[1]) === path70.resolve(_selfPath);
51418
+ var _selfPath = fileURLToPath45(import.meta.url);
51419
+ var _invokedDirectly2 = globalThis.__AC_MCP_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path72.resolve(process.argv[1]) === path72.resolve(_selfPath);
50457
51420
  if (_invokedDirectly2) {
50458
- main31();
51421
+ main33();
50459
51422
  }
50460
51423
  export {
50461
- main31 as main
51424
+ main33 as main
50462
51425
  };
50463
51426
  /*! Bundled license information:
50464
51427