@event4u/agent-config 16.2.0 → 16.4.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 (651) 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 +337 -234
  5. package/README.md +15 -13
  6. package/agents/templates/.ai-council.yml.example +26 -8
  7. package/dist/agent-src/commands/analyze/inbox.md +11 -8
  8. package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
  9. package/dist/agent-src/commands/bug/fix.md +17 -2
  10. package/dist/agent-src/commands/bug/investigate.md +1 -1
  11. package/dist/agent-src/commands/commit/in-chunks.md +40 -31
  12. package/dist/agent-src/commands/commit.md +72 -33
  13. package/dist/agent-src/commands/condense.md +2 -8
  14. package/dist/agent-src/commands/council/debate.md +11 -7
  15. package/dist/agent-src/commands/council/default.md +10 -9
  16. package/dist/agent-src/commands/council.md +1 -1
  17. package/dist/agent-src/commands/estimate-ticket.md +1 -1
  18. package/dist/agent-src/commands/feature/explore.md +3 -3
  19. package/dist/agent-src/commands/feature/plan.md +2 -2
  20. package/dist/agent-src/commands/feature/roadmap.md +1 -1
  21. package/dist/agent-src/commands/fix/ci.md +18 -4
  22. package/dist/agent-src/commands/fix/commit-messages.md +48 -23
  23. package/dist/agent-src/commands/fix/pr-comments.md +3 -6
  24. package/dist/agent-src/commands/implement-ticket.md +4 -4
  25. package/dist/agent-src/commands/jira-ticket.md +1 -1
  26. package/dist/agent-src/commands/memory/add.md +4 -16
  27. package/dist/agent-src/commands/memory/load.md +5 -6
  28. package/dist/agent-src/commands/memory/promote.md +3 -16
  29. package/dist/agent-src/commands/mission/upgrade.md +3 -2
  30. package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
  31. package/dist/agent-src/commands/optimize/deep.md +4 -2
  32. package/dist/agent-src/commands/optimize/rtk.md +4 -26
  33. package/dist/agent-src/commands/pr/create/description-only.md +18 -15
  34. package/dist/agent-src/commands/pr/create.md +42 -34
  35. package/dist/agent-src/commands/pr/merge.md +136 -9
  36. package/dist/agent-src/commands/prepare-for-review.md +13 -11
  37. package/dist/agent-src/commands/project/analyze.md +7 -35
  38. package/dist/agent-src/commands/refine-ticket.md +1 -1
  39. package/dist/agent-src/commands/review/changes.md +14 -19
  40. package/dist/agent-src/commands/roadmap/create.md +1 -1
  41. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  42. package/dist/agent-src/commands/roadmap/next.md +10 -1
  43. package/dist/agent-src/commands/roadmap/process-full.md +56 -42
  44. package/dist/agent-src/commands/roadmap/resolve-blockers.md +411 -0
  45. package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
  46. package/dist/agent-src/commands/roadmap.md +18 -4
  47. package/dist/agent-src/commands/tests/create.md +17 -3
  48. package/dist/agent-src/commands/tests/execute.md +22 -5
  49. package/dist/agent-src/commands/worktree/create.md +7 -3
  50. package/dist/agent-src/commands/worktree/verify.md +2 -1
  51. package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
  52. package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
  53. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
  54. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
  55. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
  56. package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
  57. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +7 -7
  58. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
  59. package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
  60. package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
  61. package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
  62. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
  63. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +99 -54
  64. package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
  65. package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
  66. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
  67. package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
  68. package/dist/agent-src/contexts/execution/toolchain-resolver.md +95 -7
  69. package/dist/agent-src/contexts/subagent-configuration.md +1 -1
  70. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  71. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  72. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  73. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  74. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
  75. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  76. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  77. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
  78. package/dist/agent-src/guidelines/php/git.md +15 -2
  79. package/dist/agent-src/rules/active-remediation.md +1 -2
  80. package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
  81. package/dist/agent-src/rules/architecture.md +0 -1
  82. package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
  83. package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
  84. package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
  85. package/dist/agent-src/rules/autonomous-execution.md +1 -1
  86. package/dist/agent-src/rules/brand-consistency.md +0 -1
  87. package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
  88. package/dist/agent-src/rules/broken-access-control.md +1 -1
  89. package/dist/agent-src/rules/cli-output-handling.md +0 -1
  90. package/dist/agent-src/rules/code-comment-discipline.md +0 -1
  91. package/dist/agent-src/rules/code-provenance.md +0 -1
  92. package/dist/agent-src/rules/command-suggestion-policy.md +1 -1
  93. package/dist/agent-src/rules/commit-conventions.md +1 -2
  94. package/dist/agent-src/rules/communication-through-line.md +1 -2
  95. package/dist/agent-src/rules/content-quoting-floor.md +1 -2
  96. package/dist/agent-src/rules/context-hygiene.md +6 -6
  97. package/dist/agent-src/rules/copilot-routing.md +1 -2
  98. package/dist/agent-src/rules/council-availability.md +4 -4
  99. package/dist/agent-src/rules/cross-source-consistency.md +4 -6
  100. package/dist/agent-src/rules/decision-revisit-gate.md +17 -35
  101. package/dist/agent-src/rules/delegation-policy.md +2 -3
  102. package/dist/agent-src/rules/design-fidelity.md +12 -16
  103. package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
  104. package/dist/agent-src/rules/devcontainer-routing.md +1 -2
  105. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
  106. package/dist/agent-src/rules/docker-commands.md +0 -1
  107. package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
  108. package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -1
  109. package/dist/agent-src/rules/domain-safety-pii.md +1 -1
  110. package/dist/agent-src/rules/domain-safety-retention.md +1 -1
  111. package/dist/agent-src/rules/downstream-changes.md +0 -1
  112. package/dist/agent-src/rules/engineering-safety-floor.md +1 -1
  113. package/dist/agent-src/rules/evaluator-independence.md +3 -2
  114. package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
  115. package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
  116. package/dist/agent-src/rules/fast-path-marker-visibility.md +2 -2
  117. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  118. package/dist/agent-src/rules/fix-what-you-see.md +6 -32
  119. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
  120. package/dist/agent-src/rules/git-history-discipline.md +2 -2
  121. package/dist/agent-src/rules/guidelines.md +0 -1
  122. package/dist/agent-src/rules/history-discipline.md +0 -1
  123. package/dist/agent-src/rules/icon-consistency.md +0 -1
  124. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -1
  125. package/dist/agent-src/rules/improve-before-implement.md +0 -1
  126. package/dist/agent-src/rules/invite-challenge.md +0 -1
  127. package/dist/agent-src/rules/laravel-routing.md +1 -2
  128. package/dist/agent-src/rules/laravel-translations.md +0 -1
  129. package/dist/agent-src/rules/legal-safety-floor.md +3 -3
  130. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -1
  131. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
  132. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -1
  133. package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
  134. package/dist/agent-src/rules/media-governance-routing.md +13 -17
  135. package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
  136. package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
  137. package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
  138. package/dist/agent-src/rules/missing-tool-handling.md +0 -1
  139. package/dist/agent-src/rules/model-recommendation.md +0 -1
  140. package/dist/agent-src/rules/neighbour-precedence.md +64 -0
  141. package/dist/agent-src/rules/no-attribution-footers.md +0 -1
  142. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
  143. package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
  144. package/dist/agent-src/rules/no-roadmap-references.md +0 -1
  145. package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
  146. package/dist/agent-src/rules/onboarding-gate.md +0 -1
  147. package/dist/agent-src/rules/output-discipline.md +0 -1
  148. package/dist/agent-src/rules/package-ci-checks.md +0 -1
  149. package/dist/agent-src/rules/persona-governance.md +4 -5
  150. package/dist/agent-src/rules/php-coding.md +0 -1
  151. package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
  152. package/dist/agent-src/rules/preservation-guard.md +0 -1
  153. package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -4
  154. package/dist/agent-src/rules/question-not-instruction.md +1 -1
  155. package/dist/agent-src/rules/reviewer-awareness.md +0 -1
  156. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
  157. package/dist/agent-src/rules/roadmap-progress-sync.md +4 -7
  158. package/dist/agent-src/rules/role-mode-adherence.md +0 -1
  159. package/dist/agent-src/rules/rule-type-governance.md +0 -1
  160. package/dist/agent-src/rules/runtime-safety.md +1 -1
  161. package/dist/agent-src/rules/scale-discipline.md +0 -1
  162. package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
  163. package/dist/agent-src/rules/security-sensitive-stop.md +3 -3
  164. package/dist/agent-src/rules/self-repair-loop.md +0 -1
  165. package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
  166. package/dist/agent-src/rules/session-canary.md +7 -62
  167. package/dist/agent-src/rules/settings-ask-protocol.md +6 -6
  168. package/dist/agent-src/rules/size-enforcement.md +0 -1
  169. package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
  170. package/dist/agent-src/rules/skill-quality.md +0 -1
  171. package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
  172. package/dist/agent-src/rules/source-confidentiality.md +1 -1
  173. package/dist/agent-src/rules/source-discovery-gate.md +0 -1
  174. package/dist/agent-src/rules/source-of-truth.md +0 -1
  175. package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
  176. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  177. package/dist/agent-src/rules/symfony-routing.md +1 -2
  178. package/dist/agent-src/rules/think-before-action.md +0 -1
  179. package/dist/agent-src/rules/token-budget-discipline.md +12 -46
  180. package/dist/agent-src/rules/token-efficiency.md +0 -1
  181. package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
  182. package/dist/agent-src/rules/tool-safety.md +1 -1
  183. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  184. package/dist/agent-src/rules/untrusted-input-defense.md +1 -1
  185. package/dist/agent-src/rules/upstream-proposal.md +0 -1
  186. package/dist/agent-src/rules/user-interaction.md +0 -1
  187. package/dist/agent-src/rules/user-interrupt-priority.md +1 -1
  188. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  189. package/dist/agent-src/scripts/deferral_carry.ts +339 -0
  190. package/dist/agent-src/scripts/gate_budget.ts +47 -23
  191. package/dist/agent-src/scripts/gate_execute.ts +12 -4
  192. package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
  193. package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
  194. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
  195. package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
  196. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  197. package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
  198. package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
  199. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  200. package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
  201. package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
  202. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
  203. package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
  204. package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
  205. package/dist/agent-src/skills/database/data/manifest.json +2 -2
  206. package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
  207. package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
  208. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
  209. package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
  210. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
  211. package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
  212. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  213. package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
  214. package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
  215. package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
  216. package/dist/agent-src/skills/iconography/SKILL.md +1 -1
  217. package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
  218. package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
  219. package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
  220. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  221. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  222. package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
  223. package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
  224. package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
  225. package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
  226. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  227. package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
  228. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +5 -3
  229. package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
  230. package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
  231. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +4 -2
  232. package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
  233. package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
  234. package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
  235. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  236. package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
  237. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  238. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  239. package/dist/agent-src/templates/AGENTS.md +1 -1
  240. package/dist/agent-src/templates/agent-settings.md +46 -129
  241. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
  242. package/dist/agent-src/templates/command.md +2 -2
  243. package/dist/agent-src/templates/roadmaps.md +6 -1
  244. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  245. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  246. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  247. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  248. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  249. package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  250. package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  251. package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  252. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  253. package/dist/agent-src/templates/skill.md +1 -1
  254. package/dist/cli/registry.js +2 -1
  255. package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
  256. package/dist/cli-delegate/check_update_banner.js +207 -120
  257. package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
  258. package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-5GPULQBE.js} +2797 -338
  259. package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-6SRJTYJS.js} +42 -176
  260. package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
  261. package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
  262. package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
  263. package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
  264. package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
  265. package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-AED2VQGM.js} +1245 -249
  266. package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
  267. package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
  268. package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
  269. package/dist/cli-delegate/chunk-F3QDG2GT.js +2569 -0
  270. package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-G5VVIZRC.js} +3 -3
  271. package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-H76PHZBI.js} +149 -61
  272. package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
  273. package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
  274. package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
  275. package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
  276. package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-KXXWJTDO.js} +6 -11
  277. package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
  278. package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-MDPPKQCQ.js} +58 -9
  279. package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-MSUL5NYP.js} +5 -5
  280. package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
  281. package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
  282. package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
  283. package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-PWX7CKMD.js} +4 -4
  284. package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
  285. package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-T7XSJSUQ.js} +1144 -589
  286. package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
  287. package/dist/cli-delegate/chunk-WQWXGIWB.js +1779 -0
  288. package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-XQTPXKFA.js} +1 -1
  289. package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
  290. package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
  291. package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
  292. package/dist/cli-delegate/cmd_analyze_session.js +223 -43
  293. package/dist/cli-delegate/cmd_brand_status.js +3 -2
  294. package/dist/cli-delegate/cmd_conformance.js +1252 -249
  295. package/dist/cli-delegate/cmd_converge.js +3 -3
  296. package/dist/cli-delegate/cmd_doctor.js +19 -9
  297. package/dist/cli-delegate/cmd_doctor_neighbours.js +30 -0
  298. package/dist/cli-delegate/cmd_explain.js +45 -21
  299. package/dist/cli-delegate/cmd_export.js +13 -10
  300. package/dist/cli-delegate/cmd_fleet.js +3 -3
  301. package/dist/cli-delegate/cmd_git_convention.js +1851 -0
  302. package/dist/cli-delegate/cmd_handoff.js +44 -22
  303. package/dist/cli-delegate/cmd_mcp_available.js +3 -2
  304. package/dist/cli-delegate/cmd_memory_get.js +3 -1
  305. package/dist/cli-delegate/cmd_migrate.js +3 -3
  306. package/dist/cli-delegate/cmd_packs_active.js +5 -4
  307. package/dist/cli-delegate/cmd_preflight.js +6 -6
  308. package/dist/cli-delegate/cmd_prune.js +14 -11
  309. package/dist/cli-delegate/cmd_refresh.js +2 -1
  310. package/dist/cli-delegate/cmd_route_audit.js +10 -8
  311. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  312. package/dist/cli-delegate/cmd_session_recycle.js +10 -7
  313. package/dist/cli-delegate/cmd_settings_check.js +54 -7
  314. package/dist/cli-delegate/cmd_settings_get.js +18 -8
  315. package/dist/cli-delegate/cmd_settings_migrate.js +13 -10
  316. package/dist/cli-delegate/cmd_settings_set.js +4 -4
  317. package/dist/cli-delegate/cmd_sync.js +14 -11
  318. package/dist/cli-delegate/cmd_uninstall.js +15 -12
  319. package/dist/cli-delegate/cmd_update.js +7 -7
  320. package/dist/cli-delegate/cmd_upgrade.js +9 -8
  321. package/dist/cli-delegate/cmd_validate.js +15 -12
  322. package/dist/cli-delegate/cmd_versions.js +5 -5
  323. package/dist/cli-delegate/deferral_carry.js +16 -0
  324. package/dist/cli-delegate/gate_budget.js +1 -1
  325. package/dist/cli-delegate/gate_execute.js +3 -3
  326. package/dist/cli-delegate/roadmap_gates.js +6 -6
  327. package/dist/cli-delegate/update_roadmap_progress.js +1 -1
  328. package/dist/discovery/deprecation-report.md +1 -1
  329. package/dist/discovery/discovery-manifest.json +232 -141
  330. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  331. package/dist/discovery/discovery-manifest.summary.md +3 -3
  332. package/dist/discovery/dormancy-report.md +1 -1
  333. package/dist/discovery/orphan-report.md +1 -1
  334. package/dist/discovery/packs.json +26 -9
  335. package/dist/discovery/trust-report.md +3 -3
  336. package/dist/discovery/workspaces.json +7 -4
  337. package/dist/hooks/dispatch.js +5655 -6623
  338. package/dist/hooks/dispatch.sha256 +1 -1
  339. package/dist/install/claudePathsPlan.js +47 -6
  340. package/dist/install/claudeRuleRewrite.js +7 -0
  341. package/dist/install/emit_host_rules_cli.js +39 -36
  342. package/dist/install/globalRuleScope.js +87 -0
  343. package/dist/install/host_rule_ownership.js +160 -0
  344. package/dist/install/install.mjs +2336 -1249
  345. package/dist/install/installThinLayer.js +289 -0
  346. package/dist/install/installedRuleLinks.js +262 -0
  347. package/dist/install/wizard-plan.js +24 -0
  348. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  349. package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
  350. package/dist/mcp/registry-manifest.json +5 -5
  351. package/dist/mcp/server.json +2 -2
  352. package/dist/mcp/server.mjs +36504 -30986
  353. package/dist/router.json +1 -1
  354. package/dist/scripts/_lib/agent_settings.js +26 -120
  355. package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
  356. package/dist/scripts/_lib/compile_time_toggles.js +12 -21
  357. package/dist/scripts/_lib/git_convention.js +232 -0
  358. package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
  359. package/dist/scripts/_lib/installed_layer.js +704 -0
  360. package/dist/scripts/_lib/lean_projection_mode.js +218 -15
  361. package/dist/scripts/_lib/package_root.js +68 -0
  362. package/dist/scripts/_lib/rule_consequence_class.js +45 -0
  363. package/dist/scripts/_lib/rule_injection.js +67 -10
  364. package/dist/scripts/_lib/rule_law_section.js +122 -0
  365. package/dist/scripts/_lib/settings_removed_keys.js +168 -0
  366. package/dist/scripts/_lib/thin_rules.js +535 -0
  367. package/dist/scripts/_lib/windsurf_render.js +60 -0
  368. package/dist/scripts/condense.js +14 -26
  369. package/dist/scripts/project_thin_rules.js +14 -294
  370. package/dist/server/app.js +2 -1
  371. package/dist/server/gitKeysGate.js +105 -0
  372. package/dist/server/routes/settings.js +67 -8
  373. package/dist/server/routes/wizard.js +4 -0
  374. package/dist/server/schemas/settings.js +29 -81
  375. package/dist/shared/skillRanking.js +103 -16
  376. package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
  377. package/dist/ui/index.html +1 -1
  378. package/docs/MIGRATION.md +72 -1
  379. package/docs/contracts/settings-classes.md +39 -67
  380. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  381. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  382. package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  383. package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  384. package/docs/guidelines/agent-infra/layered-settings.md +13 -1
  385. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  386. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  387. package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
  388. package/docs/guidelines/php/git.md +15 -2
  389. package/package.json +1 -1
  390. package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  391. package/src/agent-src/scripts/deferral_carry.ts +339 -0
  392. package/src/agent-src/scripts/gate_budget.ts +47 -23
  393. package/src/agent-src/scripts/gate_execute.ts +12 -4
  394. package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
  395. package/src/agent-src/templates/AGENTS.md +1 -1
  396. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  397. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  398. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  399. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  400. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  401. package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  402. package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  403. package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  404. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  405. package/src/config/agent-settings.template.yml +141 -334
  406. package/src/config/agents-paths.yml +16 -0
  407. package/src/config/assurance-capability-registry.json +7 -3
  408. package/src/config/ci-local-parity.yml +3 -0
  409. package/src/config/continuity-surface.json +10 -3
  410. package/src/config/discovery/packs.yml +17 -1
  411. package/src/config/evaluator-budgets.json +23 -10
  412. package/src/config/gate-coverage.yml +138 -3
  413. package/src/config/gate-violation-baselines.json +64 -16
  414. package/src/config/gitignore-block.txt +19 -0
  415. package/src/config/hook-bundle-budget.json +25 -0
  416. package/src/config/hook-token-budget.json +6 -1
  417. package/src/config/host-instruction-limits.json +33 -0
  418. package/src/config/release-gate-locality.yml +2 -1
  419. package/src/config/routing-coverage-seed.json +67 -4
  420. package/src/config/rule-activation-census.json +7 -3
  421. package/src/config/rule-consequence-class.json +161 -0
  422. package/src/config/rule-law-ceilings.json +105 -0
  423. package/src/config/rule-obligations.json +833 -0
  424. package/src/install/claudePathsPlan.ts +46 -4
  425. package/src/install/claudeRuleRewrite.ts +10 -1
  426. package/src/install/emit_host_rules_cli.ts +43 -34
  427. package/src/install/globalRuleScope.ts +109 -0
  428. package/src/install/host_rule_ownership.ts +170 -0
  429. package/src/install/installThinLayer.ts +378 -0
  430. package/src/install/installedRuleLinks.ts +308 -0
  431. package/src/install/wizard-plan.ts +24 -0
  432. package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
  433. package/src/scripts/_cli/cmd_conformance.ts +13 -2
  434. package/src/scripts/_cli/cmd_doctor.ts +33 -81
  435. package/src/scripts/_cli/cmd_doctor_neighbours.ts +426 -0
  436. package/src/scripts/_cli/cmd_explain.ts +72 -14
  437. package/src/scripts/_cli/cmd_git_convention.ts +637 -0
  438. package/src/scripts/_cli/cmd_settings_check.ts +66 -8
  439. package/src/scripts/_cli/cmd_settings_get.ts +18 -3
  440. package/src/scripts/_cli/doctor_execution.ts +72 -1
  441. package/src/scripts/_dispatch.bash +53 -4
  442. package/src/scripts/_lib/agent_settings.ts +26 -124
  443. package/src/scripts/_lib/blocked_by_marker.ts +1 -1
  444. package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
  445. package/src/scripts/_lib/compile_time_toggles.ts +12 -21
  446. package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
  447. package/src/scripts/_lib/estate_offsets.ts +241 -0
  448. package/src/scripts/_lib/exemption_shape.ts +143 -0
  449. package/src/scripts/_lib/fnv.ts +23 -0
  450. package/src/scripts/_lib/foreign_scan.ts +106 -0
  451. package/src/scripts/_lib/git_base_ref.ts +92 -0
  452. package/src/scripts/_lib/git_convention.ts +291 -0
  453. package/src/scripts/_lib/git_convention_carrier.ts +389 -0
  454. package/src/scripts/_lib/git_convention_grammar.ts +246 -0
  455. package/src/scripts/_lib/git_convention_measure.ts +344 -0
  456. package/src/scripts/_lib/gitignore_block.ts +314 -0
  457. package/src/scripts/_lib/global_deploy_inventory.ts +106 -0
  458. package/src/scripts/_lib/graph_feeder_record.ts +437 -0
  459. package/src/scripts/_lib/hook_settings.ts +73 -0
  460. package/src/scripts/_lib/host_capability.ts +40 -19
  461. package/src/scripts/_lib/host_hook_merge.ts +165 -0
  462. package/src/scripts/_lib/installed_layer.ts +963 -0
  463. package/src/scripts/_lib/json_merge.ts +82 -0
  464. package/src/scripts/_lib/json_pointers.ts +93 -11
  465. package/src/scripts/_lib/knowledge_global.ts +14 -1
  466. package/src/scripts/_lib/lean_projection_mode.ts +275 -15
  467. package/src/scripts/_lib/machine_wake.ts +16 -3
  468. package/src/scripts/_lib/module_reach.ts +456 -0
  469. package/src/scripts/_lib/neighbour_census.ts +760 -0
  470. package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
  471. package/src/scripts/_lib/neighbour_scan.ts +122 -0
  472. package/src/scripts/_lib/neighbour_tool_use.ts +187 -0
  473. package/src/scripts/_lib/prompt_shape.ts +46 -0
  474. package/src/scripts/_lib/ratification_artifact.ts +220 -1
  475. package/src/scripts/_lib/ratification_subject.ts +92 -0
  476. package/src/scripts/_lib/release_findings_ingest.ts +15 -7
  477. package/src/scripts/_lib/release_highlights.ts +5 -0
  478. package/src/scripts/_lib/release_migration_gate.ts +19 -3
  479. package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
  480. package/src/scripts/_lib/review_coverage.ts +134 -0
  481. package/src/scripts/_lib/rule_consequence_class.ts +71 -0
  482. package/src/scripts/_lib/rule_injection.ts +130 -10
  483. package/src/scripts/_lib/rule_law_section.ts +147 -0
  484. package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
  485. package/src/scripts/_lib/rule_obligations.ts +205 -0
  486. package/src/scripts/_lib/self_repair.ts +1 -1
  487. package/src/scripts/_lib/settings_removed_keys.ts +173 -0
  488. package/src/scripts/_lib/skill_origin.ts +254 -0
  489. package/src/scripts/_lib/structured_ask.ts +64 -21
  490. package/src/scripts/_lib/test_red_state.ts +5 -0
  491. package/src/scripts/_lib/thin_rules.ts +620 -0
  492. package/src/scripts/_lib/touched_file_quality.ts +570 -0
  493. package/src/scripts/_lib/turn_end_refusals.ts +77 -2
  494. package/src/scripts/_lib/windsurf_render.ts +63 -0
  495. package/src/scripts/_lib/worker_budget.ts +1 -1
  496. package/src/scripts/adr/regenerate_index.ts +16 -1
  497. package/src/scripts/ai_council/cli_call_budget.ts +13 -5
  498. package/src/scripts/ai_council/clients.ts +26 -57
  499. package/src/scripts/ai_council/config.ts +8 -8
  500. package/src/scripts/ai_council/modification_review.ts +100 -0
  501. package/src/scripts/ai_council/modification_review_questions.ts +90 -0
  502. package/src/scripts/ai_council/orchestrator.ts +5 -5
  503. package/src/scripts/ai_council/spend_gate.ts +18 -7
  504. package/src/scripts/ai_council/vendor_defaults.ts +45 -0
  505. package/src/scripts/ai_team/config.ts +11 -16
  506. package/src/scripts/audit_skill_overlap.ts +261 -0
  507. package/src/scripts/audit_user_type_axis.ts +20 -8
  508. package/src/scripts/before_complete_hook.ts +243 -12
  509. package/src/scripts/bench_ab_clone.ts +1 -2
  510. package/src/scripts/bench_concern_spawn_path.ts +129 -0
  511. package/src/scripts/bench_graph_feeder_latency.ts +584 -0
  512. package/src/scripts/bench_touched_file_quality.ts +238 -0
  513. package/src/scripts/check_agent_artifact_location.ts +36 -0
  514. package/src/scripts/check_branch_freshness.ts +147 -24
  515. package/src/scripts/check_enforcement_coverage.ts +130 -0
  516. package/src/scripts/check_enforcement_matrix.ts +377 -20
  517. package/src/scripts/check_estate_count.ts +130 -153
  518. package/src/scripts/check_evaluator_budgets.ts +4 -0
  519. package/src/scripts/check_finding_dispositions.ts +196 -21
  520. package/src/scripts/check_gate_coverage.ts +4 -3
  521. package/src/scripts/check_gate_reachability.ts +48 -1
  522. package/src/scripts/check_generator_sync.ts +48 -0
  523. package/src/scripts/check_hook_bundle_composition.ts +477 -0
  524. package/src/scripts/check_kernel_edit_ratified.ts +132 -14
  525. package/src/scripts/check_memory.ts +7 -1
  526. package/src/scripts/check_pack_size.ts +1 -1
  527. package/src/scripts/check_release_highlights.ts +10 -0
  528. package/src/scripts/check_release_manifest_content.ts +189 -0
  529. package/src/scripts/check_release_pr_shape.ts +38 -15
  530. package/src/scripts/check_standing_rule_delivery.ts +129 -13
  531. package/src/scripts/check_suppression_hygiene.ts +2 -5
  532. package/src/scripts/check_verify_expectation_delta.ts +521 -0
  533. package/src/scripts/ci_settle.ts +42 -5
  534. package/src/scripts/classify_merge_risk.ts +320 -0
  535. package/src/scripts/closure_scan.ts +91 -1
  536. package/src/scripts/code_graph/detect.ts +127 -7
  537. package/src/scripts/code_graph/foreign.ts +194 -0
  538. package/src/scripts/code_graph/query.ts +217 -4
  539. package/src/scripts/code_graph/types.ts +26 -2
  540. package/src/scripts/code_graph/validate.ts +3 -1
  541. package/src/scripts/code_graph/verbs.ts +103 -0
  542. package/src/scripts/command_suggester/settings.ts +8 -108
  543. package/src/scripts/command_suggester/types.ts +4 -5
  544. package/src/scripts/compile_hook_manifest.ts +33 -1
  545. package/src/scripts/condense.ts +14 -27
  546. package/src/scripts/consumer_matrix.ts +102 -0
  547. package/src/scripts/context_hygiene_hook.ts +13 -23
  548. package/src/scripts/cost/preflight.mjs +12 -1
  549. package/src/scripts/council_cli.ts +7 -7
  550. package/src/scripts/dispatch_r2_reviewer.ts +24 -11
  551. package/src/scripts/estate_exemption_shape.ts +202 -0
  552. package/src/scripts/explain_run.ts +8 -13
  553. package/src/scripts/generate_git_convention_grammar.ts +127 -0
  554. package/src/scripts/generate_host_cost_table.ts +21 -4
  555. package/src/scripts/handoff_context_hook.ts +86 -37
  556. package/src/scripts/hook_manifest.json +1 -1
  557. package/src/scripts/hook_manifest.yaml +175 -15
  558. package/src/scripts/hooks/block_config_weakening.ts +115 -7
  559. package/src/scripts/hooks/block_plumbing_writes.ts +37 -5
  560. package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
  561. package/src/scripts/hooks/concern_failure_policy.ts +280 -0
  562. package/src/scripts/hooks/concern_registry.ts +2 -0
  563. package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
  564. package/src/scripts/hooks/dispatch_hook.ts +52 -52
  565. package/src/scripts/hooks/evidence_independence.ts +12 -4
  566. package/src/scripts/hooks/exit_codes.ts +2 -1
  567. package/src/scripts/hooks/host_lowering.json +1 -1
  568. package/src/scripts/hooks/host_lowering.ts +19 -1
  569. package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
  570. package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
  571. package/src/scripts/hooks/payload_stub.ts +10 -1
  572. package/src/scripts/hooks/push_settle_hook.ts +4 -3
  573. package/src/scripts/hooks/rule_inject_hook.ts +795 -60
  574. package/src/scripts/hooks/state_io.ts +8 -4
  575. package/src/scripts/hooks/table_fingerprint.ts +21 -0
  576. package/src/scripts/hooks/telemetry_usage_hook.ts +24 -7
  577. package/src/scripts/hooks/turn_end_gate_hook.ts +85 -0
  578. package/src/scripts/hooks_status.ts +112 -0
  579. package/src/scripts/injection_scan_hook.ts +7 -0
  580. package/src/scripts/install-hooks.sh +42 -14
  581. package/src/scripts/install.ts +78 -215
  582. package/src/scripts/installed_layer_report.ts +103 -0
  583. package/src/scripts/language_mirror_hook.ts +15 -6
  584. package/src/scripts/learning_sidecar.ts +119 -8
  585. package/src/scripts/lint_blocker_citations.ts +198 -0
  586. package/src/scripts/lint_evidence_artifacts.ts +9 -0
  587. package/src/scripts/lint_hook_concern_budget.ts +10 -21
  588. package/src/scripts/lint_hook_manifest.ts +53 -0
  589. package/src/scripts/lint_major_migration_sections.ts +156 -26
  590. package/src/scripts/lint_pack_boundaries.ts +465 -29
  591. package/src/scripts/lint_roadmap_blockers.ts +282 -29
  592. package/src/scripts/lint_roadmap_complexity.ts +4 -2
  593. package/src/scripts/lint_rule_law_section.ts +647 -0
  594. package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
  595. package/src/scripts/lint_settings_classes.ts +1 -1
  596. package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
  597. package/src/scripts/lint_workflow_security.ts +173 -6
  598. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
  599. package/src/scripts/mcp_server/graph_tools.ts +72 -3
  600. package/src/scripts/measure_routing_signal.ts +54 -16
  601. package/src/scripts/measure_skill_ranker_baseline.ts +221 -8
  602. package/src/scripts/memory_learn_hook.ts +91 -6
  603. package/src/scripts/model_rule_injection.ts +55 -8
  604. package/src/scripts/onboarding_gate_hook.ts +7 -6
  605. package/src/scripts/print_required_checks.ts +15 -3
  606. package/src/scripts/probe_host_compliance.ts +33 -5
  607. package/src/scripts/probe_turnaround.ts +183 -3
  608. package/src/scripts/project_thin_rules.ts +34 -327
  609. package/src/scripts/ratification_header.ts +77 -0
  610. package/src/scripts/refusal_envelope.ts +138 -0
  611. package/src/scripts/release_publication.ts +29 -3
  612. package/src/scripts/report_dispatch_import_closure.ts +76 -0
  613. package/src/scripts/report_evidence_temperature.ts +657 -0
  614. package/src/scripts/report_installed_rule_links.ts +274 -0
  615. package/src/scripts/report_label_agreement.ts +233 -0
  616. package/src/scripts/report_module_reach.ts +212 -0
  617. package/src/scripts/report_obligation_mechanism.ts +228 -0
  618. package/src/scripts/report_parked_blockers.ts +222 -0
  619. package/src/scripts/report_required_checks_drift.ts +196 -0
  620. package/src/scripts/report_single_token_triggers.ts +277 -0
  621. package/src/scripts/report_skill_ranker_confusion.ts +543 -0
  622. package/src/scripts/report_standing_payload_by_host.ts +188 -15
  623. package/src/scripts/report_verification_record_coverage.ts +306 -0
  624. package/src/scripts/routing_doctor.ts +2 -2
  625. package/src/scripts/rule_activation_census.ts +5 -2
  626. package/src/scripts/rule_trigger_eval.ts +9 -9
  627. package/src/scripts/schemas/agent-settings.schema.json +17 -31
  628. package/src/scripts/schemas/command.schema.json +1 -1
  629. package/src/scripts/schemas/review-findings.schema.json +3 -2
  630. package/src/scripts/schemas/rule.schema.json +5 -0
  631. package/src/scripts/schemas/skill.schema.json +1 -1
  632. package/src/scripts/self_review_gate.ts +101 -9
  633. package/src/scripts/skill_tools/score_skill_relevance.ts +314 -40
  634. package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
  635. package/src/scripts/sync_gitignore.ts +29 -235
  636. package/src/scripts/sync_pr_branch.ts +403 -132
  637. package/src/scripts/trigger_eval_grandfather.json +0 -21
  638. package/src/server/schemas/settings.ts +42 -176
  639. package/src/shared/skillRanking.ts +169 -14
  640. package/dist/cli-delegate/chunk-5R7HOLAF.js +0 -99
  641. package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
  642. package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
  643. package/src/scripts/_lib/config_chain.ts +0 -477
  644. package/src/scripts/_lib/conformance_report.ts +0 -403
  645. package/src/scripts/_lib/eval_discrimination.ts +0 -95
  646. package/src/scripts/_lib/evaluator_promotion.ts +0 -225
  647. package/src/scripts/_lib/file_slicer.ts +0 -117
  648. package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
  649. package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
  650. package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
  651. package/src/scripts/_lib/role_split.ts +0 -338
