@event4u/agent-config 14.23.0 → 16.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 (541) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +144 -152
  5. package/README.md +1 -1
  6. package/dist/agent-src/commands/agent-handoff.md +8 -7
  7. package/dist/agent-src/commands/agents/init.md +1 -1
  8. package/dist/agent-src/commands/agents/user/accept.md +4 -4
  9. package/dist/agent-src/commands/agents/user/delete.md +2 -2
  10. package/dist/agent-src/commands/agents/user/init.md +3 -3
  11. package/dist/agent-src/commands/agents/user/review.md +3 -3
  12. package/dist/agent-src/commands/agents/user/show.md +3 -3
  13. package/dist/agent-src/commands/agents/user/update.md +2 -2
  14. package/dist/agent-src/commands/agents/user.md +6 -6
  15. package/dist/agent-src/commands/analytics/prune.md +1 -1
  16. package/dist/agent-src/commands/analytics/show.md +2 -2
  17. package/dist/agent-src/commands/analyze/decision.md +2 -2
  18. package/dist/agent-src/commands/analyze/inbox.md +5 -5
  19. package/dist/agent-src/commands/analyze/incident.md +3 -3
  20. package/dist/agent-src/commands/analyze/near-miss.md +3 -3
  21. package/dist/agent-src/commands/analyze/postmortem.md +4 -4
  22. package/dist/agent-src/commands/analyze/premortem.md +2 -2
  23. package/dist/agent-src/commands/analyze.md +2 -2
  24. package/dist/agent-src/commands/bug/fix.md +1 -1
  25. package/dist/agent-src/commands/bug/investigate.md +2 -2
  26. package/dist/agent-src/commands/cost/profile.md +3 -3
  27. package/dist/agent-src/commands/design.md +1 -1
  28. package/dist/agent-src/commands/feature/explore.md +1 -1
  29. package/dist/agent-src/commands/feature/plan.md +2 -2
  30. package/dist/agent-src/commands/feature/roadmap.md +2 -2
  31. package/dist/agent-src/commands/ghostwriter/fetch.md +4 -4
  32. package/dist/agent-src/commands/ghostwriter/list.md +1 -1
  33. package/dist/agent-src/commands/ghostwriter/show.md +1 -1
  34. package/dist/agent-src/commands/ghostwriter/write.md +9 -9
  35. package/dist/agent-src/commands/humanize.md +6 -6
  36. package/dist/agent-src/commands/jira-ticket.md +1 -1
  37. package/dist/agent-src/commands/judge/solo.md +1 -1
  38. package/dist/agent-src/commands/judge.md +1 -1
  39. package/dist/agent-src/commands/knowledge/cross-repo.md +1 -1
  40. package/dist/agent-src/commands/knowledge/forget.md +1 -1
  41. package/dist/agent-src/commands/knowledge/ingest.md +2 -2
  42. package/dist/agent-src/commands/knowledge/list.md +1 -1
  43. package/dist/agent-src/commands/memory/add.md +3 -3
  44. package/dist/agent-src/commands/memory/load.md +4 -4
  45. package/dist/agent-src/commands/memory/mine-session.md +1 -1
  46. package/dist/agent-src/commands/memory/promote.md +4 -4
  47. package/dist/agent-src/commands/memory/propose.md +2 -2
  48. package/dist/agent-src/commands/mode.md +5 -5
  49. package/dist/agent-src/commands/post-as/ghostwriter.md +3 -3
  50. package/dist/agent-src/commands/post-as/me.md +7 -7
  51. package/dist/agent-src/commands/pr/create.md +1 -1
  52. package/dist/agent-src/commands/pr/merge.md +1 -1
  53. package/dist/agent-src/commands/profile/activate.md +1 -1
  54. package/dist/agent-src/commands/profile/show.md +1 -1
  55. package/dist/agent-src/commands/research/deep.md +2 -2
  56. package/dist/agent-src/commands/research/report.md +2 -2
  57. package/dist/agent-src/commands/review/changes.md +1 -1
  58. package/dist/agent-src/commands/review/routing.md +1 -1
  59. package/dist/agent-src/commands/roadmap/create.md +4 -3
  60. package/dist/agent-src/commands/roadmap/materialize.md +2 -2
  61. package/dist/agent-src/commands/roadmap/next.md +1 -1
  62. package/dist/agent-src/commands/roadmap/process-full.md +2 -2
  63. package/dist/agent-src/commands/security-audit-config.md +3 -3
  64. package/dist/agent-src/commands/skill/preview.md +1 -1
  65. package/dist/agent-src/commands/skills/discover.md +1 -1
  66. package/dist/agent-src/commands/sync/agent-settings.md +2 -2
  67. package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
  68. package/dist/agent-src/commands/tests/create.md +1 -1
  69. package/dist/agent-src/commands/tests/e2e-heal.md +1 -1
  70. package/dist/agent-src/commands/tests/e2e-plan.md +1 -1
  71. package/dist/agent-src/contexts/authority/kernel-rule-edits.md +6 -6
  72. package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -2
  73. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +2 -2
  74. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +88 -1
  75. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +51 -1
  76. package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -1
  77. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +1 -1
  78. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
  79. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +1 -1
  80. package/dist/agent-src/contexts/execution/cheap-question-mechanics.md +1 -1
  81. package/dist/agent-src/contexts/execution/contract-decision-sheet.md +3 -3
  82. package/dist/agent-src/contexts/execution/mandated-lines.md +1 -1
  83. package/dist/agent-src/contexts/execution/non-interactive-contract.md +1 -1
  84. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -1
  85. package/dist/agent-src/contexts/execution/plan-confidence-gate.md +5 -5
  86. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +1 -1
  87. package/dist/agent-src/contexts/execution/subagent-modes-detail.md +1 -1
  88. package/dist/agent-src/contexts/execution/subagent-routing.md +2 -2
  89. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +1 -1
  90. package/dist/agent-src/contexts/execution/user-memory-channels.md +3 -3
  91. package/dist/agent-src/contexts/execution/verification-mechanics.md +1 -1
  92. package/dist/agent-src/contexts/judges/persona-voice-rubric.md +2 -2
  93. package/dist/agent-src/guidelines/abstraction-thresholds.md +88 -0
  94. package/dist/agent-src/guidelines/agent-infra/5w2h-analysis.md +260 -0
  95. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +99 -0
  96. package/dist/agent-src/guidelines/agent-infra/agent-interaction-and-decision-quality.md +325 -0
  97. package/dist/agent-src/guidelines/agent-infra/api-cost-levers.md +177 -0
  98. package/dist/agent-src/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +222 -0
  99. package/dist/agent-src/guidelines/agent-infra/ask-when-uncertain-demos.md +134 -0
  100. package/dist/agent-src/guidelines/agent-infra/asking-and-brevity-examples.md +198 -0
  101. package/dist/agent-src/guidelines/agent-infra/break-glass-usage.md +113 -0
  102. package/dist/agent-src/guidelines/agent-infra/carve-out-predicates.md +17 -0
  103. package/dist/agent-src/guidelines/agent-infra/comparison-matrix.md +179 -0
  104. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +165 -0
  105. package/dist/agent-src/guidelines/agent-infra/corpus-grounding-authoring.md +91 -0
  106. package/dist/agent-src/guidelines/agent-infra/critical-thinking.md +156 -0
  107. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +109 -0
  108. package/dist/agent-src/guidelines/agent-infra/developer-judgment.md +82 -0
  109. package/dist/agent-src/guidelines/agent-infra/direct-answers-demos.md +142 -0
  110. package/dist/agent-src/guidelines/agent-infra/domain-adoption-gates.md +112 -0
  111. package/dist/agent-src/guidelines/agent-infra/domain-eval-anti-pattern.md +53 -0
  112. package/dist/agent-src/guidelines/agent-infra/domain-pack-architecture.md +56 -0
  113. package/dist/agent-src/guidelines/agent-infra/downstream-changes-mechanics.md +91 -0
  114. package/dist/agent-src/guidelines/agent-infra/emphasis-budget.md +45 -0
  115. package/dist/agent-src/guidelines/agent-infra/engineering-memory-data-format.md +210 -0
  116. package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
  117. package/dist/agent-src/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  118. package/dist/agent-src/guidelines/agent-infra/failure-signatures.md +70 -0
  119. package/dist/agent-src/guidelines/agent-infra/false-green.md +233 -0
  120. package/dist/agent-src/guidelines/agent-infra/first-principles.md +192 -0
  121. package/dist/agent-src/guidelines/agent-infra/framework-neutrality-patterns.md +66 -0
  122. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +169 -0
  123. package/dist/agent-src/guidelines/agent-infra/gate-authoring.md +177 -0
  124. package/dist/agent-src/guidelines/agent-infra/guarded-baseline.md +39 -0
  125. package/dist/agent-src/guidelines/agent-infra/installed-tools-manifest.md +142 -0
  126. package/dist/agent-src/guidelines/agent-infra/inversion-thinking.md +388 -0
  127. package/dist/agent-src/guidelines/agent-infra/ios-simulator-guide.md +378 -0
  128. package/dist/agent-src/guidelines/agent-infra/language-and-tone-examples.md +141 -0
  129. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +317 -0
  130. package/dist/agent-src/guidelines/agent-infra/linked-projects-onboarding-gate.md +80 -0
  131. package/dist/agent-src/guidelines/agent-infra/mcp-request-signing.md +197 -0
  132. package/dist/agent-src/guidelines/agent-infra/memory-access.md +149 -0
  133. package/dist/agent-src/guidelines/agent-infra/mental-models.md +314 -0
  134. package/dist/agent-src/guidelines/agent-infra/minimal-safe-diff-mechanics.md +241 -0
  135. package/dist/agent-src/guidelines/agent-infra/missing-tool-handling.md +66 -0
  136. package/dist/agent-src/guidelines/agent-infra/model-recommendation.md +101 -0
  137. package/dist/agent-src/guidelines/agent-infra/naming.md +69 -0
  138. package/dist/agent-src/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
  139. package/dist/agent-src/guidelines/agent-infra/output-patterns.md +117 -0
  140. package/dist/agent-src/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
  141. package/dist/agent-src/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  142. package/dist/agent-src/guidelines/agent-infra/review-routing-data-format.md +143 -0
  143. package/dist/agent-src/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
  144. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +274 -0
  145. package/dist/agent-src/guidelines/agent-infra/role-contracts.md +209 -0
  146. package/dist/agent-src/guidelines/agent-infra/role-mode-router.md +89 -0
  147. package/dist/agent-src/guidelines/agent-infra/rule-body-migration-inventory.md +241 -0
  148. package/dist/agent-src/guidelines/agent-infra/rule-type-governance.md +73 -0
  149. package/dist/agent-src/guidelines/agent-infra/runtime-layer.md +89 -0
  150. package/dist/agent-src/guidelines/agent-infra/scqa-framework.md +526 -0
  151. package/dist/agent-src/guidelines/agent-infra/security-lint-containment.md +121 -0
  152. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +134 -0
  153. package/dist/agent-src/guidelines/agent-infra/simplicity-and-goal-demos.md +211 -0
  154. package/dist/agent-src/guidelines/agent-infra/six-hats.md +353 -0
  155. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +229 -0
  156. package/dist/agent-src/guidelines/agent-infra/skill-quality-checklist.md +157 -0
  157. package/dist/agent-src/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  158. package/dist/agent-src/guidelines/agent-infra/symptom-driven-harvest-loop.md +104 -0
  159. package/dist/agent-src/guidelines/agent-infra/systems-thinking.md +220 -0
  160. package/dist/agent-src/guidelines/agent-infra/tool-description-as-policy.md +35 -0
  161. package/dist/agent-src/guidelines/agent-infra/tool-integration.md +73 -0
  162. package/dist/agent-src/guidelines/agent-infra/traceability-field-mechanics.md +50 -0
  163. package/dist/agent-src/guidelines/agent-infra/untrusted-input-spotlighting.md +166 -0
  164. package/dist/agent-src/guidelines/agent-infra/verify-before-complete-demos.md +128 -0
  165. package/dist/agent-src/guidelines/augment-portability-patterns.md +70 -0
  166. package/dist/agent-src/guidelines/code-clarity.md +350 -0
  167. package/dist/agent-src/guidelines/component-oriented-and-oop-development.md +189 -0
  168. package/dist/agent-src/guidelines/cross-role-handoff.md +127 -0
  169. package/dist/agent-src/guidelines/design-antipatterns-triggers.json +18 -0
  170. package/dist/agent-src/guidelines/design-antipatterns.md +327 -0
  171. package/dist/agent-src/guidelines/design-asset-discipline.md +38 -0
  172. package/dist/agent-src/guidelines/design-canon.md +63 -0
  173. package/dist/agent-src/guidelines/design-fidelity-mechanics.md +293 -0
  174. package/dist/agent-src/guidelines/design-fidelity-routing.md +78 -0
  175. package/dist/agent-src/guidelines/design-handover-extraction.md +117 -0
  176. package/dist/agent-src/guidelines/design-modes.md +143 -0
  177. package/dist/agent-src/guidelines/design-reconciliation.md +172 -0
  178. package/dist/agent-src/guidelines/docs/readme-size-and-splitting.md +209 -0
  179. package/dist/agent-src/guidelines/e2e/playwright.md +363 -0
  180. package/dist/agent-src/guidelines/gtm-handoff.md +114 -0
  181. package/dist/agent-src/guidelines/monorepo-antipatterns.md +141 -0
  182. package/dist/agent-src/guidelines/php/api-design.md +115 -0
  183. package/dist/agent-src/guidelines/php/artisan-commands.md +81 -0
  184. package/dist/agent-src/guidelines/php/blade-ui.md +78 -0
  185. package/dist/agent-src/guidelines/php/controllers.md +90 -0
  186. package/dist/agent-src/guidelines/php/database.md +194 -0
  187. package/dist/agent-src/guidelines/php/eloquent.md +208 -0
  188. package/dist/agent-src/guidelines/php/flux.md +80 -0
  189. package/dist/agent-src/guidelines/php/general.md +207 -0
  190. package/dist/agent-src/guidelines/php/git.md +164 -0
  191. package/dist/agent-src/guidelines/php/jobs.md +111 -0
  192. package/dist/agent-src/guidelines/php/livewire.md +71 -0
  193. package/dist/agent-src/guidelines/php/logging.md +79 -0
  194. package/dist/agent-src/guidelines/php/naming.md +89 -0
  195. package/dist/agent-src/guidelines/php/patterns/dependency-injection.md +57 -0
  196. package/dist/agent-src/guidelines/php/patterns/dtos.md +199 -0
  197. package/dist/agent-src/guidelines/php/patterns/events.md +67 -0
  198. package/dist/agent-src/guidelines/php/patterns/factory.md +53 -0
  199. package/dist/agent-src/guidelines/php/patterns/pipelines.md +66 -0
  200. package/dist/agent-src/guidelines/php/patterns/policies.md +66 -0
  201. package/dist/agent-src/guidelines/php/patterns/repositories.md +122 -0
  202. package/dist/agent-src/guidelines/php/patterns/service-layer.md +64 -0
  203. package/dist/agent-src/guidelines/php/patterns/strategy.md +247 -0
  204. package/dist/agent-src/guidelines/php/patterns.md +28 -0
  205. package/dist/agent-src/guidelines/php/performance.md +92 -0
  206. package/dist/agent-src/guidelines/php/php-coding-patterns.md +80 -0
  207. package/dist/agent-src/guidelines/php/resources.md +100 -0
  208. package/dist/agent-src/guidelines/php/security.md +110 -0
  209. package/dist/agent-src/guidelines/php/sql.md +97 -0
  210. package/dist/agent-src/guidelines/php/validations.md +119 -0
  211. package/dist/agent-src/guidelines/php/websocket.md +100 -0
  212. package/dist/agent-src/guidelines/prompt-templates.md +189 -0
  213. package/dist/agent-src/guidelines/redundancy-taxonomy.md +208 -0
  214. package/dist/agent-src/guidelines/wing4-handoff.md +127 -0
  215. package/dist/agent-src/personas/README.md +1 -1
  216. package/dist/agent-src/personas/_template-specialist/persona.md +1 -1
  217. package/dist/agent-src/personas/product-owner.md +1 -1
  218. package/dist/agent-src/rules/active-remediation.md +1 -1
  219. package/dist/agent-src/rules/architecture.md +2 -2
  220. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  221. package/dist/agent-src/rules/ask-when-uncertain.md +2 -2
  222. package/dist/agent-src/rules/brand-source-of-truth.md +9 -7
  223. package/dist/agent-src/rules/code-comment-discipline.md +2 -2
  224. package/dist/agent-src/rules/code-provenance.md +1 -1
  225. package/dist/agent-src/rules/content-quoting-floor.md +1 -1
  226. package/dist/agent-src/rules/context-hygiene.md +5 -5
  227. package/dist/agent-src/rules/cross-source-consistency.md +1 -1
  228. package/dist/agent-src/rules/design-fidelity.md +36 -46
  229. package/dist/agent-src/rules/direct-answers.md +2 -2
  230. package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
  231. package/dist/agent-src/rules/evaluator-independence.md +1 -1
  232. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
  233. package/dist/agent-src/rules/icon-consistency.md +5 -1
  234. package/dist/agent-src/rules/improve-before-implement.md +1 -1
  235. package/dist/agent-src/rules/language-and-tone.md +3 -3
  236. package/dist/agent-src/rules/minimal-safe-diff.md +1 -1
  237. package/dist/agent-src/rules/notes-first-reasoning.md +2 -2
  238. package/dist/agent-src/rules/recurring-criticism.md +1 -1
  239. package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
  240. package/dist/agent-src/rules/role-mode-adherence.md +2 -2
  241. package/dist/agent-src/rules/security-sensitive-stop.md +1 -1
  242. package/dist/agent-src/rules/size-enforcement.md +1 -1
  243. package/dist/agent-src/rules/source-confidentiality.md +2 -2
  244. package/dist/agent-src/rules/think-before-action.md +1 -1
  245. package/dist/agent-src/rules/token-efficiency.md +7 -5
  246. package/dist/agent-src/rules/ui-audit-gate.md +3 -2
  247. package/dist/agent-src/rules/untrusted-input-defense.md +3 -3
  248. package/dist/agent-src/rules/user-interaction.md +31 -30
  249. package/dist/agent-src/skills/activation-design/SKILL.md +2 -2
  250. package/dist/agent-src/skills/adr-create/SKILL.md +5 -5
  251. package/dist/agent-src/skills/ai-council/SKILL.md +1 -1
  252. package/dist/agent-src/skills/ai-council/references/advanced-modes.md +1 -1
  253. package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
  254. package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +1 -1
  255. package/dist/agent-src/skills/brand-to-tokens/SKILL.md +24 -3
  256. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  257. package/dist/agent-src/skills/build-buy-partner/SKILL.md +1 -1
  258. package/dist/agent-src/skills/churn-prevention/SKILL.md +2 -2
  259. package/dist/agent-src/skills/code-refactoring/SKILL.md +3 -3
  260. package/dist/agent-src/skills/code-review/SKILL.md +3 -3
  261. package/dist/agent-src/skills/command-writing/SKILL.md +3 -3
  262. package/dist/agent-src/skills/comp-banding/SKILL.md +1 -1
  263. package/dist/agent-src/skills/competitive-moat-analysis/SKILL.md +1 -1
  264. package/dist/agent-src/skills/competitive-positioning/SKILL.md +2 -2
  265. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +1 -1
  266. package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
  267. package/dist/agent-src/skills/content-funnel-design/SKILL.md +2 -2
  268. package/dist/agent-src/skills/contracts-cognition/SKILL.md +1 -1
  269. package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +2 -2
  270. package/dist/agent-src/skills/corpus-grounding/SKILL.md +2 -2
  271. package/dist/agent-src/skills/customer-research/SKILL.md +2 -2
  272. package/dist/agent-src/skills/dashboard-design/SKILL.md +1 -1
  273. package/dist/agent-src/skills/data-handling-judgment/SKILL.md +1 -1
  274. package/dist/agent-src/skills/deal-qualification-meddic/SKILL.md +2 -2
  275. package/dist/agent-src/skills/decision-record/SKILL.md +3 -3
  276. package/dist/agent-src/skills/decision-review/SKILL.md +8 -8
  277. package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +22 -22
  278. package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
  279. package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +2 -2
  280. package/dist/agent-src/skills/design-review/SKILL.md +4 -4
  281. package/dist/agent-src/skills/design-system-capture/references/design-system-json.md +20 -1
  282. package/dist/agent-src/skills/design-tokens/SKILL.md +17 -2
  283. package/dist/agent-src/skills/design-variations/SKILL.md +2 -2
  284. package/dist/agent-src/skills/developer-like-execution/SKILL.md +2 -2
  285. package/dist/agent-src/skills/discovery-interview/SKILL.md +2 -2
  286. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +3 -3
  287. package/dist/agent-src/skills/editorial-calendar/SKILL.md +2 -2
  288. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +9 -0
  289. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +44 -1
  290. package/dist/agent-src/skills/existing-ui-audit/references/anti-slop-cross-reference.md +2 -2
  291. package/dist/agent-src/skills/expansion-playbook/SKILL.md +2 -2
  292. package/dist/agent-src/skills/experiment-loop/SKILL.md +1 -1
  293. package/dist/agent-src/skills/experiment-loop/references/protocol.md +1 -1
  294. package/dist/agent-src/skills/fe-design/SKILL.md +3 -3
  295. package/dist/agent-src/skills/fe-design/references/design-patterns.md +1 -1
  296. package/dist/agent-src/skills/fe-design/references/design-read-and-memory.md +3 -3
  297. package/dist/agent-src/skills/fe-design/references/source-led-port.md +1 -1
  298. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  299. package/dist/agent-src/skills/flux/SKILL.md +1 -1
  300. package/dist/agent-src/skills/forecast-accuracy/SKILL.md +2 -2
  301. package/dist/agent-src/skills/forecasting/SKILL.md +2 -2
  302. package/dist/agent-src/skills/fundraising-narrative/SKILL.md +2 -2
  303. package/dist/agent-src/skills/funnel-analysis/SKILL.md +2 -2
  304. package/dist/agent-src/skills/gtm-launch/SKILL.md +2 -2
  305. package/dist/agent-src/skills/hiring-loop-design/SKILL.md +1 -1
  306. package/dist/agent-src/skills/html-deck/SKILL.md +5 -5
  307. package/dist/agent-src/skills/humanizer/SKILL.md +1 -1
  308. package/dist/agent-src/skills/humanizer/data/patterns.md +1 -1
  309. package/dist/agent-src/skills/iconography/SKILL.md +3 -3
  310. package/dist/agent-src/skills/judge-synthesis/SKILL.md +1 -1
  311. package/dist/agent-src/skills/laravel-api-endpoint/SKILL.md +2 -2
  312. package/dist/agent-src/skills/launch-readiness/SKILL.md +3 -3
  313. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +6 -6
  314. package/dist/agent-src/skills/livewire/SKILL.md +1 -1
  315. package/dist/agent-src/skills/market-entry-analysis/SKILL.md +1 -1
  316. package/dist/agent-src/skills/mcp-builder/SKILL.md +1 -1
  317. package/dist/agent-src/skills/memory-consolidation/SKILL.md +3 -3
  318. package/dist/agent-src/skills/messaging-architecture/SKILL.md +2 -2
  319. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  320. package/dist/agent-src/skills/onboarding-design/SKILL.md +2 -2
  321. package/dist/agent-src/skills/onboarding-program/SKILL.md +1 -1
  322. package/dist/agent-src/skills/one-on-one-cadence/SKILL.md +1 -1
  323. package/dist/agent-src/skills/org-design/SKILL.md +1 -1
  324. package/dist/agent-src/skills/overbuild-review-lens/SKILL.md +3 -3
  325. package/dist/agent-src/skills/override-management/SKILL.md +1 -1
  326. package/dist/agent-src/skills/perf-feedback-craft/SKILL.md +1 -1
  327. package/dist/agent-src/skills/persona-writing/SKILL.md +1 -1
  328. package/dist/agent-src/skills/php-coder/SKILL.md +1 -1
  329. package/dist/agent-src/skills/pipeline-strategy/SKILL.md +2 -2
  330. package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -3
  331. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  332. package/dist/agent-src/skills/positioning-strategy/SKILL.md +2 -2
  333. package/dist/agent-src/skills/privacy-review/SKILL.md +1 -1
  334. package/dist/agent-src/skills/prompt-optimizer/SKILL.md +3 -3
  335. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  336. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -2
  337. package/dist/agent-src/skills/receiving-code-review/SKILL.md +1 -1
  338. package/dist/agent-src/skills/refine-ticket/SKILL.md +2 -2
  339. package/dist/agent-src/skills/release-comms/SKILL.md +2 -2
  340. package/dist/agent-src/skills/retention-loops/SKILL.md +2 -2
  341. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  342. package/dist/agent-src/skills/roadmap-management/SKILL.md +1 -1
  343. package/dist/agent-src/skills/roadmap-management/references/archival.md +1 -1
  344. package/dist/agent-src/skills/roadmap-writing/SKILL.md +5 -5
  345. package/dist/agent-src/skills/rule-writing/SKILL.md +6 -6
  346. package/dist/agent-src/skills/runway-cognition/SKILL.md +2 -2
  347. package/dist/agent-src/skills/scenario-modeling/SKILL.md +2 -2
  348. package/dist/agent-src/skills/skill-writing/SKILL.md +2 -2
  349. package/dist/agent-src/skills/skill-writing/references/procedure.md +1 -1
  350. package/dist/agent-src/skills/skill-writing/references/section-patterns.md +3 -3
  351. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +1 -1
  352. package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +3 -3
  353. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
  354. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +1 -1
  355. package/dist/agent-src/skills/systematic-debugging/SKILL.md +2 -2
  356. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +11 -5
  357. package/dist/agent-src/skills/throughput-vs-morale-tradeoff/SKILL.md +1 -1
  358. package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
  359. package/dist/agent-src/skills/typography-system/SKILL.md +2 -2
  360. package/dist/agent-src/skills/ui-component-architect/SKILL.md +28 -8
  361. package/dist/agent-src/skills/unit-economics-modeling/SKILL.md +2 -2
  362. package/dist/agent-src/skills/upstream-contribute/SKILL.md +1 -1
  363. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +2 -2
  364. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  365. package/dist/agent-src/skills/vision-articulation/SKILL.md +1 -1
  366. package/dist/agent-src/skills/voc-extract/SKILL.md +2 -2
  367. package/dist/agent-src/skills/voice-and-tone-design/SKILL.md +2 -2
  368. package/dist/agent-src/skills/wireframe/SKILL.md +1 -1
  369. package/dist/agent-src/skills/workspace-link/SKILL.md +1 -1
  370. package/dist/agent-src/templates/agent-settings.md +6 -6
  371. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  372. package/dist/agent-src/templates/contexts/knowledge-pages.md +2 -3
  373. package/dist/agent-src/templates/copilot-instructions.md +1 -1
  374. package/dist/agent-src/templates/roadmaps.md +1 -1
  375. package/dist/agent-src/templates/scripts/README.md +2 -2
  376. package/dist/agent-src/user-types/_template/user-type.md +1 -1
  377. package/dist/cli-delegate/check_update_banner.js +12 -1
  378. package/dist/cli-delegate/{chunk-NLP54U3J.js → chunk-2XY7ILBT.js} +13 -1
  379. package/dist/cli-delegate/{chunk-IAI3XL43.js → chunk-3FKR64R5.js} +22 -6
  380. package/dist/cli-delegate/{chunk-J3RFNKG4.js → chunk-55ACLDUE.js} +2 -2
  381. package/dist/cli-delegate/{chunk-PKOBQADP.js → chunk-57PN4GYJ.js} +1 -1
  382. package/dist/cli-delegate/{chunk-KCNTUSPI.js → chunk-AK6HODNQ.js} +4 -4
  383. package/dist/cli-delegate/{chunk-2FTMENJL.js → chunk-GYC3VRYN.js} +1 -1
  384. package/dist/cli-delegate/{chunk-LWTYTX6F.js → chunk-H32DGUJH.js} +15 -84
  385. package/dist/cli-delegate/{chunk-6RJA2F5A.js → chunk-IVBPRCQO.js} +1 -1
  386. package/dist/cli-delegate/chunk-NUHLI2RX.js +80 -0
  387. package/dist/cli-delegate/{chunk-TYSY33MD.js → chunk-QJWAUMJW.js} +12 -2
  388. package/dist/cli-delegate/{chunk-2KKXJW25.js → chunk-S3VFXMTM.js} +1 -1
  389. package/dist/cli-delegate/{chunk-I6RHFQEG.js → chunk-YUM5KURG.js} +17 -1
  390. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  391. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  392. package/dist/cli-delegate/cmd_conformance.js +834 -275
  393. package/dist/cli-delegate/cmd_doctor.js +3 -3
  394. package/dist/cli-delegate/cmd_explain.js +5 -3
  395. package/dist/cli-delegate/cmd_export.js +4 -4
  396. package/dist/cli-delegate/cmd_handoff.js +6 -6
  397. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  398. package/dist/cli-delegate/cmd_memory_get.js +1 -1
  399. package/dist/cli-delegate/cmd_migrate.js +2 -2
  400. package/dist/cli-delegate/cmd_packs_active.js +3 -2
  401. package/dist/cli-delegate/cmd_prune.js +4 -4
  402. package/dist/cli-delegate/cmd_route_audit.js +3 -3
  403. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  404. package/dist/cli-delegate/cmd_session_recycle.js +3 -3
  405. package/dist/cli-delegate/cmd_settings_get.js +15 -9
  406. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  407. package/dist/cli-delegate/cmd_settings_set.js +54 -11
  408. package/dist/cli-delegate/cmd_sync.js +4 -4
  409. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  410. package/dist/cli-delegate/cmd_update.js +1 -1
  411. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  412. package/dist/cli-delegate/cmd_validate.js +4 -4
  413. package/dist/cli-delegate/cmd_versions.js +1 -1
  414. package/dist/discovery/deprecation-report.md +1 -1
  415. package/dist/discovery/discovery-manifest.json +25 -78
  416. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  417. package/dist/discovery/discovery-manifest.summary.md +3 -3
  418. package/dist/discovery/dormancy-report.md +1 -1
  419. package/dist/discovery/orphan-report.md +1 -1
  420. package/dist/discovery/packs.json +5 -7
  421. package/dist/discovery/trust-report.md +2 -2
  422. package/dist/discovery/workspaces.json +4 -6
  423. package/dist/hooks/dispatch.js +9684 -9304
  424. package/dist/install/install.mjs +36 -8
  425. package/dist/mcp/registry-manifest.json +3 -3
  426. package/dist/mcp/server.json +2 -2
  427. package/dist/mcp/server.mjs +2147 -1470
  428. package/dist/router.json +1 -1
  429. package/dist/scripts/_lib/agent_settings.js +73 -0
  430. package/dist/scripts/_lib/agent_src.js +20 -0
  431. package/dist/scripts/_lib/guidelines_lane.js +158 -0
  432. package/dist/scripts/_lib/installed_lock.js +1 -1
  433. package/dist/scripts/condense.js +2 -5
  434. package/dist/server/io/yamlIO.js +175 -17
  435. package/dist/server/schemas/settings.js +18 -4
  436. package/dist/shared/settingsSurface.js +6 -1
  437. package/docs/contracts/settings-classes.md +18 -9
  438. package/docs/guidelines/abstraction-thresholds.md +35 -0
  439. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +3 -3
  440. package/docs/guidelines/agent-infra/false-green.md +2 -2
  441. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  442. package/docs/guidelines/agent-infra/skill-quality-checklist.md +1 -1
  443. package/docs/guidelines/design-fidelity-mechanics.md +4 -0
  444. package/docs/guidelines/design-fidelity-routing.md +78 -0
  445. package/docs/guidelines/design-reconciliation.md +172 -0
  446. package/docs/guidelines/gtm-handoff.md +2 -2
  447. package/docs/guidelines/wing4-handoff.md +2 -2
  448. package/package.json +7 -3
  449. package/src/config/agent-settings.template.yml +55 -8
  450. package/src/config/ci-local-parity.yml +34 -0
  451. package/src/config/continuity-surface.json +11 -32
  452. package/src/config/gate-coverage.yml +31 -8
  453. package/src/config/gate-reachability-exemptions.json +1 -0
  454. package/src/config/gate-violation-baselines.json +3 -3
  455. package/src/config/hook-token-budget.json +1 -1
  456. package/src/config/host-injection-effect.json +2 -2
  457. package/src/config/pack-size-budget.json +55 -4
  458. package/src/config/platform-anchor.json +47 -0
  459. package/src/config/preamble-payload-budget.json +12 -8
  460. package/src/config/preamble-payload-exceptions.json +28 -0
  461. package/src/config/publish-surface.json +4 -2
  462. package/src/config/ratification-policy.json +7 -0
  463. package/src/config/rule-stub-ceilings.json +16 -9
  464. package/src/scripts/_cli/cmd_settings_get.ts +22 -7
  465. package/src/scripts/_dispatch.bash +3 -1
  466. package/src/scripts/_lib/agent_settings.ts +85 -0
  467. package/src/scripts/_lib/agent_src.ts +21 -0
  468. package/src/scripts/_lib/artifact_maturity.ts +242 -0
  469. package/src/scripts/_lib/base_ref_payload.ts +315 -0
  470. package/src/scripts/_lib/conformance_report.ts +403 -0
  471. package/src/scripts/_lib/continuity_writer.ts +72 -13
  472. package/src/scripts/_lib/design_system_import.ts +20 -0
  473. package/src/scripts/_lib/design_tolerance.ts +281 -0
  474. package/src/scripts/_lib/dropped_decision.ts +142 -0
  475. package/src/scripts/_lib/guidelines_lane.ts +164 -0
  476. package/src/scripts/_lib/installed_lock.ts +1 -1
  477. package/src/scripts/_lib/measured_payload_ceiling.ts +424 -0
  478. package/src/scripts/_lib/obligation_frequency.ts +2 -3
  479. package/src/scripts/_lib/payload_catalogue_completeness.ts +211 -0
  480. package/src/scripts/_lib/platform_anchor.ts +1053 -0
  481. package/src/scripts/_lib/ratification_artifact.ts +278 -0
  482. package/src/scripts/_lib/release_findings_ingest.ts +324 -0
  483. package/src/scripts/_lib/release_tag_dispatch.ts +63 -0
  484. package/src/scripts/_lib/review_baseline.ts +254 -0
  485. package/src/scripts/_lib/review_skipped_record.ts +61 -1
  486. package/src/scripts/_lib/security_lint.ts +23 -2
  487. package/src/scripts/_lib/self_repair.ts +21 -0
  488. package/src/scripts/_lib/session_index_trust.ts +42 -1
  489. package/src/scripts/_lib/standing_bound_ratchet.ts +267 -88
  490. package/src/scripts/_lib/tolerance_shadow.ts +177 -0
  491. package/src/scripts/_lib/turn_end_refusals.ts +51 -4
  492. package/src/scripts/ai_council/redact_low_impact_entry.ts +8 -0
  493. package/src/scripts/autonomy_friction_traffic.ts +379 -0
  494. package/src/scripts/check_beta_review_markers.ts +35 -4
  495. package/src/scripts/check_finding_dispositions.ts +167 -16
  496. package/src/scripts/check_held_object_arrivals.ts +381 -0
  497. package/src/scripts/check_kernel_edit_ratified.ts +462 -0
  498. package/src/scripts/check_loss_class_declared.ts +793 -46
  499. package/src/scripts/check_platform_anchor.ts +390 -0
  500. package/src/scripts/check_preamble_payload_budget.ts +672 -107
  501. package/src/scripts/check_projected_rule_routes.ts +395 -0
  502. package/src/scripts/check_release_published.ts +1 -1
  503. package/src/scripts/check_reply_consistency.ts +86 -17
  504. package/src/scripts/code_graph/cli.ts +6 -0
  505. package/src/scripts/condense.ts +2 -6
  506. package/src/scripts/generate_host_cost_table.ts +354 -0
  507. package/src/scripts/hook_manifest.json +1 -1
  508. package/src/scripts/hook_manifest.yaml +74 -30
  509. package/src/scripts/hooks/block_kernel_rule_writes.ts +12 -2
  510. package/src/scripts/hooks/category_a.ts +1 -1
  511. package/src/scripts/hooks/chain_nudge_hook.ts +311 -25
  512. package/src/scripts/hooks/concern_registry.ts +2 -0
  513. package/src/scripts/hooks/end_review_nudge_hook.ts +101 -21
  514. package/src/scripts/hooks/review_baseline_hook.ts +130 -0
  515. package/src/scripts/hooks/session_eol_hook.ts +68 -154
  516. package/src/scripts/hooks/source_first_gate_hook.ts +12 -0
  517. package/src/scripts/hooks/turn_end_gate_hook.ts +232 -14
  518. package/src/scripts/hooks/ui_route_nudge_hook.ts +52 -15
  519. package/src/scripts/hooks_doctor.ts +4 -1
  520. package/src/scripts/hot_context_hook.ts +41 -401
  521. package/src/scripts/install.ts +1 -1
  522. package/src/scripts/interruption_report.ts +8 -2
  523. package/src/scripts/janitor.ts +8 -1
  524. package/src/scripts/lint_evidence_artifacts.ts +1 -0
  525. package/src/scripts/lint_knowledge_scale.ts +0 -26
  526. package/src/scripts/measure_turn_end_gate.ts +302 -5
  527. package/src/scripts/memory_lookup.ts +9 -9
  528. package/src/scripts/release.ts +52 -64
  529. package/src/scripts/release_drill.ts +193 -14
  530. package/src/scripts/release_env.ts +1 -1
  531. package/src/scripts/release_publication.ts +1 -1
  532. package/src/scripts/report_held_object_arrivals.ts +456 -0
  533. package/src/scripts/report_standing_payload_by_host.ts +7 -7
  534. package/src/scripts/session_memory_index.ts +5 -0
  535. package/src/scripts/sync_agent_settings.ts +394 -12
  536. package/src/server/io/yamlIO.ts +175 -17
  537. package/src/server/schemas/settings.ts +25 -5
  538. package/src/shared/settingsSurface.ts +13 -2
  539. package/src/templates/compact-instructions.md +8 -3
  540. package/dist/agent-src/commands/chat-history/import.md +0 -170
  541. package/dist/agent-src/commands/chat-history.md +0 -63
