@event4u/agent-config 3.2.0 → 4.1.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 (607) 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 +6 -6
  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 -16
  143. package/CHANGELOG.md +204 -2
  144. package/CONTRIBUTING.md +31 -12
  145. package/README.md +18 -10
  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/apply.js +238 -0
  164. package/dist/install/apply.js.map +1 -0
  165. package/dist/install/atomic.js +92 -0
  166. package/dist/install/atomic.js.map +1 -0
  167. package/dist/install/bridges/augment.js +20 -0
  168. package/dist/install/bridges/augment.js.map +1 -0
  169. package/dist/install/bridges/claude.js +44 -0
  170. package/dist/install/bridges/claude.js.map +1 -0
  171. package/dist/install/bridges/cline.js +69 -0
  172. package/dist/install/bridges/cline.js.map +1 -0
  173. package/dist/install/bridges/copilot.js +28 -0
  174. package/dist/install/bridges/copilot.js.map +1 -0
  175. package/dist/install/bridges/cursor.js +34 -0
  176. package/dist/install/bridges/cursor.js.map +1 -0
  177. package/dist/install/bridges/gemini.js +39 -0
  178. package/dist/install/bridges/gemini.js.map +1 -0
  179. package/dist/install/bridges/index.js +88 -0
  180. package/dist/install/bridges/index.js.map +1 -0
  181. package/dist/install/bridges/marker-content.js +153 -0
  182. package/dist/install/bridges/marker-content.js.map +1 -0
  183. package/dist/install/bridges/markers.js +42 -0
  184. package/dist/install/bridges/markers.js.map +1 -0
  185. package/dist/install/bridges/types.js +31 -0
  186. package/dist/install/bridges/types.js.map +1 -0
  187. package/dist/install/bridges/vscode.js +26 -0
  188. package/dist/install/bridges/vscode.js.map +1 -0
  189. package/dist/install/bridges/windsurf.js +35 -0
  190. package/dist/install/bridges/windsurf.js.map +1 -0
  191. package/dist/install/conflict.js +196 -0
  192. package/dist/install/conflict.js.map +1 -0
  193. package/dist/install/detect.js +218 -0
  194. package/dist/install/detect.js.map +1 -0
  195. package/dist/install/paths.js +82 -0
  196. package/dist/install/paths.js.map +1 -0
  197. package/dist/install/plan.js +157 -0
  198. package/dist/install/plan.js.map +1 -0
  199. package/dist/install/txlog.js +140 -0
  200. package/dist/install/txlog.js.map +1 -0
  201. package/dist/install/types.js +19 -0
  202. package/dist/install/types.js.map +1 -0
  203. package/dist/install/wizard-plan.js +184 -0
  204. package/dist/install/wizard-plan.js.map +1 -0
  205. package/dist/mcp/registry-manifest.json +4 -4
  206. package/dist/router.json +67 -19
  207. package/dist/server/app.js +6 -0
  208. package/dist/server/app.js.map +1 -1
  209. package/dist/server/routes/install.js +547 -0
  210. package/dist/server/routes/install.js.map +1 -0
  211. package/dist/server/routes/wizard.js +301 -6
  212. package/dist/server/routes/wizard.js.map +1 -1
  213. package/dist/server/routes/workspace.js +396 -0
  214. package/dist/server/routes/workspace.js.map +1 -0
  215. package/dist/server/schemas/settings.js +4 -3
  216. package/dist/server/schemas/settings.js.map +1 -1
  217. package/dist/ui/assets/index-BXZILUxe.css +1 -0
  218. package/dist/ui/assets/index-DLEuEW1V.js +35 -0
  219. package/dist/ui/assets/index-DLEuEW1V.js.map +1 -0
  220. package/dist/ui/index.html +2 -2
  221. package/docs/MIGRATION.md +1 -1
  222. package/docs/adrs/cost/0001-hard-stop-hook.md +1 -1
  223. package/docs/adrs/router/0001-three-tier-routing.md +4 -4
  224. package/docs/adrs/schema/0001-json-schema-frontmatter.md +1 -1
  225. package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +4 -4
  226. package/docs/adrs/{caveman → telegraph}/0001-default-off-until-bench.md +9 -9
  227. package/docs/adrs/telegraph/README.md +9 -0
  228. package/docs/architecture/augment-projection.md +4 -4
  229. package/docs/architecture/claude-bundle.md +1 -1
  230. package/docs/architecture/current-onboard-baseline.md +3 -3
  231. package/docs/architecture/multi-tool-projection.md +10 -10
  232. package/docs/architecture/source-projection.md +27 -27
  233. package/docs/architecture.md +19 -15
  234. package/docs/archive/CHANGELOG-pre-2.11.0.md +2 -2
  235. package/docs/archive/CHANGELOG-pre-2.15.0.md +3 -3
  236. package/docs/archive/CHANGELOG-pre-2.16.0.md +1 -1
  237. package/docs/archive/CHANGELOG-pre-2.2.0.md +70 -70
  238. package/docs/archive/CHANGELOG-pre-2.20.0.md +2 -2
  239. package/docs/archive/CHANGELOG-pre-2.25.0.md +15 -15
  240. package/docs/archive/CHANGELOG-pre-3.0.0.md +4 -4
  241. package/docs/archive/CHANGELOG-pre-3.1.0.md +2 -2
  242. package/docs/archive/CHANGELOG-pre-3.2.0.md +3 -3
  243. package/docs/benchmark.md +65 -0
  244. package/docs/benchmarks.md +18 -18
  245. package/docs/catalog.md +17 -15
  246. package/docs/contracts/CHANGELOG-conventions.md +2 -2
  247. package/docs/contracts/STABILITY.md +2 -2
  248. package/docs/contracts/adoption-signal-floor.md +110 -0
  249. package/docs/contracts/adr-chat-history-split.md +4 -4
  250. package/docs/contracts/adr-command-suggestion.md +4 -4
  251. package/docs/contracts/adr-gtm-context-spine.md +1 -1
  252. package/docs/contracts/adr-implement-ticket-runtime.md +4 -4
  253. package/docs/contracts/adr-install-user-type-axis.md +1 -1
  254. package/docs/contracts/adr-layout.md +2 -2
  255. package/docs/contracts/adr-mcp-runtime.md +1 -1
  256. package/docs/contracts/adr-product-ui-track.md +10 -10
  257. package/docs/contracts/adr-user-types-axis.md +3 -3
  258. package/docs/contracts/adr-wing4-context-spine.md +1 -1
  259. package/docs/contracts/agent-memory-contract.md +3 -3
  260. package/docs/contracts/agents-md-tech-stack.md +2 -2
  261. package/docs/contracts/ai-council-config.md +2 -2
  262. package/docs/contracts/at-rest-encryption.md +4 -0
  263. package/docs/contracts/audit-log-v1.md +1 -1
  264. package/docs/contracts/benchmark-ab-contract.md +101 -0
  265. package/docs/contracts/benchmark-corpus-spec.md +4 -4
  266. package/docs/contracts/benchmark-report-schema.md +5 -5
  267. package/docs/contracts/branch-protection-policy.md +98 -0
  268. package/docs/contracts/ci-cost-budget.md +106 -0
  269. package/docs/contracts/ci-green-floor.md +141 -0
  270. package/docs/contracts/command-clusters.md +6 -6
  271. package/docs/contracts/command-surface-tiers.md +2 -2
  272. package/docs/contracts/command-taxonomy.md +2 -2
  273. package/docs/contracts/{compression-default-kill-criterion.md → condensation-default-kill-criterion.md} +29 -29
  274. package/docs/contracts/config-presets.md +1 -1
  275. package/docs/contracts/context-paths.md +3 -3
  276. package/docs/contracts/context-spine.md +1 -1
  277. package/docs/contracts/cost-enforcement.md +1 -1
  278. package/docs/contracts/cost-summary-schema.md +12 -12
  279. package/docs/contracts/cross-wing-handoff.md +4 -4
  280. package/docs/contracts/daily-workspace.md +4 -0
  281. package/docs/contracts/decision-trace-v1.md +2 -2
  282. package/docs/contracts/discovery-manifest.md +4 -4
  283. package/docs/contracts/explain-modes.md +4 -0
  284. package/docs/contracts/file-ownership-matrix.json +3493 -3318
  285. package/docs/contracts/file-ownership-matrix.md +3 -3
  286. package/docs/contracts/frontmatter-contract.md +4 -4
  287. package/docs/contracts/ghostwriter-schema.md +3 -3
  288. package/docs/contracts/gui-wizard.md +1 -1
  289. package/docs/contracts/harness-expectations.md +123 -0
  290. package/docs/contracts/host-agent-protocol.md +4 -0
  291. package/docs/contracts/implement-ticket-flow.md +9 -9
  292. package/docs/contracts/install-scopes.md +77 -0
  293. package/docs/contracts/iron-law-overrides.txt +1 -1
  294. package/docs/contracts/kernel-membership.md +26 -26
  295. package/docs/contracts/linear-ai-rules-inclusion.md +1 -1
  296. package/docs/contracts/linter-structural-model.md +2 -2
  297. package/docs/contracts/load-context-budget-model.md +4 -4
  298. package/docs/contracts/load-context-schema.md +13 -13
  299. package/docs/contracts/local-analytics.md +4 -0
  300. package/docs/contracts/local-knowledge-ingestion.md +1 -1
  301. package/docs/contracts/mcp-beta-criteria.md +1 -1
  302. package/docs/contracts/mcp-cloud-scope.md +6 -6
  303. package/docs/contracts/mcp-phase-1-scope.md +3 -3
  304. package/docs/contracts/mcp-registry-manifest.schema.json +1 -1
  305. package/docs/contracts/mcp-tool-inventory.md +1 -1
  306. package/docs/contracts/mcp-tool-stub-envelope.md +1 -1
  307. package/docs/contracts/measurement-baseline.md +11 -11
  308. package/docs/contracts/mental-models.md +30 -30
  309. package/docs/contracts/multi-tool-projection-fidelity.md +4 -4
  310. package/docs/contracts/namespace.md +4 -4
  311. package/docs/contracts/orchestration-dsl-v1.md +7 -7
  312. package/docs/contracts/package-self-orientation.md +12 -12
  313. package/docs/contracts/persona-schema.md +6 -6
  314. package/docs/contracts/pilot/language-and-tone.md +1 -1
  315. package/docs/contracts/plain-language-surface.md +117 -0
  316. package/docs/contracts/profile-system.md +3 -3
  317. package/docs/contracts/release-pr-gating.md +103 -0
  318. package/docs/contracts/role-experience.md +3 -3
  319. package/docs/contracts/rule-classification.md +13 -13
  320. package/docs/contracts/rule-interactions.md +4 -4
  321. package/docs/contracts/rule-interactions.yml +30 -30
  322. package/docs/contracts/rule-priority-hierarchy.md +13 -13
  323. package/docs/contracts/rule-router.md +2 -2
  324. package/docs/contracts/safety-model.md +1 -1
  325. package/docs/contracts/skill-distribution-channels.md +61 -0
  326. package/docs/contracts/skill-domains.md +2 -2
  327. package/docs/contracts/smoke-contracts.md +5 -5
  328. package/docs/contracts/telegraph-telemetry.md +83 -0
  329. package/docs/contracts/trust-and-safety.md +5 -5
  330. package/docs/contracts/ui-stack-extension.md +7 -7
  331. package/docs/contracts/ui-track-flow.md +9 -9
  332. package/docs/contracts/user-type-schema.md +4 -4
  333. package/docs/contracts/workflow-packs.md +4 -4
  334. package/docs/contracts/workspace-documents.md +4 -0
  335. package/docs/customization.md +28 -8
  336. package/docs/decisions/ADR-001-kernel-swap-deferred.md +6 -6
  337. package/docs/decisions/ADR-002-kernel-bucket-overrides.md +11 -11
  338. package/docs/decisions/ADR-003-flat-cluster-subs-and-colon-syntax.md +2 -2
  339. package/docs/decisions/ADR-004-rule-governance-pruning.md +4 -4
  340. package/docs/decisions/ADR-005-subagent-worktrees.md +7 -7
  341. package/docs/decisions/ADR-011-domain-pack-readiness.md +6 -6
  342. package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +3 -3
  343. package/docs/decisions/ADR-015-discovery-manifest-contract.md +3 -3
  344. package/docs/decisions/ADR-017-monorepo-physical-layout.md +10 -10
  345. package/docs/decisions/ADR-018-trust-and-safety-layer.md +6 -6
  346. package/docs/decisions/ADR-019-router-json-dist-location.md +2 -2
  347. package/docs/decisions/ADR-020-global-only-consumer-scope.md +2 -2
  348. package/docs/decisions/ADR-021-deployment-shape.md +1 -1
  349. package/docs/decisions/ADR-022-daily-workspace-decomposition.md +1 -1
  350. package/docs/decisions/ADR-027-changelog-machine-vs-manual.md +129 -0
  351. package/docs/decisions/ADR-028-root-layout.md +147 -0
  352. package/docs/decisions/ADR-029-multi-workspace-deferred.md +122 -0
  353. package/docs/decisions/ADR-rule-kernel-and-router.md +5 -5
  354. package/docs/decisions/INDEX.md +8 -0
  355. package/docs/deploy/team-deployment-posture.md +20 -0
  356. package/docs/development.md +17 -17
  357. package/docs/distribution/registries.md +32 -0
  358. package/docs/distribution/registry-submissions.md +85 -0
  359. package/docs/distribution/telemetry-schema.md +1 -1
  360. package/docs/getting-started-by-role.md +45 -3
  361. package/docs/getting-started.md +2 -2
  362. package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
  363. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +1 -1
  364. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
  365. package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
  366. package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
  367. package/docs/guidelines/agent-infra/direct-answers-demos.md +1 -1
  368. package/docs/guidelines/agent-infra/first-principles.md +2 -2
  369. package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
  370. package/docs/guidelines/agent-infra/layered-settings.md +56 -2
  371. package/docs/guidelines/agent-infra/mental-models.md +3 -3
  372. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +2 -2
  373. package/docs/guidelines/agent-infra/rule-type-governance.md +1 -1
  374. package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
  375. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +2 -2
  376. package/docs/guidelines/agent-infra/six-hats.md +3 -3
  377. package/docs/guidelines/agent-infra/skill-quality-checklist.md +5 -5
  378. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  379. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +1 -1
  380. package/docs/guidelines/augment-portability-patterns.md +4 -4
  381. package/docs/guidelines/cross-role-handoff.md +2 -2
  382. package/docs/guidelines/php/php-coding-patterns.md +1 -1
  383. package/docs/guidelines/prompt-templates.md +6 -6
  384. package/docs/maintainers/dev-mode.md +1 -1
  385. package/docs/mcp-server.md +1 -1
  386. package/docs/mcp.md +1 -1
  387. package/docs/parity/bench-ruflo.json +3 -3
  388. package/docs/parity/bench.json +3 -3
  389. package/docs/parity/ruflo.md +3 -3
  390. package/docs/profiles.md +11 -11
  391. package/docs/quality.md +11 -11
  392. package/docs/safety.md +3 -3
  393. package/docs/setup/mcp-client-config.md +2 -2
  394. package/docs/setup/mcp-cloud-endpoints.md +1 -1
  395. package/docs/setup/mcp-cloud-setup.md +2 -2
  396. package/docs/setup/mcp-r2-bootstrap.md +2 -2
  397. package/docs/setup/mcp-server-docker.md +3 -3
  398. package/docs/setup/per-ide/windsurf.md +1 -1
  399. package/docs/skills-catalog.md +8 -7
  400. package/docs/troubleshooting.md +1 -1
  401. package/docs/walkthroughs/daily-workspace-a11y.md +87 -0
  402. package/llms.txt +7 -6
  403. package/package.json +1 -1
  404. package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
  405. package/scripts/_archive/README.md +2 -2
  406. package/scripts/_archive/_backfill_skill_domains.py +3 -3
  407. package/scripts/_archive/_bootstrap_tier_frontmatter.py +3 -3
  408. package/scripts/_archive/_p43_bodies.py +10 -10
  409. package/scripts/_archive/{_p43_compress.py → _p43_condense.py} +5 -5
  410. package/scripts/_archive/_p4_migrate.py +7 -7
  411. package/scripts/_archive/_phase2_shim_helper.py +1 -1
  412. package/scripts/_archive/_pilot_council_question.py +5 -5
  413. package/scripts/_cli/explain_last/inputs.py +1 -1
  414. package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
  415. package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
  416. package/scripts/_lib/agent_settings.py +195 -1
  417. package/scripts/_lib/agent_src.py +19 -19
  418. package/scripts/_lib/bench_ab_cache.py +162 -0
  419. package/scripts/_lib/bench_ab_scoring.py +209 -0
  420. package/scripts/_lib/bench_cost.py +2 -2
  421. package/scripts/_lib/bench_report.py +2 -2
  422. package/scripts/_lib/{bench_caveman.py → bench_telegraph.py} +21 -21
  423. package/scripts/_lib/{bench_caveman_report.py → bench_telegraph_report.py} +22 -22
  424. package/scripts/_lib/claude_desktop_bundler.py +5 -5
  425. package/scripts/_lib/module_detection.py +223 -0
  426. package/scripts/_lib/scope_guard.sh +162 -0
  427. package/scripts/_phase4_bucket.py +3 -3
  428. package/scripts/_pilot_measure.py +4 -4
  429. package/scripts/_tmp_scan_framework_leakage.py +1 -1
  430. package/scripts/adoption_report.py +195 -0
  431. package/scripts/adoption_snapshot.py +219 -0
  432. package/scripts/adoption_status.py +166 -0
  433. package/scripts/ai-video/lib/parse-blueprint.sh +1 -1
  434. package/scripts/ai_council/advisors.py +5 -5
  435. package/scripts/ai_council/compile_corpus.py +1 -1
  436. package/scripts/ai_council/one_off_archive/2026-05/_one_off_budget_v2_audit.py +3 -3
  437. package/scripts/ai_council/one_off_archive/2026-05/_one_off_context_layer_v1_review.py +2 -2
  438. package/scripts/ai_council/one_off_archive/2026-05/_one_off_inject_quiet_flag.py +1 -1
  439. package/scripts/ai_council/one_off_archive/2026-05/_one_off_measure_v2.sh +1 -1
  440. package/scripts/ai_council/one_off_archive/2026-05/_one_off_measure_verbosity.sh +1 -1
  441. package/scripts/ai_council/one_off_archive/2026-05/_one_off_nondestructive_inline_audit.py +3 -3
  442. package/scripts/ai_council/one_off_archive/2026-05/_one_off_per_task.sh +1 -1
  443. package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase6_trigger_jaccard.py +1 -1
  444. package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase_2a_budget_rebalance.py +6 -6
  445. package/scripts/ai_council/one_off_archive/2026-05/_one_off_rebalancing_audit.py +1 -1
  446. package/scripts/ai_council/one_off_archive/2026-05/_one_off_tier_retrofit.py +6 -6
  447. package/scripts/annotate_discovery.py +13 -13
  448. package/scripts/apply_modules_config.py +290 -0
  449. package/scripts/audit_adr_coverage.py +2 -2
  450. package/scripts/audit_auto_rules.py +2 -2
  451. package/scripts/audit_cloud_compatibility.py +3 -3
  452. package/scripts/audit_command_surface.py +9 -9
  453. package/scripts/audit_likelihood.py +2 -2
  454. package/scripts/audit_mcp_tools.py +1 -1
  455. package/scripts/audit_user_type_axis.py +2 -2
  456. package/scripts/bench_ab_cache_dispatch.py +68 -0
  457. package/scripts/bench_ab_clone.py +170 -0
  458. package/scripts/bench_ab_diff.py +227 -0
  459. package/scripts/bench_ab_integrity.py +143 -0
  460. package/scripts/bench_ab_run.py +235 -0
  461. package/scripts/bench_ab_task_runner.py +369 -0
  462. package/scripts/bench_ab_tracka_run.py +202 -0
  463. package/scripts/bench_baseline_ready.py +3 -3
  464. package/scripts/{bench_compress_memory.py → bench_condense_memory.py} +16 -16
  465. package/scripts/bench_drift_check.py +2 -2
  466. package/scripts/bench_per_tool.py +2 -2
  467. package/scripts/bench_run.py +36 -36
  468. package/scripts/bench_runner.py +2 -2
  469. package/scripts/bootstrap.sh +99 -0
  470. package/scripts/build_cloud_bundle.py +6 -6
  471. package/scripts/build_discovery_manifest.py +7 -7
  472. package/scripts/build_linear_digest.py +3 -3
  473. package/scripts/build_mcp_registry_manifest.py +2 -2
  474. package/scripts/build_rule_trigger_matrix.py +8 -8
  475. package/scripts/chat_history.py +5 -5
  476. package/scripts/check_always_budget.py +11 -5
  477. package/scripts/check_augment_description_cap.py +3 -3
  478. package/scripts/check_cluster_patterns.py +2 -2
  479. package/scripts/check_command_count_messaging.py +3 -3
  480. package/scripts/{check_compression.py → check_condensation.py} +34 -34
  481. package/scripts/{check_compressed_paths.py → check_condensed_paths.py} +8 -8
  482. package/scripts/check_context_paths.py +7 -7
  483. package/scripts/check_council_layout.py +2 -2
  484. package/scripts/check_council_references.py +9 -9
  485. package/scripts/check_iron_law_prominence.py +2 -2
  486. package/scripts/check_kernel_rule_bundle.py +2 -2
  487. package/scripts/check_module_management_neutral.py +149 -0
  488. package/scripts/check_no_roadmap_refs.py +9 -9
  489. package/scripts/check_portability.py +3 -3
  490. package/scripts/check_public_catalog_links.py +4 -4
  491. package/scripts/check_references.py +7 -6
  492. package/scripts/check_release_pr_shape.py +112 -0
  493. package/scripts/check_reply_consistency.py +3 -3
  494. package/scripts/check_safety_floor_untouched.py +1 -1
  495. package/scripts/check_template_pin_drift.py +5 -5
  496. package/scripts/check_token_optimizer_freshness.py +3 -3
  497. package/scripts/ci_status.py +301 -0
  498. package/scripts/ci_time_ratio.py +1 -1
  499. package/scripts/cleanup_other_scope.sh +146 -0
  500. package/scripts/compile_router.py +10 -10
  501. package/scripts/{compress.py → condense.py} +64 -64
  502. package/scripts/condense.sh +18 -0
  503. package/scripts/{compress_memory.py → condense_memory.py} +33 -33
  504. package/scripts/config/presets.py +2 -2
  505. package/scripts/config/profiles.py +1 -1
  506. package/scripts/cost_by_conversation.py +3 -3
  507. package/scripts/cost_summary.py +7 -7
  508. package/scripts/count_token_optimizer_usage.sh +1 -1
  509. package/scripts/gen_discovery_baseline.py +5 -5
  510. package/scripts/generate_index.py +6 -6
  511. package/scripts/generate_ownership_matrix.py +10 -10
  512. package/scripts/generate_pack_manifests.py +1 -1
  513. package/scripts/ghostwriter_fixture_allowlist.txt +1 -1
  514. package/scripts/install +3 -3
  515. package/scripts/install-hooks.sh +6 -6
  516. package/scripts/install.py +76 -11
  517. package/scripts/install.sh +187 -1
  518. package/scripts/inventory_frontmatter.py +2 -2
  519. package/scripts/iron_law_sha.py +3 -3
  520. package/scripts/lint_agents_layout.py +14 -7
  521. package/scripts/lint_agents_md.py +4 -4
  522. package/scripts/lint_archived_skills.py +3 -3
  523. package/scripts/lint_artefact_frontmatter.py +2 -2
  524. package/scripts/lint_bench_ab.py +172 -0
  525. package/scripts/lint_bench_corpus.py +1 -1
  526. package/scripts/lint_command_tiers.py +5 -5
  527. package/scripts/lint_context_spine_usage.py +1 -1
  528. package/scripts/lint_framework_leakage.py +7 -7
  529. package/scripts/lint_framework_leakage_allowlist.json +144 -84
  530. package/scripts/lint_ghostwriter_source.py +3 -3
  531. package/scripts/lint_handoffs.py +1 -1
  532. package/scripts/lint_load_context.py +11 -11
  533. package/scripts/lint_media_policy_linkage.py +5 -5
  534. package/scripts/lint_namespace.py +1 -1
  535. package/scripts/lint_no_new_atomic_commands.py +2 -2
  536. package/scripts/lint_orchestration_dsl.py +1 -1
  537. package/scripts/lint_pack_boundaries.py +2 -2
  538. package/scripts/lint_persona_governance.py +4 -4
  539. package/scripts/lint_role_experiences.py +237 -0
  540. package/scripts/lint_rule_interactions.py +2 -2
  541. package/scripts/lint_rule_tiers.py +1 -1
  542. package/scripts/lint_trust_coherence.py +2 -2
  543. package/scripts/mcp_registry_submit.sh +187 -0
  544. package/scripts/mcp_server/__init__.py +1 -1
  545. package/scripts/mcp_server/catalog.py +1 -1
  546. package/scripts/mcp_server/consumer_tool_catalog.json +1 -1
  547. package/scripts/mcp_server/tools.py +2 -2
  548. package/scripts/measure_frugality_savings.py +10 -10
  549. package/scripts/measure_patterns.py +1 -1
  550. package/scripts/measure_projection_bytes.py +5 -5
  551. package/scripts/measure_rule_budget.py +3 -3
  552. package/scripts/measure_skill_reduction.py +1 -1
  553. package/scripts/memory_lookup.py +1 -1
  554. package/scripts/memory_status.py +2 -2
  555. package/scripts/migrate_command_suggestions.py +3 -3
  556. package/scripts/mine_session.py +1 -1
  557. package/scripts/move_artefact.py +3 -3
  558. package/scripts/new_skill.py +2 -2
  559. package/scripts/pack_mcp_content.py +14 -14
  560. package/scripts/plan_physical_move.py +6 -6
  561. package/scripts/print_required_checks.py +196 -0
  562. package/scripts/probe_skill_registration.py +413 -0
  563. package/scripts/propose_modules_config.py +145 -0
  564. package/scripts/prototype_lint_contradictions.py +1 -1
  565. package/scripts/recruit_preflight.sh +152 -0
  566. package/scripts/refine_ticket_detect.py +3 -3
  567. package/scripts/release.py +20 -0
  568. package/scripts/render_benchmark_md.py +308 -0
  569. package/scripts/roadmap_progress_hook.py +1 -1
  570. package/scripts/run_skill_evals.py +2 -2
  571. package/scripts/runtime_registry.py +4 -4
  572. package/scripts/schemas/command.schema.json +4 -4
  573. package/scripts/schemas/rule.schema.json +5 -5
  574. package/scripts/schemas/skill.schema.json +3 -3
  575. package/scripts/schemas/user-type.schema.json +1 -1
  576. package/scripts/score_skill_selection.py +1 -1
  577. package/scripts/skill_collision_clusters.py +2 -2
  578. package/scripts/skill_linter.py +81 -81
  579. package/scripts/skill_overlap.py +5 -5
  580. package/scripts/skill_tools/audit_persona_coverage.py +2 -2
  581. package/scripts/skill_tools/audit_user_type_coverage.py +2 -2
  582. package/scripts/skill_tools/run_block_d_eval.py +1 -1
  583. package/scripts/skill_tools/score_skill_relevance.py +1 -1
  584. package/scripts/skill_tools/suggest_skill_for_task.py +1 -1
  585. package/scripts/skill_trigger_eval.py +5 -5
  586. package/scripts/smoke/kernel.sh +7 -1
  587. package/scripts/smoke/router.sh +5 -5
  588. package/scripts/smoke/skills.sh +1 -1
  589. package/scripts/smoke_quickstart.py +1 -1
  590. package/scripts/snapshot_agent_outputs.py +3 -3
  591. package/scripts/spotcheck_thin_root.py +1 -1
  592. package/scripts/{caveman_stats.py → telegraph_stats.py} +18 -18
  593. package/scripts/update_counts.py +1 -1
  594. package/scripts/validate_decision_engine.py +1 -1
  595. package/scripts/validate_frontmatter.py +1 -1
  596. package/scripts/validate_safe_paths.py +3 -3
  597. package/scripts/{validate_caveman_carveouts.py → validate_telegraph_carveouts.py} +7 -7
  598. package/scripts/verify_roadmap_closure.py +6 -6
  599. package/templates/consumer-settings/ONBOARDING.md +41 -0
  600. package/.agent-src/commands/install-via-agent.md +0 -129
  601. package/.agent-src/skills/compress-memory/SKILL.md +0 -131
  602. package/dist/ui/assets/index-D-DY1ywI.js +0 -35
  603. package/dist/ui/assets/index-D-DY1ywI.js.map +0 -1
  604. package/dist/ui/assets/index-Dqfhmg-d.css +0 -1
  605. package/docs/adrs/caveman/README.md +0 -9
  606. package/docs/contracts/caveman-telemetry.md +0 -83
  607. package/scripts/compress.sh +0 -18
