@event4u/agent-config 3.3.0 → 4.2.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 (561) hide show
  1. package/.agent-src/README.md +2 -2
  2. package/.agent-src/commands/agent-handoff.md +31 -2
  3. package/.agent-src/commands/agent-status.md +5 -5
  4. package/.agent-src/commands/agents/audit.md +8 -8
  5. package/.agent-src/commands/agents/init.md +25 -1
  6. package/.agent-src/commands/agents/optimize.md +3 -3
  7. package/.agent-src/commands/agents/user.md +1 -1
  8. package/.agent-src/commands/agents.md +1 -1
  9. package/.agent-src/commands/analyze-reference-repo.md +1 -1
  10. package/.agent-src/commands/check-current-md.md +8 -8
  11. package/.agent-src/commands/{compress.md → condense.md} +55 -55
  12. package/.agent-src/commands/context/create.md +7 -4
  13. package/.agent-src/commands/context/refactor.md +3 -1
  14. package/.agent-src/commands/feature/dev.md +1 -1
  15. package/.agent-src/commands/feature/explore.md +1 -1
  16. package/.agent-src/commands/feature/plan.md +10 -8
  17. package/.agent-src/commands/feature/refactor.md +3 -1
  18. package/.agent-src/commands/feature/roadmap.md +7 -4
  19. package/.agent-src/commands/fix/portability.md +3 -3
  20. package/.agent-src/commands/fix/refs.md +4 -4
  21. package/.agent-src/commands/ghostwriter.md +2 -2
  22. package/.agent-src/commands/memory/learn-low-impact.md +3 -3
  23. package/.agent-src/commands/module/explore.md +34 -8
  24. package/.agent-src/commands/optimize/agents-dir.md +9 -7
  25. package/.agent-src/commands/optimize/augmentignore.md +2 -2
  26. package/.agent-src/commands/optimize/skills.md +9 -9
  27. package/.agent-src/commands/post-as.md +1 -1
  28. package/.agent-src/commands/project-analyze.md +2 -2
  29. package/.agent-src/commands/project-health.md +3 -2
  30. package/.agent-src/commands/research/deep.md +1 -1
  31. package/.agent-src/commands/research/report.md +1 -1
  32. package/.agent-src/commands/research.md +1 -1
  33. package/.agent-src/commands/roadmap/ai-council.md +1 -1
  34. package/.agent-src/commands/roadmap/create.md +9 -4
  35. package/.agent-src/commands/rule-compliance-audit.md +1 -1
  36. package/.agent-src/commands/upstream-contribute.md +14 -14
  37. package/.agent-src/commands/video/from-script.md +1 -1
  38. package/.agent-src/commands/video/scene.md +1 -1
  39. package/.agent-src/commands/video/stitch.md +1 -1
  40. package/.agent-src/commands/video/storyboard.md +1 -1
  41. package/.agent-src/commands/video.md +1 -1
  42. package/.agent-src/contexts/augment-infrastructure.md +1 -1
  43. package/.agent-src/contexts/authority/commit-mechanics.md +15 -0
  44. package/.agent-src/contexts/authority/kernel-rule-edits.md +3 -3
  45. package/.agent-src/contexts/authority/scope-mechanics.md +1 -1
  46. package/.agent-src/contexts/communication/rules-auto/augment-source-of-truth-mechanics.md +28 -28
  47. package/.agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +4 -4
  48. package/.agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +2 -2
  49. package/.agent-src/contexts/contracts/artifact-engagement-flow.md +6 -6
  50. package/.agent-src/contexts/contracts/command-suggestion-flow.md +3 -3
  51. package/.agent-src/contexts/contracts/emergency-triage-block.md +4 -4
  52. package/.agent-src/contexts/contracts/frugality-charter.md +3 -3
  53. package/.agent-src/contexts/documentation-hierarchy.md +14 -7
  54. package/.agent-src/contexts/execution/autonomy-examples.md +1 -1
  55. package/.agent-src/contexts/execution/cheap-question-mechanics.md +39 -2
  56. package/.agent-src/contexts/execution/roadmap-process-loop.md +28 -5
  57. package/.agent-src/contexts/override-system.md +5 -5
  58. package/.agent-src/ghostwriter/fictional-fixture-v1.md +1 -1
  59. package/.agent-src/personas/advisors/first-principles.md +1 -1
  60. package/.agent-src/personas/hollywood-director.md +1 -1
  61. package/.agent-src/rules/architecture.md +5 -1
  62. package/.agent-src/rules/augment-edit-discipline.md +5 -5
  63. package/.agent-src/rules/augment-source-of-truth.md +15 -15
  64. package/.agent-src/rules/commit-conventions.md +1 -1
  65. package/.agent-src/rules/commit-policy.md +10 -0
  66. package/.agent-src/rules/domain-adoption-policy.md +3 -3
  67. package/.agent-src/rules/fast-path-marker-visibility.md +3 -3
  68. package/.agent-src/rules/finance-safety-floor.md +1 -1
  69. package/.agent-src/rules/framework-neutrality-in-generic-skills.md +8 -8
  70. package/.agent-src/rules/git-history-discipline.md +1 -1
  71. package/.agent-src/rules/improve-before-implement.md +2 -2
  72. package/.agent-src/rules/language-and-tone.md +2 -2
  73. package/.agent-src/rules/media-governance-routing.md +5 -5
  74. package/.agent-src/rules/no-attribution-footers.md +1 -0
  75. package/.agent-src/rules/no-cheap-questions.md +3 -0
  76. package/.agent-src/rules/no-decorative-emojis-in-git-surfaces.md +111 -0
  77. package/.agent-src/rules/no-pr-progress-comments.md +118 -0
  78. package/.agent-src/rules/no-roadmap-references.md +3 -3
  79. package/.agent-src/rules/non-destructive-by-default.md +1 -1
  80. package/.agent-src/rules/persona-governance.md +3 -3
  81. package/.agent-src/rules/preservation-guard.md +15 -15
  82. package/.agent-src/rules/roadmap-ci-steps-policy.md +7 -3
  83. package/.agent-src/rules/rule-type-governance.md +1 -1
  84. package/.agent-src/rules/skill-quality.md +1 -1
  85. package/.agent-src/rules/{caveman-speak.md → telegraph-speak.md} +15 -15
  86. package/.agent-src/rules/token-optimizer-maintenance.md +6 -6
  87. package/.agent-src/skills/agent-docs-writing/SKILL.md +17 -11
  88. package/.agent-src/skills/agents-md-thin-root/SKILL.md +9 -9
  89. package/.agent-src/skills/check-refs/SKILL.md +2 -2
  90. package/.agent-src/skills/code-refactoring/SKILL.md +2 -2
  91. package/.agent-src/skills/command-writing/SKILL.md +19 -19
  92. package/.agent-src/skills/comp-banding/SKILL.md +1 -1
  93. package/.agent-src/skills/condense-memory/SKILL.md +131 -0
  94. package/.agent-src/skills/context-authoring/SKILL.md +2 -2
  95. package/.agent-src/skills/context-document/SKILL.md +5 -3
  96. package/.agent-src/skills/copilot-agents-optimization/SKILL.md +3 -3
  97. package/.agent-src/skills/description-assist/SKILL.md +2 -2
  98. package/.agent-src/skills/git-workflow/SKILL.md +1 -1
  99. package/.agent-src/skills/guideline-writing/SKILL.md +5 -5
  100. package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +4 -4
  101. package/.agent-src/skills/lint-skills/SKILL.md +3 -3
  102. package/.agent-src/skills/md-language-check/SKILL.md +2 -2
  103. package/.agent-src/skills/module-detect-on-the-fly/SKILL.md +138 -0
  104. package/.agent-src/skills/module-management/SKILL.md +166 -94
  105. package/.agent-src/skills/override-management/SKILL.md +1 -1
  106. package/.agent-src/skills/persona-writing/SKILL.md +5 -5
  107. package/.agent-src/skills/positioning-strategy/SKILL.md +1 -1
  108. package/.agent-src/skills/project-docs/SKILL.md +6 -4
  109. package/.agent-src/skills/readme-reviewer/SKILL.md +2 -2
  110. package/.agent-src/skills/roadmap-management/SKILL.md +13 -1
  111. package/.agent-src/skills/roadmap-writing/SKILL.md +4 -2
  112. package/.agent-src/skills/rule-refactor/SKILL.md +5 -5
  113. package/.agent-src/skills/rule-writing/SKILL.md +18 -18
  114. package/.agent-src/skills/script-writing/SKILL.md +1 -1
  115. package/.agent-src/skills/skill-improvement-pipeline/SKILL.md +6 -6
  116. package/.agent-src/skills/skill-management/SKILL.md +21 -21
  117. package/.agent-src/skills/skill-reviewer/SKILL.md +2 -2
  118. package/.agent-src/skills/skill-writing/SKILL.md +8 -8
  119. package/.agent-src/skills/skill-writing/evals/triggers.json +1 -1
  120. package/.agent-src/skills/token-optimizer/SKILL.md +4 -4
  121. package/.agent-src/skills/unit-economics-modeling/SKILL.md +1 -1
  122. package/.agent-src/skills/upstream-contribute/SKILL.md +17 -17
  123. package/.agent-src/templates/AGENTS.md +1 -0
  124. package/.agent-src/templates/agent-settings.md +24 -13
  125. package/.agent-src/templates/agents/agent-project-settings.example.yml +61 -2
  126. package/.agent-src/templates/command.md +5 -5
  127. package/.agent-src/templates/contexts.md +1 -1
  128. package/.agent-src/templates/copilot-instructions.md +8 -8
  129. package/.agent-src/templates/features.md +1 -1
  130. package/.agent-src/templates/hooks/pre-commit-frontmatter +2 -2
  131. package/.agent-src/templates/hooks/pre-commit-roadmap-progress +3 -3
  132. package/.agent-src/templates/persona.md +2 -2
  133. package/.agent-src/templates/roadmaps.md +1 -1
  134. package/.agent-src/templates/rule.md +13 -13
  135. package/.agent-src/templates/scripts/memory_lookup.py +1 -1
  136. package/.agent-src/templates/scripts/memory_status.py +2 -2
  137. package/.agent-src/templates/scripts/work_engine/_lib/agent_settings.py +195 -1
  138. package/.agent-src/templates/scripts/work_engine/orchestration.py +1 -1
  139. package/.agent-src/templates/skill-archive-note.md +5 -5
  140. package/.agent-src/templates/skill.md +1 -1
  141. package/.claude-plugin/marketplace.json +4 -4
  142. package/AGENTS.md +16 -17
  143. package/CHANGELOG.md +216 -3
  144. package/CONTRIBUTING.md +31 -12
  145. package/README.md +21 -12
  146. package/config/agent-settings.template.yml +22 -2
  147. package/config/discovery/unassigned-artefacts.yml +24 -24
  148. package/config/profiles/full.ini +1 -1
  149. package/dist/cli/agent-config.js +52 -3
  150. package/dist/cli/agent-config.js.map +1 -1
  151. package/dist/cli/commands/uiServe.js +9 -0
  152. package/dist/cli/commands/uiServe.js.map +1 -1
  153. package/dist/cli/registry.js +2 -1
  154. package/dist/cli/registry.js.map +1 -1
  155. package/dist/discovery/deprecation-report.md +1 -1
  156. package/dist/discovery/discovery-manifest.json +649 -606
  157. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  158. package/dist/discovery/discovery-manifest.summary.md +4 -4
  159. package/dist/discovery/orphan-report.md +1 -1
  160. package/dist/discovery/packs.json +439 -437
  161. package/dist/discovery/trust-report.md +5 -5
  162. package/dist/discovery/workspaces.json +450 -448
  163. package/dist/install/atomic.js +92 -0
  164. package/dist/install/atomic.js.map +1 -0
  165. package/dist/install/conflict.js +196 -0
  166. package/dist/install/conflict.js.map +1 -0
  167. package/dist/install/detect.js +218 -0
  168. package/dist/install/detect.js.map +1 -0
  169. package/dist/install/paths.js +82 -0
  170. package/dist/install/paths.js.map +1 -0
  171. package/dist/install/plan.js +157 -0
  172. package/dist/install/plan.js.map +1 -0
  173. package/dist/install/txlog.js +140 -0
  174. package/dist/install/txlog.js.map +1 -0
  175. package/dist/install/types.js +19 -0
  176. package/dist/install/types.js.map +1 -0
  177. package/dist/install/wizard-plan.js +184 -0
  178. package/dist/install/wizard-plan.js.map +1 -0
  179. package/dist/mcp/registry-manifest.json +4 -4
  180. package/dist/router.json +67 -19
  181. package/dist/server/app.js +6 -0
  182. package/dist/server/app.js.map +1 -1
  183. package/dist/server/routes/install.js +358 -0
  184. package/dist/server/routes/install.js.map +1 -0
  185. package/dist/server/routes/wizard.js +468 -32
  186. package/dist/server/routes/wizard.js.map +1 -1
  187. package/dist/server/routes/workspace.js +396 -0
  188. package/dist/server/routes/workspace.js.map +1 -0
  189. package/dist/server/schemas/settings.js +5 -3
  190. package/dist/server/schemas/settings.js.map +1 -1
  191. package/dist/ui/assets/index-BDAhhpDV.js +40 -0
  192. package/dist/ui/assets/index-BDAhhpDV.js.map +1 -0
  193. package/dist/ui/assets/index-BXZILUxe.css +1 -0
  194. package/dist/ui/index.html +2 -2
  195. package/docs/MIGRATION.md +1 -1
  196. package/docs/adrs/cost/0001-hard-stop-hook.md +1 -1
  197. package/docs/adrs/router/0001-three-tier-routing.md +4 -4
  198. package/docs/adrs/schema/0001-json-schema-frontmatter.md +1 -1
  199. package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +4 -4
  200. package/docs/adrs/{caveman → telegraph}/0001-default-off-until-bench.md +9 -9
  201. package/docs/adrs/telegraph/README.md +9 -0
  202. package/docs/architecture/augment-projection.md +4 -4
  203. package/docs/architecture/claude-bundle.md +1 -1
  204. package/docs/architecture/current-onboard-baseline.md +3 -3
  205. package/docs/architecture/multi-tool-projection.md +10 -10
  206. package/docs/architecture/source-projection.md +27 -27
  207. package/docs/architecture.md +19 -15
  208. package/docs/archive/CHANGELOG-pre-2.11.0.md +2 -2
  209. package/docs/archive/CHANGELOG-pre-2.15.0.md +3 -3
  210. package/docs/archive/CHANGELOG-pre-2.16.0.md +1 -1
  211. package/docs/archive/CHANGELOG-pre-2.2.0.md +70 -70
  212. package/docs/archive/CHANGELOG-pre-2.20.0.md +2 -2
  213. package/docs/archive/CHANGELOG-pre-2.25.0.md +15 -15
  214. package/docs/archive/CHANGELOG-pre-3.0.0.md +4 -4
  215. package/docs/archive/CHANGELOG-pre-3.1.0.md +2 -2
  216. package/docs/archive/CHANGELOG-pre-3.2.0.md +3 -3
  217. package/docs/benchmark.md +65 -0
  218. package/docs/benchmarks.md +16 -16
  219. package/docs/catalog.md +17 -15
  220. package/docs/contracts/CHANGELOG-conventions.md +1 -1
  221. package/docs/contracts/STABILITY.md +2 -2
  222. package/docs/contracts/adoption-signal-floor.md +110 -0
  223. package/docs/contracts/adr-chat-history-split.md +4 -4
  224. package/docs/contracts/adr-command-suggestion.md +4 -4
  225. package/docs/contracts/adr-gtm-context-spine.md +1 -1
  226. package/docs/contracts/adr-implement-ticket-runtime.md +4 -4
  227. package/docs/contracts/adr-install-user-type-axis.md +1 -1
  228. package/docs/contracts/adr-layout.md +2 -2
  229. package/docs/contracts/adr-product-ui-track.md +10 -10
  230. package/docs/contracts/adr-user-types-axis.md +3 -3
  231. package/docs/contracts/adr-wing4-context-spine.md +1 -1
  232. package/docs/contracts/agent-memory-contract.md +3 -3
  233. package/docs/contracts/agents-md-tech-stack.md +2 -2
  234. package/docs/contracts/ai-council-config.md +2 -2
  235. package/docs/contracts/at-rest-encryption.md +4 -0
  236. package/docs/contracts/audit-log-v1.md +1 -1
  237. package/docs/contracts/benchmark-ab-contract.md +101 -0
  238. package/docs/contracts/benchmark-corpus-spec.md +1 -1
  239. package/docs/contracts/branch-protection-policy.md +98 -0
  240. package/docs/contracts/ci-cost-budget.md +106 -0
  241. package/docs/contracts/ci-green-floor.md +141 -0
  242. package/docs/contracts/command-clusters.md +6 -6
  243. package/docs/contracts/command-surface-tiers.md +2 -2
  244. package/docs/contracts/command-taxonomy.md +2 -2
  245. package/docs/contracts/{compression-default-kill-criterion.md → condensation-default-kill-criterion.md} +29 -29
  246. package/docs/contracts/config-presets.md +1 -1
  247. package/docs/contracts/context-paths.md +3 -3
  248. package/docs/contracts/context-spine.md +1 -1
  249. package/docs/contracts/cost-summary-schema.md +12 -12
  250. package/docs/contracts/cross-wing-handoff.md +4 -4
  251. package/docs/contracts/daily-workspace.md +4 -0
  252. package/docs/contracts/decision-trace-v1.md +2 -2
  253. package/docs/contracts/discovery-manifest.md +4 -4
  254. package/docs/contracts/explain-modes.md +4 -0
  255. package/docs/contracts/file-ownership-matrix.json +3493 -3318
  256. package/docs/contracts/file-ownership-matrix.md +3 -3
  257. package/docs/contracts/frontmatter-contract.md +4 -4
  258. package/docs/contracts/ghostwriter-schema.md +3 -3
  259. package/docs/contracts/gui-wizard.md +110 -97
  260. package/docs/contracts/harness-expectations.md +123 -0
  261. package/docs/contracts/host-agent-protocol.md +4 -0
  262. package/docs/contracts/implement-ticket-flow.md +9 -9
  263. package/docs/contracts/install-scopes.md +77 -0
  264. package/docs/contracts/iron-law-overrides.txt +1 -1
  265. package/docs/contracts/kernel-membership.md +26 -26
  266. package/docs/contracts/linear-ai-rules-inclusion.md +1 -1
  267. package/docs/contracts/linter-structural-model.md +2 -2
  268. package/docs/contracts/load-context-budget-model.md +4 -4
  269. package/docs/contracts/load-context-schema.md +13 -13
  270. package/docs/contracts/local-analytics.md +4 -0
  271. package/docs/contracts/local-knowledge-ingestion.md +1 -1
  272. package/docs/contracts/mcp-cloud-scope.md +2 -2
  273. package/docs/contracts/mcp-phase-1-scope.md +3 -3
  274. package/docs/contracts/measurement-baseline.md +5 -5
  275. package/docs/contracts/mental-models.md +30 -30
  276. package/docs/contracts/multi-tool-projection-fidelity.md +4 -4
  277. package/docs/contracts/namespace.md +4 -4
  278. package/docs/contracts/orchestration-dsl-v1.md +7 -7
  279. package/docs/contracts/package-self-orientation.md +12 -12
  280. package/docs/contracts/persona-schema.md +6 -6
  281. package/docs/contracts/pilot/language-and-tone.md +1 -1
  282. package/docs/contracts/plain-language-surface.md +117 -0
  283. package/docs/contracts/profile-system.md +3 -3
  284. package/docs/contracts/release-pr-gating.md +103 -0
  285. package/docs/contracts/role-experience.md +3 -3
  286. package/docs/contracts/rule-classification.md +13 -13
  287. package/docs/contracts/rule-interactions.md +4 -4
  288. package/docs/contracts/rule-interactions.yml +30 -30
  289. package/docs/contracts/rule-priority-hierarchy.md +13 -13
  290. package/docs/contracts/rule-router.md +2 -2
  291. package/docs/contracts/safety-model.md +1 -1
  292. package/docs/contracts/skill-distribution-channels.md +61 -0
  293. package/docs/contracts/skill-domains.md +2 -2
  294. package/docs/contracts/smoke-contracts.md +5 -5
  295. package/docs/contracts/telegraph-telemetry.md +83 -0
  296. package/docs/contracts/trust-and-safety.md +5 -5
  297. package/docs/contracts/ui-stack-extension.md +7 -7
  298. package/docs/contracts/ui-track-flow.md +9 -9
  299. package/docs/contracts/user-type-schema.md +4 -4
  300. package/docs/contracts/workflow-packs.md +4 -4
  301. package/docs/contracts/workspace-documents.md +4 -0
  302. package/docs/customization.md +28 -8
  303. package/docs/decisions/ADR-001-kernel-swap-deferred.md +6 -6
  304. package/docs/decisions/ADR-002-kernel-bucket-overrides.md +11 -11
  305. package/docs/decisions/ADR-003-flat-cluster-subs-and-colon-syntax.md +2 -2
  306. package/docs/decisions/ADR-004-rule-governance-pruning.md +4 -4
  307. package/docs/decisions/ADR-005-subagent-worktrees.md +7 -7
  308. package/docs/decisions/ADR-011-domain-pack-readiness.md +6 -6
  309. package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +3 -3
  310. package/docs/decisions/ADR-015-discovery-manifest-contract.md +3 -3
  311. package/docs/decisions/ADR-017-monorepo-physical-layout.md +10 -10
  312. package/docs/decisions/ADR-018-trust-and-safety-layer.md +6 -6
  313. package/docs/decisions/ADR-019-router-json-dist-location.md +2 -2
  314. package/docs/decisions/ADR-020-global-only-consumer-scope.md +2 -2
  315. package/docs/decisions/ADR-021-deployment-shape.md +3 -3
  316. package/docs/decisions/ADR-022-daily-workspace-decomposition.md +1 -1
  317. package/docs/decisions/ADR-027-changelog-machine-vs-manual.md +2 -2
  318. package/docs/decisions/ADR-028-root-layout.md +7 -7
  319. package/docs/decisions/ADR-029-multi-workspace-deferred.md +2 -2
  320. package/docs/decisions/ADR-rule-kernel-and-router.md +5 -5
  321. package/docs/deploy/connector-setup.md +2 -2
  322. package/docs/deploy/policy-cookbook.md +2 -2
  323. package/docs/deploy/team-deployment-posture.md +20 -0
  324. package/docs/development.md +17 -17
  325. package/docs/distribution/registries.md +32 -0
  326. package/docs/distribution/registry-submissions.md +85 -0
  327. package/docs/distribution/telemetry-schema.md +1 -1
  328. package/docs/getting-started-by-role.md +45 -3
  329. package/docs/getting-started.md +2 -2
  330. package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
  331. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +1 -1
  332. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
  333. package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
  334. package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
  335. package/docs/guidelines/agent-infra/direct-answers-demos.md +1 -1
  336. package/docs/guidelines/agent-infra/first-principles.md +2 -2
  337. package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
  338. package/docs/guidelines/agent-infra/layered-settings.md +56 -2
  339. package/docs/guidelines/agent-infra/mental-models.md +3 -3
  340. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +2 -2
  341. package/docs/guidelines/agent-infra/rule-type-governance.md +1 -1
  342. package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
  343. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +2 -2
  344. package/docs/guidelines/agent-infra/six-hats.md +3 -3
  345. package/docs/guidelines/agent-infra/skill-quality-checklist.md +5 -5
  346. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  347. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +1 -1
  348. package/docs/guidelines/augment-portability-patterns.md +4 -4
  349. package/docs/guidelines/cross-role-handoff.md +2 -2
  350. package/docs/guidelines/php/php-coding-patterns.md +1 -1
  351. package/docs/guidelines/prompt-templates.md +6 -6
  352. package/docs/maintainers/dev-mode.md +1 -1
  353. package/docs/mcp.md +1 -1
  354. package/docs/parity/bench.json +3 -3
  355. package/docs/parity/ruflo.md +2 -2
  356. package/docs/profiles.md +11 -11
  357. package/docs/quality.md +11 -11
  358. package/docs/safety.md +3 -3
  359. package/docs/setup/mcp-client-config.md +1 -1
  360. package/docs/setup/mcp-r2-bootstrap.md +1 -1
  361. package/docs/setup/mcp-server-docker.md +3 -3
  362. package/docs/setup/per-ide/windsurf.md +1 -1
  363. package/docs/skills-catalog.md +8 -7
  364. package/docs/troubleshooting.md +1 -1
  365. package/docs/walkthroughs/daily-workspace-a11y.md +87 -0
  366. package/llms.txt +7 -6
  367. package/package.json +1 -1
  368. package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
  369. package/scripts/_archive/README.md +2 -2
  370. package/scripts/_archive/_backfill_skill_domains.py +3 -3
  371. package/scripts/_archive/_bootstrap_tier_frontmatter.py +3 -3
  372. package/scripts/_archive/_p43_bodies.py +10 -10
  373. package/scripts/_archive/{_p43_compress.py → _p43_condense.py} +5 -5
  374. package/scripts/_archive/_p4_migrate.py +7 -7
  375. package/scripts/_archive/_phase2_shim_helper.py +1 -1
  376. package/scripts/_archive/_pilot_council_question.py +5 -5
  377. package/scripts/_cli/explain_last/inputs.py +1 -1
  378. package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
  379. package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
  380. package/scripts/_lib/agent_settings.py +195 -1
  381. package/scripts/_lib/agent_src.py +19 -19
  382. package/scripts/_lib/bench_ab_cache.py +162 -0
  383. package/scripts/_lib/bench_ab_scoring.py +209 -0
  384. package/scripts/_lib/{bench_caveman.py → bench_telegraph.py} +21 -21
  385. package/scripts/_lib/{bench_caveman_report.py → bench_telegraph_report.py} +21 -21
  386. package/scripts/_lib/claude_desktop_bundler.py +5 -5
  387. package/scripts/_lib/module_detection.py +223 -0
  388. package/scripts/_lib/scope_guard.sh +162 -0
  389. package/scripts/_phase4_bucket.py +3 -3
  390. package/scripts/_pilot_measure.py +4 -4
  391. package/scripts/_tmp_scan_framework_leakage.py +1 -1
  392. package/scripts/adoption_report.py +195 -0
  393. package/scripts/adoption_snapshot.py +219 -0
  394. package/scripts/adoption_status.py +166 -0
  395. package/scripts/ai-video/lib/parse-blueprint.sh +1 -1
  396. package/scripts/ai_council/advisors.py +5 -5
  397. package/scripts/ai_council/compile_corpus.py +1 -1
  398. package/scripts/ai_council/one_off_archive/2026-05/_one_off_budget_v2_audit.py +3 -3
  399. package/scripts/ai_council/one_off_archive/2026-05/_one_off_context_layer_v1_review.py +2 -2
  400. package/scripts/ai_council/one_off_archive/2026-05/_one_off_inject_quiet_flag.py +1 -1
  401. package/scripts/ai_council/one_off_archive/2026-05/_one_off_measure_v2.sh +1 -1
  402. package/scripts/ai_council/one_off_archive/2026-05/_one_off_measure_verbosity.sh +1 -1
  403. package/scripts/ai_council/one_off_archive/2026-05/_one_off_nondestructive_inline_audit.py +3 -3
  404. package/scripts/ai_council/one_off_archive/2026-05/_one_off_per_task.sh +1 -1
  405. package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase6_trigger_jaccard.py +1 -1
  406. package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase_2a_budget_rebalance.py +6 -6
  407. package/scripts/ai_council/one_off_archive/2026-05/_one_off_rebalancing_audit.py +1 -1
  408. package/scripts/ai_council/one_off_archive/2026-05/_one_off_tier_retrofit.py +6 -6
  409. package/scripts/annotate_discovery.py +13 -13
  410. package/scripts/apply_modules_config.py +290 -0
  411. package/scripts/audit_adr_coverage.py +2 -2
  412. package/scripts/audit_auto_rules.py +2 -2
  413. package/scripts/audit_cloud_compatibility.py +3 -3
  414. package/scripts/audit_command_surface.py +9 -9
  415. package/scripts/audit_likelihood.py +2 -2
  416. package/scripts/audit_user_type_axis.py +2 -2
  417. package/scripts/bench_ab_cache_dispatch.py +68 -0
  418. package/scripts/bench_ab_clone.py +170 -0
  419. package/scripts/bench_ab_diff.py +227 -0
  420. package/scripts/bench_ab_integrity.py +143 -0
  421. package/scripts/bench_ab_run.py +235 -0
  422. package/scripts/bench_ab_task_runner.py +369 -0
  423. package/scripts/bench_ab_tracka_run.py +202 -0
  424. package/scripts/{bench_compress_memory.py → bench_condense_memory.py} +16 -16
  425. package/scripts/bench_run.py +33 -33
  426. package/scripts/bench_runner.py +2 -2
  427. package/scripts/bootstrap.sh +99 -0
  428. package/scripts/build_cloud_bundle.py +6 -6
  429. package/scripts/build_discovery_manifest.py +7 -7
  430. package/scripts/build_linear_digest.py +3 -3
  431. package/scripts/build_rule_trigger_matrix.py +8 -8
  432. package/scripts/chat_history.py +5 -5
  433. package/scripts/check_always_budget.py +11 -5
  434. package/scripts/check_augment_description_cap.py +3 -3
  435. package/scripts/check_cluster_patterns.py +2 -2
  436. package/scripts/check_command_count_messaging.py +3 -3
  437. package/scripts/{check_compression.py → check_condensation.py} +34 -34
  438. package/scripts/{check_compressed_paths.py → check_condensed_paths.py} +8 -8
  439. package/scripts/check_context_paths.py +7 -7
  440. package/scripts/check_council_layout.py +2 -2
  441. package/scripts/check_council_references.py +9 -9
  442. package/scripts/check_iron_law_prominence.py +2 -2
  443. package/scripts/check_kernel_rule_bundle.py +2 -2
  444. package/scripts/check_module_management_neutral.py +149 -0
  445. package/scripts/check_no_roadmap_refs.py +9 -9
  446. package/scripts/check_portability.py +3 -3
  447. package/scripts/check_public_catalog_links.py +4 -4
  448. package/scripts/check_references.py +7 -6
  449. package/scripts/check_release_pr_shape.py +112 -0
  450. package/scripts/check_reply_consistency.py +3 -3
  451. package/scripts/check_safety_floor_untouched.py +1 -1
  452. package/scripts/check_template_pin_drift.py +5 -5
  453. package/scripts/check_token_optimizer_freshness.py +3 -3
  454. package/scripts/ci_status.py +301 -0
  455. package/scripts/ci_time_ratio.py +1 -1
  456. package/scripts/cleanup_other_scope.sh +146 -0
  457. package/scripts/compile_router.py +10 -10
  458. package/scripts/{compress.py → condense.py} +64 -64
  459. package/scripts/condense.sh +18 -0
  460. package/scripts/{compress_memory.py → condense_memory.py} +33 -33
  461. package/scripts/config/presets.py +2 -2
  462. package/scripts/config/profiles.py +1 -1
  463. package/scripts/cost_by_conversation.py +3 -3
  464. package/scripts/cost_summary.py +7 -7
  465. package/scripts/count_token_optimizer_usage.sh +1 -1
  466. package/scripts/gen_discovery_baseline.py +5 -5
  467. package/scripts/generate_index.py +6 -6
  468. package/scripts/generate_ownership_matrix.py +10 -10
  469. package/scripts/generate_pack_manifests.py +1 -1
  470. package/scripts/ghostwriter_fixture_allowlist.txt +1 -1
  471. package/scripts/install +3 -3
  472. package/scripts/install-hooks.sh +6 -6
  473. package/scripts/install.py +273 -45
  474. package/scripts/install.sh +187 -1
  475. package/scripts/inventory_frontmatter.py +2 -2
  476. package/scripts/iron_law_sha.py +3 -3
  477. package/scripts/lint_agents_layout.py +14 -7
  478. package/scripts/lint_agents_md.py +4 -4
  479. package/scripts/lint_archived_skills.py +3 -3
  480. package/scripts/lint_artefact_frontmatter.py +2 -2
  481. package/scripts/lint_bench_ab.py +172 -0
  482. package/scripts/lint_bench_corpus.py +1 -1
  483. package/scripts/lint_command_tiers.py +5 -5
  484. package/scripts/lint_context_spine_usage.py +1 -1
  485. package/scripts/lint_framework_leakage.py +7 -7
  486. package/scripts/lint_framework_leakage_allowlist.json +152 -84
  487. package/scripts/lint_ghostwriter_source.py +3 -3
  488. package/scripts/lint_handoffs.py +1 -1
  489. package/scripts/lint_load_context.py +11 -11
  490. package/scripts/lint_media_policy_linkage.py +5 -5
  491. package/scripts/lint_namespace.py +1 -1
  492. package/scripts/lint_no_new_atomic_commands.py +2 -2
  493. package/scripts/lint_orchestration_dsl.py +1 -1
  494. package/scripts/lint_pack_boundaries.py +2 -2
  495. package/scripts/lint_persona_governance.py +4 -4
  496. package/scripts/lint_role_experiences.py +237 -0
  497. package/scripts/lint_rule_interactions.py +2 -2
  498. package/scripts/lint_rule_tiers.py +1 -1
  499. package/scripts/lint_trust_coherence.py +2 -2
  500. package/scripts/mcp_registry_submit.sh +187 -0
  501. package/scripts/mcp_server/tools.py +1 -1
  502. package/scripts/measure_frugality_savings.py +10 -10
  503. package/scripts/measure_patterns.py +1 -1
  504. package/scripts/measure_projection_bytes.py +5 -5
  505. package/scripts/measure_rule_budget.py +3 -3
  506. package/scripts/measure_skill_reduction.py +1 -1
  507. package/scripts/memory_lookup.py +1 -1
  508. package/scripts/memory_status.py +2 -2
  509. package/scripts/migrate_command_suggestions.py +3 -3
  510. package/scripts/mine_session.py +1 -1
  511. package/scripts/move_artefact.py +3 -3
  512. package/scripts/new_skill.py +2 -2
  513. package/scripts/pack_mcp_content.py +9 -9
  514. package/scripts/plan_physical_move.py +6 -6
  515. package/scripts/print_required_checks.py +196 -0
  516. package/scripts/probe_skill_registration.py +413 -0
  517. package/scripts/propose_modules_config.py +145 -0
  518. package/scripts/prototype_lint_contradictions.py +1 -1
  519. package/scripts/recruit_preflight.sh +152 -0
  520. package/scripts/refine_ticket_detect.py +3 -3
  521. package/scripts/release.py +20 -0
  522. package/scripts/render_benchmark_md.py +308 -0
  523. package/scripts/roadmap_progress_hook.py +1 -1
  524. package/scripts/run_skill_evals.py +2 -2
  525. package/scripts/runtime_registry.py +4 -4
  526. package/scripts/schemas/command.schema.json +4 -4
  527. package/scripts/schemas/rule.schema.json +5 -5
  528. package/scripts/schemas/skill.schema.json +3 -3
  529. package/scripts/schemas/user-type.schema.json +1 -1
  530. package/scripts/score_skill_selection.py +1 -1
  531. package/scripts/skill_collision_clusters.py +2 -2
  532. package/scripts/skill_linter.py +81 -81
  533. package/scripts/skill_overlap.py +5 -5
  534. package/scripts/skill_tools/audit_persona_coverage.py +2 -2
  535. package/scripts/skill_tools/audit_user_type_coverage.py +2 -2
  536. package/scripts/skill_tools/run_block_d_eval.py +1 -1
  537. package/scripts/skill_tools/score_skill_relevance.py +1 -1
  538. package/scripts/skill_tools/suggest_skill_for_task.py +1 -1
  539. package/scripts/skill_trigger_eval.py +3 -3
  540. package/scripts/smoke/kernel.sh +7 -1
  541. package/scripts/smoke/router.sh +5 -5
  542. package/scripts/smoke/skills.sh +1 -1
  543. package/scripts/smoke_quickstart.py +1 -1
  544. package/scripts/snapshot_agent_outputs.py +3 -3
  545. package/scripts/spotcheck_thin_root.py +1 -1
  546. package/scripts/{caveman_stats.py → telegraph_stats.py} +18 -18
  547. package/scripts/update_counts.py +1 -1
  548. package/scripts/validate_decision_engine.py +1 -1
  549. package/scripts/validate_frontmatter.py +1 -1
  550. package/scripts/validate_safe_paths.py +3 -3
  551. package/scripts/{validate_caveman_carveouts.py → validate_telegraph_carveouts.py} +7 -7
  552. package/scripts/verify_roadmap_closure.py +6 -6
  553. package/templates/consumer-settings/ONBOARDING.md +41 -0
  554. package/.agent-src/commands/install-via-agent.md +0 -129
  555. package/.agent-src/skills/compress-memory/SKILL.md +0 -131
  556. package/dist/ui/assets/index-D-DY1ywI.js +0 -35
  557. package/dist/ui/assets/index-D-DY1ywI.js.map +0 -1
  558. package/dist/ui/assets/index-Dqfhmg-d.css +0 -1
  559. package/docs/adrs/caveman/README.md +0 -9
  560. package/docs/contracts/caveman-telemetry.md +0 -83
  561. package/scripts/compress.sh +0 -18
