@event4u/agent-config 9.23.0 → 9.25.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 (52) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +82 -0
  3. package/README.md +2 -2
  4. package/dist/agent-src/commands/agent-handoff.md +10 -3
  5. package/dist/agent-src/commands/analyze/conformance.md +182 -0
  6. package/dist/agent-src/commands/analyze/inbox.md +221 -0
  7. package/dist/agent-src/commands/analyze.md +4 -3
  8. package/dist/agent-src/commands/pr/create.md +6 -6
  9. package/dist/agent-src/rules/context-hygiene.md +3 -0
  10. package/dist/agent-src/rules/decision-revisit-gate.md +2 -0
  11. package/dist/agent-src/rules/evaluator-independence.md +105 -0
  12. package/dist/agent-src/rules/session-canary.md +13 -1
  13. package/dist/agent-src/rules/user-interaction.md +22 -0
  14. package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +1 -1
  15. package/dist/agent-src/skills/rule-writing/SKILL.md +45 -0
  16. package/dist/agent-src/skills/skill-writing/SKILL.md +114 -0
  17. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  18. package/dist/cli/registry.js +1 -0
  19. package/dist/cli/registry.js.map +1 -1
  20. package/dist/discovery/deprecation-report.md +1 -1
  21. package/dist/discovery/discovery-manifest.json +96 -22
  22. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  23. package/dist/discovery/discovery-manifest.summary.md +4 -4
  24. package/dist/discovery/orphan-report.md +1 -1
  25. package/dist/discovery/packs.json +11 -8
  26. package/dist/discovery/trust-report.md +3 -3
  27. package/dist/discovery/workspaces.json +9 -6
  28. package/dist/hooks/dispatch.js +1026 -328
  29. package/dist/mcp/registry-manifest.json +2 -2
  30. package/dist/mcp/server.json +2 -2
  31. package/dist/router.json +1 -1
  32. package/package.json +1 -1
  33. package/src/config/evaluator-budgets.json +68 -68
  34. package/src/config/gate-coverage.yml +103 -5
  35. package/src/config/gate-violation-baselines.json +11 -6
  36. package/src/scripts/_dispatch.bash +12 -0
  37. package/src/scripts/before_complete_hook.ts +127 -5
  38. package/src/scripts/check_depth_budget.ts +295 -0
  39. package/src/scripts/conformance_scan.ts +392 -0
  40. package/src/scripts/git_authorization_hook.ts +263 -0
  41. package/src/scripts/hook_manifest.yaml +50 -9
  42. package/src/scripts/hooks/block_unauthorized_git.ts +254 -0
  43. package/src/scripts/hooks/concern_registry.ts +8 -0
  44. package/src/scripts/hooks/evidence_independence.ts +334 -0
  45. package/src/scripts/language_mirror_hook.ts +267 -0
  46. package/src/scripts/lint_decision_impact.ts +246 -0
  47. package/src/scripts/lint_example_fences.ts +609 -0
  48. package/src/scripts/lint_rule_interactions.ts +90 -0
  49. package/src/scripts/lint_rule_migration_ledger.ts +480 -0
  50. package/src/scripts/lint_skill_descriptions.ts +86 -2
  51. package/src/scripts/measure_rule_absoluta.ts +231 -0
  52. package/src/scripts/schemas/rule.schema.json +10 -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, path43) {
116
- const ctrl = callVisitor(key, node, visitor, path43);
115
+ function visit_(key, node, visitor, path47) {
116
+ const ctrl = callVisitor(key, node, visitor, path47);
117
117
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
118
- replaceNode(key, path43, ctrl);
119
- return visit_(key, ctrl, visitor, path43);
118
+ replaceNode(key, path47, ctrl);
119
+ return visit_(key, ctrl, visitor, path47);
120
120
  }
121
121
  if (typeof ctrl !== "symbol") {
122
122
  if (identity.isCollection(node)) {
123
- path43 = Object.freeze(path43.concat(node));
123
+ path47 = Object.freeze(path47.concat(node));
124
124
  for (let i = 0; i < node.items.length; ++i) {
125
- const ci = visit_(i, node.items[i], visitor, path43);
125
+ const ci = visit_(i, node.items[i], visitor, path47);
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
- path43 = Object.freeze(path43.concat(node));
137
- const ck = visit_("key", node.key, visitor, path43);
136
+ path47 = Object.freeze(path47.concat(node));
137
+ const ck = visit_("key", node.key, visitor, path47);
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, path43);
142
+ const cv = visit_("value", node.value, visitor, path47);
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, path43) {
164
- const ctrl = await callVisitor(key, node, visitor, path43);
163
+ async function visitAsync_(key, node, visitor, path47) {
164
+ const ctrl = await callVisitor(key, node, visitor, path47);
165
165
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
166
- replaceNode(key, path43, ctrl);
167
- return visitAsync_(key, ctrl, visitor, path43);
166
+ replaceNode(key, path47, ctrl);
167
+ return visitAsync_(key, ctrl, visitor, path47);
168
168
  }
169
169
  if (typeof ctrl !== "symbol") {
170
170
  if (identity.isCollection(node)) {
171
- path43 = Object.freeze(path43.concat(node));
171
+ path47 = Object.freeze(path47.concat(node));
172
172
  for (let i = 0; i < node.items.length; ++i) {
173
- const ci = await visitAsync_(i, node.items[i], visitor, path43);
173
+ const ci = await visitAsync_(i, node.items[i], visitor, path47);
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
- path43 = Object.freeze(path43.concat(node));
185
- const ck = await visitAsync_("key", node.key, visitor, path43);
184
+ path47 = Object.freeze(path47.concat(node));
185
+ const ck = await visitAsync_("key", node.key, visitor, path47);
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, path43);
190
+ const cv = await visitAsync_("value", node.value, visitor, path47);
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, path43) {
217
+ function callVisitor(key, node, visitor, path47) {
218
218
  if (typeof visitor === "function")
219
- return visitor(key, node, path43);
219
+ return visitor(key, node, path47);
220
220
  if (identity.isMap(node))
221
- return visitor.Map?.(key, node, path43);
221
+ return visitor.Map?.(key, node, path47);
222
222
  if (identity.isSeq(node))
223
- return visitor.Seq?.(key, node, path43);
223
+ return visitor.Seq?.(key, node, path47);
224
224
  if (identity.isPair(node))
225
- return visitor.Pair?.(key, node, path43);
225
+ return visitor.Pair?.(key, node, path47);
226
226
  if (identity.isScalar(node))
227
- return visitor.Scalar?.(key, node, path43);
227
+ return visitor.Scalar?.(key, node, path47);
228
228
  if (identity.isAlias(node))
229
- return visitor.Alias?.(key, node, path43);
229
+ return visitor.Alias?.(key, node, path47);
230
230
  return void 0;
231
231
  }
232
- function replaceNode(key, path43, node) {
233
- const parent = path43[path43.length - 1];
232
+ function replaceNode(key, path47, node) {
233
+ const parent = path47[path47.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, path43, value) {
843
+ function collectionFromPath(schema, path47, value) {
844
844
  let v = value;
845
- for (let i = path43.length - 1; i >= 0; --i) {
846
- const k = path43[i];
845
+ for (let i = path47.length - 1; i >= 0; --i) {
846
+ const k = path47[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 = (path43) => path43 == null || typeof path43 === "object" && !!path43[Symbol.iterator]().next().done;
865
+ var isEmptyPath = (path47) => path47 == null || typeof path47 === "object" && !!path47[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(path43, value) {
896
- if (isEmptyPath(path43))
895
+ addIn(path47, value) {
896
+ if (isEmptyPath(path47))
897
897
  this.add(value);
898
898
  else {
899
- const [key, ...rest] = path43;
899
+ const [key, ...rest] = path47;
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(path43) {
914
- const [key, ...rest] = path43;
913
+ deleteIn(path47) {
914
+ const [key, ...rest] = path47;
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(path43, keepScalar) {
929
- const [key, ...rest] = path43;
928
+ getIn(path47, keepScalar) {
929
+ const [key, ...rest] = path47;
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(path43) {
948
- const [key, ...rest] = path43;
947
+ hasIn(path47) {
948
+ const [key, ...rest] = path47;
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(path43, value) {
959
- const [key, ...rest] = path43;
958
+ setIn(path47, value) {
959
+ const [key, ...rest] = path47;
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(path43, value) {
3474
+ addIn(path47, value) {
3475
3475
  if (assertCollection(this.contents))
3476
- this.contents.addIn(path43, value);
3476
+ this.contents.addIn(path47, 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(path43) {
3552
- if (Collection.isEmptyPath(path43)) {
3551
+ deleteIn(path47) {
3552
+ if (Collection.isEmptyPath(path47)) {
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(path43) : false;
3558
+ return assertCollection(this.contents) ? this.contents.deleteIn(path47) : 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(path43, keepScalar) {
3574
- if (Collection.isEmptyPath(path43))
3573
+ getIn(path47, keepScalar) {
3574
+ if (Collection.isEmptyPath(path47))
3575
3575
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3576
- return identity.isCollection(this.contents) ? this.contents.getIn(path43, keepScalar) : void 0;
3576
+ return identity.isCollection(this.contents) ? this.contents.getIn(path47, 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(path43) {
3588
- if (Collection.isEmptyPath(path43))
3587
+ hasIn(path47) {
3588
+ if (Collection.isEmptyPath(path47))
3589
3589
  return this.contents !== void 0;
3590
- return identity.isCollection(this.contents) ? this.contents.hasIn(path43) : false;
3590
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path47) : 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(path43, value) {
3608
- if (Collection.isEmptyPath(path43)) {
3607
+ setIn(path47, value) {
3608
+ if (Collection.isEmptyPath(path47)) {
3609
3609
  this.contents = value;
3610
3610
  } else if (this.contents == null) {
3611
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path43), value);
3611
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path47), value);
3612
3612
  } else if (assertCollection(this.contents)) {
3613
- this.contents.setIn(path43, value);
3613
+ this.contents.setIn(path47, value);
3614
3614
  }
3615
3615
  }
3616
3616
  /**
@@ -5570,9 +5570,9 @@ var require_cst_visit = __commonJS({
5570
5570
  visit.BREAK = BREAK;
5571
5571
  visit.SKIP = SKIP;
5572
5572
  visit.REMOVE = REMOVE;
5573
- visit.itemAtPath = (cst, path43) => {
5573
+ visit.itemAtPath = (cst, path47) => {
5574
5574
  let item = cst;
5575
- for (const [field, index] of path43) {
5575
+ for (const [field, index] of path47) {
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, path43) => {
5585
- const parent = visit.itemAtPath(cst, path43.slice(0, -1));
5586
- const field = path43[path43.length - 1][0];
5584
+ visit.parentCollection = (cst, path47) => {
5585
+ const parent = visit.itemAtPath(cst, path47.slice(0, -1));
5586
+ const field = path47[path47.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(path43, item, visitor) {
5593
- let ctrl = visitor(item, path43);
5592
+ function _visit(path47, item, visitor) {
5593
+ let ctrl = visitor(item, path47);
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(path43.concat([[field, i]])), token.items[i], visitor);
5600
+ const ci = _visit(Object.freeze(path47.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, path43);
5611
+ ctrl = ctrl(item, path47);
5612
5612
  }
5613
5613
  }
5614
- return typeof ctrl === "function" ? ctrl(item, path43) : ctrl;
5614
+ return typeof ctrl === "function" ? ctrl(item, path47) : ctrl;
5615
5615
  }
5616
5616
  exports.visit = visit;
5617
5617
  }
@@ -6913,14 +6913,14 @@ var require_parser = __commonJS({
6913
6913
  case "scalar":
6914
6914
  case "single-quoted-scalar":
6915
6915
  case "double-quoted-scalar": {
6916
- const fs42 = this.flowScalar(this.type);
6916
+ const fs46 = this.flowScalar(this.type);
6917
6917
  if (atNextItem || it.value) {
6918
- map.items.push({ start, key: fs42, sep: [] });
6918
+ map.items.push({ start, key: fs46, sep: [] });
6919
6919
  this.onKeyLine = true;
6920
6920
  } else if (it.sep) {
6921
- this.stack.push(fs42);
6921
+ this.stack.push(fs46);
6922
6922
  } else {
6923
- Object.assign(it, { key: fs42, sep: [] });
6923
+ Object.assign(it, { key: fs46, 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 fs42 = this.flowScalar(this.type);
7051
+ const fs46 = this.flowScalar(this.type);
7052
7052
  if (!it || it.value)
7053
- fc.items.push({ start: [], key: fs42, sep: [] });
7053
+ fc.items.push({ start: [], key: fs46, sep: [] });
7054
7054
  else if (it.sep)
7055
- this.stack.push(fs42);
7055
+ this.stack.push(fs46);
7056
7056
  else
7057
- Object.assign(it, { key: fs42, sep: [] });
7057
+ Object.assign(it, { key: fs46, sep: [] });
7058
7058
  return;
7059
7059
  }
7060
7060
  case "flow-map-end":
@@ -7363,15 +7363,15 @@ var require_dist = __commonJS({
7363
7363
  });
7364
7364
 
7365
7365
  // src/scripts/hooks/dispatch_entry.ts
7366
- import * as path42 from "node:path";
7367
- import { fileURLToPath as fileURLToPath32 } from "node:url";
7366
+ import * as path46 from "node:path";
7367
+ import { fileURLToPath as fileURLToPath36 } from "node:url";
7368
7368
 
7369
7369
  // src/scripts/hooks/dispatch_hook.ts
7370
7370
  var import_yaml6 = __toESM(require_dist(), 1);
7371
7371
  import { spawnSync as spawnSync5 } from "node:child_process";
7372
- import fs41 from "node:fs";
7373
- import path41 from "node:path";
7374
- import { fileURLToPath as fileURLToPath31, pathToFileURL as pathToFileURL26 } from "node:url";
7372
+ import fs45 from "node:fs";
7373
+ import path45 from "node:path";
7374
+ import { fileURLToPath as fileURLToPath35, pathToFileURL as pathToFileURL30 } from "node:url";
7375
7375
 
7376
7376
  // src/scripts/_lib/spawn_env.ts
7377
7377
  var DENY_EXACT = /* @__PURE__ */ new Set([
@@ -15061,6 +15061,8 @@ function _empty_state2() {
15061
15061
  verifications_this_session: 0,
15062
15062
  last_stop_at: null,
15063
15063
  verified_this_turn: false,
15064
+ ci_saw_pending: false,
15065
+ nonevidence_this_turn: 0,
15064
15066
  checked_at: _now2()
15065
15067
  };
15066
15068
  }
@@ -15107,13 +15109,60 @@ function _extract_command(payload) {
15107
15109
  return [tool, null];
15108
15110
  }
15109
15111
  function _is_verification(command) {
15110
- return _VERIFICATION_RE.test(command);
15112
+ return _VERIFICATION_RE.test(command) || isCiPoll(command);
15113
+ }
15114
+ var _VACUOUS_PATTERNS = [
15115
+ // gh pr checks / gh run — no checks registered at all.
15116
+ /\b0\s+(?:checks?|runs?)\b/i,
15117
+ // Test runners reporting an empty run.
15118
+ /\bno tests? (?:ran|found|to run|were run)\b/i,
15119
+ /\bNo test files found\b/i,
15120
+ /\b0\s+pass(?:ed|ing)?\b[\s,|·]*\b0\s+fail(?:ed|ing|ures)?\b/i,
15121
+ /\bTests?\s+0\s+passed\b/i,
15122
+ /\bRan 0 tests?\b/i,
15123
+ // Linters / scanners with an empty target set.
15124
+ /\bno files? (?:matched|to (?:lint|check|scan)|found)\b/i,
15125
+ /\b0\s+files?\s+(?:checked|scanned|linted)\b/i,
15126
+ /\bnothing to check\b/i
15127
+ ];
15128
+ function isVacuousOutput(output) {
15129
+ const text = output.trim();
15130
+ if (!text) {
15131
+ return true;
15132
+ }
15133
+ return _VACUOUS_PATTERNS.some((re) => re.test(text));
15134
+ }
15135
+ var _CI_POLL_RE = /\bgh\s+(?:pr\s+checks|run\s+(?:watch|list|view))\b/i;
15136
+ function isCiPoll(command) {
15137
+ return _CI_POLL_RE.test(command);
15138
+ }
15139
+ function pendingCount(output) {
15140
+ const m = /(\d+)\s+(?:checks? )?pending\b/i.exec(output) ?? /\bpending[:=]\s*(\d+)/i.exec(output);
15141
+ if (m?.[1] !== void 0) {
15142
+ return Number(m[1]);
15143
+ }
15144
+ const rows = output.match(/^\S.*\b(pending|in_progress|queued)\b/gim);
15145
+ return rows ? rows.length : null;
15146
+ }
15147
+ function _extract_output(payload) {
15148
+ for (const key of ["tool_response", "toolResponse", "output", "stdout", "result"]) {
15149
+ const v = payload[key];
15150
+ if (typeof v === "string") {
15151
+ return v;
15152
+ }
15153
+ if (v !== null && typeof v === "object") {
15154
+ return JSON.stringify(v);
15155
+ }
15156
+ }
15157
+ return null;
15111
15158
  }
15112
15159
  function _reset_turn(state, session_id) {
15113
15160
  state["session_id"] = session_id || state["session_id"] || "";
15114
15161
  state["turn_started_at"] = _now2();
15115
15162
  state["verifications_this_turn"] = 0;
15116
15163
  state["verified_this_turn"] = false;
15164
+ state["ci_saw_pending"] = false;
15165
+ state["nonevidence_this_turn"] = 0;
15117
15166
  return state;
15118
15167
  }
15119
15168
  function _asInt2(v) {
@@ -15143,15 +15192,35 @@ function _update2(state, event, envelope) {
15143
15192
  } else if (event === "post_tool_use") {
15144
15193
  const [tool, cmd] = _extract_command(pl);
15145
15194
  if (cmd && _is_verification(cmd)) {
15195
+ const output = _extract_output(pl);
15196
+ const vacuous = output !== null && isVacuousOutput(output);
15197
+ let counts = !vacuous;
15198
+ if (isCiPoll(cmd)) {
15199
+ const pending = output === null ? null : pendingCount(output);
15200
+ if (pending !== null && pending > 0) {
15201
+ state["ci_saw_pending"] = true;
15202
+ counts = false;
15203
+ } else if (pending === 0) {
15204
+ counts = !vacuous && state["ci_saw_pending"] === true;
15205
+ } else {
15206
+ counts = false;
15207
+ }
15208
+ }
15146
15209
  state["last_verification"] = {
15147
15210
  command: cmd.slice(0, 512),
15148
15211
  tool,
15149
15212
  at: _now2(),
15150
- platform: envelope["platform"] || ""
15213
+ platform: envelope["platform"] || "",
15214
+ vacuous,
15215
+ counted: counts
15151
15216
  };
15152
- state["verifications_this_turn"] = _asInt2(state["verifications_this_turn"]) + 1;
15153
- state["verifications_this_session"] = _asInt2(state["verifications_this_session"]) + 1;
15154
- state["verified_this_turn"] = true;
15217
+ if (counts) {
15218
+ state["verifications_this_turn"] = _asInt2(state["verifications_this_turn"]) + 1;
15219
+ state["verifications_this_session"] = _asInt2(state["verifications_this_session"]) + 1;
15220
+ state["verified_this_turn"] = true;
15221
+ } else {
15222
+ state["nonevidence_this_turn"] = _asInt2(state["nonevidence_this_turn"]) + 1;
15223
+ }
15155
15224
  }
15156
15225
  } else if (event === "stop") {
15157
15226
  state["last_stop_at"] = _now2();
@@ -17398,11 +17467,636 @@ if (_isCliEntry18()) {
17398
17467
  process.exit(main22());
17399
17468
  }
17400
17469
 
17401
- // src/scripts/hooks/block_no_verify.ts
17402
- import * as fs33 from "node:fs";
17470
+ // src/scripts/language_mirror_hook.ts
17471
+ import fs33 from "node:fs";
17472
+ import path33 from "node:path";
17403
17473
  import { fileURLToPath as fileURLToPath25, pathToFileURL as pathToFileURL20 } from "node:url";
17404
- import * as path33 from "node:path";
17405
- var _HERE3 = fileURLToPath25(import.meta.url);
17474
+ var EXIT_ALLOW5 = 0;
17475
+ var STATE_FILE5 = path33.join("agents", "state", "language-mirror.json");
17476
+ function _isObject6(v) {
17477
+ return typeof v === "object" && v !== null && !Array.isArray(v);
17478
+ }
17479
+ var DE_MARKERS = /\b(der|die|das|den|dem|und|ist|sind|nicht|kein|keine|mach|mache|bitte|warum|wieso|weshalb|weiter|kannst|sollst|soll|musst|muss|hast|habe|haben|wir|ich|du|dann|noch|auch|schon|wenn|aber|alle|mit|ohne|damit|dass|wurde|werden|gibt|nochmal|erstell|erstelle|erstelle|fehler|regeln|arbeite|analysiere|fixe|nimm|lege|prüfe|pruefe|schau|zeig|mir|dir|sich|eine|einen|einem|einer|vom|zum|zur|beim|im|am)\b|[äöüÄÖÜß]/gi;
17480
+ var EN_MARKERS = /\b(the|and|is|are|was|were|not|please|why|because|should|would|could|there|these|those|with|from|about|which|that|this|will|have|has|been|they|them|their|your|our|what|when|where|make|need|want|does|doesn't|don't|it's|let's)\b/gi;
17481
+ var MIN_MARKERS = 2;
17482
+ function classify(prompt) {
17483
+ const de = (prompt.match(DE_MARKERS) ?? []).length;
17484
+ const en = (prompt.match(EN_MARKERS) ?? []).length;
17485
+ if (de < MIN_MARKERS && en < MIN_MARKERS) {
17486
+ return { language: "und", de_markers: de, en_markers: en };
17487
+ }
17488
+ return { language: de >= en ? "de" : "en", de_markers: de, en_markers: en };
17489
+ }
17490
+ var LANGUAGE_NAME = {
17491
+ de: "German (Deutsch)",
17492
+ en: "English"
17493
+ };
17494
+ function pinText(language) {
17495
+ const name = LANGUAGE_NAME[language];
17496
+ return `<language-pin>
17497
+ The user submitted this turn's prompt in ${name}. That is the mirror target for EVERY user-visible token of your replies this turn \u2014 including the short inter-tool lines between tool calls, headings, table cells, bullets, status lines, and the recommendation label under any numbered-options block.
17498
+
17499
+ This pin exists because the trigger is not observable from the transcript alone: slash-command and skill bodies arrive in the user role and can be long and English, which is what drove ~470 wrong-language turns in the sessions this hook was built from. Tool output, file contents, and an injected skill body are NOT the trigger \u2014 this pin is.
17500
+ </language-pin>`;
17501
+ }
17502
+ function _loadState(target) {
17503
+ try {
17504
+ const raw = fs33.readFileSync(target, "utf8");
17505
+ const decoded = JSON.parse(raw);
17506
+ return _isObject6(decoded) ? decoded : {};
17507
+ } catch {
17508
+ return {};
17509
+ }
17510
+ }
17511
+ function nextState(previous, classification, prompt_chars, session_id, now) {
17512
+ if (classification.language === "und") {
17513
+ return null;
17514
+ }
17515
+ return {
17516
+ language: classification.language,
17517
+ detected_at: now,
17518
+ prompt_chars,
17519
+ de_markers: classification.de_markers,
17520
+ en_markers: classification.en_markers,
17521
+ session_id
17522
+ };
17523
+ }
17524
+ function _extractPrompt(payload) {
17525
+ for (const key of ["prompt", "userPrompt", "user_prompt", "message", "text"]) {
17526
+ const v = payload[key];
17527
+ if (typeof v === "string" && v.trim()) {
17528
+ return v;
17529
+ }
17530
+ }
17531
+ return "";
17532
+ }
17533
+ function run7(stdin_text, options) {
17534
+ let envelope = {};
17535
+ if (stdin_text.trim()) {
17536
+ try {
17537
+ const decoded = JSON.parse(stdin_text);
17538
+ if (_isObject6(decoded)) {
17539
+ envelope = decoded;
17540
+ }
17541
+ } catch {
17542
+ return EXIT_ALLOW5;
17543
+ }
17544
+ }
17545
+ const payload = _isObject6(envelope["payload"]) ? envelope["payload"] : envelope;
17546
+ const prompt = _extractPrompt(payload);
17547
+ if (!prompt) {
17548
+ return EXIT_ALLOW5;
17549
+ }
17550
+ const session_id = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
17551
+ const target = path33.join(options.consumer_root, STATE_FILE5);
17552
+ const previous = _loadState(target);
17553
+ const classification = classify(prompt);
17554
+ const next = nextState(previous, classification, prompt.length, session_id, (/* @__PURE__ */ new Date()).toISOString());
17555
+ const effective = next?.language ?? previous.language;
17556
+ if (next) {
17557
+ try {
17558
+ atomic_write_json(target, next);
17559
+ } catch {
17560
+ }
17561
+ }
17562
+ if (effective === "de" || effective === "en") {
17563
+ process.stdout.write(
17564
+ `${JSON.stringify({ decision: "warn", reason: `Reply language for this turn: ${LANGUAGE_NAME[effective]}.`, additional_context: pinText(effective) })}
17565
+ `
17566
+ );
17567
+ }
17568
+ return EXIT_ALLOW5;
17569
+ }
17570
+ function main23(argv) {
17571
+ const args = argv ?? process.argv.slice(2);
17572
+ let consumer_root = process.cwd();
17573
+ for (let i = 0; i < args.length; i += 1) {
17574
+ const a = args[i];
17575
+ if (a === "--project-dir" && args[i + 1] !== void 0) {
17576
+ consumer_root = args[i + 1];
17577
+ i += 1;
17578
+ } else if (a !== void 0 && a.startsWith("--project-dir=")) {
17579
+ consumer_root = a.slice("--project-dir=".length);
17580
+ }
17581
+ }
17582
+ return run7(readHookStdin(), { consumer_root });
17583
+ }
17584
+ function _isCliEntry19() {
17585
+ if (true) {
17586
+ return false;
17587
+ }
17588
+ if (process.argv[1] === void 0) {
17589
+ return false;
17590
+ }
17591
+ const argvUrl = pathToFileURL20(path33.resolve(process.argv[1])).href;
17592
+ if (import.meta.url === argvUrl) {
17593
+ return true;
17594
+ }
17595
+ try {
17596
+ const here = fs33.realpathSync(fileURLToPath25(import.meta.url));
17597
+ const argv = fs33.realpathSync(path33.resolve(process.argv[1]));
17598
+ return here === argv;
17599
+ } catch {
17600
+ return false;
17601
+ }
17602
+ }
17603
+ if (_isCliEntry19()) {
17604
+ process.exit(main23());
17605
+ }
17606
+
17607
+ // src/scripts/git_authorization_hook.ts
17608
+ import fs34 from "node:fs";
17609
+ import path34 from "node:path";
17610
+ import { fileURLToPath as fileURLToPath26, pathToFileURL as pathToFileURL21 } from "node:url";
17611
+ var EXIT_ALLOW6 = 0;
17612
+ var STATE_FILE6 = path34.join("agents", "state", "git-authorization.json");
17613
+ function _isObject7(v) {
17614
+ return typeof v === "object" && v !== null && !Array.isArray(v);
17615
+ }
17616
+ var PHRASES = [
17617
+ { op: "commit", re: /\b(commit(e|et|ten|ted|ting)?|committe|einchecken)\b/i },
17618
+ { op: "push", re: /\b(push(e|en|ed|ing)?|hochladen|hochschieben|raufschieben)\b/i },
17619
+ { op: "branch", re: /\b(branch(e|es)?|zweig|feature-branch|erstelle einen branch)\b/i },
17620
+ { op: "pr-create", re: /\b(pull[- ]request|pr\b|mach(e|en)? (einen|nen) pr|erstelle .{0,20}pr)\b/i },
17621
+ { op: "pr-merge", re: /\b(merge[nrd]?|mergen|zusammenführen|zusammenfuehren|reinmergen|gemerged)\b/i },
17622
+ { op: "tag", re: /\b(tag(ge|gen|ged|ging)?|version(iere|ieren)?)\b/i },
17623
+ { op: "release", re: /\b(release[nd]?|releasen|veröffentlich(e|en|ung)|veroeffentlich(e|en))\b/i },
17624
+ { op: "publish", re: /\b(publish(e|en|ed|ing)?|npm publish|publiziere[n]?)\b/i }
17625
+ ];
17626
+ var PASTED_COMMANDS = [
17627
+ { op: "publish", re: /\bnpm\s+publish\b/i },
17628
+ { op: "tag", re: /\bgit\s+push\s+[^\n]*--tags\b|\bgit\s+tag\s+-a\b/i },
17629
+ { op: "release", re: /\bgh\s+release\s+create\b/i },
17630
+ { op: "pr-merge", re: /\bgh\s+pr\s+merge\b/i },
17631
+ { op: "pr-create", re: /\bgh\s+pr\s+create\b/i },
17632
+ { op: "push", re: /\bgit\s+push\b/i },
17633
+ { op: "commit", re: /\bgit\s+commit\b/i },
17634
+ { op: "branch", re: /\bgit\s+(checkout\s+-b|switch\s+-c|branch)\b/i }
17635
+ ];
17636
+ function splitFences(prompt) {
17637
+ const fences = [];
17638
+ const prose = prompt.replace(/```[^\n]*\n([\s\S]*?)```/g, (_m, body) => {
17639
+ fences.push(body);
17640
+ return " ";
17641
+ });
17642
+ return { prose, fences };
17643
+ }
17644
+ function _commandLines(fence) {
17645
+ return fence.split("\n").map((l) => l.trim()).filter((l) => l.length > 0).filter((l) => !/^(remote:|error:|hint:|fatal:|warning:|To |!\s|\s*\^)/i.test(l)).map((l) => l.replace(/^[$>#]\s*/, "")).filter((l) => /^(git|gh|npm|pnpm|yarn|task)\b/.test(l));
17646
+ }
17647
+ function classifyAuthorization(prompt) {
17648
+ const { prose, fences } = splitFences(prompt);
17649
+ const authorized = /* @__PURE__ */ new Set();
17650
+ const evidence = {};
17651
+ for (const { op, re } of PHRASES) {
17652
+ const m = re.exec(prose);
17653
+ if (m) {
17654
+ authorized.add(op);
17655
+ evidence[op] = `prose: "${m[0]}"`;
17656
+ }
17657
+ }
17658
+ for (const fence of fences) {
17659
+ for (const line of _commandLines(fence)) {
17660
+ for (const { op, re } of PASTED_COMMANDS) {
17661
+ if (re.test(line)) {
17662
+ authorized.add(op);
17663
+ evidence[op] = `pasted command: "${line.slice(0, 80)}"`;
17664
+ }
17665
+ }
17666
+ }
17667
+ }
17668
+ return { authorized: [...authorized], evidence };
17669
+ }
17670
+ function run8(stdin_text, options) {
17671
+ let envelope = {};
17672
+ if (stdin_text.trim()) {
17673
+ try {
17674
+ const decoded = JSON.parse(stdin_text);
17675
+ if (_isObject7(decoded)) {
17676
+ envelope = decoded;
17677
+ }
17678
+ } catch {
17679
+ return EXIT_ALLOW6;
17680
+ }
17681
+ }
17682
+ const payload = _isObject7(envelope["payload"]) ? envelope["payload"] : envelope;
17683
+ let prompt = "";
17684
+ for (const key of ["prompt", "userPrompt", "user_prompt", "message", "text"]) {
17685
+ const v = payload[key];
17686
+ if (typeof v === "string" && v.trim()) {
17687
+ prompt = v;
17688
+ break;
17689
+ }
17690
+ }
17691
+ if (!prompt) {
17692
+ return EXIT_ALLOW6;
17693
+ }
17694
+ const { authorized, evidence } = classifyAuthorization(prompt);
17695
+ const ledger = {
17696
+ session_id: typeof envelope["session_id"] === "string" ? envelope["session_id"] : "",
17697
+ detected_at: (/* @__PURE__ */ new Date()).toISOString(),
17698
+ authorized,
17699
+ evidence,
17700
+ prompt_chars: prompt.length
17701
+ };
17702
+ try {
17703
+ atomic_write_json(path34.join(options.consumer_root, STATE_FILE6), ledger);
17704
+ } catch {
17705
+ }
17706
+ return EXIT_ALLOW6;
17707
+ }
17708
+ function main24(argv) {
17709
+ const args = argv ?? process.argv.slice(2);
17710
+ let consumer_root = process.cwd();
17711
+ for (let i = 0; i < args.length; i += 1) {
17712
+ const a = args[i];
17713
+ if (a === "--project-dir" && args[i + 1] !== void 0) {
17714
+ consumer_root = args[i + 1];
17715
+ i += 1;
17716
+ } else if (a !== void 0 && a.startsWith("--project-dir=")) {
17717
+ consumer_root = a.slice("--project-dir=".length);
17718
+ }
17719
+ }
17720
+ return run8(readHookStdin(), { consumer_root });
17721
+ }
17722
+ function _isCliEntry20() {
17723
+ if (true) {
17724
+ return false;
17725
+ }
17726
+ if (process.argv[1] === void 0) {
17727
+ return false;
17728
+ }
17729
+ const argvUrl = pathToFileURL21(path34.resolve(process.argv[1])).href;
17730
+ if (import.meta.url === argvUrl) {
17731
+ return true;
17732
+ }
17733
+ try {
17734
+ const here = fs34.realpathSync(fileURLToPath26(import.meta.url));
17735
+ const argv = fs34.realpathSync(path34.resolve(process.argv[1]));
17736
+ return here === argv;
17737
+ } catch {
17738
+ return false;
17739
+ }
17740
+ }
17741
+ if (_isCliEntry20()) {
17742
+ process.exit(main24());
17743
+ }
17744
+
17745
+ // src/scripts/hooks/block_unauthorized_git.ts
17746
+ import fs35 from "node:fs";
17747
+ import path35 from "node:path";
17748
+ import { fileURLToPath as fileURLToPath27, pathToFileURL as pathToFileURL22 } from "node:url";
17749
+ var EXIT_ALLOW7 = 0;
17750
+ var EXIT_BLOCK = 2;
17751
+ function _isObject8(v) {
17752
+ return typeof v === "object" && v !== null && !Array.isArray(v);
17753
+ }
17754
+ var BLOCK_OPS = /* @__PURE__ */ new Set([
17755
+ "publish",
17756
+ "tag",
17757
+ "release",
17758
+ "pr-merge"
17759
+ ]);
17760
+ var WARN_OPS = /* @__PURE__ */ new Set([
17761
+ "commit",
17762
+ "push",
17763
+ "pr-create",
17764
+ "branch"
17765
+ ]);
17766
+ var COMMAND_OPS = [
17767
+ { op: "publish", re: /\b(npm|pnpm|yarn)\s+publish\b/i },
17768
+ { op: "release", re: /\bgh\s+release\s+create\b/i },
17769
+ { op: "tag", re: /\bgit\s+push\b[^\n;|&]*--tags\b|\bgit\s+push\b[^\n;|&]*\brefs\/tags\//i },
17770
+ { op: "pr-merge", re: /\bgh\s+pr\s+merge\b/i },
17771
+ { op: "pr-create", re: /\bgh\s+pr\s+create\b/i },
17772
+ { op: "push", re: /\bgit\s+push\b/i },
17773
+ { op: "commit", re: /\bgit\s+commit\b/i },
17774
+ { op: "branch", re: /\bgit\s+(checkout\s+-b|switch\s+-c)\b/i }
17775
+ ];
17776
+ var COMMAND_TOOLS3 = /* @__PURE__ */ new Set([
17777
+ "launch-process",
17778
+ "launch_process",
17779
+ "Bash",
17780
+ "BashTool",
17781
+ "run-process",
17782
+ "runProcess",
17783
+ "shell",
17784
+ "execute_shell",
17785
+ "RunShellCommand"
17786
+ ]);
17787
+ function extractCommand(envelope) {
17788
+ const payload = _isObject8(envelope["payload"]) ? envelope["payload"] : envelope;
17789
+ const toolRaw = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
17790
+ const tool = typeof toolRaw === "string" ? toolRaw : null;
17791
+ if (tool !== null && !COMMAND_TOOLS3.has(tool)) {
17792
+ return null;
17793
+ }
17794
+ const input = _isObject8(payload["tool_input"]) ? payload["tool_input"] : _isObject8(payload["toolInput"]) ? payload["toolInput"] : payload;
17795
+ for (const key of ["command", "cmd", "script"]) {
17796
+ const v = input[key];
17797
+ if (typeof v === "string" && v.trim()) {
17798
+ return v;
17799
+ }
17800
+ }
17801
+ return null;
17802
+ }
17803
+ function commandOp(command) {
17804
+ for (const { op, re } of COMMAND_OPS) {
17805
+ if (re.test(command)) {
17806
+ return op;
17807
+ }
17808
+ }
17809
+ return null;
17810
+ }
17811
+ function _loadLedger(consumer_root) {
17812
+ try {
17813
+ const raw = fs35.readFileSync(path35.join(consumer_root, STATE_FILE6), "utf8");
17814
+ const decoded = JSON.parse(raw);
17815
+ if (_isObject8(decoded) && Array.isArray(decoded["authorized"])) {
17816
+ return {
17817
+ authorized: new Set(decoded["authorized"].filter(Boolean)),
17818
+ present: true
17819
+ };
17820
+ }
17821
+ } catch {
17822
+ }
17823
+ return { authorized: /* @__PURE__ */ new Set(), present: false };
17824
+ }
17825
+ function decide(command, ledger) {
17826
+ if (command === null) {
17827
+ return { exit: EXIT_ALLOW7, stdout: "", stderr: "" };
17828
+ }
17829
+ const op = commandOp(command);
17830
+ if (op === null || ledger.authorized.has(op)) {
17831
+ return { exit: EXIT_ALLOW7, stdout: "", stderr: "" };
17832
+ }
17833
+ const shown = command.length > 120 ? `${command.slice(0, 117)}\u2026` : command;
17834
+ if (BLOCK_OPS.has(op)) {
17835
+ const reason = `Blocked: \`${op}\` with no authorization in this turn's prompt. This operation is irreversible and non-destructive-by-default already declares it never-autonomous. Command: ${shown}. Ask the user, in one numbered-options block, and run it only after they answer this turn.`;
17836
+ return { exit: EXIT_BLOCK, stdout: "", stderr: `${reason}
17837
+ ` };
17838
+ }
17839
+ if (WARN_OPS.has(op)) {
17840
+ const reason = `No \`${op}\` authorization found in this turn's prompt (commit-policy: a one-shot authorization is spent on the operation it named). If the user did authorize it this turn, proceed; otherwise stop and ask. Command: ${shown}`;
17841
+ return {
17842
+ exit: EXIT_ALLOW7,
17843
+ stdout: `${JSON.stringify({ decision: "warn", reason })}
17844
+ `,
17845
+ stderr: ""
17846
+ };
17847
+ }
17848
+ return { exit: EXIT_ALLOW7, stdout: "", stderr: "" };
17849
+ }
17850
+ function run9(stdin_text, options) {
17851
+ let envelope = {};
17852
+ if (stdin_text.trim()) {
17853
+ try {
17854
+ const decoded = JSON.parse(stdin_text);
17855
+ if (_isObject8(decoded)) {
17856
+ envelope = decoded;
17857
+ }
17858
+ } catch {
17859
+ return EXIT_ALLOW7;
17860
+ }
17861
+ }
17862
+ const decision = decide(extractCommand(envelope), _loadLedger(options.consumer_root));
17863
+ if (decision.stdout) {
17864
+ process.stdout.write(decision.stdout);
17865
+ }
17866
+ if (decision.stderr) {
17867
+ process.stderr.write(decision.stderr);
17868
+ }
17869
+ return decision.exit;
17870
+ }
17871
+ function main25(argv) {
17872
+ const args = argv ?? process.argv.slice(2);
17873
+ let consumer_root = process.cwd();
17874
+ for (let i = 0; i < args.length; i += 1) {
17875
+ const a = args[i];
17876
+ if (a === "--project-dir" && args[i + 1] !== void 0) {
17877
+ consumer_root = args[i + 1];
17878
+ i += 1;
17879
+ } else if (a !== void 0 && a.startsWith("--project-dir=")) {
17880
+ consumer_root = a.slice("--project-dir=".length);
17881
+ }
17882
+ }
17883
+ return run9(readHookStdin(), { consumer_root });
17884
+ }
17885
+ function _isCliEntry21() {
17886
+ if (true) {
17887
+ return false;
17888
+ }
17889
+ if (process.argv[1] === void 0) {
17890
+ return false;
17891
+ }
17892
+ const argvUrl = pathToFileURL22(path35.resolve(process.argv[1])).href;
17893
+ if (import.meta.url === argvUrl) {
17894
+ return true;
17895
+ }
17896
+ try {
17897
+ const here = fs35.realpathSync(fileURLToPath27(import.meta.url));
17898
+ const argv = fs35.realpathSync(path35.resolve(process.argv[1]));
17899
+ return here === argv;
17900
+ } catch {
17901
+ return false;
17902
+ }
17903
+ }
17904
+ if (_isCliEntry21()) {
17905
+ process.exit(main25());
17906
+ }
17907
+
17908
+ // src/scripts/hooks/evidence_independence.ts
17909
+ import crypto2 from "node:crypto";
17910
+ import fs36 from "node:fs";
17911
+ import path36 from "node:path";
17912
+ import { fileURLToPath as fileURLToPath28, pathToFileURL as pathToFileURL23 } from "node:url";
17913
+ var EXIT_ALLOW8 = 0;
17914
+ var EXIT_BLOCK2 = 2;
17915
+ var STATE_FILE7 = path36.join("agents", "state", "evidence-dispatch.json");
17916
+ function _isObject9(v) {
17917
+ return typeof v === "object" && v !== null && !Array.isArray(v);
17918
+ }
17919
+ var DISPATCH_TOOLS = /* @__PURE__ */ new Set([
17920
+ "Agent",
17921
+ "Task",
17922
+ "task",
17923
+ "dispatch_agent",
17924
+ "dispatchAgent",
17925
+ "launch_agent",
17926
+ "run_subagent",
17927
+ "Subagent"
17928
+ ]);
17929
+ var EVALUATION_RE = /\b(review|reviewer|audit|auditor|judge|verdict|blind[- ]pass|blind review|adversarial|critique|assess(ment)?|verify (my|the) (work|change|diff|implementation)|find (any )?(bugs|issues|defects|problems) in (my|the))\b/i;
17930
+ var PRELOADED_VERDICT_RE = [
17931
+ /\bno[- ]findings? (is|are) (expected|welcome|fine|acceptable|the likely)/i,
17932
+ /\b(you )?(should|will|probably) find (nothing|no (issues|problems|bugs|findings))/i,
17933
+ /\bconfirm (that )?there (are|is) no\b/i,
17934
+ /\bi (believe|think|expect) (this|it) is (clean|correct|fine)\b/i,
17935
+ /\bexpect(ed)? (to be )?(clean|green|no findings)\b/i,
17936
+ /\bjust confirm\b/i,
17937
+ /\bit('s| is) (probably|likely) fine\b/i
17938
+ ];
17939
+ function isDispatchTool(tool) {
17940
+ return tool !== null && DISPATCH_TOOLS.has(tool);
17941
+ }
17942
+ function isEvaluationPrompt(prompt) {
17943
+ return EVALUATION_RE.test(prompt);
17944
+ }
17945
+ var SELF_SCOPE_RE = /\b(my (work|change|diff|implementation|code|fix|patch|branch|pr)|this (diff|change|branch|pr|delta|implementation|patch)|the delta|the change i|what i (wrote|built|changed|implemented)|i just (wrote|built|changed|implemented))\b/i;
17946
+ function isSelfScoped(prompt) {
17947
+ return SELF_SCOPE_RE.test(prompt);
17948
+ }
17949
+ function preloadedVerdict(prompt) {
17950
+ for (const re of PRELOADED_VERDICT_RE) {
17951
+ const m = re.exec(prompt);
17952
+ if (m) {
17953
+ return m[0];
17954
+ }
17955
+ }
17956
+ return null;
17957
+ }
17958
+ function extractDispatch(envelope) {
17959
+ const payload = _isObject9(envelope["payload"]) ? envelope["payload"] : envelope;
17960
+ const toolRaw = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
17961
+ const tool = typeof toolRaw === "string" ? toolRaw : null;
17962
+ const input = _isObject9(payload["tool_input"]) ? payload["tool_input"] : _isObject9(payload["toolInput"]) ? payload["toolInput"] : payload;
17963
+ for (const key of ["prompt", "instructions", "task", "description"]) {
17964
+ const v = input[key];
17965
+ if (typeof v === "string" && v.trim()) {
17966
+ return [tool, v];
17967
+ }
17968
+ }
17969
+ return [tool, ""];
17970
+ }
17971
+ function _load(target) {
17972
+ try {
17973
+ const decoded = JSON.parse(fs36.readFileSync(target, "utf8"));
17974
+ if (_isObject9(decoded) && Array.isArray(decoded["evaluations"])) {
17975
+ return decoded;
17976
+ }
17977
+ } catch {
17978
+ }
17979
+ return { session_id: "", turn_started_at: "", evaluations: [] };
17980
+ }
17981
+ var WARN_TEXT = "First evaluation dispatch this turn. Two shapes fabricated a binding honest-null in the audited sessions \u2014 check your prompt for both before it goes out: (1) a verdict pre-loaded into the prompt, and (2) a scope narrowed to files you chose. A review you commissioned on your own work is admissible as gate evidence only when the prompt is recorded alongside the verdict.";
17982
+ function decide2(tool, prompt, priorEvaluations) {
17983
+ if (!isDispatchTool(tool) || !isEvaluationPrompt(prompt)) {
17984
+ return { exit: EXIT_ALLOW8, stdout: "", stderr: "", evaluations: priorEvaluations };
17985
+ }
17986
+ const preloaded = preloadedVerdict(prompt);
17987
+ if (preloaded !== null) {
17988
+ return {
17989
+ exit: EXIT_BLOCK2,
17990
+ stdout: "",
17991
+ stderr: `Blocked: this evaluation prompt pre-loads its verdict ("${preloaded}"). That is the construct that produced a fabricated NO-FINDINGS committed as binding gate evidence, over a delta an unsteered pass then found a live critical in. Remove the expectation from the prompt and let the evaluator reach its own verdict.
17992
+ `,
17993
+ evaluations: priorEvaluations
17994
+ };
17995
+ }
17996
+ if (!isSelfScoped(prompt)) {
17997
+ return { exit: EXIT_ALLOW8, stdout: "", stderr: "", evaluations: priorEvaluations };
17998
+ }
17999
+ if (priorEvaluations >= 1) {
18000
+ return {
18001
+ exit: EXIT_BLOCK2,
18002
+ stdout: "",
18003
+ stderr: `Blocked: second evaluation dispatch of your own work in this turn (verdict shopping). One evaluation has already run; commissioning another with a different prompt or scope selects the answer instead of measuring it. Report what the first pass returned, then re-plan.
18004
+ `,
18005
+ evaluations: priorEvaluations
18006
+ };
18007
+ }
18008
+ return {
18009
+ exit: EXIT_ALLOW8,
18010
+ stdout: `${JSON.stringify({ decision: "warn", reason: WARN_TEXT })}
18011
+ `,
18012
+ stderr: "",
18013
+ evaluations: priorEvaluations + 1
18014
+ };
18015
+ }
18016
+ function run10(stdin_text, options) {
18017
+ let envelope = {};
18018
+ if (stdin_text.trim()) {
18019
+ try {
18020
+ const decoded = JSON.parse(stdin_text);
18021
+ if (_isObject9(decoded)) {
18022
+ envelope = decoded;
18023
+ }
18024
+ } catch {
18025
+ return EXIT_ALLOW8;
18026
+ }
18027
+ }
18028
+ const target = path36.join(options.consumer_root, STATE_FILE7);
18029
+ const state = _load(target);
18030
+ const session_id = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
18031
+ const turnMarker = typeof envelope["turn_id"] === "string" ? envelope["turn_id"] : session_id;
18032
+ if (state.session_id !== turnMarker) {
18033
+ state.session_id = turnMarker;
18034
+ state.turn_started_at = (/* @__PURE__ */ new Date()).toISOString();
18035
+ state.evaluations = [];
18036
+ }
18037
+ const [tool, prompt] = extractDispatch(envelope);
18038
+ const decision = decide2(tool, prompt, state.evaluations.length);
18039
+ if (decision.evaluations > state.evaluations.length) {
18040
+ state.evaluations.push({
18041
+ at: (/* @__PURE__ */ new Date()).toISOString(),
18042
+ digest: crypto2.createHash("sha256").update(prompt).digest("hex").slice(0, 16),
18043
+ prompt_chars: prompt.length
18044
+ });
18045
+ try {
18046
+ atomic_write_json(target, state);
18047
+ } catch {
18048
+ }
18049
+ }
18050
+ if (decision.stdout) {
18051
+ process.stdout.write(decision.stdout);
18052
+ }
18053
+ if (decision.stderr) {
18054
+ process.stderr.write(decision.stderr);
18055
+ }
18056
+ return decision.exit;
18057
+ }
18058
+ function main26(argv) {
18059
+ const args = argv ?? process.argv.slice(2);
18060
+ let consumer_root = process.cwd();
18061
+ for (let i = 0; i < args.length; i += 1) {
18062
+ const a = args[i];
18063
+ if (a === "--project-dir" && args[i + 1] !== void 0) {
18064
+ consumer_root = args[i + 1];
18065
+ i += 1;
18066
+ } else if (a !== void 0 && a.startsWith("--project-dir=")) {
18067
+ consumer_root = a.slice("--project-dir=".length);
18068
+ }
18069
+ }
18070
+ return run10(readHookStdin(), { consumer_root });
18071
+ }
18072
+ function _isCliEntry22() {
18073
+ if (true) {
18074
+ return false;
18075
+ }
18076
+ if (process.argv[1] === void 0) {
18077
+ return false;
18078
+ }
18079
+ const argvUrl = pathToFileURL23(path36.resolve(process.argv[1])).href;
18080
+ if (import.meta.url === argvUrl) {
18081
+ return true;
18082
+ }
18083
+ try {
18084
+ const here = fs36.realpathSync(fileURLToPath28(import.meta.url));
18085
+ const argv = fs36.realpathSync(path36.resolve(process.argv[1]));
18086
+ return here === argv;
18087
+ } catch {
18088
+ return false;
18089
+ }
18090
+ }
18091
+ if (_isCliEntry22()) {
18092
+ process.exit(main26());
18093
+ }
18094
+
18095
+ // src/scripts/hooks/block_no_verify.ts
18096
+ import * as fs37 from "node:fs";
18097
+ import { fileURLToPath as fileURLToPath29, pathToFileURL as pathToFileURL24 } from "node:url";
18098
+ import * as path37 from "node:path";
18099
+ var _HERE3 = fileURLToPath29(import.meta.url);
17406
18100
  var _SHELL_SEPARATORS = /* @__PURE__ */ new Set(["&&", "||", ";", "|"]);
17407
18101
  var _NO_VERIFY_FLAGS = /* @__PURE__ */ new Set(["--no-verify"]);
17408
18102
  var _NO_VERIFY_SHORT = /* @__PURE__ */ new Set(["-n"]);
@@ -17725,7 +18419,7 @@ block_no_verify.py: error: unrecognized arguments: ${arg}
17725
18419
  function _readStdin11() {
17726
18420
  return readHookStdin();
17727
18421
  }
17728
- function main23(argv) {
18422
+ function main27(argv) {
17729
18423
  const parsed = _parseArgs4(argv ?? process.argv.slice(2));
17730
18424
  if (parsed.exitCode !== void 0) {
17731
18425
  return parsed.exitCode;
@@ -17763,33 +18457,33 @@ function main23(argv) {
17763
18457
  }
17764
18458
  return 0;
17765
18459
  }
17766
- function _isCliEntry19() {
18460
+ function _isCliEntry23() {
17767
18461
  if (true) {
17768
18462
  return false;
17769
18463
  }
17770
18464
  if (process.argv[1] === void 0) {
17771
18465
  return false;
17772
18466
  }
17773
- const argvUrl = pathToFileURL20(path33.resolve(process.argv[1])).href;
18467
+ const argvUrl = pathToFileURL24(path37.resolve(process.argv[1])).href;
17774
18468
  if (import.meta.url === argvUrl) {
17775
18469
  return true;
17776
18470
  }
17777
18471
  try {
17778
- const here = fs33.realpathSync(fileURLToPath25(import.meta.url));
17779
- const argv = fs33.realpathSync(path33.resolve(process.argv[1]));
18472
+ const here = fs37.realpathSync(fileURLToPath29(import.meta.url));
18473
+ const argv = fs37.realpathSync(path37.resolve(process.argv[1]));
17780
18474
  return here === argv;
17781
18475
  } catch {
17782
18476
  return false;
17783
18477
  }
17784
18478
  }
17785
- if (_isCliEntry19() || false) {
17786
- process.exitCode = main23();
18479
+ if (_isCliEntry23() || false) {
18480
+ process.exitCode = main27();
17787
18481
  }
17788
18482
 
17789
18483
  // src/scripts/hooks/block_kernel_rule_writes.ts
17790
- import * as fs34 from "node:fs";
17791
- import { fileURLToPath as fileURLToPath26, pathToFileURL as pathToFileURL21 } from "node:url";
17792
- import * as path34 from "node:path";
18484
+ import * as fs38 from "node:fs";
18485
+ import { fileURLToPath as fileURLToPath30, pathToFileURL as pathToFileURL25 } from "node:url";
18486
+ import * as path38 from "node:path";
17793
18487
 
17794
18488
  // src/scripts/_lib/kernel_rules.ts
17795
18489
  var KERNEL_RULE_IDS = [
@@ -17813,8 +18507,8 @@ function is_kernel_rule(name) {
17813
18507
  }
17814
18508
 
17815
18509
  // src/scripts/hooks/block_kernel_rule_writes.ts
17816
- var _HERE4 = fileURLToPath26(import.meta.url);
17817
- function _isObject6(v) {
18510
+ var _HERE4 = fileURLToPath30(import.meta.url);
18511
+ function _isObject10(v) {
17818
18512
  return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
17819
18513
  }
17820
18514
  var _PATH_KEYS = [
@@ -17826,10 +18520,10 @@ var _PATH_KEYS = [
17826
18520
  "notebook_path"
17827
18521
  ];
17828
18522
  function _extract(envelope) {
17829
- const payload = _isObject6(envelope["payload"]) ? envelope["payload"] : envelope;
18523
+ const payload = _isObject10(envelope["payload"]) ? envelope["payload"] : envelope;
17830
18524
  const nameVal = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"] ?? envelope["tool_name"] ?? envelope["tool"];
17831
18525
  const tool = typeof nameVal === "string" ? nameVal : "";
17832
- const ti = _isObject6(payload["tool_input"]) ? payload["tool_input"] : _isObject6(envelope["tool_input"]) ? envelope["tool_input"] : null;
18526
+ const ti = _isObject10(payload["tool_input"]) ? payload["tool_input"] : _isObject10(envelope["tool_input"]) ? envelope["tool_input"] : null;
17833
18527
  const paths = [];
17834
18528
  if (ti !== null) {
17835
18529
  for (const key of _PATH_KEYS) {
@@ -17905,7 +18599,7 @@ function _bash_targets_kernel_rule(command) {
17905
18599
  continue;
17906
18600
  }
17907
18601
  if (prevWasSeparator && !tok.startsWith("-")) {
17908
- verbs.add(path34.basename(tok));
18602
+ verbs.add(path38.basename(tok));
17909
18603
  prevWasSeparator = false;
17910
18604
  }
17911
18605
  }
@@ -17960,8 +18654,8 @@ function check_envelope(envelope) {
17960
18654
  return [false, ""];
17961
18655
  }
17962
18656
  function _extract_command3(envelope) {
17963
- const payload = _isObject6(envelope["payload"]) ? envelope["payload"] : envelope;
17964
- const ti = _isObject6(payload["tool_input"]) ? payload["tool_input"] : _isObject6(envelope["tool_input"]) ? envelope["tool_input"] : null;
18657
+ const payload = _isObject10(envelope["payload"]) ? envelope["payload"] : envelope;
18658
+ const ti = _isObject10(payload["tool_input"]) ? payload["tool_input"] : _isObject10(envelope["tool_input"]) ? envelope["tool_input"] : null;
17965
18659
  for (const src of [ti, payload]) {
17966
18660
  if (src === null) {
17967
18661
  continue;
@@ -17974,12 +18668,12 @@ function _extract_command3(envelope) {
17974
18668
  return null;
17975
18669
  }
17976
18670
  function _asObject2(v) {
17977
- return _isObject6(v) ? v : null;
18671
+ return _isObject10(v) ? v : null;
17978
18672
  }
17979
18673
  function _readStdin12() {
17980
18674
  return readHookStdin();
17981
18675
  }
17982
- function main24() {
18676
+ function main28() {
17983
18677
  const raw = _readStdin12();
17984
18678
  let envelope = {};
17985
18679
  if (raw.trim()) {
@@ -18004,45 +18698,45 @@ function main24() {
18004
18698
  }
18005
18699
  return 0;
18006
18700
  }
18007
- function _isCliEntry20() {
18701
+ function _isCliEntry24() {
18008
18702
  if (true) {
18009
18703
  return false;
18010
18704
  }
18011
18705
  if (process.argv[1] === void 0) {
18012
18706
  return false;
18013
18707
  }
18014
- const argvUrl = pathToFileURL21(path34.resolve(process.argv[1])).href;
18708
+ const argvUrl = pathToFileURL25(path38.resolve(process.argv[1])).href;
18015
18709
  if (import.meta.url === argvUrl) {
18016
18710
  return true;
18017
18711
  }
18018
18712
  try {
18019
- const here = fs34.realpathSync(fileURLToPath26(import.meta.url));
18020
- const argv = fs34.realpathSync(path34.resolve(process.argv[1]));
18713
+ const here = fs38.realpathSync(fileURLToPath30(import.meta.url));
18714
+ const argv = fs38.realpathSync(path38.resolve(process.argv[1]));
18021
18715
  return here === argv;
18022
18716
  } catch {
18023
18717
  return false;
18024
18718
  }
18025
18719
  }
18026
- if (_isCliEntry20() || false) {
18027
- process.exitCode = main24();
18720
+ if (_isCliEntry24() || false) {
18721
+ process.exitCode = main28();
18028
18722
  }
18029
18723
 
18030
18724
  // src/scripts/hooks/block_config_weakening.ts
18031
- import * as fs35 from "node:fs";
18032
- import * as path35 from "node:path";
18033
- import { fileURLToPath as fileURLToPath27, pathToFileURL as pathToFileURL22 } from "node:url";
18034
- var _HERE5 = fileURLToPath27(import.meta.url);
18035
- var EXIT_ALLOW5 = 0;
18036
- var EXIT_BLOCK = 1;
18725
+ import * as fs39 from "node:fs";
18726
+ import * as path39 from "node:path";
18727
+ import { fileURLToPath as fileURLToPath31, pathToFileURL as pathToFileURL26 } from "node:url";
18728
+ var _HERE5 = fileURLToPath31(import.meta.url);
18729
+ var EXIT_ALLOW9 = 0;
18730
+ var EXIT_BLOCK3 = 1;
18037
18731
  var EXIT_WARN3 = 2;
18038
18732
  var SESSION_ENTRY_CAP = 20;
18039
18733
  var SESSION_WARN_AT = 5;
18040
- function _isObject7(v) {
18734
+ function _isObject11(v) {
18041
18735
  return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
18042
18736
  }
18043
18737
  var _PATH_KEYS2 = ["file_path", "path", "target_file", "filePath", "notebook_path"];
18044
18738
  function classify_target(p) {
18045
- const posix = p.split(path35.sep).join("/");
18739
+ const posix = p.split(path39.sep).join("/");
18046
18740
  const base = posix.split("/").pop() ?? "";
18047
18741
  if (/_allowlist\.(json|txt)$/.test(base) || /^allowlist[-_.]/.test(base)) {
18048
18742
  return "allowlist";
@@ -18090,7 +18784,7 @@ function added_entries(tool_input, on_disk) {
18090
18784
  }
18091
18785
  return 0;
18092
18786
  }
18093
- function decide(kind, rel_path, session_total, added) {
18787
+ function decide3(kind, rel_path, session_total, added) {
18094
18788
  if (kind === null || added <= 0) {
18095
18789
  return { action: "allow", reason: "" };
18096
18790
  }
@@ -18116,13 +18810,13 @@ function decide(kind, rel_path, session_total, added) {
18116
18810
  return { action: "allow", reason: "" };
18117
18811
  }
18118
18812
  function _state_file(root) {
18119
- return path35.join(root, "agents", "runtime", "state", "config-weakening.json");
18813
+ return path39.join(root, "agents", "runtime", "state", "config-weakening.json");
18120
18814
  }
18121
18815
  function bump_session(root, session, key, added) {
18122
18816
  const f = _state_file(root);
18123
18817
  let data = {};
18124
18818
  try {
18125
- data = JSON.parse(fs35.readFileSync(f, "utf-8"));
18819
+ data = JSON.parse(fs39.readFileSync(f, "utf-8"));
18126
18820
  } catch {
18127
18821
  data = {};
18128
18822
  }
@@ -18131,18 +18825,18 @@ function bump_session(root, session, key, added) {
18131
18825
  bucket[key] = total;
18132
18826
  data[session] = bucket;
18133
18827
  try {
18134
- fs35.mkdirSync(path35.dirname(f), { recursive: true });
18135
- fs35.writeFileSync(f, `${JSON.stringify(data, null, 2)}
18828
+ fs39.mkdirSync(path39.dirname(f), { recursive: true });
18829
+ fs39.writeFileSync(f, `${JSON.stringify(data, null, 2)}
18136
18830
  `, "utf-8");
18137
18831
  } catch {
18138
18832
  }
18139
18833
  return total;
18140
18834
  }
18141
18835
  function _extract2(envelope) {
18142
- const payload = _isObject7(envelope["payload"]) ? envelope["payload"] : envelope;
18836
+ const payload = _isObject11(envelope["payload"]) ? envelope["payload"] : envelope;
18143
18837
  const nameVal = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"] ?? envelope["tool_name"] ?? envelope["tool"];
18144
18838
  const tool = typeof nameVal === "string" ? nameVal : "";
18145
- const ti = _isObject7(payload["tool_input"]) ? payload["tool_input"] : _isObject7(envelope["tool_input"]) ? envelope["tool_input"] : null;
18839
+ const ti = _isObject11(payload["tool_input"]) ? payload["tool_input"] : _isObject11(envelope["tool_input"]) ? envelope["tool_input"] : null;
18146
18840
  const paths = [];
18147
18841
  if (ti !== null) {
18148
18842
  for (const key of _PATH_KEYS2) {
@@ -18154,20 +18848,20 @@ function _extract2(envelope) {
18154
18848
  }
18155
18849
  return { tool, paths, ti };
18156
18850
  }
18157
- function main25() {
18851
+ function main29() {
18158
18852
  let envelope;
18159
18853
  try {
18160
18854
  const raw = readHookStdin();
18161
18855
  envelope = raw.trim() ? JSON.parse(raw) : {};
18162
18856
  } catch {
18163
- return EXIT_ALLOW5;
18857
+ return EXIT_ALLOW9;
18164
18858
  }
18165
- if (!_isObject7(envelope)) {
18166
- return EXIT_ALLOW5;
18859
+ if (!_isObject11(envelope)) {
18860
+ return EXIT_ALLOW9;
18167
18861
  }
18168
18862
  const { tool, paths, ti } = _extract2(envelope);
18169
18863
  if (!tool || !EDIT_TOOLS.has(tool) || ti === null) {
18170
- return EXIT_ALLOW5;
18864
+ return EXIT_ALLOW9;
18171
18865
  }
18172
18866
  const cwd = envelope["cwd"];
18173
18867
  const pr = envelope["workspace_root"] ?? envelope["project_root"];
@@ -18179,10 +18873,10 @@ function main25() {
18179
18873
  if (kind === null) {
18180
18874
  continue;
18181
18875
  }
18182
- const abs = path35.isAbsolute(p) ? p : path35.join(root, p);
18876
+ const abs = path39.isAbsolute(p) ? p : path39.join(root, p);
18183
18877
  let on_disk = null;
18184
18878
  try {
18185
- on_disk = fs35.readFileSync(abs, "utf-8");
18879
+ on_disk = fs39.readFileSync(abs, "utf-8");
18186
18880
  } catch {
18187
18881
  on_disk = null;
18188
18882
  }
@@ -18190,13 +18884,13 @@ function main25() {
18190
18884
  if (added <= 0) {
18191
18885
  continue;
18192
18886
  }
18193
- const rel = path35.relative(root, abs) || p;
18887
+ const rel = path39.relative(root, abs) || p;
18194
18888
  const total = kind === "allowlist" ? bump_session(root, session, rel, added) : added;
18195
- const d = decide(kind, rel, total, added);
18889
+ const d = decide3(kind, rel, total, added);
18196
18890
  if (d.action === "block") {
18197
18891
  process.stderr.write(`block-config-weakening: BLOCKED \u2014 ${d.reason}
18198
18892
  `);
18199
- return EXIT_BLOCK;
18893
+ return EXIT_BLOCK3;
18200
18894
  }
18201
18895
  if (d.action === "warn") {
18202
18896
  process.stdout.write(`${JSON.stringify({ decision: "warn", reason: d.reason })}
@@ -18204,33 +18898,33 @@ function main25() {
18204
18898
  return EXIT_WARN3;
18205
18899
  }
18206
18900
  }
18207
- return EXIT_ALLOW5;
18901
+ return EXIT_ALLOW9;
18208
18902
  }
18209
- function _isCliEntry21() {
18903
+ function _isCliEntry25() {
18210
18904
  if (true) {
18211
18905
  return false;
18212
18906
  }
18213
18907
  if (process.argv[1] === void 0) {
18214
18908
  return false;
18215
18909
  }
18216
- const argvUrl = pathToFileURL22(path35.resolve(process.argv[1])).href;
18910
+ const argvUrl = pathToFileURL26(path39.resolve(process.argv[1])).href;
18217
18911
  if (import.meta.url === argvUrl) {
18218
18912
  return true;
18219
18913
  }
18220
18914
  try {
18221
- return fs35.realpathSync(fileURLToPath27(import.meta.url)) === fs35.realpathSync(path35.resolve(process.argv[1]));
18915
+ return fs39.realpathSync(fileURLToPath31(import.meta.url)) === fs39.realpathSync(path39.resolve(process.argv[1]));
18222
18916
  } catch {
18223
18917
  return false;
18224
18918
  }
18225
18919
  }
18226
- if (_isCliEntry21() || process.argv[1] === _HERE5) {
18227
- process.exit(main25());
18920
+ if (_isCliEntry25() || process.argv[1] === _HERE5) {
18921
+ process.exit(main29());
18228
18922
  }
18229
18923
 
18230
18924
  // src/scripts/hooks/rtk_wrap_hook.ts
18231
- import fs36 from "node:fs";
18232
- import path36 from "node:path";
18233
- import { fileURLToPath as fileURLToPath28, pathToFileURL as pathToFileURL23 } from "node:url";
18925
+ import fs40 from "node:fs";
18926
+ import path40 from "node:path";
18927
+ import { fileURLToPath as fileURLToPath32, pathToFileURL as pathToFileURL27 } from "node:url";
18234
18928
 
18235
18929
  // src/install/rtkDetection.ts
18236
18930
  import { spawnSync as spawnSync4 } from "node:child_process";
@@ -18342,7 +19036,7 @@ function detectRtkCached(options = {}) {
18342
19036
 
18343
19037
  // src/scripts/hooks/rtk_wrap_hook.ts
18344
19038
  var SETTINGS_FILE6 = ".agent-settings.yml";
18345
- var EXIT_ALLOW6 = 0;
19039
+ var EXIT_ALLOW10 = 0;
18346
19040
  var EXIT_WARN4 = 2;
18347
19041
  var _RTK_PROGRAMS = /* @__PURE__ */ new Set([
18348
19042
  "git",
@@ -18368,19 +19062,19 @@ var _RTK_PROGRAMS = /* @__PURE__ */ new Set([
18368
19062
  "kubectl",
18369
19063
  "terraform"
18370
19064
  ]);
18371
- function _isObject8(v) {
19065
+ function _isObject12(v) {
18372
19066
  return typeof v === "object" && v !== null && !Array.isArray(v);
18373
19067
  }
18374
19068
  function _enabled2(root) {
18375
- const f = path36.join(root, SETTINGS_FILE6);
19069
+ const f = path40.join(root, SETTINGS_FILE6);
18376
19070
  try {
18377
- if (!fs36.statSync(f).isFile()) return false;
19071
+ if (!fs40.statSync(f).isFile()) return false;
18378
19072
  } catch {
18379
19073
  return false;
18380
19074
  }
18381
19075
  let text;
18382
19076
  try {
18383
- text = fs36.readFileSync(f, "utf-8");
19077
+ text = fs40.readFileSync(f, "utf-8");
18384
19078
  } catch {
18385
19079
  return false;
18386
19080
  }
@@ -18410,13 +19104,13 @@ function _enabled2(root) {
18410
19104
  function rtk_available(env = process.env) {
18411
19105
  const pathVar = env.PATH ?? env.Path ?? "";
18412
19106
  if (!pathVar) return false;
18413
- const dirs = pathVar.split(path36.delimiter).filter(Boolean);
19107
+ const dirs = pathVar.split(path40.delimiter).filter(Boolean);
18414
19108
  const exts = process.platform === "win32" ? ["", ".exe", ".cmd", ".bat"] : [""];
18415
19109
  for (const dir of dirs) {
18416
19110
  for (const ext of exts) {
18417
- const candidate = path36.join(dir, `rtk${ext}`);
19111
+ const candidate = path40.join(dir, `rtk${ext}`);
18418
19112
  try {
18419
- const st = fs36.statSync(candidate);
19113
+ const st = fs40.statSync(candidate);
18420
19114
  if (st.isFile()) {
18421
19115
  if (process.platform === "win32" || (st.mode & 73) !== 0) return true;
18422
19116
  }
@@ -18427,14 +19121,14 @@ function rtk_available(env = process.env) {
18427
19121
  return false;
18428
19122
  }
18429
19123
  function _extract_command4(envelope) {
18430
- const payload = _isObject8(envelope["payload"]) ? envelope["payload"] : {};
18431
- const tool_input = _isObject8(payload["tool_input"]) ? payload["tool_input"] : {};
19124
+ const payload = _isObject12(envelope["payload"]) ? envelope["payload"] : {};
19125
+ const tool_input = _isObject12(payload["tool_input"]) ? payload["tool_input"] : {};
18432
19126
  for (const src of [tool_input["command"], payload["command"], envelope["command"]]) {
18433
19127
  if (typeof src === "string") return src;
18434
19128
  }
18435
19129
  return null;
18436
19130
  }
18437
- function classify(command) {
19131
+ function classify2(command) {
18438
19132
  const cmd = command.trim();
18439
19133
  if (!cmd) return { eligible: false, reason_skip: "empty" };
18440
19134
  let tokens;
@@ -18464,61 +19158,61 @@ function _readStdin13() {
18464
19158
  function _jsonReason(reason) {
18465
19159
  return JSON.stringify({ decision: "warn", reason });
18466
19160
  }
18467
- function main26() {
19161
+ function main30() {
18468
19162
  let envelope;
18469
19163
  try {
18470
19164
  const raw = _readStdin13();
18471
19165
  envelope = raw.trim() ? JSON.parse(raw) : {};
18472
19166
  } catch {
18473
- return EXIT_ALLOW6;
19167
+ return EXIT_ALLOW10;
18474
19168
  }
18475
- if (!_isObject8(envelope)) return EXIT_ALLOW6;
19169
+ if (!_isObject12(envelope)) return EXIT_ALLOW10;
18476
19170
  const cwd = envelope["cwd"];
18477
19171
  const projectRoot = envelope["workspace_root"] ?? envelope["project_root"];
18478
19172
  const root = typeof cwd === "string" && cwd ? cwd : typeof projectRoot === "string" && projectRoot ? projectRoot : ".";
18479
- if (!_enabled2(root)) return EXIT_ALLOW6;
18480
- if (!rtk_available()) return EXIT_ALLOW6;
18481
- if (detectRtkCached().identity !== "token-killer") return EXIT_ALLOW6;
19173
+ if (!_enabled2(root)) return EXIT_ALLOW10;
19174
+ if (!rtk_available()) return EXIT_ALLOW10;
19175
+ if (detectRtkCached().identity !== "token-killer") return EXIT_ALLOW10;
18482
19176
  const command = _extract_command4(envelope);
18483
- if (!command) return EXIT_ALLOW6;
18484
- const verdict = classify(command);
18485
- if (!verdict.eligible) return EXIT_ALLOW6;
19177
+ if (!command) return EXIT_ALLOW10;
19178
+ const verdict = classify2(command);
19179
+ if (!verdict.eligible) return EXIT_ALLOW10;
18486
19180
  const reason = `rtk is installed and wraps verbose CLI output (upstream reports 60\u201390% fewer output tokens). Re-run wrapped: \`rtk ${command.trim()}\`. (Skip for completeness-critical output like \`git diff\`.)`;
18487
19181
  process.stdout.write(`${_jsonReason(reason)}
18488
19182
  `);
18489
19183
  return EXIT_WARN4;
18490
19184
  }
18491
- function _isCliEntry22() {
19185
+ function _isCliEntry26() {
18492
19186
  if (true) {
18493
19187
  return false;
18494
19188
  }
18495
19189
  if (process.argv[1] === void 0) {
18496
19190
  return false;
18497
19191
  }
18498
- const argvUrl = pathToFileURL23(path36.resolve(process.argv[1])).href;
19192
+ const argvUrl = pathToFileURL27(path40.resolve(process.argv[1])).href;
18499
19193
  if (import.meta.url === argvUrl) {
18500
19194
  return true;
18501
19195
  }
18502
19196
  try {
18503
- const here = fs36.realpathSync(fileURLToPath28(import.meta.url));
18504
- const argv = fs36.realpathSync(path36.resolve(process.argv[1]));
19197
+ const here = fs40.realpathSync(fileURLToPath32(import.meta.url));
19198
+ const argv = fs40.realpathSync(path40.resolve(process.argv[1]));
18505
19199
  return here === argv;
18506
19200
  } catch {
18507
19201
  return false;
18508
19202
  }
18509
19203
  }
18510
- if (_isCliEntry22()) {
18511
- process.exit(main26());
19204
+ if (_isCliEntry26()) {
19205
+ process.exit(main30());
18512
19206
  }
18513
19207
 
18514
19208
  // src/scripts/hooks/design_slop_hook.ts
18515
- import fs38 from "node:fs";
18516
- import path38 from "node:path";
18517
- import { fileURLToPath as fileURLToPath29, pathToFileURL as pathToFileURL24 } from "node:url";
19209
+ import fs42 from "node:fs";
19210
+ import path42 from "node:path";
19211
+ import { fileURLToPath as fileURLToPath33, pathToFileURL as pathToFileURL28 } from "node:url";
18518
19212
 
18519
19213
  // src/scripts/lint_design_slop.ts
18520
- import fs37 from "node:fs";
18521
- import path37 from "node:path";
19214
+ import fs41 from "node:fs";
19215
+ import path41 from "node:path";
18522
19216
 
18523
19217
  // src/scripts/design_slop_rules.ts
18524
19218
  function cssBlocks(content) {
@@ -18907,14 +19601,14 @@ var SLOP_RULES = [
18907
19601
  gated: (ctx) => ctx.has("brutalist", "uniform grid", "repetitive grid"),
18908
19602
  detect: ({ content }) => {
18909
19603
  const bodies = sectionBodies(content);
18910
- let run7 = 0;
19604
+ let run11 = 0;
18911
19605
  let maxRun = 0;
18912
19606
  for (const b of bodies) {
18913
19607
  if (sectionSignature(b).mediaText) {
18914
- run7 += 1;
18915
- maxRun = Math.max(maxRun, run7);
19608
+ run11 += 1;
19609
+ maxRun = Math.max(maxRun, run11);
18916
19610
  } else {
18917
- run7 = 0;
19611
+ run11 = 0;
18918
19612
  }
18919
19613
  }
18920
19614
  if (maxRun > 2) return [{ line: 1, snippet: `${maxRun} consecutive media+text sections` }];
@@ -18934,33 +19628,33 @@ function enginesForExt(ext) {
18934
19628
  return /* @__PURE__ */ new Set();
18935
19629
  }
18936
19630
  function* walkDir(dir, ext) {
18937
- if (!fs37.existsSync(dir)) return;
18938
- for (const entry of fs37.readdirSync(dir, { withFileTypes: true })) {
18939
- const full = path37.join(dir, entry.name);
19631
+ if (!fs41.existsSync(dir)) return;
19632
+ for (const entry of fs41.readdirSync(dir, { withFileTypes: true })) {
19633
+ const full = path41.join(dir, entry.name);
18940
19634
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
18941
19635
  if (entry.isDirectory()) yield* walkDir(full, ext);
18942
19636
  else if (ext.test(entry.name)) yield full;
18943
19637
  }
18944
19638
  }
18945
19639
  function loadConfig(dir) {
18946
- const p = path37.join(dir, ".design-quality.json");
18947
- if (!fs37.existsSync(p)) return {};
19640
+ const p = path41.join(dir, ".design-quality.json");
19641
+ if (!fs41.existsSync(p)) return {};
18948
19642
  try {
18949
- return JSON.parse(fs37.readFileSync(p, "utf-8"));
19643
+ return JSON.parse(fs41.readFileSync(p, "utf-8"));
18950
19644
  } catch {
18951
19645
  return {};
18952
19646
  }
18953
19647
  }
18954
19648
  function loadDesignContext(scanDir) {
18955
19649
  const candidates = [
18956
- path37.join(scanDir, "DESIGN.md"),
18957
- path37.join(process.cwd(), "DESIGN.md"),
18958
- path37.join(scanDir, "..", "DESIGN.md")
19650
+ path41.join(scanDir, "DESIGN.md"),
19651
+ path41.join(process.cwd(), "DESIGN.md"),
19652
+ path41.join(scanDir, "..", "DESIGN.md")
18959
19653
  ];
18960
19654
  let raw = "";
18961
19655
  for (const c of candidates) {
18962
- if (fs37.existsSync(c)) {
18963
- raw = fs37.readFileSync(c, "utf-8").toLowerCase();
19656
+ if (fs41.existsSync(c)) {
19657
+ raw = fs41.readFileSync(c, "utf-8").toLowerCase();
18964
19658
  break;
18965
19659
  }
18966
19660
  }
@@ -18991,7 +19685,7 @@ function parseIgnores(lines) {
18991
19685
  }
18992
19686
  function scanFile(content, relPath, ctx) {
18993
19687
  const lines = content.split("\n");
18994
- const ext = path37.extname(relPath).toLowerCase();
19688
+ const ext = path41.extname(relPath).toLowerCase();
18995
19689
  const fileEngines = enginesForExt(ext);
18996
19690
  if (fileEngines.size === 0) return [];
18997
19691
  const ignores = parseIgnores(lines);
@@ -19021,15 +19715,15 @@ function scanFile(content, relPath, ctx) {
19021
19715
  }
19022
19716
  return out;
19023
19717
  }
19024
- function main27() {
19718
+ function main31() {
19025
19719
  const args = process.argv.slice(2);
19026
19720
  const jsonMode = args.includes("--json");
19027
19721
  const quiet = args.includes("--quiet");
19028
19722
  const dirIdx = args.indexOf("--dir");
19029
- const scanDir = dirIdx >= 0 && args[dirIdx + 1] ? path37.resolve(args[dirIdx + 1]) : path37.resolve(process.cwd(), "src");
19723
+ const scanDir = dirIdx >= 0 && args[dirIdx + 1] ? path41.resolve(args[dirIdx + 1]) : path41.resolve(process.cwd(), "src");
19030
19724
  const failIdx = args.indexOf("--fail-on");
19031
19725
  const failOn = failIdx >= 0 ? args[failIdx + 1] : void 0;
19032
- if (!fs37.existsSync(scanDir)) {
19726
+ if (!fs41.existsSync(scanDir)) {
19033
19727
  if (!quiet) {
19034
19728
  process.stderr.write(`[lint_design_slop] scan directory not found: ${scanDir}
19035
19729
  `);
@@ -19063,9 +19757,9 @@ function main27() {
19063
19757
  }
19064
19758
  const findings = [];
19065
19759
  for (const fp of files) {
19066
- const rel = path37.relative(process.cwd(), fp);
19760
+ const rel = path41.relative(process.cwd(), fp);
19067
19761
  try {
19068
- const fileFindings = scanFile(fs37.readFileSync(fp, "utf-8"), rel, ctx).filter(
19762
+ const fileFindings = scanFile(fs41.readFileSync(fp, "utf-8"), rel, ctx).filter(
19069
19763
  (f) => !ignoreRules.has(f.rule.toLowerCase())
19070
19764
  );
19071
19765
  findings.push(...fileFindings);
@@ -19098,11 +19792,11 @@ lint_design_slop: ${findings.length} tell(s) flagged (rebuttable \u2014 declare
19098
19792
  process.exit(overThreshold.length > 0 ? 2 : 0);
19099
19793
  }
19100
19794
  var invokedDirectly = process.argv[1] !== void 0 && /lint_design_slop\.ts$/.test(process.argv[1]);
19101
- if (invokedDirectly) main27();
19795
+ if (invokedDirectly) main31();
19102
19796
 
19103
19797
  // src/scripts/hooks/design_slop_hook.ts
19104
19798
  var SETTINGS_FILE7 = ".agent-settings.yml";
19105
- var EXIT_ALLOW7 = 0;
19799
+ var EXIT_ALLOW11 = 0;
19106
19800
  var EXIT_WARN5 = 2;
19107
19801
  var DEGRADE_AFTER = 3;
19108
19802
  var UI_EXT = /\.(html|htm|css|scss|sass|less|vue|svelte|astro|jsx|tsx)$/i;
@@ -19110,11 +19804,11 @@ function isObject(v) {
19110
19804
  return typeof v === "object" && v !== null && !Array.isArray(v);
19111
19805
  }
19112
19806
  function enabled2(root) {
19113
- const f = path38.join(root, SETTINGS_FILE7);
19807
+ const f = path42.join(root, SETTINGS_FILE7);
19114
19808
  let text;
19115
19809
  try {
19116
- if (!fs38.statSync(f).isFile()) return false;
19117
- text = fs38.readFileSync(f, "utf-8");
19810
+ if (!fs42.statSync(f).isFile()) return false;
19811
+ text = fs42.readFileSync(f, "utf-8");
19118
19812
  } catch {
19119
19813
  return false;
19120
19814
  }
@@ -19151,11 +19845,11 @@ function extract(envelope) {
19151
19845
  return null;
19152
19846
  }
19153
19847
  function stateFile(root) {
19154
- return path38.join(root, "agents", "runtime", "state", "design-slop-hook.json");
19848
+ return path42.join(root, "agents", "runtime", "state", "design-slop-hook.json");
19155
19849
  }
19156
19850
  function readState(root) {
19157
19851
  try {
19158
- const t = fs38.readFileSync(stateFile(root), "utf-8");
19852
+ const t = fs42.readFileSync(stateFile(root), "utf-8");
19159
19853
  const parsed = JSON.parse(t);
19160
19854
  return isObject(parsed) ? parsed : {};
19161
19855
  } catch {
@@ -19165,31 +19859,31 @@ function readState(root) {
19165
19859
  function writeState(root, state) {
19166
19860
  try {
19167
19861
  const sf = stateFile(root);
19168
- fs38.mkdirSync(path38.dirname(sf), { recursive: true });
19169
- fs38.writeFileSync(sf, JSON.stringify(state, null, 2) + "\n");
19862
+ fs42.mkdirSync(path42.dirname(sf), { recursive: true });
19863
+ fs42.writeFileSync(sf, JSON.stringify(state, null, 2) + "\n");
19170
19864
  } catch {
19171
19865
  }
19172
19866
  }
19173
19867
  function readStdin() {
19174
19868
  return readHookStdin();
19175
19869
  }
19176
- function main28() {
19870
+ function main32() {
19177
19871
  let envelope;
19178
19872
  try {
19179
19873
  const raw = readStdin();
19180
19874
  envelope = raw.trim() ? JSON.parse(raw) : {};
19181
19875
  } catch {
19182
- return EXIT_ALLOW7;
19876
+ return EXIT_ALLOW11;
19183
19877
  }
19184
- if (!isObject(envelope)) return EXIT_ALLOW7;
19878
+ if (!isObject(envelope)) return EXIT_ALLOW11;
19185
19879
  const rootVal = envelope["cwd"] ?? envelope["project_root"] ?? ".";
19186
19880
  const root = typeof rootVal === "string" && rootVal ? rootVal : ".";
19187
- if (!enabled2(root)) return EXIT_ALLOW7;
19881
+ if (!enabled2(root)) return EXIT_ALLOW11;
19188
19882
  const ex = extract(envelope);
19189
- if (!ex || !ex.file || !UI_EXT.test(ex.file)) return EXIT_ALLOW7;
19883
+ if (!ex || !ex.file || !UI_EXT.test(ex.file)) return EXIT_ALLOW11;
19190
19884
  let ctx;
19191
19885
  try {
19192
- ctx = loadDesignContext(path38.dirname(path38.resolve(root, ex.file)));
19886
+ ctx = loadDesignContext(path42.dirname(path42.resolve(root, ex.file)));
19193
19887
  } catch {
19194
19888
  ctx = { raw: "", has: () => false };
19195
19889
  }
@@ -19199,9 +19893,9 @@ function main28() {
19199
19893
  (f) => f.severity === "P0" || f.severity === "P1"
19200
19894
  );
19201
19895
  } catch {
19202
- return EXIT_ALLOW7;
19896
+ return EXIT_ALLOW11;
19203
19897
  }
19204
- if (findings.length === 0) return EXIT_ALLOW7;
19898
+ if (findings.length === 0) return EXIT_ALLOW11;
19205
19899
  const state = readState(root);
19206
19900
  const surfaced = findings.filter((f) => {
19207
19901
  const sig = `${ex.file}::${f.rule}`;
@@ -19211,43 +19905,43 @@ function main28() {
19211
19905
  return true;
19212
19906
  });
19213
19907
  writeState(root, state);
19214
- if (surfaced.length === 0) return EXIT_ALLOW7;
19908
+ if (surfaced.length === 0) return EXIT_ALLOW11;
19215
19909
  const lines = surfaced.map((f) => `${f.catalogId} (${f.rule}) ${f.file}:${f.line} \u2014 ${f.message}`).join("; ");
19216
19910
  const reason = "\u26A0\uFE0F Anti-slop: high-severity aesthetic tell(s) in the proposed UI \u2014 " + lines + ". Rebuttable: declare intent in DESIGN.md, add design-slop-disable-next-line, or proceed if deliberate (this is a flag, not a block).";
19217
19911
  process.stdout.write(JSON.stringify({ decision: "warn", reason }) + "\n");
19218
19912
  return EXIT_WARN5;
19219
19913
  }
19220
- function _isCliEntry23() {
19914
+ function _isCliEntry27() {
19221
19915
  if (true) {
19222
19916
  return false;
19223
19917
  }
19224
19918
  if (process.argv[1] === void 0) {
19225
19919
  return false;
19226
19920
  }
19227
- const argvUrl = pathToFileURL24(path38.resolve(process.argv[1])).href;
19921
+ const argvUrl = pathToFileURL28(path42.resolve(process.argv[1])).href;
19228
19922
  if (import.meta.url === argvUrl) {
19229
19923
  return true;
19230
19924
  }
19231
19925
  try {
19232
- const here = fs38.realpathSync(fileURLToPath29(import.meta.url));
19233
- const argv = fs38.realpathSync(path38.resolve(process.argv[1]));
19926
+ const here = fs42.realpathSync(fileURLToPath33(import.meta.url));
19927
+ const argv = fs42.realpathSync(path42.resolve(process.argv[1]));
19234
19928
  return here === argv;
19235
19929
  } catch {
19236
19930
  return false;
19237
19931
  }
19238
19932
  }
19239
- var isCliEntry9 = _isCliEntry23();
19240
- if (isCliEntry9) process.exit(main28());
19933
+ var isCliEntry9 = _isCliEntry27();
19934
+ if (isCliEntry9) process.exit(main32());
19241
19935
 
19242
19936
  // src/scripts/hooks/code_graph_nudge_hook.ts
19243
- import fs40 from "node:fs";
19244
- import path40 from "node:path";
19245
- import { fileURLToPath as fileURLToPath30, pathToFileURL as pathToFileURL25 } from "node:url";
19937
+ import fs44 from "node:fs";
19938
+ import path44 from "node:path";
19939
+ import { fileURLToPath as fileURLToPath34, pathToFileURL as pathToFileURL29 } from "node:url";
19246
19940
 
19247
19941
  // src/scripts/code_graph/detect.ts
19248
19942
  import { execFileSync } from "node:child_process";
19249
- import * as fs39 from "node:fs";
19250
- import * as path39 from "node:path";
19943
+ import * as fs43 from "node:fs";
19944
+ import * as path43 from "node:path";
19251
19945
 
19252
19946
  // src/scripts/code_graph/validate.ts
19253
19947
  var RELATIONS = /* @__PURE__ */ new Set(["calls", "imports", "uses", "inherits", "member"]);
@@ -19328,7 +20022,7 @@ function freshness(root, file, embeddedSha) {
19328
20022
  const last = gitLastCommitEpoch(root);
19329
20023
  if (last === null) return {};
19330
20024
  try {
19331
- const mtime = Math.floor(fs39.statSync(file).mtimeMs / 1e3);
20025
+ const mtime = Math.floor(fs43.statSync(file).mtimeMs / 1e3);
19332
20026
  return { stale: mtime < last };
19333
20027
  } catch {
19334
20028
  return {};
@@ -19336,7 +20030,7 @@ function freshness(root, file, embeddedSha) {
19336
20030
  }
19337
20031
  function looksLikeGraph(p) {
19338
20032
  try {
19339
- const raw = JSON.parse(fs39.readFileSync(p, "utf-8"));
20033
+ const raw = JSON.parse(fs43.readFileSync(p, "utf-8"));
19340
20034
  if (validateGraph(raw).ok) return { ok: true, sha: raw["head_at_build"] ?? null };
19341
20035
  const nodes = raw["nodes"];
19342
20036
  const edges = raw["edges"] ?? raw["links"];
@@ -19347,23 +20041,23 @@ function looksLikeGraph(p) {
19347
20041
  }
19348
20042
  }
19349
20043
  function detectSources(root, nativeCache) {
19350
- const abs = path39.resolve(root);
20044
+ const abs = path43.resolve(root);
19351
20045
  const out = [];
19352
20046
  for (const rel of CONSUMER_CANDIDATES) {
19353
- const p = path39.join(abs, rel);
19354
- if (fs39.existsSync(p)) {
20047
+ const p = path43.join(abs, rel);
20048
+ if (fs43.existsSync(p)) {
19355
20049
  const { ok, sha } = looksLikeGraph(p);
19356
20050
  if (ok) out.push({ kind: "consumer", path: p, present: true, ...freshness(abs, p, sha) });
19357
20051
  }
19358
20052
  }
19359
- const scipCandidates = [path39.join(abs, "index.scip")];
20053
+ const scipCandidates = [path43.join(abs, "index.scip")];
19360
20054
  try {
19361
- for (const e of fs39.readdirSync(abs)) if (e.endsWith(".scip")) scipCandidates.push(path39.join(abs, e));
20055
+ for (const e of fs43.readdirSync(abs)) if (e.endsWith(".scip")) scipCandidates.push(path43.join(abs, e));
19362
20056
  } catch {
19363
20057
  }
19364
- const scip = scipCandidates.find((p) => fs39.existsSync(p));
20058
+ const scip = scipCandidates.find((p) => fs43.existsSync(p));
19365
20059
  if (scip) out.push({ kind: "scip", path: scip, present: true, note: "SCIP detected \u2014 peer tooling required (no owned reader)" });
19366
- if (fs39.existsSync(nativeCache)) out.push({ kind: "native", path: nativeCache, present: true, ...freshness(abs, nativeCache, null) });
20060
+ if (fs43.existsSync(nativeCache)) out.push({ kind: "native", path: nativeCache, present: true, ...freshness(abs, nativeCache, null) });
19367
20061
  return out;
19368
20062
  }
19369
20063
  function pickSource(verdicts) {
@@ -19376,18 +20070,18 @@ function pickSource(verdicts) {
19376
20070
 
19377
20071
  // src/scripts/hooks/code_graph_nudge_hook.ts
19378
20072
  var SETTINGS_FILE8 = ".agent-settings.yml";
19379
- var EXIT_ALLOW8 = 0;
20073
+ var EXIT_ALLOW12 = 0;
19380
20074
  var EXIT_WARN6 = 2;
19381
20075
  var CODE_EXT = /\.(php|ts|tsx|mts|cts|js|jsx|mjs|cjs)$/i;
19382
20076
  function isObject2(v) {
19383
20077
  return typeof v === "object" && v !== null && !Array.isArray(v);
19384
20078
  }
19385
20079
  function enabled3(root) {
19386
- const f = path40.join(root, SETTINGS_FILE8);
20080
+ const f = path44.join(root, SETTINGS_FILE8);
19387
20081
  let text;
19388
20082
  try {
19389
- if (!fs40.statSync(f).isFile()) return false;
19390
- text = fs40.readFileSync(f, "utf-8");
20083
+ if (!fs44.statSync(f).isFile()) return false;
20084
+ text = fs44.readFileSync(f, "utf-8");
19391
20085
  } catch {
19392
20086
  return false;
19393
20087
  }
@@ -19430,11 +20124,11 @@ function sessionId(envelope) {
19430
20124
  return typeof s === "string" && s ? s : "default";
19431
20125
  }
19432
20126
  function latchFile(root) {
19433
- return path40.join(root, "agents", "runtime", "state", "code-graph-nudge.json");
20127
+ return path44.join(root, "agents", "runtime", "state", "code-graph-nudge.json");
19434
20128
  }
19435
20129
  function alreadyNudged(root, session) {
19436
20130
  try {
19437
- const state = JSON.parse(fs40.readFileSync(latchFile(root), "utf-8"));
20131
+ const state = JSON.parse(fs44.readFileSync(latchFile(root), "utf-8"));
19438
20132
  return state[session] === true;
19439
20133
  } catch {
19440
20134
  return false;
@@ -19445,18 +20139,18 @@ function latch(root, session) {
19445
20139
  const p = latchFile(root);
19446
20140
  let state = {};
19447
20141
  try {
19448
- state = JSON.parse(fs40.readFileSync(p, "utf-8"));
20142
+ state = JSON.parse(fs44.readFileSync(p, "utf-8"));
19449
20143
  } catch {
19450
20144
  }
19451
20145
  state[session] = true;
19452
- fs40.mkdirSync(path40.dirname(p), { recursive: true });
19453
- fs40.writeFileSync(p, JSON.stringify(state));
20146
+ fs44.mkdirSync(path44.dirname(p), { recursive: true });
20147
+ fs44.writeFileSync(p, JSON.stringify(state));
19454
20148
  } catch {
19455
20149
  }
19456
20150
  }
19457
- var NATIVE_CACHE = path40.join("agents", "runtime", "state", "code-graph-v1.json");
20151
+ var NATIVE_CACHE = path44.join("agents", "runtime", "state", "code-graph-v1.json");
19458
20152
  function nudgeReason(root) {
19459
- const verdicts = detectSources(root, path40.join(root, NATIVE_CACHE));
20153
+ const verdicts = detectSources(root, path44.join(root, NATIVE_CACHE));
19460
20154
  const picked = pickSource(verdicts);
19461
20155
  if (!picked) {
19462
20156
  return 'No code-graph found. For "who calls / where used / impact" run `agent-config code-graph refresh` once, then `agent-config code-graph query <symbol>` instead of grepping blind.';
@@ -19466,28 +20160,28 @@ function nudgeReason(root) {
19466
20160
  }
19467
20161
  return "A fresh code-graph is present \u2014 for structure questions run `agent-config code-graph query|affected <symbol>` first; grep is the fallback (say which answered).";
19468
20162
  }
19469
- function main29() {
20163
+ function main33() {
19470
20164
  let envelope;
19471
20165
  try {
19472
20166
  const raw = readHookStdin();
19473
20167
  envelope = raw.trim() ? JSON.parse(raw) : {};
19474
20168
  } catch {
19475
- return EXIT_ALLOW8;
20169
+ return EXIT_ALLOW12;
19476
20170
  }
19477
- if (!isObject2(envelope)) return EXIT_ALLOW8;
20171
+ if (!isObject2(envelope)) return EXIT_ALLOW12;
19478
20172
  const cwd = envelope["cwd"];
19479
20173
  const pr = envelope["workspace_root"] ?? envelope["project_root"];
19480
20174
  const root = typeof cwd === "string" && cwd ? cwd : typeof pr === "string" && pr ? pr : ".";
19481
- if (!enabled3(root)) return EXIT_ALLOW8;
20175
+ if (!enabled3(root)) return EXIT_ALLOW12;
19482
20176
  const { isSearch, isCodeRead } = classifyTool(envelope);
19483
- if (!isSearch && !isCodeRead) return EXIT_ALLOW8;
20177
+ if (!isSearch && !isCodeRead) return EXIT_ALLOW12;
19484
20178
  const session = sessionId(envelope);
19485
- if (alreadyNudged(root, session)) return EXIT_ALLOW8;
20179
+ if (alreadyNudged(root, session)) return EXIT_ALLOW12;
19486
20180
  let reason;
19487
20181
  try {
19488
20182
  reason = nudgeReason(root);
19489
20183
  } catch {
19490
- return EXIT_ALLOW8;
20184
+ return EXIT_ALLOW12;
19491
20185
  }
19492
20186
  latch(root, session);
19493
20187
  process.stdout.write(`${JSON.stringify({ decision: "warn", reason })}
@@ -19499,15 +20193,15 @@ function isCliEntry10() {
19499
20193
  return false;
19500
20194
  }
19501
20195
  if (process.argv[1] === void 0) return false;
19502
- const argvUrl = pathToFileURL25(path40.resolve(process.argv[1])).href;
20196
+ const argvUrl = pathToFileURL29(path44.resolve(process.argv[1])).href;
19503
20197
  if (import.meta.url === argvUrl) return true;
19504
20198
  try {
19505
- return fs40.realpathSync(fileURLToPath30(import.meta.url)) === fs40.realpathSync(path40.resolve(process.argv[1]));
20199
+ return fs44.realpathSync(fileURLToPath34(import.meta.url)) === fs44.realpathSync(path44.resolve(process.argv[1]));
19506
20200
  } catch {
19507
20201
  return false;
19508
20202
  }
19509
20203
  }
19510
- if (isCliEntry10()) process.exit(main29());
20204
+ if (isCliEntry10()) process.exit(main33());
19511
20205
 
19512
20206
  // src/scripts/hooks/concern_registry.ts
19513
20207
  var CONCERN_REGISTRY = {
@@ -19528,12 +20222,16 @@ var CONCERN_REGISTRY = {
19528
20222
  "src/scripts/team_review_gate_hook.ts": main20,
19529
20223
  "src/scripts/pr_url_reminder_hook.ts": main21,
19530
20224
  "src/scripts/session_canary_hook.ts": main22,
19531
- "src/scripts/hooks/block_no_verify.ts": main23,
19532
- "src/scripts/hooks/block_kernel_rule_writes.ts": main24,
19533
- "src/scripts/hooks/block_config_weakening.ts": main25,
19534
- "src/scripts/hooks/rtk_wrap_hook.ts": main26,
19535
- "src/scripts/hooks/design_slop_hook.ts": main28,
19536
- "src/scripts/hooks/code_graph_nudge_hook.ts": main29
20225
+ "src/scripts/language_mirror_hook.ts": main23,
20226
+ "src/scripts/git_authorization_hook.ts": main24,
20227
+ "src/scripts/hooks/block_unauthorized_git.ts": main25,
20228
+ "src/scripts/hooks/evidence_independence.ts": main26,
20229
+ "src/scripts/hooks/block_no_verify.ts": main27,
20230
+ "src/scripts/hooks/block_kernel_rule_writes.ts": main28,
20231
+ "src/scripts/hooks/block_config_weakening.ts": main29,
20232
+ "src/scripts/hooks/rtk_wrap_hook.ts": main30,
20233
+ "src/scripts/hooks/design_slop_hook.ts": main32,
20234
+ "src/scripts/hooks/code_graph_nudge_hook.ts": main33
19537
20235
  };
19538
20236
 
19539
20237
  // src/scripts/hooks/host_semantics.ts
@@ -19587,13 +20285,13 @@ function emitFor(platform, event, severity, reasons, legacyExit) {
19587
20285
 
19588
20286
  // src/scripts/hooks/dispatch_hook.ts
19589
20287
  var _IN_BUNDLE = true;
19590
- var REPO_ROOT = path41.resolve(
19591
- path41.dirname(fileURLToPath31(import.meta.url)),
20288
+ var REPO_ROOT = path45.resolve(
20289
+ path45.dirname(fileURLToPath35(import.meta.url)),
19592
20290
  ..._IN_BUNDLE ? ["..", ".."] : ["..", "..", ".."]
19593
20291
  );
19594
- var MANIFEST_PATH = path41.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
19595
- var EXIT_ALLOW9 = 0;
19596
- var EXIT_BLOCK2 = 1;
20292
+ var MANIFEST_PATH = path45.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
20293
+ var EXIT_ALLOW13 = 0;
20294
+ var EXIT_BLOCK4 = 1;
19597
20295
  var EXIT_WARN7 = 2;
19598
20296
  var EVENT_VOCABULARY = /* @__PURE__ */ new Set([
19599
20297
  "session_start",
@@ -19606,11 +20304,11 @@ var EVENT_VOCABULARY = /* @__PURE__ */ new Set([
19606
20304
  "agent_error"
19607
20305
  ]);
19608
20306
  var _SEVERITY_BY_EXIT = {
19609
- [EXIT_ALLOW9]: "allow",
19610
- [EXIT_BLOCK2]: "block",
20307
+ [EXIT_ALLOW13]: "allow",
20308
+ [EXIT_BLOCK4]: "block",
19611
20309
  [EXIT_WARN7]: "warn"
19612
20310
  };
19613
- function _isObject9(v) {
20311
+ function _isObject13(v) {
19614
20312
  return typeof v === "object" && v !== null && !Array.isArray(v);
19615
20313
  }
19616
20314
  function _severity_for(rc) {
@@ -19640,33 +20338,33 @@ function _parse_concern_stdout(stdout_text) {
19640
20338
  } catch {
19641
20339
  return { _raw_stdout: text.slice(0, 500) };
19642
20340
  }
19643
- return _isObject9(parsed) ? parsed : { _raw: parsed };
20341
+ return _isObject13(parsed) ? parsed : { _raw: parsed };
19644
20342
  }
19645
20343
  function _load_yaml3(p) {
19646
- const text = fs41.readFileSync(p, "utf-8");
20344
+ const text = fs45.readFileSync(p, "utf-8");
19647
20345
  const data = (0, import_yaml6.parse)(text, { version: "1.1" });
19648
- return _isObject9(data) ? data : {};
20346
+ return _isObject13(data) ? data : {};
19649
20347
  }
19650
20348
  function _resolve_concerns(manifest, platform, event) {
19651
20349
  const platformsRaw = manifest["platforms"];
19652
- const platforms = _isObject9(platformsRaw) ? platformsRaw : {};
20350
+ const platforms = _isObject13(platformsRaw) ? platformsRaw : {};
19653
20351
  const block = platforms[platform];
19654
20352
  if (!block) {
19655
20353
  return [];
19656
20354
  }
19657
- if (_isObject9(block) && block["fallback_only"]) {
20355
+ if (_isObject13(block) && block["fallback_only"]) {
19658
20356
  return [];
19659
20357
  }
19660
- const names = _isObject9(block) ? block[event] : null;
20358
+ const names = _isObject13(block) ? block[event] : null;
19661
20359
  if (!Array.isArray(names)) {
19662
20360
  return [];
19663
20361
  }
19664
20362
  const concernsRaw = manifest["concerns"];
19665
- const concerns_def = _isObject9(concernsRaw) ? concernsRaw : {};
20363
+ const concerns_def = _isObject13(concernsRaw) ? concernsRaw : {};
19666
20364
  const out = [];
19667
20365
  for (const name of names) {
19668
20366
  const spec = typeof name === "string" ? concerns_def[name] : void 0;
19669
- if (!spec || !_isObject9(spec)) {
20367
+ if (!spec || !_isObject13(spec)) {
19670
20368
  process.stderr.write(
19671
20369
  `dispatch_hook: unknown concern '${String(name)}' in manifest
19672
20370
  `
@@ -19756,7 +20454,7 @@ function _maybe_capture_payload(args, payload_text) {
19756
20454
  }
19757
20455
  try {
19758
20456
  const target = _expanduser2(capture_dir);
19759
- fs41.mkdirSync(target, { recursive: true });
20457
+ fs45.mkdirSync(target, { recursive: true });
19760
20458
  let payload;
19761
20459
  try {
19762
20460
  payload = payload_text.trim() ? JSON.parse(payload_text) : {};
@@ -19773,8 +20471,8 @@ function _maybe_capture_payload(args, payload_text) {
19773
20471
  const ts = Date.now();
19774
20472
  const native = (args.native_event || args.event).replace(/\//g, "_");
19775
20473
  const fname = `${args.platform}__${native}__${ts}__${process.pid}.json`;
19776
- fs41.writeFileSync(
19777
- path41.join(target, fname),
20474
+ fs45.writeFileSync(
20475
+ path45.join(target, fname),
19778
20476
  _py_json_dumps2(record, 2) + "\n",
19779
20477
  { encoding: "utf-8" }
19780
20478
  );
@@ -19785,7 +20483,7 @@ function _maybe_capture_payload(args, payload_text) {
19785
20483
  function _expanduser2(p) {
19786
20484
  if (p === "~" || p.startsWith("~/")) {
19787
20485
  const home = process.env["HOME"] || process.env["USERPROFILE"] || "";
19788
- return path41.join(home, p.slice(1));
20486
+ return path45.join(home, p.slice(1));
19789
20487
  }
19790
20488
  return p;
19791
20489
  }
@@ -19793,7 +20491,7 @@ function _build_envelope(args, payload_text) {
19793
20491
  let payload;
19794
20492
  try {
19795
20493
  payload = payload_text.trim() ? JSON.parse(payload_text) : {};
19796
- if (!_isObject9(payload)) {
20494
+ if (!_isObject13(payload)) {
19797
20495
  payload = { _raw: payload };
19798
20496
  }
19799
20497
  } catch {
@@ -19817,25 +20515,25 @@ function _resolve_tsx_invocation2(scriptPath, scriptArgs) {
19817
20515
  const walkUp = (start) => {
19818
20516
  let dir = start;
19819
20517
  for (; ; ) {
19820
- const candidate = path41.join(dir, "node_modules", ".bin", binName);
20518
+ const candidate = path45.join(dir, "node_modules", ".bin", binName);
19821
20519
  if (_isFile7(candidate)) {
19822
20520
  return candidate;
19823
20521
  }
19824
- const parent = path41.dirname(dir);
20522
+ const parent = path45.dirname(dir);
19825
20523
  if (parent === dir) {
19826
20524
  return null;
19827
20525
  }
19828
20526
  dir = parent;
19829
20527
  }
19830
20528
  };
19831
- const tsx = walkUp(path41.dirname(scriptPath)) ?? walkUp(path41.dirname(fileURLToPath31(import.meta.url)));
20529
+ const tsx = walkUp(path45.dirname(scriptPath)) ?? walkUp(path45.dirname(fileURLToPath35(import.meta.url)));
19832
20530
  if (tsx !== null) {
19833
20531
  return { command: tsx, args: [scriptPath, ...scriptArgs] };
19834
20532
  }
19835
20533
  return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
19836
20534
  }
19837
20535
  function _run_concern_inproc(main_fn, concern, envelope) {
19838
- const scriptAbs = path41.join(REPO_ROOT, String(concern["script"]));
20536
+ const scriptAbs = path45.join(REPO_ROOT, String(concern["script"]));
19839
20537
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
19840
20538
  argsList.push("--platform", String(envelope["platform"] || "generic"));
19841
20539
  const workspace = String(envelope["workspace_root"] || process.cwd());
@@ -19912,7 +20610,7 @@ function _run_concern(concern, envelope) {
19912
20610
  return _run_concern_inproc(inproc, concern, envelope);
19913
20611
  }
19914
20612
  }
19915
- const script = path41.join(REPO_ROOT, String(concern["script"]));
20613
+ const script = path45.join(REPO_ROOT, String(concern["script"]));
19916
20614
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
19917
20615
  const cmd = [script, ...argsList];
19918
20616
  cmd.push("--platform", String(envelope["platform"] || "generic"));
@@ -19969,7 +20667,7 @@ function _run_concern(concern, envelope) {
19969
20667
  }
19970
20668
  function _isFile7(p) {
19971
20669
  try {
19972
- return fs41.statSync(p).isFile();
20670
+ return fs45.statSync(p).isFile();
19973
20671
  } catch {
19974
20672
  return false;
19975
20673
  }
@@ -19978,23 +20676,23 @@ function _compactJsonDumps(value) {
19978
20676
  return JSON.stringify(value);
19979
20677
  }
19980
20678
  function _reduce(rcs) {
19981
- if (rcs.some((rc) => rc === EXIT_BLOCK2)) {
19982
- return EXIT_BLOCK2;
20679
+ if (rcs.some((rc) => rc === EXIT_BLOCK4)) {
20680
+ return EXIT_BLOCK4;
19983
20681
  }
19984
20682
  if (rcs.some((rc) => rc === EXIT_WARN7)) {
19985
20683
  return EXIT_WARN7;
19986
20684
  }
19987
- return EXIT_ALLOW9;
20685
+ return EXIT_ALLOW13;
19988
20686
  }
19989
20687
  function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
19990
20688
  if (is_replay_mode()) {
19991
20689
  return;
19992
20690
  }
19993
20691
  const workspace = String(envelope["workspace_root"] || process.cwd());
19994
- const state_root = path41.join(workspace, "agents", "runtime", "state");
20692
+ const state_root = path45.join(workspace, "agents", "runtime", "state");
19995
20693
  const fb_dir = feedback_dir(state_root, session_id);
19996
20694
  try {
19997
- fs41.mkdirSync(fb_dir, { recursive: true });
20695
+ fs45.mkdirSync(fb_dir, { recursive: true });
19998
20696
  } catch (exc) {
19999
20697
  const msg = exc instanceof Error ? exc.message : String(exc);
20000
20698
  process.stderr.write(`dispatch_hook: feedback dir unavailable: ${msg}
@@ -20002,7 +20700,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
20002
20700
  return;
20003
20701
  }
20004
20702
  for (const entry of entries) {
20005
- const target = path41.join(fb_dir, `${entry["concern"]}.json`);
20703
+ const target = path45.join(fb_dir, `${entry["concern"]}.json`);
20006
20704
  try {
20007
20705
  atomic_write_json(target, entry);
20008
20706
  } catch (exc) {
@@ -20042,7 +20740,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
20042
20740
  })
20043
20741
  };
20044
20742
  try {
20045
- atomic_write_json(path41.join(fb_dir, "summary.json"), summary);
20743
+ atomic_write_json(path45.join(fb_dir, "summary.json"), summary);
20046
20744
  } catch (exc) {
20047
20745
  const msg = exc instanceof Error ? exc.message : String(exc);
20048
20746
  process.stderr.write(`dispatch_hook: summary write failed: ${msg}
@@ -20052,17 +20750,17 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
20052
20750
  function _record_rule_trips(envelope, entries) {
20053
20751
  if (is_replay_mode()) return;
20054
20752
  const tripped = entries.filter(
20055
- (e) => e["exit_code"] === EXIT_BLOCK2 || e["exit_code"] === EXIT_WARN7
20753
+ (e) => e["exit_code"] === EXIT_BLOCK4 || e["exit_code"] === EXIT_WARN7
20056
20754
  );
20057
20755
  if (tripped.length === 0) return;
20058
20756
  try {
20059
20757
  const workspace = String(envelope["workspace_root"] || process.cwd());
20060
- const state_dir = path41.join(workspace, "agents", "runtime", "state");
20061
- const target = path41.join(state_dir, "rule-trips.json");
20062
- fs41.mkdirSync(state_dir, { recursive: true });
20758
+ const state_dir = path45.join(workspace, "agents", "runtime", "state");
20759
+ const target = path45.join(state_dir, "rule-trips.json");
20760
+ fs45.mkdirSync(state_dir, { recursive: true });
20063
20761
  let doc = { schema_version: 1, concerns: {} };
20064
20762
  try {
20065
- const parsed = JSON.parse(fs41.readFileSync(target, "utf-8"));
20763
+ const parsed = JSON.parse(fs45.readFileSync(target, "utf-8"));
20066
20764
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) doc = parsed;
20067
20765
  } catch {
20068
20766
  }
@@ -20072,7 +20770,7 @@ function _record_rule_trips(envelope, entries) {
20072
20770
  const name = String(e["concern"]);
20073
20771
  const prev = concerns[name] ?? { block: 0, warn: 0 };
20074
20772
  concerns[name] = {
20075
- block: (Number(prev["block"]) || 0) + (e["exit_code"] === EXIT_BLOCK2 ? 1 : 0),
20773
+ block: (Number(prev["block"]) || 0) + (e["exit_code"] === EXIT_BLOCK4 ? 1 : 0),
20076
20774
  warn: (Number(prev["warn"]) || 0) + (e["exit_code"] === EXIT_WARN7 ? 1 : 0),
20077
20775
  last_trip: today
20078
20776
  };
@@ -20161,7 +20859,7 @@ function _parse_args(argv) {
20161
20859
  }
20162
20860
  return args;
20163
20861
  }
20164
- function main30(argv) {
20862
+ function main34(argv) {
20165
20863
  const args = _parse_args(argv ?? process.argv.slice(2));
20166
20864
  if (args.project_dir) {
20167
20865
  const project_dir = _expanduser2(args.project_dir);
@@ -20179,13 +20877,13 @@ function main30(argv) {
20179
20877
  `dispatch_hook: unknown event '${args.event}'; allowed: ${_sortedRepr(EVENT_VOCABULARY)}
20180
20878
  `
20181
20879
  );
20182
- return EXIT_ALLOW9;
20880
+ return EXIT_ALLOW13;
20183
20881
  }
20184
20882
  const manifest_path = args.manifest;
20185
- if (!fs41.existsSync(manifest_path)) {
20883
+ if (!fs45.existsSync(manifest_path)) {
20186
20884
  process.stderr.write(`dispatch_hook: manifest missing at ${manifest_path}
20187
20885
  `);
20188
- return EXIT_ALLOW9;
20886
+ return EXIT_ALLOW13;
20189
20887
  }
20190
20888
  const manifest = _load_yaml3(manifest_path);
20191
20889
  if (args.min_version) {
@@ -20207,10 +20905,10 @@ function main30(argv) {
20207
20905
  concerns: concerns.map((c) => c["name"])
20208
20906
  };
20209
20907
  process.stdout.write(_py_json_dumps2(plan, 2) + "\n");
20210
- return EXIT_ALLOW9;
20908
+ return EXIT_ALLOW13;
20211
20909
  }
20212
20910
  if (concerns.length === 0) {
20213
- return EXIT_ALLOW9;
20911
+ return EXIT_ALLOW13;
20214
20912
  }
20215
20913
  const envelope = _build_envelope(args, payload_text);
20216
20914
  const session_id = _resolve_session_id(envelope);
@@ -20226,15 +20924,15 @@ function main30(argv) {
20226
20924
  const raw_rc = rc;
20227
20925
  if (rc >= 3) {
20228
20926
  if (!concern["fail_closed"]) {
20229
- rc = EXIT_ALLOW9;
20927
+ rc = EXIT_ALLOW13;
20230
20928
  } else {
20231
- rc = EXIT_BLOCK2;
20929
+ rc = EXIT_BLOCK4;
20232
20930
  }
20233
20931
  if (stderr_text) {
20234
20932
  process.stderr.write(stderr_text);
20235
20933
  }
20236
20934
  }
20237
- if (rc === EXIT_BLOCK2 && _is_advisory(concern)) {
20935
+ if (rc === EXIT_BLOCK4 && _is_advisory(concern)) {
20238
20936
  process.stderr.write(
20239
20937
  `dispatch_hook: concern '${String(concern["name"])}' is declared severity: advisory but returned BLOCK \u2014 downgraded to warn.
20240
20938
  `
@@ -20247,7 +20945,7 @@ function main30(argv) {
20247
20945
  if (stated) {
20248
20946
  concern_messages.push({ rc, text: stated });
20249
20947
  }
20250
- if (args.event === "session_start" && rc === EXIT_ALLOW9 && typeof reply["context"] === "string" && reply["context"].trim()) {
20948
+ if (args.event === "session_start" && rc === EXIT_ALLOW13 && typeof reply["context"] === "string" && reply["context"].trim()) {
20251
20949
  context_blocks.push(reply["context"].trim());
20252
20950
  }
20253
20951
  feedback_entries.push({
@@ -20266,7 +20964,7 @@ function main30(argv) {
20266
20964
  const final_rc = _reduce(rcs);
20267
20965
  _write_feedback(envelope, session_id, feedback_entries, final_rc, started_at);
20268
20966
  _record_rule_trips(envelope, feedback_entries);
20269
- if (context_blocks.length > 0 && final_rc === EXIT_ALLOW9) {
20967
+ if (context_blocks.length > 0 && final_rc === EXIT_ALLOW13) {
20270
20968
  process.stdout.write(context_blocks.join("\n\n") + "\n");
20271
20969
  }
20272
20970
  const decidingReasons = concern_messages.filter((m) => m.rc === final_rc).map((m) => m.text);
@@ -20287,7 +20985,7 @@ function main30(argv) {
20287
20985
  }
20288
20986
  function _isDir4(p) {
20289
20987
  try {
20290
- return fs41.statSync(p).isDirectory();
20988
+ return fs45.statSync(p).isDirectory();
20291
20989
  } catch {
20292
20990
  return false;
20293
20991
  }
@@ -20298,41 +20996,41 @@ function _sortedRepr(s) {
20298
20996
  }
20299
20997
  function _readStdin14() {
20300
20998
  try {
20301
- return fs41.readFileSync(0, "utf-8");
20999
+ return fs45.readFileSync(0, "utf-8");
20302
21000
  } catch {
20303
21001
  return "";
20304
21002
  }
20305
21003
  }
20306
- function _isCliEntry24() {
21004
+ function _isCliEntry28() {
20307
21005
  if (true) {
20308
21006
  return false;
20309
21007
  }
20310
21008
  if (process.argv[1] === void 0) {
20311
21009
  return false;
20312
21010
  }
20313
- const argvUrl = pathToFileURL26(path41.resolve(process.argv[1])).href;
21011
+ const argvUrl = pathToFileURL30(path45.resolve(process.argv[1])).href;
20314
21012
  if (import.meta.url === argvUrl) {
20315
21013
  return true;
20316
21014
  }
20317
21015
  try {
20318
- const here = fs41.realpathSync(fileURLToPath31(import.meta.url));
20319
- const argv = fs41.realpathSync(path41.resolve(process.argv[1]));
21016
+ const here = fs45.realpathSync(fileURLToPath35(import.meta.url));
21017
+ const argv = fs45.realpathSync(path45.resolve(process.argv[1]));
20320
21018
  return here === argv;
20321
21019
  } catch {
20322
21020
  return false;
20323
21021
  }
20324
21022
  }
20325
- var isCliEntry11 = _isCliEntry24();
21023
+ var isCliEntry11 = _isCliEntry28();
20326
21024
  if (isCliEntry11) {
20327
- process.exit(main30(process.argv.slice(2)));
21025
+ process.exit(main34(process.argv.slice(2)));
20328
21026
  }
20329
21027
 
20330
21028
  // src/scripts/hooks/dispatch_entry.ts
20331
- var _selfPath = fileURLToPath32(import.meta.url);
20332
- var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path42.resolve(process.argv[1]) === path42.resolve(_selfPath);
21029
+ var _selfPath = fileURLToPath36(import.meta.url);
21030
+ var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path46.resolve(process.argv[1]) === path46.resolve(_selfPath);
20333
21031
  if (_invokedDirectly2) {
20334
- process.exitCode = main30(process.argv.slice(2));
21032
+ process.exitCode = main34(process.argv.slice(2));
20335
21033
  }
20336
21034
  export {
20337
- main30 as main
21035
+ main34 as main
20338
21036
  };