@event4u/agent-config 15.0.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) 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 +142 -348
  5. package/dist/agent-src/commands/roadmap/create.md +3 -2
  6. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +50 -0
  7. package/dist/agent-src/rules/user-interaction.md +31 -30
  8. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +9 -0
  9. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  10. package/dist/cli-delegate/{chunk-HZ52BRGG.js → chunk-H32DGUJH.js} +14 -89
  11. package/dist/cli-delegate/chunk-NUHLI2RX.js +80 -0
  12. package/dist/cli-delegate/{chunk-TYSY33MD.js → chunk-QJWAUMJW.js} +12 -2
  13. package/dist/cli-delegate/{chunk-2KKXJW25.js → chunk-S3VFXMTM.js} +1 -1
  14. package/dist/cli-delegate/cmd_conformance.js +831 -272
  15. package/dist/cli-delegate/cmd_explain.js +4 -2
  16. package/dist/cli-delegate/cmd_handoff.js +2 -2
  17. package/dist/cli-delegate/cmd_packs_active.js +2 -1
  18. package/dist/cli-delegate/cmd_session_recycle.js +2 -2
  19. package/dist/cli-delegate/cmd_settings_set.js +13 -0
  20. package/dist/discovery/deprecation-report.md +1 -1
  21. package/dist/discovery/discovery-manifest.json +5 -5
  22. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  23. package/dist/discovery/discovery-manifest.summary.md +1 -1
  24. package/dist/discovery/dormancy-report.md +1 -1
  25. package/dist/discovery/orphan-report.md +1 -1
  26. package/dist/discovery/packs.json +2 -2
  27. package/dist/discovery/trust-report.md +1 -1
  28. package/dist/discovery/workspaces.json +2 -2
  29. package/dist/hooks/dispatch.js +1274 -571
  30. package/dist/install/install.mjs +1 -0
  31. package/dist/mcp/registry-manifest.json +2 -2
  32. package/dist/mcp/server.json +2 -2
  33. package/dist/mcp/server.mjs +1218 -632
  34. package/dist/scripts/_lib/installed_lock.js +1 -1
  35. package/dist/server/io/yamlIO.js +50 -0
  36. package/package.json +1 -1
  37. package/src/config/continuity-surface.json +7 -0
  38. package/src/config/gate-violation-baselines.json +3 -3
  39. package/src/config/host-injection-effect.json +1 -1
  40. package/src/config/preamble-payload-budget.json +12 -7
  41. package/src/config/preamble-payload-exceptions.json +28 -0
  42. package/src/scripts/_dispatch.bash +3 -1
  43. package/src/scripts/_lib/base_ref_payload.ts +315 -0
  44. package/src/scripts/_lib/dropped_decision.ts +142 -0
  45. package/src/scripts/_lib/installed_lock.ts +1 -1
  46. package/src/scripts/_lib/measured_payload_ceiling.ts +424 -0
  47. package/src/scripts/_lib/payload_catalogue_completeness.ts +211 -0
  48. package/src/scripts/_lib/release_findings_ingest.ts +324 -0
  49. package/src/scripts/_lib/release_tag_dispatch.ts +63 -0
  50. package/src/scripts/_lib/review_baseline.ts +254 -0
  51. package/src/scripts/_lib/review_skipped_record.ts +61 -1
  52. package/src/scripts/_lib/standing_bound_ratchet.ts +216 -103
  53. package/src/scripts/_lib/turn_end_refusals.ts +51 -4
  54. package/src/scripts/check_beta_review_markers.ts +35 -4
  55. package/src/scripts/check_finding_dispositions.ts +167 -16
  56. package/src/scripts/check_held_object_arrivals.ts +381 -0
  57. package/src/scripts/check_preamble_payload_budget.ts +399 -122
  58. package/src/scripts/check_release_published.ts +1 -1
  59. package/src/scripts/check_reply_consistency.ts +86 -17
  60. package/src/scripts/hook_manifest.json +1 -1
  61. package/src/scripts/hook_manifest.yaml +39 -3
  62. package/src/scripts/hooks/block_kernel_rule_writes.ts +12 -2
  63. package/src/scripts/hooks/concern_registry.ts +2 -0
  64. package/src/scripts/hooks/end_review_nudge_hook.ts +101 -21
  65. package/src/scripts/hooks/review_baseline_hook.ts +130 -0
  66. package/src/scripts/hooks/turn_end_gate_hook.ts +232 -14
  67. package/src/scripts/hooks_doctor.ts +4 -1
  68. package/src/scripts/install.ts +1 -1
  69. package/src/scripts/interruption_report.ts +8 -2
  70. package/src/scripts/janitor.ts +8 -1
  71. package/src/scripts/measure_turn_end_gate.ts +302 -5
  72. package/src/scripts/release.ts +52 -64
  73. package/src/scripts/release_drill.ts +193 -14
  74. package/src/scripts/release_env.ts +1 -1
  75. package/src/scripts/release_publication.ts +1 -1
  76. package/src/scripts/report_held_object_arrivals.ts +456 -0
  77. package/src/scripts/sync_agent_settings.ts +140 -18
  78. package/src/server/io/yamlIO.ts +48 -0