@@ -9,7 +9,7 @@
9
9
  * is deliberately not another reminder. It is a check at the point of
10
10
  * delivery that can say no.
11
11
  *
12
- * FOUR detectors ride on one guard, because building the unsafe part twice
12
+ * FIVE detectors ride on one guard, because building the unsafe part twice
13
13
  * is how a second detector becomes a second outage:
14
14
  *
15
15
  * A — promissory closing (FC-5, 20 measured occurrences)
@@ -22,11 +22,18 @@
22
22
  * only, so tool activity is invisible to A and B.)
23
23
  * D — completion claim (a claim of done carrying no fresh evidence; landed
24
24
  * under conformance round 7 § Phase 1.)
25
+ * E — pending decision (an earlier reply in the SAME user turn put numbered
26
+ * options to the user and the closing reply carries
27
+ * none — the turn asked and then dropped the ask.
28
+ * Read off `assistantTurnTexts`, which is why that
29
+ * field exists: every other detector reads
30
+ * `lastAssistant` alone and therefore cannot see a
31
+ * question that was asked one reply earlier.)
25
32
  *
26
- * TWO of the four are CONDITIONAL, and saying "unconditional" here would be the
33
+ * TWO of the five are CONDITIONAL, and saying "unconditional" here would be the
27
34
  * same stale-header defect this block corrects below. A and D are the
