@event4u/agent-config 14.21.0 → 14.22.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 (181) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +198 -0
  5. package/CREDITS.md +37 -0
  6. package/dist/agent-src/commands/analyze/inbox.md +380 -5
  7. package/dist/agent-src/commands/analyze/repo.md +4 -2
  8. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +69 -0
  9. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -5
  10. package/dist/agent-src/rules/external-code-graph-interop.md +19 -14
  11. package/dist/agent-src/rules/token-efficiency.md +26 -3
  12. package/dist/agent-src/scripts/_cli_entry.ts +51 -0
  13. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +14 -23
  14. package/dist/agent-src/scripts/roadmap_gates.ts +4 -20
  15. package/dist/agent-src/scripts/roadmap_set_step.ts +5 -2
  16. package/dist/agent-src/scripts/stubs_due.ts +4 -18
  17. package/dist/agent-src/scripts/update_roadmap_progress.ts +7 -24
  18. package/dist/agent-src/skills/code-intelligence/SKILL.md +25 -0
  19. package/dist/agent-src/skills/roadmap-writing/SKILL.md +17 -0
  20. package/dist/agent-src/templates/agent-settings.md +0 -1
  21. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  22. package/dist/cli-delegate/_cli_entry.js +8 -0
  23. package/dist/cli-delegate/_lib/pin_resolver.js +170 -0
  24. package/dist/cli-delegate/archival_sweep.js +8 -0
  25. package/dist/cli-delegate/archive_completed_roadmaps.js +494 -0
  26. package/dist/cli-delegate/check_update_banner.js +923 -0
  27. package/dist/cli-delegate/chunk-5EK5WQN6.js +28 -0
  28. package/dist/cli-delegate/chunk-7XGD2OEU.js +96 -0
  29. package/dist/cli-delegate/{chunk-643Z7FIC.js → chunk-BIXEDQPZ.js} +6 -0
  30. package/dist/cli-delegate/chunk-DBH4AHDK.js +155 -0
  31. package/dist/cli-delegate/chunk-JO25G5H7.js +20 -0
  32. package/dist/cli-delegate/chunk-LTYVIY76.js +7961 -0
  33. package/dist/cli-delegate/chunk-QAJS5YWY.js +999 -0
  34. package/dist/cli-delegate/{chunk-ZVBOHSVF.js → chunk-TGIPZBCW.js} +1 -1
  35. package/dist/cli-delegate/{chunk-YS6XTLEK.js → chunk-TYSY33MD.js} +56 -6
  36. package/dist/cli-delegate/chunk-ULET4BYS.js +328 -0
  37. package/dist/cli-delegate/chunk-YDQSHTD7.js +187 -0
  38. package/dist/cli-delegate/chunk-YWVXLR44.js +48 -0
  39. package/dist/cli-delegate/chunk-ZZQBUHFK.js +273 -0
  40. package/dist/cli-delegate/cmd_conformance.js +2 -2
  41. package/dist/cli-delegate/cmd_export.js +1 -1
  42. package/dist/cli-delegate/cmd_handoff.js +26 -2
  43. package/dist/cli-delegate/cmd_prune.js +1 -1
  44. package/dist/cli-delegate/cmd_session_recycle.js +2 -2
  45. package/dist/cli-delegate/cmd_settings_migrate.js +1 -1
  46. package/dist/cli-delegate/cmd_sync.js +1 -1
  47. package/dist/cli-delegate/cmd_uninstall.js +1 -1
  48. package/dist/cli-delegate/cmd_validate.js +1 -1
  49. package/dist/cli-delegate/dashboard_mode.js +16 -0
  50. package/dist/cli-delegate/gate_budget.js +24 -0
  51. package/dist/cli-delegate/gate_execute.js +25 -0
  52. package/dist/cli-delegate/guarded_baseline.js +18 -0
  53. package/dist/cli-delegate/resume_probe.js +22 -0
  54. package/dist/cli-delegate/roadmap_gates.js +638 -0
  55. package/dist/cli-delegate/roadmap_set_step.js +173 -0
  56. package/dist/cli-delegate/stub_queue.js +47 -0
  57. package/dist/cli-delegate/stubs_due.js +38 -0
  58. package/dist/cli-delegate/ticket_bundles.js +59 -0
  59. package/dist/cli-delegate/update_roadmap_progress.js +60 -0
  60. package/dist/discovery/deprecation-report.md +1 -1
  61. package/dist/discovery/discovery-manifest.json +8 -8
  62. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  63. package/dist/discovery/discovery-manifest.summary.md +1 -1
  64. package/dist/discovery/dormancy-report.md +1 -1
  65. package/dist/discovery/orphan-report.md +1 -1
  66. package/dist/discovery/packs.json +2 -2
  67. package/dist/discovery/trust-report.md +1 -1
  68. package/dist/discovery/workspaces.json +2 -2
  69. package/dist/hooks/dispatch.js +1193 -917
  70. package/dist/install/claudeLayerCarriage.js +237 -0
  71. package/dist/install/claudePathsPlan.js +79 -0
  72. package/dist/install/hostLayerFingerprint.js +1 -1
  73. package/dist/install/install.mjs +6 -0
  74. package/dist/install/partitionEligibility.js +231 -117
  75. package/dist/install/ruleLayerPartition.js +10 -7
  76. package/dist/mcp/registry-manifest.json +2 -2
  77. package/dist/mcp/server.json +2 -2
  78. package/dist/mcp/server.mjs +39219 -38995
  79. package/dist/scripts/condense.js +32 -25
  80. package/docs/MIGRATION.md +49 -1
  81. package/docs/contracts/settings-classes.md +1 -1
  82. package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +73 -0
  83. package/package.json +7 -4
  84. package/src/agent-src/scripts/_cli_entry.ts +51 -0
  85. package/src/agent-src/scripts/archive_completed_roadmaps.ts +14 -23
  86. package/src/agent-src/scripts/roadmap_gates.ts +4 -20
  87. package/src/agent-src/scripts/roadmap_set_step.ts +5 -2
  88. package/src/agent-src/scripts/stubs_due.ts +4 -18
  89. package/src/agent-src/scripts/update_roadmap_progress.ts +7 -24
  90. package/src/config/continuity-surface.json +509 -0
  91. package/src/config/estate-count-budget.json +1 -1
  92. package/src/config/gate-coverage.yml +29 -8
  93. package/src/config/gate-violation-baselines.json +8 -8
  94. package/src/config/gitignore-block.txt +19 -0
  95. package/src/config/host-injection-effect.json +73 -0
  96. package/src/config/packed-binary-manifest.json +33 -0
  97. package/src/config/preamble-payload-budget.json +112 -105
  98. package/src/config/publish-surface.json +4 -2
  99. package/src/install/claudeLayerCarriage.ts +273 -0
  100. package/src/install/claudePathsPlan.ts +76 -0
  101. package/src/install/hostLayerFingerprint.ts +1 -1
  102. package/src/install/partitionEligibility.ts +261 -127
  103. package/src/install/ruleLayerPartition.ts +19 -23
  104. package/src/scripts/_dispatch.bash +77 -27
  105. package/src/scripts/_lib/auto_dispatch.ts +2 -2
  106. package/src/scripts/_lib/catalogue_layer_parity.ts +146 -0
  107. package/src/scripts/_lib/continuity_surface.ts +296 -0
  108. package/src/scripts/_lib/corpus_manifest.ts +26 -9
  109. package/src/scripts/_lib/hook_settings.ts +1 -1
  110. package/src/scripts/_lib/injection_effect.ts +151 -0
  111. package/src/scripts/_lib/layer_overlap_notice.ts +50 -6
  112. package/src/scripts/_lib/packed_binary_predicate.ts +225 -0
  113. package/src/scripts/_lib/pin_resolver.ts +13 -0
  114. package/src/scripts/_lib/regression_neighbourhood.ts +1 -1
  115. package/src/scripts/_lib/retired_status.ts +74 -0
  116. package/src/scripts/_lib/skill_catalogue.ts +156 -21
  117. package/src/scripts/_lib/subagent_capsule.ts +117 -8
  118. package/src/scripts/ai_council/api_transport.ts +5 -0
  119. package/src/scripts/ai_council/deliberation_metrics.ts +353 -0
  120. package/src/scripts/ai_council/prompts.ts +9 -0
  121. package/src/scripts/ai_council/synthesis_disagreement.ts +206 -0
  122. package/src/scripts/capture_skill_catalogue.ts +24 -11
  123. package/src/scripts/check_candidate_lines.ts +499 -0
  124. package/src/scripts/check_continuity_surface.ts +475 -0
  125. package/src/scripts/check_dependency_floors.ts +13 -6
  126. package/src/scripts/check_estate_count.ts +40 -79
  127. package/src/scripts/check_pack_size.ts +262 -23
  128. package/src/scripts/check_roadmap_trackable.ts +19 -16
  129. package/src/scripts/check_rule_layer_partition.ts +54 -34
  130. package/src/scripts/check_single_delivery.ts +97 -31
  131. package/src/scripts/check_update_banner.ts +13 -0
  132. package/src/scripts/code_graph/build.ts +138 -15
  133. package/src/scripts/code_graph/cli.ts +76 -8
  134. package/src/scripts/code_graph/extract.ts +11 -0
  135. package/src/scripts/code_graph/grammar_probe.ts +43 -0
  136. package/src/scripts/code_graph/loader.ts +88 -14
  137. package/src/scripts/code_graph/query.ts +121 -11
  138. package/src/scripts/code_graph/resolution_tiers.ts +238 -0
  139. package/src/scripts/code_graph/sqlite_store.ts +247 -6
  140. package/src/scripts/code_graph/types.ts +66 -1
  141. package/src/scripts/code_graph/validate.ts +23 -0
  142. package/src/scripts/condense.ts +34 -22
  143. package/src/scripts/corpus_manifest.ts +5 -5
  144. package/src/scripts/council_cli.ts +11 -12
  145. package/src/scripts/count_intent_disagreement.ts +426 -0
  146. package/src/scripts/handoff_context_hook.ts +79 -0
  147. package/src/scripts/hook_effect_doctor.ts +82 -1
  148. package/src/scripts/hook_manifest.json +1 -1
  149. package/src/scripts/hook_manifest.yaml +64 -12
  150. package/src/scripts/hooks/chain_nudge_hook.ts +282 -0
  151. package/src/scripts/hooks/code_graph_context_hook.ts +212 -0
  152. package/src/scripts/hooks/concern_registry.ts +4 -2
  153. package/src/scripts/hooks/host_semantics.ts +1 -1
  154. package/src/scripts/hooks/orchestration_record_hook.ts +2 -2
  155. package/src/scripts/hooks/rule_inject_hook.ts +1 -1
  156. package/src/scripts/hooks/skill_route_hook.ts +11 -4
  157. package/src/scripts/inbox_source_census.ts +322 -0
  158. package/src/scripts/install-hooks.sh +82 -0
  159. package/src/scripts/{lint_carrier_integrity.ts → lint_deferral_integrity.ts} +60 -214
  160. package/src/scripts/lint_plan_risk_register.ts +13 -17
  161. package/src/scripts/mcp_server/suggest_skill.ts +72 -0
  162. package/src/scripts/mcp_server/tools.ts +2 -56
  163. package/src/scripts/media/lib/adapter-contract.md +7 -2
  164. package/src/scripts/media/lib/fixtures/flux/asset-0001.png +0 -0
  165. package/src/scripts/media/lib/fixtures/gemini-image/asset-0001.png +0 -0
  166. package/src/scripts/media/lib/fixtures/ideogram/asset-0001.png +0 -0
  167. package/src/scripts/rdp_candidates_delta.ts +276 -0
  168. package/src/scripts/rdp_quality_eval.ts +217 -19
  169. package/src/scripts/release_mix_taxonomy.json +3 -2
  170. package/src/scripts/report_host_injection_effect.ts +189 -0
  171. package/src/scripts/report_layer_overlap.ts +41 -0
  172. package/src/scripts/report_skill_menu_census.ts +341 -0
  173. package/src/scripts/skill_tools/score_skill_relevance.ts +70 -6
  174. package/src/scripts/skill_tools/suggest_skill_for_task.ts +37 -3
  175. package/src/vendor/grammars/README.md +61 -0
  176. package/src/vendor/grammars/tree-sitter-javascript.wasm +0 -0
  177. package/src/vendor/grammars/tree-sitter-php.wasm +0 -0
  178. package/src/vendor/grammars/tree-sitter-typescript.wasm +0 -0
  179. package/src/scripts/_lib/carrier_status.ts +0 -118
  180. package/src/scripts/_lib/estate_carrier_cases.ts +0 -72
  181. package/src/scripts/hooks/code_graph_nudge_hook.ts +0 -191
