@event4u/agent-config 9.30.0 → 9.31.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 (62) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +31 -314
  3. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  4. package/dist/cli-delegate/{chunk-IYTGIG2Y.js → chunk-2WCLVDWC.js} +1 -1
  5. package/dist/cli-delegate/{chunk-66OVWGB5.js → chunk-AG47LAGQ.js} +1 -1
  6. package/dist/cli-delegate/{chunk-MP3JT3IU.js → chunk-DS6BLDMG.js} +1 -1
  7. package/dist/cli-delegate/{chunk-O3CO5BFB.js → chunk-EJITJBJX.js} +12 -1
  8. package/dist/cli-delegate/{chunk-EQY4FLJB.js → chunk-ITIQSGOQ.js} +3 -3
  9. package/dist/cli-delegate/{chunk-LCFJIQ4J.js → chunk-JEJABGKB.js} +110 -6
  10. package/dist/cli-delegate/{chunk-BTJNRUX3.js → chunk-QEEB4LHO.js} +1 -1
  11. package/dist/cli-delegate/{chunk-DDUNNFYX.js → chunk-UVKNIJH2.js} +2 -2
  12. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  13. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  14. package/dist/cli-delegate/cmd_conformance.js +98 -36
  15. package/dist/cli-delegate/cmd_doctor.js +3 -3
  16. package/dist/cli-delegate/cmd_explain.js +2 -2
  17. package/dist/cli-delegate/cmd_export.js +4 -4
  18. package/dist/cli-delegate/cmd_handoff.js +2 -2
  19. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  20. package/dist/cli-delegate/cmd_migrate.js +2 -2
  21. package/dist/cli-delegate/cmd_packs_active.js +2 -2
  22. package/dist/cli-delegate/cmd_prune.js +4 -4
  23. package/dist/cli-delegate/cmd_route_audit.js +2 -2
  24. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  25. package/dist/cli-delegate/cmd_session_recycle.js +2 -2
  26. package/dist/cli-delegate/cmd_settings_get.js +2 -55
  27. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  28. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  29. package/dist/cli-delegate/cmd_sync.js +4 -4
  30. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  31. package/dist/cli-delegate/cmd_update.js +1 -1
  32. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  33. package/dist/cli-delegate/cmd_validate.js +4 -4
  34. package/dist/cli-delegate/cmd_versions.js +1 -1
  35. package/dist/discovery/deprecation-report.md +1 -1
  36. package/dist/discovery/discovery-manifest.json +1 -1
  37. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  38. package/dist/discovery/discovery-manifest.summary.md +1 -1
  39. package/dist/discovery/orphan-report.md +1 -1
  40. package/dist/discovery/packs.json +1 -1
  41. package/dist/discovery/trust-report.md +1 -1
  42. package/dist/discovery/workspaces.json +1 -1
  43. package/dist/hooks/dispatch.js +347 -174
  44. package/dist/install/install.mjs +121 -16
  45. package/dist/mcp/registry-manifest.json +1 -1
  46. package/dist/mcp/server.json +2 -2
  47. package/dist/mcp/server.mjs +310 -138
  48. package/dist/scripts/_lib/agent_settings.js +111 -2
  49. package/dist/scripts/_lib/agent_settings.js.map +1 -1
  50. package/dist/server/schemas/settings.js +2 -2
  51. package/dist/server/schemas/settings.js.map +1 -1
  52. package/package.json +1 -1
  53. package/src/config/pack-size-budget.json +3 -2
  54. package/src/scripts/_cli/explain_last/inputs.ts +13 -0
  55. package/src/scripts/_lib/agent_settings.ts +119 -2
  56. package/src/scripts/_lib/carrier_divergence.ts +47 -0
  57. package/src/scripts/hooks/turn_end_gate_hook.ts +296 -88
  58. package/src/scripts/language_mirror_hook.ts +69 -16
  59. package/src/scripts/measure_turn_end_gate.ts +129 -51
  60. package/src/scripts/report_carrier_divergence.ts +72 -24
  61. package/src/scripts/report_conformance_funnel.ts +11 -4
  62. package/src/server/schemas/settings.ts +2 -2
