@event4u/agent-config 7.4.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 (469) hide show
  1. package/.claude-plugin/marketplace.json +11 -1
  2. package/AGENTS.md +9 -9
  3. package/CHANGELOG.md +373 -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/review-changes.md +14 -7
  34. package/dist/agent-src/commands/roadmap/create.md +88 -10
  35. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  36. package/dist/agent-src/commands/roadmap/process-full.md +15 -2
  37. package/dist/agent-src/commands/roadmap/process-phase.md +18 -6
  38. package/dist/agent-src/commands/roadmap/process-step.md +4 -0
  39. package/dist/agent-src/commands/roadmap.md +1 -1
  40. package/dist/agent-src/commands/security-audit-config.md +1 -1
  41. package/dist/agent-src/commands/sync-agent-settings.md +1 -1
  42. package/dist/agent-src/commands/sync-gitignore/fix.md +42 -6
  43. package/dist/agent-src/commands/team-knowledge/bootstrap.md +106 -0
  44. package/dist/agent-src/commands/team-knowledge/consolidate.md +105 -0
  45. package/dist/agent-src/commands/team-knowledge.md +64 -0
  46. package/dist/agent-src/contexts/authority/commit-mechanics.md +8 -0
  47. package/dist/agent-src/contexts/authority/destructive-mechanics.md +11 -0
  48. package/dist/agent-src/contexts/authority/scope-mechanics.md +25 -0
  49. package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +43 -0
  50. package/dist/agent-src/contexts/contracts/agents-md-anatomy.md +1 -1
  51. package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +2 -2
  52. package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -0
  53. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +14 -4
  54. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +11 -0
  55. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +32 -8
  56. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +107 -0
  57. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +71 -15
  58. package/dist/agent-src/contexts/execution/subagent-steering.md +41 -1
  59. package/dist/agent-src/contexts/override-system.md +1 -1
  60. package/dist/agent-src/personas/brand-strategist.md +0 -1
  61. package/dist/agent-src/personas/data-integrity.md +66 -0
  62. package/dist/agent-src/personas/design-director.md +0 -1
  63. package/dist/agent-src/personas/performance-engineer.md +66 -0
  64. package/dist/agent-src/personas/production-validator.md +73 -0
  65. package/dist/agent-src/rules/agent-authority.md +3 -4
  66. package/dist/agent-src/rules/analysis-skill-routing.md +3 -5
  67. package/dist/agent-src/rules/architecture.md +2 -4
  68. package/dist/agent-src/rules/artifact-drafting-protocol.md +35 -6
  69. package/dist/agent-src/rules/artifact-engagement-recording.md +11 -4
  70. package/dist/agent-src/rules/ask-when-uncertain.md +10 -14
  71. package/dist/agent-src/rules/augment-edit-discipline.md +3 -5
  72. package/dist/agent-src/rules/autonomous-execution.md +3 -5
  73. package/dist/agent-src/rules/brand-consistency.md +3 -5
  74. package/dist/agent-src/rules/brand-source-of-truth.md +3 -5
  75. package/dist/agent-src/rules/cli-output-handling.md +4 -6
  76. package/dist/agent-src/rules/command-suggestion-policy.md +3 -5
  77. package/dist/agent-src/rules/commit-conventions.md +3 -5
  78. package/dist/agent-src/rules/commit-policy.md +8 -10
  79. package/dist/agent-src/rules/content-quoting-floor.md +88 -0
  80. package/dist/agent-src/rules/context-hygiene.md +3 -5
  81. package/dist/agent-src/rules/copilot-routing.md +4 -6
  82. package/dist/agent-src/rules/decision-revisit-gate.md +120 -0
  83. package/dist/agent-src/rules/delegation-policy.md +10 -6
  84. package/dist/agent-src/rules/design-fidelity.md +3 -5
  85. package/dist/agent-src/rules/devcontainer-routing.md +4 -6
  86. package/dist/agent-src/rules/direct-answers.md +13 -17
  87. package/dist/agent-src/rules/docker-commands.md +3 -5
  88. package/dist/agent-src/rules/domain-adoption-policy.md +3 -5
  89. package/dist/agent-src/rules/domain-safety-disclaimer.md +3 -5
  90. package/dist/agent-src/rules/domain-safety-pii.md +7 -8
  91. package/dist/agent-src/rules/domain-safety-retention.md +3 -5
  92. package/dist/agent-src/rules/downstream-changes.md +3 -4
  93. package/dist/agent-src/rules/engineering-safety-floor.md +3 -5
  94. package/dist/agent-src/rules/external-reference-deep-dive.md +3 -5
  95. package/dist/agent-src/rules/fast-path-marker-visibility.md +3 -5
  96. package/dist/agent-src/rules/finance-safety-floor.md +3 -6
  97. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -5
  98. package/dist/agent-src/rules/git-history-discipline.md +3 -5
  99. package/dist/agent-src/rules/guidelines.md +2 -4
  100. package/dist/agent-src/rules/icon-consistency.md +4 -5
  101. package/dist/agent-src/rules/image-likeness-and-rights.md +3 -5
  102. package/dist/agent-src/rules/improve-before-implement.md +5 -5
  103. package/dist/agent-src/rules/invite-challenge.md +3 -5
  104. package/dist/agent-src/rules/language-and-tone.md +13 -15
  105. package/dist/agent-src/rules/laravel-routing.md +3 -5
  106. package/dist/agent-src/rules/laravel-translations.md +3 -5
  107. package/dist/agent-src/rules/legal-safety-floor.md +5 -7
  108. package/dist/agent-src/rules/lethal-trifecta-guard.md +3 -5
  109. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +4 -7
  110. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +3 -5
  111. package/dist/agent-src/rules/markdown-safe-codeblocks.md +2 -4
  112. package/dist/agent-src/rules/media-governance-routing.md +3 -5
  113. package/dist/agent-src/rules/media-sync-ground-truth.md +3 -5
  114. package/dist/agent-src/rules/minimal-safe-diff.md +5 -5
  115. package/dist/agent-src/rules/missing-tool-handling.md +3 -5
  116. package/dist/agent-src/rules/model-recommendation.md +4 -6
  117. package/dist/agent-src/rules/no-attribution-footers.md +3 -5
  118. package/dist/agent-src/rules/no-cheap-questions.md +5 -8
  119. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +3 -6
  120. package/dist/agent-src/rules/no-pr-progress-comments.md +3 -6
  121. package/dist/agent-src/rules/no-roadmap-references.md +3 -5
  122. package/dist/agent-src/rules/non-destructive-by-default.md +11 -13
  123. package/dist/agent-src/rules/notes-first-reasoning.md +3 -5
  124. package/dist/agent-src/rules/onboarding-gate.md +4 -6
  125. package/dist/agent-src/rules/output-discipline.md +3 -5
  126. package/dist/agent-src/rules/package-ci-checks.md +3 -5
  127. package/dist/agent-src/rules/persona-governance.md +2 -4
  128. package/dist/agent-src/rules/php-coding.md +3 -5
  129. package/dist/agent-src/rules/preservation-guard.md +2 -4
  130. package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -5
  131. package/dist/agent-src/rules/reviewer-awareness.md +5 -6
  132. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +3 -5
  133. package/dist/agent-src/rules/roadmap-progress-sync.md +5 -5
  134. package/dist/agent-src/rules/role-mode-adherence.md +2 -4
  135. package/dist/agent-src/rules/rule-type-governance.md +3 -5
  136. package/dist/agent-src/rules/runtime-safety.md +2 -4
  137. package/dist/agent-src/rules/scope-control.md +10 -11
  138. package/dist/agent-src/rules/security-sensitive-stop.md +4 -5
  139. package/dist/agent-src/rules/size-enforcement.md +2 -4
  140. package/dist/agent-src/rules/skill-improvement-trigger.md +3 -5
  141. package/dist/agent-src/rules/skill-quality.md +3 -5
  142. package/dist/agent-src/rules/slash-command-routing-policy.md +3 -5
  143. package/dist/agent-src/rules/source-confidentiality.md +3 -5
  144. package/dist/agent-src/rules/source-discovery-gate.md +3 -5
  145. package/dist/agent-src/rules/source-of-truth.md +3 -5
  146. package/dist/agent-src/rules/strategy-safety-floor.md +3 -5
  147. package/dist/agent-src/rules/symfony-routing.md +4 -6
  148. package/dist/agent-src/rules/telegraph-speak.md +4 -5
  149. package/dist/agent-src/rules/think-before-action.md +7 -4
  150. package/dist/agent-src/rules/token-budget-discipline.md +29 -5
  151. package/dist/agent-src/rules/token-efficiency.md +3 -5
  152. package/dist/agent-src/rules/token-optimizer-maintenance.md +3 -5
  153. package/dist/agent-src/rules/tool-safety.md +2 -4
  154. package/dist/agent-src/rules/ui-audit-gate.md +3 -6
  155. package/dist/agent-src/rules/untrusted-input-defense.md +11 -10
  156. package/dist/agent-src/rules/upstream-proposal.md +4 -6
  157. package/dist/agent-src/rules/user-interaction.md +7 -5
  158. package/dist/agent-src/rules/user-interrupt-priority.md +17 -8
  159. package/dist/agent-src/rules/verify-before-complete.md +12 -22
  160. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +3 -3
  161. package/dist/agent-src/scripts/update_roadmap_progress.ts +197 -7
  162. package/dist/agent-src/skills/adr-create/SKILL.md +52 -42
  163. package/dist/agent-src/skills/adversarial-review/SKILL.md +1 -1
  164. package/dist/agent-src/skills/agent-docs-writing/SKILL.md +18 -0
  165. package/dist/agent-src/skills/agent-security-review/SKILL.md +1 -1
  166. package/dist/agent-src/skills/ai-council/SKILL.md +14 -1
  167. package/dist/agent-src/skills/blade-ui/SKILL.md +4 -0
  168. package/dist/agent-src/skills/blameless-post-mortem/SKILL.md +0 -3
  169. package/dist/agent-src/skills/brand/SKILL.md +1 -1
  170. package/dist/agent-src/skills/brand-identity/SKILL.md +3 -3
  171. package/dist/agent-src/skills/brand-strategy/SKILL.md +1 -1
  172. package/dist/agent-src/skills/brand-to-tokens/SKILL.md +5 -4
  173. package/dist/agent-src/skills/canvas-design/SKILL.md +6 -0
  174. package/dist/agent-src/skills/check-refs/SKILL.md +7 -4
  175. package/dist/agent-src/skills/code-review/SKILL.md +5 -0
  176. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +6 -5
  177. package/dist/agent-src/skills/condense-memory/SKILL.md +11 -11
  178. package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
  179. package/dist/agent-src/skills/context-document/SKILL.md +17 -0
  180. package/dist/agent-src/skills/corpus-grounding/SKILL.md +3 -3
  181. package/dist/agent-src/skills/decision-record/SKILL.md +6 -0
  182. package/dist/agent-src/skills/decision-review/SKILL.md +5 -3
  183. package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +6 -1
  184. package/dist/agent-src/skills/design-intelligence/SKILL.md +45 -2
  185. package/dist/agent-src/skills/design-intelligence/references/design-languages.md +1 -1
  186. package/dist/agent-src/skills/design-review/SKILL.md +23 -11
  187. package/dist/agent-src/skills/design-system-capture/SKILL.md +41 -0
  188. package/dist/agent-src/skills/design-system-capture/reference/design-system-json.md +62 -0
  189. package/dist/agent-src/skills/design-tokens/SKILL.md +11 -4
  190. package/dist/agent-src/skills/design-variations/SKILL.md +127 -0
  191. package/dist/agent-src/skills/design-variations/evals/triggers.json +17 -0
  192. package/dist/agent-src/skills/emit-tickets/SKILL.md +4 -4
  193. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +6 -0
  194. package/dist/agent-src/skills/fe-design/SKILL.md +20 -0
  195. package/dist/agent-src/skills/flux/SKILL.md +4 -0
  196. package/dist/agent-src/skills/html-deck/SKILL.md +123 -0
  197. package/dist/agent-src/skills/html-deck/evals/triggers.json +17 -0
  198. package/dist/agent-src/skills/html-deck/templates/deck-shell.html +77 -0
  199. package/dist/agent-src/skills/iconography/SKILL.md +1 -0
  200. package/dist/agent-src/skills/image-editing/evals/triggers.json +13 -13
  201. package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +136 -0
  202. package/dist/agent-src/skills/judge-artifact-completeness/calibration/fixtures.json +149 -0
  203. package/dist/agent-src/skills/judge-artifact-completeness/evals/triggers.json +17 -0
  204. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/architecture-score.json +73 -0
  205. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/pr-review-score.json +65 -0
  206. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/roadmap-score.json +73 -0
  207. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +73 -0
  208. package/dist/agent-src/skills/judge-code-quality/SKILL.md +1 -0
  209. package/dist/agent-src/skills/judge-injection-defense/SKILL.md +99 -0
  210. package/dist/agent-src/skills/judge-injection-defense/calibration/fixtures.json +24 -0
  211. package/dist/agent-src/skills/judge-injection-defense/evals/triggers.json +17 -0
  212. package/dist/agent-src/skills/judge-injection-defense/fixtures/behavioral-fixtures.json +63 -0
  213. package/dist/agent-src/skills/judge-injection-defense/fixtures/coverage-report.md +53 -0
  214. package/dist/agent-src/skills/judge-injection-defense/fixtures/perturbation-taxonomy.json +110 -0
  215. package/dist/agent-src/skills/judge-synthesis/SKILL.md +134 -0
  216. package/dist/agent-src/skills/judge-synthesis/evals/triggers.json +17 -0
  217. package/dist/agent-src/skills/laravel/SKILL.md +0 -1
  218. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +46 -0
  219. package/dist/agent-src/skills/lint-skills/SKILL.md +6 -6
  220. package/dist/agent-src/skills/logo-generation/SKILL.md +1 -1
  221. package/dist/agent-src/skills/markitdown/SKILL.md +1 -1
  222. package/dist/agent-src/skills/md-language-check/SKILL.md +3 -3
  223. package/dist/agent-src/skills/memory-consolidation/SKILL.md +66 -1
  224. package/dist/agent-src/skills/migration-architect/SKILL.md +1 -0
  225. package/dist/agent-src/skills/module-detect-on-the-fly/SKILL.md +2 -2
  226. package/dist/agent-src/skills/performance-analysis/SKILL.md +2 -0
  227. package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +4 -4
  228. package/dist/agent-src/skills/premortem/SKILL.md +0 -3
  229. package/dist/agent-src/skills/project-analysis-core/SKILL.md +16 -0
  230. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +18 -0
  231. package/dist/agent-src/skills/react-shadcn-ui/reference/registry.md +59 -0
  232. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +3 -1
  233. package/dist/agent-src/skills/refine-ticket/SKILL.md +5 -1
  234. package/dist/agent-src/skills/release-comms/SKILL.md +47 -46
  235. package/dist/agent-src/skills/roadmap-management/SKILL.md +25 -0
  236. package/dist/agent-src/skills/roadmap-writing/SKILL.md +33 -3
  237. package/dist/agent-src/skills/root-cause-frameworks/SKILL.md +0 -3
  238. package/dist/agent-src/skills/script-writing/SKILL.md +1 -1
  239. package/dist/agent-src/skills/security-audit/SKILL.md +1 -0
  240. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +4 -0
  241. package/dist/agent-src/skills/source-discovery/SKILL.md +22 -3
  242. package/dist/agent-src/skills/sql-writing/SKILL.md +1 -1
  243. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +33 -14
  244. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +11 -0
  245. package/dist/agent-src/skills/subagent-orchestration/prompts/do-in-steps.md +8 -0
  246. package/dist/agent-src/skills/systematic-debugging/SKILL.md +30 -1
  247. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +4 -0
  248. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  249. package/dist/agent-src/skills/threat-modeling/SKILL.md +2 -2
  250. package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
  251. package/dist/agent-src/skills/typography-system/SKILL.md +4 -3
  252. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -0
  253. package/dist/agent-src/skills/wireframe/SKILL.md +118 -0
  254. package/dist/agent-src/skills/wireframe/evals/triggers.json +17 -0
  255. package/dist/agent-src/templates/agent-settings.md +22 -1
  256. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  257. package/dist/agent-src/templates/command.md +2 -2
  258. package/dist/agent-src/templates/contexts/knowledge-pages.md +116 -0
  259. package/dist/agent-src/templates/hooks/pre-commit-frontmatter +1 -1
  260. package/dist/agent-src/templates/roadmaps.md +70 -2
  261. package/dist/agent-src/templates/rule.md +1 -1
  262. package/dist/agent-src/templates/scripts/README.md +3 -3
  263. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +109 -0
  264. package/dist/agent-src/templates/tickets.md +8 -8
  265. package/dist/cli/commands/recordTriggerEval.test.js +1 -1
  266. package/dist/cli/commands/recordTriggerEval.test.js.map +1 -1
  267. package/dist/cli/initRouting.js +4 -2
  268. package/dist/cli/initRouting.js.map +1 -1
  269. package/dist/cli/registry.js +1 -0
  270. package/dist/cli/registry.js.map +1 -1
  271. package/dist/discovery/deprecation-report.md +1 -1
  272. package/dist/discovery/discovery-manifest.json +802 -258
  273. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  274. package/dist/discovery/discovery-manifest.summary.md +8 -8
  275. package/dist/discovery/orphan-report.md +1 -1
  276. package/dist/discovery/packs.json +46 -28
  277. package/dist/discovery/trust-report.md +12 -11
  278. package/dist/discovery/workspaces.json +32 -18
  279. package/dist/install/preflight.js +173 -0
  280. package/dist/install/preflight.js.map +1 -0
  281. package/dist/mcp/registry-manifest.json +4 -4
  282. package/dist/router.json +1 -1
  283. package/dist/server/routes/settings.js +4 -0
  284. package/dist/server/routes/settings.js.map +1 -1
  285. package/dist/server/schemas/settings.js +6 -1
  286. package/dist/server/schemas/settings.js.map +1 -1
  287. package/docs/CLAIMS.md +108 -0
  288. package/docs/MIGRATION.md +3 -3
  289. package/docs/architecture.md +6 -6
  290. package/docs/benchmark.md +133 -2
  291. package/docs/benchmark.pinned.yml +31 -0
  292. package/docs/capability-matrix.md +1 -0
  293. package/docs/catalog.md +92 -74
  294. package/docs/command-flows.md +16 -4
  295. package/docs/comparison.yaml +35 -0
  296. package/docs/contracts/agents-layout.md +148 -0
  297. package/docs/contracts/brand-token-consumption.md +5 -0
  298. package/docs/contracts/capability-boundary.md +5 -0
  299. package/docs/contracts/command-category-governance.md +5 -0
  300. package/docs/contracts/command-clusters.md +1 -0
  301. package/docs/contracts/command-surface-tiers.md +1 -1
  302. package/docs/contracts/conformance.md +84 -0
  303. package/docs/contracts/creative-pack-boundary.md +5 -0
  304. package/docs/contracts/discovery-manifest.schema.json +5 -4
  305. package/docs/contracts/file-ownership-matrix.json +4605 -985
  306. package/docs/contracts/governance-enforcement-projection.md +5 -0
  307. package/docs/contracts/gui-wizard.md +1 -1
  308. package/docs/contracts/hook-architecture-v1.md +2 -2
  309. package/docs/contracts/implement-ticket-flow.md +1 -1
  310. package/docs/contracts/kernel-membership.md +13 -0
  311. package/docs/contracts/mcp-tool-inventory.md +23 -23
  312. package/docs/contracts/no-runtime-boundary.md +6 -1
  313. package/docs/contracts/review-lens-schema.md +5 -0
  314. package/docs/contracts/rule-router.md +102 -8
  315. package/docs/contracts/skill-bundled-assets.md +1 -1
  316. package/docs/contracts/skill-dry-run.md +1 -1
  317. package/docs/contracts/subagent-boundary.md +5 -0
  318. package/docs/contracts/ticket-bundle-format.md +9 -4
  319. package/docs/contracts/tier-3-contrib-plugin.md +2 -2
  320. package/docs/contracts/write-engine.md +3 -0
  321. package/docs/customization.md +87 -15
  322. package/docs/decisions/ADR-107-legal-domain-pack-adoption.md +1 -1
  323. package/docs/decisions/ADR-109-subagent-v1-contract.md +246 -0
  324. package/docs/decisions/ADR-110-discipline-profile-resolution-locus.md +105 -0
  325. package/docs/decisions/INDEX.md +2 -0
  326. package/docs/distribution/awesome-list-submission.md +46 -0
  327. package/docs/distribution/launch-story-draft.md +58 -0
  328. package/docs/end-to-end-walkthroughs.md +2 -2
  329. package/docs/getting-started.md +2 -2
  330. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +24 -0
  331. package/docs/guidelines/agent-infra/corpus-grounding-authoring.md +1 -1
  332. package/docs/guidelines/agent-infra/linked-projects-onboarding-gate.md +2 -2
  333. package/docs/guidelines/agent-infra/missing-tool-handling.md +3 -3
  334. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  335. package/docs/guidelines/augment-portability-patterns.md +1 -1
  336. package/docs/guidelines/code-clarity.md +19 -0
  337. package/docs/guidelines/design-antipatterns-triggers.json +2 -1
  338. package/docs/guidelines/design-antipatterns.md +35 -0
  339. package/docs/guidelines/design-canon.md +62 -0
  340. package/docs/guidelines/design-modes.md +6 -0
  341. package/docs/guidelines/php/general.md +9 -1
  342. package/docs/guidelines/php/php-coding-patterns.md +7 -0
  343. package/docs/guides/cross-repo-retrieval.md +1 -1
  344. package/docs/guides/frontend-design-corpus-refresh.md +2 -2
  345. package/docs/guides/local-analytics.md +4 -4
  346. package/docs/guides/skill-discovery.md +1 -1
  347. package/docs/guides/skill-preview.md +1 -1
  348. package/docs/hook-payload-capture.md +6 -6
  349. package/docs/install-friction-report.md +66 -0
  350. package/docs/installation.md +1 -1
  351. package/docs/maintainers/optional-media-deps.md +50 -0
  352. package/docs/mcp-server.md +11 -12
  353. package/docs/media/proof-demo.cast +14 -0
  354. package/docs/media/proof-demo.gif +0 -0
  355. package/docs/migration/consumer-template-consumption-model.md +1 -1
  356. package/docs/migration/divergences/bench-stats-float-precision.md +1 -1
  357. package/docs/migration/node-floor.md +1 -1
  358. package/docs/migration/yaml-roundtrip-spike.md +1 -1
  359. package/docs/personas.md +16 -5
  360. package/docs/positioning-evidence.md +86 -0
  361. package/docs/proof.md +86 -0
  362. package/docs/skills-catalog.md +1 -1
  363. package/docs/troubleshooting.md +8 -8
  364. package/docs/wedge/production-validator/README.md +57 -0
  365. package/docs/wedge/production-validator/production-validator.md +56 -0
  366. package/docs/wizard.md +2 -2
  367. package/package.json +1 -1
  368. package/src/config/agent-settings.template.yml +71 -4
  369. package/src/config/agents-paths.yml +254 -0
  370. package/src/config/budgets.yml +16 -0
  371. package/src/config/discovery/packs.yml +1 -0
  372. package/src/config/discovery/unassigned-artefacts.yml +2 -0
  373. package/src/config/gitignore-block.txt +25 -0
  374. package/src/config/host-capabilities.yml +31 -0
  375. package/src/config/profiles/balanced.ini +4 -0
  376. package/src/config/profiles/full.ini +4 -0
  377. package/src/config/profiles/minimal.ini +4 -0
  378. package/src/scripts/_cli/cmd_conformance.ts +716 -0
  379. package/src/scripts/_cli/cmd_doctor.ts +23 -2
  380. package/src/scripts/_cli/cmd_fleet.ts +401 -0
  381. package/src/scripts/_cli/cmd_preflight.ts +159 -0
  382. package/src/scripts/_dispatch.bash +10 -0
  383. package/src/scripts/_lib/knowledge_events.ts +193 -0
  384. package/src/scripts/_lib/subagent_steering.ts +115 -3
  385. package/src/scripts/_lib/text_similarity.ts +75 -0
  386. package/src/scripts/ai-video/test-pipeline.sh +1 -1
  387. package/src/scripts/ai_council/clients.ts +19 -3
  388. package/src/scripts/append_contested.ts +112 -0
  389. package/src/scripts/audit_auto_rules.ts +11 -1
  390. package/src/scripts/audit_mcp_tools.ts +25 -11
  391. package/src/scripts/bench_ab_v2_run.ts +527 -40
  392. package/src/scripts/bench_ab_v2_stats.ts +6 -0
  393. package/src/scripts/bench_matrix.ts +266 -0
  394. package/src/scripts/bootstrap_knowledge.ts +267 -0
  395. package/src/scripts/build_discovery_manifest.ts +42 -2
  396. package/src/scripts/build_proof.ts +214 -0
  397. package/src/scripts/check_always_budget.ts +3 -0
  398. package/src/scripts/check_augment_description_cap.ts +2 -2
  399. package/src/scripts/check_claims.ts +270 -0
  400. package/src/scripts/check_comparison.ts +79 -0
  401. package/src/scripts/check_generated_artefact_headers.ts +109 -0
  402. package/src/scripts/check_generator_output_coverage.ts +142 -0
  403. package/src/scripts/check_gitignore_freshness.ts +127 -0
  404. package/src/scripts/check_knowledge_pages.ts +210 -0
  405. package/src/scripts/check_knowledge_sharing.ts +162 -0
  406. package/src/scripts/check_media_deps.ts +91 -0
  407. package/src/scripts/check_memory_contradiction.ts +280 -0
  408. package/src/scripts/check_memory_similarity.ts +134 -0
  409. package/src/scripts/check_quality_regression.ts +56 -10
  410. package/src/scripts/check_references.ts +3 -1
  411. package/src/scripts/check_release_pr_shape.ts +4 -0
  412. package/src/scripts/check_site_links.ts +135 -0
  413. package/src/scripts/check_skill_gaps.ts +99 -0
  414. package/src/scripts/check_token_quality_golden.ts +197 -11
  415. package/src/scripts/check_tracked_but_ignored.ts +67 -0
  416. package/src/scripts/cluster_near_miss_patterns.ts +0 -0
  417. package/src/scripts/compile_router.ts +30 -3
  418. package/src/scripts/condense.ts +350 -14
  419. package/src/scripts/consolidate_knowledge_events.ts +192 -0
  420. package/src/scripts/degrade_to_pointer.ts +136 -0
  421. package/src/scripts/design_slop_rules.test.ts +208 -0
  422. package/src/scripts/design_slop_rules.ts +530 -0
  423. package/src/scripts/emit_knowledge_event.ts +158 -0
  424. package/src/scripts/export_replay_corpus.ts +187 -0
  425. package/src/scripts/external_sources_denylist.json +14 -3
  426. package/src/scripts/fold_intake.ts +281 -0
  427. package/src/scripts/generate_capability_matrix.ts +9 -1
  428. package/src/scripts/generate_knowledge_index.ts +222 -0
  429. package/src/scripts/hook_manifest.yaml +40 -17
  430. package/src/scripts/hooks/design_slop_hook.ts +181 -0
  431. package/src/scripts/hooks/dispatch_hook.ts +18 -0
  432. package/src/scripts/hot_context_hook.ts +372 -0
  433. package/src/scripts/install +47 -0
  434. package/src/scripts/install-hooks.sh +17 -0
  435. package/src/scripts/inventory_meta_layers.ts +11 -0
  436. package/src/scripts/janitor.ts +258 -0
  437. package/src/scripts/lint_agent_security.ts +1 -0
  438. package/src/scripts/lint_agents_layout.ts +74 -15
  439. package/src/scripts/lint_bench_ab.ts +4 -1
  440. package/src/scripts/lint_confusables.ts +197 -0
  441. package/src/scripts/lint_design_slop.ts +245 -0
  442. package/src/scripts/lint_featured_skills.ts +0 -0
  443. package/src/scripts/lint_framework_leakage_allowlist.json +26 -3
  444. package/src/scripts/lint_knowledge_scale.ts +250 -0
  445. package/src/scripts/lint_legal_pack.ts +67 -0
  446. package/src/scripts/lint_persona_governance.ts +8 -3
  447. package/src/scripts/lint_regression.ts +15 -0
  448. package/src/scripts/lint_roadmap_blockers.ts +202 -0
  449. package/src/scripts/lint_roadmap_complexity.ts +81 -2
  450. package/src/scripts/lint_subagent_determinism.ts +125 -0
  451. package/src/scripts/measure_augment_budget.ts +46 -6
  452. package/src/scripts/measure_patterns.ts +4 -3
  453. package/src/scripts/measure_skill_reduction.ts +6 -6
  454. package/src/scripts/migration_status.ts +6 -2
  455. package/src/scripts/mine_missing_guardrails.ts +189 -0
  456. package/src/scripts/parity/phase_gate.ts +1 -1
  457. package/src/scripts/parity/replay.ts +21 -0
  458. package/src/scripts/project_thin_rules.ts +120 -16
  459. package/src/scripts/release.ts +39 -1
  460. package/src/scripts/render_benchmark_composite.ts +378 -0
  461. package/src/scripts/roadmap_progress_hook.ts +101 -43
  462. package/src/scripts/schemas/skill.schema.json +27 -0
  463. package/src/scripts/schemas/subagent.schema.json +106 -0
  464. package/src/scripts/skill_linter.ts +1 -0
  465. package/src/scripts/smoke/kernel.sh +5 -4
  466. package/src/scripts/surface-tiers.yml +1 -0
  467. package/src/scripts/sync_gitignore.ts +4 -0
  468. package/src/scripts/update_skill_candidates.ts +172 -0
  469. package/src/scripts/validate_frontmatter.ts +1 -0
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * lint_design_slop — deterministic anti-slop DETECTOR for consumer projects.
4
+ *
5
+ * The aesthetic-PROVENANCE layer that `lint_design_quality` deliberately omits.
6
+ * It scans HTML/CSS/JSX/Markdown for the "AI tells" catalogued in
7
+ * `docs/guidelines/design-antipatterns.md` and emits structured findings
8
+ * (rule-id + catalog-id + severity P0–P3 + file:line). The rule registry lives
9
+ * in `design_slop_rules.ts`.
10
+ *
11
+ * FLAGS, NEVER A HARD BLOCK. Default exit is 0 regardless of findings — slop
12
+ * tells are rebuttable presumptions, not failures. CI opts into failing with
13
+ * `--fail-on <P0|P1|P2|P3>` (fails when any finding at or above that severity
14
+ * remains). This honours the council 2026-06-28 "flags not blocks" verdict.
15
+ *
16
+ * Zero runtime token cost: this runs in Node (CI / pre-commit / optional hook),
17
+ * never in the model's context. `design-review` cites the structured `--json`
18
+ * output instead of reloading the 12 KB prose catalog.
19
+ *
20
+ * Dependency-free pattern analysis (no postcss/@babel) — see the design note in
21
+ * design_slop_rules.ts. Same posture as lint_design_quality.
22
+ *
23
+ * Usage:
24
+ * npx tsx lint_design_slop.ts --dir src/ [--json] [--fail-on P1] [--quiet]
25
+ *
26
+ * Context gate: a consumer DESIGN.md (project root or scan dir) that declares a
27
+ * pattern as intentional suppresses the matching rule (e.g. "warm-neutral" →
28
+ * C5 cream-palette is not flagged). Inline-ignore (eslint-style):
29
+ * design-slop-disable <rule-id> (file scope, top of file)
30
+ * design-slop-disable-next-line <rule-id>
31
+ * design-slop-disable-line <rule-id>
32
+ * Per-project config (.design-quality.json, shared with lint_design_quality):
33
+ * { "ignoreRules": ["slop-c5-cream-palette"], "ignoreFiles": ["src/legacy/**"] }
34
+ *
35
+ * Exit codes: 0 = clean OR findings-below-threshold, 2 = findings at/above
36
+ * --fail-on threshold, 1 = internal error.
37
+ */
38
+ import fs from "node:fs";
39
+ import path from "node:path";
40
+ import {
41
+ SLOP_RULES,
42
+ type DesignContext,
43
+ type Engine,
44
+ type Severity,
45
+ } from "./design_slop_rules.js";
46
+
47
+ interface Finding {
48
+ rule: string;
49
+ catalogId: string;
50
+ severity: Severity;
51
+ file: string;
52
+ line: number;
53
+ snippet: string;
54
+ message: string;
55
+ }
56
+
57
+ interface ProjectConfig {
58
+ ignoreRules?: string[];
59
+ ignoreFiles?: string[];
60
+ }
61
+
62
+ const SEVERITY_ORDER: Severity[] = ["P3", "P2", "P1", "P0"];
63
+ const sevRank = (s: Severity): number => SEVERITY_ORDER.indexOf(s);
64
+
65
+ // ext → which engine-classes a file of that type can contain
66
+ function enginesForExt(ext: string): Set<Engine> {
67
+ if (/\.(css|scss|sass|less)$/i.test(ext)) return new Set<Engine>(["css"]);
68
+ if (/\.(html|htm|vue|svelte|astro)$/i.test(ext)) return new Set<Engine>(["css", "html", "copy"]);
69
+ if (/\.(jsx|tsx)$/i.test(ext)) return new Set<Engine>(["css", "jsx", "copy"]);
70
+ if (/\.(md|mdx)$/i.test(ext)) return new Set<Engine>(["copy"]);
71
+ return new Set<Engine>();
72
+ }
73
+
74
+ function* walkDir(dir: string, ext: RegExp): Generator<string> {
75
+ if (!fs.existsSync(dir)) return;
76
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
77
+ const full = path.join(dir, entry.name);
78
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
79
+ if (entry.isDirectory()) yield* walkDir(full, ext);
80
+ else if (ext.test(entry.name)) yield full;
81
+ }
82
+ }
83
+
84
+ function loadConfig(dir: string): ProjectConfig {
85
+ const p = path.join(dir, ".design-quality.json");
86
+ if (!fs.existsSync(p)) return {};
87
+ try {
88
+ return JSON.parse(fs.readFileSync(p, "utf-8")) as ProjectConfig;
89
+ } catch {
90
+ return {};
91
+ }
92
+ }
93
+
94
+ /** Read DESIGN.md (scan dir, then project root) as the context-gate source. */
95
+ export function loadDesignContext(scanDir: string): DesignContext {
96
+ const candidates = [
97
+ path.join(scanDir, "DESIGN.md"),
98
+ path.join(process.cwd(), "DESIGN.md"),
99
+ path.join(scanDir, "..", "DESIGN.md"),
100
+ ];
101
+ let raw = "";
102
+ for (const c of candidates) {
103
+ if (fs.existsSync(c)) {
104
+ raw = fs.readFileSync(c, "utf-8").toLowerCase();
105
+ break;
106
+ }
107
+ }
108
+ return {
109
+ raw,
110
+ has: (...keywords: string[]) => keywords.some((k) => raw.includes(k.toLowerCase())),
111
+ };
112
+ }
113
+
114
+ function parseIgnores(lines: string[]): Map<string, Set<number>> {
115
+ const ignores = new Map<string, Set<number>>();
116
+ const add = (rule: string, line: number) => {
117
+ const set = ignores.get(rule) ?? new Set<number>();
118
+ set.add(line);
119
+ ignores.set(rule, set);
120
+ };
121
+ for (let i = 0; i < lines.length; i++) {
122
+ const line = lines[i] ?? "";
123
+ const file = /design-slop-disable\s+([\w-]+)/i.exec(line);
124
+ if (file && file[1] && !/-line|-next-line/.test(line)) {
125
+ ignores.set(file[1].toLowerCase(), new Set([...Array(99999).keys()].map((n) => n + 1)));
126
+ }
127
+ const next = /design-slop-disable-next-line\s+([\w-]+)/i.exec(line);
128
+ if (next && next[1]) add(next[1].toLowerCase(), i + 2);
129
+ const cur = /design-slop-disable-line\s+([\w-]+)/i.exec(line);
130
+ if (cur && cur[1]) add(cur[1].toLowerCase(), i + 1);
131
+ }
132
+ return ignores;
133
+ }
134
+
135
+ export function scanFile(
136
+ content: string,
137
+ relPath: string,
138
+ ctx: DesignContext,
139
+ ): Finding[] {
140
+ const lines = content.split("\n");
141
+ const ext = path.extname(relPath).toLowerCase();
142
+ const fileEngines = enginesForExt(ext);
143
+ if (fileEngines.size === 0) return [];
144
+ const ignores = parseIgnores(lines);
145
+
146
+ const out: Finding[] = [];
147
+ for (const rule of SLOP_RULES) {
148
+ if (!rule.engines.some((e) => fileEngines.has(e))) continue;
149
+ if (rule.gated && rule.gated(ctx)) continue; // DESIGN.md declares intent → suppress
150
+ let hits;
151
+ try {
152
+ hits = rule.detect({ content, lines, ext, ctx });
153
+ } catch {
154
+ continue; // a single rule throwing never kills the scan
155
+ }
156
+ for (const h of hits) {
157
+ const ruleIgnore = ignores.get(rule.id.toLowerCase());
158
+ if (ruleIgnore && ruleIgnore.has(h.line)) continue;
159
+ out.push({
160
+ rule: rule.id,
161
+ catalogId: rule.catalogId,
162
+ severity: rule.severity,
163
+ file: relPath,
164
+ line: h.line,
165
+ snippet: h.snippet,
166
+ message: rule.message,
167
+ });
168
+ }
169
+ }
170
+ return out;
171
+ }
172
+
173
+ function main(): void {
174
+ const args = process.argv.slice(2);
175
+ const jsonMode = args.includes("--json");
176
+ const quiet = args.includes("--quiet");
177
+ const dirIdx = args.indexOf("--dir");
178
+ const scanDir = dirIdx >= 0 && args[dirIdx + 1] ? path.resolve(args[dirIdx + 1]!) : path.resolve(process.cwd(), "src");
179
+ const failIdx = args.indexOf("--fail-on");
180
+ const failOn = (failIdx >= 0 ? args[failIdx + 1] : undefined) as Severity | undefined;
181
+
182
+ if (!fs.existsSync(scanDir)) {
183
+ if (!quiet) {
184
+ process.stderr.write(`[lint_design_slop] scan directory not found: ${scanDir}\n`);
185
+ process.stderr.write("Opt-in for consumer projects. Run with --dir <path> at your UI source.\n");
186
+ }
187
+ process.exit(0);
188
+ }
189
+
190
+ const ctx = loadDesignContext(scanDir);
191
+ const config = loadConfig(process.cwd());
192
+ const ignoreRules = new Set((config.ignoreRules ?? []).map((r) => r.toLowerCase()));
193
+ const ignoreGlobs = config.ignoreFiles ?? [];
194
+
195
+ const files: string[] = [];
196
+ for (const f of walkDir(scanDir, /\.(html|htm|css|scss|sass|less|vue|svelte|astro|jsx|tsx|md|mdx)$/i)) {
197
+ if (!ignoreGlobs.some((g) => f.includes(g.replace("**", "")))) files.push(f);
198
+ }
199
+
200
+ const findings: Finding[] = [];
201
+ for (const fp of files) {
202
+ const rel = path.relative(process.cwd(), fp);
203
+ try {
204
+ const fileFindings = scanFile(fs.readFileSync(fp, "utf-8"), rel, ctx).filter(
205
+ (f) => !ignoreRules.has(f.rule.toLowerCase()),
206
+ );
207
+ findings.push(...fileFindings);
208
+ } catch (err) {
209
+ if (!quiet) process.stderr.write(`[lint_design_slop] error: ${fp}: ${err}\n`);
210
+ }
211
+ }
212
+
213
+ findings.sort((a, b) => sevRank(b.severity) - sevRank(a.severity));
214
+
215
+ const overThreshold = failOn
216
+ ? findings.filter((f) => sevRank(f.severity) >= sevRank(failOn))
217
+ : [];
218
+
219
+ if (jsonMode) {
220
+ process.stdout.write(JSON.stringify({ findings, failOn: failOn ?? null, overThreshold: overThreshold.length }, null, 2) + "\n");
221
+ process.exit(overThreshold.length > 0 ? 2 : 0);
222
+ }
223
+
224
+ if (findings.length === 0) {
225
+ if (!quiet) process.stdout.write(`✅ lint_design_slop: no anti-slop tells in ${files.length} file(s).\n`);
226
+ process.exit(0);
227
+ }
228
+
229
+ for (const f of findings) {
230
+ const icon = f.severity === "P0" || f.severity === "P1" ? "⚠️ " : "•";
231
+ process.stdout.write(`${icon} [${f.severity} ${f.catalogId}] ${f.file}:${f.line} (${f.rule}) — ${f.message}\n ${f.snippet}\n`);
232
+ }
233
+ process.stdout.write(
234
+ `\nlint_design_slop: ${findings.length} tell(s) flagged (rebuttable — declare intent in DESIGN.md, ` +
235
+ `design-slop-disable-next-line <rule>, or .design-quality.json).` +
236
+ (failOn ? ` ${overThreshold.length} at/above ${failOn}.` : " Flags only; no CI failure (pass --fail-on to gate).") +
237
+ "\n",
238
+ );
239
+ process.exit(overThreshold.length > 0 ? 2 : 0);
240
+ }
241
+
242
+ // Run only when invoked directly (not when imported by the test guard).
243
+ const invokedDirectly =
244
+ process.argv[1] !== undefined && /lint_design_slop\.ts$/.test(process.argv[1]);
245
+ if (invokedDirectly) main();
Binary file
@@ -480,7 +480,7 @@
480
480
  {
481
481
  "file": ".agent-src.uncondensed/rules/architecture.md",
482
482
  "lines": [
483
- 71
483
+ 69
484
484
  ],
485
485
  "reason": "Multi-framework module-system enumeration (Laravel, Turborepo, NestJS, Go) — comparative example, no project mandate"
486
486
  },