@@ -18,10 +18,10 @@ const LEGACY_USER_MD_REL = '.agent-user.md';
18
18
  const LEGACY_SETTINGS_REL = '.agent-settings.yml';
19
19
  // Step count mirrors the UI's `WIZARD_STEPS` array in `src/ui/wizard/steps.ts`
20
20
  // and the chat-side `~/.claude/skills/onboard/SKILL.md`. Bump in lockstep.
21
- // Extended mode (road-to-global-only-install § Phase 1) prepends two
22
- // steps (ai-tools + packs) to ship the unified 9-step flow.
21
+ // Extended mode (road-to-global-only-install § Phase 1) prepends three
22
+ // steps (ai-tools + packs + modules) to ship the unified 10-step flow.
23
23
  const DEFAULT_TOTAL_STEPS = 7;
24
- const EXTENDED_TOTAL_STEPS = 9;
24
+ const EXTENDED_TOTAL_STEPS = 10;
25
25
  /**
26
26
  * Discovery-manifest path. Resolved from the package root the server
27
27
  * was booted with — same artefact the installer reads (ADR-015 locks
@@ -35,7 +35,7 @@ const wizardStateSchema = z.object({
35
35
  startedAt: z.string().nullable().default(null),
36
36
  });
37
37
  // road-to-global-only-install § Phase 1.5 — WizardApplyPayload shape.
38
- // Mirrors `schemas/wizard-apply-payload.schema.json`; the discriminator
38
+ // Mirrors `internal/schemas/wizard-apply-payload.schema.json`; the discriminator
39
39
  // (`schema_version`) selects the variant. Real schema validation lives
40
40
  // in install.py — the route only enforces the outer envelope so the
41
41
  // bridge spawn surface stays tight.
@@ -149,9 +149,136 @@ async function spawnInstaller(scriptPath, args) {
149
149
  });
150
150
  });
151
151
  }
152
+ /** SSE frame writer — one event per `data:` line, blank-line terminator. */
153
+ function writeFrame(reply, payload) {
154
+ reply.raw.write(`data: ${JSON.stringify(payload)}\n\n`);
155
+ }
156
+ function streamInstaller(scriptPath, args, onLine, signal) {
157
+ return new Promise((resolve, reject) => {
158
+ const child = spawn('python3', [scriptPath, ...args], {
159
+ stdio: ['ignore', 'pipe', 'pipe'],
160
+ env: { ...process.env, AGENT_CONFIG_NO_UPDATE_CHECK: '1' },
161
+ });
162
+ const onAbort = () => {
163
+ child.kill('SIGTERM');
164
+ };
165
+ if (signal !== undefined) {
166
+ if (signal.aborted)
167
+ onAbort();
168
+ else
169
+ signal.addEventListener('abort', onAbort, { once: true });
170
+ }
171
+ const stderrChunks = [];
172
+ let buf = '';
173
+ const handleLine = (line) => {
174
+ const trimmed = line.trim();
175
+ if (trimmed.length === 0)
176
+ return;
177
+ try {
178
+ onLine(JSON.parse(trimmed));
179
+ }
180
+ catch {
181
+ // Non-JSON stdout (defensive — real-apply runs with QUIET so
182
+ // only NDJSON reaches stdout). Drop it rather than corrupt the
183
+ // SSE stream.
184
+ }
185
+ };
186
+ child.stdout?.on('data', (chunk) => {
187
+ buf += chunk.toString('utf8');
188
+ let nl = buf.indexOf('\n');
189
+ while (nl !== -1) {
190
+ handleLine(buf.slice(0, nl));
191
+ buf = buf.slice(nl + 1);
192
+ nl = buf.indexOf('\n');
193
+ }
194
+ });
195
+ child.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
196
+ child.once('error', (err) => {
197
+ if (signal !== undefined)
198
+ signal.removeEventListener('abort', onAbort);
199
+ reject(err);
200
+ });
201
+ child.once('close', (code) => {
202
+ if (buf.trim().length > 0)
203
+ handleLine(buf);
204
+ if (signal !== undefined)
205
+ signal.removeEventListener('abort', onAbort);
206
+ resolve({ exitCode: code ?? 1, stderr: Buffer.concat(stderrChunks).toString('utf8') });
207
+ });
208
+ });
209
+ }
210
+ async function spawnBash(scriptPath, args) {
211
+ return new Promise((resolve, reject) => {
212
+ const child = spawn('bash', [scriptPath, ...args], {
213
+ stdio: ['ignore', 'pipe', 'pipe'],
214
+ env: { ...process.env, AGENT_CONFIG_NO_UPDATE_CHECK: '1' },
215
+ });
216
+ const stdoutChunks = [];
217
+ const stderrChunks = [];
218
+ child.stdout?.on('data', (chunk) => stdoutChunks.push(chunk));
219
+ child.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
220
+ child.once('error', reject);
221
+ child.once('close', (code) => {
222
+ resolve({
223
+ exitCode: code ?? 1,
224
+ stdout: Buffer.concat(stdoutChunks).toString('utf8'),
225
+ stderr: Buffer.concat(stderrChunks).toString('utf8'),
226
+ });
227
+ });
228
+ });
229
+ }
230
+ function parseScopeGuardOutput(stdout) {
231
+ const findings = [];
232
+ let overall = 'OK';
233
+ let countOk = 0;
234
+ let countWarn = 0;
235
+ let countDrift = 0;
236
+ for (const line of stdout.split('\n')) {
237
+ if (!line.trim())
238
+ continue;
239
+ const parts = line.split('\t');
240
+ if (parts[0] === 'SUMMARY') {
241
+ overall = parts[1] ?? 'OK';
242
+ countOk = Number.parseInt(parts[2] ?? '0', 10);
243
+ countWarn = Number.parseInt(parts[3] ?? '0', 10);
244
+ countDrift = Number.parseInt(parts[4] ?? '0', 10);
245
+ continue;
246
+ }
247
+ const [verdict, tool, otherScopePath, otherVersion, thisVersion] = parts;
248
+ if (verdict !== 'OK' && verdict !== 'WARN' && verdict !== 'DRIFT')
249
+ continue;
250
+ findings.push({
251
+ verdict: verdict,
252
+ tool: tool ?? '?',
253
+ otherScopePath: otherScopePath ?? '-',
254
+ otherVersion: otherVersion ?? '-',
255
+ thisVersion: thisVersion ?? '-',
256
+ });
257
+ }
258
+ return { overall, countOk, countWarn, countDrift, findings };
259
+ }
260
+ // road-to-configurable-modules § Phase E — wire shape of the
261
+ // `modulesConfig` field on `POST /api/v1/wizard/finish`. Matches the
262
+ // `proposed_block` JSON emitted by `propose_modules_config.py --json`
263
+ // so the wizard can round-trip the detection output untouched. Extra
264
+ // fields are rejected — the persistence helper has its own coercion
265
+ // for older payload shapes, but the wizard always sends the strict
266
+ // shape.
267
+ const modulesConfigSchema = z.object({
268
+ enabled: z.boolean(),
269
+ root_paths: z.array(z.string()),
270
+ namespace_template: z.string().optional(),
271
+ agent_folder: z.string().optional(),
272
+ skip_dirs: z.array(z.string()).optional(),
273
+ }).strict();
152
274
  export function wizardRoute(opts) {
153
275
  const extended = opts.extendedSteps === true;
154
276
  const totalSteps = opts.totalSteps ?? (extended ? EXTENDED_TOTAL_STEPS : DEFAULT_TOTAL_STEPS);
277
+ // Clamp the CLI-provided initial step to the active step range so a
278
+ // stale `--initial-step=99` cannot shove the UI past the last screen.
279
+ const rawInitial = opts.initialStep ?? 0;
280
+ const initialStep = Math.max(0, Math.min(totalSteps - 1, Math.trunc(rawInitial)));
281
+ const wizardMode = opts.wizardMode ?? null;
155
282
  const dryRun = opts.dryRun === true;
156
283
  const legacyReadRoot = opts.legacyReadRoot ?? null;
157
284
  const projectScopeRoot = opts.projectScopeRoot ?? null;
@@ -166,9 +293,21 @@ export function wizardRoute(opts) {
166
293
  // in-progress real run can be previewed.
167
294
  const existing = dryRun ? (memState ?? await readState(opts.writeRoot)) : await readState(opts.writeRoot);
168
295
  if (existing === null) {
169
- return { step: 0, totalSteps, partial: {}, startedAt: null, extendedSteps: extended };
296
+ return {
297
+ step: initialStep,
298
+ totalSteps,
299
+ partial: {},
300
+ startedAt: null,
301
+ extendedSteps: extended,
302
+ wizardMode,
303
+ };
170
304
  }
171
- return { ...existing, totalSteps: existing.totalSteps ?? totalSteps, extendedSteps: extended };
305
+ return {
306
+ ...existing,
307
+ totalSteps: existing.totalSteps ?? totalSteps,
308
+ extendedSteps: extended,
309
+ wizardMode,
310
+ };
172
311
  });