@@ -0,0 +1,202 @@
1
+ #!/usr/bin/env python3
2
+ """Track A — behavioural eval runner for the package-impact A/B bench.
3
+
4
+ Phase 3 Step 2 of `agents/roadmaps/road-to-package-impact-benchmark.md`.
5
+
6
+ For each prompt in `internal/bench/corpora/ab-tracka.yaml`, check whether
7
+ the expected rule/skill surface is present in the target clone. Present +
8
+ keyword-grep passing → trigger fires. Absent → trigger does not fire.
9
+
10
+ By construction the `without` clone has no agent-config surface — every
11
+ expected_target file is missing — so its accuracy floor is 0%. The `with`
12
+ clone has the surface installed and should score near 100%. The delta is
13
+ the lift attributable to the package.
14
+
15
+ This runner does NOT invoke `claude` — Track A measures **surface
16
+ availability**, the necessary precondition for the rule-router to fire.
17
+ Track B (Phase 4) measures actual end-to-end task behaviour.
18
+
19
+ Output schema (consumed by bench_ab_diff.py):
20
+
21
+ results:
22
+ trigger_accuracy: 0.0 .. 1.0 # share of prompts that scored 1
23
+ false_positives: int # `without` matches (expected = 0)
24
+ per_rule_accuracy: # per-target hit map
25
+ <expected_target>: {with: 0|1, without: 0|1}
26
+ per_prompt: # full audit trail
27
+ - id, expected_target, with_score, without_score, notes
28
+ """
29
+ from __future__ import annotations
30
+
31
+ import argparse
32
+ import json
33
+ import re
34
+ import sys
35
+ import time
36
+ from datetime import datetime, timezone
37
+ from pathlib import Path
38
+
39
+ REPO_ROOT = Path(__file__).resolve().parent.parent
40
+ sys.path.insert(0, str(REPO_ROOT / "scripts"))
41
+
42
+ from _lib import bench_ab_cache # type: ignore[import-not-found] # noqa: E402
43
+
44
+ CORPUS_PATH = REPO_ROOT / "internal" / "bench" / "corpora" / "ab-tracka.yaml"
45
+ CLONES_DIR = REPO_ROOT / "internal" / "bench" / "ab" / "clones"
46
+ REPORTS_DIR = REPO_ROOT / "internal" / "bench" / "reports" / "ab"
47
+
48
+ try:
49
+ import yaml
50
+ except ImportError:
51
+ sys.stderr.write("bench_ab_tracka_run: PyYAML required (pip install pyyaml)\n")
52
+ raise SystemExit(2)
53
+
54
+
55
+ def utc_stamp() -> str:
56
+ return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H-%M-%SZ")
57
+
58
+
59
+ def load_corpus() -> dict:
60
+ return yaml.safe_load(CORPUS_PATH.read_text())
61
+
62
+
63
+ def score_prompt(prompt: dict, clone_root: Path) -> tuple[int, str]:
64
+ """Return (score, reason). score=1 when the surface is present AND every keyword hits."""
65
+ target_rel = prompt.get("expected_target")
66
+ if not target_rel:
67
+ return 0, "no expected_target"
68
+ target = clone_root / target_rel
69
+ if not target.exists():
70
+ return 0, f"missing: {target_rel}"
71
+ keywords = prompt.get("expected_keywords") or []
72
+ if not isinstance(keywords, list) or not keywords:
73
+ # Surface presence alone counts when no keywords specified.
74
+ return 1, "present (no keywords)"
75
+ body = target.read_text(errors="replace")
76
+ missing = [kw for kw in keywords if not re.search(re.escape(str(kw)), body, re.IGNORECASE)]
77
+ if missing:
78
+ return 0, f"keywords missing: {','.join(missing)}"
79
+ return 1, "present (keywords matched)"
80
+
81
+
82
+ def run_variant(variant: str, prompts: list[dict]) -> dict:
83
+ clone_root = CLONES_DIR / variant
84
+ if not clone_root.exists():
85
+ raise RuntimeError(
86
+ f"clone missing at {clone_root} — run scripts/bench_ab_clone.py first"
87
+ )
88
+ per_prompt = []
89
+ per_target: dict[str, int] = {}
90
+ matched = 0
91
+ for prompt in prompts:
92
+ score, reason = score_prompt(prompt, clone_root)
93
+ per_prompt.append(
94
+ {
95
+ "id": prompt.get("id"),
96
+ "expected_target": prompt.get("expected_target"),
97
+ "score": score,
98
+ "reason": reason,
99
+ }
100
+ )
101
+ per_target[prompt.get("expected_target", "")] = max(
102
+ per_target.get(prompt.get("expected_target", ""), 0), score
103
+ )
104
+ matched += score
105
+ total = len(prompts) or 1
106
+ return {
107
+ "trigger_accuracy": round(matched / total, 4),
108
+ "matched": matched,
109
+ "total": total,
110
+ "per_target_present": per_target,
111
+ "per_prompt": per_prompt,
112
+ }
113
+
114
+
115
+ def integrity_check(without_results: dict) -> tuple[bool, str]:
116
+ """Track A safety: `without` MUST score 0 — there is no agent-config surface
117
+ to match. A non-zero score means the integrity boundary leaked and the run
118
+ is invalid.
119
+ """
120
+ matched = without_results.get("matched", 0)
121
+ if matched != 0:
122
+ # Identify which prompts leaked
123
+ leaked = [p["id"] for p in without_results.get("per_prompt", []) if p.get("score")]
124
+ return False, f"`without` scored {matched} (expected 0); leaked: {','.join(leaked)}"
125
+ return True, "without=0 (clean)"
126
+
127
+
128
+ def write_report(variant: str, results: dict, duration: float, *, integrity_ok: bool) -> Path:
129
+ REPORTS_DIR.mkdir(parents=True, exist_ok=True)
130
+ cache_key = bench_ab_cache.CacheKey(
131
+ corpus_hash=bench_ab_cache.hash_file(CORPUS_PATH),
132
+ claude_cli_version=bench_ab_cache.claude_cli_version(),
133
+ target_shape_hash=bench_ab_cache.target_shape_hash(),
134
+ )
135
+ stamp = utc_stamp()
136
+ payload = {
137
+ "schema": "ab-bench/0.1",
138
+ "stamp": stamp,
139
+ "variant": variant,
140
+ "corpus": "ab-tracka",
141
+ "cache_key": cache_key.to_dict(),
142
+ "duration_seconds": round(duration, 3),
143
+ "integrity_ok": integrity_ok,
144
+ "results": results,
145
+ }
146
+ path = REPORTS_DIR / f"{stamp}-ab-tracka-{variant}.json"
147
+ path.write_text(json.dumps(payload, indent=2) + "\n")
148
+ md = path.with_suffix(".md")
149
+ md.write_text(
150
+ f"# Track A · {variant}\n\n"
151
+ f"- Stamp: `{stamp}`\n"
152
+ f"- Trigger accuracy: **{results.get('trigger_accuracy', 0) * 100:.1f}%**"
153
+ f" ({results.get('matched', 0)}/{results.get('total', 0)})\n"
154
+ f"- Integrity OK: `{integrity_ok}`\n"
155
+ )
156
+ return path
157
+
158
+
159
+ def parse_args(argv: list[str]) -> argparse.Namespace:
160
+ parser = argparse.ArgumentParser(description="Run Track A behavioural eval per variant.")
161
+ parser.add_argument(
162
+ "--variant",
163
+ choices=("with", "without", "both"),
164
+ default="both",
165
+ help="Which variant to run (default: both).",
166
+ )
167
+ return parser.parse_args(argv)
168
+
169
+
170
+ def main(argv: list[str] | None = None) -> int:
171
+ args = parse_args(argv if argv is not None else sys.argv[1:])
172
+ if not CORPUS_PATH.exists():
173
+ sys.stderr.write(f"bench_ab_tracka_run: corpus missing at {CORPUS_PATH}\n")
174
+ return 1
175
+ data = load_corpus()
176
+ prompts = data.get("prompts") or []
177
+ if not prompts:
178
+ sys.stderr.write("bench_ab_tracka_run: corpus has no prompts\n")
179
+ return 1
180
+
181
+ variants = ("with", "without") if args.variant == "both" else (args.variant,)
182
+ integrity_ok = True
183
+ for variant in variants:
184
+ started = time.monotonic()
185
+ results = run_variant(variant, prompts)
186
+ duration = time.monotonic() - started
187
+ if variant == "without":
188
+ ok, reason = integrity_check(results)
189
+ integrity_ok = ok
190
+ if not ok:
191
+ sys.stderr.write(f"bench_ab_tracka_run: integrity failure — {reason}\n")
192
+ path = write_report(variant, results, duration, integrity_ok=integrity_ok)
193
+ sys.stdout.write(
194
+ f"bench_ab_tracka_run: {variant} → "
195
+ f"{results['trigger_accuracy'] * 100:.1f}% "
196
+ f"({results['matched']}/{results['total']}) — {path.relative_to(REPO_ROOT)}\n"
197
+ )
198
+ return 0 if integrity_ok else 1
199
+
200
+
201
+ if __name__ == "__main__":
202
+ raise SystemExit(main())
@@ -2,7 +2,7 @@
2
2
  """Baseline-closure check — step-4 Phase 3 Step 4.
3
3
 
4
4
  Returns exit 0 iff the 60-day clock has elapsed since
5
- `bench/baseline-start.txt` AND `bench/reports/` contains at least
5
+ `internal/bench/baseline-start.txt` AND `internal/bench/reports/` contains at least
6
6
  `--min-reports` complete runs for the named corpus (default 30).
7
7
 
8
8
  Read by P2 enforcement roadmaps as their precondition (G1 gate in
@@ -50,8 +50,8 @@ def main(argv: list[str] | None = None) -> int:
50
50
  formatter_class=argparse.RawDescriptionHelpFormatter,
51
51
  )
52
52
  ap.add_argument("--corpus", default="dev")
53
- ap.add_argument("--reports-dir", default="bench/reports")
54
- ap.add_argument("--baseline-file", default="bench/baseline-start.txt")
53
+ ap.add_argument("--reports-dir", default="internal/bench/reports")
54
+ ap.add_argument("--baseline-file", default="internal/bench/baseline-start.txt")
55
55
  ap.add_argument("--min-days", type=int, default=60)
56
56
  ap.add_argument("--min-reports", type=int, default=30)
57
57
  ap.add_argument("--json", action="store_true")
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env python3
2
- """Offline bench for input-side memory compression (Phase 2 / Step 11).
2
+ """Offline bench for input-side memory condensation (Phase 2 / Step 11).
3
3
 
4
- Runs `compress_memory.py` over a fixed corpus of memory-target files, records
4
+ Runs `condense_memory.py` over a fixed corpus of memory-target files, records
5
5
  pre/post char counts, approximates input-token savings (chars / 4 — the
6
- GPT-4 / Claude rule of thumb), and emits `bench/reports/caveman-v2.{json,md}`.
6
+ GPT-4 / Claude rule of thumb), and emits `internal/bench/reports/telegraph-v2.{json,md}`.
7
7
 
8
8
  Offline (no API calls). Cadence-aligned with `docs/benchmarks.md`. Citation
9
- in `bench/reports/caveman-v2.md` notes the chars→tokens approximation and
9
+ in `internal/bench/reports/telegraph-v2.md` notes the chars→tokens approximation and
10
10
  points at upstream tiktoken / claude-tokenizer if a calibrated number is
11
11
  later needed.
12
12
  """
