@event4u/agent-config 14.14.0 → 14.14.1

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 (66) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +33 -0
  5. package/README.md +1 -1
  6. package/dist/agent-src/commands/pr/create.md +16 -1
  7. package/dist/agent-src/contexts/execution/terminal-states.md +25 -4
  8. package/dist/agent-src/rules/missing-skill-recovery.md +2 -2
  9. package/dist/agent-src/rules/token-budget-discipline.md +2 -2
  10. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  11. package/dist/cli/registry.js +1 -0
  12. package/dist/cli-delegate/{chunk-ILMUPLGW.js → chunk-7RXIKF62.js} +159 -86
  13. package/dist/cli-delegate/cmd_conformance.js +1 -1
  14. package/dist/cli-delegate/cmd_doctor.js +1 -1
  15. package/dist/discovery/deprecation-report.md +1 -1
  16. package/dist/discovery/discovery-manifest.json +5 -5
  17. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  18. package/dist/discovery/discovery-manifest.summary.md +1 -1
  19. package/dist/discovery/dormancy-report.md +1 -1
  20. package/dist/discovery/orphan-report.md +1 -1
  21. package/dist/discovery/packs.json +2 -2
  22. package/dist/discovery/trust-report.md +1 -1
  23. package/dist/discovery/workspaces.json +2 -2
  24. package/dist/hooks/dispatch.js +528 -371
  25. package/dist/mcp/registry-manifest.json +2 -2
  26. package/dist/mcp/server.json +2 -2
  27. package/dist/mcp/server.mjs +185 -98
  28. package/package.json +1 -1
  29. package/src/config/assurance-capability-registry.json +1 -1
  30. package/src/config/evaluator-budgets.json +4 -4
  31. package/src/config/gate-coverage.yml +62 -2
  32. package/src/config/gate-reachability-exemptions.json +1 -0
  33. package/src/config/gate-violation-baselines.json +4 -3
  34. package/src/config/web-launch-readiness.json +4 -2
  35. package/src/scripts/_cli/_doctor_emit.ts +71 -0
  36. package/src/scripts/_cli/_doctor_strict.ts +163 -0
  37. package/src/scripts/_cli/cmd_doctor.ts +16 -37
  38. package/src/scripts/_dispatch.bash +11 -0
  39. package/src/scripts/_lib/branch_convergence.ts +186 -0
  40. package/src/scripts/_lib/context_observation.ts +132 -0
  41. package/src/scripts/_lib/continuation_ladder.ts +188 -0
  42. package/src/scripts/_lib/experiment_binding.ts +95 -0
  43. package/src/scripts/_lib/ignored_blocker.ts +8 -1
  44. package/src/scripts/_lib/outcome_envelope.ts +6 -1
  45. package/src/scripts/_lib/outcome_vocabularies.ts +135 -5
  46. package/src/scripts/_lib/release_highlights.ts +12 -3
  47. package/src/scripts/_lib/repeated_failure.ts +19 -2
  48. package/src/scripts/_lib/runtime_journal.ts +11 -4
  49. package/src/scripts/check_agent_artifact_location.ts +337 -0
  50. package/src/scripts/check_artefact_count_messaging.ts +74 -8
  51. package/src/scripts/check_enforcement_coverage.ts +40 -1
  52. package/src/scripts/check_release_highlights.ts +17 -1
  53. package/src/scripts/check_web_launch_readiness.ts +310 -20
  54. package/src/scripts/evolution_lab.ts +53 -1
  55. package/src/scripts/generate_capability_matrix.ts +16 -9
  56. package/src/scripts/grade_target_readiness.ts +221 -2
  57. package/src/scripts/hook_effect_doctor.ts +47 -4
  58. package/src/scripts/hooks/run_continuation_hook.ts +78 -88
  59. package/src/scripts/hooks/session_eol_hook.ts +12 -1
  60. package/src/scripts/install-hooks.sh +18 -0
  61. package/src/scripts/lint_code_comments.ts +106 -1
  62. package/src/scripts/release_drill.ts +57 -1
  63. package/src/scripts/release_publication.ts +58 -0
  64. package/src/scripts/roadmap_context.ts +15 -0
  65. package/src/scripts/skill_scout.ts +633 -0
  66. package/src/scripts/sync_pr_branch.ts +521 -42