@@ -0,0 +1,51 @@
1
+ /**
2
+ * "Was this module invoked as the command?" — one definition for the scripts
3
+ * under `agents/scripts` that both run directly and are imported by siblings.
4
+ *
5
+ * Five of them carried a byte-identical copy of this logic, and the copies were
6
+ * about to gain a sixth clause each. The interesting part is why the obvious
7
+ * one-liner is not enough:
8
+ *
9
+ * - `--splitting` in `build:agent-src-delegate` can move a module body into a
10
+ * shared chunk, where `import.meta.url` names the CHUNK. The URL comparison
11
+ * then never matches and the command exits 0 having done nothing — measured
12
+ * on `update_roadmap_progress` before this guard existed. Inside the bundle
13
+ * the invoked file name is the reliable signal, so the delegate branch runs
14
+ * first and a miss falls through rather than returning false.
15
+ * - A symlinked invocation (`.augment/scripts` → `dist/agent-src/scripts`, or
16
+ * macOS `/var` → `/private/var`) makes the raw URLs differ: `import.meta.url`
17
+ * is the resolved real path while `argv[1]` keeps the symlink. Hence the
18
+ * realpath comparison last.
19
+ *
20
+ * `moduleUrl` is the caller's own `import.meta.url` — it cannot be read from
21
+ * here, which is why it is a parameter rather than a lookup.
22
+ */
23
+ import * as fs from 'node:fs';
24
+ import * as path from 'node:path';
25
+ import { fileURLToPath, pathToFileURL } from 'node:url';
26
+
27
+ /** Defined only by the esbuild delegate builds; `undefined` under tsx and node. */
28
+ declare const __AGENT_CONFIG_CLI_DELEGATE__: boolean | undefined;
29
+
30
+ export function isCliEntry(moduleUrl: string, name: string): boolean {
31
+ const argv1 = process.argv[1];
32
+ if (argv1 === undefined) {
33
+ return false;
34
+ }
35
+ if (
36
+ typeof __AGENT_CONFIG_CLI_DELEGATE__ !== 'undefined' &&
37
+ __AGENT_CONFIG_CLI_DELEGATE__ &&
38
+ path.basename(argv1, '.js') === name
39
+ ) {
40
+ return true;
41
+ }
42
+ const argvPath = path.resolve(argv1);
43
+ if (moduleUrl === pathToFileURL(argvPath).href) {
44
+ return true;
45
+ }
46
+ try {
47
+ return fs.realpathSync(fileURLToPath(moduleUrl)) === fs.realpathSync(argvPath);
48
+ } catch {
49
+ return false;
50
+ }
51
+ }
@@ -56,11 +56,13 @@ import { spawnSync } from 'node:child_process';
56
56
  import * as fs from 'node:fs';
