@event4u/agent-config 14.12.0 → 14.13.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 (466) 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 +234 -0
  5. package/CONTRIBUTING.md +38 -0
  6. package/CREDITS.md +135 -0
  7. package/NOTICE +13 -0
  8. package/README.md +8 -6
  9. package/dist/agent-src/commands/analyze/inbox.md +109 -2
  10. package/dist/agent-src/commands/feature/dev.md +7 -2
  11. package/dist/agent-src/commands/ghostwriter/write.md +5 -1
  12. package/dist/agent-src/commands/implement-ticket.md +1 -1
  13. package/dist/agent-src/commands/mission/upgrade.md +1 -1
  14. package/dist/agent-src/commands/orchestrate.md +2 -2
  15. package/dist/agent-src/commands/post-as/me.md +5 -1
  16. package/dist/agent-src/commands/pr/merge.md +19 -6
  17. package/dist/agent-src/commands/roadmap/process-full.md +19 -5
  18. package/dist/agent-src/commands/tdd/red.md +12 -2
  19. package/dist/agent-src/commands/work.md +1 -1
  20. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
  21. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
  22. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
  23. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
  24. package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
  25. package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
  26. package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
  27. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  28. package/dist/agent-src/rules/broken-access-control.md +4 -0
  29. package/dist/agent-src/rules/code-provenance.md +4 -0
  30. package/dist/agent-src/rules/design-fidelity.md +1 -1
  31. package/dist/agent-src/rules/domain-safety-pii.md +4 -0
  32. package/dist/agent-src/rules/domain-safety-retention.md +4 -0
  33. package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
  34. package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
  35. package/dist/agent-src/rules/improve-before-implement.md +6 -8
  36. package/dist/agent-src/rules/laravel-routing.md +1 -1
  37. package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
  38. package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
  39. package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
  40. package/dist/agent-src/rules/source-confidentiality.md +12 -34
  41. package/dist/agent-src/rules/symfony-routing.md +1 -1
  42. package/dist/agent-src/rules/token-efficiency.md +14 -0
  43. package/dist/agent-src/rules/tool-safety.md +4 -0
  44. package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
  45. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +247 -3
  46. package/dist/agent-src/scripts/guarded_baseline.ts +328 -0
  47. package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
  48. package/dist/agent-src/scripts/stub_queue.ts +82 -0
  49. package/dist/agent-src/scripts/stubs_due.ts +400 -0
  50. package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
  51. package/dist/agent-src/scripts/update_roadmap_progress.ts +8 -4
  52. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
  53. package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
  54. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
  55. package/dist/agent-src/skills/database/SKILL.md +8 -0
  56. package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
  57. package/dist/agent-src/skills/design-review/SKILL.md +1 -1
  58. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
  59. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
  60. package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
  61. package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
  62. package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
  63. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
  64. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
  65. package/dist/agent-src/skills/laravel/SKILL.md +35 -0
  66. package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
  67. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
  68. package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
  69. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  70. package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
  71. package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
  72. package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
  73. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
  74. package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
  75. package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
  76. package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
  77. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  78. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
  79. package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
  80. package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
  81. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
  82. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  83. package/dist/agent-src/templates/roadmaps.md +97 -3
  84. package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
  85. package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  86. package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
  87. package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
  88. package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  89. package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  90. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  91. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  92. package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  93. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  94. package/dist/cli/commands/uiAudit.js +124 -5
  95. package/dist/cli/registry.js +2 -0
  96. package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
  97. package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
  98. package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
  99. package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
  100. package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
  101. package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
  102. package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
  103. package/dist/cli-delegate/cmd_adr_effective.js +102 -0
  104. package/dist/cli-delegate/cmd_conformance.js +42 -10
  105. package/dist/cli-delegate/cmd_doctor.js +3 -3
  106. package/dist/cli-delegate/cmd_export.js +3 -2
  107. package/dist/cli-delegate/cmd_fleet.js +2 -2
  108. package/dist/cli-delegate/cmd_handoff.js +1 -1
  109. package/dist/cli-delegate/cmd_preflight.js +2 -2
  110. package/dist/cli-delegate/cmd_prune.js +3 -2
  111. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  112. package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
  113. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  114. package/dist/cli-delegate/cmd_sync.js +3 -2
  115. package/dist/cli-delegate/cmd_uninstall.js +3 -2
  116. package/dist/cli-delegate/cmd_validate.js +3 -2
  117. package/dist/discovery/deprecation-report.md +1 -1
  118. package/dist/discovery/discovery-manifest.json +57 -57
  119. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  120. package/dist/discovery/discovery-manifest.summary.md +1 -1
  121. package/dist/discovery/dormancy-report.md +1 -1
  122. package/dist/discovery/orphan-report.md +1 -1
  123. package/dist/discovery/packs.json +2 -2
  124. package/dist/discovery/trust-report.md +1 -1
  125. package/dist/discovery/workspaces.json +2 -2
  126. package/dist/hooks/dispatch.js +1836 -712
  127. package/dist/install/claudeRuleRewrite.js +254 -0
  128. package/dist/install/detect.js +29 -16
  129. package/dist/install/detect_php_shape.js +159 -0
  130. package/dist/install/install.mjs +634 -428
  131. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  132. package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
  133. package/dist/mcp/registry-manifest.json +3 -3
  134. package/dist/mcp/server.json +3 -3
  135. package/dist/mcp/server.mjs +4818 -2645
  136. package/dist/server/schemas/settings.js +3 -0
  137. package/dist/ui/assets/index-D0jaCRPM.js +29 -0
  138. package/dist/ui/index.html +1 -1
  139. package/docs/MIGRATION.md +1 -1
  140. package/docs/THIRD-PARTY-NOTICES.md +25 -0
  141. package/docs/contracts/provider-lifecycle.md +1 -1
  142. package/docs/contracts/settings-classes.md +10 -4
  143. package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
  144. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
  145. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
  146. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
  147. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
  148. package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
  149. package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
  150. package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
  151. package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
  152. package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
  153. package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
  154. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
  155. package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  156. package/docs/guidelines/agent-infra/first-principles.md +2 -2
  157. package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
  158. package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
  159. package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
  160. package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
  161. package/docs/guidelines/agent-infra/layered-settings.md +10 -10
  162. package/docs/guidelines/agent-infra/memory-access.md +1 -1
  163. package/docs/guidelines/agent-infra/mental-models.md +3 -3
  164. package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  165. package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
  166. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
  167. package/docs/guidelines/agent-infra/role-contracts.md +2 -2
  168. package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
  169. package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
  170. package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
  171. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
  172. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
  173. package/docs/guidelines/agent-infra/six-hats.md +3 -3
  174. package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
  175. package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  176. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  177. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  178. package/docs/guidelines/augment-portability-patterns.md +6 -4
  179. package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
  180. package/docs/guidelines/cross-role-handoff.md +2 -2
  181. package/docs/guidelines/design-fidelity-mechanics.md +1 -1
  182. package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
  183. package/docs/guidelines/php/database.md +90 -7
  184. package/docs/guidelines/prompt-templates.md +7 -7
  185. package/llms.txt +2 -2
  186. package/package.json +5 -2
  187. package/src/agent-src/scripts/archive_completed_roadmaps.ts +247 -3
  188. package/src/agent-src/scripts/guarded_baseline.ts +328 -0
  189. package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
  190. package/src/agent-src/scripts/stub_queue.ts +82 -0
  191. package/src/agent-src/scripts/stubs_due.ts +400 -0
  192. package/src/agent-src/scripts/ticket_bundles.ts +84 -0
  193. package/src/agent-src/scripts/update_roadmap_progress.ts +8 -4
  194. package/src/agent-src/templates/scripts/check_memory.ts +258 -17
  195. package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  196. package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
  197. package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
  198. package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  199. package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  200. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  201. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  202. package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  203. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  204. package/src/config/agent-settings.template.yml +32 -3
  205. package/src/config/assurance-capability-registry.json +21 -9
  206. package/src/config/canonical-terms.yml +119 -0
  207. package/src/config/capability-native-outcome-bars.json +81 -0
  208. package/src/config/ci-local-parity.yml +80 -0
  209. package/src/config/drafting-channels.yml +43 -0
  210. package/src/config/estate-count-budget.json +38 -36
  211. package/src/config/evaluator-budgets.json +14 -14
  212. package/src/config/gate-coverage.yml +579 -63
  213. package/src/config/gate-reachability-exemptions.json +21 -0
  214. package/src/config/gate-violation-baselines.json +37 -19
  215. package/src/config/harness-evolution-budget.json +25 -0
  216. package/src/config/lapsed-beta-baseline.json +96 -0
  217. package/src/config/memory-twin-verdicts.yml +129 -0
  218. package/src/config/metric-registry.yml +124 -0
  219. package/src/config/pack-size-budget.json +16 -15
  220. package/src/config/preamble-payload-budget.json +8 -8
  221. package/src/config/profiles/balanced.ini +27 -0
  222. package/src/config/profiles/full.ini +27 -0
  223. package/src/config/profiles/minimal.ini +27 -0
  224. package/src/config/publish-surface.json +9 -2
  225. package/src/config/routing-coverage-seed.json +16 -2
  226. package/src/config/rule-stub-ceilings.json +126 -112
  227. package/src/config/turnaround-budget.json +66 -0
  228. package/src/install/claudeRuleRewrite.ts +288 -0
  229. package/src/install/detect.ts +60 -17
  230. package/src/install/detect_php_shape.ts +191 -0
  231. package/src/scripts/_cli/cmd_doctor.ts +27 -112
  232. package/src/scripts/_dispatch.bash +27 -0
  233. package/src/scripts/_lib/activation_ladder.ts +211 -0
  234. package/src/scripts/_lib/activation_states.ts +88 -0
  235. package/src/scripts/_lib/adherence_detectors.ts +143 -0
  236. package/src/scripts/_lib/arith_claims.ts +181 -0
  237. package/src/scripts/_lib/arm_ranking.ts +62 -0
  238. package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
  239. package/src/scripts/_lib/audit_field_provenance.ts +54 -0
  240. package/src/scripts/_lib/auto_dispatch.ts +32 -3
  241. package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
  242. package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
  243. package/src/scripts/_lib/candidate_proposer.ts +402 -0
  244. package/src/scripts/_lib/candidate_record.ts +601 -0
  245. package/src/scripts/_lib/capture_rate.ts +319 -0
  246. package/src/scripts/_lib/collector_denominator.ts +771 -0
  247. package/src/scripts/_lib/collector_record.ts +340 -0
  248. package/src/scripts/_lib/collector_store.ts +664 -0
  249. package/src/scripts/_lib/collector_supervision.ts +827 -0
  250. package/src/scripts/_lib/concern_estate.ts +77 -0
  251. package/src/scripts/_lib/config_chain.ts +477 -0
  252. package/src/scripts/_lib/config_cost.ts +209 -0
  253. package/src/scripts/_lib/council_settings_block.ts +6 -0
  254. package/src/scripts/_lib/curator_ops.ts +172 -0
  255. package/src/scripts/_lib/delivery_arm_experiment.ts +266 -0
  256. package/src/scripts/_lib/delivery_criticality.ts +126 -0
  257. package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
  258. package/src/scripts/_lib/empty_cycles.ts +88 -0
  259. package/src/scripts/_lib/eval_publication.ts +354 -0
  260. package/src/scripts/_lib/evaluation_vector.ts +283 -0
  261. package/src/scripts/_lib/evaluator_promotion.ts +225 -0
  262. package/src/scripts/_lib/evidence_basis.ts +118 -0
  263. package/src/scripts/_lib/exec_evidence.ts +8 -0
  264. package/src/scripts/_lib/experience_card.ts +272 -0
  265. package/src/scripts/_lib/experience_report.ts +151 -0
  266. package/src/scripts/_lib/experiment_freeze.ts +112 -0
  267. package/src/scripts/_lib/generated_by.ts +66 -0
  268. package/src/scripts/_lib/harness_evolution_guards.ts +229 -0
  269. package/src/scripts/_lib/hook_effect_probe.ts +141 -0
  270. package/src/scripts/_lib/host_denominator.ts +687 -0
  271. package/src/scripts/_lib/host_projection_reach.ts +157 -0
  272. package/src/scripts/_lib/ignored_blocker.ts +148 -0
  273. package/src/scripts/_lib/install_reach_checks.ts +495 -0
  274. package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
  275. package/src/scripts/_lib/judge_hygiene.ts +228 -0
  276. package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
  277. package/src/scripts/_lib/loop_guards.ts +299 -0
  278. package/src/scripts/_lib/loss_class.ts +129 -0
  279. package/src/scripts/_lib/machine_wake.ts +51 -0
  280. package/src/scripts/_lib/md_prose_lines.ts +177 -0
  281. package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
  282. package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
  283. package/src/scripts/_lib/orchestration_record.ts +253 -5
  284. package/src/scripts/_lib/outcome_envelope.ts +227 -0
  285. package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
  286. package/src/scripts/_lib/paired_stats.ts +245 -0
  287. package/src/scripts/_lib/paired_verdict.ts +226 -0
  288. package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
  289. package/src/scripts/_lib/privacy_class.ts +47 -0
  290. package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
  291. package/src/scripts/_lib/repeated_failure.ts +105 -0
  292. package/src/scripts/_lib/repo_root.ts +111 -0
  293. package/src/scripts/_lib/review_skipped_record.ts +37 -0
  294. package/src/scripts/_lib/role_split.ts +338 -0
  295. package/src/scripts/_lib/runtime_journal.ts +1499 -0
  296. package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
  297. package/src/scripts/_lib/skill_catalogue.ts +11 -1
  298. package/src/scripts/_lib/source_digest.ts +200 -0
  299. package/src/scripts/_lib/source_redact.ts +260 -0
  300. package/src/scripts/_lib/source_shape.ts +502 -0
  301. package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
  302. package/src/scripts/_lib/strip_comments.d.mts +8 -0
  303. package/src/scripts/_lib/strip_comments.mjs +65 -0
  304. package/src/scripts/_lib/test_red_state.ts +154 -0
  305. package/src/scripts/_lib/trigger_shift.ts +144 -0
  306. package/src/scripts/_lib/untrusted_content.ts +82 -7
  307. package/src/scripts/adoption_report.ts +1 -1
  308. package/src/scripts/adr/evidence_census.ts +1 -1
  309. package/src/scripts/adr/regenerate_index.ts +26 -2
  310. package/src/scripts/adr_cite_check.ts +164 -1
  311. package/src/scripts/ai_council/blind_review.ts +11 -1
  312. package/src/scripts/ai_council/clients.ts +4 -0
  313. package/src/scripts/ai_council/config.ts +3 -0
  314. package/src/scripts/ai_council/consensus.ts +28 -8
  315. package/src/scripts/ai_council/consensus_round.ts +226 -0
  316. package/src/scripts/ai_council/disagreement_signal.ts +338 -0
  317. package/src/scripts/ai_council/inline_findings.ts +340 -0
  318. package/src/scripts/ai_council/judge_position_bias.ts +197 -0
  319. package/src/scripts/ai_council/orchestrator.ts +16 -203
  320. package/src/scripts/ai_council/orchestrator_results.ts +23 -3
  321. package/src/scripts/ai_council/pricing.ts +106 -0
  322. package/src/scripts/ai_council/prompts.ts +74 -7
  323. package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
  324. package/src/scripts/ai_council/py_format.ts +14 -3
  325. package/src/scripts/ai_council/recouncil_guard.ts +293 -0
  326. package/src/scripts/ai_council/response_record.ts +50 -0
  327. package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
  328. package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
  329. package/src/scripts/asset_delivery_ledger.ts +157 -0
  330. package/src/scripts/attest_artifact.ts +193 -0
  331. package/src/scripts/audit_auto_rules.ts +2 -1
  332. package/src/scripts/audit_command_surface.ts +1 -1
  333. package/src/scripts/audit_mcp_tools.ts +2 -2
  334. package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
  335. package/src/scripts/audit_user_type_axis.ts +2 -1
  336. package/src/scripts/bench_ab_clone.ts +215 -10
  337. package/src/scripts/bench_ab_integrity.ts +119 -5
  338. package/src/scripts/bench_ab_v2_stats.ts +40 -213
  339. package/src/scripts/build_archive_index.ts +1 -1
  340. package/src/scripts/build_linear_digest.ts +1 -1
  341. package/src/scripts/build_proof.ts +11 -4
  342. package/src/scripts/build_rule_trigger_matrix.ts +1 -1
  343. package/src/scripts/build_source_digests.ts +157 -0
  344. package/src/scripts/cache_realization_report.ts +103 -0
  345. package/src/scripts/check_adr_frontmatter.ts +126 -0
  346. package/src/scripts/check_benchmark_report_fields.ts +207 -0
  347. package/src/scripts/check_beta_review_markers.ts +235 -6
  348. package/src/scripts/check_bundle_path_leakage.ts +34 -1
  349. package/src/scripts/check_claims.ts +576 -6
  350. package/src/scripts/check_composite_arming.ts +35 -0
  351. package/src/scripts/check_concern_admissions.ts +365 -0
  352. package/src/scripts/check_enforcement_coverage.ts +28 -0
  353. package/src/scripts/check_estate_count.ts +142 -1
  354. package/src/scripts/check_gate_reachability.ts +383 -0
  355. package/src/scripts/check_host_loadability.ts +104 -0
  356. package/src/scripts/check_loss_class_declared.ts +308 -0
  357. package/src/scripts/check_md_language.ts +15 -98
  358. package/src/scripts/check_memory_proposal.ts +18 -11
  359. package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
  360. package/src/scripts/check_no_external_sources.ts +281 -6
  361. package/src/scripts/check_pack_conformance_fixture.ts +11 -1
  362. package/src/scripts/check_pack_size.ts +59 -2
  363. package/src/scripts/check_preamble_payload_budget.ts +114 -3
  364. package/src/scripts/check_prefix_stable_mutation.ts +372 -0
  365. package/src/scripts/check_publish_surface.ts +10 -1
  366. package/src/scripts/check_references.ts +24 -1
  367. package/src/scripts/check_rule_evidence_declaration.ts +316 -0
  368. package/src/scripts/check_rule_projection_integrity.ts +14 -4
  369. package/src/scripts/check_score_contract.ts +26 -3
  370. package/src/scripts/check_static_parity.ts +285 -0
  371. package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
  372. package/src/scripts/check_suppression_hygiene.ts +15 -0
  373. package/src/scripts/ci_settle.ts +39 -2
  374. package/src/scripts/code_graph/build.ts +60 -3
  375. package/src/scripts/code_graph/extract.ts +44 -0
  376. package/src/scripts/code_graph/types.ts +24 -0
  377. package/src/scripts/collector_daemon.ts +714 -0
  378. package/src/scripts/config_cost_report.ts +302 -0
  379. package/src/scripts/consumer_matrix.ts +74 -1
  380. package/src/scripts/cost/budget.mjs +10 -3
  381. package/src/scripts/cost/track.mjs +10 -3
  382. package/src/scripts/council_cli.ts +37 -54
  383. package/src/scripts/dispatch_r2_reviewer.ts +46 -5
  384. package/src/scripts/evolution_lab.ts +980 -0
  385. package/src/scripts/external_sources_denylist.json +5 -18
  386. package/src/scripts/extract_audit_patterns.ts +21 -0
  387. package/src/scripts/fold_intake.ts +12 -1
  388. package/src/scripts/gen_discovery_baseline.ts +1 -1
  389. package/src/scripts/generate_capabilities_index.ts +12 -5
  390. package/src/scripts/generate_capability_matrix.ts +3 -3
  391. package/src/scripts/generate_command_flows.ts +2 -2
  392. package/src/scripts/generate_cookbook.ts +2 -2
  393. package/src/scripts/generate_index.ts +8 -1
  394. package/src/scripts/generate_knowledge_index.ts +2 -1
  395. package/src/scripts/generate_ownership_matrix.ts +2 -1
  396. package/src/scripts/generate_pack_manifests.ts +10 -2
  397. package/src/scripts/generate_role_experiences_catalog.ts +2 -2
  398. package/src/scripts/generate_settings_reference.ts +1 -1
  399. package/src/scripts/git_authorization_hook.ts +22 -1
  400. package/src/scripts/grade_target_readiness.ts +48 -5
  401. package/src/scripts/hook_effect_doctor.ts +261 -0
  402. package/src/scripts/hook_manifest.json +1 -1
  403. package/src/scripts/hook_manifest.yaml +98 -11
  404. package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
  405. package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
  406. package/src/scripts/hooks/concern_registry.ts +4 -0
  407. package/src/scripts/hooks/dispatch_hook.ts +32 -0
  408. package/src/scripts/hooks/journal_record_hook.ts +345 -0
  409. package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
  410. package/src/scripts/hooks/run_continuation_hook.ts +44 -9
  411. package/src/scripts/hooks/shims/install.sh +61 -0
  412. package/src/scripts/hooks/shims/php +101 -0
  413. package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
  414. package/src/scripts/hot_context_hook.ts +16 -0
  415. package/src/scripts/install-hooks.sh +20 -5
  416. package/src/scripts/install.ts +17 -35
  417. package/src/scripts/inventory_frontmatter.ts +2 -1
  418. package/src/scripts/lint_adr_sweep_routing.ts +12 -0
  419. package/src/scripts/lint_canonical_terms.ts +604 -0
  420. package/src/scripts/lint_composition_review.ts +619 -0
  421. package/src/scripts/lint_consolidation_lineage.ts +666 -0
  422. package/src/scripts/lint_eval_specs.ts +593 -0
  423. package/src/scripts/lint_hook_manifest.ts +19 -0
  424. package/src/scripts/lint_host_portability.ts +373 -0
  425. package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
  426. package/src/scripts/lint_memory_twin_parity.ts +335 -0
  427. package/src/scripts/lint_metric_consumers.ts +355 -0
  428. package/src/scripts/lint_skill_descriptions.ts +18 -1
  429. package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
  430. package/src/scripts/lint_skill_link_reach.ts +252 -0
  431. package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
  432. package/src/scripts/lint_ticket_buildable.ts +17 -1
  433. package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
  434. package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
  435. package/src/scripts/measure_docs_dead_links.ts +348 -0
  436. package/src/scripts/measure_host_capture.ts +461 -0
  437. package/src/scripts/migration_status.ts +3 -3
  438. package/src/scripts/model_rule_injection.ts +60 -0
  439. package/src/scripts/orchestration_record.ts +14 -0
  440. package/src/scripts/preamble_byte_census.ts +139 -10
  441. package/src/scripts/prepack-check.mjs +4 -1
  442. package/src/scripts/probe_turnaround.ts +384 -0
  443. package/src/scripts/probe_unblocked_ask.ts +279 -0
  444. package/src/scripts/render_benchmark_md.ts +1 -1
  445. package/src/scripts/rule_activation_census.ts +70 -9
  446. package/src/scripts/rule_backlinks.ts +1 -1
  447. package/src/scripts/run_lifecycle_suite.ts +208 -0
  448. package/src/scripts/run_skill_evals.ts +40 -0
  449. package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
  450. package/src/scripts/schemas/drafting-channels.schema.json +43 -0
  451. package/src/scripts/schemas/evals.schema.json +24 -1
  452. package/src/scripts/schemas/rule.schema.json +52 -1
  453. package/src/scripts/schemas/skill.schema.json +17 -2
  454. package/src/scripts/skill_overlap.ts +7 -1
  455. package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
  456. package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
  457. package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
  458. package/src/scripts/skill_usage_report.ts +2 -1
  459. package/src/scripts/stubs_due.ts +211 -0
  460. package/src/scripts/sweep_source_surfaces.ts +678 -0
  461. package/src/scripts/sync_pr_branch.ts +3 -3
  462. package/src/scripts/trigger_eval_grandfather.json +202 -222
  463. package/src/scripts/utilization_report.ts +22 -2
  464. package/src/server/schemas/settings.ts +5 -0
  465. package/src/templates/marketing-copy.yml +1 -1
  466. package/dist/ui/assets/index-Cxgy63kz.js +0 -26