28
35
  * completion-adjacent pair an open subagent dispatch excuses, so `main()` runs
29
- * them only when `dispatchOpen` is false; B and C run on every turn-end. That
36
+ * them only when `dispatchOpen` is false; B, C and E run on every turn-end. That
30
37
  * narrowing is deliberate (Phase 3 Step 2, narrowed again by R2 round 2) and is
31
38
  * the third allow path, alongside the two re-entrancy layers — see the
32
39
  * per-detector list in `main()`.
@@ -35,7 +42,7 @@
35
42
  * below has carried four since round 7. `DETECTOR_IDS` in
36
43
  * `_lib/turn_end_refusals.ts` is read off that union rather than off this
37
44
  * comment for exactly that reason, and the count is corrected here rather than
38
- * left as a stale header the next reader has to disbelieve.
45
+ * left as a stale header the next reader has to disbelieve. E made it five.
39
46
  *
40
47
  * ## Removal condition
41
48
  *
@@ -157,6 +164,23 @@ import {
157
164
  // agreement invisible when the producer's layout moved. A builder makes the move
158
165
  // a type error.
159
166
  import { statePathFor as ciStatePathFor } from '../before_complete_hook.js';
167
+ // The spec-backed options-block reading, imported rather than re-derived:
168
+ // `user-interaction` Iron Law 1's definition of an ask — a block PLUS its
169
+ // recommendation line — lives in exactly one place and detector E reads it from
170
+ // there.
171
+ //
172
+ // WHAT KEEPS IT FROM RUNNING ON IMPORT, stated precisely because the obvious
173
+ // answer is wrong: that module is `_isCliEntry`-guarded, but WITHOUT the
174
+ // `__AGENT_CONFIG_BUNDLE__` early-out this file carries. Inside
175
+ // `dist/hooks/dispatch.js` every module shares one `import.meta.url`, so the
176
+ // guard alone would not settle it; what does is the `.__direct__` argv rewrite
177
+ // in the `build:hooks` banner. Named here so a future change to that banner
178
+ // does not silently start running a lint's `main()` on every hook dispatch.
179
+ // Detector E, extracted to `_lib` where its prose costs no ratchet debt.
180
+ // Re-exported so every existing importer of this module is unchanged.
181
+ import { detectDroppedDecision } from '../_lib/dropped_decision.js';
182
+
183
+ export { detectDroppedDecision };
160
184
  import { isSafeTranscriptPath } from './end_review_nudge_hook.js';
161
185
  import { unwrap, type JsonObject, type JsonValue } from './envelope.js';
162
186
  import { readHookStdin } from './hook_stdin.js';
@@ -190,7 +214,13 @@ const EXIT_ALLOW = 0;
190
214
  export const TRANSCRIPT_READ_MAX_BYTES = 8 * 1024 * 1024; // 8 MB
191
215
 
192
216
  /** Detector identity, used in the state marker and the refusal text. */
193
- export type DetectorId = 'promissory' | 'language' | 'verification' | 'completion';
217
+ export type DetectorId =
218
+ | 'promissory'
219
+ | 'language'
220
+ | 'verification'
221
+ | 'completion'
222
+ | 'pending-decision'
223
+ | 'untested';
194
224
 
195
225
  export interface Finding {
196
226
  detector: DetectorId;
@@ -723,6 +753,110 @@ export function detectUnverifiedEdit(toolCalls: readonly ToolCall[]): Finding |
723
753
  };
724
754
  }