173
312
  // road-to-global-only-install § Phase 1.2 — Auto-detect endpoint.
174
313
  // Reads package signals from the maintainer's CWD (the consumer
@@ -183,6 +322,44 @@ export function wizardRoute(opts) {
183
322
  const signals = detectProjectSignals(root);
184
323
  return { root, signals };
185
324
  });
325
+ // road-to-configurable-modules § Phase E — Modules detect endpoint.
326
+ // Read-only scan: spawns `scripts/propose_modules_config.py --json`
327
+ // against the consumer project so the wizard's modules step can
328
+ // surface candidate root_paths + a prefilled `modules:` block.
329
+ // Same root-resolution rule as `/auto-detect` (legacyReadRoot ??
330
+ // cwd) — the consumer repo the maintainer is running the wizard
331
+ // against. Gated by extended-mode so the canonical 7-step flow
332
+ // stays clean.
333
+ app.get('/api/v1/modules/detect', async (_request, reply) => {
334
+ if (!extended) {
335
+ await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'extended-mode endpoint disabled' } });
336
+ return reply;
337
+ }
338
+ const root = legacyReadRoot ?? process.cwd();
339
+ const scriptPath = join(opts.packageRoot, 'scripts', 'propose_modules_config.py');
340
+ try {
341
+ const result = await spawnInstaller(scriptPath, ['--json', '--project', root]);
342
+ if (result.exitCode !== 0) {
343
+ await reply.code(500).send({
344
+ error: { code: 'DETECT_FAILED', message: result.stderr || 'module detect bridge exited non-zero', exitCode: result.exitCode },
345
+ });
346
+ return reply;
347
+ }
348
+ try {
349
+ return JSON.parse(result.stdout);
350
+ }
351
+ catch (err) {
352
+ const message = err instanceof Error ? err.message : 'invalid JSON from module detect bridge';
353
+ await reply.code(500).send({ error: { code: 'DETECT_PARSE_FAILED', message } });
354
+ return reply;
355
+ }
356
+ }
357
+ catch (err) {
358
+ const message = err instanceof Error ? err.message : 'module detect bridge failed';
359
+ await reply.code(500).send({ error: { code: 'DETECT_FAILED', message } });
360
+ return reply;
361
+ }
362
+ });
186
363
  // road-to-global-only-install § Phase 1.3 — Manifest endpoint.