@@ -112,17 +112,17 @@ var require_visit = __commonJS({
112
112
  visit.BREAK = BREAK;
113
113
  visit.SKIP = SKIP;
114
114
  visit.REMOVE = REMOVE;
115
- function visit_(key, node, visitor, path105) {
116
- const ctrl = callVisitor(key, node, visitor, path105);
115
+ function visit_(key, node, visitor, path106) {
116
+ const ctrl = callVisitor(key, node, visitor, path106);
117
117
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
118
- replaceNode(key, path105, ctrl);
119
- return visit_(key, ctrl, visitor, path105);
118
+ replaceNode(key, path106, ctrl);
119
+ return visit_(key, ctrl, visitor, path106);
120
120
  }
121
121
  if (typeof ctrl !== "symbol") {
122
122
  if (identity.isCollection(node)) {
123
- path105 = Object.freeze(path105.concat(node));
123
+ path106 = Object.freeze(path106.concat(node));
124
124
  for (let i = 0; i < node.items.length; ++i) {
125
- const ci = visit_(i, node.items[i], visitor, path105);
125
+ const ci = visit_(i, node.items[i], visitor, path106);
126
126
  if (typeof ci === "number")
127
127
  i = ci - 1;
128
128
  else if (ci === BREAK)
@@ -133,13 +133,13 @@ var require_visit = __commonJS({
133
133
  }
134
134
  }
135
135
  } else if (identity.isPair(node)) {
136
- path105 = Object.freeze(path105.concat(node));
137
- const ck = visit_("key", node.key, visitor, path105);
136
+ path106 = Object.freeze(path106.concat(node));
137
+ const ck = visit_("key", node.key, visitor, path106);
138
138
  if (ck === BREAK)
139
139
  return BREAK;
140
140
  else if (ck === REMOVE)
141
141
  node.key = null;
142
- const cv = visit_("value", node.value, visitor, path105);
142
+ const cv = visit_("value", node.value, visitor, path106);
143
143
  if (cv === BREAK)
144
144
  return BREAK;
145
145
  else if (cv === REMOVE)
@@ -160,17 +160,17 @@ var require_visit = __commonJS({
160
160
  visitAsync.BREAK = BREAK;
161
161
  visitAsync.SKIP = SKIP;
162
162
  visitAsync.REMOVE = REMOVE;
163
- async function visitAsync_(key, node, visitor, path105) {
164
- const ctrl = await callVisitor(key, node, visitor, path105);
163
+ async function visitAsync_(key, node, visitor, path106) {
164
+ const ctrl = await callVisitor(key, node, visitor, path106);
165
165
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
166
- replaceNode(key, path105, ctrl);
167
- return visitAsync_(key, ctrl, visitor, path105);
166
+ replaceNode(key, path106, ctrl);
167
+ return visitAsync_(key, ctrl, visitor, path106);
168
168
  }
169
169
  if (typeof ctrl !== "symbol") {
170
170
  if (identity.isCollection(node)) {
171
- path105 = Object.freeze(path105.concat(node));
171
+ path106 = Object.freeze(path106.concat(node));
172
172
  for (let i = 0; i < node.items.length; ++i) {
173
- const ci = await visitAsync_(i, node.items[i], visitor, path105);
173
+ const ci = await visitAsync_(i, node.items[i], visitor, path106);
174
174
  if (typeof ci === "number")
175
175
  i = ci - 1;
176
176
  else if (ci === BREAK)
@@ -181,13 +181,13 @@ var require_visit = __commonJS({
181
181
  }
182
182
  }
183
183
  } else if (identity.isPair(node)) {
184
- path105 = Object.freeze(path105.concat(node));
185
- const ck = await visitAsync_("key", node.key, visitor, path105);
184
+ path106 = Object.freeze(path106.concat(node));
185
+ const ck = await visitAsync_("key", node.key, visitor, path106);
186
186
  if (ck === BREAK)
187
187
  return BREAK;
188
188
  else if (ck === REMOVE)
189
189
  node.key = null;
190
- const cv = await visitAsync_("value", node.value, visitor, path105);
190
+ const cv = await visitAsync_("value", node.value, visitor, path106);
191
191
  if (cv === BREAK)
192
192
  return BREAK;
193
193
  else if (cv === REMOVE)
@@ -214,23 +214,23 @@ var require_visit = __commonJS({
214
214
  }
215
215
  return visitor;
216
216
  }
217
- function callVisitor(key, node, visitor, path105) {
217
+ function callVisitor(key, node, visitor, path106) {
218
218
  if (typeof visitor === "function")
219
- return visitor(key, node, path105);
219
+ return visitor(key, node, path106);
220
220
  if (identity.isMap(node))
221
- return visitor.Map?.(key, node, path105);
221
+ return visitor.Map?.(key, node, path106);
222
222
  if (identity.isSeq(node))
223
- return visitor.Seq?.(key, node, path105);
223
+ return visitor.Seq?.(key, node, path106);
224
224
  if (identity.isPair(node))
225
- return visitor.Pair?.(key, node, path105);
225
+ return visitor.Pair?.(key, node, path106);
226
226
  if (identity.isScalar(node))
227
- return visitor.Scalar?.(key, node, path105);
227
+ return visitor.Scalar?.(key, node, path106);
228
228
  if (identity.isAlias(node))
229
- return visitor.Alias?.(key, node, path105);
229
+ return visitor.Alias?.(key, node, path106);
230
230
  return void 0;
231
231
  }
232
- function replaceNode(key, path105, node) {
233
- const parent = path105[path105.length - 1];
232
+ function replaceNode(key, path106, node) {
233
+ const parent = path106[path106.length - 1];
234
234
  if (identity.isCollection(parent)) {
235
235
  parent.items[key] = node;
236
236
  } else if (identity.isPair(parent)) {
@@ -840,10 +840,10 @@ var require_Collection = __commonJS({
840
840
  var createNode = require_createNode();
841
841
  var identity = require_identity();
842
842
  var Node = require_Node();
843
- function collectionFromPath(schema, path105, value) {
843
+ function collectionFromPath(schema, path106, value) {
844
844
  let v = value;
845
- for (let i = path105.length - 1; i >= 0; --i) {
846
- const k = path105[i];
845
+ for (let i = path106.length - 1; i >= 0; --i) {
846
+ const k = path106[i];
847
847
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
848
848
  const a = [];
849
849
  a[k] = v;
@@ -862,7 +862,7 @@ var require_Collection = __commonJS({
862
862
  sourceObjects: /* @__PURE__ */ new Map()
863
863
  });
864
864
  }
865
- var isEmptyPath = (path105) => path105 == null || typeof path105 === "object" && !!path105[Symbol.iterator]().next().done;
865
+ var isEmptyPath = (path106) => path106 == null || typeof path106 === "object" && !!path106[Symbol.iterator]().next().done;
866
866
  var Collection = class extends Node.NodeBase {
867
867
  constructor(type, schema) {
868
868
  super(type);
@@ -892,11 +892,11 @@ var require_Collection = __commonJS({
892
892
  * be a Pair instance or a `{ key, value }` object, which may not have a key
893
893
  * that already exists in the map.
894
894
  */
895
- addIn(path105, value) {
896
- if (isEmptyPath(path105))
895
+ addIn(path106, value) {
896
+ if (isEmptyPath(path106))
897
897
  this.add(value);
898
898
  else {
899
- const [key, ...rest] = path105;
899
+ const [key, ...rest] = path106;
900
900
  const node = this.get(key, true);
901
901
  if (identity.isCollection(node))
902
902
  node.addIn(rest, value);
@@ -910,8 +910,8 @@ var require_Collection = __commonJS({
910
910
  * Removes a value from the collection.
911
911
  * @returns `true` if the item was found and removed.
912
912
  */
913
- deleteIn(path105) {
914
- const [key, ...rest] = path105;
913
+ deleteIn(path106) {
914
+ const [key, ...rest] = path106;
915
915
  if (rest.length === 0)
916
916
  return this.delete(key);
917
917
  const node = this.get(key, true);
@@ -925,8 +925,8 @@ var require_Collection = __commonJS({
925
925
  * scalar values from their surrounding node; to disable set `keepScalar` to
926
926
  * `true` (collections are always returned intact).
927
927
  */
928
- getIn(path105, keepScalar) {
929
- const [key, ...rest] = path105;
928
+ getIn(path106, keepScalar) {
929
+ const [key, ...rest] = path106;
930
930
  const node = this.get(key, true);
931
931
  if (rest.length === 0)
932
932
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -944,8 +944,8 @@ var require_Collection = __commonJS({
944
944
  /**
945
945
  * Checks if the collection includes a value with the key `key`.
946
946
  */
947
- hasIn(path105) {
948
- const [key, ...rest] = path105;
947
+ hasIn(path106) {
948
+ const [key, ...rest] = path106;
949
949
  if (rest.length === 0)
950
950
  return this.has(key);
951
951
  const node = this.get(key, true);
@@ -955,8 +955,8 @@ var require_Collection = __commonJS({
955
955
  * Sets a value in this collection. For `!!set`, `value` needs to be a
956
956
  * boolean to add/remove the item from the set.
957
957
  */
958
- setIn(path105, value) {
959
- const [key, ...rest] = path105;
958
+ setIn(path106, value) {
959
+ const [key, ...rest] = path106;
960
960
  if (rest.length === 0) {
961
961
  this.set(key, value);
962
962
  } else {
@@ -3471,9 +3471,9 @@ var require_Document = __commonJS({
3471
3471
  this.contents.add(value);
3472
3472
  }
3473
3473
  /** Adds a value to the document. */
3474
- addIn(path105, value) {
3474
+ addIn(path106, value) {
3475
3475
  if (assertCollection(this.contents))
3476
- this.contents.addIn(path105, value);
3476
+ this.contents.addIn(path106, value);
3477
3477
  }
3478
3478
  /**
3479
3479
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -3548,14 +3548,14 @@ var require_Document = __commonJS({
3548
3548
  * Removes a value from the document.
3549
3549
  * @returns `true` if the item was found and removed.
3550
3550
  */
3551
- deleteIn(path105) {
3552
- if (Collection.isEmptyPath(path105)) {
3551
+ deleteIn(path106) {
3552
+ if (Collection.isEmptyPath(path106)) {
3553
3553
  if (this.contents == null)
3554
3554
  return false;
3555
3555
  this.contents = null;
3556
3556
  return true;
3557
3557
  }
3558
- return assertCollection(this.contents) ? this.contents.deleteIn(path105) : false;
3558
+ return assertCollection(this.contents) ? this.contents.deleteIn(path106) : false;
3559
3559
  }
3560
3560
  /**
3561
3561
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -3570,10 +3570,10 @@ var require_Document = __commonJS({
3570
3570
  * scalar values from their surrounding node; to disable set `keepScalar` to
3571
3571
  * `true` (collections are always returned intact).
3572
3572
  */
3573
- getIn(path105, keepScalar) {
3574
- if (Collection.isEmptyPath(path105))
3573
+ getIn(path106, keepScalar) {
3574
+ if (Collection.isEmptyPath(path106))
3575
3575
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3576
- return identity.isCollection(this.contents) ? this.contents.getIn(path105, keepScalar) : void 0;
3576
+ return identity.isCollection(this.contents) ? this.contents.getIn(path106, keepScalar) : void 0;
3577
3577
  }
3578
3578
  /**
3579
3579
  * Checks if the document includes a value with the key `key`.
@@ -3584,10 +3584,10 @@ var require_Document = __commonJS({
3584
3584
  /**
3585
3585
  * Checks if the document includes a value at `path`.
3586
3586
  */
3587
- hasIn(path105) {
3588
- if (Collection.isEmptyPath(path105))
3587
+ hasIn(path106) {
3588
+ if (Collection.isEmptyPath(path106))
3589
3589
  return this.contents !== void 0;
3590
- return identity.isCollection(this.contents) ? this.contents.hasIn(path105) : false;
3590
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path106) : false;
3591
3591
  }
3592
3592
  /**
3593
3593
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -3604,13 +3604,13 @@ var require_Document = __commonJS({
3604
3604
  * Sets a value in this document. For `!!set`, `value` needs to be a
3605
3605
  * boolean to add/remove the item from the set.
3606
3606
  */
3607
- setIn(path105, value) {
3608
- if (Collection.isEmptyPath(path105)) {
3607
+ setIn(path106, value) {
3608
+ if (Collection.isEmptyPath(path106)) {
3609
3609
  this.contents = value;
3610
3610
  } else if (this.contents == null) {
3611
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path105), value);
3611
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path106), value);
3612
3612
  } else if (assertCollection(this.contents)) {
3613
- this.contents.setIn(path105, value);
3613
+ this.contents.setIn(path106, value);
3614
3614
  }
3615
3615
  }
3616
3616
  /**
@@ -5570,9 +5570,9 @@ var require_cst_visit = __commonJS({
5570
5570
  visit.BREAK = BREAK;
5571
5571
  visit.SKIP = SKIP;
5572
5572
  visit.REMOVE = REMOVE;
5573
- visit.itemAtPath = (cst, path105) => {
5573
+ visit.itemAtPath = (cst, path106) => {
5574
5574
  let item = cst;
5575
- for (const [field, index] of path105) {
5575
+ for (const [field, index] of path106) {
5576
5576
  const tok = item?.[field];
5577
5577
  if (tok && "items" in tok) {
5578
5578
  item = tok.items[index];
@@ -5581,23 +5581,23 @@ var require_cst_visit = __commonJS({
5581
5581
  }
5582
5582
  return item;
5583
5583
  };
5584
- visit.parentCollection = (cst, path105) => {
5585
- const parent = visit.itemAtPath(cst, path105.slice(0, -1));
5586
- const field = path105[path105.length - 1][0];
5584
+ visit.parentCollection = (cst, path106) => {
5585
+ const parent = visit.itemAtPath(cst, path106.slice(0, -1));
5586
+ const field = path106[path106.length - 1][0];
5587
5587
  const coll = parent?.[field];
5588
5588
  if (coll && "items" in coll)
5589
5589
  return coll;
5590
5590
  throw new Error("Parent collection not found");
5591
5591
  };
5592
- function _visit(path105, item, visitor) {
5593
- let ctrl = visitor(item, path105);
5592
+ function _visit(path106, item, visitor) {
5593
+ let ctrl = visitor(item, path106);
5594
5594
  if (typeof ctrl === "symbol")
5595
5595
  return ctrl;
5596
5596
  for (const field of ["key", "value"]) {
5597
5597
  const token = item[field];
5598
5598
  if (token && "items" in token) {
5599
5599
  for (let i = 0; i < token.items.length; ++i) {
5600
- const ci = _visit(Object.freeze(path105.concat([[field, i]])), token.items[i], visitor);
5600
+ const ci = _visit(Object.freeze(path106.concat([[field, i]])), token.items[i], visitor);
5601
5601
  if (typeof ci === "number")
5602
5602
  i = ci - 1;
5603
5603
  else if (ci === BREAK)
@@ -5608,10 +5608,10 @@ var require_cst_visit = __commonJS({
5608
5608
  }
5609
5609
  }
5610
5610
  if (typeof ctrl === "function" && field === "key")
5611
- ctrl = ctrl(item, path105);
5611
+ ctrl = ctrl(item, path106);
5612
5612
  }
5613
5613
  }
5614
- return typeof ctrl === "function" ? ctrl(item, path105) : ctrl;
5614
+ return typeof ctrl === "function" ? ctrl(item, path106) : ctrl;
5615
5615
  }
5616
5616
  exports.visit = visit;
5617
5617
  }
@@ -6913,14 +6913,14 @@ var require_parser = __commonJS({
6913
6913
  case "scalar":
6914
6914
  case "single-quoted-scalar":
6915
6915
  case "double-quoted-scalar": {
6916
- const fs102 = this.flowScalar(this.type);
6916
+ const fs103 = this.flowScalar(this.type);
6917
6917
  if (atNextItem || it.value) {
6918
- map.items.push({ start, key: fs102, sep: [] });
6918
+ map.items.push({ start, key: fs103, sep: [] });
6919
6919
  this.onKeyLine = true;
6920
6920
  } else if (it.sep) {
6921
- this.stack.push(fs102);
6921
+ this.stack.push(fs103);
6922
6922
  } else {
6923
- Object.assign(it, { key: fs102, sep: [] });
6923
+ Object.assign(it, { key: fs103, sep: [] });
6924
6924
  this.onKeyLine = true;
6925
6925
  }
6926
6926
  return;
@@ -7048,13 +7048,13 @@ var require_parser = __commonJS({
7048
7048
  case "scalar":
7049
7049
  case "single-quoted-scalar":
7050
7050
  case "double-quoted-scalar": {
7051
- const fs102 = this.flowScalar(this.type);
7051
+ const fs103 = this.flowScalar(this.type);
7052
7052
  if (!it || it.value)
7053
- fc.items.push({ start: [], key: fs102, sep: [] });
7053
+ fc.items.push({ start: [], key: fs103, sep: [] });
7054
7054
  else if (it.sep)
7055
- this.stack.push(fs102);
7055
+ this.stack.push(fs103);
7056
7056
  else
7057
- Object.assign(it, { key: fs102, sep: [] });
7057
+ Object.assign(it, { key: fs103, sep: [] });
7058
7058
  return;
7059
7059
  }
7060
7060
  case "flow-map-end":
@@ -7363,14 +7363,14 @@ var require_dist = __commonJS({
7363
7363
  });
7364
7364
 
7365
7365
  // src/scripts/hooks/dispatch_entry.ts
7366
- import * as path104 from "node:path";
7366
+ import * as path105 from "node:path";
7367
7367
  import { fileURLToPath as fileURLToPath67 } from "node:url";
7368
7368
 
7369
7369
  // src/scripts/hooks/dispatch_hook.ts
7370
7370
  var import_yaml6 = __toESM(require_dist(), 1);
7371
7371
  import { spawnSync as spawnSync10 } from "node:child_process";
7372
- import fs101 from "node:fs";
7373
- import path103 from "node:path";
7372
+ import fs102 from "node:fs";
7373
+ import path104 from "node:path";
7374
7374
  import * as tty2 from "node:tty";
7375
7375
  import { fileURLToPath as fileURLToPath66, pathToFileURL as pathToFileURL59 } from "node:url";
7376
7376
 
@@ -24686,8 +24686,8 @@ function lockfile_path(env) {
24686
24686
  }
24687
24687
  return write_target("installed.lock", { env: env ?? null });
24688
24688
  }
24689
- function read_lockfile(path105) {
24690
- const target = path105 ?? lockfile_path();
24689
+ function read_lockfile(path106) {
24690
+ const target = path106 ?? lockfile_path();
24691
24691
  let text;
24692
24692
  try {
24693
24693
  text = fs51.readFileSync(target, { encoding: "utf-8" });
@@ -33893,6 +33893,61 @@ function changedFiles(root, base) {
33893
33893
  const dirty = m.status === 0 ? m.stdout.split("\n") : [];
33894
33894
  return [.../* @__PURE__ */ new Set([...tracked, ...untracked, ...dirty])].filter((f) => f.trim().length > 0);
33895
33895
  }
33896
+ function addedLineMap(root, base) {
33897
+ const out = /* @__PURE__ */ new Map();
33898
+ const u = spawnSync9("git", ["ls-files", "--others", "--exclude-standard"], {
33899
+ cwd: root,
33900
+ encoding: "utf-8"
33901
+ });
33902
+ if (u.status === 0) {
33903
+ for (const f of u.stdout.split("\n")) {
33904
+ if (f.trim()) out.set(f.trim(), "all");
33905
+ }
33906
+ }
33907
+ for (const argv of [
33908
+ ["diff", "--unified=0", "--diff-filter=ACMR", `${base}...HEAD`],
33909
+ ["diff", "--unified=0", "--diff-filter=ACMR"]
33910
+ ]) {
33911
+ const r = spawnSync9("git", argv, { cwd: root, encoding: "utf-8" });
33912
+ if (r.status !== 0) continue;
33913
+ mergeAddedLines(out, parseAddedLines(r.stdout));
33914
+ }
33915
+ return out;
33916
+ }
33917
+ function parseAddedLines(diffText) {
33918
+ const out = /* @__PURE__ */ new Map();
33919
+ let file = null;
33920
+ for (const line of diffText.split("\n")) {
33921
+ if (line.startsWith("+++ ")) {
33922
+ const p = line.slice(4).trim();
33923
+ file = p === "/dev/null" ? null : p.replace(/^b\//, "");
33924
+ continue;
33925
+ }
33926
+ if (!file || !line.startsWith("@@")) continue;
33927
+ const m = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/.exec(line);
33928
+ if (!m) continue;
33929
+ const start = Number.parseInt(m[1], 10);
33930
+ const count = m[2] === void 0 ? 1 : Number.parseInt(m[2], 10);
33931
+ const set = out.get(file) ?? /* @__PURE__ */ new Set();
33932
+ for (let n = start; n < start + count; n += 1) set.add(n);
33933
+ out.set(file, set);
33934
+ }
33935
+ return out;
33936
+ }
33937
+ function mergeAddedLines(into, from) {
33938
+ for (const [file, lines] of from) {
33939
+ const prev = into.get(file);
33940
+ if (prev === "all") continue;
33941
+ const set = prev ?? /* @__PURE__ */ new Set();
33942
+ for (const n of lines) set.add(n);
33943
+ into.set(file, set);
33944
+ }
33945
+ }
33946
+ function findingsOnAddedLines(findings, lines) {
33947
+ if (lines === void 0) return [];
33948
+ if (lines === "all") return [...findings];
33949
+ return findings.filter((f) => lines.has(f.line));
33950
+ }
33896
33951
  var COMMENT_CASES = [
33897
33952
  {
33898
33953
  name: "a block-comment continuation carrying no leading star is flagged",
@@ -34070,6 +34125,7 @@ ${HELP}`);
34070
34125
  return 1;
34071
34126
  }
34072
34127
  const candidates = (explicit.length > 0 ? explicit : changedFiles(root, base)).filter(isScannable);
34128
+ const added = explicit.length > 0 ? null : addedLineMap(root, base);
34073
34129
  const findings = [];
34074
34130
  for (const rel of candidates) {
34075
34131
  const abs = path85.isAbsolute(rel) ? rel : path85.join(root, rel);
@@ -34079,7 +34135,8 @@ ${HELP}`);
34079
34135
  } catch {
34080
34136
  continue;
34081
34137
  }
34082
- findings.push(...scanText2(rel, text));
34138
+ const all = scanText2(rel, text);
34139
+ findings.push(...added ? findingsOnAddedLines(all, added.get(rel)) : all);
34083
34140
  }
34084
34141
  try {
34085
34142
  reportScanned({
@@ -34386,8 +34443,8 @@ if (_isCliEntry44()) {
34386
34443
  }
34387
34444
 
34388
34445
  // src/scripts/hooks/session_eol_hook.ts
34389
- import * as fs89 from "node:fs";
34390
- import * as path91 from "node:path";
34446
+ import * as fs91 from "node:fs";
34447
+ import * as path93 from "node:path";
34391
34448
  import process15 from "node:process";
34392
34449
  import { fileURLToPath as fileURLToPath59, pathToFileURL as pathToFileURL52 } from "node:url";
34393
34450
 
@@ -34561,9 +34618,112 @@ function readNewCompleteLines(filePath, fromByte) {
34561
34618
  }
34562
34619
  }
34563
34620
 
34564
- // src/scripts/_lib/run_checkpoint.ts
34621
+ // src/scripts/_lib/context_observation.ts
34622
+ import * as fs89 from "node:fs";
34623
+ import * as path91 from "node:path";
34624
+
34625
+ // src/scripts/_lib/loop_guards.ts
34565
34626
  import * as fs88 from "node:fs";
34566
34627
  import * as path90 from "node:path";
34628
+ function atomicWriteJson(file, value) {
34629
+ const tmp = `${file}.${String(process.pid)}.tmp`;
34630
+ try {
34631
+ fs88.mkdirSync(path90.dirname(file), { recursive: true });
34632
+ fs88.writeFileSync(tmp, `${JSON.stringify(value)}
34633
+ `, "utf8");
34634
+ fs88.renameSync(tmp, file);
34635
+ return true;
34636
+ } catch {
34637
+ try {
34638
+ fs88.unlinkSync(tmp);
34639
+ } catch {
34640
+ }
34641
+ return false;
34642
+ }
34643
+ }
34644
+ var DEPENDENCY_PATTERNS = [
34645
+ { kind: "binary", re: /\b(?:command not found|is not recognized as an internal or external command)\b/i },
34646
+ { kind: "credential", re: /\b(?:not (?:authenticated|logged in)|authentication (?:failed|required)|no credentials found)\b/i },
34647
+ { kind: "credential", re: /\b(?:missing|unset|not set)\b[^\n]{0,40}\b(?:credential|token|api[_ -]?key|secret)\b/i },
34648
+ { kind: "permission", re: /\b(?:permission denied|forbidden|403 forbidden)\b/i },
34649
+ { kind: "quota", re: /\b(?:rate limit(?:ed| exceeded| reached)?|quota exceeded|429 too many requests|spend (?:cap|limit) reached)\b/i },
34650
+ { kind: "service", re: /\b(?:5\d\d (?:internal )?server error|service unavailable|connection refused)\b/i }
34651
+ ];
34652
+ var DEPENDENCY_SCAN_BYTES = 64 * 1024;
34653
+ function detectUnavailableDependency(transcriptTail, tailLines = 200) {
34654
+ const lines = transcriptTail.split("\n");
34655
+ const window = lines.slice(Math.max(0, lines.length - tailLines));
34656
+ for (const line of window) {
34657
+ for (const { kind, re } of DEPENDENCY_PATTERNS) {
34658
+ if (re.test(line)) {
34659
+ return { kind, evidence: line.trim().slice(0, 200) };
34660
+ }
34661
+ }
34662
+ }
34663
+ return null;
34664
+ }
34665
+ function stallSignal(history, window = 3) {
34666
+ if (history.length === 0) {
34667
+ return { level: "flat", flatRun: 0, minimum: null, newMinimum: false };
34668
+ }
34669
+ const last = history[history.length - 1];
34670
+ const minimum = Math.min(...history);
34671
+ const earlier = history.slice(0, -1);
34672
+ const newMinimum = earlier.length > 0 && last < Math.min(...earlier);
34673
+ let flatRun = 1;
34674
+ for (let i = history.length - 2; i >= 0; i -= 1) {
34675
+ if (history[i] !== last) break;
34676
+ flatRun += 1;
34677
+ }
34678
+ if (newMinimum) return { level: "progressing", flatRun, minimum, newMinimum };
34679
+ if (flatRun >= window) return { level: "stalled", flatRun, minimum, newMinimum };
34680
+ return { level: "flat", flatRun, minimum, newMinimum };
34681
+ }
34682
+ function readUnavailableDependency(transcriptPath) {
34683
+ try {
34684
+ const raw = fs88.readFileSync(transcriptPath, "utf8");
34685
+ return detectUnavailableDependency(raw.slice(-DEPENDENCY_SCAN_BYTES));
34686
+ } catch {
34687
+ return null;
34688
+ }
34689
+ }
34690
+
34691
+ // src/scripts/_lib/context_observation.ts
34692
+ var CONTEXT_OBSERVATION_REL = path91.join(
34693
+ "agents",
34694
+ "runtime",
34695
+ "state",
34696
+ "context-observation.json"
34697
+ );
34698
+ function observationFile(repoRoot) {
34699
+ return path91.join(repoRoot, CONTEXT_OBSERVATION_REL);
34700
+ }
34701
+ function readContextObservation(repoRoot) {
34702
+ try {
34703
+ const parsed = JSON.parse(fs89.readFileSync(observationFile(repoRoot), "utf-8"));
34704
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
34705
+ const o = parsed;
34706
+ if (typeof o["fingerprint"] !== "string" || o["fingerprint"] === "") return null;
34707
+ if (typeof o["at"] !== "string") return null;
34708
+ return {
34709
+ schema_version: 1,
34710
+ roadmap: typeof o["roadmap"] === "string" ? o["roadmap"] : "",
34711
+ fingerprint: o["fingerprint"],
34712
+ at: o["at"]
34713
+ };
34714
+ } catch {
34715
+ return null;
34716
+ }
34717
+ }
34718
+ function premiseMoved(claimed, observed) {
34719
+ if (claimed === null || claimed === void 0 || claimed === "") return false;
34720
+ if (observed === null || observed === void 0 || observed === "") return false;
34721
+ return claimed !== observed;
34722
+ }
34723
+
34724
+ // src/scripts/_lib/run_checkpoint.ts
34725
+ import * as fs90 from "node:fs";
34726
+ import * as path92 from "node:path";
34567
34727
 
34568
34728
  // src/scripts/_lib/roadmap_checkboxes.ts
34569
34729
  var CHECKBOX_LINE = /^[ \t]*[-*][ \t]+\[([ xX~-])\][ \t]+(.*)$/;
@@ -34593,7 +34753,7 @@ function phaseLines(text) {
34593
34753
  }
34594
34754
 
34595
34755
  // src/scripts/_lib/run_checkpoint.ts
34596
- var CHECKPOINT_DIR_REL = path90.join("agents", "runtime", "state", "checkpoints");
34756
+ var CHECKPOINT_DIR_REL = path92.join("agents", "runtime", "state", "checkpoints");
34597
34757
  function countRoadmap(text) {
34598
34758
  const counts = { open: 0, done: 0, parked: 0, next: null };
34599
34759
  for (const raw of phaseLines(text)) {
@@ -34614,34 +34774,34 @@ function countRoadmap(text) {
34614
34774
  return counts;
34615
34775
  }
34616
34776
  function checkpointFile(repoRoot, runId) {
34617
- return path90.join(repoRoot, CHECKPOINT_DIR_REL, `${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
34777
+ return path92.join(repoRoot, CHECKPOINT_DIR_REL, `${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
34618
34778
  }
34619
34779
  function roadmapPath(repoRoot, slug) {
34620
- return path90.join(repoRoot, "agents", "roadmaps", `${slug}.md`);
34780
+ return path92.join(repoRoot, "agents", "roadmaps", `${slug}.md`);
34621
34781
  }
34622
34782
  function readHead(repoRoot) {
34623
34783
  try {
34624
- let gitDir = path90.join(repoRoot, ".git");
34625
- if (fs88.statSync(gitDir).isFile()) {
34626
- const m = /^gitdir:\s*(.+)$/m.exec(fs88.readFileSync(gitDir, "utf-8").trim());
34784
+ let gitDir = path92.join(repoRoot, ".git");
34785
+ if (fs90.statSync(gitDir).isFile()) {
34786
+ const m = /^gitdir:\s*(.+)$/m.exec(fs90.readFileSync(gitDir, "utf-8").trim());
34627
34787
  if (m === null) return null;
34628
- gitDir = path90.resolve(repoRoot, m[1]);
34788
+ gitDir = path92.resolve(repoRoot, m[1]);
34629
34789
  }
34630
34790
  let refRoot = gitDir;
34631
34791
  try {
34632
- const common = fs88.readFileSync(path90.join(gitDir, "commondir"), "utf-8").trim();
34633
- if (common !== "") refRoot = path90.resolve(gitDir, common);
34792
+ const common = fs90.readFileSync(path92.join(gitDir, "commondir"), "utf-8").trim();
34793
+ if (common !== "") refRoot = path92.resolve(gitDir, common);
34634
34794
  } catch {
34635
34795
  }
34636
- const head = fs88.readFileSync(path90.join(gitDir, "HEAD"), "utf-8").trim();
34796
+ const head = fs90.readFileSync(path92.join(gitDir, "HEAD"), "utf-8").trim();
34637
34797
  if (/^[0-9a-f]{40}$/.test(head)) return head;
34638
34798
  const ref = /^ref:\s*(.+)$/.exec(head);
34639
34799
  if (ref === null) return null;
34640
34800
  const refName = ref[1];
34641
34801
  try {
34642
- return fs88.readFileSync(path90.join(refRoot, refName), "utf-8").trim() || null;
34802
+ return fs90.readFileSync(path92.join(refRoot, refName), "utf-8").trim() || null;
34643
34803
  } catch {
34644
- const packed = fs88.readFileSync(path90.join(refRoot, "packed-refs"), "utf-8");
34804
+ const packed = fs90.readFileSync(path92.join(refRoot, "packed-refs"), "utf-8");
34645
34805
  for (const line of packed.split("\n")) {
34646
34806
  const pm = /^([0-9a-f]{40})\s+(.+)$/.exec(line.trim());
34647
34807
  if (pm !== null && pm[2] === refName) return pm[1];
@@ -34655,7 +34815,7 @@ function readHead(repoRoot) {
34655
34815
  function buildCheckpoint(repoRoot, runId, slug, opts = {}) {
34656
34816
  let text;
34657
34817
  try {
34658
- text = fs88.readFileSync(roadmapPath(repoRoot, slug), "utf-8");
34818
+ text = fs90.readFileSync(roadmapPath(repoRoot, slug), "utf-8");
34659
34819
  } catch {
34660
34820
  return null;
34661
34821
  }
@@ -34679,8 +34839,8 @@ function buildCheckpoint(repoRoot, runId, slug, opts = {}) {
34679
34839
  function writeCheckpoint(repoRoot, cp) {
34680
34840
  const file = checkpointFile(repoRoot, cp.run_id);
34681
34841
  try {
34682
- fs88.mkdirSync(path90.dirname(file), { recursive: true });
34683
- fs88.writeFileSync(file, `${JSON.stringify(cp, null, 2)}
34842
+ fs90.mkdirSync(path92.dirname(file), { recursive: true });
34843
+ fs90.writeFileSync(file, `${JSON.stringify(cp, null, 2)}
34684
34844
  `, "utf-8");
34685
34845
  return file;
34686
34846
  } catch {
@@ -34691,7 +34851,7 @@ function writeCheckpoint(repoRoot, cp) {
34691
34851
  // src/scripts/hooks/session_eol_hook.ts
34692
34852
  var EXIT_WARN17 = 2;
34693
34853
  var THRESHOLD_OVERRIDE_ENV = "AGENT_RECYCLE_THRESHOLD_TOKENS";
34694
- var CONTEXT_FILL_REL = path91.join("agents", "runtime", "state", "context-fill.json");
34854
+ var CONTEXT_FILL_REL = path93.join("agents", "runtime", "state", "context-fill.json");
34695
34855
  function str12(value) {
34696
34856
  return typeof value === "string" ? value : "";
34697
34857
  }
@@ -34706,7 +34866,7 @@ function payloadSessionId(payload, envelope) {
34706
34866
  }
34707
34867
  function readState4(file) {
34708
34868
  try {
34709
- const parsed = JSON.parse(fs89.readFileSync(file, "utf-8"));
34869
+ const parsed = JSON.parse(fs91.readFileSync(file, "utf-8"));
34710
34870
  if (parsed && typeof parsed === "object" && parsed.schema_version === 1 && parsed.counters && typeof parsed.counters.scanned_bytes === "number") {
34711
34871
  return {
34712
34872
  schema_version: 1,
@@ -34727,10 +34887,10 @@ function readState4(file) {
34727
34887
  };
34728
34888
  }
34729
34889
  function envelopeExists(workspaceRoot3, since = null) {
34730
- const target = path91.join(workspaceRoot3, RECYCLE_ENVELOPE_REL);
34890
+ const target = path93.join(workspaceRoot3, RECYCLE_ENVELOPE_REL);
34731
34891
  let raw;
34732
34892
  try {
34733
- raw = fs89.readFileSync(target, "utf-8");
34893
+ raw = fs91.readFileSync(target, "utf-8");
34734
34894
  } catch (exc) {
34735
34895
  return exc?.code !== "ENOENT";
34736
34896
  }
@@ -34744,7 +34904,7 @@ function envelopeExists(workspaceRoot3, since = null) {
34744
34904
  }
34745
34905
  }
34746
34906
  function buildMissingEnvelopeLine(workspaceRoot3) {
34747
- return `recycle advised earlier, but no envelope exists at ${path91.join(workspaceRoot3, RECYCLE_ENVELOPE_REL)} \u2014 /clear now starts the successor from nothing. Re-run \`agent-config session:recycle\` and check that it prints the absolute path it wrote before clearing.`;
34907
+ return `recycle advised earlier, but no envelope exists at ${path93.join(workspaceRoot3, RECYCLE_ENVELOPE_REL)} \u2014 /clear now starts the successor from nothing. Re-run \`agent-config session:recycle\` and check that it prints the absolute path it wrote before clearing.`;
34748
34908
  }
34749
34909
  function readThresholdTokens() {
34750
34910
  const override = process15.env[THRESHOLD_OVERRIDE_ENV];
@@ -34760,7 +34920,7 @@ function buildAdvisoryLine4(tokens, threshold) {
34760
34920
  }
34761
34921
  function writeContextFill(workspaceRoot3, tokens, threshold, ts) {
34762
34922
  try {
34763
- atomic_write_json(path91.join(workspaceRoot3, CONTEXT_FILL_REL), {
34923
+ atomic_write_json(path93.join(workspaceRoot3, CONTEXT_FILL_REL), {
34764
34924
  schema_version: 1,
34765
34925
  final_context_tokens: tokens,
34766
34926
  recycle_threshold_tokens: threshold,
@@ -34823,7 +34983,10 @@ function main58() {
34823
34983
  try {
34824
34984
  const slug = read_claimed_slug(workspaceRoot3, checkpointRunId);
34825
34985
  if (slug !== null) {
34826
- const cp = buildCheckpoint(workspaceRoot3, eolSessionKey(checkpointRunId), slug);
34986
+ const observed = readContextObservation(workspaceRoot3)?.fingerprint ?? null;
34987
+ const cp = buildCheckpoint(workspaceRoot3, eolSessionKey(checkpointRunId), slug, {
34988
+ ...observed !== null ? { contextFingerprint: observed } : {}
34989
+ });
34827
34990
  if (cp !== null) writeCheckpoint(workspaceRoot3, cp);
34828
34991
  }
34829
34992
  } catch {
@@ -34860,13 +35023,13 @@ function _isCliEntry45() {
34860
35023
  if (process15.argv[1] === void 0) {
34861
35024
  return false;
34862
35025
  }
34863
- const argvUrl = pathToFileURL52(path91.resolve(process15.argv[1])).href;
35026
+ const argvUrl = pathToFileURL52(path93.resolve(process15.argv[1])).href;
34864
35027
  if (import.meta.url === argvUrl) {
34865
35028
  return true;
34866
35029
  }
34867
35030
  try {
34868
- const here = fs89.realpathSync(fileURLToPath59(import.meta.url));
34869
- const argv = fs89.realpathSync(path91.resolve(process15.argv[1]));
35031
+ const here = fs91.realpathSync(fileURLToPath59(import.meta.url));
35032
+ const argv = fs91.realpathSync(path93.resolve(process15.argv[1]));
34870
35033
  return here === argv;
34871
35034
  } catch {
34872
35035
  return false;
@@ -34877,14 +35040,14 @@ if (_isCliEntry45()) {
34877
35040
  }
34878
35041
 
34879
35042
  // src/scripts/hooks/tool_result_bytes_hook.ts
34880
- import * as fs90 from "node:fs";
34881
- import * as path92 from "node:path";
35043
+ import * as fs92 from "node:fs";
35044
+ import * as path94 from "node:path";
34882
35045
  import { fileURLToPath as fileURLToPath60, pathToFileURL as pathToFileURL53 } from "node:url";
34883
35046
  var EXIT_ALLOW30 = 0;
34884
35047
  function isObject15(v) {
34885
35048
  return typeof v === "object" && v !== null && !Array.isArray(v);
34886
35049
  }
34887
- var CENSUS_FILE = path92.join("agents", "runtime", "state", "tool-result-census.jsonl");
35050
+ var CENSUS_FILE = path94.join("agents", "runtime", "state", "tool-result-census.jsonl");
34888
35051
  var RESULT_KEYS = ["tool_response", "toolResponse", "tool_result", "toolUseResult"];
34889
35052
  function _resultBytes(payload) {
34890
35053
  for (const key of RESULT_KEYS) {
@@ -34919,13 +35082,13 @@ function unwrapPayload4(envelope) {
34919
35082
  return isObject15(inner) ? inner : envelope;
34920
35083
  }
34921
35084
  function censusFile(consumerRoot) {
34922
- return path92.join(consumerRoot, CENSUS_FILE);
35085
+ return path94.join(consumerRoot, CENSUS_FILE);
34923
35086
  }
34924
35087
  function _appendCensusLine(consumerRoot, line) {
34925
35088
  if (is_replay_mode()) return;
34926
35089
  const file = censusFile(consumerRoot);
34927
- fs90.mkdirSync(path92.dirname(file), { recursive: true });
34928
- fs90.appendFileSync(file, `${JSON.stringify(line)}
35090
+ fs92.mkdirSync(path94.dirname(file), { recursive: true });
35091
+ fs92.appendFileSync(file, `${JSON.stringify(line)}
34929
35092
  `, "utf8");
34930
35093
  }
34931
35094
  function processEnvelope4(envelope, consumerRoot) {
@@ -34971,10 +35134,10 @@ function _isCliEntry46() {
34971
35134
  return false;
34972
35135
  }
34973
35136
  if (process.argv[1] === void 0) return false;
34974
- const argvUrl = pathToFileURL53(path92.resolve(process.argv[1])).href;
35137
+ const argvUrl = pathToFileURL53(path94.resolve(process.argv[1])).href;
34975
35138
  if (import.meta.url === argvUrl) return true;
34976
35139
  try {
34977
- return fs90.realpathSync(fileURLToPath60(import.meta.url)) === fs90.realpathSync(path92.resolve(process.argv[1]));
35140
+ return fs92.realpathSync(fileURLToPath60(import.meta.url)) === fs92.realpathSync(path94.resolve(process.argv[1]));
34978
35141
  } catch {
34979
35142
  return false;
34980
35143
  }
@@ -34982,8 +35145,8 @@ function _isCliEntry46() {
34982
35145
  if (_isCliEntry46()) process.exit(main59());
34983
35146
 
34984
35147
  // src/scripts/hooks/spawn_guard_shadow_hook.ts
34985
- import * as fs91 from "node:fs";
34986
- import * as path93 from "node:path";
35148
+ import * as fs93 from "node:fs";
35149
+ import * as path95 from "node:path";
34987
35150
  import { fileURLToPath as fileURLToPath61, pathToFileURL as pathToFileURL54 } from "node:url";
34988
35151
  var EXIT_ALLOW31 = 0;
34989
35152
  function isObject16(v) {
@@ -35061,10 +35224,10 @@ function main60() {
35061
35224
  function _isCliEntry47() {
35062
35225
  if (true) return false;
35063
35226
  if (process.argv[1] === void 0) return false;
35064
- const argvUrl = pathToFileURL54(path93.resolve(process.argv[1])).href;
35227
+ const argvUrl = pathToFileURL54(path95.resolve(process.argv[1])).href;
35065
35228
  if (import.meta.url === argvUrl) return true;
35066
35229
  try {
35067
- return fs91.realpathSync(fileURLToPath61(import.meta.url)) === fs91.realpathSync(path93.resolve(process.argv[1]));
35230
+ return fs93.realpathSync(fileURLToPath61(import.meta.url)) === fs93.realpathSync(path95.resolve(process.argv[1]));
35068
35231
  } catch {
35069
35232
  return false;
35070
35233
  }
@@ -35072,13 +35235,13 @@ function _isCliEntry47() {
35072
35235
  if (_isCliEntry47()) process.exit(main60());
35073
35236
 
35074
35237
  // src/scripts/hooks/source_first_gate_hook.ts
35075
- import * as fs92 from "node:fs";
35076
- import * as path94 from "node:path";
35238
+ import * as fs94 from "node:fs";
35239
+ import * as path96 from "node:path";
35077
35240
  import { fileURLToPath as fileURLToPath62, pathToFileURL as pathToFileURL55 } from "node:url";
35078
35241
  var EXIT_ALLOW32 = 0;
35079
35242
  var MAX_SHADOW_WARNS = 2;
35080
- var SHADOW_LOG = path94.join("agents", "runtime", "state", "source-first-gate.jsonl");
35081
- var STATE_FILE9 = path94.join("agents", "runtime", "state", "source-first-gate.json");
35243
+ var SHADOW_LOG = path96.join("agents", "runtime", "state", "source-first-gate.jsonl");
35244
+ var STATE_FILE9 = path96.join("agents", "runtime", "state", "source-first-gate.json");
35082
35245
  function isObject17(v) {
35083
35246
  return typeof v === "object" && v !== null && !Array.isArray(v);
35084
35247
  }
@@ -35152,7 +35315,7 @@ var EMPTY_STATE = { handoverSeen: false, sourceRead: false, wouldWarn: 0 };
35152
35315
  var MAX_SESSIONS2 = 50;
35153
35316
  function readState5(root, session) {
35154
35317
  try {
35155
- const all = JSON.parse(fs92.readFileSync(path94.join(root, STATE_FILE9), "utf-8"));
35318
+ const all = JSON.parse(fs94.readFileSync(path96.join(root, STATE_FILE9), "utf-8"));
35156
35319
  const entry = all[session];
35157
35320
  if (entry && typeof entry.handoverSeen === "boolean" && typeof entry.sourceRead === "boolean" && typeof entry.wouldWarn === "number") {
35158
35321
  return entry;
@@ -35164,10 +35327,10 @@ function readState5(root, session) {
35164
35327
  function writeState4(root, session, state) {
35165
35328
  if (is_replay_mode()) return;
35166
35329
  try {
35167
- const file = path94.join(root, STATE_FILE9);
35330
+ const file = path96.join(root, STATE_FILE9);
35168
35331
  let all = {};
35169
35332
  try {
35170
- all = JSON.parse(fs92.readFileSync(file, "utf-8"));
35333
+ all = JSON.parse(fs94.readFileSync(file, "utf-8"));
35171
35334
  } catch {
35172
35335
  }
35173
35336
  if (!isObject17(all)) all = {};
@@ -35178,8 +35341,8 @@ function writeState4(root, session, state) {
35178
35341
  for (const key of keys.slice(keys.length - MAX_SESSIONS2)) pruned[key] = all[key];
35179
35342
  all = pruned;
35180
35343
  }
35181
- fs92.mkdirSync(path94.dirname(file), { recursive: true });
35182
- fs92.writeFileSync(file, JSON.stringify(all));
35344
+ fs94.mkdirSync(path96.dirname(file), { recursive: true });
35345
+ fs94.writeFileSync(file, JSON.stringify(all));
35183
35346
  } catch {
35184
35347
  }
35185
35348
  }
@@ -35200,7 +35363,7 @@ function evaluateCandidates2(handoverSeen, handoverOnDisk, sourceRead) {
35200
35363
  }
35201
35364
  function handoverPresentOnDisk(root) {
35202
35365
  try {
35203
- return fs92.statSync(path94.join(root, ".claude", "design-system")).isDirectory();
35366
+ return fs94.statSync(path96.join(root, ".claude", "design-system")).isDirectory();
35204
35367
  } catch {
35205
35368
  return false;
35206
35369
  }
@@ -35208,9 +35371,9 @@ function handoverPresentOnDisk(root) {
35208
35371
  function appendShadowLine(root, line) {
35209
35372
  if (is_replay_mode()) return;
35210
35373
  try {
35211
- const file = path94.join(root, SHADOW_LOG);
35212
- fs92.mkdirSync(path94.dirname(file), { recursive: true });
35213
- fs92.appendFileSync(file, `${JSON.stringify(line)}
35374
+ const file = path96.join(root, SHADOW_LOG);
35375
+ fs94.mkdirSync(path96.dirname(file), { recursive: true });
35376
+ fs94.appendFileSync(file, `${JSON.stringify(line)}
35214
35377
  `, "utf8");
35215
35378
  } catch {
35216
35379
  }
@@ -35286,10 +35449,10 @@ function main61() {
35286
35449
  function _isCliEntry48() {
35287
35450
  if (true) return false;
35288
35451
  if (process.argv[1] === void 0) return false;
35289
- const argvUrl = pathToFileURL55(path94.resolve(process.argv[1])).href;
35452
+ const argvUrl = pathToFileURL55(path96.resolve(process.argv[1])).href;
35290
35453
  if (import.meta.url === argvUrl) return true;
35291
35454
  try {
35292
- return fs92.realpathSync(fileURLToPath62(import.meta.url)) === fs92.realpathSync(path94.resolve(process.argv[1]));
35455
+ return fs94.realpathSync(fileURLToPath62(import.meta.url)) === fs94.realpathSync(path96.resolve(process.argv[1]));
35293
35456
  } catch {
35294
35457
  return false;
35295
35458
  }
@@ -35297,12 +35460,12 @@ function _isCliEntry48() {
35297
35460
  if (_isCliEntry48()) process.exit(main61());
35298
35461
 
35299
35462
  // src/scripts/hooks/interruption_ledger_hook.ts
35300
- import * as fs93 from "node:fs";
35301
- import * as path95 from "node:path";
35463
+ import * as fs95 from "node:fs";
35464
+ import * as path97 from "node:path";
35302
35465
  import { fileURLToPath as fileURLToPath63, pathToFileURL as pathToFileURL56 } from "node:url";
35303
35466
  var EXIT_OK2 = 0;
35304
35467
  var TRANSCRIPT_READ_MAX_BYTES2 = 2 * 1024 * 1024;
35305
- var LEDGER_RELPATH = path95.join("agents", "runtime", "state", "interruptions.jsonl");
35468
+ var LEDGER_RELPATH = path97.join("agents", "runtime", "state", "interruptions.jsonl");
35306
35469
  function hasNumberedOptions(reply) {
35307
35470
  let count = 0;
35308
35471
  for (const line of reply.split("\n")) {
@@ -35326,14 +35489,14 @@ function classifyReply(reply) {
35326
35489
  function readClaimedRoadmap(workspaceRoot3, sessionId2) {
35327
35490
  if (!sessionId2) return null;
35328
35491
  try {
35329
- const file = path95.join(
35492
+ const file = path97.join(
35330
35493
  workspaceRoot3,
35331
35494
  "agents",
35332
35495
  "runtime",
35333
35496
  "state",
35334
35497
  `roadmap-claim-${sessionId2}.json`
35335
35498
  );
35336
- const parsed = JSON.parse(fs93.readFileSync(file, "utf8"));
35499
+ const parsed = JSON.parse(fs95.readFileSync(file, "utf8"));
35337
35500
  if (parsed === null || typeof parsed !== "object") return null;
35338
35501
  const slug = parsed["slug"];
35339
35502
  return typeof slug === "string" && slug.length > 0 ? slug : null;
@@ -35344,7 +35507,7 @@ function readClaimedRoadmap(workspaceRoot3, sessionId2) {
35344
35507
  function alreadyRecorded(ledgerPath, runId, turn) {
35345
35508
  let raw;
35346
35509
  try {
35347
- raw = fs93.readFileSync(ledgerPath, "utf8");
35510
+ raw = fs95.readFileSync(ledgerPath, "utf8");
35348
35511
  } catch {
35349
35512
  return false;
35350
35513
  }
@@ -35388,7 +35551,7 @@ function main62() {
35388
35551
  if (!lastAssistant) return EXIT_OK2;
35389
35552
  const sessionId2 = str14(payload["session_id"]) || str14(envelope["session_id"]);
35390
35553
  const runId = sessionId2 ? derive_session_tag(sessionId2) : "unknown";
35391
- const ledgerPath = path95.join(workspaceRoot3, LEDGER_RELPATH);
35554
+ const ledgerPath = path97.join(workspaceRoot3, LEDGER_RELPATH);
35392
35555
  if (alreadyRecorded(ledgerPath, runId, turnOrdinal)) return EXIT_OK2;
35393
35556
  const verdict = classifyReply(lastAssistant);
35394
35557
  const record = {
@@ -35400,8 +35563,8 @@ function main62() {
35400
35563
  at: (/* @__PURE__ */ new Date()).toISOString()
35401
35564
  };
35402
35565
  try {
35403
- fs93.mkdirSync(path95.dirname(ledgerPath), { recursive: true });
35404
- fs93.appendFileSync(ledgerPath, `${JSON.stringify(record)}
35566
+ fs95.mkdirSync(path97.dirname(ledgerPath), { recursive: true });
35567
+ fs95.appendFileSync(ledgerPath, `${JSON.stringify(record)}
35405
35568
  `, "utf8");
35406
35569
  } catch {
35407
35570
  }
@@ -35411,13 +35574,13 @@ function _isCliEntry49() {
35411
35574
  if (process.argv[1] === void 0) {
35412
35575
  return false;
35413
35576
  }
35414
- const argvUrl = pathToFileURL56(path95.resolve(process.argv[1])).href;
35577
+ const argvUrl = pathToFileURL56(path97.resolve(process.argv[1])).href;
35415
35578
  if (import.meta.url === argvUrl) {
35416
35579
  return true;
35417
35580
  }
35418
35581
  try {
35419
- const here = fs93.realpathSync(fileURLToPath63(import.meta.url));
35420
- const argv = fs93.realpathSync(path95.resolve(process.argv[1]));
35582
+ const here = fs95.realpathSync(fileURLToPath63(import.meta.url));
35583
+ const argv = fs95.realpathSync(path97.resolve(process.argv[1]));
35421
35584
  return here === argv;
35422
35585
  } catch {
35423
35586
  return false;
@@ -35428,15 +35591,15 @@ if (_isCliEntry49()) {
35428
35591
  }
35429
35592
 
35430
35593
  // src/scripts/hooks/run_continuation_hook.ts
35431
- import * as fs96 from "node:fs";
35594
+ import * as fs97 from "node:fs";
35432
35595
 
35433
35596
  // src/scripts/_lib/billing_grant.ts
35434
- import * as fs94 from "node:fs";
35435
- import * as path96 from "node:path";
35436
- var BILLING_GRANT_DIR_REL = path96.join("agents", "runtime", "billing-grants");
35597
+ import * as fs96 from "node:fs";
35598
+ import * as path98 from "node:path";
35599
+ var BILLING_GRANT_DIR_REL = path98.join("agents", "runtime", "billing-grants");
35437
35600
  var BILLING_GRANT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
35438
35601
  function grantFile(repoRoot, runId) {
35439
- return path96.join(
35602
+ return path98.join(
35440
35603
  repoRoot,
35441
35604
  BILLING_GRANT_DIR_REL,
35442
35605
  `${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`
@@ -35444,79 +35607,96 @@ function grantFile(repoRoot, runId) {
35444
35607
  }
35445
35608
  function revokeBillingGrant(repoRoot, runId) {
35446
35609
  try {
35447
- fs94.unlinkSync(grantFile(repoRoot, runId));
35610
+ fs96.unlinkSync(grantFile(repoRoot, runId));
35448
35611
  } catch {
35449
35612
  }
35450
35613
  }
35451
35614
 
35452
35615
  // src/scripts/hooks/run_continuation_hook.ts
35453
- import * as path98 from "node:path";
35616
+ import * as path99 from "node:path";
35454
35617
  import { fileURLToPath as fileURLToPath64, pathToFileURL as pathToFileURL57 } from "node:url";
35455
35618
 
35456
- // src/scripts/_lib/loop_guards.ts
35457
- import * as fs95 from "node:fs";
35458
- import * as path97 from "node:path";
35459
- function atomicWriteJson(file, value) {
35460
- const tmp = `${file}.${String(process.pid)}.tmp`;
35461
- try {
35462
- fs95.mkdirSync(path97.dirname(file), { recursive: true });
35463
- fs95.writeFileSync(tmp, `${JSON.stringify(value)}
35464
- `, "utf8");
35465
- fs95.renameSync(tmp, file);
35466
- return true;
35467
- } catch {
35468
- try {
35469
- fs95.unlinkSync(tmp);
35470
- } catch {
35471
- }
35472
- return false;
35473
- }
35474
- }
35475
- var DEPENDENCY_PATTERNS = [
35476
- { kind: "binary", re: /\b(?:command not found|is not recognized as an internal or external command)\b/i },
35477
- { kind: "credential", re: /\b(?:not (?:authenticated|logged in)|authentication (?:failed|required)|no credentials found)\b/i },
35478
- { kind: "credential", re: /\b(?:missing|unset|not set)\b[^\n]{0,40}\b(?:credential|token|api[_ -]?key|secret)\b/i },
35479
- { kind: "permission", re: /\b(?:permission denied|forbidden|403 forbidden)\b/i },
35480
- { kind: "quota", re: /\b(?:rate limit(?:ed| exceeded| reached)?|quota exceeded|429 too many requests|spend (?:cap|limit) reached)\b/i },
35481
- { kind: "service", re: /\b(?:5\d\d (?:internal )?server error|service unavailable|connection refused)\b/i }
35619
+ // src/scripts/_lib/outcome_vocabularies.ts
35620
+ var RUN_TERMINAL_STATES = [
35621
+ "success",
35622
+ "clean-no-op",
35623
+ "blocked",
35624
+ "approval-required",
35625
+ "exhausted",
35626
+ "stagnated",
35627
+ /**
35628
+ * The plan premise this run was built on no longer holds — the situational
35629
+ * -awareness fingerprint the run engaged under (`origin/main` plus every open
35630
+ * PR head) was re-observed and differs.
35631
+ *
35632
+ * Added by `road-to-wired-instruments` Phase 2 under the AI-council decision
35633
+ * of 2026-09-03 (option (a), unanimous). It is NOT `blocked` with a reason
35634
+ * field: premise invalidation is operationally distinct from a missing
35635
+ * precondition and from an exhausted budget, and folding it into either loses
35636
+ * both aggregation by state and type-enforced exhaustive handling. The
35637
+ * remedy differs too — re-probe and re-plan, where `blocked` says obtain the
35638
+ * missing thing and `exhausted` says the budget was too small.
35639
+ */
35640
+ "premise-invalidated"
35482
35641
  ];
35483
- var DEPENDENCY_SCAN_BYTES = 64 * 1024;
35484
- function detectUnavailableDependency(transcriptTail, tailLines = 200) {
35485
- const lines = transcriptTail.split("\n");
35486
- const window = lines.slice(Math.max(0, lines.length - tailLines));
35487
- for (const line of window) {
35488
- for (const { kind, re } of DEPENDENCY_PATTERNS) {
35489
- if (re.test(line)) {
35490
- return { kind, evidence: line.trim().slice(0, 200) };
35491
- }
35492
- }
35493
- }
35494
- return null;
35642
+ var RUN_TERMINAL_VOCABULARY_VERSION = 2;
35643
+
35644
+ // src/scripts/_lib/continuation_ladder.ts
35645
+ var MAX_ITERATIONS = 25;
35646
+ var WALL_CLOCK_CAP_MS = 4 * 60 * 60 * 1e3;
35647
+ var STALL_WINDOW = 3;
35648
+ var HALT_ACTIONS = [
35649
+ "halt-max-iterations",
35650
+ "halt-wall-clock",
35651
+ "halt-stall",
35652
+ // Phase 5.4. Checked BEFORE the counter rungs: a dependency the run cannot
35653
+ // obtain is not something more iterations close, so consuming the budget
35654
+ // against it is the waste the rung exists to stop.
35655
+ "halt-dependency-unavailable",
35656
+ // `road-to-wired-instruments` 2.2, and BEFORE the counter rungs for the same
35657
+ // reason: a run whose plan premise moved does not become correct by running
35658
+ // more iterations against the stale plan, and letting it cap out reports
35659
+ // `exhausted` — a budget problem, whose remedy is a bigger budget — for what
35660
+ // is actually a staleness problem, whose remedy is a re-probe.
35661
+ "halt-premise-invalidated"
35662
+ ];
35663
+ var TERMINAL_STATE_BY_ACTION = {
35664
+ engage: null,
35665
+ complete: "success",
35666
+ blocked: "blocked",
35667
+ "halt-max-iterations": "exhausted",
35668
+ "halt-wall-clock": "exhausted",
35669
+ "halt-stall": "stagnated",
35670
+ "halt-dependency-unavailable": "blocked",
35671
+ "halt-premise-invalidated": "premise-invalidated"
35672
+ };
35673
+ function terminalStateFor(action) {
35674
+ return TERMINAL_STATE_BY_ACTION[action] ?? null;
35495
35675
  }
35496
- function stallSignal(history, window = 3) {
35497
- if (history.length === 0) {
35498
- return { level: "flat", flatRun: 0, minimum: null, newMinimum: false };
35676
+ function ladder(state, openCount, nowMs, blockedCount, caps = {
35677
+ maxIterations: MAX_ITERATIONS,
35678
+ wallClockMs: WALL_CLOCK_CAP_MS,
35679
+ stallWindow: STALL_WINDOW
35680
+ }, unavailable = null, premiseInvalidated = false) {
35681
+ if (state.halted) return state.halted;
35682
+ if (openCount === 0) return blockedCount > 0 ? "blocked" : "complete";
35683
+ if (unavailable !== null) return "halt-dependency-unavailable";
35684
+ if (premiseInvalidated) return "halt-premise-invalidated";
35685
+ if (state.iterations >= caps.maxIterations) return "halt-max-iterations";
35686
+ const started = Date.parse(state.started_at);
35687
+ if (Number.isFinite(started) && nowMs - started >= caps.wallClockMs) {
35688
+ return "halt-wall-clock";
35499
35689
  }
35500
- const last = history[history.length - 1];
35501
- const minimum = Math.min(...history);
35502
- const earlier = history.slice(0, -1);
35503
- const newMinimum = earlier.length > 0 && last < Math.min(...earlier);
35504
- let flatRun = 1;
35505
- for (let i = history.length - 2; i >= 0; i -= 1) {
35506
- if (history[i] !== last) break;
35507
- flatRun += 1;
35690
+ const tail = state.history.slice(-caps.stallWindow);
35691
+ if (tail.length >= caps.stallWindow && tail.every((n) => n === openCount)) {
35692
+ return "halt-stall";
35508
35693
  }
35509
- if (newMinimum) return { level: "progressing", flatRun, minimum, newMinimum };
35510
- if (flatRun >= window) return { level: "stalled", flatRun, minimum, newMinimum };
35511
- return { level: "flat", flatRun, minimum, newMinimum };
35694
+ return "engage";
35512
35695
  }
35513
- function readUnavailableDependency(transcriptPath) {
35514
- try {
35515
- const raw = fs95.readFileSync(transcriptPath, "utf8");
35516
- return detectUnavailableDependency(raw.slice(-DEPENDENCY_SCAN_BYTES));
35517
- } catch {
35518
- return null;
35519
- }
35696
+ function parseHaltStamp(v) {
35697
+ if (typeof v !== "string") return null;
35698
+ if (HALT_ACTIONS.includes(v)) return v;
35699
+ return v.startsWith("halt-") ? v : null;
35520
35700
  }
35521
35701
 
35522
35702
  // src/scripts/hooks/run_continuation_hook.ts
@@ -35524,16 +35704,13 @@ var EXIT_ALLOW33 = 0;
35524
35704
  var EXIT_BLOCK5 = 1;
35525
35705
  var BLOCKED_BY_MARKER = /<!--\s*blocked-by:\s*\S[^>]*-->/;
35526
35706
  var LEDGER_TAIL_MAX_BYTES = 512 * 1024;
35527
- var EVENTS_RELPATH = path98.join(
35707
+ var EVENTS_RELPATH = path99.join(
35528
35708
  "agents",
35529
35709
  "runtime",
35530
35710
  "state",
35531
35711
  "run-continuation.jsonl"
35532
35712
  );
35533
- var STATE_DIR_REL = path98.join("agents", "runtime", "state");
35534
- var MAX_ITERATIONS = 25;
35535
- var WALL_CLOCK_CAP_MS = 4 * 60 * 60 * 1e3;
35536
- var STALL_WINDOW = 3;
35713
+ var STATE_DIR_REL = path99.join("agents", "runtime", "state");
35537
35714
  var ABSENT_CONFIRM_FIRES = 2;
35538
35715
  var DUPLICATE_WINDOW_MS = 60 * 1e3;
35539
35716
  function isDuplicateFire(state, turnOrdinal, openCount, nowMs, roadmapSource) {
@@ -35548,15 +35725,6 @@ function isDuplicateFire(state, turnOrdinal, openCount, nowMs, roadmapSource) {
35548
35725
  const at = Date.parse(state.last_engaged_at ?? "");
35549
35726
  return Number.isFinite(at) && nowMs - at < DUPLICATE_WINDOW_MS;
35550
35727
  }
35551
- var HALT_ACTIONS = [
35552
- "halt-max-iterations",
35553
- "halt-wall-clock",
35554
- "halt-stall",
35555
- // Phase 5.4. Checked BEFORE the counter rungs: a dependency the run cannot
35556
- // obtain is not something more iterations close, so consuming the budget
35557
- // against it is the waste the rung exists to stop.
35558
- "halt-dependency-unavailable"
35559
- ];
35560
35728
  function parseExecutionMode(text) {
35561
35729
  if (!text.startsWith("---")) return null;
35562
35730
  const end = text.indexOf("\n---", 3);
@@ -35611,42 +35779,23 @@ function extractVerify(stepText) {
35611
35779
  if (backticked !== null) return backticked[1].trim() || null;
35612
35780
  return null;
35613
35781
  }
35614
- function ladder(state, openCount, nowMs, blockedCount, caps = {
35615
- maxIterations: MAX_ITERATIONS,
35616
- wallClockMs: WALL_CLOCK_CAP_MS,
35617
- stallWindow: STALL_WINDOW
35618
- }, unavailable = null) {
35619
- if (state.halted) return state.halted;
35620
- if (openCount === 0) return blockedCount > 0 ? "blocked" : "complete";
35621
- if (unavailable !== null) return "halt-dependency-unavailable";
35622
- if (state.iterations >= caps.maxIterations) return "halt-max-iterations";
35623
- const started = Date.parse(state.started_at);
35624
- if (Number.isFinite(started) && nowMs - started >= caps.wallClockMs) {
35625
- return "halt-wall-clock";
35626
- }
35627
- const tail = state.history.slice(-caps.stallWindow);
35628
- if (tail.length >= caps.stallWindow && tail.every((n) => n === openCount)) {
35629
- return "halt-stall";
35630
- }
35631
- return "engage";
35632
- }
35633
35782
  function stateRelPath(runId, slug) {
35634
35783
  const safeRun = runId.replace(/[^A-Za-z0-9_-]/g, "_");
35635
35784
  const safeSlug = slug.replace(/[^A-Za-z0-9_-]/g, "_");
35636
- return path98.join(STATE_DIR_REL, `run-continuation-${safeRun}-${safeSlug}.json`);
35785
+ return path99.join(STATE_DIR_REL, `run-continuation-${safeRun}-${safeSlug}.json`);
35637
35786
  }
35638
35787
  function legacyStateRelPath(runId) {
35639
35788
  const safe = runId.replace(/[^A-Za-z0-9_-]/g, "_");
35640
- return path98.join(STATE_DIR_REL, `run-continuation-${safe}.json`);
35789
+ return path99.join(STATE_DIR_REL, `run-continuation-${safe}.json`);
35641
35790
  }
35642
35791
  function readRunState(workspaceRoot3, runId, slug) {
35643
- const keyedFile = path98.join(workspaceRoot3, stateRelPath(runId, slug));
35792
+ const keyedFile = path99.join(workspaceRoot3, stateRelPath(runId, slug));
35644
35793
  const keyed = readState6(keyedFile);
35645
35794
  if (keyed !== null) return { state: keyed, from: "keyed", keyedFile };
35646
35795
  if (fileExists(keyedFile)) {
35647
35796
  return { state: null, from: "keyed", keyedFile };
35648
35797
  }
35649
- const legacy = readState6(path98.join(workspaceRoot3, legacyStateRelPath(runId)));
35798
+ const legacy = readState6(path99.join(workspaceRoot3, legacyStateRelPath(runId)));
35650
35799
  if (legacy === null) return { state: null, from: "none", keyedFile };
35651
35800
  if (legacy.roadmap !== void 0 && legacy.roadmap !== slug) {
35652
35801
  return { state: null, from: "none", keyedFile };
@@ -35659,25 +35808,25 @@ function writeState5(file, state) {
35659
35808
  function clearRunState(workspaceRoot3, runId, keyedFile, adoptedLegacy) {
35660
35809
  revokeBillingGrant(workspaceRoot3, runId);
35661
35810
  try {
35662
- fs96.rmSync(keyedFile, { force: true });
35811
+ fs97.rmSync(keyedFile, { force: true });
35663
35812
  } catch {
35664
35813
  }
35665
35814
  if (!adoptedLegacy) return;
35666
35815
  try {
35667
- fs96.rmSync(path98.join(workspaceRoot3, legacyStateRelPath(runId)), { force: true });
35816
+ fs97.rmSync(path99.join(workspaceRoot3, legacyStateRelPath(runId)), { force: true });
35668
35817
  } catch {
35669
35818
  }
35670
35819
  }
35671
35820
  function fileExists(p) {
35672
35821
  try {
35673
- return fs96.statSync(p).isFile();
35822
+ return fs97.statSync(p).isFile();
35674
35823
  } catch {
35675
35824
  return false;
35676
35825
  }
35677
35826
  }
35678
35827
  function readState6(file) {
35679
35828
  try {
35680
- const parsed = JSON.parse(fs96.readFileSync(file, "utf8"));
35829
+ const parsed = JSON.parse(fs97.readFileSync(file, "utf8"));
35681
35830
  if (parsed === null || typeof parsed !== "object") return null;
35682
35831
  const o = parsed;
35683
35832
  if (typeof o["started_at"] !== "string") return null;
@@ -35707,26 +35856,27 @@ function readState6(file) {
35707
35856
  if (o["inert_reported"] === true) {
35708
35857
  rec.inert_reported = true;
35709
35858
  }
35710
- const halted = o["halted"];
35711
- if (typeof halted === "string" && HALT_ACTIONS.includes(halted)) {
35712
- rec.halted = halted;
35859
+ if (typeof o["context_fingerprint"] === "string" && o["context_fingerprint"] !== "") {
35860
+ rec.context_fingerprint = o["context_fingerprint"];
35713
35861
  }
35862
+ const halted = parseHaltStamp(o["halted"]);
35863
+ if (halted !== null) rec.halted = halted;
35714
35864
  return rec;
35715
35865
  } catch {
35716
35866
  return null;
35717
35867
  }
35718
35868
  }
35719
35869
  function normalizeDir(p) {
35720
- const abs = path98.resolve(p);
35870
+ const abs = path99.resolve(p);
35721
35871
  try {
35722
- return fs96.realpathSync(abs);
35872
+ return fs97.realpathSync(abs);
35723
35873
  } catch {
35724
35874
  return abs;
35725
35875
  }
35726
35876
  }
35727
35877
  function normalizeFile(p) {
35728
- const abs = path98.resolve(p);
35729
- return path98.join(normalizeDir(path98.dirname(abs)), path98.basename(abs));
35878
+ const abs = path99.resolve(p);
35879
+ return path99.join(normalizeDir(path99.dirname(abs)), path99.basename(abs));
35730
35880
  }
35731
35881
  function provenance(workspaceRoot3, claimPath, sessionRoot, sessionCwd) {
35732
35882
  const reader = normalizeDir(workspaceRoot3);
@@ -35753,36 +35903,36 @@ function provenance(workspaceRoot3, claimPath, sessionRoot, sessionCwd) {
35753
35903
  };
35754
35904
  }
35755
35905
  function resolveRoadmap(sessionRoot, workspaceRoot3, slug) {
35756
- const dirRel = path98.join("agents", "roadmaps");
35906
+ const dirRel = path99.join("agents", "roadmaps");
35757
35907
  const stem = slug.trim().replace(/\.md$/, "");
35758
- const rel = path98.join(dirRel, `${stem}.md`);
35759
- const norm = path98.normalize(rel);
35760
- if (path98.dirname(norm) !== dirRel) return null;
35761
- if (sessionRoot !== workspaceRoot3 && isDirectory(path98.join(sessionRoot, dirRel))) {
35762
- return path98.join(sessionRoot, norm);
35908
+ const rel = path99.join(dirRel, `${stem}.md`);
35909
+ const norm = path99.normalize(rel);
35910
+ if (path99.dirname(norm) !== dirRel) return null;
35911
+ if (sessionRoot !== workspaceRoot3 && isDirectory(path99.join(sessionRoot, dirRel))) {
35912
+ return path99.join(sessionRoot, norm);
35763
35913
  }
35764
- return path98.join(normalizeDir(workspaceRoot3), norm);
35914
+ return path99.join(normalizeDir(workspaceRoot3), norm);
35765
35915
  }
35766
35916
  function isDirectory(p) {
35767
35917
  try {
35768
- return fs96.statSync(p).isDirectory();
35918
+ return fs97.statSync(p).isDirectory();
35769
35919
  } catch {
35770
35920
  return false;
35771
35921
  }
35772
35922
  }
35773
35923
  function eventAlreadyLogged(workspaceRoot3, runId, slug, event) {
35774
35924
  try {
35775
- const file = path98.join(workspaceRoot3, EVENTS_RELPATH);
35776
- const size = fs96.statSync(file).size;
35925
+ const file = path99.join(workspaceRoot3, EVENTS_RELPATH);
35926
+ const size = fs97.statSync(file).size;
35777
35927
  const start = Math.max(0, size - LEDGER_TAIL_MAX_BYTES);
35778
- const fd = fs96.openSync(file, "r");
35928
+ const fd = fs97.openSync(file, "r");
35779
35929
  let text;
35780
35930
  try {
35781
35931
  const buf = Buffer.alloc(size - start);
35782
- const read = fs96.readSync(fd, buf, 0, buf.length, start);
35932
+ const read = fs97.readSync(fd, buf, 0, buf.length, start);
35783
35933
  text = buf.subarray(0, read).toString("utf8");
35784
35934
  } finally {
35785
- fs96.closeSync(fd);
35935
+ fs97.closeSync(fd);
35786
35936
  }
35787
35937
  for (const line of text.split("\n")) {
35788
35938
  if (line === "") continue;
@@ -35805,9 +35955,9 @@ function eventAlreadyLogged(workspaceRoot3, runId, slug, event) {
35805
35955
  }
35806
35956
  function appendEvent2(workspaceRoot3, record) {
35807
35957
  try {
35808
- const file = path98.join(workspaceRoot3, EVENTS_RELPATH);
35809
- fs96.mkdirSync(path98.dirname(file), { recursive: true });
35810
- fs96.appendFileSync(file, `${JSON.stringify(record)}
35958
+ const file = path99.join(workspaceRoot3, EVENTS_RELPATH);
35959
+ fs97.mkdirSync(path99.dirname(file), { recursive: true });
35960
+ fs97.appendFileSync(file, `${JSON.stringify(record)}
35811
35961
  `, "utf8");
35812
35962
  } catch {
35813
35963
  }
@@ -35815,7 +35965,7 @@ function appendEvent2(workspaceRoot3, record) {
35815
35965
  function refusedThisTurn(workspaceRoot3, sessionId2, turnOrdinal) {
35816
35966
  try {
35817
35967
  const file = sessionRefusalFile(workspaceRoot3, deriveSessionKey(sessionId2 || "unknown-session"));
35818
- const rec = parseRecord(fs96.readFileSync(file, "utf-8"));
35968
+ const rec = parseRecord(fs97.readFileSync(file, "utf-8"));
35819
35969
  return rec !== null && rec.refused_turn === turnOrdinal;
35820
35970
  } catch {
35821
35971
  return false;
@@ -35849,7 +35999,7 @@ function main63() {
35849
35999
  let roadmapText = null;
35850
36000
  if (roadmapPath2 !== null) {
35851
36001
  try {
35852
- roadmapText = fs96.readFileSync(roadmapPath2, "utf8");
36002
+ roadmapText = fs97.readFileSync(roadmapPath2, "utf8");
35853
36003
  roadmapFile = roadmapPath2;
35854
36004
  } catch {
35855
36005
  roadmapText = null;
@@ -35898,7 +36048,7 @@ function main63() {
35898
36048
  );
35899
36049
  if (!transcriptPath) return EXIT_ALLOW33;
35900
36050
  try {
35901
- if (fs96.statSync(transcriptPath).size > TRANSCRIPT_READ_MAX_BYTES) {
36051
+ if (fs97.statSync(transcriptPath).size > TRANSCRIPT_READ_MAX_BYTES) {
35902
36052
  const inert = readRunState(workspaceRoot3, runId, slug);
35903
36053
  if (inert.state !== null && inert.state.inert_reported !== true) {
35904
36054
  const inertRoots = provenance(
@@ -35973,7 +36123,17 @@ function main63() {
35973
36123
  }
35974
36124
  const unavailable = readUnavailableDependency(transcriptPath);
35975
36125
  state.stall = stallSignal(state.history, STALL_WINDOW).level;
35976
- const action = ladder(state, scan.open, Date.now(), scan.blocked, void 0, unavailable);
36126
+ const observed = readContextObservation(workspaceRoot3)?.fingerprint ?? null;
36127
+ const premiseInvalidated = premiseMoved(state.context_fingerprint, observed);
36128
+ const action = ladder(
36129
+ state,
36130
+ scan.open,
36131
+ Date.now(),
36132
+ scan.blocked,
36133
+ void 0,
36134
+ unavailable,
36135
+ premiseInvalidated
36136
+ );
35977
36137
  if (action !== "engage") {
35978
36138
  const alreadyStamped = prev?.halted !== void 0;
35979
36139
  const alreadyBlocked = action === "blocked" && eventAlreadyLogged(workspaceRoot3, runId, slug, "blocked");
@@ -35986,6 +36146,12 @@ function main63() {
35986
36146
  iterations: state.iterations,
35987
36147
  open: scan.open,
35988
36148
  blocked: scan.blocked,
36149
+ // A ledger line is a persisted shape carrying a `RunTerminalState`,
36150
+ // so it names the vocabulary version it was written against: a
36151
+ // reader meeting an unknown value can then tell a newer writer
36152
+ // from a corrupt row.
36153
+ terminal_state: terminalStateFor(action),
36154
+ terminal_vocabulary_version: RUN_TERMINAL_VOCABULARY_VERSION,
35989
36155
  at: (/* @__PURE__ */ new Date()).toISOString(),
35990
36156
  ...roots
35991
36157
  });
@@ -36006,6 +36172,9 @@ function main63() {
36006
36172
  }
36007
36173
  state.iterations += 1;
36008
36174
  state.last_turn = turnOrdinal;
36175
+ if (state.context_fingerprint === void 0 && observed !== null) {
36176
+ state.context_fingerprint = observed;
36177
+ }
36009
36178
  state.history.push(scan.open);
36010
36179
  state.last_engaged_at = (/* @__PURE__ */ new Date()).toISOString();
36011
36180
  if (!writeState5(stateFile4, state)) {
@@ -36038,11 +36207,11 @@ function _isCliEntry50() {
36038
36207
  return false;
36039
36208
  }
36040
36209
  if (process.argv[1] === void 0) return false;
36041
- const argvUrl = pathToFileURL57(path98.resolve(process.argv[1])).href;
36210
+ const argvUrl = pathToFileURL57(path99.resolve(process.argv[1])).href;
36042
36211
  if (import.meta.url === argvUrl) return true;
36043
36212
  try {
36044
- const here = fs96.realpathSync(fileURLToPath64(import.meta.url));
36045
- const argv = fs96.realpathSync(path98.resolve(process.argv[1]));
36213
+ const here = fs97.realpathSync(fileURLToPath64(import.meta.url));
36214
+ const argv = fs97.realpathSync(path99.resolve(process.argv[1]));
36046
36215
  return here === argv;
36047
36216
  } catch {
36048
36217
  return false;
@@ -36053,26 +36222,14 @@ if (_isCliEntry50()) {
36053
36222
  }
36054
36223
 
36055
36224
  // src/scripts/hooks/journal_record_hook.ts
36056
- import * as fs98 from "node:fs";
36057
- import * as path100 from "node:path";
36225
+ import * as fs99 from "node:fs";
36226
+ import * as path101 from "node:path";
36058
36227
  import { fileURLToPath as fileURLToPath65, pathToFileURL as pathToFileURL58 } from "node:url";
36059
36228
 
36060
36229
  // src/scripts/_lib/runtime_journal.ts
36061
36230
  import * as crypto14 from "node:crypto";
36062
- import * as fs97 from "node:fs";
36063
- import * as path99 from "node:path";
36064
-
36065
- // src/scripts/_lib/outcome_vocabularies.ts
36066
- var RUN_TERMINAL_STATES = [
36067
- "success",
36068
- "clean-no-op",
36069
- "blocked",
36070
- "approval-required",
36071
- "exhausted",
36072
- "stagnated"
36073
- ];
36074
-
36075
- // src/scripts/_lib/runtime_journal.ts
36231
+ import * as fs98 from "node:fs";
36232
+ import * as path100 from "node:path";
36076
36233
  var JOURNAL_SCHEMA_VERSION = 3;
36077
36234
  var BOUNDARY_RULE_VERSION = 1;
36078
36235
  var RETENTION_TTL_DAYS = 30;
@@ -36163,7 +36320,7 @@ function requireId(name, id, optional) {
36163
36320
  }
36164
36321
  var JOURNAL_DIR_NAME = "agent-journal";
36165
36322
  var JOURNAL_FILE_NAME = "journal.sqlite";
36166
- var JOURNAL_FALLBACK_REL = path99.join("agents", "runtime", "state", JOURNAL_FILE_NAME);
36323
+ var JOURNAL_FALLBACK_REL = path100.join("agents", "runtime", "state", JOURNAL_FILE_NAME);
36167
36324
  function digest(domain, input) {
36168
36325
  return crypto14.createHash("sha256").update(`${domain}\0${input}`).digest("hex").slice(0, 12);
36169
36326
  }
@@ -36174,20 +36331,20 @@ function resolveJournal(root) {
36174
36331
  if (common !== null) {
36175
36332
  const own = git_dir(root) ?? common;
36176
36333
  return {
36177
- path: path99.join(common, JOURNAL_DIR_NAME, JOURNAL_FILE_NAME),
36334
+ path: path100.join(common, JOURNAL_DIR_NAME, JOURNAL_FILE_NAME),
36178
36335
  scope: "repo-shared",
36179
36336
  reason: "common git dir resolved \u2014 every worktree of this repo writes one database",
36180
36337
  repository_id: digest(REPO_DOMAIN, common),
36181
36338
  worktree_id: digest(WORKTREE_DOMAIN, own)
36182
36339
  };
36183
36340
  }
36184
- let real = path99.resolve(root);
36341
+ let real = path100.resolve(root);
36185
36342
  try {
36186
- real = fs97.realpathSync(real);
36343
+ real = fs98.realpathSync(real);
36187
36344
  } catch {
36188
36345
  }
36189
36346
  return {
36190
- path: path99.join(real, JOURNAL_FALLBACK_REL),
36347
+ path: path100.join(real, JOURNAL_FALLBACK_REL),
36191
36348
  scope: "worktree-local",
36192
36349
  reason: "no common git dir \u2014 not inside a git repository; falling back to the tree-local path",
36193
36350
  repository_id: digest(REPO_DOMAIN, real),
@@ -36273,7 +36430,7 @@ function ensureWal(db) {
36273
36430
  function discard(dbPath) {
36274
36431
  for (const p of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
36275
36432
  try {
36276
- fs97.rmSync(p, { force: true });
36433
+ fs98.rmSync(p, { force: true });
36277
36434
  } catch {
36278
36435
  }
36279
36436
  }
@@ -36285,9 +36442,9 @@ function openJournal(root) {
36285
36442
  );
36286
36443
  }
36287
36444
  const location = resolveJournal(root);
36288
- fs97.mkdirSync(path99.dirname(location.path), { recursive: true });
36445
+ fs98.mkdirSync(path100.dirname(location.path), { recursive: true });
36289
36446
  const { DatabaseSync } = loadSqliteSync("runtime_journal");
36290
- if (fs97.existsSync(location.path)) {
36447
+ if (fs98.existsSync(location.path)) {
36291
36448
  let drift = false;
36292
36449
  let probe = null;
36293
36450
  try {
@@ -36369,7 +36526,7 @@ function recordEvent(h, input) {
36369
36526
  const explicit = requireId("episode_id", input.episode_id, true);
36370
36527
  if (input.terminal_state !== null && input.terminal_state !== void 0 && !TERMINAL_STATES.includes(input.terminal_state)) {
36371
36528
  throw new JournalContractError(
36372
- `terminal_state ${JSON.stringify(input.terminal_state)} is not one of the six.`
36529
+ `terminal_state ${JSON.stringify(input.terminal_state)} is not in the run vocabulary.`
36373
36530
  );
36374
36531
  }
36375
36532
  if (input.consumption !== null && input.consumption !== void 0 && !CONSUMPTION_STATES.includes(input.consumption)) {
@@ -36530,10 +36687,10 @@ function _isCliEntry51() {
36530
36687
  return false;
36531
36688
  }
36532
36689
  if (process.argv[1] === void 0) return false;
36533
- const argvUrl = pathToFileURL58(path100.resolve(process.argv[1])).href;
36690
+ const argvUrl = pathToFileURL58(path101.resolve(process.argv[1])).href;
36534
36691
  if (import.meta.url === argvUrl) return true;
36535
36692
  try {
36536
- return fs98.realpathSync(fileURLToPath65(import.meta.url)) === fs98.realpathSync(path100.resolve(process.argv[1]));
36693
+ return fs99.realpathSync(fileURLToPath65(import.meta.url)) === fs99.realpathSync(path101.resolve(process.argv[1]));
36537
36694
  } catch {
36538
36695
  return false;
36539
36696
  }
@@ -36696,8 +36853,8 @@ function _py_json_dumps2(value, indent) {
36696
36853
 
36697
36854
  // src/scripts/_lib/collector_denominator.ts
36698
36855
  import crypto15 from "node:crypto";
36699
- import fs100 from "node:fs";
36700
- import path102 from "node:path";
36856
+ import fs101 from "node:fs";
36857
+ import path103 from "node:path";
36701
36858
 
36702
36859
  // src/scripts/_lib/collector_record.ts
36703
36860
  var COLLECTOR_EVENTS = [
@@ -36774,30 +36931,30 @@ var FIELD_PURPOSE = {
36774
36931
  var ALLOWED_FIELDS = new Set(Object.keys(FIELD_PURPOSE));
36775
36932
 
36776
36933
  // src/scripts/_lib/collector_store.ts
36777
- import * as fs99 from "node:fs";
36934
+ import * as fs100 from "node:fs";
36778
36935
  import * as os12 from "node:os";
36779
- import * as path101 from "node:path";
36936
+ import * as path102 from "node:path";
36780
36937
  var COLLECTOR_DIR_NAME = "agent-collector";
36781
36938
  var COLLECTOR_FILE_NAME = "collector.sqlite";
36782
36939
  var OPT_OUT_MARKER_NAME = "OPT-OUT";
36783
36940
  var MIGRATION_MARKER_NAME = "MIGRATION-IN-FLIGHT";
36784
36941
  var QUARANTINE_DIR_NAME = "quarantine";
36785
36942
  function defaultUserRoot() {
36786
- return path101.join(os12.homedir(), ".event4u", "agent-config");
36943
+ return path102.join(os12.homedir(), ".event4u", "agent-config");
36787
36944
  }
36788
36945
  function resolveCollectorStore(userRoot = defaultUserRoot()) {
36789
- const dir = path101.join(userRoot, COLLECTOR_DIR_NAME);
36946
+ const dir = path102.join(userRoot, COLLECTOR_DIR_NAME);
36790
36947
  return {
36791
36948
  userRoot,
36792
36949
  root: dir,
36793
- path: path101.join(dir, COLLECTOR_FILE_NAME),
36794
- optOutMarker: path101.join(dir, OPT_OUT_MARKER_NAME),
36795
- migrationMarker: path101.join(dir, MIGRATION_MARKER_NAME),
36796
- quarantineDir: path101.join(dir, QUARANTINE_DIR_NAME)
36950
+ path: path102.join(dir, COLLECTOR_FILE_NAME),
36951
+ optOutMarker: path102.join(dir, OPT_OUT_MARKER_NAME),
36952
+ migrationMarker: path102.join(dir, MIGRATION_MARKER_NAME),
36953
+ quarantineDir: path102.join(dir, QUARANTINE_DIR_NAME)
36797
36954
  };
36798
36955
  }
36799
36956
  function isOptedOut(userRoot = defaultUserRoot()) {
36800
- return fs99.existsSync(resolveCollectorStore(userRoot).optOutMarker);
36957
+ return fs100.existsSync(resolveCollectorStore(userRoot).optOutMarker);
36801
36958
  }
36802
36959
  var MIGRATIONS = Object.freeze({
36803
36960
  // 0 → 1. No DDL: `user_version` 0 is the default SQLite assigns, and a
@@ -36814,24 +36971,24 @@ var SPOOL_DIR_NAME = "spool";
36814
36971
  var SPOOL_PENDING_NAME = "pending.jsonl";
36815
36972
  var ENABLED_MARKER_NAME = "ENABLED";
36816
36973
  function denominatorPath(userRoot) {
36817
- return path102.join(resolveCollectorStore(userRoot).root, DENOMINATOR_FILE_NAME);
36974
+ return path103.join(resolveCollectorStore(userRoot).root, DENOMINATOR_FILE_NAME);
36818
36975
  }
36819
36976
  function spoolDir(userRoot) {
36820
- return path102.join(resolveCollectorStore(userRoot).root, SPOOL_DIR_NAME);
36977
+ return path103.join(resolveCollectorStore(userRoot).root, SPOOL_DIR_NAME);
36821
36978
  }
36822
36979
  function spoolPendingPath(userRoot) {
36823
- return path102.join(spoolDir(userRoot), SPOOL_PENDING_NAME);
36980
+ return path103.join(spoolDir(userRoot), SPOOL_PENDING_NAME);
36824
36981
  }
36825
36982
  function enabledMarkerPath(userRoot) {
36826
- return path102.join(resolveCollectorStore(userRoot).root, ENABLED_MARKER_NAME);
36983
+ return path103.join(resolveCollectorStore(userRoot).root, ENABLED_MARKER_NAME);
36827
36984
  }
36828
36985
  function isCollectorEnabled(userRoot) {
36829
36986
  if (isOptedOut(userRoot)) return false;
36830
- if (fs100.existsSync(killSwitchPathLocal(userRoot))) return false;
36831
- return fs100.existsSync(enabledMarkerPath(userRoot));
36987
+ if (fs101.existsSync(killSwitchPathLocal(userRoot))) return false;
36988
+ return fs101.existsSync(enabledMarkerPath(userRoot));
36832
36989
  }
36833
36990
  function killSwitchPathLocal(userRoot) {
36834
- return path102.join(resolveCollectorStore(userRoot).root, "STOP");
36991
+ return path103.join(resolveCollectorStore(userRoot).root, "STOP");
36835
36992
  }
36836
36993
  function utcDate(at = Date.now()) {
36837
36994
  return new Date(at).toISOString().slice(0, 10);
@@ -36843,8 +37000,8 @@ function recordOpportunity(event, platform, userRoot, at = Date.now(), opts = {}
36843
37000
  if (!COLLECTOR_EVENTS.includes(event)) return false;
36844
37001
  if (!COLLECTOR_PLATFORMS.includes(platform)) return false;
36845
37002
  const target = denominatorPath(userRoot);
36846
- fs100.mkdirSync(path102.dirname(target), { recursive: true });
36847
- fs100.appendFileSync(target, `${utcDate(at)} ${event} ${platform}
37003
+ fs101.mkdirSync(path103.dirname(target), { recursive: true });
37004
+ fs101.appendFileSync(target, `${utcDate(at)} ${event} ${platform}
36848
37005
  `);
36849
37006
  return true;
36850
37007
  } catch {
@@ -36858,19 +37015,19 @@ var MACHINE_ID_NAME = "machine-id";
36858
37015
  var EPISODE_DIR_NAME = "episodes";
36859
37016
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
36860
37017
  function machineIdPath(userRoot) {
36861
- return path102.join(resolveCollectorStore(userRoot).root, MACHINE_ID_NAME);
37018
+ return path103.join(resolveCollectorStore(userRoot).root, MACHINE_ID_NAME);
36862
37019
  }
36863
37020
  function machineId(userRoot) {
36864
37021
  const target = machineIdPath(userRoot);
36865
37022
  try {
36866
- const existing = fs100.readFileSync(target, "utf8").trim();
37023
+ const existing = fs101.readFileSync(target, "utf8").trim();
36867
37024
  if (UUID_RE.test(existing)) return existing;
36868
37025
  } catch {
36869
37026
  }
36870
37027
  try {
36871
37028
  const minted = crypto15.randomUUID();
36872
- fs100.mkdirSync(path102.dirname(target), { recursive: true });
36873
- fs100.writeFileSync(target, `${minted}
37029
+ fs101.mkdirSync(path103.dirname(target), { recursive: true });
37030
+ fs101.writeFileSync(target, `${minted}
36874
37031
  `);
36875
37032
  return minted;
36876
37033
  } catch {
@@ -36894,17 +37051,17 @@ function episodeId(env = process.env) {
36894
37051
  ].join("-");
36895
37052
  }
36896
37053
  function nextSequence(episode, userRoot) {
36897
- const dir = path102.join(resolveCollectorStore(userRoot).root, EPISODE_DIR_NAME);
36898
- const target = path102.join(dir, `${episode}.seq`);
37054
+ const dir = path103.join(resolveCollectorStore(userRoot).root, EPISODE_DIR_NAME);
37055
+ const target = path103.join(dir, `${episode}.seq`);
36899
37056
  try {
36900
- fs100.mkdirSync(dir, { recursive: true });
37057
+ fs101.mkdirSync(dir, { recursive: true });
36901
37058
  let current = 0;
36902
37059
  try {
36903
- const raw = Number.parseInt(fs100.readFileSync(target, "utf8").trim(), 10);
37060
+ const raw = Number.parseInt(fs101.readFileSync(target, "utf8").trim(), 10);
36904
37061
  if (Number.isInteger(raw) && raw >= 0) current = raw + 1;
36905
37062
  } catch {
36906
37063
  }
36907
- fs100.writeFileSync(target, `${current}
37064
+ fs101.writeFileSync(target, `${current}
36908
37065
  `);
36909
37066
  return current;
36910
37067
  } catch {
@@ -36943,12 +37100,12 @@ function spoolRecord(record, userRoot) {
36943
37100
  try {
36944
37101
  if (!isCollectorEnabled(userRoot)) return false;
36945
37102
  const target = spoolPendingPath(userRoot);
36946
- fs100.mkdirSync(path102.dirname(target), { recursive: true });
37103
+ fs101.mkdirSync(path103.dirname(target), { recursive: true });
36947
37104
  try {
36948
- if (fs100.statSync(target).size >= SPOOL_MAX_BYTES) return false;
37105
+ if (fs101.statSync(target).size >= SPOOL_MAX_BYTES) return false;
36949
37106
  } catch {
36950
37107
  }
36951
- fs100.appendFileSync(target, `${JSON.stringify(record)}
37108
+ fs101.appendFileSync(target, `${JSON.stringify(record)}
36952
37109
  `);
36953
37110
  return true;
36954
37111
  } catch {
@@ -36958,11 +37115,11 @@ function spoolRecord(record, userRoot) {
36958
37115
 
36959
37116
  // src/scripts/hooks/dispatch_hook.ts
36960
37117
  var _IN_BUNDLE = true;
36961
- var REPO_ROOT = path103.resolve(
36962
- path103.dirname(fileURLToPath66(import.meta.url)),
37118
+ var REPO_ROOT = path104.resolve(
37119
+ path104.dirname(fileURLToPath66(import.meta.url)),
36963
37120
  ..._IN_BUNDLE ? ["..", ".."] : ["..", "..", ".."]
36964
37121
  );
36965
- var MANIFEST_PATH = path103.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
37122
+ var MANIFEST_PATH = path104.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
36966
37123
  var EXIT_ALLOW35 = 0;
36967
37124
  var EXIT_BLOCK6 = 1;
36968
37125
  var EXIT_WARN18 = 2;
@@ -37024,11 +37181,11 @@ function _manifest_fingerprint(text) {
37024
37181
  return `${h.toString(16)}:${String(text.length)}`;
37025
37182
  }
37026
37183
  function _load_yaml3(p) {
37027
- const text = fs101.readFileSync(p, "utf-8");
37184
+ const text = fs102.readFileSync(p, "utf-8");
37028
37185
  const compiled = p.replace(/\.ya?ml$/u, ".json");
37029
37186
  if (compiled !== p) {
37030
37187
  try {
37031
- const raw = JSON.parse(fs101.readFileSync(compiled, "utf-8"));
37188
+ const raw = JSON.parse(fs102.readFileSync(compiled, "utf-8"));
37032
37189
  if (_isObject17(raw) && raw["fingerprint"] === _manifest_fingerprint(text) && _isObject17(raw["manifest"])) {
37033
37190
  return raw["manifest"];
37034
37191
  }
@@ -37134,7 +37291,7 @@ function _maybe_capture_payload(args, payload_text) {
37134
37291
  }
37135
37292
  try {
37136
37293
  const target = _expanduser3(capture_dir);
37137
- fs101.mkdirSync(target, { recursive: true });
37294
+ fs102.mkdirSync(target, { recursive: true });
37138
37295
  let payload;
37139
37296
  try {
37140
37297
  payload = payload_text.trim() ? JSON.parse(payload_text) : {};
@@ -37151,8 +37308,8 @@ function _maybe_capture_payload(args, payload_text) {
37151
37308
  const ts = Date.now();
37152
37309
  const native = (args.native_event || args.event).replace(/\//g, "_");
37153
37310
  const fname = `${args.platform}__${native}__${ts}__${process.pid}.json`;
37154
- fs101.writeFileSync(
37155
- path103.join(target, fname),
37311
+ fs102.writeFileSync(
37312
+ path104.join(target, fname),
37156
37313
  _py_json_dumps2(record, 2) + "\n",
37157
37314
  { encoding: "utf-8" }
37158
37315
  );
@@ -37163,7 +37320,7 @@ function _maybe_capture_payload(args, payload_text) {
37163
37320
  function _expanduser3(p) {
37164
37321
  if (p === "~" || p.startsWith("~/")) {
37165
37322
  const home = process.env["HOME"] || process.env["USERPROFILE"] || "";
37166
- return path103.join(home, p.slice(1));
37323
+ return path104.join(home, p.slice(1));
37167
37324
  }
37168
37325
  return p;
37169
37326
  }
@@ -37195,25 +37352,25 @@ function _resolve_tsx_invocation2(scriptPath, scriptArgs) {
37195
37352
  const walkUp = (start) => {
37196
37353
  let dir = start;
37197
37354
  for (; ; ) {
37198
- const candidate = path103.join(dir, "node_modules", ".bin", binName);
37355
+ const candidate = path104.join(dir, "node_modules", ".bin", binName);
37199
37356
  if (_isFile8(candidate)) {
37200
37357
  return candidate;
37201
37358
  }
37202
- const parent = path103.dirname(dir);
37359
+ const parent = path104.dirname(dir);
37203
37360
  if (parent === dir) {
37204
37361
  return null;
37205
37362
  }
37206
37363
  dir = parent;
37207
37364
  }
37208
37365
  };
37209
- const tsx = walkUp(path103.dirname(scriptPath)) ?? walkUp(path103.dirname(fileURLToPath66(import.meta.url)));
37366
+ const tsx = walkUp(path104.dirname(scriptPath)) ?? walkUp(path104.dirname(fileURLToPath66(import.meta.url)));
37210
37367
  if (tsx !== null) {
37211
37368
  return { command: tsx, args: [scriptPath, ...scriptArgs] };
37212
37369
  }
37213
37370
  return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
37214
37371
  }
37215
37372
  function _run_concern_inproc(main_fn, concern, envelope) {
37216
- const scriptAbs = path103.join(REPO_ROOT, String(concern["script"]));
37373
+ const scriptAbs = path104.join(REPO_ROOT, String(concern["script"]));
37217
37374
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
37218
37375
  argsList.push("--platform", String(envelope["platform"] || "generic"));
37219
37376
  const workspace = String(envelope["workspace_root"] || process.cwd());
@@ -37290,7 +37447,7 @@ function _run_concern(concern, envelope) {
37290
37447
  return _run_concern_inproc(inproc, concern, envelope);
37291
37448
  }
37292
37449
  }
37293
- const script = path103.join(REPO_ROOT, String(concern["script"]));
37450
+ const script = path104.join(REPO_ROOT, String(concern["script"]));
37294
37451
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
37295
37452
  const cmd = [script, ...argsList];
37296
37453
  cmd.push("--platform", String(envelope["platform"] || "generic"));
@@ -37347,7 +37504,7 @@ function _run_concern(concern, envelope) {
37347
37504
  }
37348
37505
  function _isFile8(p) {
37349
37506
  try {
37350
- return fs101.statSync(p).isFile();
37507
+ return fs102.statSync(p).isFile();
37351
37508
  } catch {
37352
37509
  return false;
37353
37510
  }
@@ -37369,10 +37526,10 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
37369
37526
  return;
37370
37527
  }
37371
37528
  const workspace = String(envelope["workspace_root"] || process.cwd());
37372
- const state_root = path103.join(workspace, "agents", "runtime", "state");
37529
+ const state_root = path104.join(workspace, "agents", "runtime", "state");
37373
37530
  const fb_dir = feedback_dir(state_root, session_id);
37374
37531
  try {
37375
- fs101.mkdirSync(fb_dir, { recursive: true });
37532
+ fs102.mkdirSync(fb_dir, { recursive: true });
37376
37533
  } catch (exc) {
37377
37534
  const msg = exc instanceof Error ? exc.message : String(exc);
37378
37535
  process.stderr.write(`dispatch_hook: feedback dir unavailable: ${msg}
@@ -37380,7 +37537,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
37380
37537
  return;
37381
37538
  }
37382
37539
  for (const entry of entries) {
37383
- const target = path103.join(fb_dir, `${entry["concern"]}.json`);
37540
+ const target = path104.join(fb_dir, `${entry["concern"]}.json`);
37384
37541
  try {
37385
37542
  atomic_write_json(target, entry);
37386
37543
  } catch (exc) {
@@ -37429,7 +37586,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
37429
37586
  };
37430
37587
  try {
37431
37588
  const invocation = `${String(process.pid)}-${process.hrtime.bigint().toString()}`;
37432
- update_json_under_lock(path103.join(fb_dir, "summary.json"), (loaded) => {
37589
+ update_json_under_lock(path104.join(fb_dir, "summary.json"), (loaded) => {
37433
37590
  const priorRaw = loaded["invocations"];
37434
37591
  const prior = Array.isArray(priorRaw) ? priorRaw : [];
37435
37592
  const next = [...prior, { invocation, ...summary }];
@@ -37456,8 +37613,8 @@ function _record_rule_trips(envelope, entries) {
37456
37613
  if (tripped.length === 0) return;
37457
37614
  try {
37458
37615
  const workspace = String(envelope["workspace_root"] || process.cwd());
37459
- const state_dir = path103.join(workspace, "agents", "runtime", "state");
37460
- const target = path103.join(state_dir, "rule-trips.json");
37616
+ const state_dir = path104.join(workspace, "agents", "runtime", "state");
37617
+ const target = path104.join(state_dir, "rule-trips.json");
37461
37618
  const today = _now_iso3().slice(0, 10);
37462
37619
  update_json_under_lock(target, (loaded) => {
37463
37620
  const doc = { schema_version: 1, concerns: {}, ...loaded };
@@ -37599,7 +37756,7 @@ function main65(argv) {
37599
37756
  recordOpportunity(args.event, args.platform);
37600
37757
  recordCapture(args.event, args.platform);
37601
37758
  const manifest_path = args.manifest;
37602
- if (!fs101.existsSync(manifest_path)) {
37759
+ if (!fs102.existsSync(manifest_path)) {
37603
37760
  process.stderr.write(`dispatch_hook: manifest missing at ${manifest_path}
37604
37761
  `);
37605
37762
  return EXIT_ALLOW35;
@@ -37766,7 +37923,7 @@ function main65(argv) {
37766
37923
  }
37767
37924
  function _isDir4(p) {
37768
37925
  try {
37769
- return fs101.statSync(p).isDirectory();
37926
+ return fs102.statSync(p).isDirectory();
37770
37927
  } catch {
37771
37928
  return false;
37772
37929
  }
@@ -37783,13 +37940,13 @@ function _isCliEntry52() {
37783
37940
  if (process.argv[1] === void 0) {
37784
37941
  return false;
37785
37942
  }
37786
- const argvUrl = pathToFileURL59(path103.resolve(process.argv[1])).href;
37943
+ const argvUrl = pathToFileURL59(path104.resolve(process.argv[1])).href;
37787
37944
  if (import.meta.url === argvUrl) {
37788
37945
  return true;
37789
37946
  }
37790
37947
  try {
37791
- const here = fs101.realpathSync(fileURLToPath66(import.meta.url));
37792
- const argv = fs101.realpathSync(path103.resolve(process.argv[1]));
37948
+ const here = fs102.realpathSync(fileURLToPath66(import.meta.url));
37949
+ const argv = fs102.realpathSync(path104.resolve(process.argv[1]));
37793
37950
  return here === argv;
37794
37951
  } catch {
37795
37952
  return false;
@@ -37802,7 +37959,7 @@ if (isCliEntry14) {
37802
37959
 
37803
37960
  // src/scripts/hooks/dispatch_entry.ts
37804
37961
  var _selfPath = fileURLToPath67(import.meta.url);
37805
- var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path104.resolve(process.argv[1]) === path104.resolve(_selfPath);
37962
+ var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path105.resolve(process.argv[1]) === path105.resolve(_selfPath);
37806
37963
  if (_invokedDirectly2) {
37807
37964
  process.exitCode = main65(process.argv.slice(2));
37808
37965
  }