725
755
 
756
+ // ---------------------------------------------------------------------------
757
+ // Detector F — a completion claim over production code no test accompanies
758
+ // ---------------------------------------------------------------------------
759
+
760
+ /**
761
+ * WHY THIS EXISTS, and why detector C did not already cover it.
762
+ *
763
+ * Detector C asks "did ANY verification command run after the last edit". It is
764
+ * satisfied by `eslint`. That is deliberate — see `isVerificationCommand`, which
765
+ * is narrow about what counts as a command and says nothing about what the
766
+ * command COVERS. So a turn can write four hundred lines of feature code, run
767
+ * the linter, claim done, and pass every guard in this file.
768
+ *
769
+ * Measured consequence, reported by the maintainer 2026-09-11 about a consumer
770
+ * project: a feature shipped whose detail view crashed on open, whose flyouts
771
+ * were broken, and for which the maintainer then had to hand-enumerate what
772
+ * should have been exercised — every view, every CRUD path, drag-and-drop,
773
+ * mobile, filters. Their words: *"Solche Fehler können nur auftreten, weil Du
774
+ * nicht TDD gearbeitet ... hast."* Nothing in the suite refused that turn,
775
+ * because nothing in the suite asks whether the change is TESTED — only whether
776
+ * something ran.
777
+ *
778
+ * THE SIGNAL, and why it is this one. "Is the change covered" is undecidable
779
+ * from a transcript: coverage lives in the consumer's tooling, which this hook
780
+ * cannot run. What IS decidable is the cheapest possible proxy, and it happens
781
+ * to be the exact shape of the reported failure — **production source changed,
782
+ * no test file touched, done claimed**. A proxy is worth shipping here precisely
783
+ * because the population it flags is small and the failure it catches is total:
784
+ * a feature with zero new test lines is not under-tested, it is untested.
785
+ *
786
+ * WHY IT IS GATED ON THE CLAIM rather than on the edit. Firing on every edit
787
+ * would refuse the first turn of every red-green-refactor cycle — the discipline
788
+ * it exists to encourage — and a guard that fires on the majority of turns is a
789
+ * guard that gets switched off. The obligation belongs to the CLAIM, which is
790
+ * also where `verify-before-complete` puts it and where detector D already sits.
791
+ *
792
+ * WHAT IT CANNOT DO. It cannot tell a good test from a token one: a turn that
793
+ * touches any test file clears it. That is a deliberate floor rather than an
794
+ * oversight — `testing-anti-patterns` owns assertion quality, and a guard that
795
+ * tried to judge it from a path would be judging something it cannot see. The
796
+ * honest claim is narrow: this refuses the case where the agent wrote NO test at
797
+ * all and said it was finished.
798
+ */
799
+
800
+ /** Extensions that carry behaviour a test can be owed for. */
801
+ const _SOURCE_RE = /\.(?:ts|tsx|js|jsx|mjs|cjs|vue|svelte|php|py|rb|go|rs|java|kt|swift|cs|scala|ex|exs)$/i;
802
+
803
+ /**
804
+ * Paths that ARE tests, across the conventions this suite's stacks use.
805
+ *
806
+ * Deliberately generous: a false NEGATIVE here (calling a test file a test) only
807
+ * silences the detector, while a false positive would refuse a turn that did
808
+ * write its tests — the direction that gets a guard disabled.
809
+ */
810
+ const _TEST_PATH_RE =
811
+ /(?:^|\/)(?:tests?|specs?|__tests__|__specs__|e2e|cypress|playwright|features)\//i;
812
+ const _TEST_FILE_RE =
813
+ /(?:\.(?:test|spec)\.[a-z]+$)|(?:_test\.[a-z]+$)|(?:(?:^|\/)test_[^/]+$)|(?:Test\.php$)|(?:Spec\.php$)|(?:\.feature$)/i;
814
+
815
+ function _isTestPath(p: string): boolean {
816
+ return _TEST_PATH_RE.test(p) || _TEST_FILE_RE.test(p);
817
+ }
818
+
819
+ function _isProductionSource(p: string): boolean {
820
+ return _SOURCE_RE.test(p) && !_isTestPath(p);
821
+ }
822
+
823
+ /**
824
+ * Fire when the turn changed production code, touched no test, and said done.
825
+ *
826
+ * All three conditions are load-bearing. Drop the first and it fires on a docs
827
+ * turn; drop the second and it fires on a turn that did its job; drop the third
828
+ * and it fires mid-cycle on the red step of red-green-refactor.
829
+ */
830
+ export function detectUntestedChange(reply: string, toolCalls: readonly ToolCall[]): Finding | null {
831
+ const edited = toolCalls
832
+ .filter((c) => _EDIT_TOOLS.has(c.name) && c.path !== undefined)
833
+ .map((c) => c.path as string);
834
+ const source = edited.filter(_isProductionSource);
835
+ if (source.length === 0) return null;
836
+ if (edited.some(_isTestPath)) return null;
837
+
838
+ // The claim gate, reusing detector D's pair rather than a second dialect of
839
+ // "done" — two lists of completion phrasings would drift, and the negation
840
+ // check is what keeps an honest "noch nicht fertig" from being refused.
841
+ const prose = visibleProse(reply);
842
+ const m = _COMPLETION_RE.exec(prose);
843
+ if (!m) return null;
844
+ if (_NEGATED_CLAIM_RE.test(_lineAround(prose, m.index))) return null;
845
+
846
+ const shown = source.slice(0, 3).join(', ');
847
+ return {
848
+ detector: 'untested',
849
+ evidence: shown + (source.length > 3 ? ` (+${String(source.length - 3)} more)` : ''),
850
+ reason:
851
+ 'a completion claim over production code this turn changed, with NO test file ' +
852
+ 'touched anywhere in the turn — running a linter is not evidence the change ' +
853
+ 'works. Write the test that would have caught the failure, and enumerate the ' +
854
+ 'states the change actually has (every view, every CRUD path, the empty and ' +
855
+ 'error states) rather than the happy one. If a test genuinely does not belong ' +
856
+ 'here, say which file carries the coverage instead',
857
+ };
858
+ }
859
+
726
860
  // ---------------------------------------------------------------------------