187
364
  // Surfaces the locked discovery-manifest (ADR-015) so the UI can
188
365
  // render the supported AI IDs + every pack the manifest exposes.
@@ -202,6 +379,123 @@ export function wizardRoute(opts) {
202
379
  return reply;
203
380
  }
204
381
  });
382
+ // road-to-clean-skill-distribution-channels § Phase D Step 3 —
383
+ // harness-expectations endpoint. Returns the three classes the
384
+ // wizard's final review step renders after install completes.
385
+ // Content is static + sourced from docs/contracts/harness-expectations.md
386
+ // (the doc is the long form; this endpoint is the wizard-shaped
387
+ // short form so the UI does not have to parse markdown).
388
+ app.get('/api/v1/wizard/harness-expectations', async (_request, reply) => {
389
+ if (!extended) {
390
+ await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'extended-mode endpoint disabled' } });
391
+ return reply;
392
+ }
393
+ return {
394
+ contractPath: 'docs/contracts/harness-expectations.md',
395
+ classes: [
396
+ {
397
+ id: 'sibling-plugins',
398
+ title: 'Plugin-namespaced peer skills',
399
+ symptom: 'Skills appear under namespaces like codex:* or cc-gemini-plugin:*.',
400
+ cause: 'Sibling AI-tool plugins loaded by the harness; not owned by this package.',
401
+ action: 'Use the harness’s plugin-list command to identify the source.',
402
+ },
403
+ {
404
+ id: 'deferred-tools',
405
+ title: 'Tools deferred behind ToolSearch',
406
+ symptom: 'system-reminder mentions “deferred tools … available via ToolSearch”.',
407
+ cause: 'Harness defers schema load until needed to protect context budget.',
408
+ action: 'Run ToolSearch with select:<name> to load the schema before calling.',
409
+ },
410
+ {
411
+ id: 'duplicate-registration',
412
+ title: 'Duplicate skill registration',
413
+ symptom: 'Same skill name appears twice in the available-skills list.',
414
+ cause: 'Cross-scope install drift (~/.claude/skills/ + ./.claude/skills/ at different versions).',
415
+ action: 'Run `task probe:skills` — if findings show DUPLICATE/DRIFT, clean with `bash scripts/cleanup_other_scope.sh --confirm`.',
416
+ },
417
+ ],
418
+ triage: [
419
+ 'Run `task probe:skills` first — confirms or rules out class 3.',
420
+ 'If a vendor: prefix shows, check the harness’s plugin list.',
421
+ 'deferred-tools reminder = expected; the skill must call ToolSearch.',
422
+ ],
423
+ };
424
+ });
425
+ // road-to-clean-skill-distribution-channels § Phase C Step 6 —
426
+ // probe endpoint. Spawns scripts/probe_skill_registration.py with
427
+ // --format=json so the wizard's final step can surface DUPLICATE /
428
+ // DRIFT findings before the operator closes the install. Read-only.
429
+ app.get('/api/v1/wizard/probe', async (_request, reply) => {
430
+ if (!extended) {
431
+ await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'extended-mode endpoint disabled' } });
432
+ return reply;
433
+ }
434
+ const probePath = join(opts.packageRoot, 'scripts', 'probe_skill_registration.py');
435
+ if (!existsSync(probePath)) {
436
+ await reply.code(500).send({ error: { code: 'PROBE_MISSING', message: `probe script not found at ${probePath}` } });
437
+ return reply;
438
+ }
439
+ const projectRoot = legacyReadRoot ?? process.cwd();
440
+ try {
441
+ const result = await spawnInstaller(probePath, ['--project', projectRoot, '--format=json']);
442
+ // Default mode exits 0 regardless of findings; --strict (not
443
+ // passed here) is the only path with a non-zero exit.
444
+ if (result.exitCode !== 0) {
445
+ await reply.code(500).send({
446
+ error: { code: 'PROBE_FAILED', message: result.stderr || `probe exited ${result.exitCode}`, exitCode: result.exitCode },
447
+ });
448
+ return reply;
449
+ }
450
+ try {
451
+ return JSON.parse(result.stdout);
452
+ }
453
+ catch (err) {
454
+ const message = err instanceof Error ? err.message : 'invalid JSON from probe';
455
+ await reply.code(500).send({ error: { code: 'PROBE_PARSE_FAILED', message } });
456
+ return reply;
457
+ }
458
+ }
459
+ catch (err) {
460
+ const message = err instanceof Error ? err.message : 'probe failed to spawn';
461
+ await reply.code(500).send({ error: { code: 'PROBE_FAILED', message } });
462
+ return reply;
463
+ }
464
+ });
465
+ // road-to-clean-skill-distribution-channels § Phase B Step 4 —
466
+ // scope-guard endpoint. Spawns scripts/_lib/scope_guard.sh against
467
+ // the target project root and the user's $HOME, returns a
468
+ // structured verdict the wizard's first step renders before the
469
+ // operator picks an install scope. Read-only — no file writes.
470
+ app.get('/api/v1/wizard/scope-guard', async (_request, reply) => {
471
+ if (!extended) {
472
+ await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'extended-mode endpoint disabled' } });
473
+ return reply;
474
+ }
475
+ const guardPath = join(opts.packageRoot, 'scripts', '_lib', 'scope_guard.sh');
476
+ if (!existsSync(guardPath)) {
477
+ await reply.code(500).send({ error: { code: 'GUARD_MISSING', message: `scope_guard.sh not found at ${guardPath}` } });
478
+ return reply;
479
+ }
480
+ const projectRoot = legacyReadRoot ?? process.cwd();
481
+ try {
482
+ const result = await spawnBash(guardPath, ['project', opts.packageRoot, projectRoot]);
483
+ // The script always exits 0; we still pass through stderr
484
+ // on a non-zero so the UI can surface platform issues.
485
+ if (result.exitCode !== 0) {
486
+ await reply.code(500).send({
487
+ error: { code: 'GUARD_FAILED', message: result.stderr || `scope_guard.sh exited ${result.exitCode}`, exitCode: result.exitCode },
488
+ });
489
+ return reply;
490
+ }
491
+ return parseScopeGuardOutput(result.stdout);
492
+ }
493
+ catch (err) {
494
+ const message = err instanceof Error ? err.message : 'scope_guard.sh failed to spawn';
495
+ await reply.code(500).send({ error: { code: 'GUARD_FAILED', message } });
496
+ return reply;
497
+ }
498
+ });
205
499
  app.post('/api/v1/wizard/state', async (request, reply) => {
206
500
  const body = (request.body ?? {});
207
501
  const parsed = wizardStateSchema.safeParse({
@@ -223,13 +517,17 @@ export function wizardRoute(opts) {
223
517
  await writeState(opts.writeRoot, parsed.data);
224
518
  return { ok: true };
225
519
  });
226
- // road-to-global-only-install § Phase 1.5 — Wizard Apply bridge.
227
- // Validates the WizardApplyPayload envelope, spills it to a temp
228
- // file, and spawns `python3 scripts/install.py --apply-payload
229
- // <tmp> --dry-run`. Returns the installer's plan-summary stdout
230
- // so the UI can render the preview before the maintainer commits.
231
- // Real-apply (non-dry-run) is gated until Phase 1.9 minor release
232
- // (kill-switch per D7 no dual code paths).
520
+ // road-to-single-install-source-of-truth § Phase 2 — Wizard Apply bridge.
521
+ // Validates the WizardApplyPayload envelope and spills it to a temp file,
522
+ // then dispatches `scripts/install.py --apply-payload <tmp>` — the single
523
+ // installer (D12 / ADR-020). Two modes on the SAME endpoint:
524
+ // dry_run:true → buffered plan-summary preview (JSON), used by the
525
+ // Review step. Adds `--dry-run`.
526
+ // dry_run:false REAL apply, streamed as SSE. install.py emits NDJSON
527
+ // (`{type:"file"|"done"|"error"}`); we map each line to the SSE frame
528
+ // vocabulary the UI consumes (`progress`/`done`/`error`) and abort the
529
+ // child on client disconnect (Finding #24). CSRF + Host/Origin
530
+ // allow-list are enforced by the app-level onRequest hooks.
233
531
  app.post('/api/v1/wizard/apply', async (request, reply) => {
234
532
  if (!extended) {
235
533
  await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'extended-mode endpoint disabled' } });
@@ -242,35 +540,114 @@ export function wizardRoute(opts) {
242
540
  });
243
541
  return reply;
244
542
  }
245
- // Force dry-run on the bridge until Phase 1.9 protects
246
- // against accidental real writes during the rollout window.
247
- const payload = { ...parsed.data, dry_run: true };
543
+ const isDryRun = parsed.data.dry_run === true;
544
+ const payload = parsed.data;
248
545
  const tmpPath = join(tmpdir(), `agent-config-apply-${randomBytes(8).toString('hex')}.json`);
546
+ const scriptPath = join(opts.packageRoot, 'scripts', 'install.py');
547
+ if (isDryRun) {
548
+ // Plan-summary preview — buffered JSON (Review step).
549
+ try {
550
+ await fs.writeFile(tmpPath, JSON.stringify(payload), { mode: 0o600 });
551
+ const result = await spawnInstaller(scriptPath, ['--apply-payload', tmpPath, '--dry-run']);
552
+ if (result.exitCode !== 0) {
553
+ await reply.code(500).send({
554
+ error: { code: 'BRIDGE_FAILED', message: result.stderr || 'installer bridge exited non-zero', exitCode: result.exitCode },
555
+ });
556
+ return reply;
557
+ }
558
+ return {
559
+ ok: true,
560
+ dryRun: true,
561
+ schemaVersion: payload.schema_version,
562
+ preview: result.stdout,
563
+ };
564
+ }
565
+ catch (err) {
566
+ const message = err instanceof Error ? err.message : 'apply bridge failed';
567
+ await reply.code(500).send({ error: { code: 'BRIDGE_FAILED', message } });
568
+ return reply;
569
+ }
570
+ finally {
571
+ await fs.unlink(tmpPath).catch(() => undefined);
572
+ }
573
+ }
574
+ // Real apply — SSE stream. Flush headers so the browser opens the
575
+ // channel immediately.
576
+ reply.raw.writeHead(200, {
577
+ 'Content-Type': 'text/event-stream',
578
+ 'Cache-Control': 'no-cache, no-transform',
579
+ Connection: 'keep-alive',
580
+ 'X-Accel-Buffering': 'no',
581
+ });
582
+ reply.raw.flushHeaders?.();
583
+ const controller = new AbortController();
584
+ const onClose = () => {
585
+ if (!reply.raw.writableEnded)
586
+ controller.abort();
587
+ };
588
+ reply.raw.on('close', onClose);
589
+ let written = 0;
590
+ let total = 0;
591
+ let sawTerminal = false;
249
592
  try {
250
593
  await fs.writeFile(tmpPath, JSON.stringify(payload), { mode: 0o600 });
251
- const scriptPath = join(opts.packageRoot, 'scripts', 'install.py');
252
- const result = await spawnInstaller(scriptPath, ['--apply-payload', tmpPath, '--dry-run']);
253
- if (result.exitCode !== 0) {
254
- await reply.code(500).send({
255
- error: { code: 'BRIDGE_FAILED', message: result.stderr || 'installer bridge exited non-zero', exitCode: result.exitCode },
256
- });
257
- return reply;
594
+ const result = await streamInstaller(scriptPath, ['--apply-payload', tmpPath], (obj) => {
595
+ const t = obj.type;
596
+ if (t === 'file') {
597
+ written = typeof obj.written === 'number' ? obj.written : written;
598
+ total = typeof obj.total === 'number' ? obj.total : total;
599
+ writeFrame(reply, {
600
+ type: 'progress',
601
+ file: obj.file,
602
+ status: obj.status,
603
+ written,
604
+ total,
605
+ });
606
+ }
607
+ else if (t === 'done') {
608
+ sawTerminal = true;
609
+ writeFrame(reply, { type: 'done', summary: { written, total } });
610
+ }
611
+ else if (t === 'error') {
612
+ sawTerminal = true;
613
+ writeFrame(reply, {
614
+ type: 'error',
615
+ code: typeof obj.code === 'string' ? obj.code : 'E_INSTALL',
616
+ message: typeof obj.message === 'string' ? obj.message : 'install failed',
617
+ recoverable: false,
618
+ });
619
+ }
620
+ }, controller.signal);
621
+ // install.py exited without a terminal frame (crash / kill): emit
622
+ // one so the UI never hangs waiting for `done`/`error`.
623
+ if (!sawTerminal) {
624
+ if (result.exitCode === 0) {
625
+ writeFrame(reply, { type: 'done', summary: { written, total } });
626
+ }
627
+ else {
628
+ writeFrame(reply, {
629
+ type: 'error',
630
+ code: 'BRIDGE_FAILED',
631
+ message: result.stderr.trim() || `installer exited ${result.exitCode}`,
632
+ recoverable: false,
633
+ });
634
+ }
258
635
  }
259
- return {
260
- ok: true,
261
- dryRun: true,
262
- schemaVersion: payload.schema_version,
263
- preview: result.stdout,
264
- };
265
636
  }
266
637
  catch (err) {
267
- const message = err instanceof Error ? err.message : 'apply bridge failed';
268
- await reply.code(500).send({ error: { code: 'BRIDGE_FAILED', message } });
269
- return reply;
638
+ writeFrame(reply, {
639
+ type: 'error',
640
+ code: 'E_CRASH',
641
+ message: err instanceof Error ? err.message : String(err),
642
+ recoverable: false,
643
+ });
270
644
  }
271
645
  finally {
646
+ reply.raw.off('close', onClose);
647
+ reply.raw.end();
272
648
  await fs.unlink(tmpPath).catch(() => undefined);
273
649
  }
650
+ return reply;
274
651
  });
