@event4u/agent-config 7.5.0 → 8.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 (428) hide show
  1. package/.claude-plugin/marketplace.json +8 -1
  2. package/AGENTS.md +9 -9
  3. package/CHANGELOG.md +325 -0
  4. package/README.md +35 -5
  5. package/dist/agent-src/commands/analytics/prune.md +1 -1
  6. package/dist/agent-src/commands/analytics/show.md +1 -1
  7. package/dist/agent-src/commands/analyze/decision.md +2 -2
  8. package/dist/agent-src/commands/analyze/incident.md +2 -2
  9. package/dist/agent-src/commands/analyze/near-miss.md +2 -2
  10. package/dist/agent-src/commands/analyze/postmortem.md +2 -2
  11. package/dist/agent-src/commands/analyze/premortem.md +2 -2
  12. package/dist/agent-src/commands/cost-report.md +25 -0
  13. package/dist/agent-src/commands/evals/analyze.json +30 -0
  14. package/dist/agent-src/commands/evals/mission-upgrade.json +30 -0
  15. package/dist/agent-src/commands/implement-ticket.md +1 -1
  16. package/dist/agent-src/commands/knowledge/forget.md +1 -1
  17. package/dist/agent-src/commands/knowledge/ingest.md +1 -1
  18. package/dist/agent-src/commands/knowledge/list.md +1 -1
  19. package/dist/agent-src/commands/memory/load.md +12 -11
  20. package/dist/agent-src/commands/memory/promote.md +30 -0
  21. package/dist/agent-src/commands/memory/propose.md +16 -2
  22. package/dist/agent-src/commands/mission/upgrade.md +1 -1
  23. package/dist/agent-src/commands/module/explore.md +11 -7
  24. package/dist/agent-src/commands/optimize-project.md +243 -0
  25. package/dist/agent-src/commands/optimize.md +5 -0
  26. package/dist/agent-src/commands/pr/create.md +37 -8
  27. package/dist/agent-src/commands/prediction-pool.md +2 -2
  28. package/dist/agent-src/commands/profile/activate.md +3 -3
  29. package/dist/agent-src/commands/profile/deactivate.md +2 -2
  30. package/dist/agent-src/commands/profile/show.md +3 -3
  31. package/dist/agent-src/commands/research/deep.md +5 -0
  32. package/dist/agent-src/commands/research/report.md +2 -1
  33. package/dist/agent-src/commands/roadmap/create.md +88 -10
  34. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  35. package/dist/agent-src/commands/roadmap/process-full.md +15 -2
  36. package/dist/agent-src/commands/roadmap/process-phase.md +18 -6
  37. package/dist/agent-src/commands/roadmap/process-step.md +4 -0
  38. package/dist/agent-src/commands/roadmap.md +1 -1
  39. package/dist/agent-src/commands/security-audit-config.md +1 -1
  40. package/dist/agent-src/commands/sync-agent-settings.md +1 -1
  41. package/dist/agent-src/commands/sync-gitignore/fix.md +42 -6
  42. package/dist/agent-src/commands/team-knowledge/bootstrap.md +106 -0
  43. package/dist/agent-src/commands/team-knowledge/consolidate.md +105 -0
  44. package/dist/agent-src/commands/team-knowledge.md +64 -0
  45. package/dist/agent-src/contexts/authority/commit-mechanics.md +8 -0
  46. package/dist/agent-src/contexts/authority/destructive-mechanics.md +11 -0
  47. package/dist/agent-src/contexts/authority/scope-mechanics.md +25 -0
  48. package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +43 -0
  49. package/dist/agent-src/contexts/contracts/agents-md-anatomy.md +1 -1
  50. package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +2 -2
  51. package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -0
  52. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +14 -4
  53. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +11 -0
  54. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +32 -8
  55. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +107 -0
  56. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +71 -15
  57. package/dist/agent-src/contexts/execution/subagent-steering.md +41 -1
  58. package/dist/agent-src/contexts/override-system.md +1 -1
  59. package/dist/agent-src/personas/brand-strategist.md +0 -1
  60. package/dist/agent-src/personas/data-integrity.md +66 -0
  61. package/dist/agent-src/personas/design-director.md +0 -1
  62. package/dist/agent-src/personas/performance-engineer.md +66 -0
  63. package/dist/agent-src/personas/production-validator.md +73 -0
  64. package/dist/agent-src/rules/agent-authority.md +3 -4
  65. package/dist/agent-src/rules/analysis-skill-routing.md +3 -5
  66. package/dist/agent-src/rules/architecture.md +2 -4
  67. package/dist/agent-src/rules/artifact-drafting-protocol.md +35 -6
  68. package/dist/agent-src/rules/artifact-engagement-recording.md +2 -4
  69. package/dist/agent-src/rules/ask-when-uncertain.md +10 -14
  70. package/dist/agent-src/rules/augment-edit-discipline.md +3 -5
  71. package/dist/agent-src/rules/autonomous-execution.md +3 -5
  72. package/dist/agent-src/rules/brand-consistency.md +3 -5
  73. package/dist/agent-src/rules/brand-source-of-truth.md +3 -5
  74. package/dist/agent-src/rules/cli-output-handling.md +4 -6
  75. package/dist/agent-src/rules/command-suggestion-policy.md +3 -5
  76. package/dist/agent-src/rules/commit-conventions.md +3 -5
  77. package/dist/agent-src/rules/commit-policy.md +8 -10
  78. package/dist/agent-src/rules/content-quoting-floor.md +88 -0
  79. package/dist/agent-src/rules/context-hygiene.md +3 -5
  80. package/dist/agent-src/rules/copilot-routing.md +4 -6
  81. package/dist/agent-src/rules/decision-revisit-gate.md +120 -0
  82. package/dist/agent-src/rules/delegation-policy.md +10 -6
  83. package/dist/agent-src/rules/design-fidelity.md +3 -5
  84. package/dist/agent-src/rules/devcontainer-routing.md +4 -6
  85. package/dist/agent-src/rules/direct-answers.md +13 -17
  86. package/dist/agent-src/rules/docker-commands.md +3 -5
  87. package/dist/agent-src/rules/domain-adoption-policy.md +3 -5
  88. package/dist/agent-src/rules/domain-safety-disclaimer.md +3 -5
  89. package/dist/agent-src/rules/domain-safety-pii.md +3 -5
  90. package/dist/agent-src/rules/domain-safety-retention.md +3 -5
  91. package/dist/agent-src/rules/downstream-changes.md +3 -4
  92. package/dist/agent-src/rules/engineering-safety-floor.md +3 -5
  93. package/dist/agent-src/rules/external-reference-deep-dive.md +3 -5
  94. package/dist/agent-src/rules/fast-path-marker-visibility.md +3 -5
  95. package/dist/agent-src/rules/finance-safety-floor.md +3 -6
  96. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -5
  97. package/dist/agent-src/rules/git-history-discipline.md +3 -5
  98. package/dist/agent-src/rules/guidelines.md +2 -4
  99. package/dist/agent-src/rules/icon-consistency.md +3 -5
  100. package/dist/agent-src/rules/image-likeness-and-rights.md +3 -5
  101. package/dist/agent-src/rules/improve-before-implement.md +5 -5
  102. package/dist/agent-src/rules/invite-challenge.md +3 -5
  103. package/dist/agent-src/rules/language-and-tone.md +13 -15
  104. package/dist/agent-src/rules/laravel-routing.md +3 -5
  105. package/dist/agent-src/rules/laravel-translations.md +3 -5
  106. package/dist/agent-src/rules/legal-safety-floor.md +3 -5
  107. package/dist/agent-src/rules/lethal-trifecta-guard.md +3 -5
  108. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +4 -7
  109. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +3 -5
  110. package/dist/agent-src/rules/markdown-safe-codeblocks.md +2 -4
  111. package/dist/agent-src/rules/media-governance-routing.md +3 -5
  112. package/dist/agent-src/rules/media-sync-ground-truth.md +3 -5
  113. package/dist/agent-src/rules/minimal-safe-diff.md +5 -5
  114. package/dist/agent-src/rules/missing-tool-handling.md +3 -5
  115. package/dist/agent-src/rules/model-recommendation.md +4 -6
  116. package/dist/agent-src/rules/no-attribution-footers.md +3 -5
  117. package/dist/agent-src/rules/no-cheap-questions.md +5 -8
  118. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +3 -6
  119. package/dist/agent-src/rules/no-pr-progress-comments.md +3 -6
  120. package/dist/agent-src/rules/no-roadmap-references.md +3 -5
  121. package/dist/agent-src/rules/non-destructive-by-default.md +11 -13
  122. package/dist/agent-src/rules/notes-first-reasoning.md +3 -5
  123. package/dist/agent-src/rules/onboarding-gate.md +4 -6
  124. package/dist/agent-src/rules/output-discipline.md +3 -5
  125. package/dist/agent-src/rules/package-ci-checks.md +3 -5
  126. package/dist/agent-src/rules/persona-governance.md +2 -4
  127. package/dist/agent-src/rules/php-coding.md +3 -5
  128. package/dist/agent-src/rules/preservation-guard.md +2 -4
  129. package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -5
  130. package/dist/agent-src/rules/reviewer-awareness.md +5 -6
  131. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +3 -5
  132. package/dist/agent-src/rules/roadmap-progress-sync.md +5 -5
  133. package/dist/agent-src/rules/role-mode-adherence.md +2 -4
  134. package/dist/agent-src/rules/rule-type-governance.md +3 -5
  135. package/dist/agent-src/rules/runtime-safety.md +2 -4
  136. package/dist/agent-src/rules/scope-control.md +10 -11
  137. package/dist/agent-src/rules/security-sensitive-stop.md +4 -5
  138. package/dist/agent-src/rules/size-enforcement.md +2 -4
  139. package/dist/agent-src/rules/skill-improvement-trigger.md +3 -5
  140. package/dist/agent-src/rules/skill-quality.md +3 -5
  141. package/dist/agent-src/rules/slash-command-routing-policy.md +3 -5
  142. package/dist/agent-src/rules/source-confidentiality.md +3 -5
  143. package/dist/agent-src/rules/source-discovery-gate.md +3 -5
  144. package/dist/agent-src/rules/source-of-truth.md +3 -5
  145. package/dist/agent-src/rules/strategy-safety-floor.md +3 -5
  146. package/dist/agent-src/rules/symfony-routing.md +4 -6
  147. package/dist/agent-src/rules/telegraph-speak.md +4 -5
  148. package/dist/agent-src/rules/think-before-action.md +7 -4
  149. package/dist/agent-src/rules/token-budget-discipline.md +29 -5
  150. package/dist/agent-src/rules/token-efficiency.md +3 -5
  151. package/dist/agent-src/rules/token-optimizer-maintenance.md +3 -5
  152. package/dist/agent-src/rules/tool-safety.md +2 -4
  153. package/dist/agent-src/rules/ui-audit-gate.md +3 -6
  154. package/dist/agent-src/rules/untrusted-input-defense.md +3 -5
  155. package/dist/agent-src/rules/upstream-proposal.md +4 -6
  156. package/dist/agent-src/rules/user-interaction.md +7 -5
  157. package/dist/agent-src/rules/user-interrupt-priority.md +17 -8
  158. package/dist/agent-src/rules/verify-before-complete.md +12 -22
  159. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +3 -3
  160. package/dist/agent-src/scripts/update_roadmap_progress.ts +197 -7
  161. package/dist/agent-src/skills/adr-create/SKILL.md +48 -42
  162. package/dist/agent-src/skills/agent-docs-writing/SKILL.md +18 -0
  163. package/dist/agent-src/skills/agent-security-review/SKILL.md +1 -1
  164. package/dist/agent-src/skills/ai-council/SKILL.md +14 -1
  165. package/dist/agent-src/skills/blameless-post-mortem/SKILL.md +0 -3
  166. package/dist/agent-src/skills/brand/SKILL.md +1 -1
  167. package/dist/agent-src/skills/brand-identity/SKILL.md +3 -3
  168. package/dist/agent-src/skills/brand-strategy/SKILL.md +1 -1
  169. package/dist/agent-src/skills/brand-to-tokens/SKILL.md +3 -3
  170. package/dist/agent-src/skills/canvas-design/SKILL.md +6 -0
  171. package/dist/agent-src/skills/check-refs/SKILL.md +7 -4
  172. package/dist/agent-src/skills/code-review/SKILL.md +1 -0
  173. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +6 -5
  174. package/dist/agent-src/skills/condense-memory/SKILL.md +11 -11
  175. package/dist/agent-src/skills/context-document/SKILL.md +17 -0
  176. package/dist/agent-src/skills/corpus-grounding/SKILL.md +3 -3
  177. package/dist/agent-src/skills/decision-record/SKILL.md +6 -0
  178. package/dist/agent-src/skills/decision-review/SKILL.md +5 -3
  179. package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +6 -1
  180. package/dist/agent-src/skills/design-intelligence/SKILL.md +5 -2
  181. package/dist/agent-src/skills/design-intelligence/references/design-languages.md +1 -1
  182. package/dist/agent-src/skills/design-tokens/SKILL.md +10 -4
  183. package/dist/agent-src/skills/design-variations/SKILL.md +127 -0
  184. package/dist/agent-src/skills/design-variations/evals/triggers.json +17 -0
  185. package/dist/agent-src/skills/emit-tickets/SKILL.md +4 -4
  186. package/dist/agent-src/skills/fe-design/SKILL.md +20 -0
  187. package/dist/agent-src/skills/html-deck/SKILL.md +123 -0
  188. package/dist/agent-src/skills/html-deck/evals/triggers.json +17 -0
  189. package/dist/agent-src/skills/html-deck/templates/deck-shell.html +77 -0
  190. package/dist/agent-src/skills/judge-code-quality/SKILL.md +1 -0
  191. package/dist/agent-src/skills/laravel/SKILL.md +0 -1
  192. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +46 -0
  193. package/dist/agent-src/skills/lint-skills/SKILL.md +6 -6
  194. package/dist/agent-src/skills/md-language-check/SKILL.md +3 -3
  195. package/dist/agent-src/skills/memory-consolidation/SKILL.md +66 -1
  196. package/dist/agent-src/skills/migration-architect/SKILL.md +1 -0
  197. package/dist/agent-src/skills/module-detect-on-the-fly/SKILL.md +2 -2
  198. package/dist/agent-src/skills/performance-analysis/SKILL.md +2 -0
  199. package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +4 -4
  200. package/dist/agent-src/skills/premortem/SKILL.md +0 -3
  201. package/dist/agent-src/skills/project-analysis-core/SKILL.md +16 -0
  202. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +3 -1
  203. package/dist/agent-src/skills/release-comms/SKILL.md +46 -45
  204. package/dist/agent-src/skills/roadmap-management/SKILL.md +21 -0
  205. package/dist/agent-src/skills/roadmap-writing/SKILL.md +32 -2
  206. package/dist/agent-src/skills/root-cause-frameworks/SKILL.md +0 -3
  207. package/dist/agent-src/skills/security-audit/SKILL.md +1 -0
  208. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +4 -0
  209. package/dist/agent-src/skills/source-discovery/SKILL.md +22 -3
  210. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +33 -14
  211. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +11 -0
  212. package/dist/agent-src/skills/subagent-orchestration/prompts/do-in-steps.md +8 -0
  213. package/dist/agent-src/skills/systematic-debugging/SKILL.md +29 -0
  214. package/dist/agent-src/skills/threat-modeling/SKILL.md +2 -2
  215. package/dist/agent-src/skills/typography-system/SKILL.md +2 -2
  216. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -0
  217. package/dist/agent-src/skills/wireframe/SKILL.md +118 -0
  218. package/dist/agent-src/skills/wireframe/evals/triggers.json +17 -0
  219. package/dist/agent-src/templates/agent-settings.md +22 -1
  220. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  221. package/dist/agent-src/templates/command.md +2 -2
  222. package/dist/agent-src/templates/contexts/knowledge-pages.md +116 -0
  223. package/dist/agent-src/templates/hooks/pre-commit-frontmatter +1 -1
  224. package/dist/agent-src/templates/roadmaps.md +70 -2
  225. package/dist/agent-src/templates/rule.md +1 -1
  226. package/dist/agent-src/templates/scripts/README.md +3 -3
  227. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +109 -0
  228. package/dist/agent-src/templates/tickets.md +8 -8
  229. package/dist/cli/commands/recordTriggerEval.test.js +1 -1
  230. package/dist/cli/commands/recordTriggerEval.test.js.map +1 -1
  231. package/dist/cli/initRouting.js +4 -2
  232. package/dist/cli/initRouting.js.map +1 -1
  233. package/dist/cli/registry.js +1 -0
  234. package/dist/cli/registry.js.map +1 -1
  235. package/dist/discovery/deprecation-report.md +1 -1
  236. package/dist/discovery/discovery-manifest.json +718 -240
  237. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  238. package/dist/discovery/discovery-manifest.summary.md +8 -8
  239. package/dist/discovery/orphan-report.md +1 -1
  240. package/dist/discovery/packs.json +43 -28
  241. package/dist/discovery/trust-report.md +12 -11
  242. package/dist/discovery/workspaces.json +29 -18
  243. package/dist/install/preflight.js +173 -0
  244. package/dist/install/preflight.js.map +1 -0
  245. package/dist/mcp/registry-manifest.json +4 -4
  246. package/dist/router.json +1 -1
  247. package/dist/server/routes/settings.js +4 -0
  248. package/dist/server/routes/settings.js.map +1 -1
  249. package/dist/server/schemas/settings.js +3 -1
  250. package/dist/server/schemas/settings.js.map +1 -1
  251. package/docs/CLAIMS.md +108 -0
  252. package/docs/MIGRATION.md +3 -3
  253. package/docs/architecture.md +5 -5
  254. package/docs/benchmark.md +133 -2
  255. package/docs/benchmark.pinned.yml +31 -0
  256. package/docs/capability-matrix.md +1 -0
  257. package/docs/catalog.md +70 -60
  258. package/docs/command-flows.md +15 -3
  259. package/docs/comparison.yaml +35 -0
  260. package/docs/contracts/agents-layout.md +148 -0
  261. package/docs/contracts/brand-token-consumption.md +5 -0
  262. package/docs/contracts/capability-boundary.md +5 -0
  263. package/docs/contracts/command-category-governance.md +5 -0
  264. package/docs/contracts/command-clusters.md +1 -0
  265. package/docs/contracts/command-surface-tiers.md +1 -1
  266. package/docs/contracts/conformance.md +84 -0
  267. package/docs/contracts/creative-pack-boundary.md +5 -0
  268. package/docs/contracts/discovery-manifest.schema.json +5 -4
  269. package/docs/contracts/file-ownership-matrix.json +4605 -985
  270. package/docs/contracts/governance-enforcement-projection.md +5 -0
  271. package/docs/contracts/gui-wizard.md +1 -1
  272. package/docs/contracts/hook-architecture-v1.md +2 -2
  273. package/docs/contracts/implement-ticket-flow.md +1 -1
  274. package/docs/contracts/kernel-membership.md +13 -0
  275. package/docs/contracts/mcp-tool-inventory.md +23 -23
  276. package/docs/contracts/no-runtime-boundary.md +6 -1
  277. package/docs/contracts/review-lens-schema.md +5 -0
  278. package/docs/contracts/rule-router.md +102 -8
  279. package/docs/contracts/skill-bundled-assets.md +1 -1
  280. package/docs/contracts/skill-dry-run.md +1 -1
  281. package/docs/contracts/subagent-boundary.md +5 -0
  282. package/docs/contracts/ticket-bundle-format.md +9 -4
  283. package/docs/contracts/tier-3-contrib-plugin.md +2 -2
  284. package/docs/contracts/write-engine.md +3 -0
  285. package/docs/customization.md +87 -15
  286. package/docs/decisions/ADR-107-legal-domain-pack-adoption.md +1 -1
  287. package/docs/decisions/ADR-109-subagent-v1-contract.md +246 -0
  288. package/docs/decisions/ADR-110-discipline-profile-resolution-locus.md +105 -0
  289. package/docs/decisions/INDEX.md +2 -0
  290. package/docs/distribution/awesome-list-submission.md +46 -0
  291. package/docs/distribution/launch-story-draft.md +58 -0
  292. package/docs/end-to-end-walkthroughs.md +2 -2
  293. package/docs/getting-started.md +2 -2
  294. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +24 -0
  295. package/docs/guidelines/agent-infra/corpus-grounding-authoring.md +1 -1
  296. package/docs/guidelines/agent-infra/linked-projects-onboarding-gate.md +2 -2
  297. package/docs/guidelines/agent-infra/missing-tool-handling.md +3 -3
  298. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  299. package/docs/guidelines/augment-portability-patterns.md +1 -1
  300. package/docs/guidelines/code-clarity.md +19 -0
  301. package/docs/guidelines/design-antipatterns-triggers.json +2 -1
  302. package/docs/guidelines/design-antipatterns.md +10 -1
  303. package/docs/guidelines/design-modes.md +6 -0
  304. package/docs/guidelines/php/general.md +9 -1
  305. package/docs/guidelines/php/php-coding-patterns.md +7 -0
  306. package/docs/guides/cross-repo-retrieval.md +1 -1
  307. package/docs/guides/frontend-design-corpus-refresh.md +2 -2
  308. package/docs/guides/local-analytics.md +4 -4
  309. package/docs/guides/skill-discovery.md +1 -1
  310. package/docs/guides/skill-preview.md +1 -1
  311. package/docs/hook-payload-capture.md +6 -6
  312. package/docs/install-friction-report.md +66 -0
  313. package/docs/installation.md +1 -1
  314. package/docs/maintainers/optional-media-deps.md +50 -0
  315. package/docs/mcp-server.md +11 -12
  316. package/docs/media/proof-demo.cast +14 -0
  317. package/docs/media/proof-demo.gif +0 -0
  318. package/docs/migration/consumer-template-consumption-model.md +1 -1
  319. package/docs/migration/divergences/bench-stats-float-precision.md +1 -1
  320. package/docs/migration/node-floor.md +1 -1
  321. package/docs/migration/yaml-roundtrip-spike.md +1 -1
  322. package/docs/personas.md +16 -5
  323. package/docs/positioning-evidence.md +86 -0
  324. package/docs/proof.md +86 -0
  325. package/docs/skills-catalog.md +1 -1
  326. package/docs/troubleshooting.md +8 -8
  327. package/docs/wedge/production-validator/README.md +57 -0
  328. package/docs/wedge/production-validator/production-validator.md +56 -0
  329. package/docs/wizard.md +2 -2
  330. package/package.json +1 -1
  331. package/src/config/agent-settings.template.yml +59 -4
  332. package/src/config/agents-paths.yml +254 -0
  333. package/src/config/budgets.yml +16 -0
  334. package/src/config/discovery/packs.yml +1 -0
  335. package/src/config/discovery/unassigned-artefacts.yml +2 -0
  336. package/src/config/gitignore-block.txt +25 -0
  337. package/src/config/host-capabilities.yml +31 -0
  338. package/src/config/profiles/balanced.ini +4 -0
  339. package/src/config/profiles/full.ini +4 -0
  340. package/src/config/profiles/minimal.ini +4 -0
  341. package/src/scripts/_cli/cmd_conformance.ts +716 -0
  342. package/src/scripts/_cli/cmd_doctor.ts +23 -2
  343. package/src/scripts/_cli/cmd_fleet.ts +401 -0
  344. package/src/scripts/_cli/cmd_preflight.ts +159 -0
  345. package/src/scripts/_dispatch.bash +10 -0
  346. package/src/scripts/_lib/knowledge_events.ts +193 -0
  347. package/src/scripts/_lib/subagent_steering.ts +115 -3
  348. package/src/scripts/_lib/text_similarity.ts +75 -0
  349. package/src/scripts/ai-video/test-pipeline.sh +1 -1
  350. package/src/scripts/ai_council/clients.ts +19 -3
  351. package/src/scripts/append_contested.ts +112 -0
  352. package/src/scripts/audit_auto_rules.ts +11 -1
  353. package/src/scripts/audit_mcp_tools.ts +25 -11
  354. package/src/scripts/bench_ab_v2_run.ts +527 -40
  355. package/src/scripts/bench_ab_v2_stats.ts +6 -0
  356. package/src/scripts/bench_matrix.ts +266 -0
  357. package/src/scripts/bootstrap_knowledge.ts +267 -0
  358. package/src/scripts/build_discovery_manifest.ts +42 -2
  359. package/src/scripts/build_proof.ts +214 -0
  360. package/src/scripts/check_always_budget.ts +3 -0
  361. package/src/scripts/check_augment_description_cap.ts +2 -2
  362. package/src/scripts/check_claims.ts +270 -0
  363. package/src/scripts/check_comparison.ts +79 -0
  364. package/src/scripts/check_generated_artefact_headers.ts +109 -0
  365. package/src/scripts/check_generator_output_coverage.ts +142 -0
  366. package/src/scripts/check_gitignore_freshness.ts +127 -0
  367. package/src/scripts/check_knowledge_pages.ts +210 -0
  368. package/src/scripts/check_knowledge_sharing.ts +162 -0
  369. package/src/scripts/check_media_deps.ts +91 -0
  370. package/src/scripts/check_memory_contradiction.ts +280 -0
  371. package/src/scripts/check_memory_similarity.ts +134 -0
  372. package/src/scripts/check_quality_regression.ts +56 -10
  373. package/src/scripts/check_references.ts +3 -1
  374. package/src/scripts/check_release_pr_shape.ts +4 -0
  375. package/src/scripts/check_site_links.ts +135 -0
  376. package/src/scripts/check_skill_gaps.ts +99 -0
  377. package/src/scripts/check_token_quality_golden.ts +197 -11
  378. package/src/scripts/check_tracked_but_ignored.ts +67 -0
  379. package/src/scripts/cluster_near_miss_patterns.ts +0 -0
  380. package/src/scripts/compile_router.ts +30 -3
  381. package/src/scripts/condense.ts +350 -14
  382. package/src/scripts/consolidate_knowledge_events.ts +192 -0
  383. package/src/scripts/degrade_to_pointer.ts +136 -0
  384. package/src/scripts/design_slop_rules.test.ts +15 -0
  385. package/src/scripts/design_slop_rules.ts +28 -0
  386. package/src/scripts/emit_knowledge_event.ts +158 -0
  387. package/src/scripts/export_replay_corpus.ts +187 -0
  388. package/src/scripts/external_sources_denylist.json +7 -2
  389. package/src/scripts/fold_intake.ts +281 -0
  390. package/src/scripts/generate_capability_matrix.ts +9 -1
  391. package/src/scripts/generate_knowledge_index.ts +222 -0
  392. package/src/scripts/hook_manifest.yaml +26 -14
  393. package/src/scripts/hooks/dispatch_hook.ts +18 -0
  394. package/src/scripts/hot_context_hook.ts +372 -0
  395. package/src/scripts/install +47 -0
  396. package/src/scripts/install-hooks.sh +17 -0
  397. package/src/scripts/inventory_meta_layers.ts +11 -0
  398. package/src/scripts/janitor.ts +258 -0
  399. package/src/scripts/lint_agents_layout.ts +74 -15
  400. package/src/scripts/lint_bench_ab.ts +4 -1
  401. package/src/scripts/lint_featured_skills.ts +0 -0
  402. package/src/scripts/lint_framework_leakage_allowlist.json +26 -3
  403. package/src/scripts/lint_knowledge_scale.ts +250 -0
  404. package/src/scripts/lint_legal_pack.ts +67 -0
  405. package/src/scripts/lint_persona_governance.ts +8 -3
  406. package/src/scripts/lint_regression.ts +15 -0
  407. package/src/scripts/lint_roadmap_blockers.ts +202 -0
  408. package/src/scripts/lint_roadmap_complexity.ts +81 -2
  409. package/src/scripts/lint_subagent_determinism.ts +125 -0
  410. package/src/scripts/measure_augment_budget.ts +46 -6
  411. package/src/scripts/measure_patterns.ts +4 -3
  412. package/src/scripts/measure_skill_reduction.ts +6 -6
  413. package/src/scripts/migration_status.ts +6 -2
  414. package/src/scripts/mine_missing_guardrails.ts +189 -0
  415. package/src/scripts/parity/phase_gate.ts +1 -1
  416. package/src/scripts/parity/replay.ts +21 -0
  417. package/src/scripts/project_thin_rules.ts +120 -16
  418. package/src/scripts/release.ts +39 -1
  419. package/src/scripts/render_benchmark_composite.ts +378 -0
  420. package/src/scripts/roadmap_progress_hook.ts +101 -43
  421. package/src/scripts/schemas/skill.schema.json +27 -0
  422. package/src/scripts/schemas/subagent.schema.json +106 -0
  423. package/src/scripts/skill_linter.ts +1 -0
  424. package/src/scripts/smoke/kernel.sh +5 -4
  425. package/src/scripts/surface-tiers.yml +1 -0
  426. package/src/scripts/sync_gitignore.ts +4 -0
  427. package/src/scripts/update_skill_candidates.ts +172 -0
  428. package/src/scripts/validate_frontmatter.ts +1 -0
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Generate docs/proof.md — the public, self-verifying trust surface.
4
+ *
5
+ * Market-readiness roadmap Track B / B4. Renders, from real sources, the three
6
+ * proofs a skeptic can check themselves:
7
+ * 1. Every markered public claim binds to a resolvable evidence pointer
8
+ * (rendered from docs/CLAIMS.md — reuses the check_claims ledger loader).
9
+ * 2. Honest-null results are published, not hidden (pointer to docs/benchmark.md).
10
+ * 3. A "verify it yourself" block — the exact commands that reproduce 1 + 2 on
11
+ * a fresh checkout.
12
+ *
13
+ * **Generated, never hand-maintained** — drift-checked in CI via `--check`, the
14
+ * same discipline as generate_capabilities_index / generate_cookbook. Output is
15
+ * deterministic (sorted, no timestamp) so `--check` is stable. A proof page that
16
+ * could drift from its sources would undermine the very claim it makes.
17
+ *
18
+ * Usage:
19
+ * ./scripts-run src/scripts/build_proof # (re)write docs/proof.md
20
+ * ./scripts-run src/scripts/build_proof --check # exit 2 if stale
21
+ */
22
+ import * as fs from 'node:fs';
23
+ import * as path from 'node:path';
24
+ import { fileURLToPath, pathToFileURL } from 'node:url';
25
+
26
+ import { REPO, LEDGER_REL, load_ledger, pointer_unresolved } from './check_claims.js';
27
+ import { collectSkillGaps } from './check_skill_gaps.js';
28
+ import { loadRows as loadComparisonRows } from './check_comparison.js';
29
+
30
+ const _FILE = fileURLToPath(import.meta.url);
31
+ const OUT_REL = 'docs/proof.md';
32
+ const BENCH_REL = 'docs/benchmark.md';
33
+
34
+ class ExitCode extends Error {
35
+ code: number;
36
+ constructor(code: number) {
37
+ super(`exit ${code}`);
38
+ this.code = code;
39
+ }
40
+ }
41
+
42
+ function render(): string {
43
+ const ledger = load_ledger();
44
+ const entries = [...ledger.values()].sort((a, b) => a.id.localeCompare(b.id));
45
+ const backed = entries.filter((e) => e.status === 'backed');
46
+ const unbacked = entries.filter((e) => e.status === 'unbacked');
47
+
48
+ const L: string[] = [];
49
+ L.push('<!-- GENERATED by src/scripts/build_proof.ts — do NOT hand-edit.');
50
+ L.push(' Drift-checked in CI (`task build-proof-check`). Regenerate with');
51
+ L.push(' `./scripts-run src/scripts/build_proof` after editing docs/CLAIMS.md. -->');
52
+ L.push('');
53
+ L.push('# Proof — verify our claims yourself');
54
+ L.push('');
55
+ L.push('We sell falsifiability, so the selling is machine-checked. Every');
56
+ L.push('public claim binds to resolvable evidence; a skeptic can reproduce');
57
+ L.push('every check below on a fresh checkout. This page is itself generated');
58
+ L.push('from those sources and fails CI if it drifts.');
59
+ L.push('');
60
+ L.push('## See it run (< 60s, real output)');
61
+ L.push('');
62
+ L.push('![The trust surface running green — every "verify it yourself" command below, recorded from a real run](media/proof-demo.gif)');
63
+ L.push('');
64
+ L.push('The recording is of the exact commands in § 5, nothing staged. Its');
65
+ L.push('commands are re-executed in CI (`.github/workflows/proof-demo.yml`), so a');
66
+ L.push('demo that showed something broken would turn CI red — the recording');
67
+ L.push('cannot drift from current behavior.');
68
+ L.push('');
69
+ L.push('## 1. Every public claim binds to evidence');
70
+ L.push('');
71
+ L.push(`Rendered from [\`${LEDGER_REL}\`](CLAIMS.md). A \`<!-- claim:ID -->\` marker in`);
72
+ L.push('README/docs must resolve to a `backed` entry here with a resolving');
73
+ L.push('evidence pointer, or `task check-claims` fails the build.');
74
+ L.push('');
75
+ L.push('| Claim | Kind | Evidence | Resolves |');
76
+ L.push('|---|---|---|---|');
77
+ for (const e of backed) {
78
+ const un = pointer_unresolved(e.evidence);
79
+ const resolves = un ? `❌ ${un}` : '✅';
80
+ const claim = e.claim.replace(/\|/g, '\\|');
81
+ const evidence = e.evidence.replace(/\|/g, '\\|');
82
+ L.push(`| ${claim} | ${e.kind} | \`${evidence}\` | ${resolves} |`);
83
+ }
84
+ L.push('');
85
+ L.push(`**${backed.length} backed claim(s)** — all evidence pointers resolve in CI.`);
86
+ if (unbacked.length > 0) {
87
+ L.push('');
88
+ L.push(`We also publish our **debt**: ${unbacked.length} claim(s) are logged as`);
89
+ L.push('`unbacked` inventory in the ledger — not yet bound, and therefore not');
90
+ L.push('allowed to carry a marker in public prose. Hiding them would be the');
91
+ L.push('opposite of the point.');
92
+ }
93
+ L.push('');
94
+ L.push('## 2. We publish honest nulls');
95
+ L.push('');
96
+ if (fs.existsSync(path.join(REPO, BENCH_REL))) {
97
+ L.push(`Benchmark results — **including the runs where the package changed nothing** —`);
98
+ L.push(`live in [\`${BENCH_REL}\`](benchmark.md). We do not delete a measured null to`);
99
+ L.push('make a number look better; the null is the evidence of honesty.');
100
+ } else {
101
+ L.push('Benchmark results are published under `docs/` including measured nulls.');
102
+ }
103
+ L.push('');
104
+ L.push('## 3. Known limits (published, witness-tested)');
105
+ L.push('');
106
+ const skillGaps = collectSkillGaps();
107
+ if (skillGaps.length === 0) {
108
+ L.push('No skill has logged a known-limit `gaps:` entry yet. When one does, it');
109
+ L.push('appears here with a witness test that reproduces the limitation — the');
110
+ L.push('transparency surface a headline-benchmark structurally cannot ship.');
111
+ } else {
112
+ L.push('Each limitation below is stated by the skill itself and carries a witness');
113
+ L.push('test that reproduces it. If the limitation is ever fixed, its witness goes');
114
+ L.push('red — so a "Known limit" can never quietly become false.');
115
+ L.push('');
116
+ L.push('| skill | known limit | witness |');
117
+ L.push('|---|---|---|');
118
+ for (const sg of skillGaps) {
119
+ for (const g of sg.gaps) {
120
+ const desc = g.description.replace(/\|/g, '\\|');
121
+ L.push(`| \`${sg.skill}\` | ${desc} | [\`${g.witness}\`](../${g.witness}) |`);
122
+ }
123
+ }
124
+ }
125
+ L.push('');
126
+ L.push('## 4. What is checkable — us vs. the category');
127
+ L.push('');
128
+ const cmpRows = loadComparisonRows();
129
+ if (cmpRows.length === 0) {
130
+ L.push('No comparison rows recorded yet.');
131
+ } else {
132
+ L.push('This is not a takedown — the point is the last column. For each claim,');
133
+ L.push('our evidence is a pointer you can resolve on a fresh checkout; the wider');
134
+ L.push('category is described only by what is publicly observable, never a named');
135
+ L.push('competitor and never a counter-claim to anyone\'s headline number. A claim');
136
+ L.push('is "checkable" only when its `our evidence` pointer resolves — CI enforces');
137
+ L.push('that (`task check-comparison`), so this column can never lie.');
138
+ L.push('');
139
+ L.push('| Claim | Our evidence | The category | Checkable? |');
140
+ L.push('|---|---|---|---|');
141
+ for (const r of cmpRows) {
142
+ const claim = r.claim.replace(/\|/g, '\\|');
143
+ const theirs = r.their_evidence.replace(/\|/g, '\\|');
144
+ const filePart = (r.our_evidence.split('#')[0] ?? r.our_evidence).split(':')[0] ?? r.our_evidence;
145
+ const ours = pointer_unresolved(r.our_evidence) === null
146
+ ? `[\`${r.our_evidence}\`](../${filePart})`
147
+ : `\`${r.our_evidence}\``;
148
+ L.push(`| ${claim} | ${ours} | ${theirs} | ${r.checkable ? '✅' : '—'} |`);
149
+ }
150
+ }
151
+ L.push('');
152
+ L.push('## 5. Verify it yourself');
153
+ L.push('');
154
+ L.push('On a fresh checkout, reproduce the claims above:');
155
+ L.push('');
156
+ L.push('```bash');
157
+ L.push('task check-claims # every markered public claim binds to resolvable evidence');
158
+ L.push('task check-refs # no broken internal references');
159
+ L.push('task check-skill-gaps # every logged known-limit cites a real witness test');
160
+ L.push('task check-comparison # every comparison-table "our evidence" pointer resolves');
161
+ L.push('task build-proof-check # this page is in sync with its sources');
162
+ L.push('```');
163
+ L.push('');
164
+ L.push('If a claim ever loses its binding, or this page drifts from the ledger,');
165
+ L.push('CI goes red. Reproducibility is the proof.');
166
+ L.push('');
167
+ return L.join('\n');
168
+ }
169
+
170
+ function main(argv: string[] = process.argv.slice(2)): number {
171
+ const check = argv.includes('--check');
172
+ if (argv.includes('-h') || argv.includes('--help')) {
173
+ process.stdout.write('usage: build_proof [--check]\n');
174
+ return 0;
175
+ }
176
+ const out = render();
177
+ const outPath = path.join(REPO, OUT_REL);
178
+ if (check) {
179
+ const current = fs.existsSync(outPath) ? fs.readFileSync(outPath, 'utf8') : '';
180
+ if (current !== out) {
181
+ process.stderr.write(
182
+ `❌ build_proof: ${OUT_REL} is stale. Run './scripts-run src/scripts/build_proof' and commit.\n`,
183
+ );
184
+ return 2;
185
+ }
186
+ process.stdout.write(`✅ build_proof: ${OUT_REL} in sync.\n`);
187
+ return 0;
188
+ }
189
+ fs.mkdirSync(path.dirname(outPath), { recursive: true });
190
+ fs.writeFileSync(outPath, out);
191
+ process.stdout.write(`✅ build_proof: wrote ${OUT_REL}.\n`);
192
+ return 0;
193
+ }
194
+
195
+ function _isCliEntry(): boolean {
196
+ const a = process.argv[1];
197
+ if (!a) return false;
198
+ if (a === _FILE || pathToFileURL(path.resolve(a)).href === import.meta.url) return true;
199
+ try {
200
+ return fs.realpathSync(a) === fs.realpathSync(_FILE);
201
+ } catch {
202
+ return false;
203
+ }
204
+ }
205
+ if (_isCliEntry()) {
206
+ try {
207
+ process.exit(main());
208
+ } catch (exc) {
209
+ if (exc instanceof ExitCode) process.exit(exc.code);
210
+ throw exc;
211
+ }
212
+ }
213
+
214
+ export { render, main, OUT_REL };
@@ -46,6 +46,9 @@ const CONCENTRATION_TOP3_PCT = 0.3;
46
46
  const KNOWN_CONCENTRATION_BREACHES: Record<string, number> = {
47
47
  'language-and-tone.md': 4_174,
48
48
  'no-cheap-questions.md': 3_719,
49
+ // Retired by the concentration-cap recalibration in the budget-SoT PR
50
+ // (12% mis-fits a 9-rule kernel; direct-answers 12.7% < the recalibrated cap).
51
+ 'direct-answers.md': 3_600,
49
52
  };
