@event4u/agent-config 9.9.0 → 9.11.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 (479) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +212 -194
  3. package/README.md +13 -16
  4. package/agents/templates/.ai-council.yml.example +481 -0
  5. package/agents/templates/.ai-video.xml.example +247 -0
  6. package/dist/agent-src/commands/agent-status.md +12 -11
  7. package/dist/agent-src/commands/agents/user/accept.md +115 -30
  8. package/dist/agent-src/commands/agents/user/delete.md +147 -0
  9. package/dist/agent-src/commands/agents/user/review.md +65 -28
  10. package/dist/agent-src/commands/agents/user/show.md +82 -29
  11. package/dist/agent-src/commands/agents/user/update.md +2 -2
  12. package/dist/agent-src/commands/agents/user.md +16 -3
  13. package/dist/agent-src/commands/check-current-md.md +0 -10
  14. package/dist/agent-src/commands/condense.md +28 -97
  15. package/dist/agent-src/commands/cost/report.md +7 -0
  16. package/dist/agent-src/commands/fix/portability.md +0 -8
  17. package/dist/agent-src/commands/fix/refs.md +0 -8
  18. package/dist/agent-src/commands/humanize.md +2 -2
  19. package/dist/agent-src/commands/jira-ticket.md +1 -1
  20. package/dist/agent-src/commands/memory/load.md +11 -0
  21. package/dist/agent-src/commands/optimize/skills.md +1 -1
  22. package/dist/agent-src/commands/pr/create.md +4 -4
  23. package/dist/agent-src/commands/profile/show.md +3 -3
  24. package/dist/agent-src/commands/rule-compliance-audit.md +5 -4
  25. package/dist/agent-src/commands/security-audit-config.md +1 -1
  26. package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
  27. package/dist/agent-src/commands/tdd.md +21 -0
  28. package/dist/agent-src/commands/team/delegate.md +2 -2
  29. package/dist/agent-src/commands/team-knowledge/bootstrap.md +9 -8
  30. package/dist/agent-src/commands/team-knowledge/consolidate.md +8 -7
  31. package/dist/agent-src/commands/team.md +4 -1
  32. package/dist/agent-src/commands/upstream-contribute.md +0 -1
  33. package/dist/agent-src/contexts/authority/commit-mechanics.md +7 -0
  34. package/dist/agent-src/contexts/authority/destructive-mechanics.md +16 -0
  35. package/dist/agent-src/contexts/authority/scope-mechanics.md +61 -0
  36. package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +20 -18
  37. package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
  38. package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -1
  39. package/dist/agent-src/contexts/communication/rules-auto/source-of-truth-mechanics.md +9 -10
  40. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +1 -1
  41. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +11 -0
  42. package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +26 -15
  43. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +3 -0
  44. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +67 -37
  45. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
  46. package/dist/agent-src/contexts/execution/autonomy-examples.md +1 -1
  47. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +7 -6
  48. package/dist/agent-src/contexts/execution/evidence-discipline.md +92 -77
  49. package/dist/agent-src/contexts/execution/orchestration-benchmark-gate.md +22 -21
  50. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +24 -0
  51. package/dist/agent-src/contexts/execution/project-intelligence.md +122 -103
  52. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +23 -21
  53. package/dist/agent-src/contexts/execution/subagent-response-contract.md +5 -5
  54. package/dist/agent-src/contexts/execution/subagent-routing.md +11 -0
  55. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +13 -13
  56. package/dist/agent-src/contexts/execution/subagent-steering.md +36 -34
  57. package/dist/agent-src/contexts/execution/toolchain-resolver.md +1 -1
  58. package/dist/agent-src/contexts/execution/user-memory-channels.md +189 -0
  59. package/dist/agent-src/contexts/execution/verification-mechanics.md +9 -0
  60. package/dist/agent-src/contexts/model-recommendations.md +3 -2
  61. package/dist/agent-src/contexts/subagent-configuration.md +3 -3
  62. package/dist/agent-src/ghostwriter/README.md +2 -2
  63. package/dist/agent-src/packs/README.md +1 -1
  64. package/dist/agent-src/personas/README.md +5 -5
  65. package/dist/agent-src/personas/_template-specialist/persona.md +3 -3
  66. package/dist/agent-src/personas/backend-architect.md +24 -23
  67. package/dist/agent-src/personas/eloquent-tamer.md +30 -30
  68. package/dist/agent-src/personas/frontend-engineer.md +30 -30
  69. package/dist/agent-src/personas/product-owner.md +41 -38
  70. package/dist/agent-src/personas/qa.md +13 -13
  71. package/dist/agent-src/personas/security-engineer.md +22 -22
  72. package/dist/agent-src/presets/README.md +3 -3
  73. package/dist/agent-src/profiles/README.md +3 -3
  74. package/dist/agent-src/rules/active-remediation.md +2 -2
  75. package/dist/agent-src/rules/artifact-engagement-recording.md +4 -4
  76. package/dist/agent-src/rules/ask-when-uncertain.md +0 -4
  77. package/dist/agent-src/rules/augment-edit-discipline.md +1 -1
  78. package/dist/agent-src/rules/broken-access-control.md +4 -4
  79. package/dist/agent-src/rules/code-comment-discipline.md +1 -1
  80. package/dist/agent-src/rules/code-provenance.md +2 -2
  81. package/dist/agent-src/rules/commit-policy.md +4 -9
  82. package/dist/agent-src/rules/communication-through-line.md +5 -5
  83. package/dist/agent-src/rules/decision-revisit-gate.md +1 -1
  84. package/dist/agent-src/rules/design-fidelity.md +1 -1
  85. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
  86. package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
  87. package/dist/agent-src/rules/domain-safety-pii.md +1 -1
  88. package/dist/agent-src/rules/external-code-graph-interop.md +1 -1
  89. package/dist/agent-src/rules/fast-path-marker-visibility.md +43 -7
  90. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  91. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -3
  92. package/dist/agent-src/rules/history-discipline.md +1 -1
  93. package/dist/agent-src/rules/legal-safety-floor.md +1 -1
  94. package/dist/agent-src/rules/lethal-trifecta-guard.md +5 -5
  95. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +10 -8
  96. package/dist/agent-src/rules/media-governance-routing.md +13 -13
  97. package/dist/agent-src/rules/media-sync-ground-truth.md +29 -11
  98. package/dist/agent-src/rules/no-cheap-questions.md +7 -7
  99. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +29 -18
  100. package/dist/agent-src/rules/non-destructive-by-default.md +5 -23
  101. package/dist/agent-src/rules/onboarding-gate.md +14 -4
  102. package/dist/agent-src/rules/persona-governance.md +2 -2
  103. package/dist/agent-src/rules/prefer-enums-over-literals.md +9 -9
  104. package/dist/agent-src/rules/preservation-guard.md +10 -2
  105. package/dist/agent-src/rules/question-not-instruction.md +1 -1
  106. package/dist/agent-src/rules/roadmap-progress-sync.md +6 -6
  107. package/dist/agent-src/rules/rule-type-governance.md +1 -1
  108. package/dist/agent-src/rules/scale-discipline.md +1 -1
  109. package/dist/agent-src/rules/scope-control.md +1 -1
  110. package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
  111. package/dist/agent-src/rules/security-sensitive-stop.md +17 -11
  112. package/dist/agent-src/rules/senior-engineering-discipline.md +17 -17
  113. package/dist/agent-src/rules/session-canary.md +1 -1
  114. package/dist/agent-src/rules/skill-quality.md +1 -1
  115. package/dist/agent-src/rules/source-confidentiality.md +21 -19
  116. package/dist/agent-src/rules/source-of-truth.md +6 -5
  117. package/dist/agent-src/rules/spreadsheet-source-quality.md +2 -2
  118. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  119. package/dist/agent-src/rules/think-before-action.md +5 -5
  120. package/dist/agent-src/rules/token-budget-discipline.md +5 -3
  121. package/dist/agent-src/rules/token-efficiency.md +2 -2
  122. package/dist/agent-src/rules/untrusted-input-defense.md +4 -4
  123. package/dist/agent-src/rules/user-interaction.md +12 -0
  124. package/dist/agent-src/rules/verify-before-complete.md +4 -24
  125. package/dist/agent-src/skills/adversarial-review/SKILL.md +2 -2
  126. package/dist/agent-src/skills/agent-security-review/SKILL.md +52 -45
  127. package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +2 -2
  128. package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +20 -20
  129. package/dist/agent-src/skills/ai-council/SKILL.md +185 -128
  130. package/dist/agent-src/skills/analysis-skill-router/SKILL.md +3 -3
  131. package/dist/agent-src/skills/api-endpoint/SKILL.md +2 -2
  132. package/dist/agent-src/skills/artisan-commands/SKILL.md +2 -2
  133. package/dist/agent-src/skills/async-python-patterns/SKILL.md +8 -7
  134. package/dist/agent-src/skills/authz-review/SKILL.md +16 -15
  135. package/dist/agent-src/skills/aws-infrastructure/SKILL.md +5 -5
  136. package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
  137. package/dist/agent-src/skills/bug-analyzer/SKILL.md +30 -12
  138. package/dist/agent-src/skills/code-intelligence/SKILL.md +0 -1
  139. package/dist/agent-src/skills/code-intelligence/evals/triggers.json +52 -0
  140. package/dist/agent-src/skills/code-review/SKILL.md +6 -6
  141. package/dist/agent-src/skills/command-routing/SKILL.md +5 -4
  142. package/dist/agent-src/skills/composer-packages/SKILL.md +2 -2
  143. package/dist/agent-src/skills/condense-memory/SKILL.md +43 -41
  144. package/dist/agent-src/skills/context-document/SKILL.md +23 -21
  145. package/dist/agent-src/skills/copilot-config/SKILL.md +6 -1
  146. package/dist/agent-src/skills/decision-record/SKILL.md +20 -18
  147. package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
  148. package/dist/agent-src/skills/design-review/SKILL.md +15 -14
  149. package/dist/agent-src/skills/design-system-capture/reference/design-system-json.md +28 -25
  150. package/dist/agent-src/skills/devcontainer/SKILL.md +2 -2
  151. package/dist/agent-src/skills/docker/SKILL.md +1 -1
  152. package/dist/agent-src/skills/docx-authoring/evals/triggers.json +52 -0
  153. package/dist/agent-src/skills/emit-tickets/SKILL.md +2 -2
  154. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +1 -1
  155. package/dist/agent-src/skills/estimate-ticket/SKILL.md +2 -2
  156. package/dist/agent-src/skills/evaluate-llm-feature/SKILL.md +0 -1
  157. package/dist/agent-src/skills/evaluate-llm-feature/evals/triggers.json +52 -0
  158. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +21 -7
  159. package/dist/agent-src/skills/fe-design/SKILL.md +10 -0
  160. package/dist/agent-src/skills/feature-planning/SKILL.md +2 -2
  161. package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +3 -3
  162. package/dist/agent-src/skills/flux/SKILL.md +1 -1
  163. package/dist/agent-src/skills/frontend-render-security/SKILL.md +13 -13
  164. package/dist/agent-src/skills/git-workflow/SKILL.md +33 -33
  165. package/dist/agent-src/skills/grafana/SKILL.md +5 -0
  166. package/dist/agent-src/skills/humanizer/SKILL.md +83 -66
  167. package/dist/agent-src/skills/humanizer/data/patterns.md +14 -14
  168. package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +4 -4
  169. package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +82 -37
  170. package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +17 -5
  171. package/dist/agent-src/skills/judge-injection-defense/SKILL.md +63 -25
  172. package/dist/agent-src/skills/judge-security-auditor/SKILL.md +2 -0
  173. package/dist/agent-src/skills/judge-synthesis/SKILL.md +72 -28
  174. package/dist/agent-src/skills/laravel-horizon/SKILL.md +5 -0
  175. package/dist/agent-src/skills/laravel-mail/SKILL.md +5 -4
  176. package/dist/agent-src/skills/laravel-middleware/SKILL.md +5 -4
  177. package/dist/agent-src/skills/laravel-notifications/SKILL.md +10 -9
  178. package/dist/agent-src/skills/laravel-pennant/SKILL.md +1 -1
  179. package/dist/agent-src/skills/laravel-pulse/SKILL.md +9 -8
  180. package/dist/agent-src/skills/laravel-reverb/SKILL.md +6 -5
  181. package/dist/agent-src/skills/laravel-scheduling/SKILL.md +6 -1
  182. package/dist/agent-src/skills/laravel-validation/SKILL.md +12 -0
  183. package/dist/agent-src/skills/launch-readiness/SKILL.md +1 -1
  184. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +7 -7
  185. package/dist/agent-src/skills/learning-tutor/SKILL.md +44 -43
  186. package/dist/agent-src/skills/learning-tutor/evals/triggers.json +52 -0
  187. package/dist/agent-src/skills/license-compliance-audit/SKILL.md +7 -7
  188. package/dist/agent-src/skills/license-compliance-borrow-check/SKILL.md +3 -3
  189. package/dist/agent-src/skills/license-compliance-credits/SKILL.md +4 -4
  190. package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +0 -1
  191. package/dist/agent-src/skills/memory-consolidation/SKILL.md +69 -64
  192. package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -6
  193. package/dist/agent-src/skills/pdf-tools/evals/triggers.json +52 -0
  194. package/dist/agent-src/skills/performance-analysis/SKILL.md +7 -3
  195. package/dist/agent-src/skills/persona-improvement/SKILL.md +0 -2
  196. package/dist/agent-src/skills/persona-improvement/evals/triggers.json +52 -0
  197. package/dist/agent-src/skills/php-coder/SKILL.md +10 -0
  198. package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +129 -120
  199. package/dist/agent-src/skills/prediction-pool-optimizer/reference/ev-fixtures.md +36 -35
  200. package/dist/agent-src/skills/prediction-pool-optimizer/reference/odds-and-bonus.md +45 -41
  201. package/dist/agent-src/skills/project-analysis-core/SKILL.md +4 -4
  202. package/dist/agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +3 -3
  203. package/dist/agent-src/skills/project-analysis-react/SKILL.md +1 -1
  204. package/dist/agent-src/skills/project-analysis-symfony/SKILL.md +1 -1
  205. package/dist/agent-src/skills/project-analysis-zend-laminas/SKILL.md +2 -2
  206. package/dist/agent-src/skills/prompt-engineering-patterns/SKILL.md +1 -1
  207. package/dist/agent-src/skills/prompt-validator/SKILL.md +39 -39
  208. package/dist/agent-src/skills/quality-tools/SKILL.md +15 -15
  209. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +55 -19
  210. package/dist/agent-src/skills/react-shadcn-ui/reference/registry.md +29 -27
  211. package/dist/agent-src/skills/readme-writing-package/SKILL.md +2 -2
  212. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +25 -25
  213. package/dist/agent-src/skills/recursive-verification/SKILL.md +6 -5
  214. package/dist/agent-src/skills/refine-prompt/SKILL.md +1 -1
  215. package/dist/agent-src/skills/refine-ticket/SKILL.md +20 -2
  216. package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
  217. package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
  218. package/dist/agent-src/skills/roadmap-management/SKILL.md +80 -66
  219. package/dist/agent-src/skills/roadmap-writing/SKILL.md +84 -77
  220. package/dist/agent-src/skills/rule-refactor/SKILL.md +1 -1
  221. package/dist/agent-src/skills/screenshot-hygiene/evals/triggers.json +52 -0
  222. package/dist/agent-src/skills/security-audit/SKILL.md +26 -9
  223. package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +38 -16
  224. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +14 -11
  225. package/dist/agent-src/skills/skill-writing/SKILL.md +9 -8
  226. package/dist/agent-src/skills/song-to-script/SKILL.md +93 -85
  227. package/dist/agent-src/skills/sql-writing/SKILL.md +2 -2
  228. package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +4 -3
  229. package/dist/agent-src/skills/standards-from-config/SKILL.md +61 -43
  230. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +22 -8
  231. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +28 -2
  232. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +13 -13
  233. package/dist/agent-src/skills/systematic-debugging/SKILL.md +22 -21
  234. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
  235. package/dist/agent-src/skills/technical-specification/SKILL.md +5 -0
  236. package/dist/agent-src/skills/terraform/SKILL.md +2 -2
  237. package/dist/agent-src/skills/terragrunt/SKILL.md +8 -8
  238. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +1 -1
  239. package/dist/agent-src/skills/threat-modeling/SKILL.md +19 -13
  240. package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
  241. package/dist/agent-src/skills/upstream-contribute/SKILL.md +0 -1
  242. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +9 -9
  243. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -1
  244. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +4 -6
  245. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +67 -61
  246. package/dist/agent-src/skills/video-director/SKILL.md +7 -7
  247. package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -3
  248. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  249. package/dist/agent-src/templates/contexts/knowledge-pages.md +47 -45
  250. package/dist/agent-src/templates/contexts/lesson-card.md +2 -2
  251. package/dist/agent-src/templates/contexts/tenant-boundaries.md +2 -2
  252. package/dist/agent-src/templates/contexts.md +1 -1
  253. package/dist/agent-src/templates/features.md +1 -1
  254. package/dist/agent-src/templates/roadmaps.md +125 -116
  255. package/dist/agent-src/templates/rule.md +2 -1
  256. package/dist/agent-src/templates/scripts/pr_risk_review.ts +0 -0
  257. package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  258. package/dist/agent-src/templates/scripts/tier_usage_report.ts +2 -2
  259. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
  260. package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
  261. package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +22 -2
  262. package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +21 -2
  263. package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
  264. package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
  265. package/dist/agent-src/templates/scripts/work_engine/state.ts +21 -4
  266. package/dist/agent-src/user-types/README.md +8 -8
  267. package/dist/agent-src/user-types/galabau-field-crew.md +34 -33
  268. package/dist/agent-src/user-types/metalworking-shop.md +35 -34
  269. package/dist/agent-src/user-types/truck-driver.md +22 -20
  270. package/dist/cli/initRouting.js +74 -11
  271. package/dist/cli/initRouting.js.map +1 -1
  272. package/dist/cli/main.js +14 -3
  273. package/dist/cli/main.js.map +1 -1
  274. package/dist/cli/python/workspace_roles.js +2 -2
  275. package/dist/cli/python/workspace_roles.js.map +1 -1
  276. package/dist/cli-delegate/chunk-4SV3XGFA.js +6910 -0
  277. package/dist/cli-delegate/chunk-736JCWLM.js +1104 -0
  278. package/dist/cli-delegate/chunk-7DSAMZFU.js +356 -0
  279. package/dist/cli-delegate/chunk-7HQ52DHU.js +74 -0
  280. package/dist/cli-delegate/chunk-BJGXZNPM.js +266 -0
  281. package/dist/cli-delegate/chunk-FTAISGDQ.js +117 -0
  282. package/dist/cli-delegate/chunk-GME3Q44L.js +82 -0
  283. package/dist/cli-delegate/chunk-GRRPEPRN.js +336 -0
  284. package/dist/cli-delegate/chunk-HJ6DAJHR.js +502 -0
  285. package/dist/cli-delegate/chunk-IR7P7JWA.js +872 -0
  286. package/dist/cli-delegate/chunk-J55WI3RR.js +47 -0
  287. package/dist/cli-delegate/chunk-MCJYCQPF.js +35 -0
  288. package/dist/cli-delegate/chunk-NDJLNC6Q.js +169 -0
  289. package/dist/cli-delegate/chunk-OMIVVCG2.js +26 -0
  290. package/dist/cli-delegate/chunk-OY53J6II.js +7336 -0
  291. package/dist/cli-delegate/chunk-RDGRHAAB.js +259 -0
  292. package/dist/cli-delegate/chunk-TFG57JJM.js +1969 -0
  293. package/dist/cli-delegate/chunk-XX6TOPD7.js +715 -0
  294. package/dist/cli-delegate/chunk-YMFO6FDN.js +10603 -0
  295. package/dist/cli-delegate/cmd_analyze_session.js +294 -0
  296. package/dist/cli-delegate/cmd_conformance.js +646 -0
  297. package/dist/cli-delegate/cmd_converge.js +326 -0
  298. package/dist/cli-delegate/cmd_doctor.js +144 -0
  299. package/dist/cli-delegate/cmd_explain.js +2508 -0
  300. package/dist/cli-delegate/cmd_export.js +296 -0
  301. package/dist/cli-delegate/cmd_fleet.js +332 -0
  302. package/dist/cli-delegate/cmd_memory_get.js +3878 -0
  303. package/dist/cli-delegate/cmd_migrate.js +11 -0
  304. package/dist/cli-delegate/cmd_preflight.js +270 -0
  305. package/dist/cli-delegate/cmd_prune.js +444 -0
  306. package/dist/cli-delegate/cmd_refresh.js +28 -0
  307. package/dist/cli-delegate/cmd_settings_check.js +574 -0
  308. package/dist/cli-delegate/cmd_settings_migrate.js +223 -0
  309. package/dist/cli-delegate/cmd_sync.js +264 -0
  310. package/dist/cli-delegate/cmd_uninstall.js +656 -0
  311. package/dist/cli-delegate/cmd_update.js +425 -0
  312. package/dist/cli-delegate/cmd_upgrade.js +444 -0
  313. package/dist/cli-delegate/cmd_validate.js +305 -0
  314. package/dist/cli-delegate/cmd_versions.js +370 -0
  315. package/dist/discovery/deprecation-report.md +1 -1
  316. package/dist/discovery/discovery-manifest.json +100 -67
  317. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  318. package/dist/discovery/discovery-manifest.summary.md +4 -4
  319. package/dist/discovery/orphan-report.md +1 -1
  320. package/dist/discovery/packs.json +16 -10
  321. package/dist/discovery/trust-report.md +2 -2
  322. package/dist/discovery/workspaces.json +7 -5
  323. package/dist/hooks/dispatch.js +186 -12
  324. package/dist/install/emit_host_rules_cli.js +2 -1
  325. package/dist/install/emit_host_rules_cli.js.map +1 -1
  326. package/dist/install/install.mjs +418 -378
  327. package/dist/install/rule_scope.js +5 -1
  328. package/dist/install/rule_scope.js.map +1 -1
  329. package/dist/install/toolDetection.js +40 -12
  330. package/dist/install/toolDetection.js.map +1 -1
  331. package/dist/install/wizard-plan.js +2 -2
  332. package/dist/install/wizard-plan.js.map +1 -1
  333. package/dist/mcp/registry-manifest.json +3 -3
  334. package/dist/mcp/server.json +2 -2
  335. package/dist/mcp/server.mjs +2194 -1003
  336. package/dist/router.json +1 -1
  337. package/dist/scripts/_lib/compile_time_toggles.js +48 -0
  338. package/dist/scripts/_lib/compile_time_toggles.js.map +1 -0
  339. package/dist/scripts/condense.js +234 -217
  340. package/dist/scripts/condense.js.map +1 -1
  341. package/dist/server/schemas/settings.js +4 -0
  342. package/dist/server/schemas/settings.js.map +1 -1
  343. package/dist/shared/userMd/utils.js +30 -0
  344. package/dist/shared/userMd/utils.js.map +1 -1
  345. package/dist/ui/assets/index-BpSQt5vm.js.map +1 -1
  346. package/docs/guidelines/agent-infra/api-cost-levers.md +56 -5
  347. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +93 -33
  348. package/package.json +4 -2
  349. package/src/agent-src/templates/scripts/pr_risk_review.ts +0 -0
  350. package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  351. package/src/agent-src/templates/scripts/tier_usage_report.ts +2 -2
  352. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
  353. package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
  354. package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +22 -2
  355. package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +21 -2
  356. package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
  357. package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
  358. package/src/agent-src/templates/scripts/work_engine/state.ts +21 -4
  359. package/src/config/agent-settings.template.yml +32 -2
  360. package/src/config/ci-local-parity.yml +142 -0
  361. package/src/config/discovery/packs.yml +7 -0
  362. package/src/config/evaluator-budgets.json +1 -1
  363. package/src/config/gate-coverage.yml +127 -0
  364. package/src/config/pack-size-budget.json +27 -0
  365. package/src/config/preamble-payload-budget.json +44 -0
  366. package/src/install/emit_host_rules_cli.ts +2 -1
  367. package/src/install/rule_scope.ts +5 -1
  368. package/src/install/toolDetection.ts +39 -8
  369. package/src/install/wizard-plan.ts +2 -2
  370. package/src/scripts/_cli/cmd_conformance.ts +2 -1
  371. package/src/scripts/_cli/cmd_converge.ts +2 -1
  372. package/src/scripts/_cli/cmd_doctor.ts +292 -15
  373. package/src/scripts/_cli/cmd_export.ts +2 -1
  374. package/src/scripts/_cli/cmd_fleet.ts +2 -1
  375. package/src/scripts/_cli/cmd_migrate.ts +2 -1
  376. package/src/scripts/_cli/cmd_preflight.ts +2 -1
  377. package/src/scripts/_cli/cmd_refresh.ts +2 -1
  378. package/src/scripts/_cli/cmd_update.ts +2 -1
  379. package/src/scripts/_cli/cmd_upgrade.ts +2 -1
  380. package/src/scripts/_cli/cmd_versions.ts +2 -1
  381. package/src/scripts/_cli/detection_report.ts +480 -0
  382. package/src/scripts/_dispatch.bash +52 -14
  383. package/src/scripts/_lib/agent_user_profile.ts +381 -0
  384. package/src/scripts/_lib/agents_overlay.ts +9 -0
  385. package/src/scripts/_lib/anchor_eval.ts +311 -0
  386. package/src/scripts/_lib/cc_transcript.ts +316 -0
  387. package/src/scripts/_lib/changelog_eras.ts +103 -9
  388. package/src/scripts/_lib/compile_time_toggles.ts +79 -0
  389. package/src/scripts/_lib/confusables.ts +101 -0
  390. package/src/scripts/_lib/duplicate_scope_census.ts +77 -0
  391. package/src/scripts/_lib/environment_detector.ts +441 -0
  392. package/src/scripts/_lib/managed_agents_folder.ts +181 -0
  393. package/src/scripts/_lib/package_root.ts +72 -0
  394. package/src/scripts/_lib/payload_hash_drift.ts +126 -0
  395. package/src/scripts/_lib/preservation_migration.ts +291 -0
  396. package/src/scripts/_lib/retrieval_sanitize.ts +166 -2
  397. package/src/scripts/_lib/scan_scope.ts +115 -0
  398. package/src/scripts/_lib/user_global_memory_audit.ts +187 -0
  399. package/src/scripts/_lib/user_global_observations.ts +830 -0
  400. package/src/scripts/_lib/user_global_revocations.ts +110 -0
  401. package/src/scripts/_lib/user_memory_gate_counters.ts +291 -0
  402. package/src/scripts/ai_council/blind_review.ts +0 -0
  403. package/src/scripts/ai_council/budget_guard.ts +90 -11
  404. package/src/scripts/ai_council/bundler.ts +2 -2
  405. package/src/scripts/ai_council/clients.ts +59 -3
  406. package/src/scripts/ai_council/config.ts +53 -7
  407. package/src/scripts/ai_council/modes.ts +68 -2
  408. package/src/scripts/ai_council/orchestrator.ts +54 -9
  409. package/src/scripts/ai_council/transport_resolver.ts +331 -0
  410. package/src/scripts/ai_team/team_dispatch.ts +17 -6
  411. package/src/scripts/anchor_eval_falsify.ts +198 -0
  412. package/src/scripts/anchor_scoring_run.ts +239 -0
  413. package/src/scripts/annotate_discovery.ts +1 -65
  414. package/src/scripts/bench_quality_run.ts +168 -4
  415. package/src/scripts/cache_realization_report.ts +782 -0
  416. package/src/scripts/check_artefact_count_messaging.ts +5 -1
  417. package/src/scripts/check_augment_description_cap.ts +15 -4
  418. package/src/scripts/check_bundle_path_leakage.ts +10 -4
  419. package/src/scripts/check_ci_local_parity.ts +317 -0
  420. package/src/scripts/check_condensation.ts +96 -191
  421. package/src/scripts/check_context_paths.ts +38 -9
  422. package/src/scripts/check_dependency_floors.ts +153 -0
  423. package/src/scripts/check_gate_coverage.ts +299 -0
  424. package/src/scripts/check_iron_law_prominence.ts +22 -1
  425. package/src/scripts/check_kernel_prefix_stability.ts +0 -0
  426. package/src/scripts/check_no_new_legacy_path.ts +16 -6
  427. package/src/scripts/check_no_roadmap_refs.ts +22 -9
  428. package/src/scripts/check_originality_freshness.ts +167 -0
  429. package/src/scripts/check_pack_size.ts +188 -0
  430. package/src/scripts/check_preamble_payload_budget.ts +130 -0
  431. package/src/scripts/check_proposal.ts +0 -0
  432. package/src/scripts/check_references.ts +0 -1
  433. package/src/scripts/check_safety_floor_untouched.ts +171 -24
  434. package/src/scripts/check_site_links.ts +62 -3
  435. package/src/scripts/ci_status.ts +0 -0
  436. package/src/scripts/cluster_near_miss_patterns.ts +0 -0
  437. package/src/scripts/code_graph/build.ts +0 -0
  438. package/src/scripts/command_suggester/types.ts +0 -0
  439. package/src/scripts/compile_router.ts +10 -14
  440. package/src/scripts/condense.sh +3 -4
  441. package/src/scripts/condense.ts +247 -228
  442. package/src/scripts/cost/track.mjs +168 -33
  443. package/src/scripts/cost_summary.ts +33 -1
  444. package/src/scripts/council_cli.ts +51 -5
  445. package/src/scripts/discovery_graph.ts +0 -0
  446. package/src/scripts/encoding_corpus.ts +500 -0
  447. package/src/scripts/encoding_corpus_report.ts +216 -0
  448. package/src/scripts/evaluator_umbrella.sh +34 -1
  449. package/src/scripts/generate_index.ts +19 -2
  450. package/src/scripts/install-hooks.sh +2 -2
  451. package/src/scripts/learning_sidecar.ts +0 -0
  452. package/src/scripts/lint_confusables.ts +10 -72
  453. package/src/scripts/lint_eval_fixture_citations.ts +113 -0
  454. package/src/scripts/lint_featured_skills.ts +0 -0
  455. package/src/scripts/lint_hidden_unicode.ts +208 -0
  456. package/src/scripts/lint_load_context.ts +17 -5
  457. package/src/scripts/lint_new_skill_gate.ts +9 -3
  458. package/src/scripts/lint_no_python_twin_rationale.ts +17 -2
  459. package/src/scripts/lint_originality.ts +1 -1
  460. package/src/scripts/lint_skill_originality.ts +1 -1
  461. package/src/scripts/lint_ticket_buildable.ts +1 -1
  462. package/src/scripts/lint_ui_stack_bundles.ts +170 -0
  463. package/src/scripts/mcp_server/tools.ts +4 -4
  464. package/src/scripts/measure_scope_dedup.ts +224 -0
  465. package/src/scripts/memory_lookup.ts +0 -0
  466. package/src/scripts/mine_session.ts +98 -0
  467. package/src/scripts/orchestration_payload_hash_drift.ts +145 -0
  468. package/src/scripts/preamble_byte_census.ts +574 -0
  469. package/src/scripts/probe_skill_registration.ts +2 -2
  470. package/src/scripts/redact_hook_capture.ts +13 -0
  471. package/src/scripts/release.ts +65 -10
  472. package/src/scripts/router_telemetry.ts +1 -1
  473. package/src/scripts/second_brain_retrieval.ts +14 -4
  474. package/src/scripts/skill_linter.ts +5 -0
  475. package/src/scripts/surface-tiers.yml +2 -0
  476. package/src/scripts/validate_pack_yaml.ts +0 -0
  477. package/src/server/schemas/settings.ts +8 -0
  478. package/src/shared/userMd/utils.ts +31 -0
  479. package/dist/agent-src/rules/telegraph-speak.md +0 -87
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Payload-hash × cache-hit drift aggregator (pure, no-I/O).
3
+ *
4
+ * `road-to-cache-economy.md` Phase 3, step 6: the
5
+ * `orchestration` object's `payload_hash` and `cache_hit` fields are both
6
+ * `null`-by-default and read by nothing (per the roadmap's own defect list).
7
+ * This module is the reader: it joins the two fields recorded on the SAME
8
+ * audit-log-v1 line — `payload_hash` names which spawn-payload shape a
9
+ * dispatch used, `cache_hit` is the provider-reported prompt-cache hit for
10
+ * that dispatch — so prefix-stability drift becomes visible.
11
+ *
12
+ * Cohort split (the roadmap's own verify criterion — "a cohort dispatched
13
+ * with a deliberately unstable payload shows a lower read share than a
14
+ * stable one"):
15
+ *
16
+ * - STABLE cohort: every occurrence of a `payload_hash` AFTER its first —
17
+ * a hash that repeats means the same payload shape was dispatched again,
18
+ * so a cache hit on the repeat is the signal a stable prefix predicts.
19
+ * - UNSTABLE cohort: every `payload_hash` that occurs exactly once in the
20
+ * window — a payload that never repeats can never show a repeat-hit, so
21
+ * its (necessarily first-call) `cache_hit` value is the unstable-payload
22
+ * baseline.
23
+ *
24
+ * A hash's FIRST occurrence is excluded from the stable cohort — nothing
25
+ * exists yet for a first call to hit, so counting it would understate the
26
+ * stable cohort's hit rate for a reason that has nothing to do with prefix
27
+ * stability.
28
+ *
29
+ * Zero recorded lines is a VALID state (both fields are lean-init
30
+ * extensions with no caller wiring a real value yet) — the aggregator
31
+ * returns a report with empty cohorts rather than failing, and the CLI
32
+ * wrapper states that plainly rather than presenting empty input as a green
33
+ * result.
34
+ */
35
+
36
+ export interface PayloadHashLine {
37
+ payload_hash: string | null;
38
+ cache_hit: boolean | null;
39
+ }
40
+
41
+ export interface HashGroupStat {
42
+ payload_hash: string;
43
+ occurrences: number;
44
+ hit_count: number;
45
+ hit_rate: number;
46
+ }
47
+
48
+ export interface CohortStat {
49
+ n: number;
50
+ hit_count: number;
51
+ hit_rate: number | null;
52
+ }
53
+
54
+ export interface PayloadHashDriftReport {
55
+ total_lines: number;
56
+ /** Lines carrying both a non-null `payload_hash` and a boolean `cache_hit`. */
57
+ lines_with_data: number;
58
+ /** Per-hash breakdown, most-occurrences first. */
59
+ groups: HashGroupStat[];
60
+ stable_cohort: CohortStat;
61
+ unstable_cohort: CohortStat;
62
+ /** True only when BOTH cohorts have data AND the stable cohort's hit rate is strictly higher. */
63
+ drift_visible: boolean;
64
+ }
65
+
66
+ function emptyCohort(): CohortStat {
67
+ return { n: 0, hit_count: 0, hit_rate: null };
68
+ }
69
+
70
+ /**
71
+ * Aggregates already-parsed audit-log-v1 orchestration lines. `lines` order
72
+ * matters — it is read as chronological (the CLI wrapper reads
73
+ * `agents/runtime/state/audit/*.jsonl` in filename-sorted order, matching
74
+ * `readAuditLines`), since "first occurrence of a hash" is the only signal
75
+ * that decides which cohort an occurrence falls into.
76
+ */
77
+ export function aggregatePayloadHashDrift(lines: readonly PayloadHashLine[]): PayloadHashDriftReport {
78
+ const withData = lines.filter((l) => l.payload_hash !== null && l.cache_hit !== null);
79
+
80
+ const byHash = new Map<string, boolean[]>();
81
+ for (const l of withData) {
82
+ const hash = l.payload_hash as string;
83
+ const arr = byHash.get(hash) ?? [];
84
+ arr.push(l.cache_hit as boolean);
85
+ byHash.set(hash, arr);
86
+ }
87
+
88
+ const groups: HashGroupStat[] = [];
89
+ const stable = emptyCohort();
90
+ const unstable = emptyCohort();
91
+
92
+ for (const [hash, hits] of byHash) {
93
+ const hitCount = hits.filter(Boolean).length;
94
+ groups.push({
95
+ payload_hash: hash,
96
+ occurrences: hits.length,
97
+ hit_count: hitCount,
98
+ hit_rate: hitCount / hits.length,
99
+ });
100
+
101
+ if (hits.length === 1) {
102
+ unstable.n += 1;
103
+ if (hits[0] === true) unstable.hit_count += 1;
104
+ } else {
105
+ // Every occurrence AFTER the first (repeat dispatches of the same payload shape).
106
+ const repeats = hits.slice(1);
107
+ stable.n += repeats.length;
108
+ stable.hit_count += repeats.filter(Boolean).length;
109
+ }
110
+ }
111
+
112
+ groups.sort((a, b) => b.occurrences - a.occurrences || a.payload_hash.localeCompare(b.payload_hash));
113
+ stable.hit_rate = stable.n > 0 ? stable.hit_count / stable.n : null;
114
+ unstable.hit_rate = unstable.n > 0 ? unstable.hit_count / unstable.n : null;
115
+
116
+ const driftVisible = stable.hit_rate !== null && unstable.hit_rate !== null && stable.hit_rate > unstable.hit_rate;
117
+
118
+ return {
119
+ total_lines: lines.length,
120
+ lines_with_data: withData.length,
121
+ groups,
122
+ stable_cohort: stable,
123
+ unstable_cohort: unstable,
124
+ drift_visible: driftVisible,
125
+ };
126
+ }
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Preservation-conformance verifier for safety-floor rule edits.
3
+ *
4
+ * `check_safety_floor_untouched` blocks every edit to the four safety-floor
5
+ * rules. That is right for substantive edits and wrong for a P4 migration, which
6
+ * moves lookup material into a `load_context:` target without losing anything.
7
+ * This module decides which one a diff is — by CHECKING, never by trusting a
8
+ * label, a commit message, or a contributor's word. A migration that cannot be
9
+ * proven conformant is treated as substantive and blocked (fail-closed).
10
+ *
11
+ * The contract it enforces is `preservation-guard`'s: every paragraph, list
12
+ * item, and fenced block from the source survives — either still in the rule
13
+ * (telegraph condensation is allowed, so matching is fuzzy) or verbatim in one
14
+ * of the rule's declared `load_context:` targets (a migration is a move, so
15
+ * matching there is near-exact). Iron Law sections are stricter still: their
16
+ * headings must survive at the same level and their fenced blocks byte-for-byte.
17
+ *
18
+ * Pure functions over strings — no git, no fs — so the whole decision is unit
19
+ * testable without manufacturing commits. That absence is why the guard it
20
+ * serves shipped inert for months.
21
+ */
22
+
23
+ /** A structural unit of a markdown body: heading, paragraph, list item, or fence. */
24
+ export interface Unit {
25
+ kind: 'heading' | 'paragraph' | 'list-item' | 'fence';
26
+ /** Heading depth (1-6) for `heading`, else 0. */
27
+ level: number;
28
+ /** Raw text as it appeared, minus the trailing newline. */
29
+ raw: string;
30
+ /** Normalised form used for comparison. */
31
+ norm: string;
32
+ }
33
+
34
+ /** Strip frontmatter; return the body. */
35
+ export function strip_frontmatter(text: string): string {
36
+ const m = /^---\n[\s\S]*?\n---\n/.exec(text);
37
+ return m === null ? text : text.slice(m[0].length);
38
+ }
39
+
40
+ /** `load_context:` targets declared in a rule's frontmatter, in order. */
41
+ export function load_context_targets(text: string): string[] {
42
+ const fm = /^---\n([\s\S]*?)\n---\n/.exec(text);
43
+ if (fm === null) return [];
44
+ const out: string[] = [];
45
+ let inBlock = false;
46
+ for (const line of fm[1]!.split('\n')) {
47
+ if (/^load_context:\s*$/.test(line)) {
48
+ inBlock = true;
49
+ continue;
50
+ }
51
+ if (inBlock) {
52
+ const item = /^\s*-\s+(.+?)\s*$/.exec(line);
53
+ if (item !== null) {
54
+ out.push(item[1]!.replace(/^["']|["']$/g, ''));
55
+ continue;
56
+ }
57
+ if (/^\S/.test(line)) inBlock = false;
58
+ }
59
+ }
60
+ return out;
61
+ }
62
+
63
+ /**
64
+ * Normalise a unit for comparison.
65
+ *
66
+ * Deliberately blind to the three things a legitimate migration changes and
67
+ * nothing else: heading depth (an H2 becomes an H3 under a host section), link
68
+ * targets (relative paths are rewritten for the new location), and whitespace.
69
+ * Everything that carries obligation — words, emphasis, negations — is compared
70
+ * as written.
71
+ */
72
+ export function normalise(raw: string): string {
73
+ return raw
74
+ .replace(/^#{1,6}\s+/gm, '') // heading depth
75
+ .replace(/\]\([^)]*\)/g, ']()') // link targets
76
+ .replace(/^\s*[-*+]\s+/gm, '') // list markers
77
+ .replace(/\s+/g, ' ')
78
+ .trim();
79
+ }
80
+
81
+ /** Split a markdown body into structural units. Fenced blocks stay intact. */
82
+ export function parse_units(body: string): Unit[] {
83
+ const lines = body.split('\n');
84
+ const units: Unit[] = [];
85
+ let para: string[] = [];
86
+
87
+ const flush = (): void => {
88
+ if (para.length === 0) return;
89
+ const raw = para.join('\n');
90
+ if (raw.trim() !== '') units.push({ kind: 'paragraph', level: 0, raw, norm: normalise(raw) });
91
+ para = [];
92
+ };
93
+
94
+ for (let i = 0; i < lines.length; i += 1) {
95
+ const line = lines[i]!;
96
+ const fence = /^(\s*)(`{3,}|~{3,})/.exec(line);
97
+ if (fence !== null) {
98
+ flush();
99
+ const marker = fence[2]!;
100
+ const block = [line];
101
+ i += 1;
102
+ while (i < lines.length) {
103
+ block.push(lines[i]!);
104
+ if (lines[i]!.trimStart().startsWith(marker)) break;
105
+ i += 1;
106
+ }
107
+ const raw = block.join('\n');
108
+ units.push({ kind: 'fence', level: 0, raw, norm: raw.replace(/\s+$/gm, '') });
109
+ continue;
110
+ }
111
+ const heading = /^(#{1,6})\s+(.*)$/.exec(line);
112
+ if (heading !== null) {
113
+ flush();
114
+ units.push({
115
+ kind: 'heading',
116
+ level: heading[1]!.length,
117
+ raw: line,
118
+ norm: normalise(line),
119
+ });
120
+ continue;
121
+ }
122
+ const item = /^\s*[-*+]\s+/.test(line) || /^\s*\d+\.\s+/.test(line);
123
+ if (item) {
124
+ flush();
125
+ units.push({ kind: 'list-item', level: 0, raw: line, norm: normalise(line) });
126
+ continue;
127
+ }
128
+ if (line.trim() === '') {
129
+ flush();
130
+ continue;
131
+ }
132
+ para.push(line);
133
+ }
134
+ flush();
135
+ return units;
136
+ }
137
+
138
+ /** Dice coefficient over character bigrams — cheap, order-sensitive enough. */
139
+ export function similarity(a: string, b: string): number {
140
+ if (a === b) return 1;
141
+ if (a.length < 2 || b.length < 2) return a === b ? 1 : 0;
142
+ const grams = (s: string): Map<string, number> => {
143
+ const m = new Map<string, number>();
144
+ for (let i = 0; i < s.length - 1; i += 1) {
145
+ const g = s.slice(i, i + 2);
146
+ m.set(g, (m.get(g) ?? 0) + 1);
147
+ }
148
+ return m;
149
+ };
150
+ const ga = grams(a);
151
+ const gb = grams(b);
152
+ let overlap = 0;
153
+ for (const [g, n] of ga) overlap += Math.min(n, gb.get(g) ?? 0);
154
+ return (2 * overlap) / (a.length - 1 + b.length - 1);
155
+ }
156
+
157
+ /** A unit still present in the rule after telegraph condensation. */
158
+ const KEPT_IN_RULE = 0.6;
159
+ /** A unit moved into a context file — a move, so near-verbatim. */
160
+ const MOVED_TO_CONTEXT = 0.9;
161
+
162
+ export interface Finding {
163
+ code:
164
+ | 'iron-law-heading-lost'
165
+ | 'iron-law-fence-changed'
166
+ | 'passage-lost'
167
+ | 'unexplained-addition';
168
+ detail: string;
169
+ }
170
+
171
+ /** Units belonging to an Iron Law section (heading matches, until the next same-or-shallower heading). */
172
+ export function iron_law_units(units: readonly Unit[]): Unit[] {
173
+ const out: Unit[] = [];
174
+ let depth: number | null = null;
175
+ for (const u of units) {
176
+ if (u.kind === 'heading') {
177
+ if (/^(the\s+)?iron\s+law/i.test(u.norm)) {
178
+ depth = u.level;
179
+ out.push(u);
180
+ continue;
181
+ }
182
+ if (depth !== null && u.level <= depth) depth = null;
183
+ }
184
+ if (depth !== null) out.push(u);
185
+ }
186
+ return out;
187
+ }
188
+
189
+ export interface VerifyInput {
190
+ /** Rule file content before the change. */
191
+ base_rule: string;
192
+ /** Rule file content after the change. */
193
+ head_rule: string;
194
+ /** Declared `load_context` target path → content AFTER the change. */
195
+ head_contexts: ReadonlyMap<string, string>;
196
+ /** Same targets, content BEFORE — so only ADDED context text counts as a landing site. */
197
+ base_contexts: ReadonlyMap<string, string>;
198
+ }
199
+
200
+ /**
201
+ * Decide whether a safety-floor rule edit is a preservation-conforming
202
+ * migration. Returns [] when it is; otherwise every reason it is not.
203
+ */
204
+ export function verify_migration(input: VerifyInput): Finding[] {
205
+ const findings: Finding[] = [];
206
+ const baseUnits = parse_units(strip_frontmatter(input.base_rule));
207
+ const headUnits = parse_units(strip_frontmatter(input.head_rule));
208
+
209
+ // ── Iron Law: headings survive at depth, fences survive byte-for-byte ──
210
+ const baseIron = iron_law_units(baseUnits);
211
+ const headIron = iron_law_units(headUnits);
212
+ for (const u of baseIron) {
213
+ if (u.kind === 'heading') {
214
+ const hit = headIron.some((h) => h.kind === 'heading' && h.norm === u.norm && h.level === u.level);
215
+ if (!hit) {
216
+ findings.push({
217
+ code: 'iron-law-heading-lost',
218
+ detail: `${u.raw.trim()} — must survive verbatim at the same level`,
219
+ });
220
+ }
221
+ } else if (u.kind === 'fence') {
222
+ const hit = headIron.some((h) => h.kind === 'fence' && h.raw === u.raw);
223
+ if (!hit) {
224
+ findings.push({
225
+ code: 'iron-law-fence-changed',
226
+ detail: `fenced block under ${u.raw.split('\n')[0] ?? ''} changed — Iron Law fences are byte-exact`,
227
+ });
228
+ }
229
+ }
230
+ }
231
+
232
+ // ── Landing sites: only text ADDED to a DECLARED context counts ──
233
+ //
234
+ // The declared set is re-derived here from the rule's own frontmatter rather
235
+ // than trusted from the caller. A migration is only legitimate into a file
236
+ // the rule actually points readers at; dropping a passage into some other
237
+ // file leaves it unreachable from the rule and is a loss, not a move.
238
+ const declared = load_context_targets(input.head_rule);
239
+ const isDeclared = (p: string): boolean =>
240
+ declared.some((rel) => p === rel || p.endsWith(`/${rel}`));
241
+ const landing: string[] = [];
242
+ for (const [path, head] of input.head_contexts) {
243
+ if (!isDeclared(path)) continue;
244
+ const before = new Set(parse_units(strip_frontmatter(input.base_contexts.get(path) ?? '')).map((u) => u.norm));
245
+ for (const u of parse_units(strip_frontmatter(head))) {
246
+ if (!before.has(u.norm)) landing.push(u.norm);
247
+ }
248
+ }
249
+
250
+ // ── Every base unit survives: in the rule (fuzzy) or in a context (near-exact) ──
251
+ const headNorms = headUnits.map((u) => u.norm);
252
+ const usedHead = new Set<number>();
253
+ for (const u of baseUnits) {
254
+ let bestIdx = -1;
255
+ let best = 0;
256
+ for (let i = 0; i < headNorms.length; i += 1) {
257
+ if (usedHead.has(i)) continue;
258
+ const s = similarity(u.norm, headNorms[i]!);
259
+ if (s > best) {
260
+ best = s;
261
+ bestIdx = i;
262
+ }
263
+ }
264
+ if (best >= KEPT_IN_RULE) {
265
+ usedHead.add(bestIdx);
266
+ continue;
267
+ }
268
+ const moved = landing.some((l) => similarity(u.norm, l) >= MOVED_TO_CONTEXT);
269
+ if (!moved) {
270
+ findings.push({
271
+ code: 'passage-lost',
272
+ detail: `${u.kind}: ${u.raw.trim().slice(0, 90)}… — not kept in the rule and not found in any declared load_context target`,
273
+ });
274
+ }
275
+ }
276
+
277
+ // ── Nothing genuinely new in the rule: a migration only removes ──
278
+ for (let i = 0; i < headUnits.length; i += 1) {
279
+ if (usedHead.has(i)) continue;
280
+ const u = headUnits[i]!;
281
+ const back = baseUnits.some((b) => similarity(b.norm, u.norm) >= KEPT_IN_RULE);
282
+ if (!back) {
283
+ findings.push({
284
+ code: 'unexplained-addition',
285
+ detail: `${u.kind}: ${u.raw.trim().slice(0, 90)}… — new content in a safety-floor rule is a substantive edit, not a migration`,
286
+ });
287
+ }
288
+ }
289
+
290
+ return findings;
291
+ }
@@ -3,8 +3,8 @@
3
3
  * (road-to-retrieval-substrate-hardening B6).
4
4
  *
5
5
  * Corpus content — especially user-ingested knowledge chunks under
6
- * `agents/memory/knowledge/` — flows into the agent context via `retrieve_v1`
7
- * / `memory_get_v1`. An attacker (or a compromised ingested source) can embed
6
+ * `agents/memory/knowledge/` — flows into the agent context on the retrieval
7
+ * read surfaces. An attacker (or a compromised ingested source) can embed
8
8
  * hidden-instruction vectors (bidi controls, zero-width chars, Unicode Tag
9
9
  * block) or control-char noise that the model may act on — the untrusted-input
10
10
  * / lethal-trifecta injection surface. This floor strips those vectors from
@@ -15,12 +15,49 @@
15
15
  * layer + unbounded length; visible content is the agent's to read as data.
16
16
  * Codepoint classes are shared with `lint_hidden_unicode` (one source of truth
17
17
  * for what counts as a hidden-instruction vector).
18
+ *
19
+ * WHERE IT ACTUALLY RUNS — measured end-to-end, not asserted. Keep this list
20
+ * honest: an earlier version of this header named surfaces by intent, and the
21
+ * legacy-envelope gap below went unnoticed for exactly that reason. Every
22
+ * claim here is backed by a probe row in
23
+ * `agents/evidence/reports/sanitize-floor-wiring.md`:
24
+ *
25
+ * - `retrieve_v1()` — yes (`memory_lookup.ts` calls `sanitize_entry`)
26
+ * - `memory_get_v1()` — yes (same)
27
+ * - MCP `memory_lookup` / `memory_get` tools — inherited from the two above
28
+ * - `retrieve()` / `retrieve_with_meta()` — yes, since the S0.0 wiring fix;
29
+ * before it they emitted every vector intact, and so did the CLI default
30
+ * (`--envelope legacy`), which is the path the rules document
31
+ * - inter-agent channels (`ai_team` / `ai_council` model replies) — the
32
+ * inbound parse choke point only; the subagent boundary itself is a HOST
33
+ * primitive this package cannot reach (see the report, § S0.0b)
34
+ *
35
+ * Anything not on that list is uncovered. Do not widen the list without a
36
+ * probe row to back it.
18
37
  */
19
38
  import { _classify } from '../lint_hidden_unicode.js';
39
+ import { TOKEN_RE, classifyToken } from './confusables.js';
20
40
 
21
41
  /** Hard per-field length cap — bounds a runaway/adversarial body. */
22
42
  export const MAX_FIELD_CHARS = 8192;
23
43
 
44
+ /**
45
+ * Invisible fillers — render as blank but are not whitespace, so they sit in
46
+ * neither the zero-width nor the bidi set and survived the original floor
47
+ * (measured: `agents/evidence/reports/encoding-channel-coverage.md` row 18).
48
+ *
49
+ * These are the ONLY channel Phase 1 chose to strip rather than flag: invisible
50
+ * by nature, with no legitimate role in this corpus, so folding them into the
51
+ * existing invisible set carries no corruption risk. Every other uncovered
52
+ * channel is a flag, because rewriting visible text can corrupt legitimate
53
+ * content.
54
+ */
55
+ const _INVISIBLE_FILLERS: ReadonlySet<number> = new Set([
56
+ 0x3164, // HANGUL FILLER
57
+ 0x115f, // HANGUL CHOSEONG FILLER
58
+ 0x1160, // HANGUL JUNGSEONG FILLER
59
+ ]);
60
+
24
61
  /** True for a C0/C1 control char that is NOT a benign whitespace (\t, \n). */
25
62
  function _isStrippableControl(cp: number): boolean {
26
63
  if (cp === 0x09 || cp === 0x0a) return false; // keep tab + newline
@@ -42,11 +79,138 @@ export function sanitize_text(s: string): string {
42
79
  if (cp === undefined) continue;
43
80
  if (_classify(cp) !== null) continue; // hidden-instruction vector → drop
44
81
  if (_isStrippableControl(cp)) continue; // control-char noise → drop
82
+ if (_INVISIBLE_FILLERS.has(cp)) continue; // blank-but-not-whitespace → drop
45
83
  out += ch;
46
84
  }
47
85
  return out.length > MAX_FIELD_CHARS ? out.slice(0, MAX_FIELD_CHARS) : out;
48
86
  }
49
87
 
88
+ // ---------------------------------------------------------------------------
89
+ // Visible-layer scanner — FLAG ONLY, never rewrites
90
+ // ---------------------------------------------------------------------------
91
+ //
92
+ // `sanitize_text` strips the invisible layer. This reports the VISIBLE layer,
93
+ // which the floor deliberately does not touch: folding a confusable to a Latin
94
+ // skeleton, or NFKC-normalising a math-alphanumeric run, corrupts any body that
95
+ // legitimately contains mixed script, CJK punctuation, or a ligature. Phase 1
96
+ // measured each channel and chose flag-not-rewrite for every one of these:
97
+ // `agents/evidence/reports/encoding-channel-coverage.md` § Disposition.
98
+ //
99
+ // Deterministic and pure: no model call, no network, no I/O. Safe to run in CI
100
+ // and on a request path.
101
+ //
102
+ // Not scanned, deliberately, with the reason recorded so it is not mistaken for
103
+ // an oversight:
104
+ // - confusable whitespace (NBSP, figure space) — pervasive in real prose
105
+ // - HTML/XML entities — decoding them would CREATE the payload
106
+ // - nested multibase (base64) — legitimate throughout this repo; semantic,
107
+ // not structural
108
+ // - structured-data key ordering — not a codepoint channel at all, and
109
+ // reordering keys would break the byte-identical v1 envelope contract
110
+ // - word-order permutation — carrier text with legitimate word order is
111
+ // indistinguishable from permuted text without semantics
112
+
113
+ /** Codepoint thresholds — a run is the signal; a single occurrence is not. */
114
+ const _VS_RUN_MIN = 3;
115
+ const _COMBINING_RUN_MIN = 5;
116
+
117
+ export interface EncodingFinding {
118
+ /** Stable channel id, matching the frozen corpus labels. */
119
+ readonly channel: string;
120
+ /** Why it fired, with the concrete evidence (codepoint or token). */
121
+ readonly detail: string;
122
+ }
123
+
124
+ function _isVariationSelector(cp: number): boolean {
125
+ return (cp >= 0xfe00 && cp <= 0xfe0f) || (cp >= 0xe0100 && cp <= 0xe01ef);
126
+ }
127
+
128
+ function _isCombiningMark(cp: number): boolean {
129
+ return cp >= 0x0300 && cp <= 0x036f;
130
+ }
131
+
132
+ /**
133
+ * Report visible-layer encoding signals in a string. Never mutates it.
134
+ *
135
+ * The confusable signature is NOT reimplemented here — it is the shared
136
+ * `classifyToken` from `_lib/confusables.ts`, the single definition this
137
+ * package's authoring-time linter also uses, so the two surfaces cannot drift
138
+ * apart on what counts as a homoglyph.
139
+ */
140
+ export function scan_encoding_findings(s: string): EncodingFinding[] {
141
+ const out: EncodingFinding[] = [];
142
+
143
+ // Longest run of variation selectors / combining marks anywhere in the
144
+ // string. A run is what distinguishes steganography from legitimate use:
145
+ // U+FE0F is the emoji presentation selector and diacritics are normal in
146
+ // many languages, so a single occurrence is never the signal.
147
+ let vsRun = 0;
148
+ let vsMax = 0;
149
+ let cmRun = 0;
150
+ let cmMax = 0;
151
+ let hasMathAlnum = false;
152
+ let hasFullwidth = false;
153
+ for (const ch of s) {
154
+ const cp = ch.codePointAt(0);
155
+ if (cp === undefined) continue;
156
+ if (_isVariationSelector(cp)) {
157
+ vsRun += 1;
158
+ vsMax = Math.max(vsMax, vsRun);
159
+ } else {
160
+ vsRun = 0;
161
+ }
162
+ if (_isCombiningMark(cp)) {
163
+ cmRun += 1;
164
+ cmMax = Math.max(cmMax, cmRun);
165
+ } else {
166
+ cmRun = 0;
167
+ }
168
+ if (cp >= 0x1d400 && cp <= 0x1d7ff) hasMathAlnum = true;
169
+ if (cp >= 0xff01 && cp <= 0xff5e) hasFullwidth = true;
170
+ }
171
+ if (vsMax >= _VS_RUN_MIN) {
172
+ out.push({
173
+ channel: 'variation-selector-run',
174
+ detail: `variation-selector run x${vsMax} (steganography signature)`,
175
+ });
176
+ }
177
+ if (cmMax >= _COMBINING_RUN_MIN) {
178
+ out.push({
179
+ channel: 'combining-mark-run',
180
+ detail: `combining-mark run x${cmMax} on one base character`,
181
+ });
182
+ }
183
+ if (hasMathAlnum) {
184
+ out.push({
185
+ channel: 'math-alphanumeric',
186
+ detail: 'Mathematical Alphanumeric Symbols used as letters (U+1D400–1D7FF)',
187
+ });
188
+ }
189
+ if (hasFullwidth) {
190
+ out.push({
191
+ channel: 'fullwidth-forms',
192
+ detail: 'Halfwidth/Fullwidth Forms used as ASCII letters (U+FF01–FF5E)',
193
+ });
194
+ }
195
+
196
+ // Mixed-script confusable tokens — shared signature, one table in the tree.
197
+ for (const m of s.matchAll(TOKEN_RE)) {
198
+ const verdict = classifyToken(m[0]);
199
+ if (verdict !== null) {
200
+ const script = verdict.startsWith('latin+greek') ? 'greek' : 'cyrillic';
201
+ out.push({ channel: `confusable-${script}`, detail: `${m[0]} — ${verdict}` });
202
+ }
203
+ }
204
+
205
+ // Punycode / IDN in a text-expected field. Flagged, never rewritten:
206
+ // `xn--` labels are valid DNS and rewriting one would break a real link.
207
+ for (const m of s.matchAll(/\bxn--[a-z0-9-]+/gi)) {
208
+ out.push({ channel: 'punycode-idn', detail: `punycode label ${m[0]}` });
209
+ }
210
+
211
+ return out;
212
+ }
213
+
50
214
  /**
51
215
  * Return a shallow copy of a retrieval entry with every string value (and
52
216
  * one level of string-array values) sanitized. Non-string values pass through