@@ -515,14 +515,14 @@
515
515
  {
516
516
  "file": ".agent-src.uncondensed/rules/architecture.md",
517
517
  "lines": [
518
- 76
518
+ 74
519
519
  ],
520
520
  "reason": "Single Laravel-shape example showing how `{module_root}/*/{agent_folder}/` resolves on a Laravel HMVC project (road-to-configurable-modules Phase D)"
521
521
  },
522
522
  {
523
523
  "file": ".agent-src.uncondensed/rules/roadmap-ci-steps-policy.md",
524
524
  "lines": [
525
- 101
525
+ 99
526
526
  ],
527
527
  "reason": "Single Laravel-shape example showing module-scoped roadmap path (road-to-configurable-modules Phase D)"
528
528
  },
@@ -598,6 +598,29 @@
598
598
  29
599
599
  ],
600
600
  "reason": "Cross-stack UI-stack enumeration (React, Blade, Tailwind)"
601
+ },
602
+ {
603
+ "file": "src/skills/code-review/SKILL.md",
604
+ "lines": [
605
+ 79,
606
+ 88,
607
+ 90
608
+ ],
609
+ "reason": "Cross-stack security-review checklist rows naming Laravel/Symfony/NestJS/DTO peers side-by-side (allowed multi-ecosystem documentation, not a mandate)"
610
+ },
611
+ {
612
+ "file": "src/skills/context-document/SKILL.md",
613
+ "lines": [
614
+ 83
615
+ ],
616
+ "reason": "Module-path resolution table citing the Laravel shape as one named example next to the generic modules.root_paths mechanism"
617
+ },
618
+ {
619
+ "file": "src/skills/verify-completion-evidence/SKILL.md",
620
+ "lines": [
621
+ 183
622
+ ],
623
+ "reason": "Carve-out pointer to the quality-tools skill (the sanctioned one-line handoff shape from framework-neutrality-in-generic-skills)"
601
624
  }