@@ -0,0 +1,584 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * What the graph feeder costs the stop slot (`road-to-a-graph-that-feeds-the-gate`
4
+ * step 3.5).
5
+ *
6
+ * `_lib/graph_feeder_record.ts` withdrew its "costs nothing" claim and left the
7
+ * latency unmeasured. It matters because the feeder runs inside the blocking
8
+ * `turn-end-gate` concern: a host that timed the stop hook out would discard F's
9
+ * refusal, so a slow shadow arm weakens the gate it is meant to feed.
10
+ *
11
+ * WHAT IS MEASURED. The hook's own `main()`, in-process, with the stdin override
12
+ * the in-process dispatcher uses — the route a host actually takes, so a spawn
13
+ * or `tsx` start-up cost does not drown the difference. Two arms over the SAME
14
+ * generated repository and the SAME turn (an absolute-path edit to a production
15
+ * file, no test touched, a completion claim, so detector F fires):
16
+ *
17
+ * with — a native graph exists and the edit is uncommitted, so the feeder
18
+ * takes its full path: `git` freshness probes, a graph open, an
19
+ * `untested` walk, a row append.
20
+ * without — the identical tree with no graph cache, so the feeder stops at
21
+ * `absent`. This is the cost a consumer who never builds a graph
22
+ * pays, and the baseline the feeder's increment is read against.
23
+ *
24
+ * Arms are INTERLEAVED, one call each per round, and the rounds cycle through
25
+ * all six ORDERS of the three calls: interleaving spreads slow drift across the
26
+ * arms, and the full permutation cycle balances the position of every call and
27
+ * its direct predecessor WITHIN a round (GC after the heavier arm, cache
28
+ * warmth) — exactly so when the round count is a multiple of six. Across a round
29
+ * boundary it does not: the first call of a round follows the previous round's
30
+ * last call, and those six transitions are unbalanced (two are a call following
31
+ * itself). A third
32
+ * reading, inside the same rotation, times the feeder's own work (`graphState` + `graphUntestedVerdict`) in isolation on the
33
+ * `with` tree, because the difference of two noisy totals is a weaker number
34
+ * than a direct one.
35
+ *
36
+ * WHAT IT DOES NOT CLAIM. One machine, one generated repository shape. The size
37
+ * is a flag rather than a constant so a reader can re-take the reading at the
38
+ * scale they care about; the published page names the machine and the flags it
39
+ * was taken with. Not a gate: it prints and exits 0 on any completed run.
40
+ *
41
+ * `--repo P --edit F` takes the third reading only, over an EXISTING repository
42
+ * and its own graph: no hook call and no feeder row written, but NOT read-only.
43
+ * `loadGraph` re-emits the repository's SQLite twin
44
+ * (`sqliteTwinPath` of its graph cache) whenever no valid one exists,
45
+ * and the unbilled warm-up round absorbs that write. A generated tree
46
+ * prices the walk; it does not price opening a real index, whose load time grows
47
+ * with the graph and is the larger term on a repository of any size.
48
+ *
49
+ * Usage:
50
+ * ./scripts-run src/scripts/bench_graph_feeder_latency [--runs N] [--files N]
51
+ * [--format text|json]
52
+ * ./scripts-run src/scripts/bench_graph_feeder_latency --repo P --edit F [--runs N]
53
+ * ./scripts-run src/scripts/bench_graph_feeder_latency --load-split GRAPH_JSON [--runs N]
54
+ *
55
+ * `--load-split` decomposes the load term `--repo` reports (`benchLoadSplit`)
56
+ * over a scratch copy of the graph file, so it writes nothing to the repository.
57
+ */
58
+ import { execFileSync } from 'node:child_process';
59
+ import * as fs from 'node:fs';
60
+ import * as os from 'node:os';
61
+ import * as path from 'node:path';
62
+ import { performance } from 'node:perf_hooks';
63
+ import { pathToFileURL } from 'node:url';
64
+
65
+ import { gitEnv } from './_lib/git_env.js';
66
+ import { graphUntestedVerdict } from './_lib/graph_feeder_record.js';
67
+ import { LexicalIndex } from './_lib/lexical_index.js';
68
+ import { buildFromRepo } from './code_graph/build.js';
69
+ import { graphState, NATIVE_CACHE_REL } from './code_graph/detect.js';
70
+ import { loadGraph } from './code_graph/query.js';
71
+ import { emitSqliteTwin, sqliteTwinPath } from './code_graph/sqlite_store.js';
72
+ import type { CodeEdge, CodeGraph } from './code_graph/types.js';
73
+ import { validateGraph } from './code_graph/validate.js';
74
+ import { clearHookStdinOverride, setHookStdinOverride } from './hooks/hook_stdin.js';
75
+ import { main as turnEndGateMain } from './hooks/turn_end_gate_hook.js';
76
+
77
+ export interface Distribution {
78
+ n: number;
79
+ p50: number;
80
+ p95: number;
81
+ max: number;
82
+ }
83
+
84
+ export interface LatencyReport {
85
+ runs: number;
86
+ files: number;
87
+ graphState: string;
88
+ /** The `without` tree's state — `absent`, or that arm is not the no-feeder baseline. */
89
+ graphStateWithout: string;
90
+ /** Exit codes seen per arm — a shadow arm must not move them. */
91
+ exitCodes: { with: number[]; without: number[] };
92
+ with: Distribution;
93
+ without: Distribution;
94
+ /** `with.p50 - without.p50`, and the same for p95. */
95
+ delta: { p50: number; p95: number };
96
+ /** The feeder's own work, timed directly on the `with` tree. */
97
+ feederOnly: Distribution;
98
+ /**
99
+ * Every verdict the timed feeder calls returned. `graphUntestedVerdict`
100
+ * turns any throw into `null`, so a broken graph load would otherwise be
101
+ * timed as if it were the real walk.
102
+ */
103
+ feederVerdicts: (string | null)[];
104
+ node: string;
105
+ platform: string;
106
+ cpu: string;
107
+ }
108
+
109
+ /** Nearest-rank percentile over an ascending array. */
110
+ export function percentile(sorted: readonly number[], p: number): number {
111
+ if (sorted.length === 0) return Number.NaN;
112
+ const rank = Math.ceil((p / 100) * sorted.length);
113
+ return sorted[Math.min(sorted.length, Math.max(1, rank)) - 1] as number;
114
+ }
115
+
116
+ export function distribution(samples: readonly number[]): Distribution {
117
+ const s = [...samples].sort((a, b) => a - b);
118
+ const r = (x: number): number => Math.round(x * 100) / 100;
119
+ return { n: s.length, p50: r(percentile(s, 50)), p95: r(percentile(s, 95)), max: r(s[s.length - 1] ?? Number.NaN) };
120
+ }
121
+
122
+ function git(dir: string, args: string[]): void {
123
+ // An inherited GIT_DIR (every git hook exports one) overrides `-C`, which
124
+ // would commit the fixture onto the host repository.
125
+ const env = {
126
+ ...gitEnv(),
127
+ GIT_AUTHOR_NAME: 'bench',
128
+ GIT_AUTHOR_EMAIL: 'bench@example.com',
129
+ GIT_COMMITTER_NAME: 'bench',
130
+ GIT_COMMITTER_EMAIL: 'bench@example.com',
131
+ };
132
+ execFileSync('git', ['-C', dir, ...args], { env, stdio: 'ignore' });
133
+ }
134
+
135
+ /**
136
+ * A committed repository of `files` production modules chained by imports, one
137
+ * test file covering the first module only, and the edited `src/service.ts`
138
+ * left uncommitted — the shape a real stop sees mid-session.
139
+ */
140
+ export async function makeFixture(root: string, files: number, withGraph: boolean): Promise<string> {
141
+ const dir = fs.realpathSync(fs.mkdtempSync(path.join(root, withGraph ? 'with-' : 'without-')));
142
+ fs.mkdirSync(path.join(dir, 'src'));
143
+ fs.mkdirSync(path.join(dir, 'tests'));
144
+ fs.writeFileSync(path.join(dir, 'src', 'service.ts'), 'export function handle(x: string): string {\n return x;\n}\n');
145
+ for (let i = 0; i < files; i++) {
146
+ const prev = i === 0 ? './service.js' : `./mod${i - 1}.js`;
147
+ const prevFn = i === 0 ? 'handle' : `run${i - 1}`;
148
+ fs.writeFileSync(
149
+ path.join(dir, 'src', `mod${i}.ts`),
150
+ `import { ${prevFn} } from '${prev}';\n\nexport function run${i}(x: string): string {\n return ${prevFn}(x) + '${i}';\n}\n`,
151
+ );
152
+ }
153
+ fs.writeFileSync(
154
+ path.join(dir, 'tests', 'mod0.test.ts'),
155
+ // The specifier is assembled so `prepack-check`, which scans shipped
156
+ // sources for relative imports, does not read fixture text as one.
157
+ `import { run0 } from '${['..', 'src', 'mod0.js'].join('/')}';\n\nexport function check(): boolean {\n return run0('a') === 'a0';\n}\n`,
158
+ );
159
+ git(dir, ['init', '-q']);
160
+ git(dir, ['add', '-A']);
161
+ git(dir, ['commit', '-q', '-m', 'fixture']);
162
+ if (withGraph) await buildFromRepo(dir, path.join(dir, NATIVE_CACHE_REL));
163
+ fs.writeFileSync(path.join(dir, 'src', 'service.ts'), 'export function handle(x: string): string {\n return x.trim();\n}\n');
164
+ return dir;
165
+ }
166
+
167
+ function writeTranscript(dir: string, home: string, tag: string): string {
168
+ const file = path.join(home, `transcript-${tag}.jsonl`);
169
+ const lines = [
170
+ { type: 'user', message: { content: 'mach das fertig' } },
171
+ {
172
+ type: 'assistant',
173
+ message: {
174
+ content: [{ type: 'tool_use', name: 'Edit', input: { file_path: path.join(dir, 'src', 'service.ts') } }],
175
+ },
176
+ },
177
+ { type: 'assistant', message: { content: [{ type: 'text', text: 'Fertig. Der Service trimmt jetzt.' }] } },
178
+ ];
179
+ fs.writeFileSync(file, lines.map((l) => JSON.stringify(l)).join('\n') + '\n');
180
+ return file;
181
+ }
182
+
183
+ /** One in-process stop. A fresh session id per call keeps every call on the live path. */
184
+ function timeStop(dir: string, transcriptPath: string, session: string): { ms: number; rc: number } {
185
+ setHookStdinOverride(
186
+ JSON.stringify({
187
+ schema_version: 1,
188
+ platform: 'claude',
189
+ event: 'stop',
190
+ native_event: 'Stop',
191
+ session_id: session,
192
+ workspace_root: dir,
193
+ payload: { transcript_path: transcriptPath },
194
+ settings: {},
195
+ }),
196
+ );
197
+ const write = process.stderr.write.bind(process.stderr);
198
+ process.stderr.write = (() => true) as typeof process.stderr.write;
199
+ const t0 = performance.now();
200
+ try {
201
+ const rc = turnEndGateMain();
202
+ return { ms: performance.now() - t0, rc };
203
+ } finally {
204
+ process.stderr.write = write;
205
+ clearHookStdinOverride();
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Every order of the three calls. Cycling through all six puts each call first
211
+ * equally often AND, within a round, gives every call each other call as its
212
+ * direct predecessor equally often; rotating the start of one fixed cycle only
213
+ * does the former. The round-boundary transitions are not balanced.
214
+ */
215
+ export const ORDERS: readonly (readonly number[])[] = [
216
+ [0, 1, 2],
217
+ [0, 2, 1],
218
+ [1, 0, 2],
219
+ [1, 2, 0],
220
+ [2, 0, 1],
221
+ [2, 1, 0],
222
+ ];
223
+
224
+ /** Assigning `undefined` to `process.env` stores the string "undefined"; an unset variable must be deleted. */
225
+ function restoreEnv(key: string, value: string | undefined): void {
226
+ if (value === undefined) delete process.env[key];
227
+ else process.env[key] = value;
228
+ }
229
+
230
+ export async function bench(opts: { runs?: number; files?: number }): Promise<LatencyReport> {
231
+ const runs = Math.max(1, opts.runs ?? 30);
232
+ const files = Math.max(1, opts.files ?? 200);
233
+ const root = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'graph-feeder-latency-')));
234
+ const home = path.join(root, 'home');
235
+ fs.mkdirSync(home);
236
+ const savedEnv = { HOME: process.env.HOME, USERPROFILE: process.env.USERPROFILE, CFG: process.env.EVENT4U_CONFIG_HOME };
237
+ process.env.HOME = home;
238
+ process.env.USERPROFILE = home;
239
+ process.env.EVENT4U_CONFIG_HOME = path.join(home, '.event4u', 'agent-config');
240
+ try {
241
+ const withDir = await makeFixture(root, files, true);
242
+ const withoutDir = await makeFixture(root, files, false);
243
+ const tWith = writeTranscript(withDir, home, 'with');
244
+ const tWithout = writeTranscript(withoutDir, home, 'without');
245
+ const state = graphState(withDir);
246
+ const stateWithout = graphState(withoutDir);
247
+
248
+ const edit = [path.join(withDir, 'src', 'service.ts')];
249
+ const feederCall = (): { ms: number; verdict: string | null } => {
250
+ const t0 = performance.now();
251
+ const v = graphUntestedVerdict(withDir, graphState(withDir), edit).verdict;
252
+ return { ms: performance.now() - t0, verdict: v };
253
+ };
254
+
255
+ // Warm every path once so module-level initialisation is not billed to round one.
256
+ timeStop(withDir, tWith, 'warm-with');
257
+ timeStop(withoutDir, tWithout, 'warm-without');
258
+ feederCall();
259
+
260
+ const a: number[] = [];
261
+ const b: number[] = [];
262
+ const feeder: number[] = [];
263
+ const feederVerdicts: (string | null)[] = [];
264
+ const exitCodes = { with: [] as number[], without: [] as number[] };
265
+ for (let i = 0; i < runs; i++) {
266
+ const calls = [
267
+ (): void => {
268
+ const x = timeStop(withDir, tWith, `with-${i}`);
269
+ a.push(x.ms);
270
+ if (!exitCodes.with.includes(x.rc)) exitCodes.with.push(x.rc);
271
+ },
272
+ (): void => {
273
+ const y = timeStop(withoutDir, tWithout, `without-${i}`);
274
+ b.push(y.ms);
275
+ if (!exitCodes.without.includes(y.rc)) exitCodes.without.push(y.rc);
276
+ },
277
+ (): void => {
278
+ const f = feederCall();
279
+ feeder.push(f.ms);
280
+ if (!feederVerdicts.includes(f.verdict)) feederVerdicts.push(f.verdict);
281
+ },
282
+ ];
283
+ for (const k of ORDERS[i % ORDERS.length] ?? []) calls[k]?.();
284
+ }
285
+
286
+ const w = distribution(a);
287
+ const wo = distribution(b);
288
+ const round = (x: number): number => Math.round(x * 100) / 100;
289
+ return {
290
+ runs,
291
+ files,
292
+ graphState: state,
293
+ graphStateWithout: stateWithout,
294
+ exitCodes,
295
+ with: w,
296
+ without: wo,
297
+ delta: { p50: round(w.p50 - wo.p50), p95: round(w.p95 - wo.p95) },
298
+ feederOnly: distribution(feeder),
299
+ feederVerdicts,
300
+ node: process.version,
301
+ platform: `${os.platform()} ${os.release()} ${os.arch()}`,
302
+ cpu: `${os.cpus()[0]?.model ?? 'unknown'} x${os.cpus().length}`,
303
+ };
304
+ } finally {
305
+ restoreEnv('HOME', savedEnv.HOME);
306
+ restoreEnv('USERPROFILE', savedEnv.USERPROFILE);
307
+ restoreEnv('EVENT4U_CONFIG_HOME', savedEnv.CFG);
308
+ fs.rmSync(root, { recursive: true, force: true });
309
+ }
310
+ }
311
+
312
+ export interface RepoReport {
313
+ runs: number;
314
+ repo: string;
315
+ edit: string;
316
+ graphState: string;
317
+ /** Every distinct verdict across the billed rounds — a swallowed load failure reads `null`. */
318
+ verdicts: (string | null)[];
319
+ feederOnly: Distribution;
320
+ }
321
+
322
+ /**
323
+ * The feeder's work alone over an existing repository's graph. Writes no feeder
324
+ * row and calls no hook, but it is NOT read-only: `graphUntestedVerdict` ->
325
+ * `loadGraph` re-emits the graph cache's SQLite twin (`sqliteTwinPath`) into the
326
+ * measured repository whenever no valid twin exists, and the unbilled warm-up
327
+ * round absorbs that write, so billed rounds price whatever path the twin left
328
+ * (twin-backed when the emit succeeded, the JSON path when it failed).
329
+ */
330
+ export function benchRepo(opts: { repo: string; edit: string; runs?: number | undefined }): RepoReport {
331
+ const runs = Math.max(1, opts.runs ?? 30);
332
+ const repo = path.resolve(opts.repo);
333
+ const edit = [path.resolve(repo, opts.edit)];
334
+ let state = graphState(repo);
335
+ const verdicts: (string | null)[] = [];
336
+ const samples: number[] = [];
337
+ for (let i = 0; i <= runs; i++) {
338
+ const t0 = performance.now();
339
+ state = graphState(repo);
340
+ const verdict = graphUntestedVerdict(repo, state, edit).verdict;
341
+ // Round zero is the warm-up and is not billed.
342
+ if (i > 0) {
343
+ samples.push(performance.now() - t0);
344
+ if (!verdicts.includes(verdict)) verdicts.push(verdict);
345
+ }
346
+ }
347
+ return { runs, repo: path.basename(repo), edit: opts.edit, graphState: state, verdicts, feederOnly: distribution(samples) };
348
+ }
349
+
350
+ export interface LoadSplitReport {
351
+ runs: number;
352
+ graph: string;
353
+ bytes: number;
354
+ nodes: number;
355
+ edges: number;
356
+ /** `loadGraph`'s JSON path, stage by stage, each a distribution over the billed rounds. */
357
+ stages: { read: Distribution; parse: Distribution; validate: Distribution; twinEmit: Distribution; maps: Distribution; lexical: Distribution };
358
+ /** Billed rounds in which `emitSqliteTwin` returned true; 0 means every stop pays the attempt again. */
359
+ twinWritten: number;
360
+ /** The whole `loadGraph` over the same copy with its twin removed first: the term the stages decompose. */
361
+ loadGraph: Distribution;
362
+ }
363
+
364
+ /**
365
+ * Decompose `loadGraph`'s JSON path (`code_graph/query.ts`) over a COPY of a
366
+ * graph cache, so the measured repository is never written. Each round removes
367
+ * the copy's twin first, then times the stages `loadGraph` runs when no valid
368
+ * twin exists: read, `JSON.parse`, `validateGraph`, `emitSqliteTwin`, and the
369
+ * node and edge maps, and the lexical index. The stages re-implement that sequence
370
+ * rather than instrument it, so the whole `loadGraph` is timed in the same round
371
+ * as the check that the split accounts for the term it names. Foreign-graph
372
+ * adaptation is not timed: a native cache never takes it.
373
+ */
374
+ export function benchLoadSplit(opts: { graph: string; runs?: number | undefined }): LoadSplitReport {
375
+ const runs = Math.max(1, opts.runs ?? 5);
376
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'feeder-load-split-'));
377
+ const copy = path.join(root, 'code-graph-v1.json');
378
+ fs.copyFileSync(opts.graph, copy);
379
+ const twin = sqliteTwinPath(copy);
380
+ const read: number[] = [];
381
+ const parse: number[] = [];
382
+ const validate: number[] = [];
383
+ const twinEmit: number[] = [];
384
+ const maps: number[] = [];
385
+ const lexical: number[] = [];
386
+ const whole: number[] = [];
387
+ let twinWritten = 0;
388
+ let nodes = 0;
389
+ let edges = 0;
390
+ const push = (m: Map<string, CodeEdge[]>, k: string, e: CodeEdge): void => {
391
+ const arr = m.get(k);
392
+ if (arr) arr.push(e);
393
+ else m.set(k, [e]);
394
+ };
395
+ try {
396
+ for (let i = 0; i <= runs; i++) {
397
+ fs.rmSync(twin, { force: true });
398
+ const t0 = performance.now();
399
+ const raw = fs.readFileSync(copy, 'utf-8');
400
+ const t1 = performance.now();
401
+ const parsed = JSON.parse(raw) as unknown;
402
+ const t2 = performance.now();
403
+ const v = validateGraph(parsed);
404
+ if (!v.ok) throw new Error(`invalid graph at ${opts.graph}: ${v.errors.slice(0, 3).join('; ')}`);
405
+ const graph = parsed as CodeGraph;
406
+ const t3 = performance.now();
407
+ const wrote = emitSqliteTwin(graph, raw, copy);
408
+ const t4 = performance.now();
409
+ const byId = new Map(graph.nodes.map((n) => [n.id, n]));
410
+ const outM = new Map<string, CodeEdge[]>();
411
+ const inM = new Map<string, CodeEdge[]>();
412
+ for (const e of graph.edges) {
413
+ push(outM, e.source, e);
414
+ push(inM, e.target, e);
415
+ }
416
+ const t45 = performance.now();
417
+ new LexicalIndex(graph.nodes.map((n) => ({ id: n.id, text: `${n.label} ${n.id}` })));
418
+ const t5 = performance.now();
419
+ fs.rmSync(twin, { force: true });
420
+ const t6 = performance.now();
421
+ loadGraph(copy).close();
422
+ const t7 = performance.now();
423
+ void byId;
424
+ nodes = graph.nodes.length;
425
+ edges = graph.edges.length;
426
+ // Round zero is the warm-up and is not billed.
427
+ if (i === 0) continue;
428
+ read.push(t1 - t0);
429
+ parse.push(t2 - t1);
430
+ validate.push(t3 - t2);
431
+ twinEmit.push(t4 - t3);
432
+ maps.push(t45 - t4);
433
+ lexical.push(t5 - t45);
434
+ whole.push(t7 - t6);
435
+ if (wrote) twinWritten++;
436
+ }
437
+ } finally {
438
+ fs.rmSync(root, { recursive: true, force: true });
439
+ }
440
+ return {
441
+ runs,
442
+ graph: path.basename(opts.graph),
443
+ bytes: fs.statSync(opts.graph).size,
444
+ nodes,
445
+ edges,
446
+ stages: {
447
+ read: distribution(read),
448
+ parse: distribution(parse),
449
+ validate: distribution(validate),
450
+ twinEmit: distribution(twinEmit),
451
+ maps: distribution(maps),
452
+ lexical: distribution(lexical),
453
+ },
454
+ twinWritten,
455
+ loadGraph: distribution(whole),
456
+ };
457
+ }
458
+
459
+ function renderLoadSplit(r: LoadSplitReport): string {
460
+ const row = (name: string, d: Distribution): string => `| ${name} | ${d.n} | ${d.p50} | ${d.p95} | ${d.max} |`;
461
+ return [
462
+ `loadGraph JSON path over a copy of ${r.graph}: ${r.bytes} bytes, ${r.nodes} nodes, ${r.edges} edges, ${r.runs} billed rounds`,
463
+ '',
464
+ '| stage | n | p50 ms | p95 ms | max ms |',
465
+ '|---|---|---|---|---|',
466
+ row('read file', r.stages.read),
467
+ row('JSON.parse', r.stages.parse),
468
+ row('validateGraph', r.stages.validate),
469
+ row('emitSqliteTwin', r.stages.twinEmit),
470
+ row('node + edge maps', r.stages.maps),
471
+ row('lexical index', r.stages.lexical),
472
+ row('whole loadGraph', r.loadGraph),
473
+ '',
474
+ `twin written in ${r.twinWritten} of ${r.runs} rounds`,
475
+ ].join('\n');
476
+ }
477
+
478
+ function renderRepo(r: RepoReport): string {
479
+ const d = r.feederOnly;
480
+ return [
481
+ `graph-feeder work over ${r.repo} — edit ${r.edit}, graph state ${r.graphState}, verdicts ${JSON.stringify(r.verdicts)}`,
482
+ `n ${d.n} · p50 ${d.p50} ms · p95 ${d.p95} ms · max ${d.max} ms`,
483
+ // A stop follows an edit, so the realistic state is `edited`; on a clean
484
+ // tree the git probes answer differently and the reading prices that.
485
+ ...(r.graphState === 'edited' ? [] : [`note: graph state is ${r.graphState}, not edited — a stop normally follows an uncommitted edit`]),
486
+ ].join('\n');
487
+ }
488
+
489
+ function render(r: LatencyReport): string {
490
+ const row = (name: string, d: Distribution): string =>
491
+ `| ${name} | ${d.n} | ${d.p50} | ${d.p95} | ${d.max} |`;
492
+ return [
493
+ `graph-feeder latency — ${r.runs} rounds, ${r.files} generated modules, graph state ${r.graphState} (without arm: ${r.graphStateWithout})`,
494
+ `machine: ${r.cpu}, ${r.platform}, node ${r.node}`,
495
+ '',
496
+ '| arm | n | p50 ms | p95 ms | max ms |',
497
+ '|---|---|---|---|---|',
498
+ row('stop hook, with feeder', r.with),
499
+ row('stop hook, without feeder', r.without),
500
+ row('feeder work alone', r.feederOnly),
501
+ '',
502
+ `delta: p50 ${r.delta.p50} ms, p95 ${r.delta.p95} ms`,
503
+ `exit codes: with ${JSON.stringify(r.exitCodes.with)}, without ${JSON.stringify(r.exitCodes.without)}`,
504
+ `feeder verdicts: ${JSON.stringify(r.feederVerdicts)}`,
505
+ ].join('\n');
506
+ }
507
+
508
+ export interface Args {
509
+ runs?: number;
510
+ files?: number;
511
+ repo?: string;
512
+ edit?: string;
513
+ loadSplit?: string;
514
+ format: 'text' | 'json';
515
+ }
516
+
517
+ export function parseArgs(argv: readonly string[]): Args | null {
518
+ const out: Args = { format: 'text' };
519
+ for (let i = 0; i < argv.length; i++) {
520
+ const a = argv[i];
521
+ const v = argv[i + 1];
522
+ if (a === '--runs' || a === '--files') {
523
+ const n = Number(v);
524
+ if (!Number.isInteger(n) || n < 1) return null;
525
+ if (a === '--runs') out.runs = n;
526
+ else out.files = n;
527
+ i++;
528
+ } else if ((a === '--repo' || a === '--edit') && v !== undefined && v !== '' && !v.startsWith('--')) {
529
+ if (a === '--repo') out.repo = v;
530
+ else out.edit = v;
531
+ i++;
532
+ } else if (a === '--load-split' && v !== undefined && v !== '' && !v.startsWith('--')) {
533
+ out.loadSplit = v;
534
+ i++;
535
+ } else if (a === '--format' && (v === 'text' || v === 'json')) {
536
+ out.format = v;
537
+ i++;
538
+ } else {
539
+ return null;
540
+ }
541
+ }
542
+ // Both or neither: a repository with no edit to price is not a reading.
543
+ if ((out.repo === undefined) !== (out.edit === undefined)) return null;
544
+ // `--files` sizes the generated fixture, which `--repo` mode never builds.
545
+ if (out.repo !== undefined && out.files !== undefined) return null;
546
+ // `--load-split` reads one graph file; it neither builds a fixture nor prices an edit.
547
+ if (out.loadSplit !== undefined && (out.repo !== undefined || out.files !== undefined)) return null;
548
+ return out;
549
+ }
550
+
551
+ async function cli(): Promise<number> {
552
+ const args = parseArgs(process.argv.slice(2));
553
+ if (args === null) {
554
+ process.stderr.write(
555
+ 'usage: bench_graph_feeder_latency [--runs N] [--files N] [--format text|json]\n' +
556
+ ' bench_graph_feeder_latency --repo P --edit F [--runs N] [--format text|json]\n' +
557
+ ' bench_graph_feeder_latency --load-split GRAPH_JSON [--runs N] [--format text|json]\n',
558
+ );
559
+ return 2;
560
+ }
561
+ if (args.loadSplit !== undefined) {
562
+ const r = benchLoadSplit({ graph: args.loadSplit, runs: args.runs });
563
+ process.stdout.write(args.format === 'json' ? `${JSON.stringify(r, null, 2)}\n` : `${renderLoadSplit(r)}\n`);
564
+ return 0;
565
+ }
566
+ if (args.repo !== undefined && args.edit !== undefined) {
567
+ const r = benchRepo({ repo: args.repo, edit: args.edit, runs: args.runs });
568
+ process.stdout.write(args.format === 'json' ? `${JSON.stringify(r, null, 2)}\n` : `${renderRepo(r)}\n`);
569
+ return 0;
570
+ }
571
+ const r = await bench(args);
572
+ process.stdout.write(args.format === 'json' ? `${JSON.stringify(r, null, 2)}\n` : `${render(r)}\n`);
573
+ return 0;
574
+ }
575
+
576
+ if (process.argv[1] !== undefined && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
577
+ cli().then(
578
+ (rc) => process.exit(rc),
579
+ (e: unknown) => {
580
+ process.stderr.write(`bench_graph_feeder_latency: ${String(e)}\n`);
581
+ process.exit(2);
582
+ },
583
+ );
584
+ }