@@ -7364,14 +7364,14 @@ var require_dist = __commonJS({
7364
7364
 
7365
7365
  // src/scripts/hooks/dispatch_entry.ts
7366
7366
  import * as path64 from "node:path";
7367
- import { fileURLToPath as fileURLToPath46 } from "node:url";
7367
+ import { fileURLToPath as fileURLToPath47 } 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 spawnSync7 } from "node:child_process";
7372
7372
  import fs62 from "node:fs";
7373
7373
  import path63 from "node:path";
7374
- import { fileURLToPath as fileURLToPath45, pathToFileURL as pathToFileURL40 } from "node:url";
7374
+ import { fileURLToPath as fileURLToPath46, pathToFileURL as pathToFileURL40 } from "node:url";
7375
7375
 
7376
7376
  // src/scripts/_lib/spawn_env.ts
7377
7377
  var DENY_EXACT = /* @__PURE__ */ new Set([
@@ -7546,6 +7546,15 @@ function atomic_write_json(target, payload, options = {}) {
7546
7546
  const body = _py_json_dumps(payload, indent) + "\n";
7547
7547
  _atomic_write_text(targetPath, body);
7548
7548
  }
7549
+ function atomic_write_text(target, text) {
7550
+ if (is_replay_mode()) {
7551
+ return;
7552
+ }
7553
+ const targetPath = path.resolve(target);
7554
+ const state_dir = path.dirname(targetPath);
7555
+ fs.mkdirSync(state_dir, { recursive: true });
7556
+ _atomic_write_text(targetPath, text);
7557
+ }
7549
7558
  function _acquire_lock(lock_path) {
7550
7559
  const fd = fs.openSync(lock_path, "a", 420);
7551
7560
  const held = lock_path + ".held";
@@ -7717,7 +7726,7 @@ function fix_hint(_workspace_root) {
7717
7726
  import { createHash as createHash2 } from "node:crypto";
7718
7727
  import * as fs13 from "node:fs";
7719
7728
  import * as path12 from "node:path";
7720
- import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL5 } from "node:url";
7729
+ import { fileURLToPath as fileURLToPath8, pathToFileURL as pathToFileURL5 } from "node:url";
7721
7730
 
7722
7731
  // src/scripts/memory_lookup.ts
7723
7732
  var import_yaml2 = __toESM(require_dist(), 1);
@@ -11426,6 +11435,7 @@ if (_isMain3) {
11426
11435
  import { createRequire as createRequire3 } from "node:module";
11427
11436
  import * as fs11 from "node:fs";
11428
11437
  import * as path11 from "node:path";
11438
+ import { fileURLToPath as fileURLToPath7 } from "node:url";
11429
11439
 
11430
11440
  // src/scripts/_lib/user_global_paths.ts
11431
11441
  import * as fs10 from "node:fs";
@@ -11483,6 +11493,61 @@ function write_target(relative_name, options = {}) {
11483
11493
  return path10.join(event4u_root(options.env ?? null), relative_name);
11484
11494
  }
11485
11495
 
11496
+ // src/shared/settingsCarveOut.ts
11497
+ var SETTINGS_CARVE_OUT = [
11498
+ {
11499
+ key: "projection.mode",
11500
+ reader: "src/scripts/install.ts:3409 _resolve_scoped_projection",
11501
+ absentResolvesTo: "legacy-all",
11502
+ reason: "The template fallback applies only when NO global settings file exists. Once a file exists, an absent key means legacy-all by documented contract, so an existing install is never silently narrowed on upgrade."
11503
+ },
11504
+ {
11505
+ key: "projection.rule_workspaces",
11506
+ reader: "src/install/rule_scope.ts:96 ruleScopeFromSettings",
11507
+ absentResolvesTo: "null \u2014 LEGACY_ALL, i.e. every rule ships including maintainer-only ones",
11508
+ reason: "Same upgrade contract as projection.mode, and the failure is louder: an absent list widens the projection instead of narrowing it."
11509
+ },
11510
+ {
11511
+ key: "discipline_profile",
11512
+ reader: "work_engine/_lib/agent_settings.ts:1263",
11513
+ absentResolvesTo: "essential, unconditionally",
11514
+ reason: "The template ships `auto`, which resolves to `off` on any measured-null model, any non-Claude host, and any host exposing no model id. Absent skips that resolution entirely and loads the essential tier everywhere."
11515
+ },
11516
+ {
11517
+ key: "chat_history.frequency",
11518
+ reader: "src/scripts/chat_history.ts:1140",
11519
+ absentResolvesTo: "per_phase",
11520
+ reason: "Canonical substitution is `per_turn`. Absent gives coarser capture than the shipped default \u2014 an audit-thinning change, which the class contract's own test 8 (what can the attacker HIDE) names as the severe direction."
11521
+ },
11522
+ {
11523
+ key: "profile.id",
11524
+ reader: "src/scripts/config/profiles.ts:221 resolve_profile",
11525
+ absentResolvesTo: "the id `developer`, but a DEGRADED profile \u2014 packs: [], personas: [], hints: []",
11526
+ reason: "Exactly the projection.mode shape: the template default is honoured only when no settings file exists. With a file present the id resolves but its profile body does not load, so the install silently loses every pack and persona."
11527
+ },
11528
+ {
11529
+ key: "quality.local_auto_run",
11530
+ reader: "src/scripts/lint_roadmap_ci_steps.ts:106",
11531
+ absentResolvesTo: "true \u2014 which DISABLES the CI-step gate",
11532
+ reason: "Inverted polarity, and the most dangerous row in the set: the template ships `false`, which ARMS the gate. Omitting the key would disarm a quality gate for every fresh install while the reference page says it is on."
11533
+ },
11534
+ {
11535
+ key: "onboarding.onboarded",
11536
+ reader: "src/scripts/onboarding_gate_hook.ts:99",
11537
+ absentResolvesTo: "gate skipped, as if onboarding had already completed",
11538
+ reason: "Absent behaves like `onboarded: true`, not like the template default `false`. Omitting it would skip the onboarding gate on precisely the fresh installs the gate exists for."
11539
+ },
11540
+ {
11541
+ key: "chat_history.enabled",
11542
+ reader: "src/scripts/chat_history.ts:1025 _read_chat_history_enabled",
11543
+ absentResolvesTo: "false",
11544
+ reason: "The reader falls back to false while the template ships true. This one is privacy-shaped: fixing the reader would start recording history for every install whose file lacks the key. Writing it explicitly keeps the decision visible in the file the user can read."
11545
+ }
11546
+ ];
11547
+ function carveOutKeys() {
11548
+ return SETTINGS_CARVE_OUT.map((c) => c.key);
11549
+ }
11550
+
11486
11551
  // src/scripts/_lib/agent_settings.ts
11487
11552
  var _require2 = createRequire3(import.meta.url);
11488
11553
  var Logger = class {
@@ -11581,7 +11646,45 @@ var MERGEABLE_KEYS = [
11581
11646
  "knowledge.global_sharing.freshness.hypothesis_after_days",
11582
11647
  "knowledge.global_sharing.freshness.stale_after_days"
11583
11648
  ];
11584
- var _DEFAULTS = {};
11649
+ var TEMPLATE_RELATIVE = path11.join("src", "config", "agent-settings.template.yml");
11650
+ var _PACKAGE_ROOT = path11.resolve(path11.dirname(fileURLToPath7(import.meta.url)), "..", "..", "..");
11651
+ function default_template_path() {
11652
+ return path11.join(_PACKAGE_ROOT, TEMPLATE_RELATIVE);
11653
+ }
11654
+ function _is_placeholder(value) {
11655
+ return typeof value === "string" && /^__[A-Z0-9_]+__$/.test(value);
11656
+ }
11657
+ function _prune_template(tree, excluded, prefix = "") {
11658
+ const out = {};
11659
+ for (const [key, value] of Object.entries(tree)) {
11660
+ const dotted = prefix === "" ? key : `${prefix}.${key}`;
11661
+ if (excluded.has(dotted) || _is_placeholder(value)) {
11662
+ continue;
11663
+ }
11664
+ if (_is_plain_dict(value)) {
11665
+ const child = _prune_template(value, excluded, dotted);
11666
+ if (Object.keys(child).length > 0) {
11667
+ out[key] = child;
11668
+ }
11669
+ continue;
11670
+ }
11671
+ out[key] = value;
11672
+ }
11673
+ return out;
11674
+ }
11675
+ var _template_defaults_cache = null;
11676
+ function template_defaults(template_path) {
11677
+ const use_cache = template_path === void 0;
11678
+ if (use_cache && _template_defaults_cache !== null) {
11679
+ return _deepcopy(_template_defaults_cache);
11680
+ }
11681
+ const parsed = _read_yaml(template_path ?? default_template_path()) ?? {};
11682
+ const pruned = _prune_template(parsed, new Set(carveOutKeys()));
11683
+ if (use_cache) {
11684
+ _template_defaults_cache = pruned;
11685
+ }
11686
+ return _deepcopy(pruned);
11687
+ }
11585
11688
  var ANCHOR_AGENT_SETTINGS = "agent-settings";
11586
11689
  var ANCHOR_AGENTS_DIR = "agents-dir";
11587
11690
  var ANCHOR_GIT = "git";
@@ -11724,6 +11827,7 @@ function load_agent_settings(options = {}) {
11724
11827
  const user_global_path = options.user_global_path ?? null;
11725
11828
  const verbose = options.verbose ?? false;
11726
11829
  const cwd = options.cwd ?? null;
11830
+ const template_path = options.template_path ?? null;
11727
11831
  const user_global_raw = {};
11728
11832
  for (const p of user_global_path ? [user_global_path] : user_global_settings_paths()) {
11729
11833
  _deep_merge(user_global_raw, _read_yaml(p) ?? {});
@@ -11736,7 +11840,7 @@ function load_agent_settings(options = {}) {
11736
11840
  );
11737
11841
  }
11738
11842
  const cascade = _resolve_cascade_paths(cwd, project_path);
11739
- const merged = _deep_copy_defaults(_DEFAULTS);
11843
+ const merged = template_defaults(template_path ?? void 0);
11740
11844
  _deep_merge(merged, user_global_filtered);
11741
11845
  for (const p of cascade) {
11742
11846
  const layer = _read_yaml(p) ?? {};
@@ -11872,10 +11976,18 @@ function _deep_merge(dst, src) {
11872
11976
  }
11873
11977
  }
11874
11978
  }
11875
- function _deep_copy_defaults(src) {
11876
- const out = {};
11877
- _deep_merge(out, src);
11878
- return out;
11979
+ function _deepcopy(value) {
11980
+ if (Array.isArray(value)) {
11981
+ return value.map((v) => _deepcopy(v));
11982
+ }
11983
+ if (_is_plain_dict(value)) {
11984
+ const out = {};
11985
+ for (const [k, v] of Object.entries(value)) {
11986
+ out[k] = _deepcopy(v);
11987
+ }
11988
+ return out;
11989
+ }
11990
+ return value;
11879
11991
  }
11880
11992
  function _is_plain_dict(value) {
11881
11993
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -13888,7 +14000,7 @@ function _isCliEntry5() {
13888
14000
  return true;
13889
14001
  }
13890
14002
  try {
13891
- const here = fs13.realpathSync(fileURLToPath7(import.meta.url));
14003
+ const here = fs13.realpathSync(fileURLToPath8(import.meta.url));
13892
14004
  const argv = fs13.realpathSync(path12.resolve(process.argv[1]));
13893
14005
  return here === argv;
13894
14006
  } catch {
@@ -13916,7 +14028,7 @@ import * as fs15 from "node:fs";
13916
14028
  import { createRequire as createRequire4 } from "node:module";
13917
14029
  import * as path14 from "node:path";
13918
14030
  import process6 from "node:process";
13919
- import { fileURLToPath as fileURLToPath8 } from "node:url";
14031
+ import { fileURLToPath as fileURLToPath9 } from "node:url";
13920
14032
 
13921
14033
  // src/scripts/ai_council/config.ts
13922
14034
  var import_yaml3 = __toESM(require_dist(), 1);
@@ -15609,7 +15721,7 @@ function main7() {
15609
15721
  return 0;
15610
15722
  }
15611
15723
  var _bundled2 = true;
15612
- if (!_bundled2 && fileURLToPath8(import.meta.url) === path14.resolve(process6.argv[1] ?? "")) {
15724
+ if (!_bundled2 && fileURLToPath9(import.meta.url) === path14.resolve(process6.argv[1] ?? "")) {
15613
15725
  process6.exit(main7());
15614
15726
  }
15615
15727
 
@@ -15617,7 +15729,7 @@ if (!_bundled2 && fileURLToPath8(import.meta.url) === path14.resolve(process6.ar
15617
15729
  import * as fs16 from "node:fs";
15618
15730
  import * as path16 from "node:path";
15619
15731
  import process7 from "node:process";
15620
- import { fileURLToPath as fileURLToPath9 } from "node:url";
15732
+ import { fileURLToPath as fileURLToPath10 } from "node:url";
15621
15733
 
15622
15734
  // src/scripts/_lib/recycle_envelope_paths.ts
15623
15735
  import * as path15 from "node:path";
@@ -15908,7 +16020,7 @@ function main8() {
15908
16020
  return 0;
15909
16021
  }
15910
16022
  var _bundled3 = true;
15911
- if (!_bundled3 && fileURLToPath9(import.meta.url) === path16.resolve(process7.argv[1] ?? "")) {
16023
+ if (!_bundled3 && fileURLToPath10(import.meta.url) === path16.resolve(process7.argv[1] ?? "")) {
15912
16024
  process7.exit(main8());
15913
16025
  }
15914
16026
 
@@ -15916,7 +16028,7 @@ if (!_bundled3 && fileURLToPath9(import.meta.url) === path16.resolve(process7.ar
15916
16028
  import { spawnSync as spawnSync3 } from "node:child_process";
15917
16029
  import fs17 from "node:fs";
15918
16030
  import path17 from "node:path";
15919
- import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL6 } from "node:url";
16031
+ import { fileURLToPath as fileURLToPath11, pathToFileURL as pathToFileURL6 } from "node:url";
15920
16032
  var REPLAY_ENV_VAR5 = "AGENT_CONFIG_REPLAY";
15921
16033
  var WRITE_TOOLS = /* @__PURE__ */ new Set([
15922
16034
  "str-replace-editor",
@@ -15939,7 +16051,7 @@ var DIST_SCRIPT_SUBDIRS = [
15939
16051
  path17.join("src/agent-src", "scripts")
15940
16052
  ];
15941
16053
  var PACKAGE_ROOT_ENV_VAR = "AGENT_CONFIG_PACKAGE_ROOT";
15942
- var __filename = fileURLToPath10(import.meta.url);
16054
+ var __filename = fileURLToPath11(import.meta.url);
15943
16055
  function _candidate_paths(payload) {
15944
16056
  const out = [];
15945
16057
  const fc = payload["file_changes"];
@@ -16057,7 +16169,7 @@ function _resolve_tsx_invocation(scriptPath) {
16057
16169
  dir = parent;
16058
16170
  }
16059
16171
  };
16060
- const tsx = walkUp(path17.dirname(scriptPath)) ?? walkUp(path17.dirname(fileURLToPath10(import.meta.url)));
16172
+ const tsx = walkUp(path17.dirname(scriptPath)) ?? walkUp(path17.dirname(fileURLToPath11(import.meta.url)));
16061
16173
  if (tsx !== null) {
16062
16174
  return { command: tsx, args: [scriptPath] };
16063
16175
  }
@@ -16181,7 +16293,7 @@ function _isCliEntry6() {
16181
16293
  return true;
16182
16294
  }
16183
16295
  try {
16184
- const here = fs17.realpathSync(fileURLToPath10(import.meta.url));
16296
+ const here = fs17.realpathSync(fileURLToPath11(import.meta.url));
16185
16297
  const argv = fs17.realpathSync(path17.resolve(process.argv[1]));
16186
16298
  return here === argv;
16187
16299
  } catch {
@@ -16196,7 +16308,7 @@ if (isCliEntry) {
16196
16308
  // src/scripts/onboarding_gate_hook.ts
16197
16309
  import fs18 from "node:fs";
16198
16310
  import path18 from "node:path";
16199
- import { fileURLToPath as fileURLToPath11, pathToFileURL as pathToFileURL7 } from "node:url";
16311
+ import { fileURLToPath as fileURLToPath12, pathToFileURL as pathToFileURL7 } from "node:url";
16200
16312
  var SETTINGS_FILE = ".agent-settings.yml";
16201
16313
  var SETTINGS_CANDIDATES = [
16202
16314
  path18.join("agents", "settings", SETTINGS_FILE),
@@ -16349,7 +16461,7 @@ function _isCliEntry7() {
16349
16461
  return true;
16350
16462
  }
16351
16463
  try {
16352
- const here = fs18.realpathSync(fileURLToPath11(import.meta.url));
16464
+ const here = fs18.realpathSync(fileURLToPath12(import.meta.url));
16353
16465
  const argv = fs18.realpathSync(path18.resolve(process.argv[1]));
16354
16466
  return here === argv;
16355
16467
  } catch {
@@ -16364,7 +16476,7 @@ if (isCliEntry2) {
16364
16476
  // src/scripts/context_hygiene_hook.ts
16365
16477
  import fs19 from "node:fs";
16366
16478
  import path19 from "node:path";
16367
- import { fileURLToPath as fileURLToPath12, pathToFileURL as pathToFileURL8 } from "node:url";
16479
+ import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL8 } from "node:url";
16368
16480
  var STATE_DIR2 = path19.join("agents", "state");
16369
16481
  var STATE_FILE2 = path19.join(STATE_DIR2, "context-hygiene.json");
16370
16482
  var LOOP_THRESHOLD = 3;
@@ -16541,7 +16653,7 @@ function _isCliEntry8() {
16541
16653
  return true;
16542
16654
  }
16543
16655
  try {
16544
- const here = fs19.realpathSync(fileURLToPath12(import.meta.url));
16656
+ const here = fs19.realpathSync(fileURLToPath13(import.meta.url));
16545
16657
  const argv = fs19.realpathSync(path19.resolve(process.argv[1]));
16546
16658
  return here === argv;
16547
16659
  } catch {
@@ -16556,7 +16668,7 @@ if (isCliEntry3) {
16556
16668
  // src/scripts/before_complete_hook.ts
16557
16669
  import fs20 from "node:fs";
16558
16670
  import path20 from "node:path";
16559
- import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL9 } from "node:url";
16671
+ import { fileURLToPath as fileURLToPath14, pathToFileURL as pathToFileURL9 } from "node:url";
16560
16672
  var STATE_FILE3 = path20.join("agents", "state", "verify-before-complete.json");
16561
16673
  var COMMAND_TOOLS = /* @__PURE__ */ new Set([
16562
16674
  "launch-process",
@@ -16846,7 +16958,7 @@ function _isCliEntry9() {
16846
16958
  return true;
16847
16959
  }
16848
16960
  try {
16849
- const here = fs20.realpathSync(fileURLToPath13(import.meta.url));
16961
+ const here = fs20.realpathSync(fileURLToPath14(import.meta.url));
16850
16962
  const argv = fs20.realpathSync(path20.resolve(process.argv[1]));
16851
16963
  return here === argv;
16852
16964
  } catch {
@@ -16861,7 +16973,7 @@ if (isCliEntry4) {
16861
16973
  // src/scripts/minimal_safe_diff_hook.ts
16862
16974
  import fs21 from "node:fs";
16863
16975
  import path21 from "node:path";
16864
- import { fileURLToPath as fileURLToPath14, pathToFileURL as pathToFileURL10 } from "node:url";
16976
+ import { fileURLToPath as fileURLToPath15, pathToFileURL as pathToFileURL10 } from "node:url";
16865
16977
  var STATE_FILE4 = path21.join("agents", "state", "minimal-safe-diff.json");
16866
16978
  var SETTINGS_FILE2 = ".agent-settings.yml";
16867
16979
  var DEFAULT_THRESHOLD = 5;
@@ -17124,7 +17236,7 @@ function _isCliEntry10() {
17124
17236
  return true;
17125
17237
  }
17126
17238
  try {
17127
- const here = fs21.realpathSync(fileURLToPath14(import.meta.url));
17239
+ const here = fs21.realpathSync(fileURLToPath15(import.meta.url));
17128
17240
  const argv = fs21.realpathSync(path21.resolve(process.argv[1]));
17129
17241
  return here === argv;
17130
17242
  } catch {
@@ -17139,7 +17251,7 @@ if (isCliEntry5) {
17139
17251
  // src/scripts/injection_scan_hook.ts
17140
17252
  import fs22 from "node:fs";
17141
17253
  import path22 from "node:path";
17142
- import { fileURLToPath as fileURLToPath15, pathToFileURL as pathToFileURL11 } from "node:url";
17254
+ import { fileURLToPath as fileURLToPath16, pathToFileURL as pathToFileURL11 } from "node:url";
17143
17255
  var SETTINGS_FILE3 = ".agent-settings.yml";
17144
17256
  var EXIT_ALLOW = 0;
17145
17257
  var EXIT_WARN = 2;
@@ -17359,7 +17471,7 @@ function _isCliEntry11() {
17359
17471
  return true;
17360
17472
  }
17361
17473
  try {
17362
- const here = fs22.realpathSync(fileURLToPath15(import.meta.url));
17474
+ const here = fs22.realpathSync(fileURLToPath16(import.meta.url));
17363
17475
  const argv = fs22.realpathSync(path22.resolve(process.argv[1]));
17364
17476
  return here === argv;
17365
17477
  } catch {
@@ -17373,7 +17485,7 @@ if (_isCliEntry11()) {
17373
17485
  // src/scripts/memory_learn_hook.ts
17374
17486
  import fs23 from "node:fs";
17375
17487
  import path23 from "node:path";
17376
- import { fileURLToPath as fileURLToPath16, pathToFileURL as pathToFileURL12 } from "node:url";
17488
+ import { fileURLToPath as fileURLToPath17, pathToFileURL as pathToFileURL12 } from "node:url";
17377
17489
 
17378
17490
  // src/shared/settingsClasses.ts
17379
17491
  function isConservativeDefault(value) {
@@ -17488,12 +17600,12 @@ var _isMain4 = (() => {
17488
17600
  if (_isMain4) {
17489
17601
  process.exit(main15());
17490
17602
  }
17491
- var _HERE2 = fileURLToPath16(import.meta.url);
17603
+ var _HERE2 = fileURLToPath17(import.meta.url);
17492
17604
 
17493
17605
  // src/scripts/first_run_gate_hook.ts
17494
17606
  import fs24 from "node:fs";
17495
17607
  import path24 from "node:path";
17496
- import { fileURLToPath as fileURLToPath17, pathToFileURL as pathToFileURL13 } from "node:url";
17608
+ import { fileURLToPath as fileURLToPath18, pathToFileURL as pathToFileURL13 } from "node:url";
17497
17609
  var PLUGIN_ID = "agent-config@event4u-agent-config";
17498
17610
  var ACTION_NEEDED_FILE = ".augment/.first-run-action-needed.md";
17499
17611
  var REGENERATOR_PATHS = [
@@ -17659,7 +17771,7 @@ function _isCliEntry12() {
17659
17771
  return true;
17660
17772
  }
17661
17773
  try {
17662
- const here = fs24.realpathSync(fileURLToPath17(import.meta.url));
17774
+ const here = fs24.realpathSync(fileURLToPath18(import.meta.url));
17663
17775
  const argv = fs24.realpathSync(path24.resolve(process.argv[1]));
17664
17776
  return here === argv;
17665
17777
  } catch {
@@ -17675,7 +17787,7 @@ if (isCliEntry6) {
17675
17787
  var import_yaml4 = __toESM(require_dist(), 1);
17676
17788
  import fs26 from "node:fs";
17677
17789
  import path26 from "node:path";
17678
- import { fileURLToPath as fileURLToPath18, pathToFileURL as pathToFileURL14 } from "node:url";
17790
+ import { fileURLToPath as fileURLToPath19, pathToFileURL as pathToFileURL14 } from "node:url";
17679
17791
 
17680
17792
  // src/scripts/hooks/probe_throttle.ts
17681
17793
  import fs25 from "node:fs";
@@ -17807,7 +17919,7 @@ function _isCliEntry13() {
17807
17919
  return true;
17808
17920
  }
17809
17921
  try {
17810
- const here = fs26.realpathSync(fileURLToPath18(import.meta.url));
17922
+ const here = fs26.realpathSync(fileURLToPath19(import.meta.url));
17811
17923
  const argv = fs26.realpathSync(path26.resolve(process.argv[1]));
17812
17924
  return here === argv;
17813
17925
  } catch {
@@ -17822,20 +17934,20 @@ if (isCliEntry7) {
17822
17934
  // src/scripts/wrapper_freshness_hook.ts
17823
17935
  import fs28 from "node:fs";
17824
17936
  import path28 from "node:path";
17825
- import { fileURLToPath as fileURLToPath20, pathToFileURL as pathToFileURL15 } from "node:url";
17937
+ import { fileURLToPath as fileURLToPath21, pathToFileURL as pathToFileURL15 } from "node:url";
17826
17938
 
17827
17939
  // src/scripts/_lib/cli_wrapper.ts
17828
17940
  import fs27 from "node:fs";
17829
17941
  import path27 from "node:path";
17830
- import { fileURLToPath as fileURLToPath19 } from "node:url";
17831
- var _PACKAGE_ROOT = path27.resolve(
17832
- path27.dirname(fileURLToPath19(import.meta.url)),
17942
+ import { fileURLToPath as fileURLToPath20 } from "node:url";
17943
+ var _PACKAGE_ROOT2 = path27.resolve(
17944
+ path27.dirname(fileURLToPath20(import.meta.url)),
17833
17945
  "..",
17834
17946
  "..",
17835
17947
  ".."
17836
17948
  );
17837
17949
  var _TEMPLATE = path27.join(
17838
- _PACKAGE_ROOT,
17950
+ _PACKAGE_ROOT2,
17839
17951
  "src",
17840
17952
  "templates",
17841
17953
  "agent-config-wrapper.sh"
@@ -17955,7 +18067,7 @@ function _git_hooks_dir(root) {
17955
18067
  function refresh_precommit_hook(root) {
17956
18068
  try {
17957
18069
  const template = path28.join(
17958
- path28.resolve(path28.dirname(fileURLToPath20(import.meta.url)), "..", ".."),
18070
+ path28.resolve(path28.dirname(fileURLToPath21(import.meta.url)), "..", ".."),
17959
18071
  "dist",
17960
18072
  "agent-src",
17961
18073
  "templates",
@@ -18048,7 +18160,7 @@ function _isCliEntry14() {
18048
18160
  return true;
18049
18161
  }
18050
18162
  try {
18051
- const here = fs28.realpathSync(fileURLToPath20(import.meta.url));
18163
+ const here = fs28.realpathSync(fileURLToPath21(import.meta.url));
18052
18164
  const argv = fs28.realpathSync(path28.resolve(process.argv[1]));
18053
18165
  return here === argv;
18054
18166
  } catch {
@@ -18065,7 +18177,7 @@ var import_yaml5 = __toESM(require_dist(), 1);
18065
18177
  import fs29 from "node:fs";
18066
18178
  import os3 from "node:os";
18067
18179
  import path29 from "node:path";
18068
- import { fileURLToPath as fileURLToPath21, pathToFileURL as pathToFileURL16 } from "node:url";
18180
+ import { fileURLToPath as fileURLToPath22, pathToFileURL as pathToFileURL16 } from "node:url";
18069
18181
  var CHECK_WINDOW_MS = 24 * 60 * 60 * 1e3;
18070
18182
  var STATE_REL = ["agents", "runtime", "state", "surface-probe.json"];
18071
18183
  function _project_root3() {
@@ -18080,7 +18192,7 @@ function _package_root() {
18080
18192
  if (env) {
18081
18193
  return env;
18082
18194
  }
18083
- return path29.resolve(path29.dirname(fileURLToPath21(import.meta.url)), "..", "..");
18195
+ return path29.resolve(path29.dirname(fileURLToPath22(import.meta.url)), "..", "..");
18084
18196
  }
18085
18197
  function _readStdinIfNotTty3() {
18086
18198
  readHookStdin();
@@ -18207,7 +18319,7 @@ function _isCliEntry15() {
18207
18319
  return true;
18208
18320
  }
18209
18321
  try {
18210
- const here = fs29.realpathSync(fileURLToPath21(import.meta.url));
18322
+ const here = fs29.realpathSync(fileURLToPath22(import.meta.url));
18211
18323
  const argv = fs29.realpathSync(path29.resolve(process.argv[1]));
18212
18324
  return here === argv;
18213
18325
  } catch {
@@ -18221,7 +18333,7 @@ if (_isCliEntry15()) {
18221
18333
  // src/scripts/team_review_gate_hook.ts
18222
18334
  import fs31 from "node:fs";
18223
18335
  import path32 from "node:path";
18224
- import { fileURLToPath as fileURLToPath22, pathToFileURL as pathToFileURL17 } from "node:url";
18336
+ import { fileURLToPath as fileURLToPath23, pathToFileURL as pathToFileURL17 } from "node:url";
18225
18337
 
18226
18338
  // src/scripts/ai_team/review_gate.ts
18227
18339
  import * as crypto from "node:crypto";
@@ -18754,7 +18866,7 @@ function _isCliEntry16() {
18754
18866
  return true;
18755
18867
  }
18756
18868
  try {
18757
- const here = fs31.realpathSync(fileURLToPath22(import.meta.url));
18869
+ const here = fs31.realpathSync(fileURLToPath23(import.meta.url));
18758
18870
  const argv = fs31.realpathSync(path32.resolve(process.argv[1]));
18759
18871
  return here === argv;
18760
18872
  } catch {
@@ -18768,7 +18880,7 @@ if (_isCliEntry16()) {
18768
18880
  // src/scripts/pr_url_reminder_hook.ts
18769
18881
  import fs32 from "node:fs";
18770
18882
  import path33 from "node:path";
18771
- import { fileURLToPath as fileURLToPath23, pathToFileURL as pathToFileURL18 } from "node:url";
18883
+ import { fileURLToPath as fileURLToPath24, pathToFileURL as pathToFileURL18 } from "node:url";
18772
18884
  var EXIT_ALLOW3 = 0;
18773
18885
  var EXIT_WARN2 = 2;
18774
18886
  var COMMAND_TOOLS2 = /* @__PURE__ */ new Set([
@@ -18879,7 +18991,7 @@ function _isCliEntry17() {
18879
18991
  return true;
18880
18992
  }
18881
18993
  try {
18882
- const here = fs32.realpathSync(fileURLToPath23(import.meta.url));
18994
+ const here = fs32.realpathSync(fileURLToPath24(import.meta.url));
18883
18995
  const argv = fs32.realpathSync(path33.resolve(process.argv[1]));
18884
18996
  return here === argv;
18885
18997
  } catch {
@@ -18893,7 +19005,7 @@ if (_isCliEntry17()) {
18893
19005
  // src/scripts/session_canary_hook.ts
18894
19006
  import fs33 from "node:fs";
18895
19007
  import path34 from "node:path";
18896
- import { fileURLToPath as fileURLToPath24, pathToFileURL as pathToFileURL19 } from "node:url";
19008
+ import { fileURLToPath as fileURLToPath25, pathToFileURL as pathToFileURL19 } from "node:url";
18897
19009
  var EXIT_ALLOW4 = 0;
18898
19010
  var SETTINGS_FILE5 = ".agent-settings.yml";
18899
19011
  function _isObject5(v) {
@@ -19054,7 +19166,7 @@ function _isCliEntry18() {
19054
19166
  return true;
19055
19167
  }
19056
19168
  try {
19057
- const here = fs33.realpathSync(fileURLToPath24(import.meta.url));
19169
+ const here = fs33.realpathSync(fileURLToPath25(import.meta.url));
19058
19170
  const argv = fs33.realpathSync(path34.resolve(process.argv[1]));
19059
19171
  return here === argv;
19060
19172
  } catch {
@@ -19068,7 +19180,7 @@ if (_isCliEntry18()) {
19068
19180
  // src/scripts/council_availability_hook.ts
19069
19181
  import * as fs34 from "node:fs";
19070
19182
  import * as path35 from "node:path";
19071
- import { fileURLToPath as fileURLToPath25, pathToFileURL as pathToFileURL20 } from "node:url";
19183
+ import { fileURLToPath as fileURLToPath26, pathToFileURL as pathToFileURL20 } from "node:url";
19072
19184
  var EXIT_ALLOW5 = 0;
19073
19185
  function resolveAvailability(cwd, env) {
19074
19186
  let p;
@@ -19174,7 +19286,7 @@ if (_isCliEntry19()) {
19174
19286
  // src/scripts/self_repair_hook.ts
19175
19287
  import * as fs36 from "node:fs";
19176
19288
  import * as path37 from "node:path";
19177
- import { fileURLToPath as fileURLToPath26, pathToFileURL as pathToFileURL21 } from "node:url";
19289
+ import { fileURLToPath as fileURLToPath27, pathToFileURL as pathToFileURL21 } from "node:url";
19178
19290
 
19179
19291
  // src/scripts/_lib/self_repair.ts
19180
19292
  import { createHash as createHash4 } from "node:crypto";
@@ -19586,7 +19698,7 @@ function isCliEntry9() {
19586
19698
  return true;
19587
19699
  }
19588
19700
  try {
19589
- return fs36.realpathSync(fileURLToPath26(import.meta.url)) === fs36.realpathSync(path37.resolve(process.argv[1]));
19701
+ return fs36.realpathSync(fileURLToPath27(import.meta.url)) === fs36.realpathSync(path37.resolve(process.argv[1]));
19590
19702
  } catch {
19591
19703
  return false;
19592
19704
  }
@@ -19599,7 +19711,7 @@ if (isCliEntry9()) {
19599
19711
  import * as fs40 from "node:fs";
19600
19712
  import * as path41 from "node:path";
19601
19713
  import process9 from "node:process";
19602
- import { fileURLToPath as fileURLToPath27 } from "node:url";
19714
+ import { fileURLToPath as fileURLToPath28 } from "node:url";
19603
19715
 
19604
19716
  // src/scripts/_lib/git_common_dir.ts
19605
19717
  import fs37 from "node:fs";
@@ -20024,14 +20136,14 @@ function main25() {
20024
20136
  return 0;
20025
20137
  }
20026
20138
  var _bundled4 = true;
20027
- if (!_bundled4 && fileURLToPath27(import.meta.url) === path41.resolve(process9.argv[1] ?? "")) {
20139
+ if (!_bundled4 && fileURLToPath28(import.meta.url) === path41.resolve(process9.argv[1] ?? "")) {
20028
20140
  process9.exit(main25());
20029
20141
  }
20030
20142
 
20031
20143
  // src/scripts/language_mirror_hook.ts
20032
20144
  import fs41 from "node:fs";
20033
20145
  import path42 from "node:path";
20034
- import { fileURLToPath as fileURLToPath28, pathToFileURL as pathToFileURL22 } from "node:url";
20146
+ import { fileURLToPath as fileURLToPath29, pathToFileURL as pathToFileURL22 } from "node:url";
20035
20147
 
20036
20148
  // src/scripts/_lib/prompt_shape.ts
20037
20149
  function isSyntheticPrompt(prompt) {
@@ -20054,7 +20166,11 @@ function humanAuthoredLead(text) {
20054
20166
  var EXIT_ALLOW7 = 0;
20055
20167
  var EXIT_WARN3 = 2;
20056
20168
  var STATE_FILE5 = path42.join("agents", "state", "language-mirror.json");
20057
- var PIN_LOST_MARKER = path42.join("agents", "state", "language-mirror.pin-lost");
20169
+ var PIN_LOST_DIR = path42.join("agents", "state", "language-mirror.pin-lost");
20170
+ function pinLostMarker(session_id) {
20171
+ const safe = (session_id || "unknown-session").replace(/[^A-Za-z0-9._-]/g, "_");
20172
+ return path42.join(PIN_LOST_DIR, `${safe}.marker`);
20173
+ }
20058
20174
  function _isObject6(v) {
20059
20175
  return typeof v === "object" && v !== null && !Array.isArray(v);
20060
20176
  }
@@ -20193,35 +20309,49 @@ function _extractPrompt(payload) {
20193
20309
  }
20194
20310
  return "";
20195
20311
  }
20196
- function _setPinLost(consumer_root) {
20312
+ function _sessionId(envelope) {
20313
+ const v = envelope["session_id"];
20314
+ return typeof v === "string" && v.trim() !== "" ? v : "unknown-session";
20315
+ }
20316
+ function _migrateLegacyMarker(consumer_root) {
20317
+ const legacy = path42.join(consumer_root, PIN_LOST_DIR);
20318
+ try {
20319
+ if (fs41.statSync(legacy).isFile()) {
20320
+ fs41.rmSync(legacy, { force: true });
20321
+ }
20322
+ } catch {
20323
+ }
20324
+ }
20325
+ function _setPinLost(consumer_root, session_id) {
20326
+ if (is_replay_mode()) return;
20327
+ _migrateLegacyMarker(consumer_root);
20197
20328
  try {
20198
- const target = path42.join(consumer_root, PIN_LOST_MARKER);
20199
- fs41.mkdirSync(path42.dirname(target), { recursive: true });
20200
- fs41.writeFileSync(target, (/* @__PURE__ */ new Date()).toISOString());
20329
+ atomic_write_text(path42.join(consumer_root, pinLostMarker(session_id)), (/* @__PURE__ */ new Date()).toISOString());
20201
20330
  } catch {
20202
20331
  }
20203
20332
  }
20204
- function _pinLost(consumer_root) {
20333
+ function _pinLost(consumer_root, session_id) {
20205
20334
  try {
20206
- return fs41.existsSync(path42.join(consumer_root, PIN_LOST_MARKER));
20335
+ return fs41.existsSync(path42.join(consumer_root, pinLostMarker(session_id)));
20207
20336
  } catch {
20208
20337
  return false;
20209
20338
  }
20210
20339
  }
20211
- function _clearPinLost(consumer_root) {
20340
+ function _clearPinLost(consumer_root, session_id) {
20341
+ if (is_replay_mode()) return;
20212
20342
  try {
20213
- fs41.rmSync(path42.join(consumer_root, PIN_LOST_MARKER), { force: true });
20343
+ fs41.rmSync(path42.join(consumer_root, pinLostMarker(session_id)), { force: true });
20214
20344
  } catch {
20215
20345
  }
20216
20346
  }
20217
- function _reEmitAfterCompaction(consumer_root) {
20218
- if (!_pinLost(consumer_root)) {
20347
+ function _reEmitAfterCompaction(consumer_root, session_id) {
20348
+ if (!_pinLost(consumer_root, session_id)) {
20219
20349
  return EXIT_ALLOW7;
20220
20350
  }
20221
20351
  const previous = _loadState(path42.join(consumer_root, STATE_FILE5));
20222
20352
  const language = previous.language;
20223
20353
  const source = previous.source === "system-locale" ? "system-locale" : "prompt";
20224
- _clearPinLost(consumer_root);
20354
+ _clearPinLost(consumer_root, session_id);
20225
20355
  if (language !== "de" && language !== "en") {
20226
20356
  return EXIT_ALLOW7;
20227
20357
  }
@@ -20250,11 +20380,11 @@ function run8(stdin_text, options) {
20250
20380
  const payload = _isObject6(envelope["payload"]) ? envelope["payload"] : envelope;
20251
20381
  const event = typeof envelope["event"] === "string" ? envelope["event"] : "";
20252
20382
  if (event === "pre_compact") {
20253
- _setPinLost(options.consumer_root);
20383
+ _setPinLost(options.consumer_root, _sessionId(envelope));
20254
20384
  return EXIT_ALLOW7;
20255
20385
  }
20256
20386
  if (event === "post_tool_use") {
20257
- return _reEmitAfterCompaction(options.consumer_root);
20387
+ return _reEmitAfterCompaction(options.consumer_root, _sessionId(envelope));
20258
20388
  }
20259
20389
  const prompt = _extractPrompt(payload);
20260
20390
  if (!prompt) {
@@ -20321,7 +20451,7 @@ function _isCliEntry20() {
20321
20451
  return true;
20322
20452
  }
20323
20453
  try {
20324
- const here = fs41.realpathSync(fileURLToPath28(import.meta.url));
20454
+ const here = fs41.realpathSync(fileURLToPath29(import.meta.url));
20325
20455
  const argv = fs41.realpathSync(path42.resolve(process.argv[1]));
20326
20456
  return here === argv;
20327
20457
  } catch {
@@ -20335,7 +20465,7 @@ if (_isCliEntry20()) {
20335
20465
  // src/scripts/git_authorization_hook.ts
20336
20466
  import fs42 from "node:fs";
20337
20467
  import path43 from "node:path";
20338
- import { fileURLToPath as fileURLToPath29, pathToFileURL as pathToFileURL23 } from "node:url";
20468
+ import { fileURLToPath as fileURLToPath30, pathToFileURL as pathToFileURL23 } from "node:url";
20339
20469
  var EXIT_ALLOW8 = 0;
20340
20470
  var STATE_FILE6 = path43.join("agents", "state", "git-authorization.json");
20341
20471
  function _isObject7(v) {
@@ -20490,7 +20620,7 @@ function _isCliEntry21() {
20490
20620
  return true;
20491
20621
  }
20492
20622
  try {
20493
- const here = fs42.realpathSync(fileURLToPath29(import.meta.url));
20623
+ const here = fs42.realpathSync(fileURLToPath30(import.meta.url));
20494
20624
  const argv = fs42.realpathSync(path43.resolve(process.argv[1]));
20495
20625
  return here === argv;
20496
20626
  } catch {
@@ -20504,7 +20634,7 @@ if (_isCliEntry21()) {
20504
20634
  // src/scripts/hooks/block_unauthorized_git.ts
20505
20635
  import fs43 from "node:fs";
20506
20636
  import path44 from "node:path";
20507
- import { fileURLToPath as fileURLToPath30, pathToFileURL as pathToFileURL24 } from "node:url";
20637
+ import { fileURLToPath as fileURLToPath31, pathToFileURL as pathToFileURL24 } from "node:url";
20508
20638
  var EXIT_ALLOW9 = 0;
20509
20639
  var EXIT_BLOCK = 1;
20510
20640
  function _isObject8(v) {
@@ -20826,7 +20956,7 @@ function _isCliEntry22() {
20826
20956
  return true;
20827
20957
  }
20828
20958
  try {
20829
- const here = fs43.realpathSync(fileURLToPath30(import.meta.url));
20959
+ const here = fs43.realpathSync(fileURLToPath31(import.meta.url));
20830
20960
  const argv = fs43.realpathSync(path44.resolve(process.argv[1]));
20831
20961
  return here === argv;
20832
20962
  } catch {
@@ -20841,7 +20971,7 @@ if (_isCliEntry22()) {
20841
20971
  import crypto2 from "node:crypto";
20842
20972
  import fs44 from "node:fs";
20843
20973
  import path45 from "node:path";
20844
- import { fileURLToPath as fileURLToPath31, pathToFileURL as pathToFileURL25 } from "node:url";
20974
+ import { fileURLToPath as fileURLToPath32, pathToFileURL as pathToFileURL25 } from "node:url";
20845
20975
  var EXIT_ALLOW10 = 0;
20846
20976
  var EXIT_BLOCK2 = 1;
20847
20977
  var STATE_FILE7 = path45.join("agents", "state", "evidence-dispatch.json");
@@ -21035,7 +21165,7 @@ function _isCliEntry23() {
21035
21165
  return true;
21036
21166
  }
21037
21167
  try {
21038
- const here = fs44.realpathSync(fileURLToPath31(import.meta.url));
21168
+ const here = fs44.realpathSync(fileURLToPath32(import.meta.url));
21039
21169
  const argv = fs44.realpathSync(path45.resolve(process.argv[1]));
21040
21170
  return here === argv;
21041
21171
  } catch {
@@ -21048,9 +21178,9 @@ if (_isCliEntry23()) {
21048
21178
 
21049
21179
  // src/scripts/hooks/block_no_verify.ts
21050
21180
  import * as fs45 from "node:fs";
21051
- import { fileURLToPath as fileURLToPath32, pathToFileURL as pathToFileURL26 } from "node:url";
21181
+ import { fileURLToPath as fileURLToPath33, pathToFileURL as pathToFileURL26 } from "node:url";
21052
21182
  import * as path46 from "node:path";
21053
- var _HERE3 = fileURLToPath32(import.meta.url);
21183
+ var _HERE3 = fileURLToPath33(import.meta.url);
21054
21184
  var _SHELL_SEPARATORS = /* @__PURE__ */ new Set(["&&", "||", ";", "|"]);
21055
21185
  var _NO_VERIFY_FLAGS = /* @__PURE__ */ new Set(["--no-verify"]);
21056
21186
  var _NO_VERIFY_SHORT = /* @__PURE__ */ new Set(["-n"]);
@@ -21458,7 +21588,7 @@ function _isCliEntry24() {
21458
21588
  return true;
21459
21589
  }
21460
21590
  try {
21461
- const here = fs45.realpathSync(fileURLToPath32(import.meta.url));
21591
+ const here = fs45.realpathSync(fileURLToPath33(import.meta.url));
21462
21592
  const argv = fs45.realpathSync(path46.resolve(process.argv[1]));
21463
21593
  return here === argv;
21464
21594
  } catch {
@@ -21471,9 +21601,9 @@ if (_isCliEntry24() || false) {
21471
21601
 
21472
21602
  // src/scripts/hooks/block_kernel_rule_writes.ts
21473
21603
  import * as fs46 from "node:fs";
21474
- import { fileURLToPath as fileURLToPath33, pathToFileURL as pathToFileURL27 } from "node:url";
21604
+ import { fileURLToPath as fileURLToPath34, pathToFileURL as pathToFileURL27 } from "node:url";
21475
21605
  import * as path47 from "node:path";
21476
- var _HERE4 = fileURLToPath33(import.meta.url);
21606
+ var _HERE4 = fileURLToPath34(import.meta.url);
21477
21607
  function _isObject10(v) {
21478
21608
  return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
21479
21609
  }
@@ -21676,7 +21806,7 @@ function _isCliEntry25() {
21676
21806
  return true;
21677
21807
  }
21678
21808
  try {
21679
- const here = fs46.realpathSync(fileURLToPath33(import.meta.url));
21809
+ const here = fs46.realpathSync(fileURLToPath34(import.meta.url));
21680
21810
  const argv = fs46.realpathSync(path47.resolve(process.argv[1]));
21681
21811
  return here === argv;
21682
21812
  } catch {
@@ -21690,8 +21820,8 @@ if (_isCliEntry25() || false) {
21690
21820
  // src/scripts/hooks/block_config_weakening.ts
21691
21821
  import * as fs47 from "node:fs";
21692
21822
  import * as path48 from "node:path";
21693
- import { fileURLToPath as fileURLToPath34, pathToFileURL as pathToFileURL28 } from "node:url";
21694
- var _HERE5 = fileURLToPath34(import.meta.url);
21823
+ import { fileURLToPath as fileURLToPath35, pathToFileURL as pathToFileURL28 } from "node:url";
21824
+ var _HERE5 = fileURLToPath35(import.meta.url);
21695
21825
  var EXIT_ALLOW11 = 0;
21696
21826
  var EXIT_BLOCK3 = 1;
21697
21827
  var EXIT_WARN4 = 2;
@@ -21878,7 +22008,7 @@ function _isCliEntry26() {
21878
22008
  return true;
21879
22009
  }
21880
22010
  try {
21881
- return fs47.realpathSync(fileURLToPath34(import.meta.url)) === fs47.realpathSync(path48.resolve(process.argv[1]));
22011
+ return fs47.realpathSync(fileURLToPath35(import.meta.url)) === fs47.realpathSync(path48.resolve(process.argv[1]));
21882
22012
  } catch {
21883
22013
  return false;
21884
22014
  }
@@ -21890,7 +22020,7 @@ if (_isCliEntry26() || process.argv[1] === _HERE5) {
21890
22020
  // src/scripts/hooks/rtk_wrap_hook.ts
21891
22021
  import fs48 from "node:fs";
21892
22022
  import path49 from "node:path";
21893
- import { fileURLToPath as fileURLToPath35, pathToFileURL as pathToFileURL29 } from "node:url";
22023
+ import { fileURLToPath as fileURLToPath36, pathToFileURL as pathToFileURL29 } from "node:url";
21894
22024
 
21895
22025
  // src/install/rtkDetection.ts
21896
22026
  import { spawnSync as spawnSync4 } from "node:child_process";
@@ -22228,7 +22358,7 @@ function _isCliEntry27() {
22228
22358
  return true;
22229
22359
  }
22230
22360
  try {
22231
- const here = fs48.realpathSync(fileURLToPath35(import.meta.url));
22361
+ const here = fs48.realpathSync(fileURLToPath36(import.meta.url));
22232
22362
  const argv = fs48.realpathSync(path49.resolve(process.argv[1]));
22233
22363
  return here === argv;
22234
22364
  } catch {
@@ -22242,7 +22372,7 @@ if (_isCliEntry27()) {
22242
22372
  // src/scripts/hooks/design_slop_hook.ts
22243
22373
  import fs50 from "node:fs";
22244
22374
  import path51 from "node:path";
22245
- import { fileURLToPath as fileURLToPath36, pathToFileURL as pathToFileURL30 } from "node:url";
22375
+ import { fileURLToPath as fileURLToPath37, pathToFileURL as pathToFileURL30 } from "node:url";
22246
22376
 
22247
22377
  // src/scripts/lint_design_slop.ts
22248
22378
  import fs49 from "node:fs";
@@ -22962,7 +23092,7 @@ function _isCliEntry28() {
22962
23092
  return true;
22963
23093
  }
22964
23094
  try {
22965
- const here = fs50.realpathSync(fileURLToPath36(import.meta.url));
23095
+ const here = fs50.realpathSync(fileURLToPath37(import.meta.url));
22966
23096
  const argv = fs50.realpathSync(path51.resolve(process.argv[1]));
22967
23097
  return here === argv;
22968
23098
  } catch {
@@ -22975,7 +23105,7 @@ if (isCliEntry10) process.exit(main35());
22975
23105
  // src/scripts/hooks/code_graph_nudge_hook.ts
22976
23106
  import fs52 from "node:fs";
22977
23107
  import path53 from "node:path";
22978
- import { fileURLToPath as fileURLToPath37, pathToFileURL as pathToFileURL31 } from "node:url";
23108
+ import { fileURLToPath as fileURLToPath38, pathToFileURL as pathToFileURL31 } from "node:url";
22979
23109
 
22980
23110
  // src/scripts/code_graph/detect.ts
22981
23111
  import { execFileSync } from "node:child_process";
@@ -23235,7 +23365,7 @@ function isCliEntry11() {
23235
23365
  const argvUrl = pathToFileURL31(path53.resolve(process.argv[1])).href;
23236
23366
  if (import.meta.url === argvUrl) return true;
23237
23367
  try {
23238
- return fs52.realpathSync(fileURLToPath37(import.meta.url)) === fs52.realpathSync(path53.resolve(process.argv[1]));
23368
+ return fs52.realpathSync(fileURLToPath38(import.meta.url)) === fs52.realpathSync(path53.resolve(process.argv[1]));
23239
23369
  } catch {
23240
23370
  return false;
23241
23371
  }
@@ -23246,7 +23376,7 @@ if (isCliEntry11()) process.exit(main36());
23246
23376
  import * as crypto4 from "node:crypto";
23247
23377
  import * as fs54 from "node:fs";
23248
23378
  import * as path55 from "node:path";
23249
- import { fileURLToPath as fileURLToPath38, pathToFileURL as pathToFileURL33 } from "node:url";
23379
+ import { fileURLToPath as fileURLToPath39, pathToFileURL as pathToFileURL33 } from "node:url";
23250
23380
 
23251
23381
  // src/scripts/_lib/orchestration_record.ts
23252
23382
  var DISPATCH_OUTCOMES = ["DONE", "DONE_WITH_CONCERNS", "NEEDS_CONTEXT", "BLOCKED", "killed"];
@@ -23694,7 +23824,7 @@ function _isCliEntry29() {
23694
23824
  const argvUrl = pathToFileURL33(path55.resolve(process.argv[1])).href;
23695
23825
  if (import.meta.url === argvUrl) return true;
23696
23826
  try {
23697
- return fs54.realpathSync(fileURLToPath38(import.meta.url)) === fs54.realpathSync(path55.resolve(process.argv[1]));
23827
+ return fs54.realpathSync(fileURLToPath39(import.meta.url)) === fs54.realpathSync(path55.resolve(process.argv[1]));
23698
23828
  } catch {
23699
23829
  return false;
23700
23830
  }
@@ -23704,7 +23834,7 @@ if (_isCliEntry29()) process.exit(main38());
23704
23834
  // src/scripts/hooks/delegation_nudge_hook.ts
23705
23835
  import fs55 from "node:fs";
23706
23836
  import path56 from "node:path";
23707
- import { fileURLToPath as fileURLToPath39, pathToFileURL as pathToFileURL34 } from "node:url";
23837
+ import { fileURLToPath as fileURLToPath40, pathToFileURL as pathToFileURL34 } from "node:url";
23708
23838
 
23709
23839
  // src/scripts/_lib/host_capability.ts
23710
23840
  import process10 from "node:process";
@@ -24248,7 +24378,7 @@ function _isCliEntry30() {
24248
24378
  return true;
24249
24379
  }
24250
24380
  try {
24251
- const here = fs55.realpathSync(fileURLToPath39(import.meta.url));
24381
+ const here = fs55.realpathSync(fileURLToPath40(import.meta.url));
24252
24382
  const argv = fs55.realpathSync(path56.resolve(process.argv[1]));
24253
24383
  return here === argv;
24254
24384
  } catch {
@@ -24265,7 +24395,7 @@ import * as crypto5 from "node:crypto";
24265
24395
  import * as fs56 from "node:fs";
24266
24396
  import * as os6 from "node:os";
24267
24397
  import * as path57 from "node:path";
24268
- import { fileURLToPath as fileURLToPath40, pathToFileURL as pathToFileURL35 } from "node:url";
24398
+ import { fileURLToPath as fileURLToPath41, pathToFileURL as pathToFileURL35 } from "node:url";
24269
24399
 
24270
24400
  // src/scripts/_lib/review_skipped_record.ts
24271
24401
  function isNonNegInt(n) {
@@ -24560,7 +24690,7 @@ function _isCliEntry31() {
24560
24690
  return true;
24561
24691
  }
24562
24692
  try {
24563
- const here = fs56.realpathSync(fileURLToPath40(import.meta.url));
24693
+ const here = fs56.realpathSync(fileURLToPath41(import.meta.url));
24564
24694
  const argv = fs56.realpathSync(path57.resolve(process.argv[1]));
24565
24695
  return here === argv;
24566
24696
  } catch {
@@ -24575,13 +24705,32 @@ if (_isCliEntry31()) {
24575
24705
  import * as crypto6 from "node:crypto";
24576
24706
  import * as fs57 from "node:fs";
24577
24707
  import * as path58 from "node:path";
24578
- import { fileURLToPath as fileURLToPath41, pathToFileURL as pathToFileURL36 } from "node:url";
24708
+ import { fileURLToPath as fileURLToPath42, pathToFileURL as pathToFileURL36 } from "node:url";
24579
24709
  var EXIT_BLOCK4 = 1;
24580
24710
  var EXIT_ALLOW17 = 0;
24711
+ var TRANSCRIPT_READ_MAX_BYTES = 8 * 1024 * 1024;
24712
+ function stripFencedBlocks(text) {
24713
+ const out = [];
24714
+ let open = null;
24715
+ for (const line of text.split("\n")) {
24716
+ const m = /^[ \t]{0,3}([`~]{3,})(.*)$/.exec(line);
24717
+ if (open === null) {
24718
+ if (m) {
24719
+ open = { ch: m[1][0], len: m[1].length };
24720
+ out.push(" ");
24721
+ continue;
24722
+ }
24723
+ out.push(line);
24724
+ continue;
24725
+ }
24726
+ if (m && m[1][0] === open.ch && m[1].length >= open.len && (m[2] ?? "").trim() === "") {
24727
+ open = null;
24728
+ }
24729
+ }
24730
+ return out.join("\n");
24731
+ }
24581
24732
  function visibleProse(reply) {
24582
- let text = reply;
24583
- text = text.replace(/^[ \t]*(`{3,}|~{3,})[\s\S]*?^[ \t]*\1[ \t]*$/gm, " ");
24584
- text = text.replace(/^[ \t]*(`{3,}|~{3,})[\s\S]*$/m, " ");
24733
+ let text = stripFencedBlocks(reply);
24585
24734
  text = text.replace(/`[^`\n]*`/g, " ");
24586
24735
  text = text.replace(/^[ \t]*>.*$/gm, " ");
24587
24736
  text = text.replace(/^[ \t]*\|.*\|[ \t]*$/gm, " ");
@@ -24605,10 +24754,28 @@ var PROMISSORY = [
24605
24754
  /\bals n(ä|ae)chstes (werde|mache|baue|pr(ü|ue)fe) ich\b/i,
24606
24755
  // German puts the infinitive at the END of the clause ("ich werde jetzt
24607
24756
  // die Tests schreiben"), so the verb cannot be matched adjacent to
24608
- // "werde" — it has to be looked for across the rest of the sentence. The
24609
- // negative lookahead keeps a stated REFUSAL to act ("ich werde das nicht
24610
- // anfassen") out: declining to do something is not a promise to do it.
24611
- /\bich werde\b(?![^.!?\n]*\bnicht\b)[^.!?\n]*\b\w{3,}en\b/i,
24757
+ // "werde" — it has to be looked for across the rest of the sentence.
24758
+ //
24759
+ // The lookahead excludes a stated REFUSAL to act: declining to do
24760
+ // something is not a promise to do it. R2 finding 4 reproduced four live
24761
+ // false refusals against the old `\bnicht\b`-only version — "Ich werde
24762
+ // nichts anfassen" (no word boundary after `nicht`), "keine Tests
24763
+ // schreiben", "niemals raten", and the passive non-promise "Ich werde
24764
+ // gefragt, ob …". Each was a false refusal on a BLOCKING guard, which is
24765
+ // the precision failure the council warning is about.
24766
+ // `\p{L}` with the `u` flag, NOT `\w`: R2 round 2, finding 15 verified that
24767
+ // `\b\w{3,}en\b` cannot reach an infinitive whose post-umlaut fragment is
24768
+ // short, because `ü`/`ö`/`ä` are not `\w` and create a word boundary — so
24769
+ // "prüfen" and "lösen" were silent while the comment above claimed the
24770
+ // verb-final construction was handled.
24771
+ //
24772
+ // Honest about what this proxy matches: any word of 3+ letters ending in
24773
+ // "en" within the clause, which is the infinitive in practice but also hits
24774
+ // a plural noun ("die Zeilen zählen" matches on "Zeilen"). That is
24775
+ // acceptable here — the clause already requires "ich werde" and excludes
24776
+ // negations and passives, so a forward commitment is what remains — but it
24777
+ // is a proxy for the infinitive, not a parse of one.
24778
+ new RegExp("\\bich werde\\b(?![^.!?\\n]*\\b(?:nicht|nichts|kein(?:e|en|em|er|es)?|niemals|nie)\\b)(?![^.!?\\n]*\\b(?:gefragt|gebeten|informiert|benachrichtigt)\\b)[^.!?\\n]*(?<!\\p{L})\\p{L}{3,}en(?!\\p{L})", "iu"),
24612
24779
  /\bI(?:'| wi)ll (report|let you know|update you|follow up)\b/i,
24613
24780
  /\bI(?:'| wi)ll (now |then )?\w+ (it|that|this|next)\b/i,
24614
24781
  /\bnext,? I(?:'| wi)ll\b/i,
@@ -24628,7 +24795,7 @@ var HANDBACK = [
24628
24795
  function detectPromissory(reply) {
24629
24796
  const tail = finalParagraph(reply);
24630
24797
  if (!tail) return null;
24631
- if (tail.includes("?")) return null;
24798
+ if (/\?["'’)\]]*\s*$/.test(tail)) return null;
24632
24799
  if (HANDBACK.some((re) => re.test(tail))) return null;
24633
24800
  for (const re of PROMISSORY) {
24634
24801
  const m = tail.match(re);
@@ -24663,47 +24830,54 @@ function detectLanguage(reply, pinned) {
24663
24830
  return {
24664
24831
  detector: "language",
24665
24832
  evidence: prose.trim().slice(0, 120),
24666
- reason: `the pinned reply language is "${pinned}" but the user-visible prose classifies as "${verdict.language}" (${verdict.de_markers} de / ${verdict.en_markers} en markers, code, quotes, paths and identifiers already excluded)`
24833
+ reason: `the pinned reply language is "${pinned}" but the reply classifies as "${verdict.language}" (${verdict.de_markers} de / ${verdict.en_markers} en markers; code, quotes, tables, URLs and paths excluded, then scored lead-first by the same classifier that sets the pin)`
24667
24834
  };
24668
24835
  }
24669
24836
  function stateDir(workspaceRoot2) {
24670
24837
  return path58.join(workspaceRoot2, "agents", "runtime", "state", "turn-end-gate");
24671
24838
  }
24672
- function stateFile2(workspaceRoot2, turnKey) {
24673
- return path58.join(stateDir(workspaceRoot2), `${turnKey}.json`);
24839
+ function sessionStateFile2(workspaceRoot2, sessionKey) {
24840
+ return path58.join(stateDir(workspaceRoot2), `${sessionKey}.json`);
24674
24841
  }
24675
- function deriveTurnKey(sessionId2, lastUserText) {
24676
- return crypto6.createHash("sha256").update(`${sessionId2}
24677
- ${lastUserText}`).digest("hex").slice(0, 32);
24842
+ function deriveSessionKey2(sessionId2) {
24843
+ return crypto6.createHash("sha256").update(sessionId2).digest("hex").slice(0, 32);
24678
24844
  }
24679
- function alreadyRefusedThisTurn(workspaceRoot2, turnKey) {
24845
+ function alreadyRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal) {
24680
24846
  try {
24681
- return fs57.existsSync(stateFile2(workspaceRoot2, turnKey));
24847
+ const raw = fs57.readFileSync(sessionStateFile2(workspaceRoot2, sessionKey), "utf-8");
24848
+ const decoded = JSON.parse(raw);
24849
+ if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
24850
+ return decoded["refused_turn"] === turnOrdinal;
24851
+ }
24682
24852
  } catch {
24683
- return false;
24684
24853
  }
24854
+ return false;
24685
24855
  }
24686
- function markRefusedThisTurn(workspaceRoot2, turnKey, detector) {
24856
+ function markRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal, detector) {
24687
24857
  if (is_replay_mode()) return;
24688
24858
  try {
24689
- atomic_write_json(stateFile2(workspaceRoot2, turnKey), {
24859
+ atomic_write_json(sessionStateFile2(workspaceRoot2, sessionKey), {
24690
24860
  refused_at: (/* @__PURE__ */ new Date()).toISOString(),
24861
+ refused_turn: turnOrdinal,
24691
24862
  detector
24692
24863
  });
24693
24864
  } catch {
24694
24865
  }
24695
24866
  }
24696
24867
  function readTranscriptTail(transcriptPath, opts = {}) {
24697
- const empty = { lastAssistant: "", lastUser: "" };
24868
+ const empty = { lastAssistant: "", turnOrdinal: 0 };
24698
24869
  if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
24699
24870
  let lines;
24700
24871
  try {
24872
+ if (opts.maxBytes !== void 0 && fs57.statSync(transcriptPath).size > opts.maxBytes) {
24873
+ return empty;
24874
+ }
24701
24875
  lines = fs57.readFileSync(transcriptPath, "utf-8").split("\n");
24702
24876
  } catch {
24703
24877
  return empty;
24704
24878
  }
24705
24879
  let lastAssistant = "";
24706
- let lastUser = "";
24880
+ let turnOrdinal = 0;
24707
24881
  for (const rawLine of lines) {
24708
24882
  const line = rawLine.trim();
24709
24883
  if (!line) continue;
@@ -24715,16 +24889,20 @@ function readTranscriptTail(transcriptPath, opts = {}) {
24715
24889
  }
24716
24890
  if (typeof obj !== "object" || obj === null || Array.isArray(obj)) continue;
24717
24891
  const entry = obj;
24892
+ if (entry["isSidechain"] === true) continue;
24718
24893
  const role = entry["type"];
24719
24894
  if (role !== "assistant" && role !== "user") continue;
24720
24895
  const msg = entry["message"];
24721
24896
  if (typeof msg !== "object" || msg === null || Array.isArray(msg)) continue;
24722
24897
  const text = _messageText(msg["content"]);
24723
24898
  if (text === null) continue;
24724
- if (role === "assistant") lastAssistant = text;
24725
- else lastUser = text;
24899
+ if (role === "assistant") {
24900
+ lastAssistant = text;
24901
+ } else if (!isSyntheticPrompt(text)) {
24902
+ turnOrdinal += 1;
24903
+ }
24726
24904
  }
24727
- return { lastAssistant: lastAssistant.trim(), lastUser: lastUser.trim() };
24905
+ return { lastAssistant: lastAssistant.trim(), turnOrdinal };
24728
24906
  }
24729
24907
  function _messageText(content) {
24730
24908
  if (typeof content === "string") return content;
@@ -24739,32 +24917,30 @@ function _messageText(content) {
24739
24917
  }
24740
24918
  return parts.length > 0 ? parts.join("\n") : null;
24741
24919
  }
24920
+ function _isOn(v) {
24921
+ if (typeof v === "boolean") return v;
24922
+ if (typeof v !== "string") return null;
24923
+ const s = v.trim().toLowerCase();
24924
+ if (s === "true" || s === "yes" || s === "on") return true;
24925
+ if (s === "false" || s === "no" || s === "off") return false;
24926
+ return null;
24927
+ }
24742
24928
  function readGateSettings(workspaceRoot2) {
24743
24929
  const off = { enabled: false, promissory: true, language: true };
24744
- let raw;
24930
+ let settings;
24745
24931
  try {
24746
- raw = fs57.readFileSync(path58.join(workspaceRoot2, ".agent-settings.yml"), "utf-8");
24932
+ settings = load_agent_settings({ cwd: workspaceRoot2 });
24747
24933
  } catch {
24748
24934
  return off;
24749
24935
  }
24750
- const lines = raw.split("\n");
24751
- const headerIdx = lines.findIndex((l) => /^\s*turn_end_gate:\s*$/.test(l));
24752
- if (headerIdx === -1) return off;
24753
- const headerIndent = (lines[headerIdx].match(/^\s*/) ?? [""])[0].length;
24754
- const body = [];
24755
- for (const line of lines.slice(headerIdx + 1)) {
24756
- if (line.trim() === "" || line.trimStart().startsWith("#")) continue;
24757
- const indent = (line.match(/^\s*/) ?? [""])[0].length;
24758
- if (indent <= headerIndent) break;
24759
- body.push(line);
24760
- }
24936
+ const hooks = settings["hooks"];
24937
+ if (typeof hooks !== "object" || hooks === null || Array.isArray(hooks)) return off;
24938
+ const block = hooks["turn_end_gate"];
24939
+ if (typeof block !== "object" || block === null || Array.isArray(block)) return off;
24940
+ const gate = block;
24761
24941
  const flag = (name, dflt) => {
24762
- const re = new RegExp(`^\\s+${name}:\\s*(true|false)\\s*$`);
24763
- for (const line of body) {
24764
- const m = line.match(re);
24765
- if (m) return m[1] === "true";
24766
- }
24767
- return dflt;
24942
+ const v = _isOn(gate[name]);
24943
+ return v === null ? dflt : v;
24768
24944
  };
24769
24945
  return {
24770
24946
  enabled: flag("enabled", false),
@@ -24790,17 +24966,14 @@ function main41() {
24790
24966
  const transcriptPath = str4(
24791
24967
  payload["transcript_path"] ?? payload["transcriptPath"]
24792
24968
  );
24793
- const homeOverride = process.env["AGENT_CONFIG_TRANSCRIPT_HOME"];
24794
- const { lastAssistant, lastUser } = readTranscriptTail(
24795
- transcriptPath,
24796
- homeOverride ? { homeDir: homeOverride } : {}
24797
- );
24969
+ const { lastAssistant, turnOrdinal } = readTranscriptTail(transcriptPath, {
24970
+ maxBytes: TRANSCRIPT_READ_MAX_BYTES
24971
+ });
24798
24972
  if (!lastAssistant) return EXIT_ALLOW17;
24799
- const turnKey = deriveTurnKey(
24800
- str4(envelope["session_id"]) || "unknown-session",
24801
- lastUser
24973
+ const sessionKey = deriveSessionKey2(
24974
+ str4(envelope["session_id"]) || "unknown-session"
24802
24975
  );
24803
- if (alreadyRefusedThisTurn(workspaceRoot2, turnKey)) return EXIT_ALLOW17;
24976
+ if (alreadyRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal)) return EXIT_ALLOW17;
24804
24977
  const findings = [];
24805
24978
  if (settings.promissory) {
24806
24979
  const f = detectPromissory(lastAssistant);
@@ -24811,7 +24984,7 @@ function main41() {
24811
24984
  if (f) findings.push(f);
24812
24985
  }
24813
24986
  if (findings.length === 0) return EXIT_ALLOW17;
24814
- markRefusedThisTurn(workspaceRoot2, turnKey, findings[0].detector);
24987
+ markRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal, findings[0].detector);
24815
24988
  const lines = findings.map(
24816
24989
  (f) => ` \xB7 ${f.detector}: ${f.reason}
24817
24990
  evidence: ${JSON.stringify(f.evidence)}`
@@ -24838,7 +25011,7 @@ function _isCliEntry32() {
24838
25011
  return true;
24839
25012
  }
24840
25013
  try {
24841
- const here = fs57.realpathSync(fileURLToPath41(import.meta.url));
25014
+ const here = fs57.realpathSync(fileURLToPath42(import.meta.url));
24842
25015
  const argv = fs57.realpathSync(path58.resolve(process.argv[1]));
24843
25016
  return here === argv;
24844
25017
  } catch {
@@ -24854,7 +25027,7 @@ import { spawnSync as spawnSync6 } from "node:child_process";
24854
25027
  import * as crypto7 from "node:crypto";
24855
25028
  import * as fs58 from "node:fs";
24856
25029
  import * as path59 from "node:path";
24857
- import { fileURLToPath as fileURLToPath42, pathToFileURL as pathToFileURL37 } from "node:url";
25030
+ import { fileURLToPath as fileURLToPath43, pathToFileURL as pathToFileURL37 } from "node:url";
24858
25031
  var EXIT_ALLOW18 = 0;
24859
25032
  var EXIT_WARN10 = 2;
24860
25033
  var MIN_FILE_LINES = 50;
@@ -24918,24 +25091,24 @@ function buildAdvisoryLine2(fileLines, diffLines) {
24918
25091
  const pct = Math.round(diffLines / fileLines * 100);
24919
25092
  return `this Write replaced ${fileLines} lines for an effective diff of ~${pct}% (${diffLines} changed lines) \u2014 a targeted Edit pays for the diff, not the file.`;
24920
25093
  }
24921
- function deriveSessionKey2(envelope, payload) {
25094
+ function deriveSessionKey3(envelope, payload) {
24922
25095
  const raw = str5(envelope["session_id"]) || str5(payload["session_id"] ?? payload["sessionId"]);
24923
25096
  const material = raw || "unknown-session";
24924
25097
  return crypto7.createHash("sha256").update(material).digest("hex");
24925
25098
  }
24926
- function sessionStateFile2(workspaceRoot2, sessionKey) {
25099
+ function sessionStateFile3(workspaceRoot2, sessionKey) {
24927
25100
  return path59.join(workspaceRoot2, "agents", "runtime", "state", "edit-shape", `${sessionKey}.json`);
24928
25101
  }
24929
25102
  function hasFiredThisSession2(workspaceRoot2, sessionKey) {
24930
25103
  try {
24931
- return fs58.existsSync(sessionStateFile2(workspaceRoot2, sessionKey));
25104
+ return fs58.existsSync(sessionStateFile3(workspaceRoot2, sessionKey));
24932
25105
  } catch {
24933
25106
  return false;
24934
25107
  }
24935
25108
  }
24936
25109
  function markFiredThisSession2(workspaceRoot2, sessionKey) {
24937
25110
  try {
24938
- atomic_write_json(sessionStateFile2(workspaceRoot2, sessionKey), {
25111
+ atomic_write_json(sessionStateFile3(workspaceRoot2, sessionKey), {
24939
25112
  fired_at: (/* @__PURE__ */ new Date()).toISOString()
24940
25113
  });
24941
25114
  } catch {
@@ -24967,7 +25140,7 @@ function main42() {
24967
25140
  const diffLines = effectiveDiffLines(workspaceRoot2, relPath.startsWith("..") ? absPath : relPath);
24968
25141
  if (diffLines === 0) return EXIT_ALLOW18;
24969
25142
  if (diffLines / fileLines > MAX_DIFF_RATIO) return EXIT_ALLOW18;
24970
- const sessionKey = deriveSessionKey2(envelope, payload);
25143
+ const sessionKey = deriveSessionKey3(envelope, payload);
24971
25144
  if (hasFiredThisSession2(workspaceRoot2, sessionKey)) return EXIT_ALLOW18;
24972
25145
  markFiredThisSession2(workspaceRoot2, sessionKey);
24973
25146
  process.stdout.write(
@@ -24995,7 +25168,7 @@ function _isCliEntry33() {
24995
25168
  return true;
24996
25169
  }
24997
25170
  try {
24998
- const here = fs58.realpathSync(fileURLToPath42(import.meta.url));
25171
+ const here = fs58.realpathSync(fileURLToPath43(import.meta.url));
24999
25172
  const argv = fs58.realpathSync(path59.resolve(process.argv[1]));
25000
25173
  return here === argv;
25001
25174
  } catch {
@@ -25010,7 +25183,7 @@ if (_isCliEntry33()) {
25010
25183
  import * as crypto8 from "node:crypto";
25011
25184
  import * as fs59 from "node:fs";
25012
25185
  import * as path60 from "node:path";
25013
- import { fileURLToPath as fileURLToPath43, pathToFileURL as pathToFileURL38 } from "node:url";
25186
+ import { fileURLToPath as fileURLToPath44, pathToFileURL as pathToFileURL38 } from "node:url";
25014
25187
  var EXIT_ALLOW19 = 0;
25015
25188
  var EXIT_WARN11 = 2;
25016
25189
  var EXEMPT_PATH_PATTERNS2 = [
@@ -25040,7 +25213,7 @@ function isExemptPath2(filePath) {
25040
25213
  function emptyLedger() {
25041
25214
  return { reads: {}, writes: {}, fired: {} };
25042
25215
  }
25043
- function deriveSessionKey3(envelope, payload) {
25216
+ function deriveSessionKey4(envelope, payload) {
25044
25217
  const raw = str6(envelope["session_id"]) || str6(payload["session_id"] ?? payload["sessionId"]);
25045
25218
  const material = raw || "unknown-session";
25046
25219
  return crypto8.createHash("sha256").update(material).digest("hex");
@@ -25107,7 +25280,7 @@ function main43() {
25107
25280
  const absPath = path60.isAbsolute(filePath) ? filePath : path60.resolve(workspaceRoot2, filePath);
25108
25281
  const relPath = path60.relative(workspaceRoot2, absPath);
25109
25282
  if (isExemptPath2(relPath) || isExemptPath2(absPath)) return EXIT_ALLOW19;
25110
- const sessionKey = deriveSessionKey3(envelope, payload);
25283
+ const sessionKey = deriveSessionKey4(envelope, payload);
25111
25284
  const ledger = readLedger(workspaceRoot2, sessionKey);
25112
25285
  const key = relPath.startsWith("..") ? absPath : relPath;
25113
25286
  if (isWrite) {
@@ -25166,7 +25339,7 @@ function _isCliEntry34() {
25166
25339
  return true;
25167
25340
  }
25168
25341
  try {
25169
- const here = fs59.realpathSync(fileURLToPath43(import.meta.url));
25342
+ const here = fs59.realpathSync(fileURLToPath44(import.meta.url));
25170
25343
  const argv = fs59.realpathSync(path60.resolve(process.argv[1]));
25171
25344
  return here === argv;
25172
25345
  } catch {
@@ -25182,7 +25355,7 @@ import * as crypto9 from "node:crypto";
25182
25355
  import * as fs61 from "node:fs";
25183
25356
  import * as path62 from "node:path";
25184
25357
  import process11 from "node:process";
25185
- import { fileURLToPath as fileURLToPath44, pathToFileURL as pathToFileURL39 } from "node:url";
25358
+ import { fileURLToPath as fileURLToPath45, pathToFileURL as pathToFileURL39 } from "node:url";
25186
25359
 
25187
25360
  // src/config/recycle-threshold-budget.json
25188
25361
  var recycle_threshold_budget_default = {
@@ -25346,10 +25519,10 @@ function str7(value) {
25346
25519
  function stateDir2(workspaceRoot2) {
25347
25520
  return path62.join(workspaceRoot2, "agents", "runtime", "state", "session-eol");
25348
25521
  }
25349
- function stateFile3(workspaceRoot2, sessionKey) {
25522
+ function stateFile2(workspaceRoot2, sessionKey) {
25350
25523
  return path62.join(stateDir2(workspaceRoot2), `${sessionKey}.json`);
25351
25524
  }
25352
- function deriveSessionKey4(envelope, payload) {
25525
+ function deriveSessionKey5(envelope, payload) {
25353
25526
  const raw = str7(envelope["session_id"]) || str7(payload["transcript_path"] ?? payload["transcriptPath"]);
25354
25527
  return crypto9.createHash("sha256").update(raw || "unknown-session").digest("hex");
25355
25528
  }
@@ -25413,8 +25586,8 @@ function main44() {
25413
25586
  if (!transcriptPath || !isSafeTranscriptPath(transcriptPath)) {
25414
25587
  return 0;
25415
25588
  }
25416
- const sessionKey = deriveSessionKey4(envelope, payload);
25417
- const file = stateFile3(workspaceRoot2, sessionKey);
25589
+ const sessionKey = deriveSessionKey5(envelope, payload);
25590
+ const file = stateFile2(workspaceRoot2, sessionKey);
25418
25591
  const state = readState2(file);
25419
25592
  let counters = state.counters;
25420
25593
  const read = readNewCompleteLines(transcriptPath, counters.scanned_bytes);
@@ -25468,7 +25641,7 @@ function _isCliEntry35() {
25468
25641
  return true;
25469
25642
  }
25470
25643
  try {
25471
- const here = fs61.realpathSync(fileURLToPath44(import.meta.url));
25644
+ const here = fs61.realpathSync(fileURLToPath45(import.meta.url));
25472
25645
  const argv = fs61.realpathSync(path62.resolve(process11.argv[1]));
25473
25646
  return here === argv;
25474
25647
  } catch {
@@ -25572,7 +25745,7 @@ function emitFor(platform, event, severity, reasons, legacyExit) {
25572
25745
  // src/scripts/hooks/dispatch_hook.ts
25573
25746
  var _IN_BUNDLE = true;
25574
25747
  var REPO_ROOT = path63.resolve(
25575
- path63.dirname(fileURLToPath45(import.meta.url)),
25748
+ path63.dirname(fileURLToPath46(import.meta.url)),
25576
25749
  ..._IN_BUNDLE ? ["..", ".."] : ["..", "..", ".."]
25577
25750
  );
25578
25751
  var MANIFEST_PATH = path63.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
@@ -25856,7 +26029,7 @@ function _resolve_tsx_invocation2(scriptPath, scriptArgs) {
25856
26029
  dir = parent;
25857
26030
  }
25858
26031
  };
25859
- const tsx = walkUp(path63.dirname(scriptPath)) ?? walkUp(path63.dirname(fileURLToPath45(import.meta.url)));
26032
+ const tsx = walkUp(path63.dirname(scriptPath)) ?? walkUp(path63.dirname(fileURLToPath46(import.meta.url)));
25860
26033
  if (tsx !== null) {
25861
26034
  return { command: tsx, args: [scriptPath, ...scriptArgs] };
25862
26035
  }
@@ -26351,7 +26524,7 @@ function _isCliEntry36() {
26351
26524
  return true;
26352
26525
  }
26353
26526
  try {
26354
- const here = fs62.realpathSync(fileURLToPath45(import.meta.url));
26527
+ const here = fs62.realpathSync(fileURLToPath46(import.meta.url));
26355
26528
  const argv = fs62.realpathSync(path63.resolve(process.argv[1]));
26356
26529
  return here === argv;
26357
26530
  } catch {
@@ -26364,7 +26537,7 @@ if (isCliEntry12) {
26364
26537
  }
26365
26538
 
26366
26539
  // src/scripts/hooks/dispatch_entry.ts
26367
- var _selfPath = fileURLToPath46(import.meta.url);
26540
+ var _selfPath = fileURLToPath47(import.meta.url);
26368
26541
  var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path64.resolve(process.argv[1]) === path64.resolve(_selfPath);
26369
26542
  if (_invokedDirectly2) {
26370
26543
  process.exitCode = main45(process.argv.slice(2));