602
625
  ]
603
626
  }
@@ -0,0 +1,250 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Warn-only scale + budget tripwires for the memory/knowledge substrate —
4
+ * road-to-second-brain Phase 0 (council 2026-07-07, see
5
+ * `agents/settings/contexts/second-brain-delta-verdict.md`).
6
+ *
7
+ * These tripwires REPLACE roadmap gates: each warning names its pre-decided
8
+ * activation path, so a firing tripwire is actionable without re-opening the
9
+ * decision. The script never fails the build.
10
+ *
11
+ * Tripwires:
12
+ * - intake scale — `agents/knowledge/intake/events-*.jsonl` > 2000 events
13
+ * → wire `fold_intake.ts` into post-session/CI
14
+ * - sessions scale — `agents/knowledge/sessions/` > 50 pages
15
+ * → design fold-through-consolidate-gate for tracked pages
16
+ * - type scale — any single memory/knowledge type > 200 files
17
+ * → build the pre-decided file-first in-memory BM25 CLI
18
+ * - corpus scale — > 500 files across all types
19
+ * → same BM25 activation path
20
+ * - hot-context size — `agents/runtime/state/hot-context.md` > 600 tokens
21
+ * (estimated at 4 chars/token) → trim schema / fix the
22
+ * deterministic writer
23
+ *
24
+ * Usage: lint_knowledge_scale.ts [--dir <repo-root>] [--format text|json] [--quiet]
25
+ * Exit codes: 0 = ran cleanly (warnings never fail the build), 1 = usage
26
+ * error, 3 = internal error.
27
+ */
28
+ import * as fs from 'node:fs';
29
+ import * as path from 'node:path';
30
+ import process from 'node:process';
31
+ import { fileURLToPath } from 'node:url';
32
+
33
+ const PROG = 'lint_knowledge_scale.ts';
34
+
35
+ export const INTAKE_EVENTS_MAX = 2000;
36
+ export const SESSIONS_PAGES_MAX = 50;
37
+ export const TYPE_FILES_MAX = 200;
38
+ export const CORPUS_FILES_MAX = 500;
39
+ export const HOT_CONTEXT_TOKENS_MAX = 600;
40
+ export const CHARS_PER_TOKEN = 4;
41
+
42
+ const KNOWLEDGE_TYPED_DIRS = ['sessions', 'concepts', 'procedures', 'decisions'] as const;
43
+
44
+ export interface Warning {
45
+ rule: string;
46
+ metric: string; // "<observed>/<threshold>"
47
+ message: string; // includes the pre-decided activation path
48
+ }
49
+
50
+ function listFiles(dir: string, exts: readonly string[]): string[] {
51
+ let entries: fs.Dirent[];
52
+ try {
53
+ entries = fs.readdirSync(dir, { withFileTypes: true });
54
+ } catch {
55
+ return [];
56
+ }
57
+ return entries
58
+ .filter((e) => e.isFile() && exts.some((x) => e.name.endsWith(x)))
59
+ .map((e) => path.join(dir, e.name));
60
+ }
61
+
62
+ function countJsonlLines(file: string): number {
63
+ let text: string;
64
+ try {
65
+ text = fs.readFileSync(file, 'utf-8');
66
+ } catch {
67
+ return 0;
68
+ }
69
+ return text.split('\n').filter((l) => l.trim().length > 0).length;
70
+ }
71
+
72
+ /** Collect per-type file counts across the knowledge + memory substrate. */
73
+ export function collectTypeCounts(root: string): Map<string, number> {
74
+ const counts = new Map<string, number>();
75
+
76
+ // Knowledge cards (flat, top-level *.md except README/INDEX).
77
+ const cardsDir = path.join(root, 'agents', 'knowledge');
78
+ const cards = listFiles(cardsDir, ['.md']).filter((f) => {
79
+ const base = path.basename(f).toLowerCase();
80
+ return base !== 'readme.md' && base !== 'index.md';
81
+ });
82
+ counts.set('knowledge/cards', cards.length);
83
+
84
+ // Lifecycle-typed knowledge dirs.
85
+ for (const d of KNOWLEDGE_TYPED_DIRS) {
86
+ counts.set(`knowledge/${d}`, listFiles(path.join(cardsDir, d), ['.md']).length);
87
+ }
88
+
89
+ // Curated memory types: agents/memory/<type>/ dirs and <type>.yml files.
90
+ // The gitignored per-task scratch (`agents/memory/knowledge/`) is excluded —
91
+ // it is session state, not a curated type.
92
+ const memoryDir = path.join(root, 'agents', 'memory');
93
+ let memEntries: fs.Dirent[] = [];
94
+ try {
95
+ memEntries = fs.readdirSync(memoryDir, { withFileTypes: true });
96
+ } catch {
97
+ // no memory dir — fine
98
+ }
99
+ for (const e of memEntries) {
100
+ if (e.isDirectory()) {
101
+ if (e.name === 'knowledge' || e.name === 'intake' || e.name === 'archive') continue;
102
+ const n = listFiles(path.join(memoryDir, e.name), ['.md', '.yml', '.yaml']).length;
103
+ counts.set(`memory/${e.name}`, n);
104
+ } else if (e.isFile() && (e.name.endsWith('.yml') || e.name.endsWith('.yaml'))) {
105
+ counts.set(`memory/${e.name}`, 1);
106
+ }
107
+ }
108
+ return counts;
109
+ }
110
+
111
+ export function runChecks(root: string): Warning[] {
112
+ const warnings: Warning[] = [];
113
+
114
+ // 1. Intake scale.
115
+ const intakeDir = path.join(root, 'agents', 'knowledge', 'intake');
116
+ const intakeFiles = listFiles(intakeDir, ['.jsonl']).filter((f) =>
117
+ path.basename(f).startsWith('events-'),
118
+ );
119
+ const intakeEvents = intakeFiles.reduce((acc, f) => acc + countJsonlLines(f), 0);
120
+ if (intakeEvents > INTAKE_EVENTS_MAX) {
121
+ warnings.push({
122
+ rule: 'intake-scale',
123
+ metric: `${intakeEvents}/${INTAKE_EVENTS_MAX}`,
124
+ message:
125
+ `intake holds ${intakeEvents} events (> ${INTAKE_EVENTS_MAX}). ` +
126
+ 'Activation path (pre-decided): wire `src/scripts/fold_intake.ts` into the post-session/CI cadence.',
127
+ });
128
+ }
129
+
130
+ // 2. Sessions scale.
131
+ const sessionsDir = path.join(root, 'agents', 'knowledge', 'sessions');
132
+ const sessionPages = listFiles(sessionsDir, ['.md']).length;
133
+ if (sessionPages > SESSIONS_PAGES_MAX) {
134
+ warnings.push({
135
+ rule: 'sessions-scale',
136
+ metric: `${sessionPages}/${SESSIONS_PAGES_MAX}`,
137
+ message:
138
+ `agents/knowledge/sessions/ holds ${sessionPages} pages (> ${SESSIONS_PAGES_MAX}). ` +
139
+ 'Activation path (pre-decided): design fold-through-consolidate-gate for tracked pages — never fold tracked files without the gate.',
140
+ });
141
+ }
142
+
143
+ // 3 + 4. Type + corpus scale.
144
+ const typeCounts = collectTypeCounts(root);
145
+ let total = 0;
146
+ for (const [type, n] of typeCounts) {
147
+ total += n;
148
+ if (n > TYPE_FILES_MAX) {
149
+ warnings.push({
150
+ rule: 'type-scale',
151
+ metric: `${n}/${TYPE_FILES_MAX}`,
152
+ message:
153
+ `type '${type}' holds ${n} files (> ${TYPE_FILES_MAX}). ` +
154
+ 'Activation path (pre-decided): build the file-first in-memory BM25 CLI (re-index at session start, no vectors, no service).',
155
+ });
156
+ }
157
+ }
158
+ if (total > CORPUS_FILES_MAX) {
159
+ warnings.push({
160
+ rule: 'corpus-scale',
161
+ metric: `${total}/${CORPUS_FILES_MAX}`,
162
+ message:
163
+ `memory/knowledge corpus holds ${total} files (> ${CORPUS_FILES_MAX}). ` +
164
+ 'Activation path (pre-decided): build the file-first in-memory BM25 CLI (re-index at session start, no vectors, no service).',
165
+ });
166
+ }
167
+
168
+ // 5. Hot-context budget.
169
+ const hotContext = path.join(root, 'agents', 'runtime', 'state', 'hot-context.md');
170
+ let hotText = '';
171
+ try {
172
+ hotText = fs.readFileSync(hotContext, 'utf-8');
173
+ } catch {
174
+ // absent — fine (feature not active or fresh session)
175
+ }
176
+ if (hotText) {
177
+ const tokens = Math.ceil(hotText.length / CHARS_PER_TOKEN);
178
+ if (tokens > HOT_CONTEXT_TOKENS_MAX) {
179
+ warnings.push({
180
+ rule: 'hot-context-budget',
181
+ metric: `${tokens}/${HOT_CONTEXT_TOKENS_MAX}`,
182
+ message:
183
+ `hot-context.md parses to ~${tokens} tokens (> ${HOT_CONTEXT_TOKENS_MAX}). ` +
184
+ 'Activation path (pre-decided): trim the schema sections or fix the deterministic writer cap.',
185
+ });
186
+ }
187
+ }
188
+
189
+ return warnings;
190
+ }
191
+
192
+ function main(argv: string[]): number {
193
+ let dir = '.';
194
+ let format = 'text';
195
+ let quiet = false;
196
+ for (let i = 0; i < argv.length; i++) {
197
+ const a = argv[i];
198
+ if (a === '--dir') {
199
+ dir = argv[++i] ?? '';
200
+ if (!dir) {
201
+ process.stderr.write(`${PROG}: error: --dir requires a value\n`);
202
+ return 1;
203
+ }
204
+ } else if (a === '--format') {
205
+ format = argv[++i] ?? '';
206
+ if (format !== 'text' && format !== 'json') {
207
+ process.stderr.write(`${PROG}: error: --format must be text|json\n`);
208
+ return 1;
209
+ }
210
+ } else if (a === '--quiet') {
211
+ quiet = true;
212
+ } else if (a === '-h' || a === '--help') {
213
+ process.stdout.write(
214
+ `usage: ${PROG} [--dir <repo-root>] [--format text|json] [--quiet]\n`,
215
+ );
216
+ return 0;
217
+ } else {
218
+ process.stderr.write(`${PROG}: error: unknown argument ${a}\n`);
219
+ return 1;
220
+ }
221
+ }
222
+
223
+ let warnings: Warning[];
224
+ try {
225
+ warnings = runChecks(path.resolve(dir));
226
+ } catch (exc) {
227
+ process.stderr.write(`${PROG}: internal error: ${String(exc)}\n`);
228
+ return 3;
229
+ }
230
+
231
+ if (format === 'json') {
232
+ process.stdout.write(JSON.stringify({ warnings }, null, 2) + '\n');
233
+ } else if (warnings.length === 0) {
234
+ if (!quiet) {
235
+ process.stdout.write(`${PROG}: all scale tripwires silent (warn-only)\n`);
236
+ }
237
+ } else {
238
+ for (const w of warnings) {
239
+ process.stdout.write(`⚠️ [${w.rule}] ${w.metric} — ${w.message}\n`);
240
+ }
241
+ process.stdout.write(
242
+ `${PROG}: ${warnings.length} tripwire(s) fired — warn-only, build not failed\n`,
243
+ );
244
+ }
245
+ return 0;
246
+ }
247
+
248
+ if (fileURLToPath(import.meta.url) === path.resolve(process.argv[1] ?? '')) {
249
+ process.exit(main(process.argv.slice(2)));
250
+ }
@@ -74,6 +74,62 @@ export function legalPromotionViolations(packsYml: string, legalNotice: string):
74
74
  return [];