@@ -0,0 +1,400 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Read-only query: which roadmap stubs are overdue for a read, and which
4
+ * decisions are sitting on the owner.
5
+ *
6
+ * WHY THIS EXISTS, AND WHY IT LANDS BEFORE THE DATES DO.
7
+ * `agents/roadmaps/stubs/` holds 77 files that are, by construction, not active
8
+ * work — the directory listing IS the inventory (the index tables were deleted
9
+ * on 2026-08-21 and `check_no_stub_inventory_table` keeps them deleted). Giving
10
+ * each stub a `review_by:` date without giving anyone a way to READ those dates
11
+ * would be strictly worse than adding nothing: the repository would carry a
12
+ * field certifying attention it does not pay, and a stale date reads as
13
+ * evidence. An AI council (2026-08-26, 2/2) made the ordering a rule — the
14
+ * reader lands first, the backfill second. This is the reader.
15
+ *
16
+ * WHAT IT IS NOT. It is not a gate: it always exits 0, because "three stubs are
17
+ * overdue" is a state of the world, not a defect in a diff. It is not an
18
+ * inventory table: it prints to stdout on demand and writes nothing, least of
19
+ * all into `agents/roadmaps/stubs/`, so the guard that deleted the tables stays
20
+ * green and un-weakened. `agent-config roadmap:progress` consumes only its two
21
+ * COUNTS for the dashboard header — two integers, no rows, nothing to grow an
22
+ * index back from.
23
+ *
24
+ * THE TWO SHAPES HAVE DIFFERENT CLOCKS, and the cadence follows the shape, not
25
+ * the file. A drain-run transfer is capability-gated: an environment can appear
26
+ * at any moment, so it is re-probed every 30 days. An org-mode stub is
27
+ * demand-gated: customer recruitment and audit funding move slowly, so its
28
+ * demand question is re-asked every 120 days. Both numbers, and the reason 120
29
+ * was taken over 180, are recorded in `agents/roadmaps/stubs/README.md`
30
+ * § Frontmatter contract.
31
+ *
32
+ * OWNER DECISIONS are counted from two deterministic markers, because "the text
33
+ * routes a decision to the owner" needs to be readable by a script and not only
34
+ * by a person: an `## Unresolved decision` heading, and an open `### blocker:`
35
+ * whose owner is the maintainer. A stub can carry both.
36
+ *
37
+ * CLI contract: always exit 0.
38
+ * ./scripts-run src/scripts/stubs_due
39
+ * ./scripts-run src/scripts/stubs_due --json
40
+ * ./scripts-run src/scripts/stubs_due --counts # the two integers only
41
+ * ./scripts-run src/scripts/stubs_due --today 2026-12-01 # pin "now"
42
+ */
43
+ import * as fs from 'node:fs';
44
+ import * as path from 'node:path';
45
+ import { fileURLToPath, pathToFileURL } from 'node:url';
46
+
47
+ const STUB_DIR = path.join('agents', 'roadmaps', 'stubs');
48
+
49
+ /** Cadence in days, per stub shape. Source of truth: the README section above. */
50
+ export const CADENCE_DAYS = { transfer: 30, orgmode: 120 } as const;
51
+
52
+ /** The marker that identifies a drain-run transfer in a stub body. */
53
+ const TRANSFER_MARKER = 'drain-run transfer';
54
+
55
+ const _HERE = path.resolve(fileURLToPath(import.meta.url));
56
+
57
+ export type StubShape = 'transfer' | 'orgmode';
58
+
59
+ export interface StubRecord {
60
+ file: string;
61
+ shape: StubShape;
62
+ review_by: string | null;
63
+ reviewed_at: string | null;
64
+ probe_none: boolean;
65
+ has_probe_heading: boolean;
66
+ owner_decisions: number;
67
+ overdue: boolean;
68
+ days_overdue: number | null;
69
+ }
70
+
71
+ function _isDir(p: string): boolean {
72
+ try {
73
+ return fs.statSync(p).isDirectory();
74
+ } catch {
75
+ return false;
76
+ }
77
+ }
78
+
79
+ /** Walk up from CWD until a dir containing `agents/roadmaps/stubs` is found. */
80
+ export function repo_root(start?: string): string {
81
+ let cur = start ?? process.cwd();
82
+ const chain = [cur];
83
+ for (;;) {
84
+ const parent = path.dirname(cur);
85
+ if (parent === cur) break;
86
+ chain.push(parent);
87
+ cur = parent;
88
+ }
89
+ for (const candidate of chain) {
90
+ if (_isDir(path.join(candidate, STUB_DIR))) {
91
+ return candidate;
92
+ }
93
+ }
94
+ return start ?? process.cwd();
95
+ }
96
+
97
+ /**
98
+ * The frontmatter block, as raw lines. Returns [] when the file does not open
99
+ * with `---` — a stub without frontmatter simply has no fields, which the
100
+ * caller reports rather than crashing on.
101
+ */
102
+ function _frontmatter(text: string): string[] {
103
+ const lines = text.split('\n');
104
+ if (lines[0]?.trim() !== '---') {
105
+ return [];
106
+ }
107
+ const out: string[] = [];
108
+ for (const line of lines.slice(1)) {
109
+ if (line.trim() === '---') {
110
+ return out;
111
+ }
112
+ out.push(line);
113
+ }
114
+ return [];
115
+ }
116
+
117
+ function _scalar(front: string[], key: string): string | null {
118
+ const prefix = `${key}:`;
119
+ for (const line of front) {
120
+ if (line.startsWith(prefix)) {
121
+ return line.slice(prefix.length).trim().replace(/^["']|["']$/g, '');
122
+ }
123
+ }
124
+ return null;
125
+ }
126
+
127
+ /**
128
+ * Owner-routed decisions in one stub body. Two markers, unioned:
129
+ * - an `## Unresolved decision …` heading — the shape
130
+ * `road-to-owner-authority-decisions.md` already uses;
131
+ * - an open `### blocker:` whose Owner line names the maintainer.
132
+ * Counting the union rather than one of them is deliberate: a stub can carry
133
+ * both, and either alone would under-report.
134
+ */
135
+ export function count_owner_decisions(text: string): number {
136
+ const lines = text.split('\n');
137
+ let n = 0;
138
+ for (const line of lines) {
139
+ if (/^#{2,4}\s+Unresolved decision\b/.test(line)) {
140
+ n += 1;
141
+ }
142
+ }
143
+ // Open maintainer-owned blockers. Scan each `### blocker:` section for the
144
+ // two field lines; a blocker missing either is not counted, because an
145
+ // unstated owner is not an owner decision.
146
+ let inBlocker = false;
147
+ let ownerIsMaintainer = false;
148
+ let statusOpen = false;
149
+ const flush = (): void => {
150
+ if (inBlocker && ownerIsMaintainer && statusOpen) {
151
+ n += 1;
152
+ }
153
+ inBlocker = false;
154
+ ownerIsMaintainer = false;
155
+ statusOpen = false;
156
+ };
157
+ for (const line of lines) {
158
+ if (/^#{2,4}\s+(blocker:|b-)/.test(line.trim()) || /^#{2,4}\s+\S+ — /.test(line)) {
159
+ if (/blocker:/.test(line) || /^#{2,4}\s+b-/.test(line.trim())) {
160
+ flush();
161
+ inBlocker = true;
162
+ continue;
163
+ }
164
+ }
165
+ if (!inBlocker) continue;
166
+ if (/^#{1,4}\s/.test(line)) {
167
+ flush();
168
+ continue;
169
+ }
170
+ if (/^-\s+\*\*Owner:\*\*\s*maintainer\b/i.test(line)) ownerIsMaintainer = true;
171
+ if (/^-\s+\*\*Status:\*\*\s*open\b/i.test(line)) statusOpen = true;
172
+ }
173
+ flush();
174
+ return n;
175
+ }
176
+
177
+ /** ISO date (UTC) N days after `from`. */
178
+ function _addDays(from: Date, days: number): string {
179
+ const d = new Date(from.getTime() + days * 86_400_000);
180
+ return d.toISOString().slice(0, 10);
181
+ }
182
+
183
+ function _parseIso(s: string): Date | null {
184
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(s)) return null;
185
+ const d = new Date(`${s}T00:00:00Z`);
186
+ return Number.isNaN(d.getTime()) ? null : d;
187
+ }
188
+
189
+ /** Read every stub and classify it. `today` is injectable so tests are stable. */
190
+ export function scan(root: string, today: string): StubRecord[] {
191
+ return scan_dir(path.join(root, STUB_DIR), today);
192
+ }
193
+
194
+ /**
195
+ * Same, but addressed by the stub DIRECTORY rather than the repo root.
196
+ * `update_roadmap_progress` already holds `agents/roadmaps` and would otherwise
197
+ * have to walk back up two levels to hand this function a root it would
198
+ * immediately re-join — a fragile round trip past exactly the directory both
199
+ * callers care about.
200
+ */
201
+ export function scan_dir(base: string, today: string): StubRecord[] {
202
+ if (!_isDir(base)) return [];
203
+ const now = _parseIso(today);
204
+ const out: StubRecord[] = [];
205
+ let names: string[];
206
+ try {
207
+ names = fs
208
+ .readdirSync(base)
209
+ .filter((n) => n.endsWith('.md') && n !== 'README.md')
210
+ .sort();
211
+ } catch {
212
+ return [];
213
+ }
214
+ for (const name of names) {
215
+ let text: string;
216
+ try {
217
+ text = fs.readFileSync(path.join(base, name), 'utf8');
218
+ } catch {
219
+ continue;
220
+ }
221
+ const front = _frontmatter(text);
222
+ const review_by = _scalar(front, 'review_by');
223
+ const reviewed_at = _scalar(front, 'reviewed_at');
224
+ const probeVal = _scalar(front, 'probe');
225
+ const shape: StubShape = text.includes(TRANSFER_MARKER) ? 'transfer' : 'orgmode';
226
+ let overdue = false;
227
+ let days_overdue: number | null = null;
228
+ if (review_by !== null && now !== null) {
229
+ const due = _parseIso(review_by);
230
+ if (due !== null && due.getTime() < now.getTime()) {
231
+ overdue = true;
232
+ days_overdue = Math.round((now.getTime() - due.getTime()) / 86_400_000);
233
+ }
234
+ }
235
+ out.push({
236
+ file: `${STUB_DIR}/${name}`,
237
+ shape,
238
+ review_by,
239
+ reviewed_at,
240
+ probe_none: probeVal === 'none',
241
+ has_probe_heading: /^#{1,4} *(Probe|Promotion)/m.test(text),
242
+ owner_decisions: count_owner_decisions(text),
243
+ overdue,
244
+ days_overdue,
245
+ });
246
+ }
247
+ return out;
248
+ }
249
+
250
+ export interface Counts {
251
+ overdue: number;
252
+ owner_decisions: number;
253
+ missing_review_by: number;
254
+ total: number;
255
+ }
256
+
257
+ export function counts(records: StubRecord[]): Counts {
258
+ return {
259
+ overdue: records.filter((r) => r.overdue).length,
260
+ owner_decisions: records.reduce((s, r) => s + r.owner_decisions, 0),
261
+ missing_review_by: records.filter((r) => r.review_by === null).length,
262
+ total: records.length,
263
+ };
264
+ }
265
+
266
+ /** Suggested `review_by:` for a stub of this shape, dated from `from`. */
267
+ export function due_date(shape: StubShape, from: string): string {
268
+ const d = _parseIso(from) ?? new Date();
269
+ return _addDays(d, CADENCE_DAYS[shape]);
270
+ }
271
+
272
+ export function main(argv: readonly string[] = process.argv.slice(2)): number {
273
+ const asJson = argv.includes('--json');
274
+ const countsOnly = argv.includes('--counts');
275
+ const todayIdx = argv.indexOf('--today');
276
+ const today =
277
+ todayIdx >= 0 && argv[todayIdx + 1] !== undefined
278
+ ? (argv[todayIdx + 1] as string)
279
+ : new Date().toISOString().slice(0, 10);
280
+
281
+ const root = repo_root();
282
+ const records = scan(root, today);
283
+ const c = counts(records);
284
+
285
+ if (countsOnly) {
286
+ process.stdout.write(`${c.overdue} ${c.owner_decisions}\n`);
287
+ return 0;
288
+ }
289
+ if (asJson) {
290
+ process.stdout.write(`${JSON.stringify({ today, counts: c, stubs: records }, null, 2)}\n`);
291
+ return 0;
292
+ }
293
+
294
+ process.stdout.write(`stubs:due · ${today} · ${c.total} stub(s) under ${STUB_DIR}/\n\n`);
295
+
296
+ const overdue = records.filter((r) => r.overdue).sort((a, b) => (b.days_overdue ?? 0) - (a.days_overdue ?? 0));
297
+ if (overdue.length === 0) {
298
+ process.stdout.write(' ✅ no stub is past its review date.\n');
299
+ } else {
300
+ process.stdout.write(` ⚠️ ${overdue.length} overdue:\n`);
301
+ for (const r of overdue) {
302
+ process.stdout.write(
303
+ ` ${r.file} (${r.shape}, due ${r.review_by}, ${r.days_overdue}d late)\n`,
304
+ );
305
+ }
306
+ }
307
+
308
+ if (c.missing_review_by > 0) {
309
+ process.stdout.write(
310
+ `\n ⚠️ ${c.missing_review_by} stub(s) carry no \`review_by:\` — see ` +
311
+ `${STUB_DIR}/README.md § Frontmatter contract:\n`,
312
+ );
313
+ for (const r of records.filter((x) => x.review_by === null)) {
314
+ process.stdout.write(
315
+ ` ${r.file} (${r.shape}, suggested ${due_date(r.shape, today)})\n`,
316
+ );
317
+ }
318
+ }
319
+
320
+ const withDecisions = records.filter((r) => r.owner_decisions > 0);
321
+ process.stdout.write(`\n ${c.owner_decisions} decision(s) routed to the owner`);
322
+ if (withDecisions.length === 0) {
323
+ process.stdout.write('.\n');
324
+ } else {
325
+ process.stdout.write(':\n');
326
+ for (const r of withDecisions) {
327
+ process.stdout.write(` ${r.file} (${r.owner_decisions})\n`);
328
+ }
329
+ }
330
+
331
+ const noProbe = records.filter((r) => !r.probe_none && !r.has_probe_heading);
332
+ if (noProbe.length > 0) {
333
+ process.stdout.write(
334
+ `\n ⚠️ ${noProbe.length} stub(s) name no promoting probe and do not say ` +
335
+ '`probe: none`:\n',
336
+ );
337
+ for (const r of noProbe) {
338
+ process.stdout.write(` ${r.file}\n`);
339
+ }
340
+ }
341
+
342
+ process.stdout.write('\n Read-only. This command writes nothing.\n');
343
+ return 0;
344
+ }
345
+
346
+ function _isCliEntry(): boolean {
347
+ if (process.argv[1] === undefined) {
348
+ return false;
349
+ }
350
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
351
+ if (import.meta.url === argvUrl) {
352
+ return true;
353
+ }
354
+ try {
355
+ const here = fs.realpathSync(fileURLToPath(import.meta.url));
356
+ const argv = fs.realpathSync(path.resolve(process.argv[1]));
357
+ return here === argv;
358
+ } catch {
359
+ return false;
360
+ }
361
+ }
362
+
363
+ if (_isCliEntry() || process.argv[1] === _HERE) {
364
+ process.exitCode = main();
365
+ }
366
+
367
+ /**
368
+ * The dashboard header fragment: two integers and a pointer, or `''` when both
369
+ * are zero.
370
+ *
371
+ * Lives here rather than in `update_roadmap_progress` deliberately. That file
372
+ * sits on the wrong side of the 1,500-line source-size ratchet, so every line
373
+ * added to it is charged; this one is 365 lines and is charged nothing. The
374
+ * generator gets a one-line call, and the rule that a count is not an inventory
375
+ * — no row, no per-stub link, nothing for the deleted index tables to grow back
376
+ * from — is enforced in one place instead of two.
377
+ *
378
+ * Failure-tolerant by construction: a tree with no `agents/roadmaps/stubs/`
379
+ * yields `''` rather than throwing. This runs in consumer installs that carry no
380
+ * stub directory at all, so a throwing read here would break their dashboard.
381
+ */
382
+ export function headerFragment(stubsDir: string, today?: string): string {
383
+ let overdue = 0;
384
+ let decisions = 0;
385
+ try {
386
+ const c = counts(scan_dir(stubsDir, today ?? new Date().toISOString().slice(0, 10)));
387
+ overdue = c.overdue;
388
+ decisions = c.owner_decisions;
389
+ } catch {
390
+ return '';
391
+ }
392
+ if (overdue === 0 && decisions === 0) {
393
+ return '';
394
+ }
395
+ return (
396
+ ` · **${overdue}** overdue stub${overdue !== 1 ? 's' : ''}` +
397
+ `, **${decisions}** owner decision${decisions !== 1 ? 's' : ''}` +
398
+ ' → `agent-config stubs:due`'
399
+ );
400
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Ticket bundles, read from `agents/tickets/_registry.yml` for the dashboard.
3
+ *
4
+ * Extracted from `update_roadmap_progress.ts` and imported back, so behaviour is
5
+ * unchanged. The move is mechanical: that file sits above the 1500-line ceiling
6
+ * `check_source_size_budget` charges, and a run that adds lines there pays for
7
+ * them by extraction rather than by raising a baseline.
8
+ */
9
+ import { createRequire } from 'node:module';
10
+ import * as fs from 'node:fs';
11
+ import * as path from 'node:path';
12
+
13
+ import type * as YamlModule from 'yaml';
14
+
15
+ const _require = createRequire(import.meta.url);
16
+
17
+ /** Local copy: the parent keeps its own, and one tiny predicate is cheaper than
18
+ * an export cycle between two scripts in the same directory. */
19
+ function _isDir(p: string): boolean {
20
+ try {
21
+ return fs.statSync(p).isDirectory();
22
+ } catch {
23
+ return false;
24
+ }
25
+ }
26
+
27
+ export interface Bundle {
28
+ slug: string;
29
+ tickets: number;
30
+ status: string;
31
+ roadmap: string;
32
+ }
33
+
34
+ export function collect_bundles(repo_root: string): Bundle[] {
35
+ const reg = path.join(repo_root, 'agents', 'tickets', '_registry.yml');
36
+ if (!fs.existsSync(reg)) {
37
+ return [];
38
+ }
39
+ let YAML: typeof YamlModule;
40
+ try {
41
+ YAML = _require('yaml') as typeof YamlModule;
42
+ } catch {
43
+ return [];
44
+ }
45
+ let data: unknown;
46
+ try {
47
+ // yaml.safe_load(...) or {} — PyYAML 1.1 semantics; graceful on malformed.
48
+ data = YAML.parse(fs.readFileSync(reg, { encoding: 'utf-8' }), { version: '1.1' }) ?? {};
49
+ } catch {
50
+ return [];
51
+ }
52
+ const out: Bundle[] = [];
53
+ const bundles =
54
+ data && typeof data === 'object' && !Array.isArray(data)
55
+ ? ((data as Record<string, unknown>)['bundles'] ?? null)
56
+ : null;
57
+ const bundleMap =
58
+ bundles && typeof bundles === 'object' && !Array.isArray(bundles)
59
+ ? (bundles as Record<string, unknown>)
60
+ : {};
61
+ for (const slug of Object.keys(bundleMap).sort()) {
62
+ const metaRaw = bundleMap[slug];
63
+ const meta =
64
+ metaRaw && typeof metaRaw === 'object' && !Array.isArray(metaRaw)
65
+ ? (metaRaw as Record<string, unknown>)
66
+ : {};
67
+ const bdir = path.join(repo_root, 'agents', 'tickets', slug);
68
+ let n = 0;
69
+ if (_isDir(bdir)) {
70
+ try {
71
+ n = fs.readdirSync(bdir).filter((f) => f.startsWith('T-') && f.endsWith('.md')).length;
72
+ } catch {
73
+ n = 0;
74
+ }
75
+ }
76
+ out.push({
77
+ slug,
78
+ tickets: n,
79
+ status: (meta['status'] as string) ?? '?',
80
+ roadmap: (meta['source_roadmap'] as string) ?? '',
81
+ });
82
+ }
83
+ return out;
84
+ }
@@ -71,6 +71,8 @@ import {
71
71
  type DashboardMode,
72
72
  } from './dashboard_mode.js';
73
73
  import type * as YamlModule from 'yaml';
74
+ import { headerFragment as stubHeaderFragment } from './stubs_due.js';
75
+ import { reportGuardedBaselines } from './guarded_baseline.js'; // third step state; contract lives there
74
76
 
75
77
  const _HERE = fileURLToPath(import.meta.url);
76
78
  const _require = createRequire(import.meta.url);
@@ -995,6 +997,8 @@ function render(roadmaps: RoadmapStats[], bundles: Bundle[] | null, roadmap_root
995
997
  ? `, **${user_open_blockers}** need you → \`agent-config gates\``
996
998
  : '')
997
999
  : '') +
1000
+ // Two integers, never a row — see `stubs_due.headerFragment`.
1001
+ stubHeaderFragment(path.join(roadmap_root, 'stubs')) +
998
1002
  '\n';
999
1003
  lines.push(
1000
1004
  // Honest provenance (road-to-roadmap-archival-robustness, gap C): name a
@@ -1362,8 +1366,8 @@ function main(argv?: readonly string[]): number {
1362
1366
  return 1;
1363
1367
  }
1364
1368
  }
1365
- const roadmaps = collect(roadmap_root);
1366
- const new_text = render(roadmaps, collect_bundles(repo_root), roadmap_root);
1369
+ const roadmaps = collect(roadmap_root), guarded = reportGuardedBaselines(roadmaps, repo_root);
1370
+ const new_text = render(roadmaps, collect_bundles(repo_root), roadmap_root) + guarded.section;
1367
1371
  const complete = unarchived_complete(roadmaps);
1368
1372
  const pending = pending_iron_law_3(roadmaps);
1369
1373
  const gated = merge_gated_pending(roadmaps);
@@ -1395,7 +1399,7 @@ function main(argv?: readonly string[]): number {
1395
1399
  });
