@event4u/agent-config 14.22.0 → 15.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (557) 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 +333 -356
  5. package/README.md +1 -1
  6. package/dist/agent-src/commands/agent-handoff.md +8 -7
  7. package/dist/agent-src/commands/agents/init.md +1 -1
  8. package/dist/agent-src/commands/agents/user/accept.md +4 -4
  9. package/dist/agent-src/commands/agents/user/delete.md +2 -2
  10. package/dist/agent-src/commands/agents/user/init.md +3 -3
  11. package/dist/agent-src/commands/agents/user/review.md +3 -3
  12. package/dist/agent-src/commands/agents/user/show.md +3 -3
  13. package/dist/agent-src/commands/agents/user/update.md +2 -2
  14. package/dist/agent-src/commands/agents/user.md +6 -6
  15. package/dist/agent-src/commands/analytics/prune.md +1 -1
  16. package/dist/agent-src/commands/analytics/show.md +2 -2
  17. package/dist/agent-src/commands/analyze/decision.md +2 -2
  18. package/dist/agent-src/commands/analyze/inbox.md +5 -5
  19. package/dist/agent-src/commands/analyze/incident.md +3 -3
  20. package/dist/agent-src/commands/analyze/near-miss.md +3 -3
  21. package/dist/agent-src/commands/analyze/postmortem.md +4 -4
  22. package/dist/agent-src/commands/analyze/premortem.md +2 -2
  23. package/dist/agent-src/commands/analyze.md +2 -2
  24. package/dist/agent-src/commands/bug/fix.md +1 -1
  25. package/dist/agent-src/commands/bug/investigate.md +2 -2
  26. package/dist/agent-src/commands/cost/profile.md +3 -3
  27. package/dist/agent-src/commands/design.md +1 -1
  28. package/dist/agent-src/commands/feature/explore.md +1 -1
  29. package/dist/agent-src/commands/feature/plan.md +2 -2
  30. package/dist/agent-src/commands/feature/roadmap.md +2 -2
  31. package/dist/agent-src/commands/ghostwriter/fetch.md +4 -4
  32. package/dist/agent-src/commands/ghostwriter/list.md +1 -1
  33. package/dist/agent-src/commands/ghostwriter/show.md +1 -1
  34. package/dist/agent-src/commands/ghostwriter/write.md +9 -9
  35. package/dist/agent-src/commands/humanize.md +6 -6
  36. package/dist/agent-src/commands/jira-ticket.md +1 -1
  37. package/dist/agent-src/commands/judge/solo.md +1 -1
  38. package/dist/agent-src/commands/judge.md +1 -1
  39. package/dist/agent-src/commands/knowledge/cross-repo.md +1 -1
  40. package/dist/agent-src/commands/knowledge/forget.md +1 -1
  41. package/dist/agent-src/commands/knowledge/ingest.md +2 -2
  42. package/dist/agent-src/commands/knowledge/list.md +1 -1
  43. package/dist/agent-src/commands/memory/add.md +3 -3
  44. package/dist/agent-src/commands/memory/load.md +4 -4
  45. package/dist/agent-src/commands/memory/mine-session.md +1 -1
  46. package/dist/agent-src/commands/memory/promote.md +4 -4
  47. package/dist/agent-src/commands/memory/propose.md +2 -2
  48. package/dist/agent-src/commands/mode.md +5 -5
  49. package/dist/agent-src/commands/post-as/ghostwriter.md +3 -3
  50. package/dist/agent-src/commands/post-as/me.md +7 -7
  51. package/dist/agent-src/commands/pr/create.md +1 -1
  52. package/dist/agent-src/commands/pr/merge.md +48 -39
  53. package/dist/agent-src/commands/profile/activate.md +1 -1
  54. package/dist/agent-src/commands/profile/show.md +1 -1
  55. package/dist/agent-src/commands/research/deep.md +2 -2
  56. package/dist/agent-src/commands/research/report.md +2 -2
  57. package/dist/agent-src/commands/review/changes.md +1 -1
  58. package/dist/agent-src/commands/review/routing.md +1 -1
  59. package/dist/agent-src/commands/roadmap/create.md +1 -1
  60. package/dist/agent-src/commands/roadmap/materialize.md +2 -2
  61. package/dist/agent-src/commands/roadmap/next.md +9 -1
  62. package/dist/agent-src/commands/roadmap/process-full.md +2 -2
  63. package/dist/agent-src/commands/security-audit-config.md +3 -3
  64. package/dist/agent-src/commands/skill/preview.md +1 -1
  65. package/dist/agent-src/commands/skills/discover.md +1 -1
  66. package/dist/agent-src/commands/sync/agent-settings.md +2 -2
  67. package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
  68. package/dist/agent-src/commands/tests/create.md +1 -1
  69. package/dist/agent-src/commands/tests/e2e-heal.md +1 -1
  70. package/dist/agent-src/commands/tests/e2e-plan.md +1 -1
  71. package/dist/agent-src/contexts/authority/kernel-rule-edits.md +6 -6
  72. package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -2
  73. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +2 -2
  74. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +88 -1
  75. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +1 -1
  76. package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -1
  77. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +1 -1
  78. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
  79. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +13 -1
  80. package/dist/agent-src/contexts/execution/cheap-question-mechanics.md +1 -1
  81. package/dist/agent-src/contexts/execution/contract-decision-sheet.md +3 -3
  82. package/dist/agent-src/contexts/execution/mandated-lines.md +1 -1
  83. package/dist/agent-src/contexts/execution/non-interactive-contract.md +1 -1
  84. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -1
  85. package/dist/agent-src/contexts/execution/plan-confidence-gate.md +5 -5
  86. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +1 -1
  87. package/dist/agent-src/contexts/execution/subagent-modes-detail.md +1 -1
  88. package/dist/agent-src/contexts/execution/subagent-routing.md +2 -2
  89. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +1 -1
  90. package/dist/agent-src/contexts/execution/user-memory-channels.md +3 -3
  91. package/dist/agent-src/contexts/execution/verification-mechanics.md +1 -1
  92. package/dist/agent-src/contexts/judges/persona-voice-rubric.md +2 -2
  93. package/dist/agent-src/guidelines/abstraction-thresholds.md +88 -0
  94. package/dist/agent-src/guidelines/agent-infra/5w2h-analysis.md +260 -0
  95. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +99 -0
  96. package/dist/agent-src/guidelines/agent-infra/agent-interaction-and-decision-quality.md +325 -0
  97. package/dist/agent-src/guidelines/agent-infra/api-cost-levers.md +177 -0
  98. package/dist/agent-src/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +222 -0
  99. package/dist/agent-src/guidelines/agent-infra/ask-when-uncertain-demos.md +134 -0
  100. package/dist/agent-src/guidelines/agent-infra/asking-and-brevity-examples.md +198 -0
  101. package/dist/agent-src/guidelines/agent-infra/break-glass-usage.md +113 -0
  102. package/dist/agent-src/guidelines/agent-infra/carve-out-predicates.md +17 -0
  103. package/dist/agent-src/guidelines/agent-infra/comparison-matrix.md +179 -0
  104. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +165 -0
  105. package/dist/agent-src/guidelines/agent-infra/corpus-grounding-authoring.md +91 -0
  106. package/dist/agent-src/guidelines/agent-infra/critical-thinking.md +156 -0
  107. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +109 -0
  108. package/dist/agent-src/guidelines/agent-infra/developer-judgment.md +82 -0
  109. package/dist/agent-src/guidelines/agent-infra/direct-answers-demos.md +142 -0
  110. package/dist/agent-src/guidelines/agent-infra/domain-adoption-gates.md +112 -0
  111. package/dist/agent-src/guidelines/agent-infra/domain-eval-anti-pattern.md +53 -0
  112. package/dist/agent-src/guidelines/agent-infra/domain-pack-architecture.md +56 -0
  113. package/dist/agent-src/guidelines/agent-infra/downstream-changes-mechanics.md +91 -0
  114. package/dist/agent-src/guidelines/agent-infra/emphasis-budget.md +45 -0
  115. package/dist/agent-src/guidelines/agent-infra/engineering-memory-data-format.md +210 -0
  116. package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
  117. package/dist/agent-src/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  118. package/dist/agent-src/guidelines/agent-infra/failure-signatures.md +70 -0
  119. package/dist/agent-src/guidelines/agent-infra/false-green.md +233 -0
  120. package/dist/agent-src/guidelines/agent-infra/first-principles.md +192 -0
  121. package/dist/agent-src/guidelines/agent-infra/framework-neutrality-patterns.md +66 -0
  122. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +169 -0
  123. package/dist/agent-src/guidelines/agent-infra/gate-authoring.md +177 -0
  124. package/dist/agent-src/guidelines/agent-infra/guarded-baseline.md +39 -0
  125. package/dist/agent-src/guidelines/agent-infra/installed-tools-manifest.md +142 -0
  126. package/dist/agent-src/guidelines/agent-infra/inversion-thinking.md +388 -0
  127. package/dist/agent-src/guidelines/agent-infra/ios-simulator-guide.md +378 -0
  128. package/dist/agent-src/guidelines/agent-infra/language-and-tone-examples.md +141 -0
  129. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +317 -0
  130. package/dist/agent-src/guidelines/agent-infra/linked-projects-onboarding-gate.md +80 -0
  131. package/dist/agent-src/guidelines/agent-infra/mcp-request-signing.md +197 -0
  132. package/dist/agent-src/guidelines/agent-infra/memory-access.md +149 -0
  133. package/dist/agent-src/guidelines/agent-infra/mental-models.md +314 -0
  134. package/dist/agent-src/guidelines/agent-infra/minimal-safe-diff-mechanics.md +241 -0
  135. package/dist/agent-src/guidelines/agent-infra/missing-tool-handling.md +66 -0
  136. package/dist/agent-src/guidelines/agent-infra/model-recommendation.md +101 -0
  137. package/dist/agent-src/guidelines/agent-infra/naming.md +69 -0
  138. package/dist/agent-src/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
  139. package/dist/agent-src/guidelines/agent-infra/output-patterns.md +117 -0
  140. package/dist/agent-src/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
  141. package/dist/agent-src/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  142. package/dist/agent-src/guidelines/agent-infra/review-routing-data-format.md +143 -0
  143. package/dist/agent-src/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
  144. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +274 -0
  145. package/dist/agent-src/guidelines/agent-infra/role-contracts.md +209 -0
  146. package/dist/agent-src/guidelines/agent-infra/role-mode-router.md +89 -0
  147. package/dist/agent-src/guidelines/agent-infra/rule-body-migration-inventory.md +241 -0
  148. package/dist/agent-src/guidelines/agent-infra/rule-type-governance.md +73 -0
  149. package/dist/agent-src/guidelines/agent-infra/runtime-layer.md +89 -0
  150. package/dist/agent-src/guidelines/agent-infra/scqa-framework.md +526 -0
  151. package/dist/agent-src/guidelines/agent-infra/security-lint-containment.md +121 -0
  152. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +134 -0
  153. package/dist/agent-src/guidelines/agent-infra/simplicity-and-goal-demos.md +211 -0
  154. package/dist/agent-src/guidelines/agent-infra/six-hats.md +353 -0
  155. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +229 -0
  156. package/dist/agent-src/guidelines/agent-infra/skill-quality-checklist.md +157 -0
  157. package/dist/agent-src/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  158. package/dist/agent-src/guidelines/agent-infra/symptom-driven-harvest-loop.md +104 -0
  159. package/dist/agent-src/guidelines/agent-infra/systems-thinking.md +220 -0
  160. package/dist/agent-src/guidelines/agent-infra/tool-description-as-policy.md +35 -0
  161. package/dist/agent-src/guidelines/agent-infra/tool-integration.md +73 -0
  162. package/dist/agent-src/guidelines/agent-infra/traceability-field-mechanics.md +50 -0
  163. package/dist/agent-src/guidelines/agent-infra/untrusted-input-spotlighting.md +166 -0
  164. package/dist/agent-src/guidelines/agent-infra/verify-before-complete-demos.md +128 -0
  165. package/dist/agent-src/guidelines/augment-portability-patterns.md +70 -0
  166. package/dist/agent-src/guidelines/code-clarity.md +350 -0
  167. package/dist/agent-src/guidelines/component-oriented-and-oop-development.md +189 -0
  168. package/dist/agent-src/guidelines/cross-role-handoff.md +127 -0
  169. package/dist/agent-src/guidelines/design-antipatterns-triggers.json +18 -0
  170. package/dist/agent-src/guidelines/design-antipatterns.md +327 -0
  171. package/dist/agent-src/guidelines/design-asset-discipline.md +38 -0
  172. package/dist/agent-src/guidelines/design-canon.md +63 -0
  173. package/dist/agent-src/guidelines/design-fidelity-mechanics.md +293 -0
  174. package/dist/agent-src/guidelines/design-fidelity-routing.md +78 -0
  175. package/dist/agent-src/guidelines/design-handover-extraction.md +117 -0
  176. package/dist/agent-src/guidelines/design-modes.md +143 -0
  177. package/dist/agent-src/guidelines/design-reconciliation.md +172 -0
  178. package/dist/agent-src/guidelines/docs/readme-size-and-splitting.md +209 -0
  179. package/dist/agent-src/guidelines/e2e/playwright.md +363 -0
  180. package/dist/agent-src/guidelines/gtm-handoff.md +114 -0
  181. package/dist/agent-src/guidelines/monorepo-antipatterns.md +141 -0
  182. package/dist/agent-src/guidelines/php/api-design.md +115 -0
  183. package/dist/agent-src/guidelines/php/artisan-commands.md +81 -0
  184. package/dist/agent-src/guidelines/php/blade-ui.md +78 -0
  185. package/dist/agent-src/guidelines/php/controllers.md +90 -0
  186. package/dist/agent-src/guidelines/php/database.md +194 -0
  187. package/dist/agent-src/guidelines/php/eloquent.md +208 -0
  188. package/dist/agent-src/guidelines/php/flux.md +80 -0
  189. package/dist/agent-src/guidelines/php/general.md +207 -0
  190. package/dist/agent-src/guidelines/php/git.md +164 -0
  191. package/dist/agent-src/guidelines/php/jobs.md +111 -0
  192. package/dist/agent-src/guidelines/php/livewire.md +71 -0
  193. package/dist/agent-src/guidelines/php/logging.md +79 -0
  194. package/dist/agent-src/guidelines/php/naming.md +89 -0
  195. package/dist/agent-src/guidelines/php/patterns/dependency-injection.md +57 -0
  196. package/dist/agent-src/guidelines/php/patterns/dtos.md +199 -0
  197. package/dist/agent-src/guidelines/php/patterns/events.md +67 -0
  198. package/dist/agent-src/guidelines/php/patterns/factory.md +53 -0
  199. package/dist/agent-src/guidelines/php/patterns/pipelines.md +66 -0
  200. package/dist/agent-src/guidelines/php/patterns/policies.md +66 -0
  201. package/dist/agent-src/guidelines/php/patterns/repositories.md +122 -0
  202. package/dist/agent-src/guidelines/php/patterns/service-layer.md +64 -0
  203. package/dist/agent-src/guidelines/php/patterns/strategy.md +247 -0
  204. package/dist/agent-src/guidelines/php/patterns.md +28 -0
  205. package/dist/agent-src/guidelines/php/performance.md +92 -0
  206. package/dist/agent-src/guidelines/php/php-coding-patterns.md +80 -0
  207. package/dist/agent-src/guidelines/php/resources.md +100 -0
  208. package/dist/agent-src/guidelines/php/security.md +110 -0
  209. package/dist/agent-src/guidelines/php/sql.md +97 -0
  210. package/dist/agent-src/guidelines/php/validations.md +119 -0
  211. package/dist/agent-src/guidelines/php/websocket.md +100 -0
  212. package/dist/agent-src/guidelines/prompt-templates.md +189 -0
  213. package/dist/agent-src/guidelines/redundancy-taxonomy.md +208 -0
  214. package/dist/agent-src/guidelines/wing4-handoff.md +127 -0
  215. package/dist/agent-src/personas/README.md +1 -1
  216. package/dist/agent-src/personas/_template-specialist/persona.md +1 -1
  217. package/dist/agent-src/personas/product-owner.md +1 -1
  218. package/dist/agent-src/rules/active-remediation.md +1 -1
  219. package/dist/agent-src/rules/architecture.md +2 -2
  220. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  221. package/dist/agent-src/rules/ask-when-uncertain.md +2 -2
  222. package/dist/agent-src/rules/brand-source-of-truth.md +9 -7
  223. package/dist/agent-src/rules/code-comment-discipline.md +2 -2
  224. package/dist/agent-src/rules/code-provenance.md +1 -1
  225. package/dist/agent-src/rules/content-quoting-floor.md +1 -1
  226. package/dist/agent-src/rules/context-hygiene.md +5 -5
  227. package/dist/agent-src/rules/cross-source-consistency.md +1 -1
  228. package/dist/agent-src/rules/design-fidelity.md +36 -46
  229. package/dist/agent-src/rules/direct-answers.md +2 -2
  230. package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
  231. package/dist/agent-src/rules/evaluator-independence.md +1 -1
  232. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
  233. package/dist/agent-src/rules/icon-consistency.md +5 -1
  234. package/dist/agent-src/rules/improve-before-implement.md +1 -1
  235. package/dist/agent-src/rules/language-and-tone.md +3 -3
  236. package/dist/agent-src/rules/minimal-safe-diff.md +1 -1
  237. package/dist/agent-src/rules/notes-first-reasoning.md +36 -25
  238. package/dist/agent-src/rules/recurring-criticism.md +1 -1
  239. package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
  240. package/dist/agent-src/rules/role-mode-adherence.md +2 -2
  241. package/dist/agent-src/rules/security-sensitive-stop.md +1 -1
  242. package/dist/agent-src/rules/size-enforcement.md +1 -1
  243. package/dist/agent-src/rules/source-confidentiality.md +2 -2
  244. package/dist/agent-src/rules/think-before-action.md +1 -1
  245. package/dist/agent-src/rules/token-efficiency.md +7 -5
  246. package/dist/agent-src/rules/ui-audit-gate.md +3 -2
  247. package/dist/agent-src/rules/untrusted-input-defense.md +3 -3
  248. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +106 -4
  249. package/dist/agent-src/skills/activation-design/SKILL.md +2 -2
  250. package/dist/agent-src/skills/adr-create/SKILL.md +5 -5
  251. package/dist/agent-src/skills/ai-council/SKILL.md +1 -1
  252. package/dist/agent-src/skills/ai-council/references/advanced-modes.md +1 -1
  253. package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
  254. package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +1 -1
  255. package/dist/agent-src/skills/brand-to-tokens/SKILL.md +24 -3
  256. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  257. package/dist/agent-src/skills/build-buy-partner/SKILL.md +1 -1
  258. package/dist/agent-src/skills/churn-prevention/SKILL.md +2 -2
  259. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -1
  260. package/dist/agent-src/skills/code-refactoring/SKILL.md +3 -3
  261. package/dist/agent-src/skills/code-review/SKILL.md +3 -3
  262. package/dist/agent-src/skills/command-writing/SKILL.md +3 -3
  263. package/dist/agent-src/skills/comp-banding/SKILL.md +1 -1
  264. package/dist/agent-src/skills/competitive-moat-analysis/SKILL.md +1 -1
  265. package/dist/agent-src/skills/competitive-positioning/SKILL.md +2 -2
  266. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +1 -1
  267. package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
  268. package/dist/agent-src/skills/content-funnel-design/SKILL.md +2 -2
  269. package/dist/agent-src/skills/contracts-cognition/SKILL.md +1 -1
  270. package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +2 -2
  271. package/dist/agent-src/skills/corpus-grounding/SKILL.md +2 -2
  272. package/dist/agent-src/skills/customer-research/SKILL.md +2 -2
  273. package/dist/agent-src/skills/dashboard-design/SKILL.md +1 -1
  274. package/dist/agent-src/skills/data-handling-judgment/SKILL.md +1 -1
  275. package/dist/agent-src/skills/deal-qualification-meddic/SKILL.md +2 -2
  276. package/dist/agent-src/skills/decision-record/SKILL.md +3 -3
  277. package/dist/agent-src/skills/decision-review/SKILL.md +8 -8
  278. package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +22 -22
  279. package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
  280. package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +2 -2
  281. package/dist/agent-src/skills/design-review/SKILL.md +4 -4
  282. package/dist/agent-src/skills/design-system-capture/references/design-system-json.md +20 -1
  283. package/dist/agent-src/skills/design-tokens/SKILL.md +17 -2
  284. package/dist/agent-src/skills/design-variations/SKILL.md +2 -2
  285. package/dist/agent-src/skills/developer-like-execution/SKILL.md +2 -2
  286. package/dist/agent-src/skills/discovery-interview/SKILL.md +2 -2
  287. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +3 -3
  288. package/dist/agent-src/skills/editorial-calendar/SKILL.md +2 -2
  289. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +44 -1
  290. package/dist/agent-src/skills/existing-ui-audit/references/anti-slop-cross-reference.md +2 -2
  291. package/dist/agent-src/skills/expansion-playbook/SKILL.md +2 -2
  292. package/dist/agent-src/skills/experiment-loop/SKILL.md +1 -1
  293. package/dist/agent-src/skills/experiment-loop/references/protocol.md +1 -1
  294. package/dist/agent-src/skills/fe-design/SKILL.md +3 -3
  295. package/dist/agent-src/skills/fe-design/references/design-patterns.md +1 -1
  296. package/dist/agent-src/skills/fe-design/references/design-read-and-memory.md +3 -3
  297. package/dist/agent-src/skills/fe-design/references/source-led-port.md +1 -1
  298. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  299. package/dist/agent-src/skills/flux/SKILL.md +1 -1
  300. package/dist/agent-src/skills/forecast-accuracy/SKILL.md +2 -2
  301. package/dist/agent-src/skills/forecasting/SKILL.md +2 -2
  302. package/dist/agent-src/skills/fundraising-narrative/SKILL.md +2 -2
  303. package/dist/agent-src/skills/funnel-analysis/SKILL.md +2 -2
  304. package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +9 -0
  305. package/dist/agent-src/skills/gtm-launch/SKILL.md +2 -2
  306. package/dist/agent-src/skills/hiring-loop-design/SKILL.md +1 -1
  307. package/dist/agent-src/skills/html-deck/SKILL.md +5 -5
  308. package/dist/agent-src/skills/humanizer/SKILL.md +1 -1
  309. package/dist/agent-src/skills/humanizer/data/patterns.md +1 -1
  310. package/dist/agent-src/skills/iconography/SKILL.md +3 -3
  311. package/dist/agent-src/skills/judge-synthesis/SKILL.md +1 -1
  312. package/dist/agent-src/skills/laravel-api-endpoint/SKILL.md +2 -2
  313. package/dist/agent-src/skills/launch-readiness/SKILL.md +3 -3
  314. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +6 -6
  315. package/dist/agent-src/skills/livewire/SKILL.md +1 -1
  316. package/dist/agent-src/skills/market-entry-analysis/SKILL.md +1 -1
  317. package/dist/agent-src/skills/mcp-builder/SKILL.md +1 -1
  318. package/dist/agent-src/skills/memory-consolidation/SKILL.md +3 -3
  319. package/dist/agent-src/skills/messaging-architecture/SKILL.md +2 -2
  320. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  321. package/dist/agent-src/skills/onboarding-design/SKILL.md +2 -2
  322. package/dist/agent-src/skills/onboarding-program/SKILL.md +1 -1
  323. package/dist/agent-src/skills/one-on-one-cadence/SKILL.md +1 -1
  324. package/dist/agent-src/skills/org-design/SKILL.md +1 -1
  325. package/dist/agent-src/skills/overbuild-review-lens/SKILL.md +3 -3
  326. package/dist/agent-src/skills/override-management/SKILL.md +1 -1
  327. package/dist/agent-src/skills/perf-feedback-craft/SKILL.md +1 -1
  328. package/dist/agent-src/skills/persona-writing/SKILL.md +1 -1
  329. package/dist/agent-src/skills/php-coder/SKILL.md +1 -1
  330. package/dist/agent-src/skills/pipeline-strategy/SKILL.md +2 -2
  331. package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -3
  332. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  333. package/dist/agent-src/skills/positioning-strategy/SKILL.md +2 -2
  334. package/dist/agent-src/skills/privacy-review/SKILL.md +1 -1
  335. package/dist/agent-src/skills/prompt-optimizer/SKILL.md +3 -3
  336. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  337. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -2
  338. package/dist/agent-src/skills/receiving-code-review/SKILL.md +1 -1
  339. package/dist/agent-src/skills/refine-ticket/SKILL.md +2 -2
  340. package/dist/agent-src/skills/release-comms/SKILL.md +2 -2
  341. package/dist/agent-src/skills/retention-loops/SKILL.md +2 -2
  342. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  343. package/dist/agent-src/skills/roadmap-management/SKILL.md +1 -1
  344. package/dist/agent-src/skills/roadmap-management/references/archival.md +1 -1
  345. package/dist/agent-src/skills/roadmap-writing/SKILL.md +5 -5
  346. package/dist/agent-src/skills/rule-writing/SKILL.md +6 -6
  347. package/dist/agent-src/skills/runway-cognition/SKILL.md +2 -2
  348. package/dist/agent-src/skills/scenario-modeling/SKILL.md +2 -2
  349. package/dist/agent-src/skills/skill-writing/SKILL.md +2 -2
  350. package/dist/agent-src/skills/skill-writing/references/procedure.md +1 -1
  351. package/dist/agent-src/skills/skill-writing/references/section-patterns.md +3 -3
  352. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +1 -1
  353. package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +3 -3
  354. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
  355. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +1 -1
  356. package/dist/agent-src/skills/systematic-debugging/SKILL.md +2 -2
  357. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +60 -4
  358. package/dist/agent-src/skills/throughput-vs-morale-tradeoff/SKILL.md +1 -1
  359. package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
  360. package/dist/agent-src/skills/typography-system/SKILL.md +2 -2
  361. package/dist/agent-src/skills/ui-component-architect/SKILL.md +28 -8
  362. package/dist/agent-src/skills/unit-economics-modeling/SKILL.md +2 -2
  363. package/dist/agent-src/skills/upstream-contribute/SKILL.md +1 -1
  364. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +2 -2
  365. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  366. package/dist/agent-src/skills/vision-articulation/SKILL.md +1 -1
  367. package/dist/agent-src/skills/voc-extract/SKILL.md +2 -2
  368. package/dist/agent-src/skills/voice-and-tone-design/SKILL.md +2 -2
  369. package/dist/agent-src/skills/wireframe/SKILL.md +1 -1
  370. package/dist/agent-src/skills/workspace-link/SKILL.md +1 -1
  371. package/dist/agent-src/templates/agent-settings.md +6 -6
  372. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  373. package/dist/agent-src/templates/contexts/knowledge-pages.md +2 -3
  374. package/dist/agent-src/templates/copilot-instructions.md +1 -1
  375. package/dist/agent-src/templates/roadmaps.md +1 -1
  376. package/dist/agent-src/templates/scripts/README.md +2 -2
  377. package/dist/agent-src/user-types/_template/user-type.md +1 -1
  378. package/dist/cli/registry.js +1 -1
  379. package/dist/cli-delegate/archive_completed_roadmaps.js +52 -4
  380. package/dist/cli-delegate/check_update_banner.js +12 -1
  381. package/dist/cli-delegate/{chunk-TGIPZBCW.js → chunk-2KKXJW25.js} +22 -8
  382. package/dist/cli-delegate/{chunk-NLP54U3J.js → chunk-2XY7ILBT.js} +13 -1
  383. package/dist/cli-delegate/{chunk-4FS4WRXP.js → chunk-3FKR64R5.js} +34 -6
  384. package/dist/cli-delegate/{chunk-J3RFNKG4.js → chunk-55ACLDUE.js} +2 -2
  385. package/dist/cli-delegate/{chunk-PKOBQADP.js → chunk-57PN4GYJ.js} +1 -1
  386. package/dist/cli-delegate/{chunk-BIXEDQPZ.js → chunk-AK6HODNQ.js} +4 -4
  387. package/dist/cli-delegate/{chunk-2FTMENJL.js → chunk-GYC3VRYN.js} +1 -1
  388. package/dist/cli-delegate/{chunk-LWTYTX6F.js → chunk-HZ52BRGG.js} +24 -18
  389. package/dist/cli-delegate/{chunk-6RJA2F5A.js → chunk-IVBPRCQO.js} +1 -1
  390. package/dist/cli-delegate/{chunk-I6RHFQEG.js → chunk-YUM5KURG.js} +17 -1
  391. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  392. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  393. package/dist/cli-delegate/cmd_conformance.js +3 -3
  394. package/dist/cli-delegate/cmd_doctor.js +3 -3
  395. package/dist/cli-delegate/cmd_explain.js +2 -2
  396. package/dist/cli-delegate/cmd_export.js +4 -4
  397. package/dist/cli-delegate/cmd_handoff.js +24 -16
  398. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  399. package/dist/cli-delegate/cmd_memory_get.js +1 -1
  400. package/dist/cli-delegate/cmd_migrate.js +2 -2
  401. package/dist/cli-delegate/cmd_packs_active.js +2 -2
  402. package/dist/cli-delegate/cmd_prune.js +4 -4
  403. package/dist/cli-delegate/cmd_route_audit.js +3 -3
  404. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  405. package/dist/cli-delegate/cmd_session_recycle.js +4 -14
  406. package/dist/cli-delegate/cmd_settings_get.js +15 -9
  407. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  408. package/dist/cli-delegate/cmd_settings_set.js +41 -11
  409. package/dist/cli-delegate/cmd_sync.js +4 -4
  410. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  411. package/dist/cli-delegate/cmd_update.js +1 -1
  412. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  413. package/dist/cli-delegate/cmd_validate.js +4 -4
  414. package/dist/cli-delegate/cmd_versions.js +1 -1
  415. package/dist/discovery/deprecation-report.md +1 -1
  416. package/dist/discovery/discovery-manifest.json +27 -80
  417. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  418. package/dist/discovery/discovery-manifest.summary.md +3 -3
  419. package/dist/discovery/dormancy-report.md +1 -1
  420. package/dist/discovery/orphan-report.md +1 -1
  421. package/dist/discovery/packs.json +5 -7
  422. package/dist/discovery/trust-report.md +2 -2
  423. package/dist/discovery/workspaces.json +4 -6
  424. package/dist/hooks/dispatch.js +9249 -8981
  425. package/dist/install/install.mjs +47 -8
  426. package/dist/mcp/registry-manifest.json +3 -3
  427. package/dist/mcp/server.json +2 -2
  428. package/dist/mcp/server.mjs +5496 -2400
  429. package/dist/router.json +1 -1
  430. package/dist/scripts/_lib/agent_settings.js +73 -0
  431. package/dist/scripts/_lib/agent_src.js +20 -0
  432. package/dist/scripts/_lib/guidelines_lane.js +158 -0
  433. package/dist/scripts/_lib/lean_projection_mode.js +108 -0
  434. package/dist/scripts/_lib/router_match.js +243 -0
  435. package/dist/scripts/_lib/rule_injection.js +216 -0
  436. package/dist/scripts/condense.js +22 -25
  437. package/dist/scripts/project_thin_rules.js +139 -19
  438. package/dist/server/io/yamlIO.js +125 -17
  439. package/dist/server/schemas/settings.js +32 -5
  440. package/dist/shared/settingsSurface.js +6 -1
  441. package/docs/MIGRATION.md +56 -0
  442. package/docs/contracts/settings-classes.md +48 -7
  443. package/docs/guidelines/abstraction-thresholds.md +35 -0
  444. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +3 -3
  445. package/docs/guidelines/agent-infra/false-green.md +2 -2
  446. package/docs/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
  447. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  448. package/docs/guidelines/agent-infra/skill-quality-checklist.md +1 -1
  449. package/docs/guidelines/design-fidelity-mechanics.md +4 -0
  450. package/docs/guidelines/design-fidelity-routing.md +78 -0
  451. package/docs/guidelines/design-reconciliation.md +172 -0
  452. package/docs/guidelines/gtm-handoff.md +2 -2
  453. package/docs/guidelines/wing4-handoff.md +2 -2
  454. package/llms.txt +1 -1
  455. package/package.json +7 -3
  456. package/src/agent-src/scripts/archive_completed_roadmaps.ts +106 -4
  457. package/src/config/agent-settings.template.yml +94 -1
  458. package/src/config/ci-local-parity.yml +34 -0
  459. package/src/config/continuity-surface.json +8 -29
  460. package/src/config/evaluator-budgets.json +4 -4
  461. package/src/config/gate-coverage.yml +31 -8
  462. package/src/config/gate-reachability-exemptions.json +1 -0
  463. package/src/config/gate-violation-baselines.json +3 -3
  464. package/src/config/hook-token-budget.json +8 -7
  465. package/src/config/host-injection-effect.json +2 -2
  466. package/src/config/pack-size-budget.json +55 -4
  467. package/src/config/packed-binary-manifest.json +1 -1
  468. package/src/config/platform-anchor.json +47 -0
  469. package/src/config/preamble-payload-budget.json +2 -3
  470. package/src/config/publish-surface.json +4 -2
  471. package/src/config/ratification-policy.json +7 -0
  472. package/src/config/routing-coverage-seed.json +9 -2
  473. package/src/config/rule-stub-ceilings.json +16 -9
  474. package/src/scripts/_cli/cmd_session_recycle.ts +2 -25
  475. package/src/scripts/_cli/cmd_settings_get.ts +22 -7
  476. package/src/scripts/_cli/handoff_sessions.ts +14 -44
  477. package/src/scripts/_lib/agent_settings.ts +85 -0
  478. package/src/scripts/_lib/agent_src.ts +21 -0
  479. package/src/scripts/_lib/artifact_maturity.ts +242 -0
  480. package/src/scripts/_lib/conformance_report.ts +403 -0
  481. package/src/scripts/_lib/continuity_slot.ts +295 -0
  482. package/src/scripts/_lib/continuity_writer.ts +312 -0
  483. package/src/scripts/_lib/design_system_import.ts +20 -0
  484. package/src/scripts/_lib/design_tolerance.ts +281 -0
  485. package/src/scripts/_lib/guidelines_lane.ts +164 -0
  486. package/src/scripts/_lib/hook_settings.ts +85 -0
  487. package/src/scripts/_lib/lean_projection_mode.ts +127 -0
  488. package/src/scripts/_lib/obligation_frequency.ts +2 -3
  489. package/src/scripts/_lib/packed_binary_predicate.ts +37 -0
  490. package/src/scripts/_lib/platform_anchor.ts +1053 -0
  491. package/src/scripts/_lib/ratification_artifact.ts +278 -0
  492. package/src/scripts/_lib/recycle_envelope_paths.ts +109 -21
  493. package/src/scripts/_lib/regression_neighbourhood.ts +159 -22
  494. package/src/scripts/_lib/security_lint.ts +23 -2
  495. package/src/scripts/_lib/self_repair.ts +21 -0
  496. package/src/scripts/_lib/session_eol.ts +44 -0
  497. package/src/scripts/_lib/session_index_trust.ts +387 -0
  498. package/src/scripts/_lib/standing_bound_ratchet.ts +220 -0
  499. package/src/scripts/_lib/tolerance_shadow.ts +177 -0
  500. package/src/scripts/_lib/vendored_grammar_upstream.ts +280 -0
  501. package/src/scripts/ai_council/redact_low_impact_entry.ts +8 -0
  502. package/src/scripts/audit_mcp_tools.ts +69 -25
  503. package/src/scripts/autonomy_friction_traffic.ts +379 -0
  504. package/src/scripts/build_mcp_catalog.ts +24 -1
  505. package/src/scripts/check_host_tree_parity.ts +291 -0
  506. package/src/scripts/check_kernel_edit_ratified.ts +462 -0
  507. package/src/scripts/check_loss_class_declared.ts +793 -46
  508. package/src/scripts/check_platform_anchor.ts +390 -0
  509. package/src/scripts/check_preamble_payload_budget.ts +424 -7
  510. package/src/scripts/check_projected_rule_routes.ts +395 -0
  511. package/src/scripts/check_rule_projection_integrity.ts +102 -2
  512. package/src/scripts/ci_settle.ts +205 -5
  513. package/src/scripts/code_graph/build.ts +79 -0
  514. package/src/scripts/code_graph/cli.ts +264 -7
  515. package/src/scripts/code_graph/detect.ts +38 -0
  516. package/src/scripts/code_graph/query.ts +25 -2
  517. package/src/scripts/code_graph/sqlite_store.ts +16 -1
  518. package/src/scripts/code_graph/types.ts +52 -3
  519. package/src/scripts/code_graph/validate.ts +3 -1
  520. package/src/scripts/code_graph/verbs.ts +590 -0
  521. package/src/scripts/condense.ts +22 -26
  522. package/src/scripts/generate_host_cost_table.ts +354 -0
  523. package/src/scripts/handoff_context_hook.ts +39 -1
  524. package/src/scripts/hook_manifest.json +1 -1
  525. package/src/scripts/hook_manifest.yaml +59 -28
  526. package/src/scripts/hooks/block_speaking_inbox_dir.ts +182 -16
  527. package/src/scripts/hooks/category_a.ts +1 -1
  528. package/src/scripts/hooks/chain_nudge_hook.ts +311 -25
  529. package/src/scripts/hooks/code_graph_context_hook.ts +7 -18
  530. package/src/scripts/hooks/push_settle_hook.ts +3 -2
  531. package/src/scripts/hooks/rule_inject_hook.ts +107 -20
  532. package/src/scripts/hooks/session_eol_hook.ts +177 -145
  533. package/src/scripts/hooks/source_first_gate_hook.ts +12 -0
  534. package/src/scripts/hooks/ui_route_nudge_hook.ts +52 -15
  535. package/src/scripts/hot_context_hook.ts +103 -408
  536. package/src/scripts/lint_evidence_artifacts.ts +1 -0
  537. package/src/scripts/lint_knowledge_scale.ts +0 -26
  538. package/src/scripts/lint_roadmap_blockers.ts +164 -1
  539. package/src/scripts/mcp_server/consumer_tool_catalog.json +152 -2
  540. package/src/scripts/mcp_server/graph_tools.ts +294 -0
  541. package/src/scripts/mcp_server/path_util.ts +31 -0
  542. package/src/scripts/mcp_server/tool_catalog_source.ts +7 -1
  543. package/src/scripts/mcp_server/tools.ts +3 -13
  544. package/src/scripts/memory_lookup.ts +9 -9
  545. package/src/scripts/model_rule_injection.ts +61 -4
  546. package/src/scripts/project_thin_rules.ts +149 -16
  547. package/src/scripts/report_standing_payload_by_host.ts +650 -0
  548. package/src/scripts/schemas/agent-settings.schema.json +7 -1
  549. package/src/scripts/session_memory_index.ts +86 -8
  550. package/src/scripts/sync_agent_settings.ts +270 -10
  551. package/src/server/io/yamlIO.ts +127 -17
  552. package/src/server/schemas/settings.ts +45 -6
  553. package/src/shared/settingsSurface.ts +13 -2
  554. package/src/templates/compact-instructions.md +8 -3
  555. package/src/vendor/grammars/README.md +27 -2
  556. package/dist/agent-src/commands/chat-history/import.md +0 -170
  557. package/dist/agent-src/commands/chat-history.md +0 -63