275
652
  app.post('/api/v1/wizard/finish', async (request, reply) => {
276
653
  const body = (request.body ?? {});
@@ -293,6 +670,28 @@ export function wizardRoute(opts) {
293
670
  });
294
671
  return reply;
295
672
  }
673
+ // road-to-configurable-modules § Phase E — parse the modules
674
+ // payload. Extended-mode only; legacy 7-step flow never sends
675
+ // this field. Omitted / null → skip persistence (the team
676
+ // file stays untouched).
677
+ const rawModulesConfig = body.modulesConfig;
678
+ let modulesConfigData = null;
679
+ if (rawModulesConfig !== undefined && rawModulesConfig !== null) {
680
+ if (!extended) {
681
+ await reply.code(422).send({
682
+ error: { code: 'VALIDATION', message: 'modulesConfig requires extended mode', fields: [{ path: 'modulesConfig', message: 'extended-mode only' }] },
683
+ });
684
+ return reply;
685
+ }
686
+ const modulesParsed = modulesConfigSchema.safeParse(rawModulesConfig);
687
+ if (!modulesParsed.success) {
688
+ await reply.code(422).send({
689
+ error: { code: 'VALIDATION', message: 'invalid modulesConfig', fields: zodIssuesToFields(modulesParsed.error.issues) },
690
+ });
691
+ return reply;
692
+ }
693
+ modulesConfigData = modulesParsed.data;
694
+ }
296
695
  // road-to-global-only-install § Phase 2.3 — explicit scope opt-in.