@@ -22,13 +22,13 @@ from datetime import datetime, timezone
22
22
  from pathlib import Path
23
23
 
24
24
  REPO_ROOT = Path(__file__).resolve().parent.parent
25
- COMPRESS_SCRIPT = REPO_ROOT / "scripts" / "compress_memory.py"
26
- REPORT_JSON = REPO_ROOT / "bench" / "reports" / "caveman-v2.json"
27
- REPORT_MD = REPO_ROOT / "bench" / "reports" / "caveman-v2.md"
25
+ CONDENSE_SCRIPT = REPO_ROOT / "scripts" / "condense_memory.py"
26
+ REPORT_JSON = REPO_ROOT / "internal" / "bench" / "reports" / "telegraph-v2.json"
27
+ REPORT_MD = REPO_ROOT / "internal" / "bench" / "reports" / "telegraph-v2.md"
28
28
 
29
29
  CORPUS: list[tuple[str, str]] = [
30
30
  ("AGENTS.md", "thin-root-package"),
31
- (".agent-src.uncompressed/templates/AGENTS.md", "thin-root-consumer-template"),
31
+ (".agent-src.uncondensed/templates/AGENTS.md", "thin-root-consumer-template"),
32
32
  (".agent-src/templates/AGENTS.md", "thin-root-consumer-generated"),
33
33
  ("docs/contracts/ai-council-config.md", "prose-heavy-contract"),
34
34
  ("docs/contracts/implement-ticket-flow.md", "prose-heavy-contract"),
@@ -56,7 +56,7 @@ def bench_one(rel_path: str, category: str) -> dict:
56
56
  shutil.copy(src, target)
57
57
  before_chars = target.stat().st_size
58
58
  result = subprocess.run(
59
- [sys.executable, str(COMPRESS_SCRIPT), str(target)],
59
+ [sys.executable, str(CONDENSE_SCRIPT), str(target)],
60
60
  capture_output=True, text=True, cwd=REPO_ROOT,
61
61
  )
62
62
  if result.returncode != 0:
@@ -101,11 +101,11 @@ def aggregate(rows: list[dict]) -> dict:
101
101
  def render_md(payload: dict) -> str:
102
102
  agg = payload["aggregate"]
103
103
  lines = [
104
- "# caveman-v2 — input-side memory compression bench",
104
+ "# telegraph-v2 — input-side memory condensation bench",
105
105
  "",
106
106
  f"**Generated:** {payload['generated_at']}",
107
- f"**Schema:** `caveman-v2` (input-side; offline; chars→tokens via /4 heuristic)",
108
- f"**Script:** `scripts/bench_compress_memory.py`",
107
+ f"**Schema:** `telegraph-v2` (input-side; offline; chars→tokens via /4 heuristic)",
108
+ f"**Script:** `scripts/bench_condense_memory.py`",
109
109
  "",
110
110
  "## Headline",
111
111
  "",
@@ -134,13 +134,13 @@ def render_md(payload: dict) -> str:
134
134
  )
135
135
  lines += ["", "## Methodology",
136
136
  "",
137
- "- Offline run: `compress_memory.py` writes `.original.md` backup + frontmatter (`original_sha256`, `compressed_at`). The frontmatter pair (≈ 120 chars) is the fixed compression tax — files with little prose net negative.",
137
+ "- Offline run: `condense_memory.py` writes `.original.md` backup + frontmatter (`original_sha256`, `condensed_at`). The frontmatter pair (≈ 120 chars) is the fixed condensation tax — files with little prose net negative.",
138
138
  "- chars → tokens approximation: `tokens ≈ chars / 4` (GPT-4 / Claude English rule of thumb). Calibrated number requires `tiktoken` or `claude-tokenizer`; deferred until a consumer requests pinpoint numbers.",
139
- "- The `caveman-v1` output-side verdict (`vs_terse` median −9.27%) is orthogonal — input-side savings apply to the always-loaded memory budget, not the reply stream.",
139
+ "- The `telegraph-v1` output-side verdict (`vs_terse` median −9.27%) is orthogonal — input-side savings apply to the always-loaded memory budget, not the reply stream.",
140
140
  "",
141
141
  "## Interpretation",
142
142
  "",
143
- "- **Thin-Root files net negative.** `AGENTS.md` and `templates/AGENTS.md` already follow `agents-md-thin-root` (≥ 40 % pointer ratio). The compressor's frontmatter pair adds more bytes than the sparse prose loses. **Do not compress Thin-Root files.**",
143
+ "- **Thin-Root files net negative.** `AGENTS.md` and `templates/AGENTS.md` already follow `agents-md-thin-root` (≥ 40 % pointer ratio). The condenseor's frontmatter pair adds more bytes than the sparse prose loses. **Do not condense Thin-Root files.**",
144
144
  "- **Prose-heavy contract docs net 3–6 % saving.** Useful but modest. Pays off when the file is large and frequently loaded.",
145
145
  "- **Rule of thumb:** target files with > 5 KB and visible paragraph prose; skip pointer-only files.",
146
146
  ""]
@@ -151,7 +151,7 @@ def main() -> int:
151
151
  rows = [bench_one(p, c) for p, c in CORPUS]
152
152
  payload = {
153
153
  "generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
154
- "schema": "caveman-v2",
154
+ "schema": "telegraph-v2",
155
155
  "rows": rows,
156
156
  "aggregate": aggregate(rows),
157
157
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  """Drift detector for the bench corpus — step-4 Phase 3 Step 2.
3
3
 
4
- Compares the latest `bench/reports/<stamp>-<corpus>.json` against the
4
+ Compares the latest `internal/bench/reports/<stamp>-<corpus>.json` against the
5
5
  previous N reports (default 5) for the same corpus. Drift defined as:
6
6
 
7
7
  - selection-accuracy: latest is more than `accuracy_drop_pp` below
@@ -99,7 +99,7 @@ def _check(latest: dict[str, Any], baseline: list[dict[str, Any]],
99
99
  def main(argv: list[str] | None = None) -> int:
100
100
  ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
101
101
  ap.add_argument("--corpus", default="dev")
102
- ap.add_argument("--reports-dir", default="bench/reports")
102
+ ap.add_argument("--reports-dir", default="internal/bench/reports")
103
103
  ap.add_argument("--window", type=int, default=5, help="rolling window size (default 5)")
104
104
  ap.add_argument("--accuracy-drop-pp", type=float, default=5.0)
105
105
  ap.add_argument("--cost-increase-pct", type=float, default=20.0)
@@ -43,7 +43,7 @@ from bench_runner import rank_skills # type: ignore # noqa: E402
43
43
 
44
44
  REPO_ROOT = Path(__file__).resolve().parent.parent
45
45
  CORPUS_DIR = REPO_ROOT / "tests" / "eval"
46
- REPORTS_DIR = REPO_ROOT / "bench" / "reports"
46
+ REPORTS_DIR = REPO_ROOT / "internal" / "bench" / "reports"
47
47
 
48
48
  # tool_id -> (skills_root, kind). kind = "skills" | "rules_only" | "single_file".
49
49
  SURFACES: dict[str, tuple[Path, str]] = {
@@ -185,7 +185,7 @@ def main(argv=None) -> int:
185
185
  ap.add_argument("--threshold", type=float, default=0.85)
186
186
  ap.add_argument("--json", action="store_true")
187
187
  ap.add_argument("--write-report", action="store_true",
188
- help="emit bench/reports/<ts>-<corpus>-projection.{json,md}")
188
+ help="emit internal/bench/reports/<ts>-<corpus>-projection.{json,md}")
189
189
  args = ap.parse_args(argv)
190
190
 
191
191
  corpus_path = CORPUS_DIR / f"corpus-{args.corpus}.yaml"
@@ -5,7 +5,7 @@ Wraps the selection-accuracy baseline collector (`scripts/bench_runner.py`),
5
5
  captures token / cost data from `agents/cost-tracking/sessions.jsonl` if
6
6
  present (per ruflo pattern, external-findings § 2), runs structural
7
7
  quality assertions per prompt, and emits a versioned JSON + Markdown
8
- report under `bench/reports/` per
8
+ report under `internal/bench/reports/` per
9
9
  `docs/contracts/benchmark-report-schema.md`.
10
10
 
11
11
  Usage:
@@ -34,8 +34,8 @@ from _lib.bench_report import ( # noqa: E402
34
34
  write_json,
35
35
  write_markdown,
36
36
  )
37
- from _lib import bench_caveman # noqa: E402
38
- from _lib.bench_caveman_report import build_caveman_report, render_caveman_markdown # noqa: E402
37
+ from _lib import bench_telegraph # noqa: E402
38
+ from _lib.bench_telegraph_report import build_telegraph_report, render_telegraph_markdown # noqa: E402
39
39
  from _lib.bench_cost import load_pricing # noqa: E402
40
40
  from bench_runner import run_corpus # noqa: E402
41
41
 
@@ -46,11 +46,11 @@ except ImportError:
46
46
  sys.exit(2)
47
47
 
48
48
  BENCH_RUN_VERSION = "0.2.0"
49
- PRICING_PATH = REPO_ROOT / "bench" / "pricing.yaml"
49
+ PRICING_PATH = REPO_ROOT / "internal" / "bench" / "pricing.yaml"
50
50
  SESSIONS_JSONL = REPO_ROOT / "agents" / "cost-tracking" / "sessions.jsonl"
51
- REPORTS_DIR = REPO_ROOT / "bench" / "reports"
51
+ REPORTS_DIR = REPO_ROOT / "internal" / "bench" / "reports"
52
52
  CORPUS_DIR = REPO_ROOT / "tests" / "eval"
53
- CAVEMAN_CORPUS = REPO_ROOT / "bench" / "corpora" / "caveman" / "prompts.yaml"
53
+ TELEGRAPH_CORPUS = REPO_ROOT / "internal" / "bench" / "corpora" / "telegraph" / "prompts.yaml"
54
54
  BASELINE_COLLECTOR = REPO_ROOT / "scripts" / "bench_runner.py"
55
55
 
56
56
 
@@ -115,20 +115,20 @@ def main(argv: list[str] | None = None) -> int:
115
115
  help="Override timestamp (test hook); defaults to UTC now")
116
116
  ap.add_argument("--no-write", action="store_true",
117
117
  help="Compute the report but do not write files (dry run)")
118
- ap.add_argument("--caveman", action="store_true",
119
- help="Run the caveman three-arm compression bench instead of the "
118
+ ap.add_argument("--telegraph", action="store_true",
119
+ help="Run the telegraph three-arm condensation bench instead of the "
120
120
  "selection-accuracy bench (step-16 Phase 1).")
121
- ap.add_argument("--caveman-max-prompts", type=int, default=None,
122
- help="Cap prompts in the caveman bench (smoke test).")
123
- ap.add_argument("--caveman-dry-run", action="store_true",
124
- help="Caveman: skip live API calls; emit a stub report with "
121
+ ap.add_argument("--telegraph-max-prompts", type=int, default=None,
122
+ help="Cap prompts in the telegraph bench (smoke test).")
123
+ ap.add_argument("--telegraph-dry-run", action="store_true",
124
+ help="Telegraph: skip live API calls; emit a stub report with "
125
125
  "zero tokens (wiring check only).")
126
- ap.add_argument("--caveman-report-tag", default="caveman-v1",
127
- help="Filename tag for the caveman report (default: caveman-v1).")
126
+ ap.add_argument("--telegraph-report-tag", default="telegraph-v1",
127
+ help="Filename tag for the telegraph report (default: telegraph-v1).")
128
128
  args = ap.parse_args(argv)
129
129
 
130
- if args.caveman:
131
- return _run_caveman(args)
130
+ if args.telegraph:
131
+ return _run_telegraph(args)
132
132
 
133
133
  corpus_path = CORPUS_DIR / f"corpus-{args.corpus}.yaml"
134
134
  if not corpus_path.is_file():
@@ -170,7 +170,7 @@ def main(argv: list[str] | None = None) -> int:
170
170
 
171
171
 
172
172
  class _DryRunClient:
173
- """Stub client for --caveman-dry-run. Returns empty CouncilResponse-shaped objects."""
173
+ """Stub client for --telegraph-dry-run. Returns empty CouncilResponse-shaped objects."""
174
174
 
175
175
  def ask(self, system_prompt: str, user_prompt: str, max_tokens: int = 1024):
176
176
  from ai_council.clients import CouncilResponse
@@ -185,12 +185,12 @@ def _build_anthropic_client():
185
185
  return AnthropicClient(api_key=load_anthropic_key())
186
186
 
187
187
 
188
- def _run_caveman(args: argparse.Namespace) -> int:
189
- if not CAVEMAN_CORPUS.is_file():
190
- script_output.error(f"error: caveman corpus not found: {CAVEMAN_CORPUS}")
188
+ def _run_telegraph(args: argparse.Namespace) -> int:
189
+ if not TELEGRAPH_CORPUS.is_file():
190
+ script_output.error(f"error: telegraph corpus not found: {TELEGRAPH_CORPUS}")
191
191
  return 2
192
192
 
193
- if args.caveman_dry_run:
193
+ if args.telegraph_dry_run:
194
194
  client = _DryRunClient()
195
195
  transport = "dry-run"
196
196
  model = "stub"
@@ -211,18 +211,18 @@ def _run_caveman(args: argparse.Namespace) -> int:
211
211
  f"in={ar.input_tokens:>4} out={ar.output_tokens:>4} "
212
212
  f"{ar.latency_ms:>5}ms{err}", file=sys.stderr)
213
213
 
214
- results = bench_caveman.run_caveman_bench(
215
- client, CAVEMAN_CORPUS,
216
- max_prompts=args.caveman_max_prompts,
214
+ results = bench_telegraph.run_telegraph_bench(
215
+ client, TELEGRAPH_CORPUS,
216
+ max_prompts=args.telegraph_max_prompts,
217
217
  on_progress=_progress,
218
218
  )
219
219
 
220
220
  rates, sourced_on = load_pricing(PRICING_PATH)
221
221
  sonnet_rates = rates.get("sonnet", {"input": 0.0, "output": 0.0})
222
222
 
223
- report = build_caveman_report(
223
+ report = build_telegraph_report(
224
224
  results=results,
225
- corpus_path_rel=str(CAVEMAN_CORPUS.relative_to(REPO_ROOT)),
225
+ corpus_path_rel=str(TELEGRAPH_CORPUS.relative_to(REPO_ROOT)),
226
226
  generated_at=utc_now_iso(),
227
227
  bench_run_version=BENCH_RUN_VERSION,
228
228
  model=model,
@@ -232,27 +232,27 @@ def _run_caveman(args: argparse.Namespace) -> int:
232
232
  )
233
233
 
234
234
  stamp = args.stamp or utc_now_filename_stamp()
235
- json_path, md_path = report_paths(REPORTS_DIR, args.caveman_report_tag, stamp)
236
- # Override: caveman roadmap pins the filename to `caveman-v1.{json,md}` (no stamp).
237
- fixed_json = REPORTS_DIR / f"{args.caveman_report_tag}.json"
238
- fixed_md = REPORTS_DIR / f"{args.caveman_report_tag}.md"
235
+ json_path, md_path = report_paths(REPORTS_DIR, args.telegraph_report_tag, stamp)
236
+ # Override: telegraph roadmap pins the filename to `telegraph-v1.{json,md}` (no stamp).
237
+ fixed_json = REPORTS_DIR / f"{args.telegraph_report_tag}.json"
238
+ fixed_md = REPORTS_DIR / f"{args.telegraph_report_tag}.md"
239
239
 
240
240
  if not args.no_write:
241
241
  write_json(fixed_json, report)
242
242
  fixed_md.parent.mkdir(parents=True, exist_ok=True)
243
- fixed_md.write_text(render_caveman_markdown(report), encoding="utf-8")
243
+ fixed_md.write_text(render_telegraph_markdown(report), encoding="utf-8")
244
244
  # Also drop a timestamped copy for the cadence trail.
245
245
  write_json(json_path, report)
246
246
  json_path.with_suffix(".md").write_text(
247
- render_caveman_markdown(report), encoding="utf-8"
247
+ render_telegraph_markdown(report), encoding="utf-8"
248
248
  )
249
249
 
250
250
  cost = report["cost"]
251
251
  headline = (
252
- f"caveman · prompts {report['corpus']['prompt_count']} · "
252
+ f"telegraph · prompts {report['corpus']['prompt_count']} · "
253
253
  f"calls {cost['totals']['calls']} · errors {cost['totals']['errors']} · "
254
- f"vs_raw med {report['caveman']['aggregate']['savings_vs_raw']['median']:.2%} · "
255
- f"vs_terse med {report['caveman']['aggregate']['savings_vs_terse']['median']:.2%} · "
254
+ f"vs_raw med {report['telegraph']['aggregate']['savings_vs_raw']['median']:.2%} · "
255
+ f"vs_terse med {report['telegraph']['aggregate']['savings_vs_terse']['median']:.2%} · "
256
256
  f"cost ${cost['totals']['total_cost_usd']:.6f}"
257
257
  )
258
258
  if args.quiet:
@@ -260,7 +260,7 @@ def _run_caveman(args: argparse.Namespace) -> int:
260
260
  if not args.no_write:
261
261
  print(f"report: {fixed_md.relative_to(REPO_ROOT)}")
262
262
  else:
263
- print(render_caveman_markdown(report))
263
+ print(render_telegraph_markdown(report))
264
264
  if not args.no_write:
265
265
  print(f"\n→ json: {fixed_json.relative_to(REPO_ROOT)}")
266
266
  print(f"→ markdown: {fixed_md.relative_to(REPO_ROOT)}")
@@ -2,7 +2,7 @@
2
2
  """Bench runner for the eval corpora — step-4 measurement-and-benchmark Phase 1.
3
3
 
4
4
  Deterministic, no-API skill-selection baseline. For each prompt in a
5
- corpus YAML, ranks the 210 skills in `.agent-src.uncompressed/skills/`
5
+ corpus YAML, ranks the 210 skills in `.agent-src.uncondensed/skills/`
6
6
  by keyword overlap between the prompt text and each skill's
7
7
  `description` frontmatter field. Reports selection accuracy as
8
8
  `top-K contains >= 1 expected_skill`.
@@ -33,7 +33,7 @@ except ImportError:
33
33
  sys.exit(2)
34
34
 
35
35
  REPO_ROOT = Path(__file__).resolve().parent.parent
36
- SKILLS_DIR = REPO_ROOT / ".agent-src.uncompressed" / "skills"
36
+ SKILLS_DIR = REPO_ROOT / ".agent-src.uncondensed" / "skills"
37
37
  CORPUS_DIR = REPO_ROOT / "tests" / "eval"
38
38
 
39
39
  STOPWORDS = frozenset({
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env bash
2
+ # bootstrap.sh — Thin Bash entry for the v4 unified setup wizard.
3
+ #
4
+ # road-to-unified-setup § C1. Replaces the legacy Python boot path.
5
+ # Flow:
6
+ # 1. Verify Node ≥ 20.11.0 (the package engines bound).
7
+ # 2. Launch `npx @event4u/agent-config <subcommand>` in the background.
8
+ # 3. Tail stdout for the `WIZARD_READY <url>` marker (Phase B4).
9
+ # 4. Open the URL in the user's browser (best-effort; no fatal error
10
+ # when no `open` / `xdg-open` is available — print the URL instead).
11
+ # 5. Wait for the server process so Ctrl-C tears the wizard down cleanly.
12
+ #
13
+ # Usage:
14
+ # scripts/bootstrap.sh install # default — install wizard
15
+ # scripts/bootstrap.sh setup
16
+ # scripts/bootstrap.sh setup --no-extended
17
+ # AGENT_CONFIG_NO_OPEN=1 scripts/bootstrap.sh install # CI / headless
18
+ #
19
+ # Exit codes:
20
+ # 0 — wizard process exited cleanly
21
+ # 1 — Node missing or below the engines bound
22
+ # 2 — WIZARD_READY did not arrive within 30 seconds
23
+ # 3 — npx invocation failed before the marker
24
+ set -euo pipefail
25
+
26
+ MIN_NODE_MAJOR=20
27
+ MIN_NODE_MINOR=11
28
+ TIMEOUT_SECONDS=30
29
+ SUBCOMMAND="${1:-install}"
30
+ shift || true
31
+
32
+ if ! command -v node >/dev/null 2>&1; then
33
+ echo "error: Node.js not found in PATH (need ≥ ${MIN_NODE_MAJOR}.${MIN_NODE_MINOR}.0)." >&2
34
+ echo "install Node first — https://nodejs.org/" >&2
35
+ exit 1
36
+ fi
37
+
38
+ NODE_VERSION="$(node -p 'process.versions.node')"
39
+ NODE_MAJOR="${NODE_VERSION%%.*}"
40
+ NODE_MINOR="$(node -p 'process.versions.node.split(".")[1]')"
41
+ if [ "${NODE_MAJOR}" -lt "${MIN_NODE_MAJOR}" ] \
42
+ || { [ "${NODE_MAJOR}" -eq "${MIN_NODE_MAJOR}" ] && [ "${NODE_MINOR}" -lt "${MIN_NODE_MINOR}" ]; }; then
43
+ echo "error: Node ${NODE_VERSION} is below the required ${MIN_NODE_MAJOR}.${MIN_NODE_MINOR}.0." >&2
44
+ exit 1
45
+ fi
46
+
47
+ PIPE="$(mktemp -u "${TMPDIR:-/tmp}/agent-config-bootstrap.XXXXXX")"
48
+ mkfifo "${PIPE}"
49
+ trap 'rm -f "${PIPE}"' EXIT
50
+
51
+ # Always pass --no-open here — the bootstrap script owns the browser
52
+ # launch so it can defer it until after WIZARD_READY arrives.
53
+ npx --yes @event4u/agent-config "${SUBCOMMAND}" --no-open "$@" >"${PIPE}" 2>&1 &
54
+ NPX_PID=$!
55
+
56
+ URL=""
57
+ DEADLINE=$(( $(date +%s) + TIMEOUT_SECONDS ))
58
+ while IFS= read -r line; do
59
+ printf '%s\n' "${line}"
60
+ if [[ "${line}" == WIZARD_READY\ * ]]; then
61
+ URL="${line#WIZARD_READY }"
62
+ break
63
+ fi
64
+ if [ "$(date +%s)" -ge "${DEADLINE}" ]; then
65
+ echo "error: WIZARD_READY did not arrive within ${TIMEOUT_SECONDS}s." >&2
66
+ kill "${NPX_PID}" 2>/dev/null || true
67
+ exit 2
68
+ fi
69
+ done <"${PIPE}" &
70
+ READER_PID=$!
71
+
72
+ # If npx died before we saw the marker, surface the failure.
73
+ if ! kill -0 "${NPX_PID}" 2>/dev/null; then
74
+ wait "${READER_PID}" || true
75
+ echo "error: npx exited before WIZARD_READY arrived." >&2
76
+ exit 3
77
+ fi
78
+
79
+ wait "${READER_PID}" || true
80
+
81
+ if [ -z "${URL}" ]; then
82
+ echo "error: server did not emit WIZARD_READY." >&2
83
+ kill "${NPX_PID}" 2>/dev/null || true
84
+ exit 2
85
+ fi
86
+
87
+ if [ -z "${AGENT_CONFIG_NO_OPEN:-}" ]; then
88
+ if command -v open >/dev/null 2>&1; then
89
+ open "${URL}" || true
90
+ elif command -v xdg-open >/dev/null 2>&1; then
91
+ xdg-open "${URL}" >/dev/null 2>&1 || true
92
+ else
93
+ echo "info: open the wizard manually: ${URL}"
94
+ fi
95
+ fi
96
+
97
+ # Keep streaming stdout so the user sees server logs until Ctrl-C.
98
+ cat "${PIPE}" &
99
+ wait "${NPX_PID}"