@@ -360,6 +360,130 @@ function _countRoadmapTree(dir: string): number {
360
360
  return n;
361
361
  }
362
362
 
363
+ /**
364
+ * Blocker ids declared `Status: open` in one file, by id.
365
+ *
366
+ * Reads exactly one fact per blocker — id and open-ness. It is deliberately
367
+ * NOT `_scanBoth`: the five-field contract, the class taxonomy and the
368
+ * decidability ratchet are not applied here, because the corpus this runs over
369
+ * includes `archive/` and applying the contract there lands 23 findings on day
370
+ * one against a change that caused none of them. That shape has been reverted
371
+ * twice in this repository — `lint_roadmap_later_disposition` at 68 files and
372
+ * `check_no_new_legacy_path` at 46 — and the exclusion also protects a true
373
+ * thing an archived roadmap is allowed to say: a blocker genuinely unresolved
374
+ * when its roadmap closed is history, not a defect.
375
+ */
376
+ function _openBlockerIds(text: string): Set<string> {
377
+ const stripped = _stripFencedCode(text);
378
+ const out = new Set<string>();
379
+ const sectionMatch = BLOCKERS_SECTION_RE.exec(stripped);
380
+ if (!sectionMatch) {
381
+ return out;
382
+ }
383
+ const sectionStart = sectionMatch.index + sectionMatch[0].length;
384
+ const rest = stripped.slice(sectionStart);
385
+ const h2 = NEXT_H2_RE.exec(rest);
386
+ const section = stripped.slice(sectionStart, h2 ? sectionStart + h2.index : stripped.length);
387
+
388
+ BLOCKER_HEADING_RE.lastIndex = 0;
389
+ const heads: Array<{ end: number; start: number; id: string }> = [];
390
+ let hm: RegExpExecArray | null;
391
+ while ((hm = BLOCKER_HEADING_RE.exec(section)) !== null) {
392
+ heads.push({ start: hm.index, end: hm.index + hm[0].length, id: (hm[1] as string).trim() });
393
+ if (hm.index === BLOCKER_HEADING_RE.lastIndex) {
394
+ BLOCKER_HEADING_RE.lastIndex++;
395
+ }
396
+ }
397
+ for (let i = 0; i < heads.length; i++) {
398
+ const cur = heads[i] as { end: number; start: number; id: string };
399
+ const bodyEnd =
400
+ i + 1 < heads.length ? (heads[i + 1] as { start: number }).start : section.length;
401
+ const body = section.slice(cur.end, bodyEnd);
402
+ // Resolved is a prefix test for the same reason `blocker_is_resolved`
403
+ // makes it one: `resolved 2026-09-08 by …` is resolved.
404
+ if (!/^-[ \t]*\*\*Status:\*\*[ \t]*resolved\b/im.test(body)) {
405
+ out.add(cur.id);
406
+ }
407
+ }
408
+ return out;
409
+ }
410
+
411
+ /** Sorted `*.md` directly under the archive directory. */
412
+ function _globArchivedRoadmaps(): string[] {
413
+ const dir = path.join(REPO_ROOT, 'agents', 'roadmaps', 'archive');
414
+ let entries: fs.Dirent[];
415
+ try {
416
+ entries = fs.readdirSync(dir, { withFileTypes: true });
417
+ } catch {
418
+ return [];
419
+ }
420
+ return entries
421
+ .filter((e) => e.isFile() && e.name.endsWith('.md'))
422
+ .map((e) => path.join(dir, e.name))
423
+ .sort();
424
+ }
425
+
426
+ interface Overlap {
427
+ id: string;
428
+ active: string[];
429
+ archived: string[];
430
+ }
431
+
432
+ /** id → the files (repo-relative, sorted by input order) declaring it open. */
433
+ function _openIdIndex(files: string[]): Map<string, string[]> {
434
+ const index = new Map<string, string[]>();
435
+ for (const f of files) {
436
+ const rel = _relPosix(f, REPO_ROOT);
437
+ for (const id of _openBlockerIds(fs.readFileSync(f, 'utf-8'))) {
438
+ const hits = index.get(id);
439
+ if (hits === undefined) {
440
+ index.set(id, [rel]);
441
+ } else {
442
+ hits.push(rel);
443
+ }
444
+ }
445
+ }
446
+ return index;
447
+ }
448
+
449
+ /**
450
+ * Blocker ids declared open in BOTH an active and an archived roadmap.
451
+ *
452
+ * The assertion is the one an archived record cannot legitimately make: a
453
+ * blocker still being decided in the active tree, simultaneously declared open
454
+ * in a file that says the work closed. The transition check in
455
+ * `archive_completed_roadmaps` catches the archival that produces this state;
456
+ * this catches it however else it arrives — a hand edit, a bad merge, or a
457
+ * commit that shipped stale index content.
458
+ *
459
+ * `open_blockers` is a shrink-only ratchet over the ACTIVE tree only, so
460
+ * without this the count is satisfiable by archiving rather than by resolving.
461
+ *
462
+ * Deliberately NOT "no id open in more than one file". Two ACTIVE roadmaps may
463
+ * legitimately share one cross-cutting blocker, and forbidding that would break
464
+ * a real pattern to catch a different defect (AI council 2026-09-08, 2/2
465
+ * present: the unscoped form "forbids legitimate cross-cutting blockers in
466
+ * multiple active roadmaps"). Two ARCHIVED files sharing an open id is out of
467
+ * scope for the same day-one reason as the contract itself: measured at 2 on
468
+ * this tree, so a hard assertion there would red the build on records this
469
+ * change did not create.
470
+ */
471
+ function _archiveOverlap(
472
+ activeFiles: string[] = _globRoadmaps(),
473
+ archivedFiles: string[] = _globArchivedRoadmaps(),
474
+ ): Overlap[] {
475
+ const active = _openIdIndex(activeFiles);
476
+ const archived = _openIdIndex(archivedFiles);
477
+ const out: Overlap[] = [];
478
+ for (const [id, activeHits] of [...active.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
479
+ const archivedHits = archived.get(id);
480
+ if (archivedHits !== undefined) {
481
+ out.push({ id, active: activeHits, archived: archivedHits });
482
+ }
483
+ }
484
+ return out;
485
+ }
486
+
363
487
  function main(): number {
364
488
  try {
365
489
  assertScanned({
@@ -411,6 +535,38 @@ function main(): number {
411
535
  return 1;
412
536
  }
413
537
 
538
+ // An archived roadmap says the work closed. An open blocker declared in one
539
+ // AND in an active roadmap therefore contradicts itself, and the shrink-only
540
+ // `open_blockers` ratchet reads the active tree only — so without this the
541
+ // count is satisfiable by archiving rather than by resolving.
542
+ //
543
+ // HARD rather than ratcheted, and measured before it shipped: 0 overlapping
544
+ // ids on this tree at 2026-09-08 (12 active open ids, 33 archived), so on
545
+ // the day it lands it fires on nothing and there is no backlog to
546
+ // grandfather — the same argument the `Class:` contract above makes.
547
+ const overlap = _archiveOverlap();
548
+ if (overlap.length > 0) {
549
+ process.stderr.write(
550
+ `\n❌ ${overlap.length} blocker id(s) declared open in both an active ` +
551
+ 'and an archived roadmap\n',
552
+ );
553
+ for (const o of overlap) {
554
+ process.stderr.write(` ${o.id}\n`);
555
+ for (const rel of o.active) {
556
+ process.stderr.write(` active: ${rel}\n`);
557
+ }
558
+ for (const rel of o.archived) {
559
+ process.stderr.write(` archived: ${rel}\n`);
560
+ }
561
+ }
562
+ process.stderr.write(
563
+ '\n Resolve it in one place. An archived record may keep a blocker that\n' +
564
+ ' was genuinely unresolved when its roadmap closed; it may not keep one\n' +
565
+ ' the active tree is still deciding.\n',
566
+ );
567
+ return 1;
568
+ }
569
+
414
570
  // The decidability ratchet. A blocker that names no option, no command and
415
571
  // no recommendation is a research task handed to the person with the least
416
572
  // context — the defect this half of the gate exists to stop growing.
@@ -434,6 +590,10 @@ function main(): number {
434
590
  }
435
591
  if (!QUIET) {
436
592
  process.stdout.write(`\n✅ ${roadmaps.length} roadmap(s) blocker-contract-clean\n`);
593
+ process.stdout.write(
594
+ `✅ 0 blocker id(s) open in both an active and an archived roadmap ` +
595
+ `(${_globArchivedRoadmaps().length} archived file(s) read)\n`,
596
+ );
437
597
  process.stdout.write(`✅ ${verdict.message}\n`);
438
598
  }
439
599
  return 0;
@@ -477,6 +637,9 @@ export {
477
637
  _scan,
478
638
  _scanBoth,
479
639
  _globRoadmaps,
640
+ _globArchivedRoadmaps,
641
+ _openBlockerIds,
642
+ _archiveOverlap,
480
643
  main,
481
644
  };
482
- export type { Violation, ScanResult };
645
+ export type { Violation, ScanResult, Overlap };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": 1,
3
- "description": "Source-of-truth catalog of consumer-relevant MCP tools. Read by the stdio server (scripts/mcp_server/) and packed into the Cloud Worker bundle (internal/workers/mcp/). The 'implemented_on' field lists transports where the real handler is wired. Entries marked '[stub — implemented on demand]' are DOCUMENTATION of the on-demand backlog: per ADR-132 they are NOT registered on the stdio tools/list (the wire carries implemented tools only); the 'not_implemented' envelope contract (docs/contracts/mcp-tool-stub-envelope.md) remains for Worker parity. Generated by `build_mcp_catalog` — never hand-edit this file.",
4
- "install_hint_stdio": "npx -y @event4u/agent-config mcp-server",
3
+ "description": "Source-of-truth catalog of consumer-relevant MCP tools. Read by the stdio server (scripts/mcp_server/) and packed into the Cloud Worker bundle (internal/workers/mcp/). The 'implemented_on' field lists transports where the real handler is wired. Entries marked '[stub — implemented on demand]' are DOCUMENTATION of the on-demand backlog: per ADR-132 they are NOT registered on the stdio tools/list (the wire carries implemented tools only); the 'not_implemented' envelope contract (docs/contracts/mcp-tool-stub-envelope.md) remains for Worker parity. The 'install_hint_stdio' field is the INSTALLED-BINARY form and therefore assumes `agent-config` is on PATH (a global install, or an npx-resolved one the client already has); it deliberately carries no `npx` invocation, because the un-prompted form of that command is the one string this file's own gate forbids and the prompted form hangs a non-interactive client start. Generated by `build_mcp_catalog` — never hand-edit this file.",
4
+ "install_hint_stdio": "agent-config mcp-server",
5
5
  "tools": [
6
6
  {
7
7
  "name": "capabilities_index",
@@ -222,6 +222,156 @@
222
222
  "readOnlyHint": true
223
223
  }
224
224
  },
225
+ {
226
+ "name": "graph_dead",
227
+ "description": "Symbols with no accepted reference that no declared entry point names. REFUSES (status `refused`) while a source is unreadable: with no exportedness recorded, an exported-but-unimported symbol is indistinguishable from a dead one. Never a deletion recommendation.",
228
+ "side_effect": "ro",
229
+ "implemented_on": [
230
+ "stdio"
231
+ ],
232
+ "input_schema": {
233
+ "type": "object",
234
+ "properties": {
235
+ "entry_points": {
236
+ "type": "string",
237
+ "description": "Path under this root to a newline-separated id/label list; `#` comments ok."
238
+ },
239
+ "accept_missing_exports": {
240
+ "type": "boolean",
241
+ "default": false,
242
+ "description": "Answer anyway, accepting the gap. Never a default."
243
+ }
244
+ },
245
+ "additionalProperties": false
246
+ },
247
+ "annotations": {
248
+ "readOnlyHint": true
249
+ }
250
+ },
251
+ {
252
+ "name": "graph_impact",
253
+ "description": "What a diff can break: callers, dependents and test files reaching the changed symbols. Walks only stated-fact edges, never a same-name guess, and reports the guesses refused. Runs `git diff` for the rev.",
254
+ "side_effect": "shell",
255
+ "implemented_on": [
256
+ "stdio"
257
+ ],
258
+ "input_schema": {
259
+ "type": "object",
260
+ "required": [
261
+ "diff"
262
+ ],
263
+ "properties": {
264
+ "diff": {
265
+ "type": "string",
266
+ "description": "Git rev to diff HEAD against, e.g. `HEAD~1`."
267
+ },
268
+ "depth": {
269
+ "type": "integer",
270
+ "minimum": 1,
271
+ "default": 2,
272
+ "description": "Hop limit."
273
+ },
274
+ "untested_only": {
275
+ "type": "boolean",
276
+ "default": false,
277
+ "description": "Instead return changed symbols no test imports."
278
+ }
279
+ },
280
+ "additionalProperties": false
281
+ },
282
+ "annotations": {
283
+ "readOnlyHint": false
284
+ }
285
+ },
286
+ {
287
+ "name": "graph_path",
288
+ "description": "The shortest relation chain between two symbols, direction preserved. Answers \"how does A reach B\" without reading the files between. `(no path found)` when unconnected is an answer.",
289
+ "side_effect": "ro",
290
+ "implemented_on": [
291
+ "stdio"
292
+ ],
293
+ "input_schema": {
294
+ "type": "object",
295
+ "required": [
296
+ "from",
297
+ "to"
298
+ ],
299
+ "properties": {
300
+ "from": {
301
+ "type": "string",
302
+ "description": "Start node id, label, or free text."
303
+ },
304
+ "to": {
305
+ "type": "string",
306
+ "description": "Goal node id, label, or free text."
307
+ },
308
+ "budget": {
309
+ "type": "integer",
310
+ "minimum": 1,
311
+ "default": 1500,
312
+ "description": "Token budget for lines."
313
+ }
314
+ },
315
+ "additionalProperties": false
316
+ },
317
+ "annotations": {
318
+ "readOnlyHint": true
319
+ }
320
+ },
321
+ {
322
+ "name": "graph_query",
323
+ "description": "A symbol's direct outgoing relations — calls, imports, uses, inherits — each line carrying its confidence and resolution mechanism. For \"what does this touch\" before reading a file.",
324
+ "side_effect": "ro",
325
+ "implemented_on": [
326
+ "stdio"
327
+ ],
328
+ "input_schema": {
329
+ "type": "object",
330
+ "required": [
331
+ "symbol"
332
+ ],
333
+ "properties": {
334
+ "symbol": {
335
+ "type": "string",
336
+ "description": "Node id, label, or free text."
337
+ },
338
+ "budget": {
339
+ "type": "integer",
340
+ "minimum": 1,
341
+ "default": 1500,
342
+ "description": "Token budget for lines."
343
+ }
344
+ },
345
+ "additionalProperties": false
346
+ },
347
+ "annotations": {
348
+ "readOnlyHint": true
349
+ }
350
+ },
351
+ {
352
+ "name": "graph_tests_for",
353
+ "description": "Which test files exercise a symbol, derived from a test file importing it or its module. Empty means no test imports it — a finding, not an error.",
354
+ "side_effect": "ro",
355
+ "implemented_on": [
356
+ "stdio"
357
+ ],
358
+ "input_schema": {
359
+ "type": "object",
360
+ "required": [
361
+ "symbol"
362
+ ],
363
+ "properties": {
364
+ "symbol": {
365
+ "type": "string",
366
+ "description": "Node id `<relpath>#<sym>`, label, or free text."
367
+ }
368
+ },
369
+ "additionalProperties": false
370
+ },
371
+ "annotations": {
372
+ "readOnlyHint": true
373
+ }
374
+ },
225
375
  {
226
376
  "name": "lint_skills",
227
377
  "description": "Lint skill, rule, command, guideline, and persona markdown files for frontmatter and structural errors. Use before committing or opening a PR that adds or edits any of those artifacts, to catch schema violations early. Read-only — never writes files or spawns git. Returns the `scripts/skill_linter.py --format json` payload: a `summary` object (pass / pass_with_warnings / fail / total counts) and a per-file `results` array with severity-tagged findings. Pass `paths` to lint a subset; omit for a full tree scan.",
@@ -0,0 +1,294 @@
1
+ /**
2
+ * The five code-graph MCP tools (`road-to-a-graph-that-is-shipped` 4.1).
3
+ *
4
+ * `graph_impact`, `graph_tests_for`, `graph_dead`, `graph_query`, `graph_path`.
5
+ * They are the agent-facing half of Phase 3: the verbs exist on the CLI and an
6
+ * agent that has to shell out to reach them will not, so the engine's answers
7
+ * were unreachable from the surface the consumer actually talks to. Risk-Register
8
+ * rank 1 is precisely "the install grows and the graph is still unread"; these
9
+ * are the readers.
10
+ *
11
+ * REGISTERED HERE, NOT IN `tools.ts`.
12
+ *
13
+ * `tools.ts` sits ~500 lines past the 1500-line ceiling
14
+ * `check_source_size_budget` enforces as a shrink-only ratchet, so five tool
15
+ * records with their schemas would cost ~150 units of excess there and nothing
16
+ * here. `tools.ts` spreads {@link GRAPH_TOOLS} into `ALLOWLIST`, which is two
17
+ * lines — paid for by moving `_strip` / `_resolvePath` out to `path_util.ts` in
18
+ * the same change.
19
+ *
20
+ * TELEMETRY NEEDS NO PER-TOOL WORK.
21
+ *
22
+ * `ToolCache.dispatch` records every `tools/call` centrally, so these five emit
23
+ * the identical line the other 31 do by being in `ALLOWLIST` at all — which is
24
+ * what the step's "same telemetry line as the other 31" asks for, and is
25
+ * stronger than a per-tool emit because it cannot be forgotten.
26
+ *
27
+ * READ-ONLY, WITH ONE HONEST EXCEPTION.
28
+ *
29
+ * Four are `side_effect: 'ro'`. `graph_impact` is `'shell'`, because it resolves
30
+ * its `diff` argument by running `git diff --name-only`. That subprocess is
31
+ * read-only in effect, and the enum has no value that says so — between
32
+ * understating the mechanism as `'ro'` and naming it, naming it is the only
33
+ * choice a capability enum exists to support.
34
+ */
35
+ import * as fs from 'node:fs';
36
+ import * as path from 'node:path';
37
+
38
+ import { changedFiles } from '../code_graph/cli.js';
39
+ import { detectSources, graphState, NATIVE_CACHE_REL, pickSource } from '../code_graph/detect.js';
40
+ import { resolvePath } from './path_util.js';
41
+ import { isTestFile } from '../code_graph/build.js';
42
+ import { loadGraph, type LoadedGraph, path as graphPathVerb, query as graphQueryVerb } from '../code_graph/query.js';
43
+ import {
44
+ dead,
45
+ entryPointsFromFile,
46
+ impact,
47
+ repoEntryPoints,
48
+ testsFor,
49
+ untested,
50
+ } from '../code_graph/verbs.js';
51
+ import type { BuiltinTool } from './tools.js';
52
+
53
+ /** The `no graph here` answer, in one place so all five agree on its shape. */
54
+ function noGraph(root: string): Record<string, unknown> {
55
+ return {
56
+ status: 'unavailable',
57
+ staleness: 'absent',
58
+ error:
59
+ 'no code-graph source found under this root — run `agent-config code-graph build` ' +
60
+ 'to build one, or ship a graph.json',
61
+ root,
62
+ };
63
+ }
64
+
65
+ /**
66
+ * Resolve the graph, run `fn`, release the handle.
67
+ *
68
+ * The handle owns an open SQLite database on the indexed path, so the `finally`
69
+ * is not hygiene — a long-lived MCP server that leaked one per call would hold
70
+ * a descriptor for the life of the process.
71
+ */
72
+ function withGraph<T extends Record<string, unknown>>(
73
+ root: string,
74
+ fn: (g: LoadedGraph) => T,
75
+ ): Record<string, unknown> {
76
+ const picked = pickSource(detectSources(root, path.join(root, NATIVE_CACHE_REL)));
77
+ if (!picked || picked.kind === 'scip') return noGraph(root);
78
+ const g = loadGraph(picked.path, `${picked.kind}:${path.relative(root, picked.path)}`);
79
+ try {
80
+ const out = fn(g);
81
+ // `status` is DERIVED from the answer, never prefixed onto it. An
82
+ // independent review found `graph_dead`'s refusal returning
83
+ // `{status:'ok', refusal:'…', dead:[]}` — the same status a real answer
84
+ // carries, so a caller branching on `status` (which every fixture here
85
+ // trains it to do) read the refusal as "nothing is dead". That is the
86
+ // false negative the CLI's exit 1 exists to prevent, arriving over the
87
+ // wire instead. A refusal is its own status.
88
+ const refused = typeof out['refusal'] === 'string' && out['refusal'] !== '';
89
+ return { status: refused ? 'refused' : 'ok', ...out };
90
+ } finally {
91
+ g.close();
92
+ }
93
+ }
94
+
95
+ function str(args: Record<string, unknown>, key: string): string {
96
+ const v = args[key];
97
+ return typeof v === 'string' ? v.trim() : '';
98
+ }
99
+
100
+ function num(args: Record<string, unknown>, key: string, dflt: number): number {
101
+ const v = args[key];
102
+ return typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : dflt;
103
+ }
104
+
105
+ export const GRAPH_TOOLS: Record<string, BuiltinTool> = {
106
+ graph_impact: {
107
+ name: 'graph_impact',
108
+ side_effect: 'shell',
109
+ description:
110
+ 'What a diff can break: callers, dependents and test files reaching the ' +
111
+ 'changed symbols. Walks only stated-fact edges, never a same-name guess, ' +
112
+ 'and reports the guesses refused. Runs `git diff` for the rev.',
113
+ input_schema: {
114
+ type: 'object',
115
+ required: ['diff'],
116
+ properties: {
117
+ diff: { type: 'string', description: 'Git rev to diff HEAD against, e.g. `HEAD~1`.' },
118
+ depth: { type: 'integer', minimum: 1, default: 2, description: 'Hop limit.' },
119
+ untested_only: {
120
+ type: 'boolean',
121
+ default: false,
122
+ description: 'Instead return changed symbols no test imports.',
123
+ },
124
+ },
125
+ additionalProperties: false,
126
+ },
127
+ handler: async (args, root) => {
128
+ const rev = str(args, 'diff');
129
+ if (rev === '') return { status: 'error', error: 'diff must be a non-empty git rev' };
130
+ const files = changedFiles(root, rev);
131
+ if (files === null) return { status: 'error', error: `cannot resolve rev '${rev}' in ${root}` };
132
+ const state = graphState(root);
133
+ return withGraph(root, (g) =>
134
+ args['untested_only'] === true
135
+ ? { ...untested(g, files, state), changed_files: files.length }
136
+ : { ...impact(g, files, state, num(args, 'depth', 2), isTestFile), changed_files: files.length },
137
+ );
138
+ },
139
+ },
140
+
141
+ graph_tests_for: {
142
+ name: 'graph_tests_for',
143
+ side_effect: 'ro',
144
+ description:
145
+ 'Which test files exercise a symbol, derived from a test file importing ' +
146
+ 'it or its module. Empty means no test imports it — a finding, not an error.',
147
+ input_schema: {
148
+ type: 'object',
149
+ required: ['symbol'],
150
+ properties: {
151
+ symbol: { type: 'string', description: 'Node id `<relpath>#<sym>`, label, or free text.' },
152
+ },
153
+ additionalProperties: false,
154
+ },
155
+ handler: async (args, root) => {
156
+ const symbol = str(args, 'symbol');
157
+ if (symbol === '') return { status: 'error', error: 'symbol must be a non-empty string' };
158
+ const state = graphState(root);
159
+ return withGraph(root, (g) => ({ ...testsFor(g, symbol, state) }));
160
+ },
161
+ },
162
+
163
+ graph_dead: {
164
+ name: 'graph_dead',
165
+ side_effect: 'ro',
166
+ description:
167
+ 'Symbols with no accepted reference that no declared entry point names. ' +
168
+ 'REFUSES (status `refused`) while a source is unreadable: with no ' +
169
+ 'exportedness recorded, an exported-but-unimported symbol is ' +
170
+ 'indistinguishable from a dead one. Never a deletion recommendation.',
171
+ input_schema: {
172
+ type: 'object',
173
+ properties: {
174
+ entry_points: {
175
+ type: 'string',
176
+ description: 'Path under this root to a newline-separated id/label list; `#` comments ok.',
177
+ },
178
+ accept_missing_exports: {
179
+ type: 'boolean',
180
+ default: false,
181
+ description: 'Answer anyway, accepting the gap. Never a default.',
182
+ },
183
+ },
184
+ additionalProperties: false,
185
+ },
186
+ handler: async (args, root) => {
187
+ const state = graphState(root);
188
+ const listArg = str(args, 'entry_points');
189
+ let sources = repoEntryPoints(root);
190
+ if (listArg !== '') {
191
+ // REALPATH containment, matching the sibling pattern in
192
+ // `tools.ts` rather than reimplementing a weaker one — an
193
+ // independent review found this check using `path.resolve` +
194
+ // `startsWith`, which a symlink inside the root walks straight
195
+ // through, in the same change that extracted `resolvePath` for
196
+ // reuse. `fs.readFileSync` would then follow the link, and
197
+ // because the file's lines used to be echoed back in the
198
+ // response (see `entry_count` below) that was an
199
+ // arbitrary-file-read path.
200
+ const abs = resolvePath(path.resolve(root, listArg));
201
+ const rootReal = resolvePath(path.resolve(root));
202
+ if (abs !== rootReal && !abs.startsWith(rootReal + path.sep)) {
203
+ return { status: 'error', error: `path escapes consumer_root: ${abs}` };
204
+ }
205
+ if (!fs.existsSync(abs)) return { status: 'error', error: `entry-point list not found: ${listArg}` };
206
+ sources = [
207
+ ...sources.map((s) =>
208
+ s.name === 'exports'
209
+ ? { ...s, status: 'read' as const, detail: `supplied by ${listArg}`, entries: [] }
210
+ : s,
211
+ ),
212
+ entryPointsFromFile(abs),
213
+ ];
214
+ }
215
+ return withGraph(root, (g) => {
216
+ const r = dead(g, sources, state, {
217
+ acceptMissingExports: args['accept_missing_exports'] === true,
218
+ });
219
+ // The `entries` arrays are NOT returned. On this repository they
220
+ // are ~2,595 identifier strings — an unbounded per-call payload
221
+ // beside the standing-cost row this change itself adds — and
222
+ // returning a file the caller named is what made the
223
+ // containment check above a read primitive. A count answers the
224
+ // question a caller actually has ("was this source read, and did
225
+ // it have anything in it") without shipping the contents.
226
+ return {
227
+ ...r,
228
+ sources: r.sources.map((srcRow) => ({
229
+ name: srcRow.name,
230
+ status: srcRow.status,
231
+ ...(srcRow.detail === undefined ? {} : { detail: srcRow.detail }),
232
+ entry_count: srcRow.entries.length,
233
+ })),
234
+ };
235
+ });
236
+ },
237
+ },
238
+
239
+ graph_query: {
240
+ name: 'graph_query',
241
+ side_effect: 'ro',
242
+ description:
243
+ "A symbol's direct outgoing relations — calls, imports, uses, inherits — " +
244
+ 'each line carrying its confidence and resolution mechanism. For "what ' +
245
+ 'does this touch" before reading a file.',
246
+ input_schema: {
247
+ type: 'object',
248
+ required: ['symbol'],
249
+ properties: {
250
+ symbol: { type: 'string', description: 'Node id, label, or free text.' },
251
+ budget: { type: 'integer', minimum: 1, default: 1500, description: 'Token budget for lines.' },
252
+ },
253
+ additionalProperties: false,
254
+ },
255
+ handler: async (args, root) => {
256
+ const symbol = str(args, 'symbol');
257
+ if (symbol === '') return { status: 'error', error: 'symbol must be a non-empty string' };
258
+ const staleness = graphState(root);
259
+ return withGraph(root, (g) => ({
260
+ staleness,
261
+ ...graphQueryVerb(g, symbol, num(args, 'budget', 1500)),
262
+ }));
263
+ },
264
+ },
265
+
266
+ graph_path: {
267
+ name: 'graph_path',
268
+ side_effect: 'ro',
269
+ description:
270
+ 'The shortest relation chain between two symbols, direction preserved. ' +
271
+ 'Answers "how does A reach B" without reading the files between. ' +
272
+ '`(no path found)` when unconnected is an answer.',
273
+ input_schema: {
274
+ type: 'object',
275
+ required: ['from', 'to'],
276
+ properties: {
277
+ from: { type: 'string', description: 'Start node id, label, or free text.' },
278
+ to: { type: 'string', description: 'Goal node id, label, or free text.' },
279
+ budget: { type: 'integer', minimum: 1, default: 1500, description: 'Token budget for lines.' },
280
+ },
281
+ additionalProperties: false,
282
+ },
283
+ handler: async (args, root) => {
284
+ const from = str(args, 'from');
285
+ const to = str(args, 'to');
286
+ if (from === '' || to === '') return { status: 'error', error: 'from and to must be non-empty strings' };
287
+ const staleness = graphState(root);
288
+ return withGraph(root, (g) => ({
289
+ staleness,
290
+ ...graphPathVerb(g, from, to, num(args, 'budget', 1500)),
291
+ }));
292
+ },
293
+ },
294
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Two string/path helpers extracted from `tools.ts`.
3
+ *
4
+ * They are generic — a whitespace trim and a tolerant realpath — and `tools.ts`
5
+ * sits ~525 lines past the 1500-line ceiling `check_source_size_budget`
6
+ * enforces as a shrink-only ratchet, so every line there costs one unit of
7
+ * excess and the gate names re-pinning the baseline a defect rather than a fix.
8
+ * Moving them here pays for the graph-tool registration that arrives with
9
+ * `road-to-a-graph-that-is-shipped` 4.1, and puts them in a file where their
10
+ * prose is free.
11
+ *
12
+ * They are imported under their original underscore-prefixed names, so the
13
+ * 28 call sites in `tools.ts` are unchanged — a rename would have made a
14
+ * two-function move read as a sweep.
15
+ */
16
+ import * as fs from 'node:fs';
17
+ import * as path from 'node:path';
18
+
19
+ /** Mirror Python `str.strip()` (also strips the same Unicode whitespace set we care about here). */
20
+ export function strip(s: string): string {
21
+ return s.replace(/^\s+/, '').replace(/\s+$/, '');
22
+ }
23
+
24
+ /** Mirror Python `Path(...).resolve()` — absolutize + realpath, tolerating a missing tail. */
25
+ export function resolvePath(p: string): string {
26
+ try {
27
+ return fs.realpathSync(p);
28
+ } catch {
29
+ return path.resolve(p);
30
+ }
31
+ }