@@ -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, path111) {
116
- const ctrl = callVisitor(key, node, visitor, path111);
115
+ function visit_(key, node, visitor, path116) {
116
+ const ctrl = callVisitor(key, node, visitor, path116);
117
117
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
118
- replaceNode(key, path111, ctrl);
119
- return visit_(key, ctrl, visitor, path111);
118
+ replaceNode(key, path116, ctrl);
119
+ return visit_(key, ctrl, visitor, path116);
120
120
  }
121
121
  if (typeof ctrl !== "symbol") {
122
122
  if (identity.isCollection(node)) {
123
- path111 = Object.freeze(path111.concat(node));
123
+ path116 = Object.freeze(path116.concat(node));
124
124
  for (let i = 0; i < node.items.length; ++i) {
125
- const ci = visit_(i, node.items[i], visitor, path111);
125
+ const ci = visit_(i, node.items[i], visitor, path116);
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
- path111 = Object.freeze(path111.concat(node));
137
- const ck = visit_("key", node.key, visitor, path111);
136
+ path116 = Object.freeze(path116.concat(node));
137
+ const ck = visit_("key", node.key, visitor, path116);
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, path111);
142
+ const cv = visit_("value", node.value, visitor, path116);
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, path111) {
164
- const ctrl = await callVisitor(key, node, visitor, path111);
163
+ async function visitAsync_(key, node, visitor, path116) {
164
+ const ctrl = await callVisitor(key, node, visitor, path116);
165
165
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
166
- replaceNode(key, path111, ctrl);
167
- return visitAsync_(key, ctrl, visitor, path111);
166
+ replaceNode(key, path116, ctrl);
167
+ return visitAsync_(key, ctrl, visitor, path116);
168
168
  }
169
169
  if (typeof ctrl !== "symbol") {
170
170
  if (identity.isCollection(node)) {
171
- path111 = Object.freeze(path111.concat(node));
171
+ path116 = Object.freeze(path116.concat(node));
172
172
  for (let i = 0; i < node.items.length; ++i) {
173
- const ci = await visitAsync_(i, node.items[i], visitor, path111);
173
+ const ci = await visitAsync_(i, node.items[i], visitor, path116);
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
- path111 = Object.freeze(path111.concat(node));
185
- const ck = await visitAsync_("key", node.key, visitor, path111);
184
+ path116 = Object.freeze(path116.concat(node));
185
+ const ck = await visitAsync_("key", node.key, visitor, path116);
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, path111);
190
+ const cv = await visitAsync_("value", node.value, visitor, path116);
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, path111) {
217
+ function callVisitor(key, node, visitor, path116) {
218
218
  if (typeof visitor === "function")
219
- return visitor(key, node, path111);
219
+ return visitor(key, node, path116);
220
220
  if (identity.isMap(node))
221
- return visitor.Map?.(key, node, path111);
221
+ return visitor.Map?.(key, node, path116);
222
222
  if (identity.isSeq(node))
223
- return visitor.Seq?.(key, node, path111);
223
+ return visitor.Seq?.(key, node, path116);
224
224
  if (identity.isPair(node))
225
- return visitor.Pair?.(key, node, path111);
225
+ return visitor.Pair?.(key, node, path116);
226
226
  if (identity.isScalar(node))
227
- return visitor.Scalar?.(key, node, path111);
227
+ return visitor.Scalar?.(key, node, path116);
228
228
  if (identity.isAlias(node))
229
- return visitor.Alias?.(key, node, path111);
229
+ return visitor.Alias?.(key, node, path116);
230
230
  return void 0;
231
231
  }
232
- function replaceNode(key, path111, node) {
233
- const parent = path111[path111.length - 1];
232
+ function replaceNode(key, path116, node) {
233
+ const parent = path116[path116.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, path111, value) {
843
+ function collectionFromPath(schema, path116, value) {
844
844
  let v = value;
845
- for (let i = path111.length - 1; i >= 0; --i) {
846
- const k = path111[i];
845
+ for (let i = path116.length - 1; i >= 0; --i) {
846
+ const k = path116[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 = (path111) => path111 == null || typeof path111 === "object" && !!path111[Symbol.iterator]().next().done;
865
+ var isEmptyPath = (path116) => path116 == null || typeof path116 === "object" && !!path116[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(path111, value) {
896
- if (isEmptyPath(path111))
895
+ addIn(path116, value) {
896
+ if (isEmptyPath(path116))
897
897
  this.add(value);
898
898
  else {
899
- const [key, ...rest] = path111;
899
+ const [key, ...rest] = path116;
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(path111) {
914
- const [key, ...rest] = path111;
913
+ deleteIn(path116) {
914
+ const [key, ...rest] = path116;
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(path111, keepScalar) {
929
- const [key, ...rest] = path111;
928
+ getIn(path116, keepScalar) {
929
+ const [key, ...rest] = path116;
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(path111) {
948
- const [key, ...rest] = path111;
947
+ hasIn(path116) {
948
+ const [key, ...rest] = path116;
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(path111, value) {
959
- const [key, ...rest] = path111;
958
+ setIn(path116, value) {
959
+ const [key, ...rest] = path116;
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(path111, value) {
3474
+ addIn(path116, value) {
3475
3475
  if (assertCollection(this.contents))
3476
- this.contents.addIn(path111, value);
3476
+ this.contents.addIn(path116, 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(path111) {
3552
- if (Collection.isEmptyPath(path111)) {
3551
+ deleteIn(path116) {
3552
+ if (Collection.isEmptyPath(path116)) {
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(path111) : false;
3558
+ return assertCollection(this.contents) ? this.contents.deleteIn(path116) : 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(path111, keepScalar) {
3574
- if (Collection.isEmptyPath(path111))
3573
+ getIn(path116, keepScalar) {
3574
+ if (Collection.isEmptyPath(path116))
3575
3575
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3576
- return identity.isCollection(this.contents) ? this.contents.getIn(path111, keepScalar) : void 0;
3576
+ return identity.isCollection(this.contents) ? this.contents.getIn(path116, 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(path111) {
3588
- if (Collection.isEmptyPath(path111))
3587
+ hasIn(path116) {
3588
+ if (Collection.isEmptyPath(path116))
3589
3589
  return this.contents !== void 0;
3590
- return identity.isCollection(this.contents) ? this.contents.hasIn(path111) : false;
3590
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path116) : 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(path111, value) {
3608
- if (Collection.isEmptyPath(path111)) {
3607
+ setIn(path116, value) {
3608
+ if (Collection.isEmptyPath(path116)) {
3609
3609
  this.contents = value;
3610
3610
  } else if (this.contents == null) {
3611
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path111), value);
3611
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path116), value);
3612
3612
  } else if (assertCollection(this.contents)) {
3613
- this.contents.setIn(path111, value);
3613
+ this.contents.setIn(path116, value);
3614
3614
  }
3615
3615
  }
3616
3616
  /**
@@ -3996,10 +3996,10 @@ var require_resolve_block_map = __commonJS({
3996
3996
  let offset = bm.offset;
3997
3997
  let commentEnd = null;
3998
3998
  for (const collItem of bm.items) {
3999
- const { start, key, sep: sep9, value } = collItem;
3999
+ const { start, key, sep: sep12, value } = collItem;
4000
4000
  const keyProps = resolveProps.resolveProps(start, {
4001
4001
  indicator: "explicit-key-ind",
4002
- next: key ?? sep9?.[0],
4002
+ next: key ?? sep12?.[0],
4003
4003
  offset,
4004
4004
  onError,
4005
4005
  parentIndent: bm.indent,
@@ -4013,7 +4013,7 @@ var require_resolve_block_map = __commonJS({
4013
4013
  else if ("indent" in key && key.indent !== bm.indent)
4014
4014
  onError(offset, "BAD_INDENT", startColMsg);
4015
4015
  }
4016
- if (!keyProps.anchor && !keyProps.tag && !sep9) {
4016
+ if (!keyProps.anchor && !keyProps.tag && !sep12) {
4017
4017
  commentEnd = keyProps.end;
4018
4018
  if (keyProps.comment) {
4019
4019
  if (map.comment)
@@ -4037,7 +4037,7 @@ var require_resolve_block_map = __commonJS({
4037
4037
  ctx.atKey = false;
4038
4038
  if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
4039
4039
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
4040
- const valueProps = resolveProps.resolveProps(sep9 ?? [], {
4040
+ const valueProps = resolveProps.resolveProps(sep12 ?? [], {
4041
4041
  indicator: "map-value-ind",
4042
4042
  next: value,
4043
4043
  offset: keyNode.range[2],
@@ -4053,7 +4053,7 @@ var require_resolve_block_map = __commonJS({
4053
4053
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
4054
4054
  onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
4055
4055
  }
4056
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep9, null, valueProps, onError);
4056
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep12, null, valueProps, onError);
4057
4057
  if (ctx.schema.compat)
4058
4058
  utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
4059
4059
  offset = valueNode.range[2];
@@ -4144,7 +4144,7 @@ var require_resolve_end = __commonJS({
4144
4144
  let comment = "";
4145
4145
  if (end) {
4146
4146
  let hasSpace = false;
4147
- let sep9 = "";
4147
+ let sep12 = "";
4148
4148
  for (const token of end) {
4149
4149
  const { source, type } = token;
4150
4150
  switch (type) {
@@ -4158,13 +4158,13 @@ var require_resolve_end = __commonJS({
4158
4158
  if (!comment)
4159
4159
  comment = cb;
4160
4160
  else
4161
- comment += sep9 + cb;
4162
- sep9 = "";
4161
+ comment += sep12 + cb;
4162
+ sep12 = "";
4163
4163
  break;
4164
4164
  }
4165
4165
  case "newline":
4166
4166
  if (comment)
4167
- sep9 += source;
4167
+ sep12 += source;
4168
4168
  hasSpace = true;
4169
4169
  break;
4170
4170
  default:
@@ -4207,18 +4207,18 @@ var require_resolve_flow_collection = __commonJS({
4207
4207
  let offset = fc.offset + fc.start.source.length;
4208
4208
  for (let i = 0; i < fc.items.length; ++i) {
4209
4209
  const collItem = fc.items[i];
4210
- const { start, key, sep: sep9, value } = collItem;
4210
+ const { start, key, sep: sep12, value } = collItem;
4211
4211
  const props = resolveProps.resolveProps(start, {
4212
4212
  flow: fcName,
4213
4213
  indicator: "explicit-key-ind",
4214
- next: key ?? sep9?.[0],
4214
+ next: key ?? sep12?.[0],
4215
4215
  offset,
4216
4216
  onError,
4217
4217
  parentIndent: fc.indent,
4218
4218
  startOnNewline: false
4219
4219
  });
4220
4220
  if (!props.found) {
4221
- if (!props.anchor && !props.tag && !sep9 && !value) {
4221
+ if (!props.anchor && !props.tag && !sep12 && !value) {
4222
4222
  if (i === 0 && props.comma)
4223
4223
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
4224
4224
  else if (i < fc.items.length - 1)
@@ -4272,8 +4272,8 @@ var require_resolve_flow_collection = __commonJS({
4272
4272
  }
4273
4273
  }
4274
4274
  }
4275
- if (!isMap && !sep9 && !props.found) {
4276
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep9, null, props, onError);
4275
+ if (!isMap && !sep12 && !props.found) {
4276
+ const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep12, null, props, onError);
4277
4277
  coll.items.push(valueNode);
4278
4278
  offset = valueNode.range[2];
4279
4279
  if (isBlock(value))
@@ -4285,7 +4285,7 @@ var require_resolve_flow_collection = __commonJS({
4285
4285
  if (isBlock(key))
4286
4286
  onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
4287
4287
  ctx.atKey = false;
4288
- const valueProps = resolveProps.resolveProps(sep9 ?? [], {
4288
+ const valueProps = resolveProps.resolveProps(sep12 ?? [], {
4289
4289
  flow: fcName,
4290
4290
  indicator: "map-value-ind",
4291
4291
  next: value,
@@ -4296,8 +4296,8 @@ var require_resolve_flow_collection = __commonJS({
4296
4296
  });
4297
4297
  if (valueProps.found) {
4298
4298
  if (!isMap && !props.found && ctx.options.strict) {
4299
- if (sep9)
4300
- for (const st of sep9) {
4299
+ if (sep12)
4300
+ for (const st of sep12) {
4301
4301
  if (st === valueProps.found)
4302
4302
  break;
4303
4303
  if (st.type === "newline") {
@@ -4314,7 +4314,7 @@ var require_resolve_flow_collection = __commonJS({
4314
4314
  else
4315
4315
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
4316
4316
  }
4317
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep9, null, valueProps, onError) : null;
4317
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep12, null, valueProps, onError) : null;
4318
4318
  if (valueNode) {
4319
4319
  if (isBlock(value))
4320
4320
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
@@ -4494,7 +4494,7 @@ var require_resolve_block_scalar = __commonJS({
4494
4494
  chompStart = i + 1;
4495
4495
  }
4496
4496
  let value = "";
4497
- let sep9 = "";
4497
+ let sep12 = "";
4498
4498
  let prevMoreIndented = false;
4499
4499
  for (let i = 0; i < contentStart; ++i)
4500
4500
  value += lines[i][0].slice(trimIndent) + "\n";
@@ -4511,24 +4511,24 @@ var require_resolve_block_scalar = __commonJS({
4511
4511
  indent = "";
4512
4512
  }
4513
4513
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
4514
- value += sep9 + indent.slice(trimIndent) + content;
4515
- sep9 = "\n";
4514
+ value += sep12 + indent.slice(trimIndent) + content;
4515
+ sep12 = "\n";
4516
4516
  } else if (indent.length > trimIndent || content[0] === " ") {
4517
- if (sep9 === " ")
4518
- sep9 = "\n";
4519
- else if (!prevMoreIndented && sep9 === "\n")
4520
- sep9 = "\n\n";
4521
- value += sep9 + indent.slice(trimIndent) + content;
4522
- sep9 = "\n";
4517
+ if (sep12 === " ")
4518
+ sep12 = "\n";
4519
+ else if (!prevMoreIndented && sep12 === "\n")
4520
+ sep12 = "\n\n";
4521
+ value += sep12 + indent.slice(trimIndent) + content;
4522
+ sep12 = "\n";
4523
4523
  prevMoreIndented = true;
4524
4524
  } else if (content === "") {
4525
- if (sep9 === "\n")
4525
+ if (sep12 === "\n")
4526
4526
  value += "\n";
4527
4527
  else
4528
- sep9 = "\n";
4528
+ sep12 = "\n";
4529
4529
  } else {
4530
- value += sep9 + content;
4531
- sep9 = " ";
4530
+ value += sep12 + content;
4531
+ sep12 = " ";
4532
4532
  prevMoreIndented = false;
4533
4533
  }
4534
4534
  }
@@ -4710,25 +4710,25 @@ var require_resolve_flow_scalar = __commonJS({
4710
4710
  if (!match)
4711
4711
  return source;
4712
4712
  let res = match[1];
4713
- let sep9 = " ";
4713
+ let sep12 = " ";
4714
4714
  let pos = first.lastIndex;
4715
4715
  line.lastIndex = pos;
4716
4716
  while (match = line.exec(source)) {
4717
4717
  if (match[1] === "") {
4718
- if (sep9 === "\n")
4719
- res += sep9;
4718
+ if (sep12 === "\n")
4719
+ res += sep12;
4720
4720
  else
4721
- sep9 = "\n";
4721
+ sep12 = "\n";
4722
4722
  } else {
4723
- res += sep9 + match[1];
4724
- sep9 = " ";
4723
+ res += sep12 + match[1];
4724
+ sep12 = " ";
4725
4725
  }
4726
4726
  pos = line.lastIndex;
4727
4727
  }
4728
4728
  const last = /[ \t]*(.*)/sy;
4729
4729
  last.lastIndex = pos;
4730
4730
  match = last.exec(source);
4731
- return res + sep9 + (match?.[1] ?? "");
4731
+ return res + sep12 + (match?.[1] ?? "");
4732
4732
  }
4733
4733
  function doubleQuotedValue(source, onError) {
4734
4734
  let res = "";
@@ -5538,14 +5538,14 @@ var require_cst_stringify = __commonJS({
5538
5538
  }
5539
5539
  }
5540
5540
  }
5541
- function stringifyItem({ start, key, sep: sep9, value }) {
5541
+ function stringifyItem({ start, key, sep: sep12, value }) {
5542
5542
  let res = "";
5543
5543
  for (const st of start)
5544
5544
  res += st.source;
5545
5545
  if (key)
5546
5546
  res += stringifyToken(key);
5547
- if (sep9)
5548
- for (const st of sep9)
5547
+ if (sep12)
5548
+ for (const st of sep12)
5549
5549
  res += st.source;
5550
5550
  if (value)
5551
5551
  res += stringifyToken(value);
@@ -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, path111) => {
5573
+ visit.itemAtPath = (cst, path116) => {
5574
5574
  let item = cst;
5575
- for (const [field, index] of path111) {
5575
+ for (const [field, index] of path116) {
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, path111) => {
5585
- const parent = visit.itemAtPath(cst, path111.slice(0, -1));
5586
- const field = path111[path111.length - 1][0];
5584
+ visit.parentCollection = (cst, path116) => {
5585
+ const parent = visit.itemAtPath(cst, path116.slice(0, -1));
5586
+ const field = path116[path116.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(path111, item, visitor) {
5593
- let ctrl = visitor(item, path111);
5592
+ function _visit(path116, item, visitor) {
5593
+ let ctrl = visitor(item, path116);
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(path111.concat([[field, i]])), token.items[i], visitor);
5600
+ const ci = _visit(Object.freeze(path116.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, path111);
5611
+ ctrl = ctrl(item, path116);
5612
5612
  }
5613
5613
  }
5614
- return typeof ctrl === "function" ? ctrl(item, path111) : ctrl;
5614
+ return typeof ctrl === "function" ? ctrl(item, path116) : ctrl;
5615
5615
  }
5616
5616
  exports.visit = visit;
5617
5617
  }
@@ -6712,18 +6712,18 @@ var require_parser = __commonJS({
6712
6712
  if (this.type === "map-value-ind") {
6713
6713
  const prev = getPrevProps(this.peek(2));
6714
6714
  const start = getFirstKeyStartProps(prev);
6715
- let sep9;
6715
+ let sep12;
6716
6716
  if (scalar.end) {
6717
- sep9 = scalar.end;
6718
- sep9.push(this.sourceToken);
6717
+ sep12 = scalar.end;
6718
+ sep12.push(this.sourceToken);
6719
6719
  delete scalar.end;
6720
6720
  } else
6721
- sep9 = [this.sourceToken];
6721
+ sep12 = [this.sourceToken];
6722
6722
  const map = {
6723
6723
  type: "block-map",
6724
6724
  offset: scalar.offset,
6725
6725
  indent: scalar.indent,
6726
- items: [{ start, key: scalar, sep: sep9 }]
6726
+ items: [{ start, key: scalar, sep: sep12 }]
6727
6727
  };
6728
6728
  this.onKeyLine = true;
6729
6729
  this.stack[this.stack.length - 1] = map;
@@ -6876,15 +6876,15 @@ var require_parser = __commonJS({
6876
6876
  } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
6877
6877
  const start2 = getFirstKeyStartProps(it.start);
6878
6878
  const key = it.key;
6879
- const sep9 = it.sep;
6880
- sep9.push(this.sourceToken);
6879
+ const sep12 = it.sep;
6880
+ sep12.push(this.sourceToken);
6881
6881
  delete it.key;
6882
6882
  delete it.sep;
6883
6883
  this.stack.push({
6884
6884
  type: "block-map",
6885
6885
  offset: this.offset,
6886
6886
  indent: this.indent,
6887
- items: [{ start: start2, key, sep: sep9 }]
6887
+ items: [{ start: start2, key, sep: sep12 }]
6888
6888
  });
6889
6889
  } else if (start.length > 0) {
6890
6890
  it.sep = it.sep.concat(start, this.sourceToken);
@@ -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 fs107 = this.flowScalar(this.type);
6916
+ const fs111 = this.flowScalar(this.type);
6917
6917
  if (atNextItem || it.value) {
6918
- map.items.push({ start, key: fs107, sep: [] });
6918
+ map.items.push({ start, key: fs111, sep: [] });
6919
6919
  this.onKeyLine = true;
6920
6920
  } else if (it.sep) {
6921
- this.stack.push(fs107);
6921
+ this.stack.push(fs111);
6922
6922
  } else {
6923
- Object.assign(it, { key: fs107, sep: [] });
6923
+ Object.assign(it, { key: fs111, 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 fs107 = this.flowScalar(this.type);
7051
+ const fs111 = this.flowScalar(this.type);
7052
7052
  if (!it || it.value)
7053
- fc.items.push({ start: [], key: fs107, sep: [] });
7053
+ fc.items.push({ start: [], key: fs111, sep: [] });
7054
7054
  else if (it.sep)
7055
- this.stack.push(fs107);
7055
+ this.stack.push(fs111);
7056
7056
  else
7057
- Object.assign(it, { key: fs107, sep: [] });
7057
+ Object.assign(it, { key: fs111, sep: [] });
7058
7058
  return;
7059
7059
  }
7060
7060
  case "flow-map-end":
@@ -7078,13 +7078,13 @@ var require_parser = __commonJS({
7078
7078
  const prev = getPrevProps(parent);
7079
7079
  const start = getFirstKeyStartProps(prev);
7080
7080
  fixFlowSeqItems(fc);
7081
- const sep9 = fc.end.splice(1, fc.end.length);
7082
- sep9.push(this.sourceToken);
7081
+ const sep12 = fc.end.splice(1, fc.end.length);
7082
+ sep12.push(this.sourceToken);
7083
7083
  const map = {
7084
7084
  type: "block-map",
7085
7085
  offset: fc.offset,
7086
7086
  indent: fc.indent,
7087
- items: [{ start, key: fc, sep: sep9 }]
7087
+ items: [{ start, key: fc, sep: sep12 }]
7088
7088
  };
7089
7089
  this.onKeyLine = true;
7090
7090
  this.stack[this.stack.length - 1] = map;
@@ -7363,16 +7363,16 @@ var require_dist = __commonJS({
7363
7363
  });
7364
7364
 
7365
7365
  // src/scripts/hooks/dispatch_entry.ts
7366
- import * as path110 from "node:path";
7367
- import { fileURLToPath as fileURLToPath71 } from "node:url";
7366
+ import * as path115 from "node:path";
7367
+ import { fileURLToPath as fileURLToPath74 } from "node:url";
7368
7368
 
7369
7369
  // src/scripts/hooks/dispatch_hook.ts
7370
7370
  var import_yaml7 = __toESM(require_dist(), 1);
7371
- import { spawnSync as spawnSync10 } from "node:child_process";
7372
- import fs106 from "node:fs";
7373
- import path109 from "node:path";
7371
+ import { spawnSync as spawnSync11 } from "node:child_process";
7372
+ import fs110 from "node:fs";
7373
+ import path114 from "node:path";
7374
7374
  import * as tty2 from "node:tty";
7375
- import { fileURLToPath as fileURLToPath70, pathToFileURL as pathToFileURL61 } from "node:url";
7375
+ import { fileURLToPath as fileURLToPath73, pathToFileURL as pathToFileURL63 } from "node:url";
7376
7376
 
7377
7377
  // src/scripts/_lib/spawn_env.ts
7378
7378
  var DENY_EXACT = /* @__PURE__ */ new Set([
@@ -16091,8 +16091,8 @@ function lockfile_path(env) {
16091
16091
  }
16092
16092
  return write_target("installed.lock", { env: env ?? null });
16093
16093
  }
16094
- function read_lockfile(path111) {
16095
- const target = path111 ?? lockfile_path();
16094
+ function read_lockfile(path116) {
16095
+ const target = path116 ?? lockfile_path();
16096
16096
  let text;
16097
16097
  try {
16098
16098
  text = fs21.readFileSync(target, { encoding: "utf-8" });
@@ -16160,7 +16160,9 @@ var DETECTOR_IDS = [
16160
16160
  "promissory",
16161
16161
  "language",
16162
16162
  "verification",
16163
- "completion"
16163
+ "completion",
16164
+ "pending-decision",
16165
+ "untested"
16164
16166
  ];
16165
16167
  var REFUSAL_STATE_REL = path22.join("agents", "runtime", "state", "turn-end-gate");
16166
16168
  function refusalStateDir(workspaceRoot3) {
@@ -16185,7 +16187,9 @@ function readSessionCounts(workspaceRoot3, sessionId3) {
16185
16187
  }
16186
16188
  }
16187
16189
  function emptyCounts() {
16188
- return { promissory: 0, language: 0, verification: 0, completion: 0 };
16190
+ const out = {};
16191
+ for (const id of DETECTOR_IDS) out[id] = 0;
16192
+ return out;
16189
16193
  }
16190
16194
  function isDetector(v) {
16191
16195
  return typeof v === "string" && DETECTOR_IDS.includes(v);
@@ -16211,6 +16215,9 @@ function parseRecord(raw) {
16211
16215
  if (typeof o["agent_config_version"] === "string") {
16212
16216
  rec.agent_config_version = o["agent_config_version"];
16213
16217
  }
16218
+ if (typeof o["refused_prompt_id"] === "string") {
16219
+ rec.refused_prompt_id = o["refused_prompt_id"];
16220
+ }
16214
16221
  const counts = o["counts"];
16215
16222
  if (typeof counts === "object" && counts !== null && !Array.isArray(counts)) {
16216
16223
  const parsed = {};
@@ -16254,6 +16261,9 @@ function foldRefusal(prev, input) {
16254
16261
  else if (prev?.agent_config_version !== void 0) {
16255
16262
  rec.agent_config_version = prev.agent_config_version;
16256
16263
  }
16264
+ if (input.promptId !== void 0 && input.promptId !== "") {
16265
+ rec.refused_prompt_id = input.promptId;
16266
+ }
16257
16267
  return rec;
16258
16268
  }
16259
16269
  function readInstallBoundary() {
@@ -34016,14 +34026,92 @@ if (_isCliEntry37()) {
34016
34026
  }
34017
34027
 
34018
34028
  // src/scripts/hooks/end_review_nudge_hook.ts
34019
- import { spawnSync as spawnSync6 } from "node:child_process";
34029
+ import { spawnSync as spawnSync7 } from "node:child_process";
34020
34030
  import * as crypto9 from "node:crypto";
34021
- import * as fs82 from "node:fs";
34031
+ import * as fs83 from "node:fs";
34022
34032
  import * as os11 from "node:os";
34023
- import * as path83 from "node:path";
34033
+ import * as path84 from "node:path";
34024
34034
  import { fileURLToPath as fileURLToPath56, pathToFileURL as pathToFileURL48 } from "node:url";
34025
34035
 
34036
+ // src/scripts/_lib/review_baseline.ts
34037
+ import { spawnSync as spawnSync6 } from "node:child_process";
34038
+ import * as fs82 from "node:fs";
34039
+ import * as path83 from "node:path";
34040
+ function currentHeadSha(cwd) {
34041
+ try {
34042
+ const r = spawnSync6("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf8" });
34043
+ if (r.status !== 0) return null;
34044
+ const out = (r.stdout ?? "").trim();
34045
+ return out === "" ? null : out;
34046
+ } catch {
34047
+ return null;
34048
+ }
34049
+ }
34050
+ var BASELINE_STATE_REL = path83.join("agents", "runtime", "state", "review-baseline");
34051
+ function baselineStateDir(workspaceRoot3) {
34052
+ return path83.join(workspaceRoot3, BASELINE_STATE_REL);
34053
+ }
34054
+ function baselineStateFile(workspaceRoot3, sessionKey) {
34055
+ return path83.join(baselineStateDir(workspaceRoot3), `${sessionKey}.json`);
34056
+ }
34057
+ function parseBaseline(raw) {
34058
+ let decoded;
34059
+ try {
34060
+ decoded = JSON.parse(raw);
34061
+ } catch {
34062
+ return null;
34063
+ }
34064
+ if (typeof decoded !== "object" || decoded === null || Array.isArray(decoded)) return null;
34065
+ const o = decoded;
34066
+ const lines = o["baseline_lines"];
34067
+ if (typeof lines !== "number" || !Number.isFinite(lines) || lines < 0) return null;
34068
+ const written = o["written_at"];
34069
+ if (typeof written !== "string") return null;
34070
+ const head = o["head_sha"];
34071
+ const measure = o["measure"];
34072
+ return {
34073
+ head_sha: typeof head === "string" && head !== "" ? head : null,
34074
+ baseline_lines: lines,
34075
+ ...measure === "exact" || measure === "capped_approximation" ? { measure } : {},
34076
+ written_at: written
34077
+ };
34078
+ }
34079
+ function readBaseline(workspaceRoot3, sessionKey) {
34080
+ const file = baselineStateFile(workspaceRoot3, sessionKey);
34081
+ let raw;
34082
+ try {
34083
+ raw = fs82.readFileSync(file, "utf-8");
34084
+ } catch (exc) {
34085
+ const code = exc?.code;
34086
+ return code === "ENOENT" ? "absent" : "unreadable";
34087
+ }
34088
+ return parseBaseline(raw) ?? "unreadable";
34089
+ }
34090
+ function applyBaseline(measuredLines, baseline, headSha, measuredMeasure = "exact") {
34091
+ if (baseline === "absent" || baseline === "unreadable") {
34092
+ return { applied: false, fallback: baseline, lines: measuredLines };
34093
+ }
34094
+ if (baseline.measure !== "exact" || measuredMeasure !== "exact") {
34095
+ return { applied: false, fallback: "mixed-measure", lines: measuredLines };
34096
+ }
34097
+ if (baseline.head_sha !== headSha()) {
34098
+ return { applied: false, fallback: "head-moved", lines: measuredLines };
34099
+ }
34100
+ return {
34101
+ applied: true,
34102
+ baseline,
34103
+ lines: Math.max(0, measuredLines - baseline.baseline_lines)
34104
+ };
34105
+ }
34106
+
34026
34107
  // src/scripts/_lib/review_skipped_record.ts
34108
+ var BASELINE_APPLICATIONS = [
34109
+ "applied",
34110
+ "absent",
34111
+ "unreadable",
34112
+ "head_moved",
34113
+ "mixed_measure"
34114
+ ];
34027
34115
  var PRODUCER_PRIVACY_CLASS2 = "ids-only";
34028
34116
  function isNonNegInt(n) {
34029
34117
  return typeof n === "number" && Number.isFinite(n) && Number.isInteger(n) && n >= 0;
@@ -34039,6 +34127,9 @@ function buildReviewSkippedLine(input) {
34039
34127
  }
34040
34128
  if (!input.ts) errors.push("ts (ISO-8601 UTC) is required");
34041
34129
  if (!input.id) errors.push("id (ULID, UUID, or content hash) is required");
34130
+ if (input.baseline !== void 0 && !BASELINE_APPLICATIONS.includes(input.baseline)) {
34131
+ errors.push(`baseline must be one of ${BASELINE_APPLICATIONS.join(", ")}`);
34132
+ }
34042
34133
  if (errors.length) return { line: null, errors };
34043
34134
  const line = {
34044
34135
  schema_version: 1,
@@ -34065,7 +34156,14 @@ function buildReviewSkippedLine(input) {
34065
34156
  persona: null,
34066
34157
  input_kind: "prompt",
34067
34158
  type: "note",
34068
- review_skipped: { diff_lines: input.diff_lines, mutation_measure: input.mutation_measure }
34159
+ review_skipped: {
34160
+ diff_lines: input.diff_lines,
34161
+ mutation_measure: input.mutation_measure,
34162
+ // Omitted, not defaulted, when the producer recorded nothing —
34163
+ // audit-log-v1's absent-versus-present split is the same one
34164
+ // `skills_applied` uses above, for the same reason.
34165
+ ...input.baseline === void 0 ? {} : { baseline: input.baseline }
34166
+ }
34069
34167
  };
34070
34168
  return { line, errors: [] };
34071
34169
  }
@@ -34079,13 +34177,13 @@ function isSafeTranscriptPath(rawPath, opts = {}) {
34079
34177
  const homeDir = opts.homeDir ?? os11.homedir();
34080
34178
  const maxBytes = opts.maxBytes ?? TRANSCRIPT_SCAN_MAX_BYTES;
34081
34179
  try {
34082
- const realHome = fs82.realpathSync(homeDir);
34083
- const realPath = fs82.realpathSync(rawPath);
34084
- const relative13 = path83.relative(realHome, realPath);
34085
- if (relative13 === "" || relative13.startsWith("..") || path83.isAbsolute(relative13)) {
34180
+ const realHome = fs83.realpathSync(homeDir);
34181
+ const realPath = fs83.realpathSync(rawPath);
34182
+ const relative16 = path84.relative(realHome, realPath);
34183
+ if (relative16 === "" || relative16.startsWith("..") || path84.isAbsolute(relative16)) {
34086
34184
  return false;
34087
34185
  }
34088
- const { size } = fs82.statSync(realPath);
34186
+ const { size } = fs83.statSync(realPath);
34089
34187
  return size <= maxBytes;
34090
34188
  } catch {
34091
34189
  return false;
@@ -34116,7 +34214,7 @@ function nonDocMutatedLines(rows) {
34116
34214
  }
34117
34215
  function gitNumstatRows(cwd) {
34118
34216
  try {
34119
- const r = spawnSync6("git", ["diff", "--numstat", "HEAD"], {
34217
+ const r = spawnSync7("git", ["diff", "--numstat", "HEAD"], {
34120
34218
  cwd,
34121
34219
  encoding: "utf8",
34122
34220
  maxBuffer: 16 * 1024 * 1024
@@ -34129,7 +34227,7 @@ function gitNumstatRows(cwd) {
34129
34227
  }
34130
34228
  function untrackedNonDocFiles(cwd) {
34131
34229
  try {
34132
- const r = spawnSync6("git", ["ls-files", "--others", "--exclude-standard"], {
34230
+ const r = spawnSync7("git", ["ls-files", "--others", "--exclude-standard"], {
34133
34231
  cwd,
34134
34232
  encoding: "utf8",
34135
34233
  maxBuffer: 16 * 1024 * 1024
@@ -34144,13 +34242,13 @@ var BINARY_PROBE_BYTES = 8e3;
34144
34242
  var UNTRACKED_FILE_READ_CAP_BYTES = 8 * 1024 * 1024;
34145
34243
  function untrackedFileLineCount(cwd, relPath) {
34146
34244
  try {
34147
- const abs = path83.resolve(cwd, relPath);
34148
- const size = fs82.statSync(abs).size;
34245
+ const abs = path84.resolve(cwd, relPath);
34246
+ const size = fs83.statSync(abs).size;
34149
34247
  if (size === 0) return 0;
34150
34248
  if (size > UNTRACKED_FILE_READ_CAP_BYTES) {
34151
34249
  return MUTATION_LINE_THRESHOLD + 1;
34152
34250
  }
34153
- const buf = fs82.readFileSync(abs);
34251
+ const buf = fs83.readFileSync(abs);
34154
34252
  if (buf.length === 0) return 0;
34155
34253
  const probe = buf.subarray(0, Math.min(buf.length, BINARY_PROBE_BYTES));
34156
34254
  if (probe.includes(0)) return 0;
@@ -34229,30 +34327,31 @@ function scanTranscriptForReviewer(transcriptText) {
34229
34327
  function buildAdvisoryLine(diffLines) {
34230
34328
  return `this session mutated ${diffLines} lines without a neutral review; spawn a cross-model reviewer before claiming done (delegation-policy / verify-budget)`;
34231
34329
  }
34232
- function appendReviewSkippedTelemetry(workspaceRoot3, diffLines, mutationMeasure) {
34330
+ function appendReviewSkippedTelemetry(workspaceRoot3, diffLines, mutationMeasure, baseline) {
34233
34331
  if (is_replay_mode()) return;
34234
34332
  const ts = (/* @__PURE__ */ new Date()).toISOString();
34235
34333
  const { line, errors } = buildReviewSkippedLine({
34236
34334
  diff_lines: diffLines,
34237
34335
  mutation_measure: mutationMeasure,
34238
34336
  ts,
34239
- id: crypto9.randomUUID()
34337
+ id: crypto9.randomUUID(),
34338
+ baseline
34240
34339
  });
34241
34340
  if (errors.length || line === null) return;
34242
34341
  try {
34243
- const dir = path83.join(workspaceRoot3, "agents", "runtime", "state", "audit");
34244
- fs82.mkdirSync(dir, { recursive: true });
34245
- const file = path83.join(dir, `${ts.slice(0, 7)}.jsonl`);
34246
- fs82.appendFileSync(file, `${JSON.stringify(line)}
34342
+ const dir = path84.join(workspaceRoot3, "agents", "runtime", "state", "audit");
34343
+ fs83.mkdirSync(dir, { recursive: true });
34344
+ const file = path84.join(dir, `${ts.slice(0, 7)}.jsonl`);
34345
+ fs83.appendFileSync(file, `${JSON.stringify(line)}
34247
34346
  `, "utf8");
34248
34347
  } catch {
34249
34348
  }
34250
34349
  }
34251
34350
  function sessionStateDir(workspaceRoot3) {
34252
- return path83.join(workspaceRoot3, "agents", "runtime", "state", "end-review-nudge");
34351
+ return path84.join(workspaceRoot3, "agents", "runtime", "state", "end-review-nudge");
34253
34352
  }
34254
34353
  function sessionStateFile(workspaceRoot3, sessionKey) {
34255
- return path83.join(sessionStateDir(workspaceRoot3), `${sessionKey}.json`);
34354
+ return path84.join(sessionStateDir(workspaceRoot3), `${sessionKey}.json`);
34256
34355
  }
34257
34356
  function deriveSessionKey2(envelope, payload) {
34258
34357
  const raw = str6(envelope["session_id"]) || str6(payload["transcript_path"] ?? payload["transcriptPath"]);
@@ -34261,7 +34360,7 @@ function deriveSessionKey2(envelope, payload) {
34261
34360
  }
34262
34361
  function hasFiredThisSession(workspaceRoot3, sessionKey) {
34263
34362
  try {
34264
- return fs82.existsSync(sessionStateFile(workspaceRoot3, sessionKey));
34363
+ return fs83.existsSync(sessionStateFile(workspaceRoot3, sessionKey));
34265
34364
  } catch {
34266
34365
  return false;
34267
34366
  }
@@ -34275,6 +34374,12 @@ function markFiredThisSession(workspaceRoot3, sessionKey, ts) {
34275
34374
  function _read_stdin3() {
34276
34375
  return readHookStdin();
34277
34376
  }
34377
+ var FALLBACK_TO_TELEMETRY = {
34378
+ absent: "absent",
34379
+ unreadable: "unreadable",
34380
+ "head-moved": "head_moved",
34381
+ "mixed-measure": "mixed_measure"
34382
+ };
34278
34383
  function main54() {
34279
34384
  const [envelope, payload] = unwrap(_read_stdin3(), "claude");
34280
34385
  const event = String(envelope["event"] ?? "");
@@ -34282,19 +34387,32 @@ function main54() {
34282
34387
  return 0;
34283
34388
  }
34284
34389
  const workspace_root = String(envelope["workspace_root"] ?? "").trim() || process.cwd();
34285
- let diffLines;
34390
+ let measuredLines;
34286
34391
  let mutationMeasure;
34287
34392
  try {
34288
34393
  const measured = totalNonDocMutatedLinesWithMeasure(workspace_root);
34289
- diffLines = measured.lines;
34394
+ measuredLines = measured.lines;
34290
34395
  mutationMeasure = measured.measure;
34291
34396
  } catch {
34292
34397
  return 0;
34293
34398
  }
34399
+ const sessionKey = deriveSessionKey2(envelope, payload);
34400
+ const baselineOutcome = applyBaseline(
34401
+ measuredLines,
34402
+ readBaseline(workspace_root, sessionKey),
34403
+ // A THUNK, not a value: on the `absent` and `unreadable` branches the
34404
+ // result is discarded, and those two are the steady state on every host
34405
+ // without this nudge and on every session before its first baseline
34406
+ // write. Passing the value eagerly spent an 11-14 ms `git rev-parse` on
34407
+ // each of those stops for nothing.
34408
+ () => currentHeadSha(workspace_root),
34409
+ mutationMeasure
34410
+ );
34411
+ const diffLines = baselineOutcome.lines;
34412
+ const baselineApplication = baselineOutcome.applied ? "applied" : FALLBACK_TO_TELEMETRY[baselineOutcome.fallback];
34294
34413
  if (diffLines <= MUTATION_LINE_THRESHOLD) {
34295
34414
  return 0;
34296
34415
  }
34297
- const sessionKey = deriveSessionKey2(envelope, payload);
34298
34416
  if (hasFiredThisSession(workspace_root, sessionKey)) {
34299
34417
  return 0;
34300
34418
  }
@@ -34304,7 +34422,7 @@ function main54() {
34304
34422
  let reviewerRan = false;
34305
34423
  if (transcriptPath && isSafeTranscriptPath(transcriptPath)) {
34306
34424
  try {
34307
- reviewerRan = scanTranscriptForReviewer(fs82.readFileSync(transcriptPath, "utf-8"));
34425
+ reviewerRan = scanTranscriptForReviewer(fs83.readFileSync(transcriptPath, "utf-8"));
34308
34426
  } catch {
34309
34427
  reviewerRan = false;
34310
34428
  }
@@ -34314,7 +34432,12 @@ function main54() {
34314
34432
  }
34315
34433
  markFiredThisSession(workspace_root, sessionKey, (/* @__PURE__ */ new Date()).toISOString());
34316
34434
  try {
34317
- appendReviewSkippedTelemetry(workspace_root, diffLines, mutationMeasure);
34435
+ appendReviewSkippedTelemetry(
34436
+ workspace_root,
34437
+ diffLines,
34438
+ mutationMeasure,
34439
+ baselineApplication
34440
+ );
34318
34441
  } catch {
34319
34442
  }
34320
34443
  process.stdout.write(
@@ -34334,13 +34457,13 @@ function _isCliEntry38() {
34334
34457
  if (process.argv[1] === void 0) {
34335
34458
  return false;
34336
34459
  }
34337
- const argvUrl = pathToFileURL48(path83.resolve(process.argv[1])).href;
34460
+ const argvUrl = pathToFileURL48(path84.resolve(process.argv[1])).href;
34338
34461
  if (import.meta.url === argvUrl) {
34339
34462
  return true;
34340
34463
  }
34341
34464
  try {
34342
- const here = fs82.realpathSync(fileURLToPath56(import.meta.url));
34343
- const argv = fs82.realpathSync(path83.resolve(process.argv[1]));
34465
+ const here = fs83.realpathSync(fileURLToPath56(import.meta.url));
34466
+ const argv = fs83.realpathSync(path84.resolve(process.argv[1]));
34344
34467
  return here === argv;
34345
34468
  } catch {
34346
34469
  return false;
@@ -34350,16 +34473,530 @@ if (_isCliEntry38()) {
34350
34473
  process.exit(main54());
34351
34474
  }
34352
34475
 
34353
- // src/scripts/hooks/turn_end_gate_hook.ts
34476
+ // src/scripts/hooks/review_baseline_hook.ts
34354
34477
  import * as fs84 from "node:fs";
34355
34478
  import * as path85 from "node:path";
34356
- import { fileURLToPath as fileURLToPath58, pathToFileURL as pathToFileURL50 } from "node:url";
34479
+ import { fileURLToPath as fileURLToPath57, pathToFileURL as pathToFileURL49 } from "node:url";
34480
+ var EXIT_OK2 = 0;
34481
+ function buildBaseline(workspaceRoot3, now = /* @__PURE__ */ new Date()) {
34482
+ const measured = totalNonDocMutatedLinesWithMeasure(workspaceRoot3);
34483
+ return {
34484
+ head_sha: currentHeadSha(workspaceRoot3),
34485
+ baseline_lines: measured.lines,
34486
+ // Carried, not discarded. Past `UNTRACKED_FILE_CAP` the count is a
34487
+ // synthetic `THRESHOLD + 1 + tracked` chosen to be over the bar rather
34488
+ // than to be true, and subtracting that from a later exact count is
34489
+ // arithmetic over two different quantities. The consumer refuses the
34490
+ // subtraction when the two measures disagree; it can only do that if the
34491
+ // writer says which one it took.
34492
+ measure: measured.measure,
34493
+ written_at: now.toISOString()
34494
+ };
34495
+ }
34496
+ function main55() {
34497
+ let envelope;
34498
+ let payload;
34499
+ try {
34500
+ [envelope, payload] = unwrap(readHookStdin(), "claude");
34501
+ } catch {
34502
+ return EXIT_OK2;
34503
+ }
34504
+ const event = String(envelope["event"] ?? "");
34505
+ if (event !== "" && event !== "session_start") return EXIT_OK2;
34506
+ const workspaceRoot3 = String(envelope["workspace_root"] ?? "").trim() || process.cwd();
34507
+ const sessionKey = deriveSessionKey2(envelope, payload);
34508
+ const file = baselineStateFile(workspaceRoot3, sessionKey);
34509
+ try {
34510
+ if (fs84.existsSync(file)) return EXIT_OK2;
34511
+ } catch {
34512
+ return EXIT_OK2;
34513
+ }
34514
+ try {
34515
+ atomic_write_json(file, buildBaseline(workspaceRoot3));
34516
+ } catch {
34517
+ }
34518
+ return EXIT_OK2;
34519
+ }
34520
+ function _isCliEntry39() {
34521
+ if (true) return false;
34522
+ if (process.argv[1] === void 0) return false;
34523
+ const argvUrl = pathToFileURL49(path85.resolve(process.argv[1])).href;
34524
+ if (import.meta.url === argvUrl) return true;
34525
+ try {
34526
+ const here = fs84.realpathSync(fileURLToPath57(import.meta.url));
34527
+ const argv = fs84.realpathSync(path85.resolve(process.argv[1]));
34528
+ return here === argv;
34529
+ } catch {
34530
+ return false;
34531
+ }
34532
+ }
34533
+ if (_isCliEntry39()) {
34534
+ process.exit(main55());
34535
+ }
34536
+
34537
+ // src/scripts/hooks/turn_end_gate_hook.ts
34538
+ import * as fs88 from "node:fs";
34539
+ import * as path90 from "node:path";
34540
+ import { fileURLToPath as fileURLToPath61, pathToFileURL as pathToFileURL52 } from "node:url";
34541
+
34542
+ // src/scripts/check_reply_consistency.ts
34543
+ import * as fs86 from "node:fs";
34544
+ import * as path88 from "node:path";
34545
+ import { fileURLToPath as fileURLToPath59, pathToFileURL as pathToFileURL50 } from "node:url";
34546
+
34547
+ // src/scripts/_lib/agent_src.ts
34548
+ import * as fs85 from "node:fs";
34549
+ import * as path87 from "node:path";
34550
+ import { fileURLToPath as fileURLToPath58 } from "node:url";
34551
+
34552
+ // src/scripts/_lib/guidelines_lane.ts
34553
+ import * as path86 from "node:path";
34554
+ var GUIDELINES_SOURCE_REL = path86.join("docs", "guidelines");
34555
+
34556
+ // src/scripts/_lib/agent_src.ts
34557
+ var _HERE11 = path87.dirname(fileURLToPath58(import.meta.url));
34558
+ var _DEFAULT_ROOT = path87.resolve(_HERE11, "..", "..", "..");
34559
+ function _deriveRoots(root) {
34560
+ const packages = path87.join(root, "packages");
34561
+ const src = path87.join(root, "src");
34562
+ return {
34563
+ ROOT: root,
34564
+ LEGACY_SRC: path87.join(root, ".agent-src.uncondensed"),
34565
+ PACKAGES: packages,
34566
+ PACKAGE_CORE: path87.join(packages, "core"),
34567
+ SRC: src,
34568
+ SRC_SKILLS: path87.join(src, "skills"),
34569
+ SRC_RULES: path87.join(src, "rules"),
34570
+ SRC_AGENT: path87.join(src, "agent-src"),
34571
+ SRC_DOMAINS: path87.join(src, "domains")
34572
+ };
34573
+ }
34574
+ var _roots = _deriveRoots(_DEFAULT_ROOT);
34575
+ function _isDir4(p) {
34576
+ try {
34577
+ return fs85.statSync(p).isDirectory();
34578
+ } catch {
34579
+ return false;
34580
+ }
34581
+ }
34582
+ function _exists5(p) {
34583
+ try {
34584
+ fs85.statSync(p);
34585
+ return true;
34586
+ } catch {
34587
+ return false;
34588
+ }
34589
+ }
34590
+ function _iterdirSorted2(p) {
34591
+ let names;
34592
+ try {
34593
+ names = fs85.readdirSync(p);
34594
+ } catch {
34595
+ return [];
34596
+ }
34597
+ names.sort();
34598
+ return names.map((name) => path87.join(p, name));
34599
+ }
34600
+ function artefact_roots() {
34601
+ const roots = [];
34602
+ if (_exists5(_roots.LEGACY_SRC)) {
34603
+ roots.push(_roots.LEGACY_SRC);
34604
+ }
34605
+ if (_exists5(_roots.PACKAGES)) {
34606
+ for (const pkg of _iterdirSorted2(_roots.PACKAGES)) {
34607
+ const sub = path87.join(pkg, ".agent-src.uncondensed");
34608
+ if (_isDir4(sub)) {
34609
+ roots.push(sub);
34610
+ }
34611
+ }
34612
+ }
34613
+ if (_isDir4(_roots.SRC_AGENT)) {
34614
+ roots.push(_roots.SRC_AGENT);
34615
+ }
34616
+ if (_isDir4(_roots.SRC_SKILLS) || _isDir4(_roots.SRC_RULES)) {
34617
+ roots.push(_roots.SRC);
34618
+ }
34619
+ return roots;
34620
+ }
34621
+
34622
+ // src/scripts/check_reply_consistency.ts
34623
+ var _HERE12 = fileURLToPath59(import.meta.url);
34624
+ var ROOT3 = path88.resolve(path88.dirname(_HERE12), "..", "..");
34625
+ var QUIET = process.argv.slice(2).includes("--quiet");
34626
+ var OPTION_LINE_RE = /^\s*>?\s*(\d+)\.\s+\S/;
34627
+ var REC_LINE_RE = /(?:Recommendation|Empfehlung)\s*:\s*(\d+)\b/i;
34628
+ var TAG_RE = /\((?:recommended|rec|empfohlen)\)/i;
34629
+ var CODESPAN_RE = /`[^`\n]*`/g;
34630
+ var HEADING_RE = /^#{1,6}\s/;
34631
+ var FENCE_RE = /^\s*(```|~~~)/;
34632
+ var REC_ADJACENCY_WINDOW = 2;
34633
+ function _strip_codespans(line) {
34634
+ return line.replace(CODESPAN_RE, "``");
34635
+ }
34636
+ function splitAndMask(text) {
34637
+ return mask_fences(_splitlines4(text));
34638
+ }
34639
+ function _splitlines4(text) {
34640
+ if (text === "") return [];
34641
+ const parts = text.split(/\r\n|\r|\n/);
34642
+ if (parts.length > 0 && parts[parts.length - 1] === "") {
34643
+ parts.pop();
34644
+ }
34645
+ return parts;
34646
+ }
34647
+ function mask_fences(lines) {
34648
+ const out = [];
34649
+ let fence = null;
34650
+ for (const raw of lines) {
34651
+ const m = FENCE_RE.exec(raw);
34652
+ if (m) {
34653
+ const marker = m[1];
34654
+ if (fence === null) {
34655
+ fence = marker;
34656
+ } else if (fence === marker) {
34657
+ fence = null;
34658
+ }
34659
+ out.push("");
34660
+ continue;
34661
+ }
34662
+ out.push(fence === null ? raw : "");
34663
+ }
34664
+ return out;
34665
+ }
34666
+ function find_option_blocks(text) {
34667
+ const lines = mask_fences(_splitlines4(text));
34668
+ const blocks = [];
34669
+ let current = null;
34670
+ for (let idx = 0; idx < lines.length; idx++) {
34671
+ const m = OPTION_LINE_RE.exec(lines[idx]);
34672
+ if (m) {
34673
+ const num = parseInt(m[1], 10);
34674
+ if (current === null) {
34675
+ current = { startLine: idx + 1, endLine: idx + 1, numbers: [num] };
34676
+ } else {
34677
+ current.endLine = idx + 1;
34678
+ current.numbers.push(num);
34679
+ }
34680
+ } else {
34681
+ if (current !== null && current.numbers.length >= 2) {
34682
+ blocks.push(current);
34683
+ }
34684
+ current = null;
34685
+ }
34686
+ }
34687
+ if (current !== null && current.numbers.length >= 2) {
34688
+ blocks.push(current);
34689
+ }
34690
+ return blocks;
34691
+ }
34692
+ function recommendationsUnder(text, block, maskedLines) {
34693
+ const lines = maskedLines ?? mask_fences(_splitlines4(text));
34694
+ const recs = [];
34695
+ let inspected = 0;
34696
+ for (let idx = block.endLine; idx < lines.length && inspected < REC_ADJACENCY_WINDOW; idx++) {
34697
+ const line = lines[idx];
34698
+ if (line.trim() === "") {
34699
+ continue;
34700
+ }
34701
+ if (HEADING_RE.test(line) || OPTION_LINE_RE.test(line)) {
34702
+ break;
34703
+ }
34704
+ inspected += 1;
34705
+ const m = REC_LINE_RE.exec(line);
34706
+ if (m) {
34707
+ recs.push({ line: idx + 1, num: parseInt(m[1], 10) });
34708
+ }
34709
+ }
34710
+ return recs;
34711
+ }
34712
+ function check_reply(text) {
34713
+ const rawLines = _splitlines4(text);
34714
+ const lines = mask_fences(rawLines);
34715
+ const findings = [];
34716
+ for (let idx = 0; idx < lines.length; idx++) {
34717
+ const stripped = _strip_codespans(lines[idx]);
34718
+ if (OPTION_LINE_RE.test(stripped) && TAG_RE.test(stripped)) {
34719
+ findings.push({
34720
+ line: idx + 1,
34721
+ message: `inline tag on numbered option \u2014 ${rawLines[idx].trim()}`
34722
+ });
34723
+ }
34724
+ }
34725
+ const blocks = find_option_blocks(text);
34726
+ for (const block of blocks) {
34727
+ const recs = recommendationsUnder(text, block);
34728
+ if (recs.length === 0) {
34729
+ findings.push({
34730
+ line: block.startLine,
34731
+ message: "numbered options block without a Recommendation:/Empfehlung: line directly under it"
34732
+ });
34733
+ continue;
34734
+ }
34735
+ if (recs.length > 1) {
34736
+ findings.push({
34737
+ line: recs[1].line,
34738
+ message: `multiple recommendation lines under one options block: [${recs.map((r) => r.num).join(", ")}]`
34739
+ });
34740
+ continue;
34741
+ }
34742
+ const rec = recs[0];
34743
+ if (!block.numbers.includes(rec.num)) {
34744
+ findings.push({
34745
+ line: rec.line,
34746
+ message: `recommendation ${String(rec.num)} not present in the options block above it (options: [${block.numbers.join(", ")}])`
34747
+ });
34748
+ }
34749
+ }
34750
+ findings.sort((a, b) => a.line - b.line);
34751
+ return findings;
34752
+ }
34753
+ function _isDir5(p) {
34754
+ try {
34755
+ return fs86.statSync(p).isDirectory();
34756
+ } catch {
34757
+ return false;
34758
+ }
34759
+ }
34760
+ function _rglobMdSorted(dir) {
34761
+ const out = [];
34762
+ const walk = (current) => {
34763
+ let entries;
34764
+ try {
34765
+ entries = fs86.readdirSync(current, { withFileTypes: true });
34766
+ } catch {
34767
+ return;
34768
+ }
34769
+ for (const ent of entries) {
34770
+ const full = path88.join(current, ent.name);
34771
+ if (ent.isDirectory() || ent.isSymbolicLink() && _isDir5(full)) {
34772
+ walk(full);
34773
+ } else if (ent.name.endsWith(".md")) {
34774
+ out.push(full);
34775
+ }
34776
+ }
34777
+ };
34778
+ walk(dir);
34779
+ out.sort();
34780
+ return out;
34781
+ }
34782
+ function _relToPosixOrAbs(child, root) {
34783
+ const rel = path88.relative(root, child);
34784
+ if (rel === "" || rel.startsWith("..") || path88.isAbsolute(rel)) {
34785
+ return child.split(path88.sep).join("/");
34786
+ }
34787
+ return rel.split(path88.sep).join("/");
34788
+ }
34789
+ function cmd_scan_dir(root) {
34790
+ let roots;
34791
+ if (!_isDir5(root)) {
34792
+ const legacy = path88.join(ROOT3, ".agent-src.uncondensed");
34793
+ if (path88.resolve(root) === path88.resolve(legacy)) {
34794
+ roots = artefact_roots();
34795
+ if (roots.length === 0) {
34796
+ process.stderr.write("error: no artefact roots found (legacy or packages/*)\n");
34797
+ return 1;
34798
+ }
34799
+ } else {
34800
+ process.stderr.write(`error: not a directory: ${root}
34801
+ `);
34802
+ return 1;
34803
+ }
34804
+ } else {
34805
+ roots = [root];
34806
+ }
34807
+ const violations = [];
34808
+ let scanned = 0;
34809
+ for (const r of roots) {
34810
+ for (const md of _rglobMdSorted(r)) {
34811
+ scanned += 1;
34812
+ const text = fs86.readFileSync(md, "utf-8");
34813
+ const lines = _splitlines4(text);
34814
+ for (let idx = 0; idx < lines.length; idx++) {
34815
+ const raw = lines[idx];
34816
+ const stripped = _strip_codespans(raw);
34817
+ if (OPTION_LINE_RE.test(stripped) && TAG_RE.test(stripped)) {
34818
+ violations.push([md, idx + 1, raw.trim()]);
34819
+ }
34820
+ }
34821
+ }
34822
+ }
34823
+ try {
34824
+ assertScanned({
34825
+ gate: "check_reply_consistency",
34826
+ scanned,
34827
+ units: "markdown file(s)",
34828
+ roots: roots.map((r) => _relToPosixOrAbs(r, ROOT3))
34829
+ });
34830
+ } catch (exc) {
34831
+ if (exc instanceof DeadScopeError) {
34832
+ process.stderr.write(`\u274C ${exc.message}
34833
+ `);
34834
+ return 1;
34835
+ }
34836
+ throw exc;
34837
+ }
34838
+ if (violations.length > 0) {
34839
+ for (const [p, line, snippet] of violations) {
34840
+ process.stderr.write(` \u{1F534} ${p}:${String(line)} \u2014 inline-tag \u2014 ${snippet}
34841
+ `);
34842
+ }
34843
+ process.stderr.write(`
34844
+ \u274C ${String(violations.length)} legacy-pattern violation(s)
34845
+ `);
34846
+ return 2;
34847
+ }
34848
+ if (!QUIET) {
34849
+ const scanned2 = roots.map((r) => _relToPosixOrAbs(r, ROOT3)).join(", ");
34850
+ process.stdout.write(`\u2705 No legacy (recommended) tags found under ${scanned2}
34851
+ `);
34852
+ }
34853
+ return 0;
34854
+ }
34855
+ var USAGE = "usage: check_reply_consistency [-h] (--stdin | --file FILE | --scan-dir SCAN_DIR)\n [-v] [--quiet]\n";
34856
+ function _usage_error(message) {
34857
+ process.stderr.write(USAGE);
34858
+ process.stderr.write(`check_reply_consistency: error: ${message}
34859
+ `);
34860
+ process.exit(1);
34861
+ }
34862
+ function _readStdin14() {
34863
+ try {
34864
+ return fs86.readFileSync(0, "utf-8");
34865
+ } catch {
34866
+ return "";
34867
+ }
34868
+ }
34869
+ function parse_args9(argv) {
34870
+ let stdin = false;
34871
+ let file = null;
34872
+ let scan_dir = null;
34873
+ let verbose = false;
34874
+ const groupSeen = [];
34875
+ const need = (i, name) => {
34876
+ const v = argv[i];
34877
+ if (v === void 0) {
34878
+ _usage_error(`argument ${name}: expected one argument`);
34879
+ }
34880
+ return v;
34881
+ };
34882
+ for (let i = 0; i < argv.length; i++) {
34883
+ const arg = argv[i];
34884
+ if (arg === "--stdin") {
34885
+ stdin = true;
34886
+ groupSeen.push("--stdin");
34887
+ } else if (arg === "--file") {
34888
+ file = need(++i, "--file");
34889
+ groupSeen.push("--file");
34890
+ } else if (arg.startsWith("--file=")) {
34891
+ file = arg.slice("--file=".length);
34892
+ groupSeen.push("--file");
34893
+ } else if (arg === "--scan-dir") {
34894
+ scan_dir = need(++i, "--scan-dir");
34895
+ groupSeen.push("--scan-dir");
34896
+ } else if (arg.startsWith("--scan-dir=")) {
34897
+ scan_dir = arg.slice("--scan-dir=".length);
34898
+ groupSeen.push("--scan-dir");
34899
+ } else if (arg === "-v" || arg === "--verbose") {
34900
+ verbose = true;
34901
+ } else if (arg === "--quiet") {
34902
+ } else if (arg === "-h" || arg === "--help") {
34903
+ process.stdout.write(USAGE);
34904
+ process.exit(0);
34905
+ } else {
34906
+ _usage_error(`unrecognized arguments: ${arg}`);
34907
+ }
34908
+ }
34909
+ if (groupSeen.length === 0) {
34910
+ _usage_error("one of the arguments --stdin --file --scan-dir is required");
34911
+ }
34912
+ if (groupSeen.length > 1) {
34913
+ _usage_error(`argument ${groupSeen[1]}: not allowed with argument ${groupSeen[0]}`);
34914
+ }
34915
+ return { stdin, file, scan_dir, verbose };
34916
+ }
34917
+ function main56(argv = process.argv.slice(2)) {
34918
+ const args = parse_args9(argv);
34919
+ if (args.scan_dir !== null) {
34920
+ return cmd_scan_dir(args.scan_dir);
34921
+ }
34922
+ let text;
34923
+ try {
34924
+ text = args.stdin ? _readStdin14() : fs86.readFileSync(args.file, "utf-8");
34925
+ } catch (e) {
34926
+ process.stderr.write(`error: ${String(e)}
34927
+ `);
34928
+ return 1;
34929
+ }
34930
+ const findings = check_reply(text);
34931
+ if (findings.length === 0) {
34932
+ if (args.verbose && !QUIET) {
34933
+ process.stdout.write("\u2705 reply consistent (every options block carries one adjacent recommendation)\n");
34934
+ }
34935
+ return 0;
34936
+ }
34937
+ for (const f of findings) {
34938
+ process.stderr.write(`\u274C line ${String(f.line)}: ${f.message}
34939
+ `);
34940
+ }
34941
+ return 2;
34942
+ }
34943
+ function _isCliEntry40() {
34944
+ if (true) {
34945
+ return false;
34946
+ }
34947
+ if (process.argv[1] === void 0) {
34948
+ return false;
34949
+ }
34950
+ const argvUrl = pathToFileURL50(path88.resolve(process.argv[1])).href;
34951
+ if (import.meta.url === argvUrl) {
34952
+ return true;
34953
+ }
34954
+ try {
34955
+ const here = fs86.realpathSync(fileURLToPath59(import.meta.url));
34956
+ const argv = fs86.realpathSync(path88.resolve(process.argv[1]));
34957
+ return here === argv;
34958
+ } catch {
34959
+ return false;
34960
+ }
34961
+ }
34962
+ var _IN_BUNDLE2 = true;
34963
+ if (!_IN_BUNDLE2 && (_isCliEntry40() || process.argv[1] === _HERE12)) {
34964
+ process.exit(main56());
34965
+ }
34966
+
34967
+ // src/scripts/_lib/dropped_decision.ts
34968
+ function detectDroppedDecision(assistantTurnTexts, closingFromPayload = false) {
34969
+ if (assistantTurnTexts.length < 2) return null;
34970
+ const asksIn = (text) => {
34971
+ const blocks = find_option_blocks(text);
34972
+ if (blocks.length === 0) return blocks;
34973
+ const masked = splitAndMask(text);
34974
+ return blocks.filter((b) => recommendationsUnder(text, b, masked).length > 0);
34975
+ };
34976
+ const closing = assistantTurnTexts[assistantTurnTexts.length - 1];
34977
+ if (asksIn(closing).length > 0) return null;
34978
+ for (let i = assistantTurnTexts.length - 2; i >= 0; i -= 1) {
34979
+ const earlier = assistantTurnTexts[i];
34980
+ const blocks = asksIn(earlier);
34981
+ if (blocks.length === 0) continue;
34982
+ const block = blocks[blocks.length - 1];
34983
+ return {
34984
+ detector: "pending-decision",
34985
+ // The option NUMBERS and the line span, never the option text: the
34986
+ // evidence is quoted into a refusal that reaches the transcript, and
34987
+ // an options block can carry anything the reply carried.
34988
+ evidence: `options ${block.numbers.join("/")} at lines ${block.startLine}-${block.endLine} of an earlier reply this turn (closing reply read from ${closingFromPayload ? "the stop payload" : "the transcript"})`,
34989
+ reason: "an earlier reply in THIS turn put numbered options to the user and no user answer followed \u2014 this closing reply carries no options block, so the decision disappeared without being answered, cancelled or superseded. A hook nudge, a reviewer result or a task notification may ADD to a turn; it may not displace a question already asked (user-interaction Iron Law 3: a decision handed to the user outlives the turn). Re-present the block and its recommendation line at the end of this reply"
34990
+ };
34991
+ }
34992
+ return null;
34993
+ }
34357
34994
 
34358
34995
  // src/scripts/hooks/subagent_ledger_hook.ts
34359
34996
  import * as crypto10 from "node:crypto";
34360
- import * as fs83 from "node:fs";
34361
- import * as path84 from "node:path";
34362
- import { fileURLToPath as fileURLToPath57, pathToFileURL as pathToFileURL49 } from "node:url";
34997
+ import * as fs87 from "node:fs";
34998
+ import * as path89 from "node:path";
34999
+ import { fileURLToPath as fileURLToPath60, pathToFileURL as pathToFileURL51 } from "node:url";
34363
35000
 
34364
35001
  // src/scripts/_lib/subagent_response.ts
34365
35002
  var MAX_SUMMARY_CHARS = 2e3;
@@ -34465,7 +35102,7 @@ var EXIT_ALLOW26 = 0;
34465
35102
  function isObject13(v) {
34466
35103
  return typeof v === "object" && v !== null && !Array.isArray(v);
34467
35104
  }
34468
- var LEDGER_DIR = path84.join("agents", "runtime", "state", "subagent-ledger");
35105
+ var LEDGER_DIR = path89.join("agents", "runtime", "state", "subagent-ledger");
34469
35106
  var OPEN_SUBDIR = "open";
34470
35107
  var OPEN_RECORD_TTL_MS = 24 * 60 * 60 * 1e3;
34471
35108
  function refFor(agentId) {
@@ -34555,10 +35192,10 @@ function _jsonObjectCandidates(message) {
34555
35192
  return out;
34556
35193
  }
34557
35194
  function openDir(root) {
34558
- return path84.join(root, LEDGER_DIR, OPEN_SUBDIR);
35195
+ return path89.join(root, LEDGER_DIR, OPEN_SUBDIR);
34559
35196
  }
34560
35197
  function openFile(root, ref) {
34561
- return path84.join(openDir(root), `${ref}.json`);
35198
+ return path89.join(openDir(root), `${ref}.json`);
34562
35199
  }
34563
35200
  var DEPTH_BASES = /* @__PURE__ */ new Set(["observed", "asserted-parent", "assumed-root"]);
34564
35201
  function _asOpenRecord(value, expectedRef) {
@@ -34585,7 +35222,7 @@ function readOpenRecords(root) {
34585
35222
  const out = /* @__PURE__ */ new Map();
34586
35223
  let names;
34587
35224
  try {
34588
- names = fs83.readdirSync(openDir(root));
35225
+ names = fs87.readdirSync(openDir(root));
34589
35226
  } catch {
34590
35227
  return out;
34591
35228
  }
@@ -34593,7 +35230,7 @@ function readOpenRecords(root) {
34593
35230
  if (!name.endsWith(".json")) continue;
34594
35231
  const expectedRef = name.slice(0, -".json".length);
34595
35232
  try {
34596
- const raw = fs83.readFileSync(path84.join(openDir(root), name), "utf8");
35233
+ const raw = fs87.readFileSync(path89.join(openDir(root), name), "utf8");
34597
35234
  const rec = _asOpenRecord(JSON.parse(raw), expectedRef);
34598
35235
  if (rec) out.set(rec.ref, rec);
34599
35236
  } catch {
@@ -34608,13 +35245,13 @@ function resolveDepth(parentRef, open) {
34608
35245
  return { depth: parent.depth + 1, depth_basis: "observed" };
34609
35246
  }
34610
35247
  function ledgerFileFor2(root, ts) {
34611
- return path84.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
35248
+ return path89.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
34612
35249
  }
34613
35250
  function appendLedgerLine(root, ts, line) {
34614
35251
  if (is_replay_mode()) return;
34615
35252
  const file = ledgerFileFor2(root, ts);
34616
- fs83.mkdirSync(path84.dirname(file), { recursive: true });
34617
- fs83.appendFileSync(file, `${JSON.stringify(line)}
35253
+ fs87.mkdirSync(path89.dirname(file), { recursive: true });
35254
+ fs87.appendFileSync(file, `${JSON.stringify(line)}
34618
35255
  `, "utf8");
34619
35256
  }
34620
35257
  var WALL_CLOCK_ARMS_MS = [
@@ -34628,7 +35265,7 @@ function armsExceeded(elapsedMs) {
34628
35265
  return WALL_CLOCK_ARMS_MS.filter((a) => elapsedMs >= a.ms).map((a) => a.label);
34629
35266
  }
34630
35267
  function openRecordStats(root, nowMs = Date.now()) {
34631
- const ledgerPresent = fs83.existsSync(path84.join(root, LEDGER_DIR));
35268
+ const ledgerPresent = fs87.existsSync(path89.join(root, LEDGER_DIR));
34632
35269
  const open = readOpenRecords(root);
34633
35270
  let maxDepth = 0;
34634
35271
  let counted = 0;
@@ -34656,13 +35293,13 @@ function writeOpenRecord(root, rec) {
34656
35293
  function removeOpenRecord(root, ref) {
34657
35294
  if (is_replay_mode()) return;
34658
35295
  try {
34659
- fs83.unlinkSync(openFile(root, ref));
35296
+ fs87.unlinkSync(openFile(root, ref));
34660
35297
  } catch {
34661
35298
  }
34662
35299
  }
34663
35300
  function countOpen(root) {
34664
35301
  try {
34665
- return fs83.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
35302
+ return fs87.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
34666
35303
  } catch {
34667
35304
  return 0;
34668
35305
  }
@@ -34813,7 +35450,7 @@ function resolveConsumerRoot(envelope) {
34813
35450
  }
34814
35451
  return process.cwd();
34815
35452
  }
34816
- function main55() {
35453
+ function main57() {
34817
35454
  const raw = readHookStdin();
34818
35455
  let envelope = {};
34819
35456
  try {
@@ -34823,20 +35460,20 @@ function main55() {
34823
35460
  }
34824
35461
  return processEnvelope3(envelope, resolveConsumerRoot(envelope));
34825
35462
  }
34826
- function _isCliEntry39() {
35463
+ function _isCliEntry41() {
34827
35464
  if (true) {
34828
35465
  return false;
34829
35466
  }
34830
35467
  if (process.argv[1] === void 0) return false;
34831
- const argvUrl = pathToFileURL49(path84.resolve(process.argv[1])).href;
35468
+ const argvUrl = pathToFileURL51(path89.resolve(process.argv[1])).href;
34832
35469
  if (import.meta.url === argvUrl) return true;
34833
35470
  try {
34834
- return fs83.realpathSync(fileURLToPath57(import.meta.url)) === fs83.realpathSync(path84.resolve(process.argv[1]));
35471
+ return fs87.realpathSync(fileURLToPath60(import.meta.url)) === fs87.realpathSync(path89.resolve(process.argv[1]));
34835
35472
  } catch {
34836
35473
  return false;
34837
35474
  }
34838
35475
  }
34839
- if (_isCliEntry39()) process.exit(main55());
35476
+ if (_isCliEntry41()) process.exit(main57());
34840
35477
 
34841
35478
  // src/scripts/hooks/turn_end_gate_hook.ts
34842
35479
  var EXIT_BLOCK3 = 1;
@@ -34945,7 +35582,7 @@ function detectPromissory(reply) {
34945
35582
  function readCiSettled(workspaceRoot3, session_id) {
34946
35583
  if (!hasStableSessionId(session_id)) return { seen: false, settled: false };
34947
35584
  try {
34948
- const raw = fs84.readFileSync(path85.join(workspaceRoot3, statePathFor(session_id)), "utf-8");
35585
+ const raw = fs88.readFileSync(path90.join(workspaceRoot3, statePathFor(session_id)), "utf-8");
34949
35586
  const decoded = JSON.parse(raw);
34950
35587
  if (!owns_session_state(decoded, session_id)) return { seen: false, settled: false };
34951
35588
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
@@ -34981,8 +35618,8 @@ function detectCompletionClaim(reply, ci) {
34981
35618
  function readLanguagePin(workspaceRoot3, session_id) {
34982
35619
  if (!hasStableSessionId(session_id)) return "und";
34983
35620
  try {
34984
- const raw = fs84.readFileSync(
34985
- path85.join(workspaceRoot3, statePathFor2(session_id)),
35621
+ const raw = fs88.readFileSync(
35622
+ path90.join(workspaceRoot3, statePathFor2(session_id)),
34986
35623
  "utf-8"
34987
35624
  );
34988
35625
  const decoded = JSON.parse(raw);
@@ -35033,12 +35670,37 @@ function detectUnverifiedEdit(toolCalls) {
35033
35670
  reason: "this turn changed a file and then ran no verification command \u2014 no test, type-check, lint or build call follows the last edit (verify-before-complete: a claim without a fresh run is unverified)"
35034
35671
  };
35035
35672
  }
35673
+ var _SOURCE_RE = /\.(?:ts|tsx|js|jsx|mjs|cjs|vue|svelte|php|py|rb|go|rs|java|kt|swift|cs|scala|ex|exs)$/i;
35674
+ var _TEST_PATH_RE = /(?:^|\/)(?:tests?|specs?|__tests__|__specs__|e2e|cypress|playwright|features)\//i;
35675
+ var _TEST_FILE_RE = /(?:\.(?:test|spec)\.[a-z]+$)|(?:_test\.[a-z]+$)|(?:(?:^|\/)test_[^/]+$)|(?:Test\.php$)|(?:Spec\.php$)|(?:\.feature$)/i;
35676
+ function _isTestPath(p) {
35677
+ return _TEST_PATH_RE.test(p) || _TEST_FILE_RE.test(p);
35678
+ }
35679
+ function _isProductionSource(p) {
35680
+ return _SOURCE_RE.test(p) && !_isTestPath(p);
35681
+ }
35682
+ function detectUntestedChange(reply, toolCalls) {
35683
+ const edited = toolCalls.filter((c) => _EDIT_TOOLS.has(c.name) && c.path !== void 0).map((c) => c.path);
35684
+ const source = edited.filter(_isProductionSource);
35685
+ if (source.length === 0) return null;
35686
+ if (edited.some(_isTestPath)) return null;
35687
+ const prose = visibleProse(reply);
35688
+ const m = _COMPLETION_RE.exec(prose);
35689
+ if (!m) return null;
35690
+ if (_NEGATED_CLAIM_RE.test(_lineAround(prose, m.index))) return null;
35691
+ const shown = source.slice(0, 3).join(", ");
35692
+ return {
35693
+ detector: "untested",
35694
+ evidence: shown + (source.length > 3 ? ` (+${String(source.length - 3)} more)` : ""),
35695
+ reason: "a completion claim over production code this turn changed, with NO test file touched anywhere in the turn \u2014 running a linter is not evidence the change works. Write the test that would have caught the failure, and enumerate the states the change actually has (every view, every CRUD path, the empty and error states) rather than the happy one. If a test genuinely does not belong here, say which file carries the coverage instead"
35696
+ };
35697
+ }
35036
35698
  function sessionStateFile2(workspaceRoot3, sessionKey) {
35037
35699
  return sessionRefusalFile(workspaceRoot3, sessionKey);
35038
35700
  }
35039
35701
  function alreadyRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal) {
35040
35702
  try {
35041
- const raw = fs84.readFileSync(sessionStateFile2(workspaceRoot3, sessionKey), "utf-8");
35703
+ const raw = fs88.readFileSync(sessionStateFile2(workspaceRoot3, sessionKey), "utf-8");
35042
35704
  const decoded = JSON.parse(raw);
35043
35705
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
35044
35706
  return decoded["refused_turn"] === turnOrdinal;
@@ -35047,12 +35709,12 @@ function alreadyRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal) {
35047
35709
  }
35048
35710
  return false;
35049
35711
  }
35050
- function markRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal, detectors) {
35712
+ function markRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal, detectors, promptId) {
35051
35713
  if (is_replay_mode()) return;
35052
35714
  const file = sessionStateFile2(workspaceRoot3, sessionKey);
35053
35715
  let prev = null;
35054
35716
  try {
35055
- prev = parseRecord(fs84.readFileSync(file, "utf-8"));
35717
+ prev = parseRecord(fs88.readFileSync(file, "utf-8"));
35056
35718
  } catch {
35057
35719
  }
35058
35720
  let version;
@@ -35068,27 +35730,34 @@ function markRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal, detectors) {
35068
35730
  detectors,
35069
35731
  turnOrdinal,
35070
35732
  at: (/* @__PURE__ */ new Date()).toISOString(),
35071
- version
35733
+ version,
35734
+ promptId
35072
35735
  })
35073
35736
  );
35074
35737
  } catch {
35075
35738
  }
35076
35739
  }
35077
35740
  function readTranscriptTail(transcriptPath, opts = {}) {
35078
- const empty = { lastAssistant: "", turnOrdinal: 0, toolCalls: [] };
35741
+ const empty = {
35742
+ lastAssistant: "",
35743
+ turnOrdinal: 0,
35744
+ toolCalls: [],
35745
+ assistantTurnTexts: []
35746
+ };
35079
35747
  if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
35080
35748
  let lines;
35081
35749
  try {
35082
- if (opts.maxBytes !== void 0 && fs84.statSync(transcriptPath).size > opts.maxBytes) {
35750
+ if (opts.maxBytes !== void 0 && fs88.statSync(transcriptPath).size > opts.maxBytes) {
35083
35751
  return empty;
35084
35752
  }
35085
- lines = fs84.readFileSync(transcriptPath, "utf-8").split("\n");
35753
+ lines = fs88.readFileSync(transcriptPath, "utf-8").split("\n");
35086
35754
  } catch {
35087
35755
  return empty;
35088
35756
  }
35089
35757
  let lastAssistant = "";
35090
35758
  let turnOrdinal = 0;
35091
35759
  let toolCalls = [];
35760
+ let assistantTurnTexts = [];
35092
35761
  for (const rawLine of lines) {
35093
35762
  const line = rawLine.trim();
35094
35763
  if (!line) continue;
@@ -35107,20 +35776,27 @@ function readTranscriptTail(transcriptPath, opts = {}) {
35107
35776
  if (typeof msg !== "object" || msg === null || Array.isArray(msg)) continue;
35108
35777
  const content = msg["content"];
35109
35778
  if (role === "assistant") {
35110
- toolCalls.push(..._toolCalls(content));
35779
+ toolCalls.push(...extractToolCalls(content));
35111
35780
  }
35112
35781
  const text = _messageText(content);
35113
35782
  if (text === null) continue;
35114
35783
  if (role === "assistant") {
35115
35784
  lastAssistant = text;
35785
+ assistantTurnTexts.push(text);
35116
35786
  } else if (!isSyntheticPrompt(text)) {
35117
35787
  turnOrdinal += 1;
35118
35788
  toolCalls = [];
35789
+ assistantTurnTexts = [];
35119
35790
  }
35120
35791
  }
35121
- return { lastAssistant: lastAssistant.trim(), turnOrdinal, toolCalls };
35792
+ return {
35793
+ lastAssistant: lastAssistant.trim(),
35794
+ turnOrdinal,
35795
+ toolCalls,
35796
+ assistantTurnTexts
35797
+ };
35122
35798
  }
35123
- function _toolCalls(content) {
35799
+ function extractToolCalls(content) {
35124
35800
  if (!Array.isArray(content)) return [];
35125
35801
  const out = [];
35126
35802
  for (const blk of content) {
@@ -35158,7 +35834,7 @@ function _messageText(content) {
35158
35834
  function str8(v) {
35159
35835
  return typeof v === "string" ? v : "";
35160
35836
  }
35161
- function main56() {
35837
+ function main58() {
35162
35838
  let envelope;
35163
35839
  let payload;
35164
35840
  try {
@@ -35176,10 +35852,19 @@ function main56() {
35176
35852
  const transcriptPath = str8(
35177
35853
  payload["transcript_path"] ?? payload["transcriptPath"]
35178
35854
  );
35179
- const { lastAssistant, turnOrdinal, toolCalls } = readTranscriptTail(transcriptPath, {
35180
- maxBytes: TRANSCRIPT_READ_MAX_BYTES
35181
- });
35855
+ const { lastAssistant, turnOrdinal, toolCalls, assistantTurnTexts } = readTranscriptTail(
35856
+ transcriptPath,
35857
+ { maxBytes: TRANSCRIPT_READ_MAX_BYTES }
35858
+ );
35182
35859
  if (!lastAssistant) return EXIT_ALLOW27;
35860
+ const payloadClosing = str8(
35861
+ payload["last_assistant_message"] ?? payload["lastAssistantMessage"]
35862
+ );
35863
+ const closingFromPayload = payloadClosing !== "" && !assistantTurnTexts.includes(payloadClosing);
35864
+ const turnTexts = closingFromPayload ? [...assistantTurnTexts, payloadClosing] : assistantTurnTexts;
35865
+ const promptId = str8(
35866
+ payload["prompt_id"] ?? payload["promptId"]
35867
+ );
35183
35868
  const rawSessionId = str8(envelope["session_id"]) || "";
35184
35869
  const sessionKey = deriveSessionKey(rawSessionId || "unknown-session");
35185
35870
  if (alreadyRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal)) return EXIT_ALLOW27;
@@ -35201,7 +35886,23 @@ function main56() {
35201
35886
  // gating is where the comment above says gating belongs — inside the
35202
35887
  // detector: no CI observed, or a settled read, or no completion claim
35203
35888
  // ⇒ no finding.
35204
- dispatchOpen ? null : detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot3, rawSessionId))
35889
+ dispatchOpen ? null : detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot3, rawSessionId)),
35890
+ // Detector E is UNCONDITIONAL, and that is the opposite choice from A
35891
+ // and D one line above rather than an oversight. An open dispatch
35892
+ // excuses a promissory closing because the work is genuinely still
35893
+ // running; it excuses nothing about a question the user was already
35894
+ // asked. Worse: a dispatch — or the `end-review-nudge` stop concern
35895
+ // that produced the measured failure — IS the continuation that drops
35896
+ // the decision, so narrowing E the same way would silence it in exactly
35897
+ // the case it exists for.
35898
+ detectDroppedDecision(turnTexts, closingFromPayload),
35899
+ // Detector F takes the OTHER side of that same question, and the two
35900
+ // sitting adjacent is the clearest place to say why. E fires on a
35901
+ // question already asked, which an open dispatch cannot excuse. F fires
35902
+ // on a completion CLAIM, and a turn waiting on a subagent has not
35903
+ // finished — so its closing is not the claim F is about. Same slot,
35904
+ // opposite trigger, opposite treatment of `dispatchOpen`.
35905
+ dispatchOpen ? null : detectUntestedChange(lastAssistant, toolCalls)
35205
35906
  ]) {
35206
35907
  if (f) findings.push(f);
35207
35908
  }
@@ -35210,7 +35911,8 @@ function main56() {
35210
35911
  workspaceRoot3,
35211
35912
  sessionKey,
35212
35913
  turnOrdinal,
35213
- findings.map((f) => f.detector)
35914
+ findings.map((f) => f.detector),
35915
+ promptId
35214
35916
  );
35215
35917
  const lines = findings.map(
35216
35918
  (f) => ` \xB7 ${f.detector}: ${f.reason}
@@ -35219,41 +35921,41 @@ function main56() {
35219
35921
  process.stderr.write(
35220
35922
  `turn-end-gate: REFUSED \u2014 this turn is not finished.
35221
35923
  ${lines.join("\n")}
35222
- Do the promised work now, correct the language, run the verification the edit needs, or read the CI verdict before claiming it \u2014 then end the turn.
35924
+ Do the promised work now, correct the language, run the verification the edit needs, read the CI verdict before claiming it, or re-present the options block this turn dropped \u2014 then end the turn.
35223
35925
  This turn will not be refused a second time.
35224
35926
  `
35225
35927
  );
35226
35928
  return EXIT_BLOCK3;
35227
35929
  }
35228
- function _isCliEntry40() {
35930
+ function _isCliEntry42() {
35229
35931
  if (true) {
35230
35932
  return false;
35231
35933
  }
35232
35934
  if (process.argv[1] === void 0) {
35233
35935
  return false;
35234
35936
  }
35235
- const argvUrl = pathToFileURL50(path85.resolve(process.argv[1])).href;
35937
+ const argvUrl = pathToFileURL52(path90.resolve(process.argv[1])).href;
35236
35938
  if (import.meta.url === argvUrl) {
35237
35939
  return true;
35238
35940
  }
35239
35941
  try {
35240
- const here = fs84.realpathSync(fileURLToPath58(import.meta.url));
35241
- const argv = fs84.realpathSync(path85.resolve(process.argv[1]));
35942
+ const here = fs88.realpathSync(fileURLToPath61(import.meta.url));
35943
+ const argv = fs88.realpathSync(path90.resolve(process.argv[1]));
35242
35944
  return here === argv;
35243
35945
  } catch {
35244
35946
  return false;
35245
35947
  }
35246
35948
  }
35247
- if (_isCliEntry40()) {
35248
- process.exit(main56());
35949
+ if (_isCliEntry42()) {
35950
+ process.exit(main58());
35249
35951
  }
35250
35952
 
35251
35953
  // src/scripts/hooks/edit_shape_hook.ts
35252
- import { spawnSync as spawnSync7 } from "node:child_process";
35954
+ import { spawnSync as spawnSync8 } from "node:child_process";
35253
35955
  import * as crypto11 from "node:crypto";
35254
- import * as fs85 from "node:fs";
35255
- import * as path86 from "node:path";
35256
- import { fileURLToPath as fileURLToPath59, pathToFileURL as pathToFileURL51 } from "node:url";
35956
+ import * as fs89 from "node:fs";
35957
+ import * as path91 from "node:path";
35958
+ import { fileURLToPath as fileURLToPath62, pathToFileURL as pathToFileURL53 } from "node:url";
35257
35959
  var EXIT_ALLOW28 = 0;
35258
35960
  var EXIT_WARN16 = 2;
35259
35961
  var MIN_FILE_LINES = 50;
@@ -35293,7 +35995,7 @@ function parseNumstatLines(raw) {
35293
35995
  }
35294
35996
  function effectiveDiffLines(cwd, relPath) {
35295
35997
  try {
35296
- const r = spawnSync7("git", ["diff", "HEAD", "--numstat", "--", relPath], {
35998
+ const r = spawnSync8("git", ["diff", "HEAD", "--numstat", "--", relPath], {
35297
35999
  cwd,
35298
36000
  encoding: "utf8",
35299
36001
  maxBuffer: 16 * 1024 * 1024
@@ -35306,7 +36008,7 @@ function effectiveDiffLines(cwd, relPath) {
35306
36008
  }
35307
36009
  function fileLineCount(absPath) {
35308
36010
  try {
35309
- const text = fs85.readFileSync(absPath, "utf8");
36011
+ const text = fs89.readFileSync(absPath, "utf8");
35310
36012
  if (text.length === 0) return 0;
35311
36013
  return text.split("\n").length - (text.endsWith("\n") ? 1 : 0);
35312
36014
  } catch {
@@ -35323,11 +36025,11 @@ function deriveSessionKey3(envelope, payload) {
35323
36025
  return crypto11.createHash("sha256").update(material).digest("hex");
35324
36026
  }
35325
36027
  function sessionStateFile3(workspaceRoot3, sessionKey) {
35326
- return path86.join(workspaceRoot3, "agents", "runtime", "state", "edit-shape", `${sessionKey}.json`);
36028
+ return path91.join(workspaceRoot3, "agents", "runtime", "state", "edit-shape", `${sessionKey}.json`);
35327
36029
  }
35328
36030
  function hasFiredThisSession2(workspaceRoot3, sessionKey) {
35329
36031
  try {
35330
- return fs85.existsSync(sessionStateFile3(workspaceRoot3, sessionKey));
36032
+ return fs89.existsSync(sessionStateFile3(workspaceRoot3, sessionKey));
35331
36033
  } catch {
35332
36034
  return false;
35333
36035
  }
@@ -35348,7 +36050,7 @@ function extractFilePath2(payload) {
35348
36050
  if (!isObject14(ti)) return "";
35349
36051
  return str9(ti["file_path"] ?? ti["path"] ?? ti["filePath"]);
35350
36052
  }
35351
- function main57() {
36053
+ function main59() {
35352
36054
  try {
35353
36055
  const [envelope, payload] = unwrap(readHookStdin(), "claude");
35354
36056
  const event = str9(envelope["event"]);
@@ -35358,8 +36060,8 @@ function main57() {
35358
36060
  const filePath = extractFilePath2(payload);
35359
36061
  if (!filePath) return EXIT_ALLOW28;
35360
36062
  const workspaceRoot3 = str9(envelope["workspace_root"]).trim() || process.cwd();
35361
- const absPath = path86.isAbsolute(filePath) ? filePath : path86.resolve(workspaceRoot3, filePath);
35362
- const relPath = path86.relative(workspaceRoot3, absPath);
36063
+ const absPath = path91.isAbsolute(filePath) ? filePath : path91.resolve(workspaceRoot3, filePath);
36064
+ const relPath = path91.relative(workspaceRoot3, absPath);
35363
36065
  if (isExemptPath(relPath) || isExemptPath(absPath)) return EXIT_ALLOW28;
35364
36066
  const fileLines = fileLineCount(absPath);
35365
36067
  if (fileLines < MIN_FILE_LINES) return EXIT_ALLOW28;
@@ -35382,54 +36084,54 @@ function main57() {
35382
36084
  return EXIT_ALLOW28;
35383
36085
  }
35384
36086
  }
35385
- function _isCliEntry41() {
36087
+ function _isCliEntry43() {
35386
36088
  if (true) {
35387
36089
  return false;
35388
36090
  }
35389
36091
  if (process.argv[1] === void 0) {
35390
36092
  return false;
35391
36093
  }
35392
- const argvUrl = pathToFileURL51(path86.resolve(process.argv[1])).href;
36094
+ const argvUrl = pathToFileURL53(path91.resolve(process.argv[1])).href;
35393
36095
  if (import.meta.url === argvUrl) {
35394
36096
  return true;
35395
36097
  }
35396
36098
  try {
35397
- const here = fs85.realpathSync(fileURLToPath59(import.meta.url));
35398
- const argv = fs85.realpathSync(path86.resolve(process.argv[1]));
36099
+ const here = fs89.realpathSync(fileURLToPath62(import.meta.url));
36100
+ const argv = fs89.realpathSync(path91.resolve(process.argv[1]));
35399
36101
  return here === argv;
35400
36102
  } catch {
35401
36103
  return false;
35402
36104
  }
35403
36105
  }
35404
- if (_isCliEntry41()) {
35405
- process.exit(main57());
36106
+ if (_isCliEntry43()) {
36107
+ process.exit(main59());
35406
36108
  }
35407
36109
 
35408
36110
  // src/scripts/hooks/comment_discipline_hook.ts
35409
- import * as fs87 from "node:fs";
35410
- import * as path89 from "node:path";
35411
- import { fileURLToPath as fileURLToPath61, pathToFileURL as pathToFileURL52 } from "node:url";
36111
+ import * as fs91 from "node:fs";
36112
+ import * as path94 from "node:path";
36113
+ import { fileURLToPath as fileURLToPath64, pathToFileURL as pathToFileURL54 } from "node:url";
35412
36114
 
35413
36115
  // src/scripts/lint_code_comments.ts
35414
- import { spawnSync as spawnSync9 } from "node:child_process";
35415
- import * as fs86 from "node:fs";
36116
+ import { spawnSync as spawnSync10 } from "node:child_process";
36117
+ import * as fs90 from "node:fs";
35416
36118
  import * as os12 from "node:os";
35417
- import * as path88 from "node:path";
36119
+ import * as path93 from "node:path";
35418
36120
  import process15 from "node:process";
35419
- import { fileURLToPath as fileURLToPath60 } from "node:url";
36121
+ import { fileURLToPath as fileURLToPath63 } from "node:url";
35420
36122
 
35421
36123
  // src/scripts/_lib/gate_self_test.ts
35422
- import { spawnSync as spawnSync8 } from "node:child_process";
35423
- import * as path87 from "node:path";
36124
+ import { spawnSync as spawnSync9 } from "node:child_process";
36125
+ import * as path92 from "node:path";
35424
36126
  import process14 from "node:process";
35425
36127
  function runGateCli(repoRoot, scriptRelPath, args, cwd) {
35426
- const tsx = path87.join(
36128
+ const tsx = path92.join(
35427
36129
  repoRoot,
35428
36130
  "node_modules",
35429
36131
  ".bin",
35430
36132
  process14.platform === "win32" ? "tsx.cmd" : "tsx"
35431
36133
  );
35432
- const res = spawnSync8(tsx, [path87.join(repoRoot, scriptRelPath), ...args], {
36134
+ const res = spawnSync9(tsx, [path92.join(repoRoot, scriptRelPath), ...args], {
35433
36135
  cwd,
35434
36136
  encoding: "utf-8",
35435
36137
  maxBuffer: 64 * 1024 * 1024,
@@ -35481,7 +36183,7 @@ ${opts.gate} --self-test: ${String(opts.cases.length - failed)}/${String(opts.ca
35481
36183
  }
35482
36184
 
35483
36185
  // src/scripts/lint_code_comments.ts
35484
- var _HERE11 = fileURLToPath60(import.meta.url);
36186
+ var _HERE13 = fileURLToPath63(import.meta.url);
35485
36187
  var SCANNED_EXTENSIONS = /* @__PURE__ */ new Set([
35486
36188
  ".ts",
35487
36189
  ".tsx",
@@ -35741,20 +36443,20 @@ function scanText2(file, text) {
35741
36443
  function isScannable(rel) {
35742
36444
  if (SKIP_SEGMENTS.some((s) => rel.includes(s))) return false;
35743
36445
  if (rel.endsWith(".d.ts")) return false;
35744
- return SCANNED_EXTENSIONS.has(path88.extname(rel));
36446
+ return SCANNED_EXTENSIONS.has(path93.extname(rel));
35745
36447
  }
35746
36448
  function changedFiles(root, base) {
35747
- const r = spawnSync9("git", ["diff", "--name-only", "--diff-filter=ACMR", `${base}...HEAD`], {
36449
+ const r = spawnSync10("git", ["diff", "--name-only", "--diff-filter=ACMR", `${base}...HEAD`], {
35748
36450
  cwd: root,
35749
36451
  encoding: "utf-8"
35750
36452
  });
35751
36453
  const tracked = r.status === 0 ? r.stdout.split("\n") : [];
35752
- const u = spawnSync9("git", ["ls-files", "--others", "--exclude-standard"], {
36454
+ const u = spawnSync10("git", ["ls-files", "--others", "--exclude-standard"], {
35753
36455
  cwd: root,
35754
36456
  encoding: "utf-8"
35755
36457
  });
35756
36458
  const untracked = u.status === 0 ? u.stdout.split("\n") : [];
35757
- const m = spawnSync9("git", ["diff", "--name-only", "--diff-filter=ACMR"], {
36459
+ const m = spawnSync10("git", ["diff", "--name-only", "--diff-filter=ACMR"], {
35758
36460
  cwd: root,
35759
36461
  encoding: "utf-8"
35760
36462
  });
@@ -35763,7 +36465,7 @@ function changedFiles(root, base) {
35763
36465
  }
35764
36466
  function addedLineMap(root, base) {
35765
36467
  const out = /* @__PURE__ */ new Map();
35766
- const u = spawnSync9("git", ["ls-files", "--others", "--exclude-standard"], {
36468
+ const u = spawnSync10("git", ["ls-files", "--others", "--exclude-standard"], {
35767
36469
  cwd: root,
35768
36470
  encoding: "utf-8"
35769
36471
  });
@@ -35776,7 +36478,7 @@ function addedLineMap(root, base) {
35776
36478
  ["diff", "--unified=0", "--diff-filter=ACMR", `${base}...HEAD`],
35777
36479
  ["diff", "--unified=0", "--diff-filter=ACMR"]
35778
36480
  ]) {
35779
- const r = spawnSync9("git", argv, { cwd: root, encoding: "utf-8" });
36481
+ const r = spawnSync10("git", argv, { cwd: root, encoding: "utf-8" });
35780
36482
  if (r.status !== 0) continue;
35781
36483
  mergeAddedLines(out, parseAddedLines(r.stdout));
35782
36484
  }
@@ -35919,11 +36621,11 @@ var COMMENT_CASES = [
35919
36621
  }
35920
36622
  ];
35921
36623
  function selfTest2() {
35922
- const repoRoot = path88.resolve(path88.dirname(_HERE11), "..", "..");
35923
- const dir = fs86.mkdtempSync(path88.join(os12.tmpdir(), "lcc-selftest-"));
36624
+ const repoRoot = path93.resolve(path93.dirname(_HERE13), "..", "..");
36625
+ const dir = fs90.mkdtempSync(path93.join(os12.tmpdir(), "lcc-selftest-"));
35924
36626
  const exercise = (testCase, index) => {
35925
- const file = path88.join(dir, `case-${String(index)}.ts`);
35926
- fs86.writeFileSync(file, testCase.source, "utf-8");
36627
+ const file = path93.join(dir, `case-${String(index)}.ts`);
36628
+ fs90.writeFileSync(file, testCase.source, "utf-8");
35927
36629
  return runGateCli(repoRoot, "src/scripts/lint_code_comments.ts", ["--paths", file], dir);
35928
36630
  };
35929
36631
  try {
@@ -35938,7 +36640,7 @@ function selfTest2() {
35938
36640
  }))
35939
36641
  });
35940
36642
  } finally {
35941
- fs86.rmSync(dir, { recursive: true, force: true });
36643
+ fs90.rmSync(dir, { recursive: true, force: true });
35942
36644
  }
35943
36645
  }
35944
36646
  var HELP = `usage: lint_code_comments [--base <ref>] [--root <dir>] [--paths <f> \u2026] [--report]
@@ -35953,7 +36655,7 @@ Classes: de-comment \xB7 report-comment \xB7 provenance-comment
35953
36655
  Escape: code-comment-allow <class|*> -- <reason> (per line)
35954
36656
  code-comment-allow-file -- <reason> (first 2000 chars)
35955
36657
  `;
35956
- function main58(argv) {
36658
+ function main60(argv) {
35957
36659
  if (argv.includes("--help") || argv.includes("-h")) {
35958
36660
  process15.stdout.write(HELP);
35959
36661
  return 0;
@@ -35966,7 +36668,7 @@ function main58(argv) {
35966
36668
  return selfTest2();
35967
36669
  }
35968
36670
  let base = "origin/main";
35969
- let root = path88.resolve(path88.dirname(_HERE11), "..", "..");
36671
+ let root = path93.resolve(path93.dirname(_HERE13), "..", "..");
35970
36672
  let reportOnly = false;
35971
36673
  const explicit = [];
35972
36674
  for (let i = 0; i < argv.length; i++) {
@@ -35977,7 +36679,7 @@ function main58(argv) {
35977
36679
  } else if (a === "--base") {
35978
36680
  base = argv[++i] ?? "";
35979
36681
  } else if (a === "--root") {
35980
- root = path88.resolve(argv[++i] ?? ".");
36682
+ root = path93.resolve(argv[++i] ?? ".");
35981
36683
  } else if (a === "--report") {
35982
36684
  reportOnly = true;
35983
36685
  } else if (a === "--paths") {
@@ -35996,10 +36698,10 @@ ${HELP}`);
35996
36698
  const added = explicit.length > 0 ? null : addedLineMap(root, base);
35997
36699
  const findings = [];
35998
36700
  for (const rel of candidates) {
35999
- const abs = path88.isAbsolute(rel) ? rel : path88.join(root, rel);
36701
+ const abs = path93.isAbsolute(rel) ? rel : path93.join(root, rel);
36000
36702
  let text;
36001
36703
  try {
36002
- text = fs86.readFileSync(abs, "utf-8");
36704
+ text = fs90.readFileSync(abs, "utf-8");
36003
36705
  } catch {
36004
36706
  continue;
36005
36707
  }
@@ -36060,12 +36762,12 @@ var _isMain6 = (() => {
36060
36762
  const entry = process15.argv[1];
36061
36763
  if (!entry) return false;
36062
36764
  try {
36063
- return fs86.realpathSync(entry) === fs86.realpathSync(_HERE11);
36765
+ return fs90.realpathSync(entry) === fs90.realpathSync(_HERE13);
36064
36766
  } catch {
36065
36767
  return false;
36066
36768
  }
36067
36769
  })();
36068
- if (_isMain6) process15.exit(main58(process15.argv.slice(2)));
36770
+ if (_isMain6) process15.exit(main60(process15.argv.slice(2)));
36069
36771
 
36070
36772
  // src/scripts/hooks/comment_discipline_hook.ts
36071
36773
  var EXIT_ALLOW29 = 0;
@@ -36092,7 +36794,7 @@ function buildAdvisoryLine3(file, findings) {
36092
36794
  const more = findings.length > MAX_REPORTED ? `, +${findings.length - MAX_REPORTED} more` : "";
36093
36795
  return `comment-discipline: the text just written to ${file} carries ${summary} \u2014 ${named}${more}. A comment states a WHY or a constraint the code cannot show, in English; evidence for a roadmap step belongs in that roadmap, not in a second copy in the source. Rewrite or delete those lines now, before the next write \u2014 \`lint_code_comments\` refuses them at the gate.`;
36094
36796
  }
36095
- function main59() {
36797
+ function main61() {
36096
36798
  try {
36097
36799
  const [envelope, payload] = unwrap(readHookStdin(), "claude");
36098
36800
  const event = str10(envelope["event"]);
@@ -36108,9 +36810,9 @@ function main59() {
36108
36810
  const text = writtenText(toolName2, ti);
36109
36811
  if (!text) return EXIT_ALLOW29;
36110
36812
  const workspaceRoot3 = str10(envelope["workspace_root"]).trim() || process.cwd();
36111
- const abs = path89.isAbsolute(filePath) ? filePath : path89.resolve(workspaceRoot3, filePath);
36112
- const rel = path89.relative(workspaceRoot3, abs);
36113
- const shown = rel.startsWith("..") ? path89.basename(abs) : rel;
36813
+ const abs = path94.isAbsolute(filePath) ? filePath : path94.resolve(workspaceRoot3, filePath);
36814
+ const rel = path94.relative(workspaceRoot3, abs);
36815
+ const shown = rel.startsWith("..") ? path94.basename(abs) : rel;
36114
36816
  const findings = scanText2(shown, text);
36115
36817
  if (findings.length === 0) return EXIT_ALLOW29;
36116
36818
  process.stdout.write(
@@ -36126,24 +36828,24 @@ function main59() {
36126
36828
  return EXIT_ALLOW29;
36127
36829
  }
36128
36830
  }
36129
- function _isCliEntry42() {
36831
+ function _isCliEntry44() {
36130
36832
  if (true) return false;
36131
36833
  if (process.argv[1] === void 0) return false;
36132
- const argvUrl = pathToFileURL52(path89.resolve(process.argv[1])).href;
36834
+ const argvUrl = pathToFileURL54(path94.resolve(process.argv[1])).href;
36133
36835
  if (import.meta.url === argvUrl) return true;
36134
36836
  try {
36135
- return fs87.realpathSync(fileURLToPath61(import.meta.url)) === fs87.realpathSync(path89.resolve(process.argv[1]));
36837
+ return fs91.realpathSync(fileURLToPath64(import.meta.url)) === fs91.realpathSync(path94.resolve(process.argv[1]));
36136
36838
  } catch {
36137
36839
  return false;
36138
36840
  }
36139
36841
  }
36140
- if (_isCliEntry42()) process.exit(main59());
36842
+ if (_isCliEntry44()) process.exit(main61());
36141
36843
 
36142
36844
  // src/scripts/hooks/reread_guard_hook.ts
36143
36845
  import * as crypto12 from "node:crypto";
36144
- import * as fs88 from "node:fs";
36145
- import * as path90 from "node:path";
36146
- import { fileURLToPath as fileURLToPath62, pathToFileURL as pathToFileURL53 } from "node:url";
36846
+ import * as fs92 from "node:fs";
36847
+ import * as path95 from "node:path";
36848
+ import { fileURLToPath as fileURLToPath65, pathToFileURL as pathToFileURL55 } from "node:url";
36147
36849
  var EXIT_ALLOW30 = 0;
36148
36850
  var EXIT_WARN18 = 2;
36149
36851
  var EXEMPT_PATH_PATTERNS2 = [
@@ -36179,11 +36881,11 @@ function deriveSessionKey4(envelope, payload) {
36179
36881
  return crypto12.createHash("sha256").update(material).digest("hex");
36180
36882
  }
36181
36883
  function ledgerFile(workspaceRoot3, sessionKey) {
36182
- return path90.join(workspaceRoot3, "agents", "runtime", "state", "reread-guard", `${sessionKey}.json`);
36884
+ return path95.join(workspaceRoot3, "agents", "runtime", "state", "reread-guard", `${sessionKey}.json`);
36183
36885
  }
36184
36886
  function readLedger(workspaceRoot3, sessionKey) {
36185
36887
  try {
36186
- const parsed = JSON.parse(fs88.readFileSync(ledgerFile(workspaceRoot3, sessionKey), "utf8"));
36888
+ const parsed = JSON.parse(fs92.readFileSync(ledgerFile(workspaceRoot3, sessionKey), "utf8"));
36187
36889
  if (!isObject16(parsed)) return emptyLedger();
36188
36890
  return {
36189
36891
  reads: isObject16(parsed["reads"]) ? parsed["reads"] : {},
@@ -36224,7 +36926,7 @@ function buildDuplicateReadLine(relPath, earlierTs) {
36224
36926
  function buildPostEditReadLine(relPath) {
36225
36927
  return `re-read guard: this session just edited ${relPath} \u2014 a full-file re-read re-pays for content you already have; a ranged Read (offset/limit) over the edited hunk is enough to verify the change.`;
36226
36928
  }
36227
- function main60() {
36929
+ function main62() {
36228
36930
  try {
36229
36931
  const [envelope, payload] = unwrap(readHookStdin(), "claude");
36230
36932
  const event = str11(envelope["event"]);
@@ -36237,8 +36939,8 @@ function main60() {
36237
36939
  const filePath = extractFilePath3(toolInput);
36238
36940
  if (!filePath) return EXIT_ALLOW30;
36239
36941
  const workspaceRoot3 = str11(envelope["workspace_root"]).trim() || process.cwd();
36240
- const absPath = path90.isAbsolute(filePath) ? filePath : path90.resolve(workspaceRoot3, filePath);
36241
- const relPath = path90.relative(workspaceRoot3, absPath);
36942
+ const absPath = path95.isAbsolute(filePath) ? filePath : path95.resolve(workspaceRoot3, filePath);
36943
+ const relPath = path95.relative(workspaceRoot3, absPath);
36242
36944
  if (isExemptPath2(relPath) || isExemptPath2(absPath)) return EXIT_ALLOW30;
36243
36945
  const sessionKey = deriveSessionKey4(envelope, payload);
36244
36946
  const ledger = readLedger(workspaceRoot3, sessionKey);
@@ -36254,7 +36956,7 @@ function main60() {
36254
36956
  let mtime;
36255
36957
  let size;
36256
36958
  try {
36257
- const st = fs88.statSync(absPath);
36959
+ const st = fs92.statSync(absPath);
36258
36960
  mtime = st.mtimeMs;
36259
36961
  size = st.size;
36260
36962
  } catch {
@@ -36287,34 +36989,34 @@ function main60() {
36287
36989
  return EXIT_ALLOW30;
36288
36990
  }
36289
36991
  }
36290
- function _isCliEntry43() {
36992
+ function _isCliEntry45() {
36291
36993
  if (true) {
36292
36994
  return false;
36293
36995
  }
36294
36996
  if (process.argv[1] === void 0) {
36295
36997
  return false;
36296
36998
  }
36297
- const argvUrl = pathToFileURL53(path90.resolve(process.argv[1])).href;
36999
+ const argvUrl = pathToFileURL55(path95.resolve(process.argv[1])).href;
36298
37000
  if (import.meta.url === argvUrl) {
36299
37001
  return true;
36300
37002
  }
36301
37003
  try {
36302
- const here = fs88.realpathSync(fileURLToPath62(import.meta.url));
36303
- const argv = fs88.realpathSync(path90.resolve(process.argv[1]));
37004
+ const here = fs92.realpathSync(fileURLToPath65(import.meta.url));
37005
+ const argv = fs92.realpathSync(path95.resolve(process.argv[1]));
36304
37006
  return here === argv;
36305
37007
  } catch {
36306
37008
  return false;
36307
37009
  }
36308
37010
  }
36309
- if (_isCliEntry43()) {
36310
- process.exit(main60());
37011
+ if (_isCliEntry45()) {
37012
+ process.exit(main62());
36311
37013
  }
36312
37014
 
36313
37015
  // src/scripts/hooks/session_eol_hook.ts
36314
- import * as fs95 from "node:fs";
36315
- import * as path97 from "node:path";
37016
+ import * as fs99 from "node:fs";
37017
+ import * as path102 from "node:path";
36316
37018
  import process16 from "node:process";
36317
- import { fileURLToPath as fileURLToPath63, pathToFileURL as pathToFileURL54 } from "node:url";
37019
+ import { fileURLToPath as fileURLToPath66, pathToFileURL as pathToFileURL56 } from "node:url";
36318
37020
 
36319
37021
  // src/config/recycle-threshold-budget.json
36320
37022
  var recycle_threshold_budget_default = {
@@ -36332,13 +37034,13 @@ var recycle_threshold_budget_default = {
36332
37034
 
36333
37035
  // src/scripts/_lib/session_eol.ts
36334
37036
  import * as crypto13 from "node:crypto";
36335
- import * as fs89 from "node:fs";
36336
- import * as path92 from "node:path";
37037
+ import * as fs93 from "node:fs";
37038
+ import * as path97 from "node:path";
36337
37039
 
36338
37040
  // src/scripts/_lib/cc_transcript.ts
36339
- import * as path91 from "node:path";
37041
+ import * as path96 from "node:path";
36340
37042
  import { homedir as homedir8 } from "node:os";
36341
- var DEFAULT_PROJECTS_ROOT = path91.join(homedir8(), ".claude", "projects");
37043
+ var DEFAULT_PROJECTS_ROOT = path96.join(homedir8(), ".claude", "projects");
36342
37044
  function billableInputTokens(u) {
36343
37045
  return u.input_tokens + u.cache_read_input_tokens + u.cache_creation_input_tokens;
36344
37046
  }
@@ -36447,10 +37149,10 @@ function scanEolSlice(text, prior) {
36447
37149
  return next;
36448
37150
  }
36449
37151
  function eolStateDir(workspaceRoot3) {
36450
- return path92.join(workspaceRoot3, "agents", "runtime", "state", "session-eol");
37152
+ return path97.join(workspaceRoot3, "agents", "runtime", "state", "session-eol");
36451
37153
  }
36452
37154
  function eolStateFile(workspaceRoot3, sessionKey) {
36453
- return path92.join(eolStateDir(workspaceRoot3), `${sessionKey}.json`);
37155
+ return path97.join(eolStateDir(workspaceRoot3), `${sessionKey}.json`);
36454
37156
  }
36455
37157
  function eolSessionKey(raw) {
36456
37158
  return crypto13.createHash("sha256").update(raw || "unknown-session").digest("hex");
@@ -36467,7 +37169,7 @@ function is_substantive(counters) {
36467
37169
  }
36468
37170
  function readNewCompleteLines(filePath, fromByte) {
36469
37171
  try {
36470
- const { size } = fs89.statSync(filePath);
37172
+ const { size } = fs93.statSync(filePath);
36471
37173
  if (size < fromByte) {
36472
37174
  return { text: "", nextOffset: 0, truncated: true };
36473
37175
  }
@@ -36476,11 +37178,11 @@ function readNewCompleteLines(filePath, fromByte) {
36476
37178
  }
36477
37179
  const length = size - fromByte;
36478
37180
  const buffer = Buffer.alloc(length);
36479
- const fd = fs89.openSync(filePath, "r");
37181
+ const fd = fs93.openSync(filePath, "r");
36480
37182
  try {
36481
- fs89.readSync(fd, buffer, 0, length, fromByte);
37183
+ fs93.readSync(fd, buffer, 0, length, fromByte);
36482
37184
  } finally {
36483
- fs89.closeSync(fd);
37185
+ fs93.closeSync(fd);
36484
37186
  }
36485
37187
  const lastNewline = buffer.lastIndexOf(10);
36486
37188
  if (lastNewline === -1) {
@@ -36497,23 +37199,23 @@ function readNewCompleteLines(filePath, fromByte) {
36497
37199
  }
36498
37200
 
36499
37201
  // src/scripts/_lib/context_observation.ts
36500
- import * as fs91 from "node:fs";
36501
- import * as path94 from "node:path";
37202
+ import * as fs95 from "node:fs";
37203
+ import * as path99 from "node:path";
36502
37204
 
36503
37205
  // src/scripts/_lib/loop_guards.ts
36504
- import * as fs90 from "node:fs";
36505
- import * as path93 from "node:path";
37206
+ import * as fs94 from "node:fs";
37207
+ import * as path98 from "node:path";
36506
37208
  function atomicWriteJson(file, value) {
36507
37209
  const tmp = `${file}.${String(process.pid)}.tmp`;
36508
37210
  try {
36509
- fs90.mkdirSync(path93.dirname(file), { recursive: true });
36510
- fs90.writeFileSync(tmp, `${JSON.stringify(value)}
37211
+ fs94.mkdirSync(path98.dirname(file), { recursive: true });
37212
+ fs94.writeFileSync(tmp, `${JSON.stringify(value)}
36511
37213
  `, "utf8");
36512
- fs90.renameSync(tmp, file);
37214
+ fs94.renameSync(tmp, file);
36513
37215
  return true;
36514
37216
  } catch {
36515
37217
  try {
36516
- fs90.unlinkSync(tmp);
37218
+ fs94.unlinkSync(tmp);
36517
37219
  } catch {
36518
37220
  }
36519
37221
  return false;
@@ -36559,7 +37261,7 @@ function stallSignal(history, window = 3) {
36559
37261
  }
36560
37262
  function readUnavailableDependency(transcriptPath) {
36561
37263
  try {
36562
- const raw = fs90.readFileSync(transcriptPath, "utf8");
37264
+ const raw = fs94.readFileSync(transcriptPath, "utf8");
36563
37265
  return detectUnavailableDependency(raw.slice(-DEPENDENCY_SCAN_BYTES));
36564
37266
  } catch {
36565
37267
  return null;
@@ -36567,18 +37269,18 @@ function readUnavailableDependency(transcriptPath) {
36567
37269
  }
36568
37270
 
36569
37271
  // src/scripts/_lib/context_observation.ts
36570
- var CONTEXT_OBSERVATION_REL = path94.join(
37272
+ var CONTEXT_OBSERVATION_REL = path99.join(
36571
37273
  "agents",
36572
37274
  "runtime",
36573
37275
  "state",
36574
37276
  "context-observation.json"
36575
37277
  );
36576
37278
  function observationFile(repoRoot) {
36577
- return path94.join(repoRoot, CONTEXT_OBSERVATION_REL);
37279
+ return path99.join(repoRoot, CONTEXT_OBSERVATION_REL);
36578
37280
  }
36579
37281
  function readContextObservation(repoRoot) {
36580
37282
  try {
36581
- const parsed = JSON.parse(fs91.readFileSync(observationFile(repoRoot), "utf-8"));
37283
+ const parsed = JSON.parse(fs95.readFileSync(observationFile(repoRoot), "utf-8"));
36582
37284
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
36583
37285
  const o = parsed;
36584
37286
  if (typeof o["fingerprint"] !== "string" || o["fingerprint"] === "") return null;
@@ -36600,8 +37302,8 @@ function premiseMoved(claimed, observed) {
36600
37302
  }
36601
37303
 
36602
37304
  // src/scripts/_lib/run_checkpoint.ts
36603
- import * as fs92 from "node:fs";
36604
- import * as path95 from "node:path";
37305
+ import * as fs96 from "node:fs";
37306
+ import * as path100 from "node:path";
36605
37307
 
36606
37308
  // src/scripts/_lib/roadmap_checkboxes.ts
36607
37309
  var CHECKBOX_LINE = /^[ \t]*[-*][ \t]+\[([ xX~-])\][ \t]+(.*)$/;
@@ -36631,7 +37333,7 @@ function phaseLines(text) {
36631
37333
  }
36632
37334
 
36633
37335
  // src/scripts/_lib/run_checkpoint.ts
36634
- var CHECKPOINT_DIR_REL = path95.join("agents", "runtime", "state", "checkpoints");
37336
+ var CHECKPOINT_DIR_REL = path100.join("agents", "runtime", "state", "checkpoints");
36635
37337
  function countRoadmap(text) {
36636
37338
  const counts = { open: 0, done: 0, parked: 0, next: null };
36637
37339
  for (const raw of phaseLines(text)) {
@@ -36652,34 +37354,34 @@ function countRoadmap(text) {
36652
37354
  return counts;
36653
37355
  }
36654
37356
  function checkpointFile(repoRoot, runId) {
36655
- return path95.join(repoRoot, CHECKPOINT_DIR_REL, `${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
37357
+ return path100.join(repoRoot, CHECKPOINT_DIR_REL, `${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
36656
37358
  }
36657
37359
  function roadmapPath(repoRoot, slug) {
36658
- return path95.join(repoRoot, "agents", "roadmaps", `${slug}.md`);
37360
+ return path100.join(repoRoot, "agents", "roadmaps", `${slug}.md`);
36659
37361
  }
36660
37362
  function readHead(repoRoot) {
36661
37363
  try {
36662
- let gitDir = path95.join(repoRoot, ".git");
36663
- if (fs92.statSync(gitDir).isFile()) {
36664
- const m = /^gitdir:\s*(.+)$/m.exec(fs92.readFileSync(gitDir, "utf-8").trim());
37364
+ let gitDir = path100.join(repoRoot, ".git");
37365
+ if (fs96.statSync(gitDir).isFile()) {
37366
+ const m = /^gitdir:\s*(.+)$/m.exec(fs96.readFileSync(gitDir, "utf-8").trim());
36665
37367
  if (m === null) return null;
36666
- gitDir = path95.resolve(repoRoot, m[1]);
37368
+ gitDir = path100.resolve(repoRoot, m[1]);
36667
37369
  }
36668
37370
  let refRoot = gitDir;
36669
37371
  try {
36670
- const common = fs92.readFileSync(path95.join(gitDir, "commondir"), "utf-8").trim();
36671
- if (common !== "") refRoot = path95.resolve(gitDir, common);
37372
+ const common = fs96.readFileSync(path100.join(gitDir, "commondir"), "utf-8").trim();
37373
+ if (common !== "") refRoot = path100.resolve(gitDir, common);
36672
37374
  } catch {
36673
37375
  }
36674
- const head = fs92.readFileSync(path95.join(gitDir, "HEAD"), "utf-8").trim();
37376
+ const head = fs96.readFileSync(path100.join(gitDir, "HEAD"), "utf-8").trim();
36675
37377
  if (/^[0-9a-f]{40}$/.test(head)) return head;
36676
37378
  const ref = /^ref:\s*(.+)$/.exec(head);
36677
37379
  if (ref === null) return null;
36678
37380
  const refName = ref[1];
36679
37381
  try {
36680
- return fs92.readFileSync(path95.join(refRoot, refName), "utf-8").trim() || null;
37382
+ return fs96.readFileSync(path100.join(refRoot, refName), "utf-8").trim() || null;
36681
37383
  } catch {
36682
- const packed = fs92.readFileSync(path95.join(refRoot, "packed-refs"), "utf-8");
37384
+ const packed = fs96.readFileSync(path100.join(refRoot, "packed-refs"), "utf-8");
36683
37385
  for (const line of packed.split("\n")) {
36684
37386
  const pm = /^([0-9a-f]{40})\s+(.+)$/.exec(line.trim());
36685
37387
  if (pm !== null && pm[2] === refName) return pm[1];
@@ -36693,7 +37395,7 @@ function readHead(repoRoot) {
36693
37395
  function buildCheckpoint(repoRoot, runId, slug, opts = {}) {
36694
37396
  let text;
36695
37397
  try {
36696
- text = fs92.readFileSync(roadmapPath(repoRoot, slug), "utf-8");
37398
+ text = fs96.readFileSync(roadmapPath(repoRoot, slug), "utf-8");
36697
37399
  } catch {
36698
37400
  return null;
36699
37401
  }
@@ -36717,8 +37419,8 @@ function buildCheckpoint(repoRoot, runId, slug, opts = {}) {
36717
37419
  function writeCheckpoint(repoRoot, cp) {
36718
37420
  const file = checkpointFile(repoRoot, cp.run_id);
36719
37421
  try {
36720
- fs92.mkdirSync(path95.dirname(file), { recursive: true });
36721
- fs92.writeFileSync(file, `${JSON.stringify(cp, null, 2)}
37422
+ fs96.mkdirSync(path100.dirname(file), { recursive: true });
37423
+ fs96.writeFileSync(file, `${JSON.stringify(cp, null, 2)}
36722
37424
  `, "utf-8");
36723
37425
  return file;
36724
37426
  } catch {
@@ -36727,7 +37429,7 @@ function writeCheckpoint(repoRoot, cp) {
36727
37429
  }
36728
37430
 
36729
37431
  // src/scripts/_lib/continuity_writer.ts
36730
- import * as fs93 from "node:fs";
37432
+ import * as fs97 from "node:fs";
36731
37433
  var AUTO_RECORD_KEY = "continuity.auto_record";
36732
37434
  function auto_record_enabled(root) {
36733
37435
  try {
@@ -36825,7 +37527,7 @@ function buildContinuityRecord(input) {
36825
37527
  }
36826
37528
  let text;
36827
37529
  try {
36828
- text = fs93.readFileSync(roadmapPath(root, slug), "utf-8");
37530
+ text = fs97.readFileSync(roadmapPath(root, slug), "utf-8");
36829
37531
  } catch {
36830
37532
  return { record: null, reason: `no record \u2014 the claimed roadmap ${slug} is not readable` };
36831
37533
  }
@@ -36864,12 +37566,12 @@ function buildContinuityRecord(input) {
36864
37566
  }
36865
37567
 
36866
37568
  // src/scripts/_lib/continuity_slot.ts
36867
- import * as fs94 from "node:fs";
36868
- import * as path96 from "node:path";
37569
+ import * as fs98 from "node:fs";
37570
+ import * as path101 from "node:path";
36869
37571
  var MAX_AGE_MS = RECYCLE_MAX_AGE_HOURS * 3600 * 1e3;
36870
37572
  function _parse2(file) {
36871
37573
  try {
36872
- const decoded = JSON.parse(fs94.readFileSync(file, "utf-8"));
37574
+ const decoded = JSON.parse(fs98.readFileSync(file, "utf-8"));
36873
37575
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
36874
37576
  return decoded;
36875
37577
  }
@@ -36886,14 +37588,14 @@ function _ageMs(record, now) {
36886
37588
  return now.getTime() - at;
36887
37589
  }
36888
37590
  function inspectSlot(workspace_root, session_id, now = /* @__PURE__ */ new Date()) {
36889
- const target = path96.join(workspace_root, recycle_envelope_rel(session_id));
36890
- if (!fs94.existsSync(target)) {
36891
- const consumed = path96.join(workspace_root, recycle_consumed_rel(session_id));
36892
- if (fs94.existsSync(consumed)) {
37591
+ const target = path101.join(workspace_root, recycle_envelope_rel(session_id));
37592
+ if (!fs98.existsSync(target)) {
37593
+ const consumed = path101.join(workspace_root, recycle_consumed_rel(session_id));
37594
+ if (fs98.existsSync(consumed)) {
36893
37595
  return { state: "consumed", reason: "the record for this session was consumed", target };
36894
37596
  }
36895
- const quarantined = path96.join(workspace_root, recycle_quarantine_rel(session_id));
36896
- if (fs94.existsSync(quarantined)) {
37597
+ const quarantined = path101.join(workspace_root, recycle_quarantine_rel(session_id));
37598
+ if (fs98.existsSync(quarantined)) {
36897
37599
  return {
36898
37600
  state: "quarantined",
36899
37601
  reason: "the slot is free; an unusable record sits in quarantine",
@@ -36953,7 +37655,7 @@ function publishContinuityRecord(workspace_root, session_id, record, now = /* @_
36953
37655
  reason: `refused \u2014 ${bytes} bytes exceeds the ${RECYCLE_ENVELOPE_MAX_BYTES} byte slot cap`
36954
37656
  };
36955
37657
  }
36956
- const target = path96.join(workspace_root, recycle_envelope_rel(session_id));
37658
+ const target = path101.join(workspace_root, recycle_envelope_rel(session_id));
36957
37659
  const before = inspectSlot(workspace_root, session_id, now);
36958
37660
  if (before.state === "conflicting") {
36959
37661
  return { state: "conflicting", wrote: false, reason: `refused \u2014 ${before.reason}` };
@@ -36970,11 +37672,11 @@ function publishContinuityRecord(workspace_root, session_id, record, now = /* @_
36970
37672
  }
36971
37673
  }
36972
37674
  let quarantined;
36973
- if (before.state === "quarantined" && fs94.existsSync(target)) {
36974
- const dest = path96.join(workspace_root, recycle_quarantine_rel(session_id));
37675
+ if (before.state === "quarantined" && fs98.existsSync(target)) {
37676
+ const dest = path101.join(workspace_root, recycle_quarantine_rel(session_id));
36975
37677
  try {
36976
- fs94.mkdirSync(path96.dirname(dest), { recursive: true });
36977
- fs94.renameSync(target, dest);
37678
+ fs98.mkdirSync(path101.dirname(dest), { recursive: true });
37679
+ fs98.renameSync(target, dest);
36978
37680
  quarantined = dest;
36979
37681
  } catch (exc) {
36980
37682
  return {
@@ -37003,7 +37705,7 @@ function publishContinuityRecord(workspace_root, session_id, record, now = /* @_
37003
37705
 
37004
37706
  // src/scripts/hooks/session_eol_hook.ts
37005
37707
  var THRESHOLD_OVERRIDE_ENV = "AGENT_RECYCLE_THRESHOLD_TOKENS";
37006
- var CONTEXT_FILL_REL = path97.join("agents", "runtime", "state", "context-fill.json");
37708
+ var CONTEXT_FILL_REL = path102.join("agents", "runtime", "state", "context-fill.json");
37007
37709
  function str12(value) {
37008
37710
  return typeof value === "string" ? value : "";
37009
37711
  }
@@ -37018,7 +37720,7 @@ function payloadSessionId(payload, envelope) {
37018
37720
  }
37019
37721
  function readState4(file) {
37020
37722
  try {
37021
- const parsed = JSON.parse(fs95.readFileSync(file, "utf-8"));
37723
+ const parsed = JSON.parse(fs99.readFileSync(file, "utf-8"));
37022
37724
  if (parsed && typeof parsed === "object" && parsed.schema_version === 1 && parsed.counters && typeof parsed.counters.scanned_bytes === "number") {
37023
37725
  return {
37024
37726
  schema_version: 1,
@@ -37049,7 +37751,7 @@ function readThresholdTokens() {
37049
37751
  }
37050
37752
  function writeContextFill(workspaceRoot3, tokens, threshold, ts) {
37051
37753
  try {
37052
- atomic_write_json(path97.join(workspaceRoot3, CONTEXT_FILL_REL), {
37754
+ atomic_write_json(path102.join(workspaceRoot3, CONTEXT_FILL_REL), {
37053
37755
  schema_version: 1,
37054
37756
  final_context_tokens: tokens,
37055
37757
  recycle_threshold_tokens: threshold,
@@ -37059,7 +37761,7 @@ function writeContextFill(workspaceRoot3, tokens, threshold, ts) {
37059
37761
  } catch {
37060
37762
  }
37061
37763
  }
37062
- function main61() {
37764
+ function main63() {
37063
37765
  const [envelope, payload] = unwrap(readHookStdin(), "claude");
37064
37766
  const event = String(envelope["event"] ?? "");
37065
37767
  if (event !== "" && event !== "stop") {
@@ -37142,38 +37844,38 @@ function writeContinuityRecord(workspaceRoot3, rawSessionId, counters, threshold
37142
37844
  } catch {
37143
37845
  }
37144
37846
  }
37145
- function _isCliEntry44() {
37847
+ function _isCliEntry46() {
37146
37848
  if (true) {
37147
37849
  return false;
37148
37850
  }
37149
37851
  if (process16.argv[1] === void 0) {
37150
37852
  return false;
37151
37853
  }
37152
- const argvUrl = pathToFileURL54(path97.resolve(process16.argv[1])).href;
37854
+ const argvUrl = pathToFileURL56(path102.resolve(process16.argv[1])).href;
37153
37855
  if (import.meta.url === argvUrl) {
37154
37856
  return true;
37155
37857
  }
37156
37858
  try {
37157
- const here = fs95.realpathSync(fileURLToPath63(import.meta.url));
37158
- const argv = fs95.realpathSync(path97.resolve(process16.argv[1]));
37859
+ const here = fs99.realpathSync(fileURLToPath66(import.meta.url));
37860
+ const argv = fs99.realpathSync(path102.resolve(process16.argv[1]));
37159
37861
  return here === argv;
37160
37862
  } catch {
37161
37863
  return false;
37162
37864
  }
37163
37865
  }
37164
- if (_isCliEntry44()) {
37165
- process16.exit(main61());
37866
+ if (_isCliEntry46()) {
37867
+ process16.exit(main63());
37166
37868
  }
37167
37869
 
37168
37870
  // src/scripts/hooks/tool_result_bytes_hook.ts
37169
- import * as fs96 from "node:fs";
37170
- import * as path98 from "node:path";
37171
- import { fileURLToPath as fileURLToPath64, pathToFileURL as pathToFileURL55 } from "node:url";
37871
+ import * as fs100 from "node:fs";
37872
+ import * as path103 from "node:path";
37873
+ import { fileURLToPath as fileURLToPath67, pathToFileURL as pathToFileURL57 } from "node:url";
37172
37874
  var EXIT_ALLOW31 = 0;
37173
37875
  function isObject17(v) {
37174
37876
  return typeof v === "object" && v !== null && !Array.isArray(v);
37175
37877
  }
37176
- var CENSUS_FILE = path98.join("agents", "runtime", "state", "tool-result-census.jsonl");
37878
+ var CENSUS_FILE = path103.join("agents", "runtime", "state", "tool-result-census.jsonl");
37177
37879
  var RESULT_KEYS = ["tool_response", "toolResponse", "tool_result", "toolUseResult"];
37178
37880
  function _resultBytes(payload) {
37179
37881
  for (const key of RESULT_KEYS) {
@@ -37208,13 +37910,13 @@ function unwrapPayload4(envelope) {
37208
37910
  return isObject17(inner) ? inner : envelope;
37209
37911
  }
37210
37912
  function censusFile(consumerRoot) {
37211
- return path98.join(consumerRoot, CENSUS_FILE);
37913
+ return path103.join(consumerRoot, CENSUS_FILE);
37212
37914
  }
37213
37915
  function _appendCensusLine(consumerRoot, line) {
37214
37916
  if (is_replay_mode()) return;
37215
37917
  const file = censusFile(consumerRoot);
37216
- fs96.mkdirSync(path98.dirname(file), { recursive: true });
37217
- fs96.appendFileSync(file, `${JSON.stringify(line)}
37918
+ fs100.mkdirSync(path103.dirname(file), { recursive: true });
37919
+ fs100.appendFileSync(file, `${JSON.stringify(line)}
37218
37920
  `, "utf8");
37219
37921
  }
37220
37922
  function processEnvelope4(envelope, consumerRoot) {
@@ -37245,7 +37947,7 @@ function resolveConsumerRoot2(envelope) {
37245
37947
  }
37246
37948
  return process.cwd();
37247
37949
  }
37248
- function main62() {
37950
+ function main64() {
37249
37951
  const raw = readHookStdin();
37250
37952
  let envelope = {};
37251
37953
  try {
@@ -37255,25 +37957,25 @@ function main62() {
37255
37957
  }
37256
37958
  return processEnvelope4(envelope, resolveConsumerRoot2(envelope));
37257
37959
  }
37258
- function _isCliEntry45() {
37960
+ function _isCliEntry47() {
37259
37961
  if (true) {
37260
37962
  return false;
37261
37963
  }
37262
37964
  if (process.argv[1] === void 0) return false;
37263
- const argvUrl = pathToFileURL55(path98.resolve(process.argv[1])).href;
37965
+ const argvUrl = pathToFileURL57(path103.resolve(process.argv[1])).href;
37264
37966
  if (import.meta.url === argvUrl) return true;
37265
37967
  try {
37266
- return fs96.realpathSync(fileURLToPath64(import.meta.url)) === fs96.realpathSync(path98.resolve(process.argv[1]));
37968
+ return fs100.realpathSync(fileURLToPath67(import.meta.url)) === fs100.realpathSync(path103.resolve(process.argv[1]));
37267
37969
  } catch {
37268
37970
  return false;
37269
37971
  }
37270
37972
  }
37271
- if (_isCliEntry45()) process.exit(main62());
37973
+ if (_isCliEntry47()) process.exit(main64());
37272
37974
 
37273
37975
  // src/scripts/hooks/spawn_guard_shadow_hook.ts
37274
- import * as fs97 from "node:fs";
37275
- import * as path99 from "node:path";
37276
- import { fileURLToPath as fileURLToPath65, pathToFileURL as pathToFileURL56 } from "node:url";
37976
+ import * as fs101 from "node:fs";
37977
+ import * as path104 from "node:path";
37978
+ import { fileURLToPath as fileURLToPath68, pathToFileURL as pathToFileURL58 } from "node:url";
37277
37979
  var EXIT_ALLOW32 = 0;
37278
37980
  function isObject18(v) {
37279
37981
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -37337,7 +38039,7 @@ function processEnvelope5(envelope, consumerRoot) {
37337
38039
  }
37338
38040
  return EXIT_ALLOW32;
37339
38041
  }
37340
- function main63() {
38042
+ function main65() {
37341
38043
  const raw = readHookStdin();
37342
38044
  let envelope = {};
37343
38045
  try {
@@ -37347,27 +38049,27 @@ function main63() {
37347
38049
  }
37348
38050
  return processEnvelope5(envelope, resolveConsumerRoot(envelope));
37349
38051
  }
37350
- function _isCliEntry46() {
38052
+ function _isCliEntry48() {
37351
38053
  if (true) return false;
37352
38054
  if (process.argv[1] === void 0) return false;
37353
- const argvUrl = pathToFileURL56(path99.resolve(process.argv[1])).href;
38055
+ const argvUrl = pathToFileURL58(path104.resolve(process.argv[1])).href;
37354
38056
  if (import.meta.url === argvUrl) return true;
37355
38057
  try {
37356
- return fs97.realpathSync(fileURLToPath65(import.meta.url)) === fs97.realpathSync(path99.resolve(process.argv[1]));
38058
+ return fs101.realpathSync(fileURLToPath68(import.meta.url)) === fs101.realpathSync(path104.resolve(process.argv[1]));
37357
38059
  } catch {
37358
38060
  return false;
37359
38061
  }
37360
38062
  }
37361
- if (_isCliEntry46()) process.exit(main63());
38063
+ if (_isCliEntry48()) process.exit(main65());
37362
38064
 
37363
38065
  // src/scripts/hooks/source_first_gate_hook.ts
37364
- import * as fs98 from "node:fs";
37365
- import * as path100 from "node:path";
37366
- import { fileURLToPath as fileURLToPath66, pathToFileURL as pathToFileURL57 } from "node:url";
38066
+ import * as fs102 from "node:fs";
38067
+ import * as path105 from "node:path";
38068
+ import { fileURLToPath as fileURLToPath69, pathToFileURL as pathToFileURL59 } from "node:url";
37367
38069
  var EXIT_ALLOW33 = 0;
37368
38070
  var MAX_SHADOW_WARNS = 2;
37369
- var SHADOW_LOG = path100.join("agents", "runtime", "state", "source-first-gate.jsonl");
37370
- var STATE_FILE9 = path100.join("agents", "runtime", "state", "source-first-gate.json");
38071
+ var SHADOW_LOG = path105.join("agents", "runtime", "state", "source-first-gate.jsonl");
38072
+ var STATE_FILE9 = path105.join("agents", "runtime", "state", "source-first-gate.json");
37371
38073
  function isObject19(v) {
37372
38074
  return typeof v === "object" && v !== null && !Array.isArray(v);
37373
38075
  }
@@ -37441,7 +38143,7 @@ var EMPTY_STATE = { handoverSeen: false, sourceRead: false, wouldWarn: 0 };
37441
38143
  var MAX_SESSIONS2 = 50;
37442
38144
  function readState5(root, session) {
37443
38145
  try {
37444
- const all = JSON.parse(fs98.readFileSync(path100.join(root, STATE_FILE9), "utf-8"));
38146
+ const all = JSON.parse(fs102.readFileSync(path105.join(root, STATE_FILE9), "utf-8"));
37445
38147
  const entry = all[session];
37446
38148
  if (entry && typeof entry.handoverSeen === "boolean" && typeof entry.sourceRead === "boolean" && typeof entry.wouldWarn === "number") {
37447
38149
  return entry;
@@ -37453,10 +38155,10 @@ function readState5(root, session) {
37453
38155
  function writeState4(root, session, state) {
37454
38156
  if (is_replay_mode()) return;
37455
38157
  try {
37456
- const file = path100.join(root, STATE_FILE9);
38158
+ const file = path105.join(root, STATE_FILE9);
37457
38159
  let all = {};
37458
38160
  try {
37459
- all = JSON.parse(fs98.readFileSync(file, "utf-8"));
38161
+ all = JSON.parse(fs102.readFileSync(file, "utf-8"));
37460
38162
  } catch {
37461
38163
  }
37462
38164
  if (!isObject19(all)) all = {};
@@ -37467,8 +38169,8 @@ function writeState4(root, session, state) {
37467
38169
  for (const key of keys.slice(keys.length - MAX_SESSIONS2)) pruned[key] = all[key];
37468
38170
  all = pruned;
37469
38171
  }
37470
- fs98.mkdirSync(path100.dirname(file), { recursive: true });
37471
- fs98.writeFileSync(file, JSON.stringify(all));
38172
+ fs102.mkdirSync(path105.dirname(file), { recursive: true });
38173
+ fs102.writeFileSync(file, JSON.stringify(all));
37472
38174
  } catch {
37473
38175
  }
37474
38176
  }
@@ -37489,7 +38191,7 @@ function evaluateCandidates2(handoverSeen, handoverOnDisk, sourceRead) {
37489
38191
  }
37490
38192
  function handoverPresentOnDisk(root) {
37491
38193
  try {
37492
- return fs98.statSync(path100.join(root, ".claude", "design-system")).isDirectory();
38194
+ return fs102.statSync(path105.join(root, ".claude", "design-system")).isDirectory();
37493
38195
  } catch {
37494
38196
  return false;
37495
38197
  }
@@ -37497,9 +38199,9 @@ function handoverPresentOnDisk(root) {
37497
38199
  function appendShadowLine(root, line) {
37498
38200
  if (is_replay_mode()) return;
37499
38201
  try {
37500
- const file = path100.join(root, SHADOW_LOG);
37501
- fs98.mkdirSync(path100.dirname(file), { recursive: true });
37502
- fs98.appendFileSync(file, `${JSON.stringify(line)}
38202
+ const file = path105.join(root, SHADOW_LOG);
38203
+ fs102.mkdirSync(path105.dirname(file), { recursive: true });
38204
+ fs102.appendFileSync(file, `${JSON.stringify(line)}
37503
38205
  `, "utf8");
37504
38206
  } catch {
37505
38207
  }
@@ -37560,7 +38262,7 @@ function processEnvelope6(envelope, consumerRoot, session) {
37560
38262
  }
37561
38263
  return EXIT_ALLOW33;
37562
38264
  }
37563
- function main64() {
38265
+ function main66() {
37564
38266
  const raw = readHookStdin();
37565
38267
  let envelope = {};
37566
38268
  try {
@@ -37572,26 +38274,26 @@ function main64() {
37572
38274
  const session = typeof sessionVal === "string" && sessionVal ? sessionVal : "unknown";
37573
38275
  return processEnvelope6(envelope, resolveConsumerRoot(envelope), session);
37574
38276
  }
37575
- function _isCliEntry47() {
38277
+ function _isCliEntry49() {
37576
38278
  if (true) return false;
37577
38279
  if (process.argv[1] === void 0) return false;
37578
- const argvUrl = pathToFileURL57(path100.resolve(process.argv[1])).href;
38280
+ const argvUrl = pathToFileURL59(path105.resolve(process.argv[1])).href;
37579
38281
  if (import.meta.url === argvUrl) return true;
37580
38282
  try {
37581
- return fs98.realpathSync(fileURLToPath66(import.meta.url)) === fs98.realpathSync(path100.resolve(process.argv[1]));
38283
+ return fs102.realpathSync(fileURLToPath69(import.meta.url)) === fs102.realpathSync(path105.resolve(process.argv[1]));
37582
38284
  } catch {
37583
38285
  return false;
37584
38286
  }
37585
38287
  }
37586
- if (_isCliEntry47()) process.exit(main64());
38288
+ if (_isCliEntry49()) process.exit(main66());
37587
38289
 
37588
38290
  // src/scripts/hooks/interruption_ledger_hook.ts
37589
- import * as fs99 from "node:fs";
37590
- import * as path101 from "node:path";
37591
- import { fileURLToPath as fileURLToPath67, pathToFileURL as pathToFileURL58 } from "node:url";
37592
- var EXIT_OK2 = 0;
38291
+ import * as fs103 from "node:fs";
38292
+ import * as path106 from "node:path";
38293
+ import { fileURLToPath as fileURLToPath70, pathToFileURL as pathToFileURL60 } from "node:url";
38294
+ var EXIT_OK3 = 0;
37593
38295
  var TRANSCRIPT_READ_MAX_BYTES2 = 2 * 1024 * 1024;
37594
- var LEDGER_RELPATH = path101.join("agents", "runtime", "state", "interruptions.jsonl");
38296
+ var LEDGER_RELPATH = path106.join("agents", "runtime", "state", "interruptions.jsonl");
37595
38297
  function hasNumberedOptions(reply) {
37596
38298
  let count = 0;
37597
38299
  for (const line of reply.split("\n")) {
@@ -37615,14 +38317,14 @@ function classifyReply(reply) {
37615
38317
  function readClaimedRoadmap(workspaceRoot3, sessionId3) {
37616
38318
  if (!sessionId3) return null;
37617
38319
  try {
37618
- const file = path101.join(
38320
+ const file = path106.join(
37619
38321
  workspaceRoot3,
37620
38322
  "agents",
37621
38323
  "runtime",
37622
38324
  "state",
37623
38325
  `roadmap-claim-${sessionId3}.json`
37624
38326
  );
37625
- const parsed = JSON.parse(fs99.readFileSync(file, "utf8"));
38327
+ const parsed = JSON.parse(fs103.readFileSync(file, "utf8"));
37626
38328
  if (parsed === null || typeof parsed !== "object") return null;
37627
38329
  const slug = parsed["slug"];
37628
38330
  return typeof slug === "string" && slug.length > 0 ? slug : null;
@@ -37633,7 +38335,7 @@ function readClaimedRoadmap(workspaceRoot3, sessionId3) {
37633
38335
  function alreadyRecorded(ledgerPath, runId, turn) {
37634
38336
  let raw;
37635
38337
  try {
37636
- raw = fs99.readFileSync(ledgerPath, "utf8");
38338
+ raw = fs103.readFileSync(ledgerPath, "utf8");
37637
38339
  } catch {
37638
38340
  return false;
37639
38341
  }
@@ -37652,19 +38354,19 @@ function alreadyRecorded(ledgerPath, runId, turn) {
37652
38354
  function str14(v) {
37653
38355
  return typeof v === "string" ? v : "";
37654
38356
  }
37655
- function main65() {
38357
+ function main67() {
37656
38358
  let envelope;
37657
38359
  let payload;
37658
38360
  try {
37659
38361
  [envelope, payload] = unwrap(readHookStdin(), "claude");
37660
38362
  } catch {
37661
- return EXIT_OK2;
38363
+ return EXIT_OK3;
37662
38364
  }
37663
38365
  const workspaceRoot3 = str14(envelope["workspace_root"]) || process.cwd();
37664
38366
  const transcriptPath = str14(
37665
38367
  payload["transcript_path"] ?? payload["transcriptPath"]
37666
38368
  );
37667
- if (!transcriptPath) return EXIT_OK2;
38369
+ if (!transcriptPath) return EXIT_OK3;
37668
38370
  let lastAssistant = "";
37669
38371
  let turnOrdinal = 0;
37670
38372
  try {
@@ -37672,13 +38374,13 @@ function main65() {
37672
38374
  lastAssistant = tail.lastAssistant;
37673
38375
  turnOrdinal = tail.turnOrdinal;
37674
38376
  } catch {
37675
- return EXIT_OK2;
38377
+ return EXIT_OK3;
37676
38378
  }
37677
- if (!lastAssistant) return EXIT_OK2;
38379
+ if (!lastAssistant) return EXIT_OK3;
37678
38380
  const sessionId3 = str14(payload["session_id"]) || str14(envelope["session_id"]);
37679
38381
  const runId = sessionId3 ? derive_session_tag(sessionId3) : "unknown";
37680
- const ledgerPath = path101.join(workspaceRoot3, LEDGER_RELPATH);
37681
- if (alreadyRecorded(ledgerPath, runId, turnOrdinal)) return EXIT_OK2;
38382
+ const ledgerPath = path106.join(workspaceRoot3, LEDGER_RELPATH);
38383
+ if (alreadyRecorded(ledgerPath, runId, turnOrdinal)) return EXIT_OK3;
37682
38384
  const verdict2 = classifyReply(lastAssistant);
37683
38385
  const record = {
37684
38386
  run_id: runId,
@@ -37689,43 +38391,43 @@ function main65() {
37689
38391
  at: (/* @__PURE__ */ new Date()).toISOString()
37690
38392
  };
37691
38393
  try {
37692
- fs99.mkdirSync(path101.dirname(ledgerPath), { recursive: true });
37693
- fs99.appendFileSync(ledgerPath, `${JSON.stringify(record)}
38394
+ fs103.mkdirSync(path106.dirname(ledgerPath), { recursive: true });
38395
+ fs103.appendFileSync(ledgerPath, `${JSON.stringify(record)}
37694
38396
  `, "utf8");
37695
38397
  } catch {
37696
38398
  }
37697
- return EXIT_OK2;
38399
+ return EXIT_OK3;
37698
38400
  }
37699
- function _isCliEntry48() {
38401
+ function _isCliEntry50() {
37700
38402
  if (process.argv[1] === void 0) {
37701
38403
  return false;
37702
38404
  }
37703
- const argvUrl = pathToFileURL58(path101.resolve(process.argv[1])).href;
38405
+ const argvUrl = pathToFileURL60(path106.resolve(process.argv[1])).href;
37704
38406
  if (import.meta.url === argvUrl) {
37705
38407
  return true;
37706
38408
  }
37707
38409
  try {
37708
- const here = fs99.realpathSync(fileURLToPath67(import.meta.url));
37709
- const argv = fs99.realpathSync(path101.resolve(process.argv[1]));
38410
+ const here = fs103.realpathSync(fileURLToPath70(import.meta.url));
38411
+ const argv = fs103.realpathSync(path106.resolve(process.argv[1]));
37710
38412
  return here === argv;
37711
38413
  } catch {
37712
38414
  return false;
37713
38415
  }
37714
38416
  }
37715
- if (_isCliEntry48()) {
37716
- process.exit(main65());
38417
+ if (_isCliEntry50()) {
38418
+ process.exit(main67());
37717
38419
  }
37718
38420
 
37719
38421
  // src/scripts/hooks/run_continuation_hook.ts
37720
- import * as fs101 from "node:fs";
38422
+ import * as fs105 from "node:fs";
37721
38423
 
37722
38424
  // src/scripts/_lib/billing_grant.ts
37723
- import * as fs100 from "node:fs";
37724
- import * as path102 from "node:path";
37725
- var BILLING_GRANT_DIR_REL = path102.join("agents", "runtime", "billing-grants");
38425
+ import * as fs104 from "node:fs";
38426
+ import * as path107 from "node:path";
38427
+ var BILLING_GRANT_DIR_REL = path107.join("agents", "runtime", "billing-grants");
37726
38428
  var BILLING_GRANT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
37727
38429
  function grantFile(repoRoot, runId) {
37728
- return path102.join(
38430
+ return path107.join(
37729
38431
  repoRoot,
37730
38432
  BILLING_GRANT_DIR_REL,
37731
38433
  `${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`
@@ -37733,14 +38435,14 @@ function grantFile(repoRoot, runId) {
37733
38435
  }
37734
38436
  function revokeBillingGrant(repoRoot, runId) {
37735
38437
  try {
37736
- fs100.unlinkSync(grantFile(repoRoot, runId));
38438
+ fs104.unlinkSync(grantFile(repoRoot, runId));
37737
38439
  } catch {
37738
38440
  }
37739
38441
  }
37740
38442
 
37741
38443
  // src/scripts/hooks/run_continuation_hook.ts
37742
- import * as path103 from "node:path";
37743
- import { fileURLToPath as fileURLToPath68, pathToFileURL as pathToFileURL59 } from "node:url";
38444
+ import * as path108 from "node:path";
38445
+ import { fileURLToPath as fileURLToPath71, pathToFileURL as pathToFileURL61 } from "node:url";
37744
38446
 
37745
38447
  // src/scripts/_lib/outcome_vocabularies.ts
37746
38448
  var RUN_TERMINAL_STATES = [
@@ -37830,13 +38532,13 @@ var EXIT_ALLOW34 = 0;
37830
38532
  var EXIT_BLOCK4 = 1;
37831
38533
  var BLOCKED_BY_MARKER = /<!--\s*blocked-by:\s*\S[^>]*-->/;
37832
38534
  var LEDGER_TAIL_MAX_BYTES = 512 * 1024;
37833
- var EVENTS_RELPATH = path103.join(
38535
+ var EVENTS_RELPATH = path108.join(
37834
38536
  "agents",
37835
38537
  "runtime",
37836
38538
  "state",
37837
38539
  "run-continuation.jsonl"
37838
38540
  );
37839
- var STATE_DIR_REL = path103.join("agents", "runtime", "state");
38541
+ var STATE_DIR_REL = path108.join("agents", "runtime", "state");
37840
38542
  var ABSENT_CONFIRM_FIRES = 2;
37841
38543
  var DUPLICATE_WINDOW_MS = 60 * 1e3;
37842
38544
  function isDuplicateFire(state, turnOrdinal, openCount, nowMs, roadmapSource) {
@@ -37908,20 +38610,20 @@ function extractVerify(stepText) {
37908
38610
  function stateRelPath(runId, slug) {
37909
38611
  const safeRun = runId.replace(/[^A-Za-z0-9_-]/g, "_");
37910
38612
  const safeSlug = slug.replace(/[^A-Za-z0-9_-]/g, "_");
37911
- return path103.join(STATE_DIR_REL, `run-continuation-${safeRun}-${safeSlug}.json`);
38613
+ return path108.join(STATE_DIR_REL, `run-continuation-${safeRun}-${safeSlug}.json`);
37912
38614
  }
37913
38615
  function legacyStateRelPath(runId) {
37914
38616
  const safe = runId.replace(/[^A-Za-z0-9_-]/g, "_");
37915
- return path103.join(STATE_DIR_REL, `run-continuation-${safe}.json`);
38617
+ return path108.join(STATE_DIR_REL, `run-continuation-${safe}.json`);
37916
38618
  }
37917
38619
  function readRunState(workspaceRoot3, runId, slug) {
37918
- const keyedFile = path103.join(workspaceRoot3, stateRelPath(runId, slug));
38620
+ const keyedFile = path108.join(workspaceRoot3, stateRelPath(runId, slug));
37919
38621
  const keyed = readState6(keyedFile);
37920
38622
  if (keyed !== null) return { state: keyed, from: "keyed", keyedFile };
37921
38623
  if (fileExists(keyedFile)) {
37922
38624
  return { state: null, from: "keyed", keyedFile };
37923
38625
  }
37924
- const legacy = readState6(path103.join(workspaceRoot3, legacyStateRelPath(runId)));
38626
+ const legacy = readState6(path108.join(workspaceRoot3, legacyStateRelPath(runId)));
37925
38627
  if (legacy === null) return { state: null, from: "none", keyedFile };
37926
38628
  if (legacy.roadmap !== void 0 && legacy.roadmap !== slug) {
37927
38629
  return { state: null, from: "none", keyedFile };
@@ -37934,25 +38636,25 @@ function writeState5(file, state) {
37934
38636
  function clearRunState(workspaceRoot3, runId, keyedFile, adoptedLegacy) {
37935
38637
  revokeBillingGrant(workspaceRoot3, runId);
37936
38638
  try {
37937
- fs101.rmSync(keyedFile, { force: true });
38639
+ fs105.rmSync(keyedFile, { force: true });
37938
38640
  } catch {
37939
38641
  }
37940
38642
  if (!adoptedLegacy) return;
37941
38643
  try {
37942
- fs101.rmSync(path103.join(workspaceRoot3, legacyStateRelPath(runId)), { force: true });
38644
+ fs105.rmSync(path108.join(workspaceRoot3, legacyStateRelPath(runId)), { force: true });
37943
38645
  } catch {
37944
38646
  }
37945
38647
  }
37946
38648
  function fileExists(p) {
37947
38649
  try {
37948
- return fs101.statSync(p).isFile();
38650
+ return fs105.statSync(p).isFile();
37949
38651
  } catch {
37950
38652
  return false;
37951
38653
  }
37952
38654
  }
37953
38655
  function readState6(file) {
37954
38656
  try {
37955
- const parsed = JSON.parse(fs101.readFileSync(file, "utf8"));
38657
+ const parsed = JSON.parse(fs105.readFileSync(file, "utf8"));
37956
38658
  if (parsed === null || typeof parsed !== "object") return null;
37957
38659
  const o = parsed;
37958
38660
  if (typeof o["started_at"] !== "string") return null;
@@ -37993,16 +38695,16 @@ function readState6(file) {
37993
38695
  }
37994
38696
  }
37995
38697
  function normalizeDir(p) {
37996
- const abs = path103.resolve(p);
38698
+ const abs = path108.resolve(p);
37997
38699
  try {
37998
- return fs101.realpathSync(abs);
38700
+ return fs105.realpathSync(abs);
37999
38701
  } catch {
38000
38702
  return abs;
38001
38703
  }
38002
38704
  }
38003
38705
  function normalizeFile(p) {
38004
- const abs = path103.resolve(p);
38005
- return path103.join(normalizeDir(path103.dirname(abs)), path103.basename(abs));
38706
+ const abs = path108.resolve(p);
38707
+ return path108.join(normalizeDir(path108.dirname(abs)), path108.basename(abs));
38006
38708
  }
38007
38709
  function provenance(workspaceRoot3, claimPath, sessionRoot, sessionCwd) {
38008
38710
  const reader = normalizeDir(workspaceRoot3);
@@ -38029,36 +38731,36 @@ function provenance(workspaceRoot3, claimPath, sessionRoot, sessionCwd) {
38029
38731
  };
38030
38732
  }
38031
38733
  function resolveRoadmap(sessionRoot, workspaceRoot3, slug) {
38032
- const dirRel = path103.join("agents", "roadmaps");
38734
+ const dirRel = path108.join("agents", "roadmaps");
38033
38735
  const stem = slug.trim().replace(/\.md$/, "");
38034
- const rel = path103.join(dirRel, `${stem}.md`);
38035
- const norm = path103.normalize(rel);
38036
- if (path103.dirname(norm) !== dirRel) return null;
38037
- if (sessionRoot !== workspaceRoot3 && isDirectory(path103.join(sessionRoot, dirRel))) {
38038
- return path103.join(sessionRoot, norm);
38736
+ const rel = path108.join(dirRel, `${stem}.md`);
38737
+ const norm = path108.normalize(rel);
38738
+ if (path108.dirname(norm) !== dirRel) return null;
38739
+ if (sessionRoot !== workspaceRoot3 && isDirectory(path108.join(sessionRoot, dirRel))) {
38740
+ return path108.join(sessionRoot, norm);
38039
38741
  }
38040
- return path103.join(normalizeDir(workspaceRoot3), norm);
38742
+ return path108.join(normalizeDir(workspaceRoot3), norm);
38041
38743
  }
38042
38744
  function isDirectory(p) {
38043
38745
  try {
38044
- return fs101.statSync(p).isDirectory();
38746
+ return fs105.statSync(p).isDirectory();
38045
38747
  } catch {
38046
38748
  return false;
38047
38749
  }
38048
38750
  }
38049
38751
  function eventAlreadyLogged(workspaceRoot3, runId, slug, event) {
38050
38752
  try {
38051
- const file = path103.join(workspaceRoot3, EVENTS_RELPATH);
38052
- const size = fs101.statSync(file).size;
38753
+ const file = path108.join(workspaceRoot3, EVENTS_RELPATH);
38754
+ const size = fs105.statSync(file).size;
38053
38755
  const start = Math.max(0, size - LEDGER_TAIL_MAX_BYTES);
38054
- const fd = fs101.openSync(file, "r");
38756
+ const fd = fs105.openSync(file, "r");
38055
38757
  let text;
38056
38758
  try {
38057
38759
  const buf = Buffer.alloc(size - start);
38058
- const read = fs101.readSync(fd, buf, 0, buf.length, start);
38760
+ const read = fs105.readSync(fd, buf, 0, buf.length, start);
38059
38761
  text = buf.subarray(0, read).toString("utf8");
38060
38762
  } finally {
38061
- fs101.closeSync(fd);
38763
+ fs105.closeSync(fd);
38062
38764
  }
38063
38765
  for (const line of text.split("\n")) {
38064
38766
  if (line === "") continue;
@@ -38081,9 +38783,9 @@ function eventAlreadyLogged(workspaceRoot3, runId, slug, event) {
38081
38783
  }
38082
38784
  function appendEvent2(workspaceRoot3, record) {
38083
38785
  try {
38084
- const file = path103.join(workspaceRoot3, EVENTS_RELPATH);
38085
- fs101.mkdirSync(path103.dirname(file), { recursive: true });
38086
- fs101.appendFileSync(file, `${JSON.stringify(record)}
38786
+ const file = path108.join(workspaceRoot3, EVENTS_RELPATH);
38787
+ fs105.mkdirSync(path108.dirname(file), { recursive: true });
38788
+ fs105.appendFileSync(file, `${JSON.stringify(record)}
38087
38789
  `, "utf8");
38088
38790
  } catch {
38089
38791
  }
@@ -38091,7 +38793,7 @@ function appendEvent2(workspaceRoot3, record) {
38091
38793
  function refusedThisTurn(workspaceRoot3, sessionId3, turnOrdinal) {
38092
38794
  try {
38093
38795
  const file = sessionRefusalFile(workspaceRoot3, deriveSessionKey(sessionId3 || "unknown-session"));
38094
- const rec = parseRecord(fs101.readFileSync(file, "utf-8"));
38796
+ const rec = parseRecord(fs105.readFileSync(file, "utf-8"));
38095
38797
  return rec !== null && rec.refused_turn === turnOrdinal;
38096
38798
  } catch {
38097
38799
  return false;
@@ -38100,7 +38802,7 @@ function refusedThisTurn(workspaceRoot3, sessionId3, turnOrdinal) {
38100
38802
  function str15(v) {
38101
38803
  return typeof v === "string" ? v : "";
38102
38804
  }
38103
- function main66() {
38805
+ function main68() {
38104
38806
  if (is_replay_mode()) return EXIT_ALLOW34;
38105
38807
  if (process.env["AGENT_CONFIG_NO_RUN_CONTINUATION"] === "1") return EXIT_ALLOW34;
38106
38808
  let envelope;
@@ -38125,7 +38827,7 @@ function main66() {
38125
38827
  let roadmapText = null;
38126
38828
  if (roadmapPath2 !== null) {
38127
38829
  try {
38128
- roadmapText = fs101.readFileSync(roadmapPath2, "utf8");
38830
+ roadmapText = fs105.readFileSync(roadmapPath2, "utf8");
38129
38831
  roadmapFile = roadmapPath2;
38130
38832
  } catch {
38131
38833
  roadmapText = null;
@@ -38174,7 +38876,7 @@ function main66() {
38174
38876
  );
38175
38877
  if (!transcriptPath) return EXIT_ALLOW34;
38176
38878
  try {
38177
- if (fs101.statSync(transcriptPath).size > TRANSCRIPT_READ_MAX_BYTES) {
38879
+ if (fs105.statSync(transcriptPath).size > TRANSCRIPT_READ_MAX_BYTES) {
38178
38880
  const inert = readRunState(workspaceRoot3, runId, slug);
38179
38881
  if (inert.state !== null && inert.state.inert_reported !== true) {
38180
38882
  const inertRoots = provenance(
@@ -38328,29 +39030,29 @@ ${stepLine}
38328
39030
  Continue with this step now: do the work, run its verify line, flip the box, then end the turn. Escalate instead of continuing ONLY for a locked decision class (high_impact / user_required) or a halt your contract names.
38329
39031
  `;
38330
39032
  }
38331
- function _isCliEntry49() {
39033
+ function _isCliEntry51() {
38332
39034
  if (true) {
38333
39035
  return false;
38334
39036
  }
38335
39037
  if (process.argv[1] === void 0) return false;
38336
- const argvUrl = pathToFileURL59(path103.resolve(process.argv[1])).href;
39038
+ const argvUrl = pathToFileURL61(path108.resolve(process.argv[1])).href;
38337
39039
  if (import.meta.url === argvUrl) return true;
38338
39040
  try {
38339
- const here = fs101.realpathSync(fileURLToPath68(import.meta.url));
38340
- const argv = fs101.realpathSync(path103.resolve(process.argv[1]));
39041
+ const here = fs105.realpathSync(fileURLToPath71(import.meta.url));
39042
+ const argv = fs105.realpathSync(path108.resolve(process.argv[1]));
38341
39043
  return here === argv;
38342
39044
  } catch {
38343
39045
  return false;
38344
39046
  }
38345
39047
  }
38346
- if (_isCliEntry49()) {
38347
- process.exit(main66());
39048
+ if (_isCliEntry51()) {
39049
+ process.exit(main68());
38348
39050
  }
38349
39051
 
38350
39052
  // src/scripts/hooks/journal_record_hook.ts
38351
- import * as fs103 from "node:fs";
38352
- import * as path105 from "node:path";
38353
- import { fileURLToPath as fileURLToPath69, pathToFileURL as pathToFileURL60 } from "node:url";
39053
+ import * as fs107 from "node:fs";
39054
+ import * as path110 from "node:path";
39055
+ import { fileURLToPath as fileURLToPath72, pathToFileURL as pathToFileURL62 } from "node:url";
38354
39056
 
38355
39057
  // src/scripts/_lib/surface.ts
38356
39058
  var SURFACES = ["ide", "cli", "cloud", "unknown"];
@@ -38380,8 +39082,8 @@ function readSurface(v) {
38380
39082
 
38381
39083
  // src/scripts/_lib/runtime_journal.ts
38382
39084
  import * as crypto14 from "node:crypto";
38383
- import * as fs102 from "node:fs";
38384
- import * as path104 from "node:path";
39085
+ import * as fs106 from "node:fs";
39086
+ import * as path109 from "node:path";
38385
39087
 
38386
39088
  // src/scripts/_lib/sqlite_schema.ts
38387
39089
  function addColumnIfMissing(db, table, column, decl) {
@@ -38483,7 +39185,7 @@ function requireId(name, id, optional) {
38483
39185
  }
38484
39186
  var JOURNAL_DIR_NAME = "agent-journal";
38485
39187
  var JOURNAL_FILE_NAME = "journal.sqlite";
38486
- var JOURNAL_FALLBACK_REL = path104.join("agents", "runtime", "state", JOURNAL_FILE_NAME);
39188
+ var JOURNAL_FALLBACK_REL = path109.join("agents", "runtime", "state", JOURNAL_FILE_NAME);
38487
39189
  function digest(domain, input) {
38488
39190
  return crypto14.createHash("sha256").update(`${domain}\0${input}`).digest("hex").slice(0, 12);
38489
39191
  }
@@ -38494,20 +39196,20 @@ function resolveJournal(root) {
38494
39196
  if (common !== null) {
38495
39197
  const own = git_dir(root) ?? common;
38496
39198
  return {
38497
- path: path104.join(common, JOURNAL_DIR_NAME, JOURNAL_FILE_NAME),
39199
+ path: path109.join(common, JOURNAL_DIR_NAME, JOURNAL_FILE_NAME),
38498
39200
  scope: "repo-shared",
38499
39201
  reason: "common git dir resolved \u2014 every worktree of this repo writes one database",
38500
39202
  repository_id: digest(REPO_DOMAIN, common),
38501
39203
  worktree_id: digest(WORKTREE_DOMAIN, own)
38502
39204
  };
38503
39205
  }
38504
- let real = path104.resolve(root);
39206
+ let real = path109.resolve(root);
38505
39207
  try {
38506
- real = fs102.realpathSync(real);
39208
+ real = fs106.realpathSync(real);
38507
39209
  } catch {
38508
39210
  }
38509
39211
  return {
38510
- path: path104.join(real, JOURNAL_FALLBACK_REL),
39212
+ path: path109.join(real, JOURNAL_FALLBACK_REL),
38511
39213
  scope: "worktree-local",
38512
39214
  reason: "no common git dir \u2014 not inside a git repository; falling back to the tree-local path",
38513
39215
  repository_id: digest(REPO_DOMAIN, real),
@@ -38595,7 +39297,7 @@ function ensureWal(db) {
38595
39297
  function discard(dbPath) {
38596
39298
  for (const p of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
38597
39299
  try {
38598
- fs102.rmSync(p, { force: true });
39300
+ fs106.rmSync(p, { force: true });
38599
39301
  } catch {
38600
39302
  }
38601
39303
  }
@@ -38607,9 +39309,9 @@ function openJournal(root) {
38607
39309
  );
38608
39310
  }
38609
39311
  const location = resolveJournal(root);
38610
- fs102.mkdirSync(path104.dirname(location.path), { recursive: true });
39312
+ fs106.mkdirSync(path109.dirname(location.path), { recursive: true });
38611
39313
  const { DatabaseSync } = loadSqliteSync("runtime_journal");
38612
- if (fs102.existsSync(location.path)) {
39314
+ if (fs106.existsSync(location.path)) {
38613
39315
  let drift = false;
38614
39316
  let probe = null;
38615
39317
  try {
@@ -38848,7 +39550,7 @@ function processEnvelope7(envelope, consumerRoot) {
38848
39550
  }
38849
39551
  return EXIT_ALLOW35;
38850
39552
  }
38851
- function main67() {
39553
+ function main69() {
38852
39554
  const raw = readHookStdin();
38853
39555
  let envelope = {};
38854
39556
  try {
@@ -38858,20 +39560,20 @@ function main67() {
38858
39560
  }
38859
39561
  return processEnvelope7(envelope, resolveConsumerRoot3(envelope));
38860
39562
  }
38861
- function _isCliEntry50() {
39563
+ function _isCliEntry52() {
38862
39564
  if (true) {
38863
39565
  return false;
38864
39566
  }
38865
39567
  if (process.argv[1] === void 0) return false;
38866
- const argvUrl = pathToFileURL60(path105.resolve(process.argv[1])).href;
39568
+ const argvUrl = pathToFileURL62(path110.resolve(process.argv[1])).href;
38867
39569
  if (import.meta.url === argvUrl) return true;
38868
39570
  try {
38869
- return fs103.realpathSync(fileURLToPath69(import.meta.url)) === fs103.realpathSync(path105.resolve(process.argv[1]));
39571
+ return fs107.realpathSync(fileURLToPath72(import.meta.url)) === fs107.realpathSync(path110.resolve(process.argv[1]));
38870
39572
  } catch {
38871
39573
  return false;
38872
39574
  }
38873
39575
  }
38874
- if (_isCliEntry50()) process.exit(main67());
39576
+ if (_isCliEntry52()) process.exit(main69());
38875
39577
 
38876
39578
  // src/scripts/hooks/concern_registry.ts
38877
39579
  var CONCERN_REGISTRY = {
@@ -38920,22 +39622,23 @@ var CONCERN_REGISTRY = {
38920
39622
  "src/scripts/hooks/skill_route_hook.ts": main52,
38921
39623
  "src/scripts/hooks/rule_inject_hook.ts": main53,
38922
39624
  "src/scripts/hooks/end_review_nudge_hook.ts": main54,
38923
- "src/scripts/hooks/turn_end_gate_hook.ts": main56,
38924
- "src/scripts/hooks/edit_shape_hook.ts": main57,
38925
- "src/scripts/hooks/comment_discipline_hook.ts": main59,
38926
- "src/scripts/hooks/reread_guard_hook.ts": main60,
38927
- "src/scripts/hooks/session_eol_hook.ts": main61,
38928
- "src/scripts/hooks/subagent_ledger_hook.ts": main55,
38929
- "src/scripts/hooks/tool_result_bytes_hook.ts": main62,
38930
- "src/scripts/hooks/spawn_guard_shadow_hook.ts": main63,
38931
- "src/scripts/hooks/source_first_gate_hook.ts": main64,
38932
- "src/scripts/hooks/interruption_ledger_hook.ts": main65,
38933
- "src/scripts/hooks/run_continuation_hook.ts": main66,
38934
- "src/scripts/hooks/journal_record_hook.ts": main67
39625
+ "src/scripts/hooks/review_baseline_hook.ts": main55,
39626
+ "src/scripts/hooks/turn_end_gate_hook.ts": main58,
39627
+ "src/scripts/hooks/edit_shape_hook.ts": main59,
39628
+ "src/scripts/hooks/comment_discipline_hook.ts": main61,
39629
+ "src/scripts/hooks/reread_guard_hook.ts": main62,
39630
+ "src/scripts/hooks/session_eol_hook.ts": main63,
39631
+ "src/scripts/hooks/subagent_ledger_hook.ts": main57,
39632
+ "src/scripts/hooks/tool_result_bytes_hook.ts": main64,
39633
+ "src/scripts/hooks/spawn_guard_shadow_hook.ts": main65,
39634
+ "src/scripts/hooks/source_first_gate_hook.ts": main66,
39635
+ "src/scripts/hooks/interruption_ledger_hook.ts": main67,
39636
+ "src/scripts/hooks/run_continuation_hook.ts": main68,
39637
+ "src/scripts/hooks/journal_record_hook.ts": main69
38935
39638
  };
38936
39639
 
38937
39640
  // src/scripts/hooks/category_a.ts
38938
- import * as path106 from "node:path";
39641
+ import * as path111 from "node:path";
38939
39642
  var READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
38940
39643
  "Read",
38941
39644
  "Glob",
@@ -39114,10 +39817,10 @@ var SCRIPT_TAKING_SUBCOMMANDS = /* @__PURE__ */ new Set([
39114
39817
  ]);
39115
39818
  function isInsideWorkingTree(candidate, root) {
39116
39819
  if (!candidate.trim() || !root.trim()) return false;
39117
- const abs = path106.resolve(root, candidate);
39118
- const rel = path106.relative(path106.resolve(root), abs);
39820
+ const abs = path111.resolve(root, candidate);
39821
+ const rel = path111.relative(path111.resolve(root), abs);
39119
39822
  if (rel === "") return true;
39120
- return !rel.startsWith("..") && !path106.isAbsolute(rel);
39823
+ return !rel.startsWith("..") && !path111.isAbsolute(rel);
39121
39824
  }
39122
39825
  function _argv(command) {
39123
39826
  return command.trim().split(/\s+/).filter((t) => t.length > 0);
@@ -39145,7 +39848,7 @@ function _gitSubcommand(argv) {
39145
39848
  if (!_isFlag(token)) return token;
39146
39849
  const [flag, inlineValue] = token.includes("=") ? [token.slice(0, token.indexOf("=")), token.slice(token.indexOf("=") + 1)] : [token, null];
39147
39850
  const value = inlineValue ?? (GIT_VALUE_FLAGS.has(flag) ? argv[++i] : void 0);
39148
- if (value !== void 0 && (path106.isAbsolute(value) || value.split("/").includes(".."))) {
39851
+ if (value !== void 0 && (path111.isAbsolute(value) || value.split("/").includes(".."))) {
39149
39852
  return "";
39150
39853
  }
39151
39854
  }
@@ -39348,8 +40051,8 @@ function _py_json_dumps2(value, indent) {
39348
40051
 
39349
40052
  // src/scripts/_lib/collector_denominator.ts
39350
40053
  import crypto15 from "node:crypto";
39351
- import fs105 from "node:fs";
39352
- import path108 from "node:path";
40054
+ import fs109 from "node:fs";
40055
+ import path113 from "node:path";
39353
40056
 
39354
40057
  // src/scripts/_lib/collector_record.ts
39355
40058
  var COLLECTOR_EVENTS = [
@@ -39426,30 +40129,30 @@ var FIELD_PURPOSE = {
39426
40129
  var ALLOWED_FIELDS = new Set(Object.keys(FIELD_PURPOSE));
39427
40130
 
39428
40131
  // src/scripts/_lib/collector_store.ts
39429
- import * as fs104 from "node:fs";
40132
+ import * as fs108 from "node:fs";
39430
40133
  import * as os13 from "node:os";
39431
- import * as path107 from "node:path";
40134
+ import * as path112 from "node:path";
39432
40135
  var COLLECTOR_DIR_NAME = "agent-collector";
39433
40136
  var COLLECTOR_FILE_NAME = "collector.sqlite";
39434
40137
  var OPT_OUT_MARKER_NAME = "OPT-OUT";
39435
40138
  var MIGRATION_MARKER_NAME = "MIGRATION-IN-FLIGHT";
39436
40139
  var QUARANTINE_DIR_NAME = "quarantine";
39437
40140
  function defaultUserRoot() {
39438
- return path107.join(os13.homedir(), ".event4u", "agent-config");
40141
+ return path112.join(os13.homedir(), ".event4u", "agent-config");
39439
40142
  }
39440
40143
  function resolveCollectorStore(userRoot = defaultUserRoot()) {
39441
- const dir = path107.join(userRoot, COLLECTOR_DIR_NAME);
40144
+ const dir = path112.join(userRoot, COLLECTOR_DIR_NAME);
39442
40145
  return {
39443
40146
  userRoot,
39444
40147
  root: dir,
39445
- path: path107.join(dir, COLLECTOR_FILE_NAME),
39446
- optOutMarker: path107.join(dir, OPT_OUT_MARKER_NAME),
39447
- migrationMarker: path107.join(dir, MIGRATION_MARKER_NAME),
39448
- quarantineDir: path107.join(dir, QUARANTINE_DIR_NAME)
40148
+ path: path112.join(dir, COLLECTOR_FILE_NAME),
40149
+ optOutMarker: path112.join(dir, OPT_OUT_MARKER_NAME),
40150
+ migrationMarker: path112.join(dir, MIGRATION_MARKER_NAME),
40151
+ quarantineDir: path112.join(dir, QUARANTINE_DIR_NAME)
39449
40152
  };
39450
40153
  }
39451
40154
  function isOptedOut(userRoot = defaultUserRoot()) {
39452
- return fs104.existsSync(resolveCollectorStore(userRoot).optOutMarker);
40155
+ return fs108.existsSync(resolveCollectorStore(userRoot).optOutMarker);
39453
40156
  }
39454
40157
  var MIGRATIONS = Object.freeze({
39455
40158
  // 0 → 1. No DDL: `user_version` 0 is the default SQLite assigns, and a
@@ -39466,24 +40169,24 @@ var SPOOL_DIR_NAME = "spool";
39466
40169
  var SPOOL_PENDING_NAME = "pending.jsonl";
39467
40170
  var ENABLED_MARKER_NAME = "ENABLED";
39468
40171
  function denominatorPath(userRoot) {
39469
- return path108.join(resolveCollectorStore(userRoot).root, DENOMINATOR_FILE_NAME);
40172
+ return path113.join(resolveCollectorStore(userRoot).root, DENOMINATOR_FILE_NAME);
39470
40173
  }
39471
40174
  function spoolDir(userRoot) {
39472
- return path108.join(resolveCollectorStore(userRoot).root, SPOOL_DIR_NAME);
40175
+ return path113.join(resolveCollectorStore(userRoot).root, SPOOL_DIR_NAME);
39473
40176
  }
39474
40177
  function spoolPendingPath(userRoot) {
39475
- return path108.join(spoolDir(userRoot), SPOOL_PENDING_NAME);
40178
+ return path113.join(spoolDir(userRoot), SPOOL_PENDING_NAME);
39476
40179
  }
39477
40180
  function enabledMarkerPath(userRoot) {
39478
- return path108.join(resolveCollectorStore(userRoot).root, ENABLED_MARKER_NAME);
40181
+ return path113.join(resolveCollectorStore(userRoot).root, ENABLED_MARKER_NAME);
39479
40182
  }
39480
40183
  function isCollectorEnabled(userRoot) {
39481
40184
  if (isOptedOut(userRoot)) return false;
39482
- if (fs105.existsSync(killSwitchPathLocal(userRoot))) return false;
39483
- return fs105.existsSync(enabledMarkerPath(userRoot));
40185
+ if (fs109.existsSync(killSwitchPathLocal(userRoot))) return false;
40186
+ return fs109.existsSync(enabledMarkerPath(userRoot));
39484
40187
  }
39485
40188
  function killSwitchPathLocal(userRoot) {
39486
- return path108.join(resolveCollectorStore(userRoot).root, "STOP");
40189
+ return path113.join(resolveCollectorStore(userRoot).root, "STOP");
39487
40190
  }
39488
40191
  function utcDate(at = Date.now()) {
39489
40192
  return new Date(at).toISOString().slice(0, 10);
@@ -39495,8 +40198,8 @@ function recordOpportunity(event, platform, userRoot, at = Date.now(), opts = {}
39495
40198
  if (!COLLECTOR_EVENTS.includes(event)) return false;
39496
40199
  if (!COLLECTOR_PLATFORMS.includes(platform)) return false;
39497
40200
  const target = denominatorPath(userRoot);
39498
- fs105.mkdirSync(path108.dirname(target), { recursive: true });
39499
- fs105.appendFileSync(target, `${utcDate(at)} ${event} ${platform}
40201
+ fs109.mkdirSync(path113.dirname(target), { recursive: true });
40202
+ fs109.appendFileSync(target, `${utcDate(at)} ${event} ${platform}
39500
40203
  `);
39501
40204
  return true;
39502
40205
  } catch {
@@ -39510,19 +40213,19 @@ var MACHINE_ID_NAME = "machine-id";
39510
40213
  var EPISODE_DIR_NAME = "episodes";
39511
40214
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
39512
40215
  function machineIdPath(userRoot) {
39513
- return path108.join(resolveCollectorStore(userRoot).root, MACHINE_ID_NAME);
40216
+ return path113.join(resolveCollectorStore(userRoot).root, MACHINE_ID_NAME);
39514
40217
  }
39515
40218
  function machineId(userRoot) {
39516
40219
  const target = machineIdPath(userRoot);
39517
40220
  try {
39518
- const existing = fs105.readFileSync(target, "utf8").trim();
40221
+ const existing = fs109.readFileSync(target, "utf8").trim();
39519
40222
  if (UUID_RE.test(existing)) return existing;
39520
40223
  } catch {
39521
40224
  }
39522
40225
  try {
39523
40226
  const minted = crypto15.randomUUID();
39524
- fs105.mkdirSync(path108.dirname(target), { recursive: true });
39525
- fs105.writeFileSync(target, `${minted}
40227
+ fs109.mkdirSync(path113.dirname(target), { recursive: true });
40228
+ fs109.writeFileSync(target, `${minted}
39526
40229
  `);
39527
40230
  return minted;
39528
40231
  } catch {
@@ -39546,17 +40249,17 @@ function episodeId(env = process.env) {
39546
40249
  ].join("-");
39547
40250
  }
39548
40251
  function nextSequence(episode, userRoot) {
39549
- const dir = path108.join(resolveCollectorStore(userRoot).root, EPISODE_DIR_NAME);
39550
- const target = path108.join(dir, `${episode}.seq`);
40252
+ const dir = path113.join(resolveCollectorStore(userRoot).root, EPISODE_DIR_NAME);
40253
+ const target = path113.join(dir, `${episode}.seq`);
39551
40254
  try {
39552
- fs105.mkdirSync(dir, { recursive: true });
40255
+ fs109.mkdirSync(dir, { recursive: true });
39553
40256
  let current = 0;
39554
40257
  try {
39555
- const raw = Number.parseInt(fs105.readFileSync(target, "utf8").trim(), 10);
40258
+ const raw = Number.parseInt(fs109.readFileSync(target, "utf8").trim(), 10);
39556
40259
  if (Number.isInteger(raw) && raw >= 0) current = raw + 1;
39557
40260
  } catch {
39558
40261
  }
39559
- fs105.writeFileSync(target, `${current}
40262
+ fs109.writeFileSync(target, `${current}
39560
40263
  `);
39561
40264
  return current;
39562
40265
  } catch {
@@ -39595,12 +40298,12 @@ function spoolRecord(record, userRoot) {
39595
40298
  try {
39596
40299
  if (!isCollectorEnabled(userRoot)) return false;
39597
40300
  const target = spoolPendingPath(userRoot);
39598
- fs105.mkdirSync(path108.dirname(target), { recursive: true });
40301
+ fs109.mkdirSync(path113.dirname(target), { recursive: true });
39599
40302
  try {
39600
- if (fs105.statSync(target).size >= SPOOL_MAX_BYTES) return false;
40303
+ if (fs109.statSync(target).size >= SPOOL_MAX_BYTES) return false;
39601
40304
  } catch {
39602
40305
  }
39603
- fs105.appendFileSync(target, `${JSON.stringify(record)}
40306
+ fs109.appendFileSync(target, `${JSON.stringify(record)}
39604
40307
  `);
39605
40308
  return true;
39606
40309
  } catch {
@@ -39609,12 +40312,12 @@ function spoolRecord(record, userRoot) {
39609
40312
  }
39610
40313
 
39611
40314
  // src/scripts/hooks/dispatch_hook.ts
39612
- var _IN_BUNDLE2 = true;
39613
- var REPO_ROOT = path109.resolve(
39614
- path109.dirname(fileURLToPath70(import.meta.url)),
39615
- ..._IN_BUNDLE2 ? ["..", ".."] : ["..", "..", ".."]
40315
+ var _IN_BUNDLE3 = true;
40316
+ var REPO_ROOT = path114.resolve(
40317
+ path114.dirname(fileURLToPath73(import.meta.url)),
40318
+ ..._IN_BUNDLE3 ? ["..", ".."] : ["..", "..", ".."]
39616
40319
  );
39617
- var MANIFEST_PATH = path109.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
40320
+ var MANIFEST_PATH = path114.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
39618
40321
  var EXIT_ALLOW37 = 0;
39619
40322
  var EXIT_BLOCK6 = 1;
39620
40323
  var EXIT_WARN19 = 2;
@@ -39676,11 +40379,11 @@ function _manifest_fingerprint(text) {
39676
40379
  return `${h.toString(16)}:${String(text.length)}`;
39677
40380
  }
39678
40381
  function _load_yaml3(p) {
39679
- const text = fs106.readFileSync(p, "utf-8");
40382
+ const text = fs110.readFileSync(p, "utf-8");
39680
40383
  const compiled = p.replace(/\.ya?ml$/u, ".json");
39681
40384
  if (compiled !== p) {
39682
40385
  try {
39683
- const raw = JSON.parse(fs106.readFileSync(compiled, "utf-8"));
40386
+ const raw = JSON.parse(fs110.readFileSync(compiled, "utf-8"));
39684
40387
  if (_isObject18(raw) && raw["fingerprint"] === _manifest_fingerprint(text) && _isObject18(raw["manifest"])) {
39685
40388
  return raw["manifest"];
39686
40389
  }
@@ -39778,7 +40481,7 @@ function _maybe_capture_payload(args, payload_text) {
39778
40481
  }
39779
40482
  try {
39780
40483
  const target = _expanduser3(capture_dir);
39781
- fs106.mkdirSync(target, { recursive: true });
40484
+ fs110.mkdirSync(target, { recursive: true });
39782
40485
  let payload;
39783
40486
  try {
39784
40487
  payload = payload_text.trim() ? JSON.parse(payload_text) : {};
@@ -39795,8 +40498,8 @@ function _maybe_capture_payload(args, payload_text) {
39795
40498
  const ts = Date.now();
39796
40499
  const native = (args.native_event || args.event).replace(/\//g, "_");
39797
40500
  const fname = `${args.platform}__${native}__${ts}__${process.pid}.json`;
39798
- fs106.writeFileSync(
39799
- path109.join(target, fname),
40501
+ fs110.writeFileSync(
40502
+ path114.join(target, fname),
39800
40503
  _py_json_dumps2(record, 2) + "\n",
39801
40504
  { encoding: "utf-8" }
39802
40505
  );
@@ -39807,7 +40510,7 @@ function _maybe_capture_payload(args, payload_text) {
39807
40510
  function _expanduser3(p) {
39808
40511
  if (p === "~" || p.startsWith("~/")) {
39809
40512
  const home = process.env["HOME"] || process.env["USERPROFILE"] || "";
39810
- return path109.join(home, p.slice(1));
40513
+ return path114.join(home, p.slice(1));
39811
40514
  }
39812
40515
  return p;
39813
40516
  }
@@ -39840,25 +40543,25 @@ function _resolve_tsx_invocation2(scriptPath, scriptArgs) {
39840
40543
  const walkUp = (start) => {
39841
40544
  let dir = start;
39842
40545
  for (; ; ) {
39843
- const candidate = path109.join(dir, "node_modules", ".bin", binName);
40546
+ const candidate = path114.join(dir, "node_modules", ".bin", binName);
39844
40547
  if (_isFile8(candidate)) {
39845
40548
  return candidate;
39846
40549
  }
39847
- const parent = path109.dirname(dir);
40550
+ const parent = path114.dirname(dir);
39848
40551
  if (parent === dir) {
39849
40552
  return null;
39850
40553
  }
39851
40554
  dir = parent;
39852
40555
  }
39853
40556
  };
39854
- const tsx = walkUp(path109.dirname(scriptPath)) ?? walkUp(path109.dirname(fileURLToPath70(import.meta.url)));
40557
+ const tsx = walkUp(path114.dirname(scriptPath)) ?? walkUp(path114.dirname(fileURLToPath73(import.meta.url)));
39855
40558
  if (tsx !== null) {
39856
40559
  return { command: tsx, args: [scriptPath, ...scriptArgs] };
39857
40560
  }
39858
40561
  return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
39859
40562
  }
39860
40563
  function _run_concern_inproc(main_fn, concern, envelope) {
39861
- const scriptAbs = path109.join(REPO_ROOT, String(concern["script"]));
40564
+ const scriptAbs = path114.join(REPO_ROOT, String(concern["script"]));
39862
40565
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
39863
40566
  argsList.push("--platform", String(envelope["platform"] || "generic"));
39864
40567
  const workspace = String(envelope["workspace_root"] || process.cwd());
@@ -39894,7 +40597,7 @@ function _run_concern_inproc(main_fn, concern, envelope) {
39894
40597
  if (!(k in hardened)) delete process.env[k];
39895
40598
  }
39896
40599
  Object.assign(process.env, hardened);
39897
- if (workspace !== prevCwd && _isDir4(workspace)) {
40600
+ if (workspace !== prevCwd && _isDir6(workspace)) {
39898
40601
  process.chdir(workspace);
39899
40602
  }
39900
40603
  const result = main_fn(argsList);
@@ -39935,7 +40638,7 @@ function _run_concern(concern, envelope) {
39935
40638
  return _run_concern_inproc(inproc, concern, envelope);
39936
40639
  }
39937
40640
  }
39938
- const script = path109.join(REPO_ROOT, String(concern["script"]));
40641
+ const script = path114.join(REPO_ROOT, String(concern["script"]));
39939
40642
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
39940
40643
  const cmd = [script, ...argsList];
39941
40644
  cmd.push("--platform", String(envelope["platform"] || "generic"));
@@ -39958,7 +40661,7 @@ function _run_concern(concern, envelope) {
39958
40661
  const concern_env = hardenedSpawnEnv({ AGENT_CONFIG_PACKAGE_ROOT: REPO_ROOT });
39959
40662
  const started = performance.now();
39960
40663
  const { command, args: spawnArgs } = _resolve_tsx_invocation2(script, cmd.slice(1));
39961
- const proc = spawnSync10(command, spawnArgs, {
40664
+ const proc = spawnSync11(command, spawnArgs, {
39962
40665
  input: _compactJsonDumps(envelope),
39963
40666
  encoding: "utf-8",
39964
40667
  cwd: workspace,
@@ -39992,7 +40695,7 @@ function _run_concern(concern, envelope) {
39992
40695
  }
39993
40696
  function _isFile8(p) {
39994
40697
  try {
39995
- return fs106.statSync(p).isFile();
40698
+ return fs110.statSync(p).isFile();
39996
40699
  } catch {
39997
40700
  return false;
39998
40701
  }
@@ -40014,10 +40717,10 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
40014
40717
  return;
40015
40718
  }
40016
40719
  const workspace = String(envelope["workspace_root"] || process.cwd());
40017
- const state_root = path109.join(workspace, "agents", "runtime", "state");
40720
+ const state_root = path114.join(workspace, "agents", "runtime", "state");
40018
40721
  const fb_dir = feedback_dir(state_root, session_id);
40019
40722
  try {
40020
- fs106.mkdirSync(fb_dir, { recursive: true });
40723
+ fs110.mkdirSync(fb_dir, { recursive: true });
40021
40724
  } catch (exc) {
40022
40725
  const msg = exc instanceof Error ? exc.message : String(exc);
40023
40726
  process.stderr.write(`dispatch_hook: feedback dir unavailable: ${msg}
@@ -40025,7 +40728,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
40025
40728
  return;
40026
40729
  }
40027
40730
  for (const entry of entries) {
40028
- const target = path109.join(fb_dir, `${entry["concern"]}.json`);
40731
+ const target = path114.join(fb_dir, `${entry["concern"]}.json`);
40029
40732
  try {
40030
40733
  atomic_write_json(target, entry);
40031
40734
  } catch (exc) {
@@ -40074,7 +40777,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
40074
40777
  };
40075
40778
  try {
40076
40779
  const invocation = `${String(process.pid)}-${process.hrtime.bigint().toString()}`;
40077
- update_json_under_lock(path109.join(fb_dir, "summary.json"), (loaded) => {
40780
+ update_json_under_lock(path114.join(fb_dir, "summary.json"), (loaded) => {
40078
40781
  const priorRaw = loaded["invocations"];
40079
40782
  const prior = Array.isArray(priorRaw) ? priorRaw : [];
40080
40783
  const next = [...prior, { invocation, ...summary }];
@@ -40101,8 +40804,8 @@ function _record_rule_trips(envelope, entries) {
40101
40804
  if (tripped.length === 0) return;
40102
40805
  try {
40103
40806
  const workspace = String(envelope["workspace_root"] || process.cwd());
40104
- const state_dir = path109.join(workspace, "agents", "runtime", "state");
40105
- const target = path109.join(state_dir, "rule-trips.json");
40807
+ const state_dir = path114.join(workspace, "agents", "runtime", "state");
40808
+ const target = path114.join(state_dir, "rule-trips.json");
40106
40809
  const today = _now_iso3().slice(0, 10);
40107
40810
  update_json_under_lock(target, (loaded) => {
40108
40811
  const doc = { schema_version: 1, concerns: {}, ...loaded };
@@ -40207,11 +40910,11 @@ function _parse_args(argv) {
40207
40910
  }
40208
40911
  return args;
40209
40912
  }
40210
- function main68(argv) {
40913
+ function main70(argv) {
40211
40914
  const args = _parse_args(argv ?? process.argv.slice(2));
40212
40915
  if (args.project_dir) {
40213
40916
  const project_dir = _expanduser3(args.project_dir);
40214
- if (_isDir4(project_dir)) {
40917
+ if (_isDir6(project_dir)) {
40215
40918
  process.chdir(project_dir);
40216
40919
  } else {
40217
40920
  process.stderr.write(
@@ -40244,7 +40947,7 @@ function main68(argv) {
40244
40947
  recordOpportunity(args.event, args.platform);
40245
40948
  recordCapture(args.event, args.platform);
40246
40949
  const manifest_path = args.manifest;
40247
- if (!fs106.existsSync(manifest_path)) {
40950
+ if (!fs110.existsSync(manifest_path)) {
40248
40951
  process.stderr.write(`dispatch_hook: manifest missing at ${manifest_path}
40249
40952
  `);
40250
40953
  return EXIT_ALLOW37;
@@ -40412,9 +41115,9 @@ function main68(argv) {
40412
41115
  }
40413
41116
  return emission.exit;
40414
41117
  }
40415
- function _isDir4(p) {
41118
+ function _isDir6(p) {
40416
41119
  try {
40417
- return fs106.statSync(p).isDirectory();
41120
+ return fs110.statSync(p).isDirectory();
40418
41121
  } catch {
40419
41122
  return false;
40420
41123
  }
@@ -40424,36 +41127,36 @@ function _sortedRepr(s) {
40424
41127
  return `[${items.map((x) => `'${x}'`).join(", ")}]`;
40425
41128
  }
40426
41129
  var _stdin_read_failed = null;
40427
- function _isCliEntry51() {
41130
+ function _isCliEntry53() {
40428
41131
  if (true) {
40429
41132
  return false;
40430
41133
  }
40431
41134
  if (process.argv[1] === void 0) {
40432
41135
  return false;
40433
41136
  }
40434
- const argvUrl = pathToFileURL61(path109.resolve(process.argv[1])).href;
41137
+ const argvUrl = pathToFileURL63(path114.resolve(process.argv[1])).href;
40435
41138
  if (import.meta.url === argvUrl) {
40436
41139
  return true;
40437
41140
  }
40438
41141
  try {
40439
- const here = fs106.realpathSync(fileURLToPath70(import.meta.url));
40440
- const argv = fs106.realpathSync(path109.resolve(process.argv[1]));
41142
+ const here = fs110.realpathSync(fileURLToPath73(import.meta.url));
41143
+ const argv = fs110.realpathSync(path114.resolve(process.argv[1]));
40441
41144
  return here === argv;
40442
41145
  } catch {
40443
41146
  return false;
40444
41147
  }
40445
41148
  }
40446
- var isCliEntry16 = _isCliEntry51();
41149
+ var isCliEntry16 = _isCliEntry53();
40447
41150
  if (isCliEntry16) {
40448
- process.exit(main68(process.argv.slice(2)));
41151
+ process.exit(main70(process.argv.slice(2)));
40449
41152
  }
40450
41153
 
40451
41154
  // src/scripts/hooks/dispatch_entry.ts
40452
- var _selfPath = fileURLToPath71(import.meta.url);
40453
- var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path110.resolve(process.argv[1]) === path110.resolve(_selfPath);
41155
+ var _selfPath = fileURLToPath74(import.meta.url);
41156
+ var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path115.resolve(process.argv[1]) === path115.resolve(_selfPath);
40454
41157
  if (_invokedDirectly2) {
40455
- process.exitCode = main68(process.argv.slice(2));
41158
+ process.exitCode = main70(process.argv.slice(2));
40456
41159
  }
40457
41160
  export {
40458
- main68 as main
41161
+ main70 as main
40459
41162
  };