297
696
  // `'global'` (default) lands writes under the resolved writeRoot
298
697
  // (typically `~/.event4u/agent-config/`). `'project'` routes
@@ -332,6 +731,7 @@ export function wizardRoute(opts) {
332
731
  settingsYaml: settingsBody,
333
732
  identity: identityParsed && identityParsed.success ? identityParsed.data : null,
334
733
  userIdentityYaml: identityBody,
734
+ modulesConfig: modulesConfigData,
335
735
  },
336
736
  };
337
737
  }
@@ -355,11 +755,47 @@ export function wizardRoute(opts) {
355
755
  // and the flat-root files are independent legacy artefacts
356
756
  // that should still be cleaned. The helper handles that.
357
757
  const migratedFrom = await deleteLegacyArtefacts(legacyReadRoot, effectiveWriteRoot).catch(() => []);
758
+ // road-to-configurable-modules § Phase E — invoke the
759
+ // persistence helper after the 2PC commit so a failed
760
+ // settings write never leaves a half-applied
761
+ // `.agent-project-settings.yml` behind. Best-effort: a
762
+ // bridge failure surfaces in `modulesApply.error` but
763
+ // does NOT roll back the settings commit (the team file
764
+ // is a separate artefact and the user can re-apply).
765
+ // Same root rule as `/auto-detect`: legacyReadRoot ??
766
+ // process.cwd() — that's the consumer repo, not the
767
+ // server's writeRoot.
768
+ let modulesAppliedTo = null;
769
+ let modulesApplyError = null;
770
+ if (modulesConfigData !== null) {
771
+ const projectRoot = legacyReadRoot ?? process.cwd();
772
+ const scriptPath = join(opts.packageRoot, 'scripts', 'apply_modules_config.py');
773
+ const tmpPath = join(tmpdir(), `agent-config-modules-${randomBytes(8).toString('hex')}.json`);
774
+ try {
775
+ await fs.writeFile(tmpPath, JSON.stringify(modulesConfigData), { mode: 0o600 });
776
+ const result = await spawnInstaller(scriptPath, ['--project', projectRoot, '--input-file', tmpPath]);
777
+ if (result.exitCode !== 0) {
778
+ modulesApplyError = { code: 'MODULES_APPLY_FAILED', message: result.stderr || 'modules apply bridge exited non-zero', exitCode: result.exitCode };
779
+ }
780
+ else {
781
+ modulesAppliedTo = result.stdout.trim() || null;
782
+ }
783
+ }
784
+ catch (err) {
785
+ const message = err instanceof Error ? err.message : 'modules apply bridge failed';
786
+ modulesApplyError = { code: 'MODULES_APPLY_FAILED', message };
787
+ }
788
+ finally {
789
+ await fs.unlink(tmpPath).catch(() => undefined);
790
+ }
791
+ }
358
792
  return {
359
793
  writtenPaths: payloads.map((p) => p.target),
360
794
  txnId,
361
795
  scope,
362
796
  ...(migratedFrom.length > 0 ? { migratedFrom } : {}),
797
+ ...(modulesAppliedTo !== null ? { modulesAppliedTo } : {}),
798
+ ...(modulesApplyError !== null ? { modulesApplyError } : {}),
363
799
  };
364
800
  }
365
801
  catch (err) {