75
75
  }
76
76
 
77
+ // D7 — reference-resolution gate for the floor rule itself. The
78
+ // `legal-safety-floor` rule is authored in `src/rules/` but SHIPS/PROJECTS to
79
+ // `dist/agent-src/rules/`; its relative links must resolve from that SHIPPED
80
+ // projection root (7.5.0 shipped a `LEGAL_NOTICE.md` path that only resolved
81
+ // from the projection — correct by design, but nothing asserted it, so a wrong
82
+ // depth could silently regress). `check_references` does not catch this: it
83
+ // only scans `dist/agent-src/` + `agents/` (never `src/`), and its PATH_PATTERN
84
+ // matches only directory-rooted paths (`skills/…`, `docs/…`), so a bare
85
+ // `../../../LEGAL_NOTICE.md` filename link is invisible to it. This gate is the
86
+ // complementary backstop — every markdown link target in the floor rule must
87
+ // resolve from the projected `dist/agent-src/rules/` location.
88
+ const PROJECTED_FLOOR_DIR = path.join(REPO, 'dist', 'agent-src', 'rules');
89
+ // Markdown inline link: [text](target). Captures the target.
90
+ const MD_LINK_RE = /\[[^\]]*\]\(([^)]+)\)/g;
91
+
92
+ /**
93
+ * Pure reference-resolution check for the floor rule. `ruleText` is the floor
94
+ * rule body (read from `src/rules/legal-safety-floor.md`); every relative
95
+ * markdown link target it contains MUST resolve from `projectedDir` (the
96
+ * shipped `dist/agent-src/rules/` location). External (http/anchor/mailto) and
97
+ * absolute targets are skipped. Returns a Violation per unresolvable link.
98
+ */
99
+ export function legalFloorReferenceViolations(
100
+ ruleText: string,
101
+ projectedDir: string,
102
+ floorRel: string,
103
+ ): Violation[] {
104
+ const out: Violation[] = [];
105
+ const seen = new Set<string>();
106
+ MD_LINK_RE.lastIndex = 0;
107
+ let m: RegExpExecArray | null;
108
+ while ((m = MD_LINK_RE.exec(ruleText)) !== null) {
109
+ let target = (m[1] ?? '').trim();
110
+ // Strip a fragment/anchor and any title (`path "Title"`).
111
+ const titleSplit = target.match(/^(\S+)\s+["'(]/);
112
+ if (titleSplit) target = titleSplit[1] ?? target;
113
+ const hashIdx = target.indexOf('#');
114
+ if (hashIdx >= 0) target = target.slice(0, hashIdx);
115
+ if (!target) continue;
116
+ // Skip non-path targets: external URLs, mailto, in-page anchors,
117
+ // absolute paths (resolution root is the projection, not the FS root).
118
+ if (/^([a-z][a-z0-9+.-]*:|#|\/)/i.test(target)) continue;
119
+ if (seen.has(target)) continue;
120
+ seen.add(target);
121
+ const resolved = path.resolve(projectedDir, target);
122
+ if (!fs.existsSync(resolved)) {
123
+ out.push({
124
+ file: floorRel,
125
+ rule: 'floor-reference',
126
+ msg: `link target "${target}" does not resolve from the shipped projection (dist/agent-src/rules/) — fix the relative depth so it resolves from the projected rule location`,
127
+ });
128
+ }
129
+ }
130
+ return out;
131
+ }
132
+
77
133
  // D4 — definitive-legal-language blocklist (the floor bans these; this is the
78
134
  // deterministic backstop over skill bodies). Narrow on purpose; the floor's
79
135
  // prompt layer is the primary enforcement.
@@ -175,6 +231,17 @@ export function lintLegalPack(skillsDir: string = SKILLS_DIR): Violation[] {
175
231
  if (fs.existsSync(PACKS_YML) && fs.existsSync(PACK_NOTICE)) {
176
232
  violations.push(...legalPromotionViolations(_readText(PACKS_YML), _readText(PACK_NOTICE)));
177
233
  }
234
+ // D7 — floor-rule reference gate: every link in the floor rule must
235
+ // resolve from its SHIPPED projection (dist/agent-src/rules/).
236
+ if (fs.existsSync(PROJECTED_FLOOR_DIR)) {
237
+ violations.push(
238
+ ...legalFloorReferenceViolations(
239
+ _readText(FLOOR_RULE),
240
+ PROJECTED_FLOOR_DIR,
241
+ path.relative(REPO, FLOOR_RULE),
242
+ ),
243
+ );
244
+ }
178
245
  }
179
246
  return violations;
180
247
  }
@@ -26,10 +26,13 @@ const QUIET = process.argv.includes('--quiet');
26
26
 
27
27
  const _HERE = fileURLToPath(import.meta.url);
28
28
  const REPO = path.resolve(path.dirname(_HERE), '..', '..');
29
- const PERSONA_DIR = path.join(REPO, '.agent-src.uncondensed', 'personas');
29
+ // Source of truth is `src/` (ADR-051); the old condensed-legacy source tree is
30
+ // empty post-py2ts, so the previous path silently scanned zero personas and the
31
+ // governance gate was inert. Scan the real source tree.
32
+ const PERSONA_DIR = path.join(REPO, 'src', 'agent-src', 'personas');
30
33
  const SKILL_ROOTS: readonly string[] = [
31
- path.join(REPO, '.agent-src.uncondensed', 'skills'),
32
- path.join(REPO, '.claude', 'skills'),
34
+ path.join(REPO, 'src', 'skills'),
35
+ path.join(REPO, 'src', 'rules'),
33
36
  ];
34
37
 
35
38
  // Per-domain cap — mirrors persona-governance.md § Per-domain cap.
@@ -38,6 +41,8 @@ const DOMAIN_MAP: Record<string, string> = {
38
41
  'ai-video-technical-director': 'ai-video',
39
42
  'backend-architect': 'backend',
40
43
  'eloquent-tamer': 'backend',
44
+ 'performance-engineer': 'performance',
45
+ 'data-integrity': 'data',
41
46
  cmo: 'gtm',
42
47
  revops: 'gtm',
43
48
  'growth-pm': 'growth',
@@ -114,6 +114,21 @@ function run_linter_json(ref: string | null, repo_root: string): LinterJson {
114
114
  return { results: [], summary: {} };
115
115
  }
116
116
  const baselineArgs = ['--all', '--format', 'json', '--repo-root', tmpdir];
117
+ // Local python-skip guard (teardown D2): a historical `.py` baseline
118
+ // genuinely needs python3; when the runtime is absent, degrade to an
119
+ // empty baseline (same contract as a missing linter) instead of a
120
+ // spawn error — decouples the python-free-env shim retirement from
121
+ // porting pre-migration baselines to a frozen TS golden.
122
+ if (
123
+ baseline_linter.endsWith('.py') &&
124
+ spawnSync('python3', ['--version'], { encoding: 'utf8' }).status !== 0
125
+ ) {
126
+ process.stderr.write(
127
+ `Warning: baseline '${ref}' is pre-migration (.py) and python3 is ` +
128
+ `unavailable — baseline treated as empty.\n`,
129
+ );
130
+ return { results: [], summary: {} };
131
+ }
117
132
  const result = baseline_linter.endsWith('.ts')
118
133
  ? (() => {
119
134
  const inv = _resolve_tsx_invocation(baseline_linter, baselineArgs);