1396
1400
  if (r.stderr) process.stderr.write(r.stderr);
1397
1401
  if (r.stdout) process.stdout.write(r.stdout);
1398
- return r.rc;
1402
+ return guarded.problems > 0 ? 1 : r.rc;
1399
1403
  }
1400
1404
  fs.writeFileSync(target, new_text, { encoding: 'utf-8' });
1401
1405
  process.stdout.write(
@@ -1431,7 +1435,7 @@ function main(argv?: readonly string[]): number {
1431
1435
  if (gated.length) {
1432
1436
  _warn_merge_gated();
1433
1437
  }
1434
- return 0;
1438
+ return guarded.problems > 0 ? 1 : 0;
1435
1439
  }
1436
1440
 
1437
1441
  function _isCliEntry(): boolean {
@@ -28,16 +28,29 @@ adapters — not a second image-gen stack.
28
28
 
29
29
  ## When to use
30
30
 
31
- - User asks to generate a banner, social card, header image, or CIP (corporate identity) element.
31
+ - User asks to generate a banner, social card, header image, **platform profile
32
+ or cover image** (a LinkedIn cover, an X header, a YouTube channel art), or a
33
+ CIP (corporate identity) element.
32
34
  - Branded asset production where palette, typography, or voice must stay consistent.
33
35
  - When brand tokens are available and should drive the visual output.
34
36
  - When a brief alone (no tokens) still needs a governance-aware image output.
35
37
 
36
38
  ## Procedure
37
39
 
38
- 1. **Identify asset type and spec** — determine format (banner, social card, CIP element),
39
- output dimensions (e.g. 1200×630 for Open Graph, 1080×1080 for square social),
40
- and target channel (web, print, social platform).
40
+ 1. **Identify asset type and spec** — determine format (banner, social card,
41
+ platform profile/cover image, CIP element), output dimensions (e.g. 1200×630
42
+ for Open Graph, 1080×1080 for square social), and target channel (web, print,
43
+ social platform).
44
+
45
+ **A platform cover is a dimension constraint, not a new asset class**, and it
46
+ is the one case where guessing the number is the whole failure: a cover
47
+ rendered at the wrong aspect ratio is cropped by the platform, so the brand
48
+ marks land outside the visible area and the asset is unusable rather than
49
+ merely off-brand. Take the required dimensions from the platform's own
50
+ current spec at generation time — never from memory, and never from a number
51
+ written here, because these change without notice. If the spec cannot be
52
+ established, say so and ask rather than emitting an asset that will be
53
+ cropped.
41
54
  2. **Inject brand tokens when present** — if `pack-brand` is installed, load `.tokens.json`
42
55
  (colors, typography, voice). Feed hex values, font names, and tone keywords directly
43
56
  into the prompt. Without tokens, derive palette and type from the brief itself;
@@ -35,6 +35,23 @@ Method skill. Inventories current brand expression across touchpoints and flags
35
35
 
36
36
  1. **Gather the source of truth.** Collect the consumer brand's defined tokens (palette, type scale, logo rules), voice profile, and strategy doc if they exist. Consumer brand definition is authoritative; corpus defaults are gap-fill only.
37
37
  2. **Inventory current expression per touchpoint.** Cover logo usage, colour palette, typography, voice/copy tone, imagery style, and iconography across the relevant surfaces (site, app, decks, marketing, docs).
38
+
39
+ **Personal and company profile surfaces, including LinkedIn, X, and GitHub
40
+ organization profiles, are deliberately excluded regardless of whether their
41
+ content is fetched, pasted, or supplied as a file, pending a written
42
+ public-profile-field privacy floor defining what may be processed.**
43
+
44
+ Recorded so the next reader does not re-derive the gap, which has already
45
+ happened once. The exclusion is about **handling**, not retrieval: a pasted
46
+ profile is mechanically a different thing from a network fetch, but the
47
+ missing artefact is a field-level classification saying which profile fields
48
+ are brand surface (logo, palette, bio messaging) and which are PII-adjacent
49
+ (employment history, contributor names, location). A profile's About text
50
+ carries both in one field. Without that classification the skill cannot
51
+ distinguish them, and no test can assert that it did. AI council 2/2,
52
+ 2026-08-25. Include user-supplied profile inputs once a written, testable
53
+ field-level privacy floor exists; include fetched inputs only after both that
54
+ floor and a host-agent fetch contract exist.
38
55
  3. **UI surface.** Invoke `existing-ui-audit` for UI component inventory. Do not re-implement it here — take its output as an input to this audit.
39
56
  4. **Compare observed vs. defined.** For each touchpoint value, check it against the matching token or voice rule.
40
57
  5. **Classify each finding.** Three buckets: `on-brand` (matches the defined token), `drift` (observed value diverges from the token), `undefined` (no token exists to audit against — this is a governance gap, not automatically wrong).
@@ -42,6 +59,22 @@ Method skill. Inventories current brand expression across touchpoints and flags
42
59
  7. **Verify completeness.** Confirm every inventoried touchpoint is classified (`on-brand` / `drift` / `undefined`) — the audit is complete only when the classified count equals the inventoried count, and `existing-ui-audit` has run for every in-scope UI surface. Ensure each drift finding cites BOTH the defined value and the observed value; a finding missing either side is not yet verified.
43
60
  8. **Output the findings list** (see Output format). Do not redesign or author replacements — hand drift findings to `brand-identity` or `brand-strategy`.
44
61
 
62
+ ## Two constraints on platform-specific guidance
63
+
64
+ Both are constraints on what this skill may assert, not machinery, and neither
65
+ is a registry.
66
+
67
+ - **Any platform-specific guidance carries a source tier and a review date.**
68
+ Platform conventions — an image aspect ratio, a character limit, where a
69
+ profile crops a banner — change without notice, so a number stated here
70
+ without a date and a source is a claim that quietly stops being true. Tier it
71
+ (`platform-doc` / `observed` / `inferred`) and date it, or take it from the
72
+ platform's own current spec at audit time instead of stating it.
73
+ - **No engagement metric is stated as fact.** Reach, impression and
74
+ best-time-to-post figures are platform- and account-specific and are not
75
+ auditable from a brand token. Where such a figure is load-bearing to a
76
+ finding, attribute it; never assert it as a general truth.
77
+
45
78
  ## Output format
46
79
 
47
80
  1. **Source-of-truth summary** — what brand tokens, voice rules, and strategy exist and where they were found (or "none defined" if absent).
@@ -77,6 +77,63 @@ Every answer built with this skill MUST:
77
77
  That is the engine being honest, not broken — do not "resolve" them yourself
78
78
  by guessing.
79
79
 
80
+ ## Measured twice, and it has not won (v2, 2026-08-29)
81
+
82
+ Pre-registered, published whichever way it landed:
83
+ `internal/bench/reports/code-graph-vs-grep-inrepo-v2-2026-08-29.md`. The native
84
+ engine scored against disciplined `git grep` over three in-repo TypeScript
85
+ roots, 19 questions, per-class bars fixed before the run and unchanged from v1.
86
+
87
+ | Class | grep R | graph R | Δ pp | grep P | graph P | verdict |
88
+ |---|---|---|---|---|---|---|
89
+ | `callers` | 1.000 | 1.000 | +0.0 | 0.611 | 0.667 | TIE |
90
+ | `transitive-impact` | 0.611 | 0.500 | −11.1 | 1.000 | 0.667 | NULL |
91
+ | `path-between` | 0.917 | **1.000** | +8.3 | 0.778 | **1.000** | TIE |
92
+ | `references` | 1.000 | 0.333 | −66.7 | 0.833 | 0.333 | NULL |
93
+
94
+ **Zero classes met the win bar.** On `path-between` the graph is exact and is the
95
+ only class where it out-precises grep; it still ties, because the delta is +8.3 pp
96
+ against a +10 pp bar that was fixed before the run.
97
+
98
+ **The v1 run of 2026-08-28 published a false root cause, corrected 2026-08-29.**
99
+ It reported `path-between` as `VOID` because *"both arms measured nothing"*. Only
100
+ the grep arm did. The graph answered all three questions and v1's scorer discarded
101
+ the answer — it compared each returned symbol against the whole probe string
102
+ `"cmdBuild -> getParser"`. v1 also never invoked the shipped `path <a> <b>` verb,
103
+ and counted unresolved `symbol:` pseudo-nodes as files, which is the sole reason
104
+ its `callers` verdict was NULL with recall tied. v1's numbers are not retro-edited
105
+ — they were faithful to v1's own registration — and v1's report now carries the
106
+ correction. Do not quote a `path-between` delta near +89 pp: that figure comes
107
+ from repairing the graph arm and leaving grep on the broken probe.
108
+
109
+ **The rule's own wording was corrected by this result.** `external-code-graph-interop`
110
+ used to open by saying a committed index answers "far more precisely than a fresh
111
+ `grep`". That was never measured, and when it was, it was false for the native
112
+ engine on this repository's own code. The rule now gives the reasons that survive
113
+ measurement — an index that exists is already built and structured, so it is the
114
+ cheap first question — and drops the precision claim its own benchmark refuted.
115
+
116
+ **No class is graph-first.** Query the index first because an index that already
117
+ exists is cheap to ask and its answer is structured — not because it answers
118
+ better. When it returns nothing, that is the common case, and grep remains the
119
+ arm to fall back to rather than a grudging afterthought.
120
+
121
+ The sentence that stood here — *"the arm that won every valid class on this
122
+ corpus"* — is withdrawn. It is the framing v1's own report forbids: that report
123
+ says the defensible statement is *"zero classes met the pre-registered win
124
+ criterion"*, **not** that grep proved superior. It was also false on its own
125
+ terms under v2: grep wins two classes, ties two, and is out-precised on both
126
+ ties.
127
+
128
+ Scope, stated so this table is not over-read: it measured the **native** engine
129
+ on **this repository's TypeScript**, with a corpus of 19 questions. It is not
130
+ comparable to the 2026-07-28 external-corpus run, it is not comparable to v1
131
+ either (corpus, arm-B verb set and scorer all moved), and it says nothing about a
132
+ consumer-shipped SCIP index. Literal-string probes are reported as a separate
133
+ `capability-boundary` class with no floor derived from them: a symbol index
134
+ cannot answer them at all, which is where grep stays necessary rather than a
135
+ defect in the engine.
136
+
80
137
  ## Do NOT
81
138
 
82
139
  - Do NOT rebuild a **fresh** consumer-shipped index — query it (interop