727
861
  // Re-entrancy — the guard, keyed on the turn, not on the reply
728
862
  // ---------------------------------------------------------------------------
@@ -811,6 +945,7 @@ function markRefusedTurn(
811
945
  sessionKey: string,
812
946
  turnOrdinal: number,
813
947
  detectors: readonly DetectorId[],
948
+ promptId: string,
814
949
  ): void {
815
950
  if (is_replay_mode()) return;
816
951
  const file = sessionStateFile(workspaceRoot, sessionKey);
@@ -835,6 +970,7 @@ function markRefusedTurn(
835
970
  turnOrdinal,
836
971
  at: new Date().toISOString(),
837
972
  version,
973
+ promptId,
838
974
  }) as unknown as Record<string, unknown>,
839
975
  );
840
976
  } catch {
@@ -868,6 +1004,20 @@ export interface ToolCall {
868
1004
 
869
1005
  export interface TranscriptTail {
870
1006
  lastAssistant: string;
1007
+ /**
1008
+ * Every assistant text of the CURRENT turn, in order — reset at each genuine
1009
+ * user prompt exactly like `toolCalls`, and for the same reason: a question
1010
+ * asked three turns ago was answered, a question asked earlier in THIS turn
1011
+ * was not. Detector E reads it; the other four read `lastAssistant`, which is
1012
+ * always the last element when this is non-empty.
1013
+ *
1014
+ * A tool-only assistant entry contributes NOTHING here. `_messageText`
1015
+ * returns null for it and the collector skips it, so the ordinary shape of a
1016
+ * working turn — prose, tool call, prose — produces two elements and not
1017
+ * three. That is the whole false-positive surface of detector E, and it is
1018
+ * closed here rather than in the detector.
1019
+ */
1020
+ assistantTurnTexts: string[];
871
1021
  /**
872
1022
  * How many GENUINE user prompts the transcript carries — harness-injected
873
1023
  * user-role entries excluded via `isSyntheticPrompt`. This is the turn's
@@ -899,7 +1049,12 @@ export function readTranscriptTail(
899
1049
  transcriptPath: string,
900
1050
  opts: { homeDir?: string; maxBytes?: number } = {},
901
1051
  ): TranscriptTail {
902
- const empty: TranscriptTail = { lastAssistant: '', turnOrdinal: 0, toolCalls: [] };
1052
+ const empty: TranscriptTail = {
1053
+ lastAssistant: '',
1054
+ turnOrdinal: 0,
1055
+ toolCalls: [],
1056
+ assistantTurnTexts: [],
1057
+ };
903
1058
  if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
904
1059
  let lines: string[];
905
1060
  try {
@@ -919,6 +1074,7 @@ export function readTranscriptTail(
919
1074
  let lastAssistant = '';
920
1075
  let turnOrdinal = 0;
921
1076
  let toolCalls: ToolCall[] = [];
1077
+ let assistantTurnTexts: string[] = [];
922
1078
  for (const rawLine of lines) {
923
1079
  const line = rawLine.trim();
924
1080
  if (!line) continue;
@@ -944,12 +1100,13 @@ export function readTranscriptTail(
944
1100
  // only a tool_use block has no text at all, so `continue`-ing on a null
945
1101
  // text would drop exactly the entries this detector exists to see.
946
1102
  if (role === 'assistant') {
947
- toolCalls.push(..._toolCalls(content));
1103
+ toolCalls.push(...extractToolCalls(content));
948
1104
  }
949
1105
  const text = _messageText(content);
950
1106
  if (text === null) continue;
951
1107
  if (role === 'assistant') {
952
1108
  lastAssistant = text;
1109
+ assistantTurnTexts.push(text);
953
1110
  } else if (!isSyntheticPrompt(text)) {
954
1111
  turnOrdinal += 1;
955
1112
  // A genuine user prompt starts a new turn, so the previous turn's
@@ -957,17 +1114,34 @@ export function readTranscriptTail(
957
1114
  // run three turns ago would vouch for an edit made now — the
958
1115
  // "fresh" in edit-without-FRESH-verification is this line.
959
1116
  toolCalls = [];
1117
+ // Same boundary, same reason, for detector E: an options block the
1118
+ // user has since replied to is answered, not dropped. Resetting on
1119
+ // the identical line is what makes "in the SAME user turn" true of
1120
+ // the array rather than merely intended.
1121
+ assistantTurnTexts = [];
960
1122
  }
961
1123
  }
962
- return { lastAssistant: lastAssistant.trim(), turnOrdinal, toolCalls };
1124
+ return {
1125
+ lastAssistant: lastAssistant.trim(),
1126
+ turnOrdinal,
1127
+ toolCalls,
1128
+ assistantTurnTexts,
1129
+ };
963
1130
  }
964
1131
 
965
1132
  /**
966
1133
  * Extract this entry's tool calls, keeping only name, shell command and target
967
1134
  * path. A tool input can hold a whole file body; nothing but those three fields
968
1135
  * is carried forward.
1136
+ *
1137
+ * Exported because `measure_turn_end_gate` scores detectors C and E over a real
1138
+ * transcript corpus and therefore has to rebuild the same `ToolCall[]` the gate
1139
+ * sees. A second extractor there would be a second dialect of "what the turn
1140
+ * did", and the measurement would then be of that dialect rather than of the
1141
+ * shipped gate — the exact population-parity defect that script's own header
1142
+ * documents twice.
969
1143
  */
970
- function _toolCalls(content: unknown): ToolCall[] {
1144
+ export function extractToolCalls(content: unknown): ToolCall[] {
971
1145
  if (!Array.isArray(content)) return [];
972
1146
  const out: ToolCall[] = [];
973
1147
  for (const blk of content) {
@@ -1074,11 +1248,30 @@ export function main(): number {
1074
1248
  // in production while its comment claimed it was enforced — the same
1075
1249
  // fixed-the-definition-not-the-caller shape as two other findings in that
1076
1250
  // round, which is why this line exists rather than a default parameter.
1077
- const { lastAssistant, turnOrdinal, toolCalls } = readTranscriptTail(transcriptPath, {
1078
- maxBytes: TRANSCRIPT_READ_MAX_BYTES,
1079
- });
1251
+ const { lastAssistant, turnOrdinal, toolCalls, assistantTurnTexts } = readTranscriptTail(
1252
+ transcriptPath,
1253
+ { maxBytes: TRANSCRIPT_READ_MAX_BYTES },
1254
+ );
1080
1255
  if (!lastAssistant) return EXIT_ALLOW;
1081
1256
 
1257
+ // The closing reply comes from the field the host hands us when it supplies
1258
+ // one, not only from a file the host writes asynchronously. The transcript
1259
+ // may lag the in-memory conversation, and a tail that is one assistant entry
1260
+ // short is silence for `detectDroppedDecision`, whose early return needs two
1261
+ // texts — i.e. the detector goes quiet in exactly the shape it exists for.
1262
+ // `suggestion_capture_hook.ts` reads the same field for the same reason.
1263
+ // Appended, never substituted: `lastAssistant` and the four other detectors
1264
+ // are untouched, and a host that supplies no such field is unchanged.
1265
+ const payloadClosing = str(
1266
+ (payload['last_assistant_message'] ?? payload['lastAssistantMessage']) as
1267
+ | JsonValue
1268
+ | undefined,
1269
+ );
1270
+ const closingFromPayload = payloadClosing !== '' && !assistantTurnTexts.includes(payloadClosing);
1271
+ const turnTexts = closingFromPayload
1272
+ ? [...assistantTurnTexts, payloadClosing]
1273
+ : assistantTurnTexts;
1274
+
1082
1275
  // Layer 2 — keyed on the turn's ORDINAL, never on the prompt's text.
1083
1276
  // A host that sends no `session_id` shares one bucket AND one small-integer
1084
1277
  // ordinal namespace, so an unrelated session whose ordinal matches a stored
@@ -1092,6 +1285,13 @@ export function main(): number {
1092
1285
  // producer keys that on the raw `session_id`. Passing `sessionKey` here would
1093
1286
  // read a path nothing writes — the same shape as the STATE_FILE break this
1094
1287
  // parameter exists to close.
1288
+ // The host's own id for the prompt being processed. Read here and recorded
1289
+ // beside the ordinal in the refusal marker — never used as the guard key.
1290
+ // The ordinal's drift is what both re-entrancy layers exist for, so a later
1291
+ // reading needs the pair to tell a drifted ordinal from a second prompt.
1292
+ const promptId = str(
1293
+ (payload['prompt_id'] ?? payload['promptId']) as JsonValue | undefined,
1294
+ );
1095
1295
  const rawSessionId = str(envelope['session_id'] as JsonValue | undefined) || '';
1096
1296
  const sessionKey = deriveSessionKey(rawSessionId || 'unknown-session');
1097
1297
  if (alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal)) return EXIT_ALLOW;
@@ -1129,6 +1329,22 @@ export function main(): number {
1129
1329
  dispatchOpen
1130
1330
  ? null
1131
1331
  : detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot, rawSessionId)),
1332
+ // Detector E is UNCONDITIONAL, and that is the opposite choice from A
1333
+ // and D one line above rather than an oversight. An open dispatch
1334
+ // excuses a promissory closing because the work is genuinely still
1335
+ // running; it excuses nothing about a question the user was already
1336
+ // asked. Worse: a dispatch — or the `end-review-nudge` stop concern
1337
+ // that produced the measured failure — IS the continuation that drops
1338
+ // the decision, so narrowing E the same way would silence it in exactly
1339
+ // the case it exists for.
1340
+ detectDroppedDecision(turnTexts, closingFromPayload),
1341
+ // Detector F takes the OTHER side of that same question, and the two
1342
+ // sitting adjacent is the clearest place to say why. E fires on a
1343
+ // question already asked, which an open dispatch cannot excuse. F fires
1344
+ // on a completion CLAIM, and a turn waiting on a subagent has not
1345
+ // finished — so its closing is not the claim F is about. Same slot,
1346
+ // opposite trigger, opposite treatment of `dispatchOpen`.
1347
+ dispatchOpen ? null : detectUntestedChange(lastAssistant, toolCalls),
1132
1348
  ]) {
1133
1349
  if (f) findings.push(f);
1134
1350
  }
@@ -1139,6 +1355,7 @@ export function main(): number {
1139
1355
  sessionKey,
1140
1356
  turnOrdinal,
1141
1357
  findings.map((f) => f.detector),
1358
+ promptId,
1142
1359
  );
1143
1360
 
1144
1361
  const lines = findings.map(
@@ -1147,8 +1364,9 @@ export function main(): number {
1147
1364
  process.stderr.write(
1148
1365
  `turn-end-gate: REFUSED — this turn is not finished.\n${lines.join('\n')}\n` +
1149
1366
  ' Do the promised work now, correct the language, run the ' +
1150
- 'verification the edit needs, or read the CI verdict before claiming ' +
1151
- 'it — then end the turn.\n' +
1367
+ 'verification the edit needs, read the CI verdict before claiming ' +
1368
+ 'it, or re-present the options block this turn dropped — then end ' +
1369
+ 'the turn.\n' +
1152
1370
  ' This turn will not be refused a second time.\n',
1153
1371
  );
1154
1372
  return EXIT_BLOCK;
@@ -132,12 +132,17 @@ export function isUiWrite(event: ToolEvent): boolean {
132
132
  * `path_prefix: .claude/design-system/`. Reading one is the agent reaching
133
133
  * rung 1 of the data-basis ladder before it writes.
134
134
  *
135
- * A SHARED PREDICATE, NOT A DECISION INPUT HERE. `decide` does not branch on
136
- * it: the nudge's behaviour is unchanged by an artifact read, and the phase
137
- * that introduced this states `nothing behavioural`. The one consumer is
138
- * `report_consultation_rate`, which measures over transcripts. Keeping the
139
- * predicate beside `isUiWrite` / `isConsultation` is what stops the analyzer
140
- * and the nudge from classifying the same event differently.
135
+ * A SHARED PREDICATE, AND A RECORDED ONE — NOT A DECISION INPUT. `decide`
136
+ * evaluates it on every event and latches the result into `SessionState`, but
137
+ * no branch reads that latch: every `warn` value is what it was before, so the
138
+ * nudge's behaviour is unchanged and the phase's `nothing behavioural` still
139
+ * holds. Recording it closes the gap the predicate shipped with — it was
140
+ * exported here and consumed only by `report_consultation_rate`, so a live
141
+ * session's own state said nothing about whether the artifact had been read.
142
+ * The concern is default-OFF, so this changes nothing for a consumer and makes
143
+ * the shadow record honest (`road-to-design-intent-conformance` 2.6). Keeping
144
+ * the predicate beside `isUiWrite` / `isConsultation` is what stops the
145
+ * analyzer and the nudge from classifying the same event differently.
141
146
  *
142
147
  * THIS IS A COPY OF THE RULE'S TRIGGERS, NOT A READ OF THEM — same honesty
143
148
  * boundary the header states for `ui_surface.ts`: nothing here parses
@@ -162,12 +167,27 @@ export function isUiWrite(event: ToolEvent): boolean {
162
167
  export function isArtifactRead(event: ToolEvent): boolean {
163
168
  if (event.isWrite || !event.file) return false;
164
169
  const normalized = event.file.replace(/\\/g, '/').toLowerCase();
165
- return normalized.endsWith('design.html') || normalized.includes('.claude/design-system/');
170
+ return (
171
+ normalized.endsWith('design.html') ||
172
+ // The Claude Design canvas artboard. NOT covered by the line above:
173
+ // `ToDo.dc.html` does not end in `design.html`, which is exactly why
174
+ // the rule needed a second file pattern (2.5) and why the drift guard
175
+ // below reds when one is added here without the other.
176
+ normalized.endsWith('.dc.html') ||
177
+ normalized.includes('.claude/design-system/')
178
+ );
166
179
  }
167
180
 
168
181
  export interface SessionState {
169
182
  consulted: boolean;
170
183
  nudges: number;
184
+ /**
185
+ * Latched once a provided design artifact has been READ this session.
186
+ * Shadow-only: nothing branches on it. It exists so the session's own
187
+ * record can answer "did this agent open the handover before writing UI",
188
+ * which until 2.6 only a transcript analyzer could answer after the fact.
189
+ */
190
+ artifactRead: boolean;
171
191
  }
172
192
 
173
193
  function stateFile(root: string): string {
@@ -182,12 +202,17 @@ export function readState(root: string, session: string): SessionState {
182
202
  >;
183
203
  const entry = all[session];
184
204
  if (entry && typeof entry.consulted === 'boolean' && typeof entry.nudges === 'number') {
185
- return entry;
205
+ // `artifactRead` arrived after the file shape did, so a state file
206
+ // written by an older build carries the two older fields and not
207
+ // this one. Default it rather than rejecting the entry: dropping a
208
+ // valid latch to gain a boolean would lose the `consulted` flag and
209
+ // re-nudge a session that had already consulted.
210
+ return { ...entry, artifactRead: entry.artifactRead === true };
186
211
  }
187
212
  } catch {
188
213
  /* fresh session */
189
214
  }
190
- return { consulted: false, nudges: 0 };
215
+ return { consulted: false, nudges: 0, artifactRead: false };
191
216
  }
192
217
 
193
218
  /** Sessions retained in the state file; oldest entries drop past this. */
@@ -236,13 +261,21 @@ export function decide(
236
261
  event: ToolEvent,
237
262
  state: SessionState,
238
263
  ): { state: SessionState; warn: boolean } {
264
+ // Evaluated FIRST and independently of every branch below, because
265
+ // `isArtifactRead` and `isConsultation` are NOT disjoint — a read of
266
+ // `src/skills/design-review/references/design.html` satisfies both. Folding
267
+ // it into one of the branches would silently drop such an event from
268
+ // whichever classification lost the race, which is the failure
269
+ // `isArtifactRead`'s own header warns callers about. Latching, never
270
+ // clearing: the question is "was it read at any point this session".
271
+ const artifactRead = state.artifactRead || isArtifactRead(event);
239
272
  if (isConsultation(event)) {
240
- return { state: { ...state, consulted: true }, warn: false };
273
+ return { state: { ...state, artifactRead, consulted: true }, warn: false };
241
274
  }
242
- if (!isUiWrite(event)) return { state, warn: false };
243
- if (state.consulted) return { state, warn: false };
244
- if (state.nudges >= MAX_NUDGES) return { state, warn: false };
245
- return { state: { ...state, nudges: state.nudges + 1 }, warn: true };
275
+ if (!isUiWrite(event)) return { state: { ...state, artifactRead }, warn: false };
276
+ if (state.consulted) return { state: { ...state, artifactRead }, warn: false };
277
+ if (state.nudges >= MAX_NUDGES) return { state: { ...state, artifactRead }, warn: false };
278
+ return { state: { ...state, artifactRead, nudges: state.nudges + 1 }, warn: true };
246
279
  }
247
280
 
248
281
  /**
@@ -256,7 +289,11 @@ export function decide(
256
289
  * but the guard stays enumerated and this note stays with it.
257
290
  */
258
291
  export function stateChanged(before: SessionState, after: SessionState): boolean {
259
- return before.consulted !== after.consulted || before.nudges !== after.nudges;
292
+ return (
293
+ before.consulted !== after.consulted ||
294
+ before.nudges !== after.nudges ||
295
+ before.artifactRead !== after.artifactRead
296
+ );
260
297
  }
261
298
 
262
299
  export function nudgeReason(file: string): string {
@@ -40,6 +40,7 @@ import * as hooks_status from "./hooks_status.js";
40
40
  import {
41
41
  DETECTOR_IDS,
42
42
  collectRefusalStats,
43
+ emptyCounts,
43
44
  readInstallBoundary,
44
45
  type InstallBoundary,
45
46
  type RefusalStats,
@@ -268,7 +269,9 @@ export function collect(
268
269
  turn_end_refusals = {
269
270
  sessionsWithRefusals: 0,
270
271
  total: 0,
271
- byDetector: { promissory: 0, language: 0, verification: 0, completion: 0 },
272
+ // Derived, never a literal: a fifth detector made the old four-key object
273
+ // a type error here and a silent `NaN` in the aggregator it mirrors.
274
+ byDetector: emptyCounts(),
272
275
  byPeriod: [],
273
276
  legacyRecords: 0,
274
277
  unversionedRecords: 0,