57
57
  import * as path from 'node:path';
58
58
  import process from 'node:process';
59
- import { fileURLToPath, pathToFileURL } from 'node:url';
59
+ import { fileURLToPath } from 'node:url';
60
60
 
61
61
  import { collect } from './update_roadmap_progress.js';
62
62
  import { guardedBaselineProblems, parseGuardedBaselines } from './guarded_baseline.js';
63
63
 
64
+ import { isCliEntry } from './_cli_entry.js';
65
+
64
66
  const _HERE = fileURLToPath(import.meta.url);
65
67
 
66
68
  interface CompletedProcess {
@@ -638,6 +640,16 @@ function _regen_dashboard(root: string, dry_run: boolean): void {
638
640
  if (dry_run) {
639
641
  return;
640
642
  }
643
+ // Inside `dist/cli-delegate/` the twin sits next to us as a precompiled
644
+ // bundle, and plain `node` runs it — the tsx walk below would otherwise
645
+ // reach `npx tsx`, which resolves against the CONSUMER's npm config and
646
+ // hard-fails on a mismatched `engines`/`devEngines` pin (the very class
647
+ // ADR-204 removed from the dispatcher and left standing here).
648
+ const bundledTwin = path.join(path.dirname(_HERE), 'update_roadmap_progress.js');
649
+ if (_isFile(bundledTwin)) {
650
+ spawnSync(process.execPath, [bundledTwin], { cwd: root, encoding: 'utf-8' });
651
+ return;
652
+ }
641
653
  const script = path.join(path.dirname(_HERE), 'update_roadmap_progress.ts');
642
654
  // Python: `_run([sys.executable, str(script)], root)`; the twin spawns the
643
655
  // dashboard generator twin through the same `tsx` runtime, cwd=root.
@@ -800,28 +812,7 @@ function main(argv?: readonly string[]): number {
800
812
  return 0;
801
813
  }
802
814
 
803
- function _isCliEntry(): boolean {
804
- if (process.argv[1] === undefined) {
805
- return false;
806
- }
807
- const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
808
- if (import.meta.url === argvUrl) {
809
- return true;
810
- }
811
- // A symlinked invocation (e.g. via `.augment/scripts` → `dist/agent-src/scripts`,
812
- // or macOS /var → /private/var temp dirs) makes the raw URLs differ:
813
- // import.meta.url is the resolved real path while argv[1] keeps the symlink
814
- // path. Compare realpaths so the entry guard still fires (without this the
815
- // archival sweep silently no-ops when run through the symlink).
816
- try {
817
- const here = fs.realpathSync(fileURLToPath(import.meta.url));
818
- const argv = fs.realpathSync(path.resolve(process.argv[1]));
819
- return here === argv;
820
- } catch {
821
- return false;
822
- }
823
- }
824
- if (_isCliEntry() || process.argv[1] === _HERE) {
815
+ if (isCliEntry(import.meta.url, 'archive_completed_roadmaps')) {
825
816
  try {
826
817
  process.exitCode = main();
827
818
  } catch (exc) {
@@ -65,7 +65,7 @@
65
65
  */
66
66
 
67
67
  import * as path from 'node:path';
68
- import { fileURLToPath, pathToFileURL } from 'node:url';
68
+ import { fileURLToPath } from 'node:url';
69
69
  import * as fs from 'node:fs';
70
70
  import { spawnSync } from 'node:child_process';
71
71
 
@@ -80,6 +80,8 @@ import { execute } from './gate_execute.js';
80
80
  import { listPending } from '../templates/scripts/work_engine/hooks/builtin/staged_confirmation_store.js';
81
81
  import type { StagedAction } from '../templates/scripts/work_engine/hooks/builtin/staged_confirmation.js';
82
82
 
83
+ import { isCliEntry } from './_cli_entry.js';
84
+
83
85
  const _HERE = fileURLToPath(import.meta.url);
84
86
 
85
87
  /** Hard wrap for the rendered body — keeps output readable in a narrow pane. */
@@ -928,26 +930,8 @@ function main(argv?: readonly string[]): number {
928
930
  return 0;
929
931
  }
930
932
 
931
- function _isCliEntry(): boolean {
932
- if (process.argv[1] === undefined) {
933
- return false;
934
- }
935
- const argvPath = path.resolve(process.argv[1]);
936
- if (import.meta.url === pathToFileURL(argvPath).href) {
937
- return true;
938
- }
939
- // A symlinked invocation (`.augment/scripts` → `dist/agent-src/scripts`, or
940
- // macOS /var → /private/var) makes the raw URLs differ: import.meta.url is
941
- // the resolved real path while argv[1] keeps the symlink. Compare realpaths
942
- // so the entry guard still fires through the projection.
943
- try {
944
- return fs.realpathSync(_HERE) === fs.realpathSync(argvPath);
945
- } catch {
946
- return false;
947
- }
948
- }
949
933
 
950
- if (_isCliEntry()) {
934
+ if (isCliEntry(import.meta.url, 'roadmap_gates')) {
951
935
  process.exitCode = main();
952
936
  }
953
937
 
@@ -30,7 +30,9 @@
30
30
  import * as fs from 'node:fs';
31
31
  import * as path from 'node:path';
32
32
  import process from 'node:process';
33
- import { fileURLToPath, pathToFileURL } from 'node:url';
33
+ import { fileURLToPath } from 'node:url';
34
+
35
+ import { isCliEntry } from './_cli_entry.js';
34
36
 
35
37
  const _HERE = fileURLToPath(import.meta.url);
36
38
 
@@ -246,8 +248,9 @@ export function main(argv: string[] = process.argv.slice(2)): number {
246
248
  }
247
249
  }
248
250
 
251
+
249
252
  /* c8 ignore start */
250
- if (process.argv[1] !== undefined && pathToFileURL(path.resolve(process.argv[1])).href === pathToFileURL(_HERE).href) {
253
+ if (isCliEntry(import.meta.url, 'roadmap_set_step')) {
251
254
  process.exit(main());
252
255
  }
253
256
  /* c8 ignore stop */
@@ -42,7 +42,9 @@
42
42
  */
43
43
  import * as fs from 'node:fs';
44
44
  import * as path from 'node:path';
45
- import { fileURLToPath, pathToFileURL } from 'node:url';
45
+ import { fileURLToPath } from 'node:url';
46
+
47
+ import { isCliEntry } from './_cli_entry.js';
46
48
 
47
49
  const STUB_DIR = path.join('agents', 'roadmaps', 'stubs');
48
50
 
@@ -459,24 +461,8 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
459
461
  return 0;
460
462
  }
461
463
 
462
- function _isCliEntry(): boolean {
463
- if (process.argv[1] === undefined) {
464
- return false;
465
- }
466
- const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
467
- if (import.meta.url === argvUrl) {
468
- return true;
469
- }
470
- try {
471
- const here = fs.realpathSync(fileURLToPath(import.meta.url));
472
- const argv = fs.realpathSync(path.resolve(process.argv[1]));
473
- return here === argv;
474
- } catch {
475
- return false;
476
- }
477
- }
478
464
 
479
- if (_isCliEntry() || process.argv[1] === _HERE) {
465
+ if (isCliEntry(import.meta.url, 'stubs_due')) {
480
466
  process.exitCode = main();
481
467
  }
482
468
 
@@ -62,7 +62,7 @@ import { createRequire } from 'node:module';
62
62
  import { spawnSync } from 'node:child_process';
63
63
  import * as fs from 'node:fs';
64
64
  import * as path from 'node:path';
65
- import { fileURLToPath, pathToFileURL } from 'node:url';
65
+ import { fileURLToPath } from 'node:url';
66
66
  import { run_archival_sweep } from './archival_sweep.js';
67
67
  import {
68
68
  evaluateDashboardOnDisk,
@@ -72,6 +72,8 @@ import {
72
72
  } from './dashboard_mode.js';
73
73
  import type * as YamlModule from 'yaml';
74
74
  import { headerFragment as stubHeaderFragment } from './stubs_due.js';
75
+
76
+ import { isCliEntry } from './_cli_entry.js';
75
77
  import { reportGuardedBaselines } from './guarded_baseline.js'; // third step state; contract lives there
76
78
 
77
79
  const _HERE = fileURLToPath(import.meta.url);
@@ -96,7 +98,9 @@ const EXCLUDE_DIRS: ReadonlySet<string> = new Set(['archive', 'skipped', 'stubs'
96
98
 
97
99
  // FRONTMATTER_RE = re.compile(r"\A---\n(.*?)\n---\s*\n", re.DOTALL)
98
100
  const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---[ \t\n\r\f\v]*\n/;
99
- const UNSCHEDULED_VALUES: ReadonlySet<string> = new Set(['draft', 'carrier']);
101
+ // A set of one since ADR-262 deleted `status: carrier`; the shape stays so a
102
+ // future unscheduled value is one entry rather than a control-flow change.
103
+ const UNSCHEDULED_VALUES: ReadonlySet<string> = new Set(['draft']);
100
104
 
101
105
  const MERGE_GATED_RE = /merge-gated/i;
102
106
  // PR_NUM_RE = re.compile(r"pr\s*[=#:]?\s*#?\s*(\d+)", re.IGNORECASE)
@@ -1438,28 +1442,7 @@ function main(argv?: readonly string[]): number {
1438
1442
  return guarded.problems > 0 ? 1 : 0;
1439
1443
  }
1440
1444
 
1441
- function _isCliEntry(): boolean {
1442
- if (process.argv[1] === undefined) {
1443
- return false;
1444
- }
1445
- const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
1446
- if (import.meta.url === argvUrl) {
1447
- return true;
1448
- }
1449
- // A symlinked invocation (e.g. via `.augment/scripts` → `dist/agent-src/scripts`,
1450
- // or macOS /var → /private/var temp dirs) makes the raw URLs differ:
1451
- // import.meta.url is the resolved real path while argv[1] keeps the symlink
1452
- // path. Compare realpaths so the entry guard still fires (without this the
1453
- // dashboard regen silently no-ops when run through the symlink).
1454
- try {
1455
- const here = fs.realpathSync(fileURLToPath(import.meta.url));
1456
- const argv = fs.realpathSync(path.resolve(process.argv[1]));
1457
- return here === argv;
1458
- } catch {
1459
- return false;
1460
- }
1461
- }
1462
- if (_isCliEntry() || process.argv[1] === _HERE) {
1445
+ if (isCliEntry(import.meta.url, 'update_roadmap_progress')) {
1463
1446
  try {
1464
1447
  process.exitCode = main();
1465
1448
  } catch (exc) {
@@ -182,6 +182,28 @@ consumer-shipped SCIP index. Literal-string probes are reported as a separate
182
182
  cannot answer them at all, which is where grep stays necessary rather than a
183
183
  defect in the engine.
184
184
 
185
+ ## Staleness delivery — which hosts get it for free, and which do not
186
+
187
+ Migrated verbatim from `external-code-graph-interop` so the obligation stays in
188
+ the rule and the per-host delivery detail is paid only on activation.
189
+
190
+ On a host with a verified `pre_tool_use` contract, the `code-graph-context`
191
+ concern supplies this for free: once per session, on the first search or
192
+ code read, it delivers the graph's state as structured `additionalContext` —
193
+ `code-graph: fresh` or `code-graph: N commit(s) behind`. It is silent when no
194
+ graph exists, so hearing nothing is not evidence that the graph is fresh.
195
+
196
+ **On every other host that carrier does not exist**, and this section is the
197
+ delivery: run `agent-config code-graph detect --format json` before trusting a
198
+ relationship answer, and say which state you got. Which hosts those are is
199
+ `agent-config hooks:status` — resolved from the platform table, never guessed
200
+ from the host's name.
201
+
202
+ Either way the disposition is the same: `behind:N` → `agent-config code-graph
203
+ refresh` first, or use grep and say so. This is a freshness obligation, not an
204
+ ordering claim; the rule's query-first ordering still governs which source to
205
+ reach for.
206
+
185
207
  ## Do NOT
186
208
 
187
209
  - Do NOT rebuild a **fresh** consumer-shipped index — query it (interop
@@ -199,3 +221,6 @@ defect in the engine.
199
221
  discipline; the graph is one evidence source, still confirmed against the real
200
222
  code when load-bearing.
201
223
  - `agent-config code-graph` — the CLI surface over the engine (build / query / detect / affected).
224
+ - [`discovery_graph`](../../scripts/discovery_graph.ts) — this suite's OWN
225
+ artifact relation-graph (`affected`/`explain`). The external code-graph is the
226
+ *source-code* analogue; keep the two apart when answering.
@@ -224,6 +224,23 @@ procedure when [`roadmap-management`](../roadmap-management/SKILL.md)
224
224
  spawns a follow-up). Bare `[~]` / `[-]` is allowed; annotated is
225
225
  preferred.
226
226
 
227
+ #### A prohibition-shaped step closes with `[x]`
228
+
229
+ A step whose content is a **prohibition** (*"Do not build the enforcement"*) has
230
+ no artifact to point at. `[~]` invents receiver work nobody owes, `[-]` mislabels
231
+ restraint as cancellation, `[ ]` makes an honoured bounded obligation
232
+ unarchivable. It closes with **`[x]`** — the obligation was discharged, and `[x]`
233
+ never required that something was created. Its `verify:` must name every
234
+ implementation, registration and semantically-equivalent surface (a structural
235
+ check, not one literal grep, which misses aliases and generated code); **fail if
236
+ an expected search root is missing**, checked BEFORE the absence check, because a
237
+ glob over a vanished directory returns nothing and reads as success; scope the
238
+ claim to the branch diff — *"this change introduced no enforcement"*, never the
239
+ unprovable *"enforcement exists nowhere"*; and be re-run at archival. Not for a
240
+ prohibition meant to hold indefinitely — that belongs in a rule, test or linter,
241
+ because a closed step stops watching. Council convention, 2026-09-08 (2 seats,
242
+ convergent); falsified if tooling defines `[x]` as requiring a positive mutation.
243
+
227
244
  ### 7. Follow-up roadmaps spawn from deferred items — frontmatter shape
228
245
 
229
246
  When a parent roadmap closes with `[~]` items, the
@@ -629,7 +629,6 @@ the canonical narrative lives in
629
629
  | `hooks.injection_scan.enabled` | `true`, `false` | `false` | PostToolUse prompt-injection scanner: scans tool output for injection signatures and warns in context (exit 2) — never blocks. |
630
630
  | `hooks.rtk_wrap.enabled` | `true`, `false` | `false` | PreToolUse RTK-wrap nudge: when `rtk` is on PATH, warns (exit 2, never blocks) to re-run a verbose CLI command wrapped with rtk. |
631
631
  | `hooks.design_slop.enabled` | `true`, `false` | `false` | PreToolUse anti-slop nudge: runs the `lint_design_slop` registry against about-to-be-written UI content and warns (exit 2, never blocks) on P0/P1 aesthetic tells. |
632
- | `hooks.code_graph.enabled` | `true`, `false` | `false` | PreToolUse code-graph nudge (deprecated — honest null 2026-07-28): when a code-graph index exists, warns once per session to query the graph before grep. Requires manually installing the ABI-locked parser pair. |
633
632
  | `pipelines.skill_improvement` | `true`, `false` | `true` | When `true`: propose learning capture after meaningful tasks. When `false`: silent. Included in every profile except `custom`. |
634
633
  | `roadmap.skip_pre_run_gate` | `true`, `false` | `true` | When `true` (default): `/roadmap:process-step\|phase\|full` skips the interactive pre-run summary and starts the loop immediately — the resolved roadmap, cadence, and council are surfaced inline so an unwanted pick can still be aborted. When `false`: the loop shows the pre-run summary with numbered options (Go / Different roadmap / Different scope / Toggle council / Abort) and waits. The gate is always shown — regardless of this flag — when the roadmap is ambiguous (multiple active, none named) or a scope / cadence conflict has no sensible default. |
635
634
  | `roadmap.quality_cadence` | `end_of_roadmap`, `per_phase`, `per_step` | `end_of_roadmap` | When `/roadmap:process-step|phase|full` runs the project's quality pipeline — only relevant when `quality.local_auto_run` is `true`; when it is `false` (the default) local pipeline runs are suppressed at every cadence and remote CI is the gate. Default skips per-step / per-phase runs and gates only the final archival. `per_phase` runs once after every phase; `per_step` is the legacy verbose mode. Step checkboxes and the dashboard are always updated regardless. |
@@ -39,7 +39,7 @@ schema_version: 1
39
39
  # CI guard: a release bump of `package.json` must update this value
40
40
  # in lockstep — see scripts/check_template_pin_drift.ts (road-to-
41
41
  # portable-runtime-and-update-check P3.3).
42
- agent_config_version: "14.21.0"
42
+ agent_config_version: "14.22.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project:
@@ -0,0 +1,8 @@
1
+ import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
2
+ import {
3
+ isCliEntry
4
+ } from "./chunk-5EK5WQN6.js";
5
+ import "./chunk-JO25G5H7.js";
6
+ export {
7
+ isCliEntry
8
+ };
@@ -0,0 +1,170 @@
1
+ import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
2
+
3
+ // src/scripts/_lib/pin_resolver.ts
4
+ import { spawnSync } from "node:child_process";
5
+ import * as fs from "node:fs";
6
+ import * as path from "node:path";
7
+ import { fileURLToPath, pathToFileURL } from "node:url";
8
+ var PACKAGE_NAME = "@event4u/agent-config";
9
+ var PIN_KEY = "agent_config_version";
10
+ var NO_REEXEC_ENV = "AGENT_CONFIG_NO_PIN_REEXEC";
11
+ var REEXEC_DEPTH_ENV = "AGENT_CONFIG_PIN_REEXEC_DEPTH";
12
+ function _normalize(version) {
13
+ return version.trim().replace(/^v+/, "");
14
+ }
15
+ async function read_pin(cwd, options = {}) {
16
+ let settings;
17
+ try {
18
+ let loader = options.settings_loader;
19
+ if (loader === void 0) {
20
+ const specifier = "./agent_settings";
21
+ const mod = await import(specifier);
22
+ if (typeof mod.load_agent_settings !== "function") {
23
+ return null;
24
+ }
25
+ loader = mod.load_agent_settings;
26
+ }
27
+ settings = await loader({ cwd });
28
+ } catch {
29
+ return null;
30
+ }
31
+ const raw = settings[PIN_KEY];
32
+ if (typeof raw !== "string") {
33
+ return null;
34
+ }
35
+ const pin = raw.trim();
36
+ return pin || null;
37
+ }
38
+ function should_reexec(pin, installed, options = {}) {
39
+ const env = options.env ?? process.env;
40
+ if (env[NO_REEXEC_ENV] === "1") {
41
+ return false;
42
+ }
43
+ if (env[REEXEC_DEPTH_ENV] === "1") {
44
+ return false;
45
+ }
46
+ if (!pin) {
47
+ return false;
48
+ }
49
+ if (!installed) {
50
+ return false;
51
+ }
52
+ return _normalize(pin) !== _normalize(installed);
53
+ }
54
+ function build_reexec_argv(pin, argv) {
55
+ return ["npx", "--yes", `${PACKAGE_NAME}@${_normalize(pin)}`, ...argv];
56
+ }
57
+ function _which(cmd) {
58
+ const path_var = process.env.PATH ?? "";
59
+ const exts = process.platform === "win32" ? (process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";") : [""];
60
+ for (const dir of path_var.split(path.delimiter)) {
61
+ if (!dir) {
62
+ continue;
63
+ }
64
+ for (const ext of exts) {
65
+ const candidate = path.join(dir, cmd + ext.toLowerCase());
66
+ try {
67
+ const st = fs.statSync(candidate);
68
+ if (st.isFile()) {
69
+ if (process.platform !== "win32") {
70
+ fs.accessSync(candidate, fs.constants.X_OK);
71
+ }
72
+ return candidate;
73
+ }
74
+ } catch {
75
+ }
76
+ }
77
+ }
78
+ return null;
79
+ }
80
+ function _exec_runner(npx, argv, env) {
81
+ const result = spawnSync(npx, argv.slice(1), {
82
+ env,
83
+ stdio: "inherit"
84
+ });
85
+ process.exit(result.status ?? 1);
86
+ }
87
+ async function maybe_reexec(installed, options = {}) {
88
+ const cwd = options.cwd ?? process.cwd();
89
+ const argv = options.argv ?? process.argv.slice(1);
90
+ const env = options.env ?? process.env;
91
+ const pin_reader = options.pin_reader ?? ((c) => read_pin(c));
92
+ const which = options.which ?? _which;
93
+ const pin = await pin_reader(cwd);
94
+ if (!should_reexec(pin, installed, { env })) {
95
+ return null;
96
+ }
97
+ if (pin == null) {
98
+ throw new Error("maybe_reexec: pin narrowed to null after should_reexec");
99
+ }
100
+ const npx = which("npx");
101
+ if (!npx) {
102
+ return null;
103
+ }
104
+ const new_argv = build_reexec_argv(pin, argv.length > 0 ? argv.slice(1) : []);
105
+ const child_env = { ...env };
106
+ child_env[REEXEC_DEPTH_ENV] = "1";
107
+ const runner = options.runner ?? null;
108
+ if (runner === null) {
109
+ return _exec_runner(npx, new_argv, child_env);
110
+ }
111
+ return runner(npx, new_argv, child_env);
112
+ }
113
+ function _parse_cli(argv) {
114
+ let cwd = process.cwd();
115
+ let installed = "";
116
+ let forward = [];
117
+ let i = 0;
118
+ while (i < argv.length) {
119
+ const token = argv[i];
120
+ if (token === "--cwd" && i + 1 < argv.length) {
121
+ cwd = argv[i + 1];
122
+ i += 2;
123
+ } else if (token === "--installed" && i + 1 < argv.length) {
124
+ installed = argv[i + 1];
125
+ i += 2;
126
+ } else if (token === "--") {
127
+ forward = argv.slice(i + 1);
128
+ break;
129
+ } else {
130
+ i += 1;
131
+ }
132
+ }
133
+ return { cwd, installed, forward };
134
+ }
135
+ function _isCliEntry() {
136
+ if (process.argv[1] === void 0) {
137
+ return false;
138
+ }
139
+ if (true) {
140
+ if (path.basename(process.argv[1], ".js") === "pin_resolver") {
141
+ return true;
142
+ }
143
+ }
144
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
145
+ if (import.meta.url === argvUrl) {
146
+ return true;
147
+ }
148
+ try {
149
+ const here = fs.realpathSync(fileURLToPath(import.meta.url));
150
+ const argv = fs.realpathSync(path.resolve(process.argv[1]));
151
+ return here === argv;
152
+ } catch {
153
+ return false;
154
+ }
155
+ }
156
+ if (_isCliEntry()) {
157
+ const { cwd, installed, forward } = _parse_cli(process.argv.slice(2));
158
+ const child_argv = ["agent-config", ...forward];
159
+ await maybe_reexec(installed, { cwd, argv: child_argv });
160
+ }
161
+ export {
162
+ NO_REEXEC_ENV,
163
+ PACKAGE_NAME,
164
+ PIN_KEY,
165
+ REEXEC_DEPTH_ENV,
166
+ build_reexec_argv,
167
+ maybe_reexec,
168
+ read_pin,
169
+ should_reexec
170
+ };
@@ -0,0 +1,8 @@
1
+ import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
2
+ import {
3
+ run_archival_sweep
4
+ } from "./chunk-YWVXLR44.js";
5
+ import "./chunk-JO25G5H7.js";
6
+ export {
7
+ run_archival_sweep
8
+ };