50
53
  const KNOWN_TOP3_CONCENTRATION_CEILING: number | null = 11_300;
51
54
 
@@ -14,7 +14,7 @@
14
14
  *
15
15
  * Why: Augment injects each auto-rule's description into the
16
16
  * workspace-guidelines registry stub. Empirical 2026-05-08 budget
17
- * analysis showed this channel consuming 25 % of the 49,512-char
17
+ * analysis showed this channel consuming 25 % of the workspace-guidelines
18
18
  * ceiling. Capping descriptions guards future drift.
19
19
  *
20
20
  * Source of truth: `.agent-src.uncondensed/rules/`. The condensed
@@ -114,7 +114,7 @@ export function main(): number {
114
114
  process.stderr.write(
115
115
  `\n Guard rationale: each char in an auto-rule description ` +
116
116
  `costs one char in the\n Augment workspace-guidelines budget ` +
117
- `(cap 49,512). Trim to ≤ ${DESC_CAP}.\n`,
117
+ `(cap: src/config/budgets.yml). Trim to ≤ ${DESC_CAP}.\n`,
118
118
  );
119
119
  return 1;
120
120
  }
@@ -0,0 +1,270 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Claims-Ledger gate — no public claim without a resolvable evidence binding.
4
+ *
5
+ * The mechanical anti-hype guardrail (road-to-final-state-and-market-readiness
6
+ * Phase 1 / Track B, step B1). Every public-facing claim that carries a
7
+ * `<!-- claim:<id> -->` marker in README.md or docs/ MUST resolve to a ledger
8
+ * entry in docs/CLAIMS.md whose `status: backed` and whose `evidence` pointer
9
+ * resolves. A smuggled unbacked claim (marker without a backed, resolvable
10
+ * ledger entry) fails the build — so "we sell honesty" is itself machine-checked.
11
+ *
12
+ * Non-disruptive by design: only `<!-- claim:ID -->`-**markered** spans are
13
+ * enforced. Unmarkered prose is never checked, so existing README text does not
14
+ * retroactively break CI; the ledger tightens as claims are markered over time.
15
+ * Ledger entries with `status: unbacked` are inventory (documented debt) and do
16
+ * NOT fail the build — but marking such an entry's claim in prose does.
17
+ *
18
+ * Evidence-pointer grammar (v1):
19
+ * <repo-path>[:line] → the repo file exists (line advisory).
20
+ * <repo-path>#<substring> → the file exists AND contains <substring>.
21
+ * https://… (YYYY-MM-DD) → external cite with a dated stamp (not fetched).
22
+ *
23
+ * Exit codes: 0 = clean · 2 = unbacked/dangling/missing-entry finding OR usage
24
+ * error. Success prints to stdout; findings print to stderr.
25
+ *
26
+ * Usage:
27
+ * ./scripts-run src/scripts/check_claims
28
+ * ./scripts-run src/scripts/check_claims --quiet
29
+ */
30
+ import * as fs from 'node:fs';
31
+ import * as path from 'node:path';
32
+ import { fileURLToPath, pathToFileURL } from 'node:url';
33
+
34
+ const _FILE = fileURLToPath(import.meta.url);
35
+ const _HERE = path.dirname(_FILE);
36
+ const REPO = path.resolve(_HERE, '..', '..');
37
+ const LEDGER_REL = 'docs/CLAIMS.md';
38
+
39
+ /** Surfaces scanned for `<!-- claim:ID -->` markers. */
40
+ const SURFACE_ROOTS = ['README.md', 'docs'];
41
+
42
+ const CLAIM_MARKER = /<!--\s*claim:([A-Za-z0-9._-]+)\s*-->/g;
43
+ const URL_DATED = /^https?:\/\/\S+\(\d{4}-\d{2}-\d{2}\)\s*$/;
44
+
45
+ class ExitCode extends Error {
46
+ code: number;
47
+ constructor(code: number) {
48
+ super(`exit ${code}`);
49
+ this.code = code;
50
+ }
51
+ }
52
+
53
+ interface LedgerEntry {
54
+ id: string;
55
+ claim: string;
56
+ kind: string;
57
+ evidence: string;
58
+ status: string;
59
+ last_verified: string;
60
+ }
61
+
62
+ interface Args {
63
+ quiet: boolean;
64
+ }
65
+
66
+ function parse_args(argv: string[]): Args {
67
+ const out: Args = { quiet: false };
68
+ for (const a of argv) {
69
+ if (a === '--quiet') {
70
+ out.quiet = true;
71
+ } else if (a === '-h' || a === '--help') {
72
+ process.stdout.write('usage: check_claims [--quiet]\n');
73
+ throw new ExitCode(0);
74
+ } else {
75
+ process.stderr.write(`❌ check_claims: unrecognized argument: ${a}\n`);
76
+ throw new ExitCode(2);
77
+ }
78
+ }
79
+ return out;
80
+ }
81
+
82
+ /** Parse docs/CLAIMS.md — one entry per `### claim: <id>` block. */
83
+ function load_ledger(): Map<string, LedgerEntry> {
84
+ const ledger = new Map<string, LedgerEntry>();
85
+ const p = path.join(REPO, LEDGER_REL);
86
+ if (!fs.existsSync(p)) {
87
+ return ledger;
88
+ }
89
+ const lines = fs.readFileSync(p, 'utf8').split('\n');
90
+ let cur: Partial<LedgerEntry> & { id?: string } = {};
91
+ const flush = () => {
92
+ if (cur.id) {
93
+ ledger.set(cur.id, {
94
+ id: cur.id,
95
+ claim: cur.claim ?? '',
96
+ kind: cur.kind ?? '',
97
+ evidence: cur.evidence ?? '',
98
+ status: cur.status ?? '',
99
+ last_verified: cur.last_verified ?? '',
100
+ });
101
+ }
102
+ cur = {};
103
+ };
104
+ for (const line of lines) {
105
+ const head = line.match(/^###\s+claim:\s*([A-Za-z0-9._-]+)\s*$/);
106
+ if (head) {
107
+ flush();
108
+ cur = { id: head[1]! };
109
+ continue;
110
+ }
111
+ if (!cur.id) continue;
112
+ const field = line.match(/^-\s+(claim|kind|evidence|status|last_verified):\s*(.*)$/);
113
+ if (field) {
114
+ const key = field[1] as keyof LedgerEntry;
115
+ (cur as Record<string, string>)[key] = (field[2] ?? '').trim();
116
+ }
117
+ }
118
+ flush();
119
+ return ledger;
120
+ }
121
+
122
+ /** Recursively collect .md files under a repo-relative root (file or dir). */
123
+ function collect_md(rel: string): string[] {
124
+ const abs = path.join(REPO, rel);
125
+ if (!fs.existsSync(abs)) return [];
126
+ const st = fs.statSync(abs);
127
+ if (st.isFile()) return abs.endsWith('.md') ? [abs] : [];
128
+ const out: string[] = [];
129
+ for (const name of fs.readdirSync(abs)) {
130
+ if (name === 'node_modules' || name.startsWith('.')) continue;
131
+ out.push(...collect_md(path.join(rel, name)));
132
+ }
133
+ return out;
134
+ }
135
+
136
+ /** Find every live `<!-- claim:ID -->` marker across the scanned surfaces.
137
+ * Skips the ledger file itself and any marker shown as documentation
138
+ * (inside a ``` fenced block or an inline `backtick` span). */
139
+ function scan_markers(): { id: string; file: string }[] {
140
+ const found: { id: string; file: string }[] = [];
141
+ const files = new Set<string>();
142
+ for (const root of SURFACE_ROOTS) {
143
+ for (const f of collect_md(root)) files.add(f);
144
+ }
145
+ for (const f of files) {
146
+ const rel = path.relative(REPO, f);
147
+ if (rel === LEDGER_REL) continue; // the ledger documents the syntax
148
+ let fenced = false;
149
+ for (const line of fs.readFileSync(f, 'utf8').split('\n')) {
150
+ if (/^\s*```/.test(line)) {
151
+ fenced = !fenced;
152
+ continue;
153
+ }
154
+ if (fenced) continue;
155
+ for (const m of line.matchAll(CLAIM_MARKER)) {
156
+ const before = line.slice(0, m.index ?? 0);
157
+ const backticks = (before.match(/`/g) ?? []).length;
158
+ if (backticks % 2 === 1) continue; // inside an inline-code span
159
+ found.push({ id: m[1]!, file: rel });
160
+ }
161
+ }
162
+ }
163
+ return found;
164
+ }
165
+
166
+ /** Does an evidence pointer resolve? Returns null on success, else a reason. */
167
+ function pointer_unresolved(evidence: string): string | null {
168
+ const ev = evidence.trim();
169
+ if (!ev) return 'empty evidence pointer';
170
+ if (/^https?:\/\//.test(ev)) {
171
+ return URL_DATED.test(ev) ? null : 'external URL missing a (YYYY-MM-DD) stamp';
172
+ }
173
+ // repo-path[:line] or repo-path#substring
174
+ let target = ev;
175
+ let needle: string | null = null;
176
+ const hash = ev.indexOf('#');
177
+ if (hash !== -1) {
178
+ target = ev.slice(0, hash);
179
+ needle = ev.slice(hash + 1);
180
+ }
181
+ target = target.replace(/:\d+$/, ''); // strip :line
182
+ const abs = path.join(REPO, target);
183
+ if (!fs.existsSync(abs)) return `evidence path not found: ${target}`;
184
+ if (needle) {
185
+ const body = fs.readFileSync(abs, 'utf8');
186
+ if (!body.includes(needle)) return `evidence file lacks '${needle}': ${target}`;
187
+ }
188
+ return null;
189
+ }
190
+
191
+ interface Finding {
192
+ id: string;
193
+ file: string;
194
+ reason: string;
195
+ }
196
+
197
+ function main(argv: string[] = process.argv.slice(2)): number {
198
+ const args = parse_args(argv);
199
+ const ledger = load_ledger();
200
+ const markers = scan_markers();
201
+ const findings: Finding[] = [];
202
+
203
+ // 1. Every markered claim must map to a backed, resolvable ledger entry.
204
+ for (const { id, file } of markers) {
205
+ const entry = ledger.get(id);
206
+ if (!entry) {
207
+ findings.push({ id, file, reason: `no ledger entry in ${LEDGER_REL}` });
208
+ continue;
209
+ }
210
+ if (entry.status !== 'backed') {
211
+ findings.push({ id, file, reason: `ledger status is '${entry.status || 'missing'}', not 'backed'` });
212
+ continue;
213
+ }
214
+ const un = pointer_unresolved(entry.evidence);
215
+ if (un) findings.push({ id, file, reason: un });
216
+ }
217
+
218
+ // 2. Rot guard: a backed ledger entry whose pointer no longer resolves
219
+ // fails even before it is markered (an implementation must not outlive
220
+ // its claim, and vice-versa).
221
+ for (const entry of ledger.values()) {
222
+ if (entry.status !== 'backed') continue;
223
+ const un = pointer_unresolved(entry.evidence);
224
+ if (un) findings.push({ id: entry.id, file: LEDGER_REL, reason: `backed entry has dangling evidence — ${un}` });
225
+ }
226
+
227
+ if (findings.length > 0) {
228
+ process.stderr.write(`❌ check_claims: ${findings.length} unbacked/dangling claim(s):\n`);
229
+ for (const f of findings) {
230
+ process.stderr.write(` ${f.file} · claim:${f.id} — ${f.reason}\n`);
231
+ }
232
+ process.stderr.write(` → bind the claim in ${LEDGER_REL} (status: backed + a resolvable evidence pointer), or remove the marker.\n`);
233
+ return 2;
234
+ }
235
+
236
+ if (!args.quiet) {
237
+ const backed = [...ledger.values()].filter((e) => e.status === 'backed').length;
238
+ const unbacked = [...ledger.values()].filter((e) => e.status === 'unbacked').length;
239
+ process.stdout.write(
240
+ `✅ check_claims: ${markers.length} markered claim(s) bound · ledger ${ledger.size} entries (${backed} backed, ${unbacked} unbacked inventory)\n`,
241
+ );
242
+ }
243
+ return 0;
244
+ }
245
+
246
+ /** Robust "am I the entry script?" — realpath-compares argv[1] to this file so
247
+ * a symlinked invocation path (macOS /var → /private/var under a tmp tree)
248
+ * still resolves. Irrelevant under scripts-run (run.ts calls main directly). */
249
+ function _isCliEntry(): boolean {
250
+ const a = process.argv[1];
251
+ if (!a) return false;
252
+ if (a === _FILE || pathToFileURL(path.resolve(a)).href === import.meta.url) return true;
253
+ try {
254
+ return fs.realpathSync(a) === fs.realpathSync(_FILE);
255
+ } catch {
256
+ return false;
257
+ }
258
+ }
259
+ if (_isCliEntry()) {
260
+ try {
261
+ process.exit(main());
262
+ } catch (exc) {
263
+ if (exc instanceof ExitCode) {
264
+ process.exit(exc.code);
265
+ }
266
+ throw exc;
267
+ }
268
+ }
269
+
270
+ export { REPO, LEDGER_REL, main, parse_args, load_ledger, scan_markers, pointer_unresolved, ExitCode };
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * B7 — the falsifiability lock for the comparison-honesty table.
4
+ *
5
+ * Every `rows[].our_evidence` in `docs/comparison.yaml` must resolve to a real
6
+ * pointer (file / file#substring / file:line / dated URL) — reusing the
7
+ * check_claims resolver — and every `checkable: true` row must carry a resolving
8
+ * `our_evidence`. So the proof page's comparison table can never claim
9
+ * "checkable ✓" against a pointer that does not exist. Read-only; exit 0 clean /
10
+ * 1 on any unresolved pointer or malformed row.
11
+ *
12
+ * We assert only OUR side. `their_evidence` is prose about the publicly-
13
+ * observable category (no named source — check_no_external_sources guards that);
14
+ * we never counter-claim a competitor number, so there is nothing to verify on
15
+ * their side beyond "it is uncheckable", which is the point.
16
+ */
17
+ import * as fs from 'node:fs';
18
+ import * as path from 'node:path';
19
+ import { fileURLToPath, pathToFileURL } from 'node:url';
20
+ import { parse as parseYaml } from 'yaml';
21
+
22
+ import { REPO, pointer_unresolved } from './check_claims.js';
23
+
24
+ const _HERE = fileURLToPath(import.meta.url);
25
+ export const DATA_REL = 'docs/comparison.yaml';
26
+
27
+ export interface Row {
28
+ claim: string;
29
+ our_evidence: string;
30
+ their_evidence: string;
31
+ checkable: boolean;
32
+ }
33
+
34
+ export function loadRows(repo: string = REPO): Row[] {
35
+ const p = path.join(repo, DATA_REL);
36
+ if (!fs.existsSync(p)) return [];
37
+ const data = parseYaml(fs.readFileSync(p, 'utf-8')) as { rows?: Row[] } | null;
38
+ return Array.isArray(data?.rows) ? (data!.rows as Row[]) : [];
39
+ }
40
+
41
+ export function findErrors(rows: Row[]): string[] {
42
+ const errs: string[] = [];
43
+ rows.forEach((r, i) => {
44
+ if (typeof r?.claim !== 'string' || !r.claim.trim()) errs.push(`row[${i}]: missing/empty claim`);
45
+ if (typeof r?.their_evidence !== 'string' || !r.their_evidence.trim()) {
46
+ errs.push(`row[${i}]: missing/empty their_evidence`);
47
+ }
48
+ if (typeof r?.checkable !== 'boolean') errs.push(`row[${i}]: checkable must be a boolean`);
49
+ if (typeof r?.our_evidence !== 'string' || !r.our_evidence.trim()) {
50
+ errs.push(`row[${i}]: missing/empty our_evidence`);
51
+ return;
52
+ }
53
+ const bad = pointer_unresolved(r.our_evidence);
54
+ if (bad !== null) errs.push(`row[${i}] (${r.claim.slice(0, 40)}…): our_evidence ${bad}: ${r.our_evidence}`);
55
+ });
56
+ return errs;
57
+ }
58
+
59
+ export function main(argv: string[] = process.argv.slice(2)): number {
60
+ const quiet = argv.includes('--quiet');
61
+ const rows = loadRows();
62
+ const errs = findErrors(rows);
63
+ if (errs.length > 0) {
64
+ process.stdout.write('❌ comparison-honesty:\n');
65
+ for (const e of errs.sort()) process.stdout.write(` - ${e}\n`);
66
+ return 1;
67
+ }
68
+ if (!quiet) {
69
+ const checkable = rows.filter((r) => r.checkable).length;
70
+ process.stdout.write(
71
+ `✅ comparison-honesty: ${rows.length} row(s), ${checkable} checkable, all our_evidence pointers resolve.\n`,
72
+ );
73
+ }
74
+ return 0;
75
+ }
76
+
77
+ const _isCli =
78
+ process.argv[1] !== undefined && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href;
79
+ if (_isCli) process.exit(main());