@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
@@ -50,6 +50,7 @@ Contract — pure, read-only, tolerant:
50
50
  """
51
51
  from __future__ import annotations
52
52
 
53
+ import copy
53
54
  import logging
54
55
  import os
55
56
  from pathlib import Path
@@ -60,6 +61,7 @@ from . import user_global_paths
60
61
  logger = logging.getLogger(__name__)
61
62
 
62
63
  DEFAULT_PROJECT_FILE = ".agent-settings.yml"
64
+ DEFAULT_TEAM_FILE = ".agent-project-settings.yml"
63
65
  USER_GLOBAL_FILENAME = "agent-settings.yml"
64
66
 
65
67
  #: Canonical write target under the new ``~/.event4u/agent-config/``
@@ -86,11 +88,25 @@ MERGEABLE_KEYS: tuple[str, ...] = (
86
88
  "cost_profile",
87
89
  "personal.bot_icon",
88
90
  "personal.autonomy",
89
- "caveman.speak_scope",
91
+ "telegraph.speak_scope",
90
92
  )
91
93
 
92
94
  _DEFAULTS: dict[str, Any] = {}
93
95
 
96
+ #: Defaults applied by :func:`get_modules_config` when a key is absent
97
+ #: from both the team file and the developer cascade. The values mirror
98
+ #: the ``modules:`` block shipped in
99
+ #: ``templates/agents/agent-project-settings.example.yml``. Lists are
100
+ #: returned as fresh copies — callers may mutate the result safely.
101
+ MODULES_DEFAULTS: dict[str, Any] = {
102
+ "enabled": False,
103
+ "root_paths": [],
104
+ "namespace_template": "",
105
+ "agent_folder": "agents",
106
+ "skip_dirs": [".module-template", ".example"],
107
+ "detection_acknowledged": False,
108
+ }
109
+
94
110
 
95
111
  #: Anchor identifier returned by :func:`find_project_root_with_anchor`.
96
112
  ANCHOR_AGENT_SETTINGS = "agent-settings"
@@ -470,6 +486,184 @@ def load_agent_settings(
470
486
  return merged
471
487
 
472
488
 
489
+ def get_modules_config(
490
+ project_root: Path | str | None = None,
491
+ team_path: Path | str | None = None,
492
+ project_path: Path | str | None = None,
493
+ cwd: Path | None = None,
494
+ ) -> dict[str, Any]:
495
+ """Return the merged ``modules:`` configuration with defaults applied.
496
+
497
+ Three-tier precedence (deepest wins) per the layered-settings model
498
+ documented in ``docs/guidelines/agent-infra/layered-settings.md``:
499
+
500
+ 1. :data:`MODULES_DEFAULTS` — package-shipped defaults.
501
+ 2. Team file — ``<project_root>/.agent-project-settings.yml``
502
+ (committed, all developers see the same values).
503
+ 3. Developer cascade — every ``.agent-settings.yml`` walked by
504
+ :func:`_resolve_cascade_paths` (git-ignored local overrides).
505
+
506
+ The team layer may pin keys via a top-level ``locked_keys`` list of
507
+ dotted paths (e.g. ``[modules.root_paths]``). Locked keys discard any
508
+ matching override from the developer cascade and emit a ``logging``
509
+ INFO record. Locks are advisory — the team file always wins anyway —
510
+ but the explicit list makes the intent reviewable and gives the loader
511
+ a hook for the warning.
512
+
513
+ ``project_root`` defaults to ``find_project_root(cwd or Path.cwd())``.
514
+ ``team_path`` overrides the resolved team-file location for tests.
515
+ ``project_path`` + ``cwd`` flow through to :func:`load_agent_settings`
516
+ unchanged.
517
+
518
+ Pure, read-only — no file is ever written. Missing files / malformed
519
+ YAML / absent ``modules:`` block all return the defaults.
520
+ """
521
+ cwd_resolved = cwd if cwd is not None else Path.cwd()
522
+
523
+ if team_path is not None:
524
+ team_file = Path(team_path)
525
+ else:
526
+ if project_root is not None:
527
+ root = Path(project_root)
528
+ else:
529
+ root = find_project_root(cwd_resolved) or cwd_resolved
530
+ team_file = root / DEFAULT_TEAM_FILE
531
+
532
+ team_raw = _read_yaml(team_file) or {}
533
+ team_modules = team_raw.get("modules") if isinstance(team_raw.get("modules"), dict) else {}
534
+ locked_keys_raw = team_raw.get("locked_keys")
535
+ locked_keys: tuple[str, ...] = tuple(
536
+ k for k in (locked_keys_raw or []) if isinstance(k, str)
537
+ )
538
+
539
+ dev_merged = load_agent_settings(
540
+ project_path=project_path,
541
+ cwd=cwd,
542
+ )
543
+ dev_modules = dev_merged.get("modules") if isinstance(dev_merged.get("modules"), dict) else {}
544
+
545
+ merged: dict[str, Any] = copy.deepcopy(MODULES_DEFAULTS)
546
+ if team_modules:
547
+ _deep_merge(merged, team_modules)
548
+
549
+ if dev_modules:
550
+ for key, value in dev_modules.items():
551
+ dotted = f"modules.{key}"
552
+ if dotted in locked_keys and key in (team_modules or {}):
553
+ logger.info(
554
+ "agent_settings: ignoring developer override of locked key %s",
555
+ dotted,
556
+ )
557
+ continue
558
+ if isinstance(value, dict) and isinstance(merged.get(key), dict):
559
+ _deep_merge(merged[key], value)
560
+ else:
561
+ merged[key] = value
562
+
563
+ return merged
564
+
565
+
566
+ def enumerate_modules(
567
+ project_root: Path | str | None = None,
568
+ cwd: Path | None = None,
569
+ modules_config: dict[str, Any] | None = None,
570
+ ) -> list[dict[str, Any]]:
571
+ """Enumerate every module under ``modules.root_paths``.
572
+
573
+ Phase D Step 1 of road-to-configurable-modules. For each path in
574
+ ``modules.root_paths`` (resolved relative to ``project_root``), lists
575
+ immediate subdirectories that survive the ``modules.skip_dirs`` filter
576
+ and reports whether each module ships a per-module agent folder
577
+ (``modules.agent_folder``, default ``agents``).
578
+
579
+ Returns a list of dicts \u2014 one per discovered module \u2014 sorted by
580
+ ``(root_path, name)`` for deterministic output:
581
+
582
+ * ``name`` \u2014 directory name of the module
583
+ * ``root_path`` \u2014 repo-relative root containing the module
584
+ * ``module_path`` \u2014 repo-relative path to the module itself
585
+ * ``has_agent_folder`` \u2014 ``True`` iff a directory matching
586
+ ``modules.agent_folder`` lives directly under the module
587
+ * ``agent_folder_path`` \u2014 repo-relative path to that folder
588
+ (``None`` when ``has_agent_folder`` is ``False``)
589
+
590
+ Contract:
591
+
592
+ * ``modules.enabled`` is **not** consulted \u2014 callers decide whether
593
+ to skip the call. Disabled projects normally yield ``[]`` because
594
+ ``root_paths`` is empty by default.
595
+ * Missing roots are skipped silently (logged at INFO).
596
+ * Hidden directories (leading ``.``) and entries in
597
+ ``modules.skip_dirs`` are filtered out.
598
+ * Symlinks are followed only when they resolve inside the project
599
+ root \u2014 same boundary as ``find_project_root``.
600
+ * Pure, read-only \u2014 no file or directory is ever written.
601
+
602
+ ``modules_config`` lets tests inject a pre-built dict; when ``None``
603
+ the function calls :func:`get_modules_config` with the same
604
+ ``project_root`` / ``cwd`` so the precedence chain matches.
605
+ """
606
+ cwd_resolved = cwd if cwd is not None else Path.cwd()
607
+ if project_root is not None:
608
+ root = Path(project_root)
609
+ else:
610
+ root = find_project_root(cwd_resolved) or cwd_resolved
611
+ root = root.resolve()
612
+
613
+ if modules_config is None:
614
+ modules_config = get_modules_config(project_root=root, cwd=cwd)
615
+
616
+ root_paths_raw = modules_config.get("root_paths") or []
617
+ skip_dirs_raw = modules_config.get("skip_dirs") or MODULES_DEFAULTS["skip_dirs"]
618
+ agent_folder = str(modules_config.get("agent_folder") or MODULES_DEFAULTS["agent_folder"])
619
+
620
+ skip_dirs: set[str] = {str(s) for s in skip_dirs_raw if isinstance(s, str)}
621
+
622
+ discovered: list[dict[str, Any]] = []
623
+ for raw in root_paths_raw:
624
+ if not isinstance(raw, str) or not raw.strip():
625
+ continue
626
+ root_rel = raw.strip().strip("/")
627
+ root_abs = (root / root_rel).resolve()
628
+ try:
629
+ if not root_abs.is_dir() or not str(root_abs).startswith(str(root)):
630
+ logger.info("enumerate_modules: skipping missing/out-of-tree root %s", root_rel)
631
+ continue
632
+ except OSError:
633
+ logger.info("enumerate_modules: unreadable root %s", root_rel)
634
+ continue
635
+
636
+ try:
637
+ children = sorted(root_abs.iterdir(), key=lambda p: p.name)
638
+ except OSError:
639
+ logger.info("enumerate_modules: cannot list %s", root_rel)
640
+ continue
641
+
642
+ for child in children:
643
+ name = child.name
644
+ if name.startswith(".") or name in skip_dirs:
645
+ continue
646
+ if not child.is_dir():
647
+ continue
648
+ agent_dir = child / agent_folder
649
+ has_agent = agent_dir.is_dir()
650
+ try:
651
+ module_rel = child.resolve().relative_to(root)
652
+ except ValueError:
653
+ continue
654
+ entry: dict[str, Any] = {
655
+ "name": name,
656
+ "root_path": root_rel,
657
+ "module_path": str(module_rel),
658
+ "has_agent_folder": has_agent,
659
+ "agent_folder_path": str(module_rel / agent_folder) if has_agent else None,
660
+ }
661
+ discovered.append(entry)
662
+
663
+ discovered.sort(key=lambda m: (m["root_path"], m["name"]))
664
+ return discovered
665
+
666
+
473
667
  def iter_setting_overrides(
474
668
  project_path: Path | str | None = None,
475
669
  user_global_path: Path | str | None = None,
@@ -1,17 +1,17 @@
1
1
  """Locate artefact source roots across the monorepo physical layout.
2
2
 
3
3
  Phase 4 of the monorepo migration (ADR-017) physically moves source
4
- artefacts out of the flat ``.agent-src.uncompressed/`` directory into
5
- ``packages/core/.agent-src.uncompressed/`` and
6
- ``packages/pack-*/.agent-src.uncompressed/`` trees. This helper hides
4
+ artefacts out of the flat ``.agent-src.uncondensed/`` directory into
5
+ ``packages/core/.agent-src.uncondensed/`` and
6
+ ``packages/pack-*/.agent-src.uncondensed/`` trees. This helper hides
7
7
  that decision from every scanner so they keep working pre-move and
8
8
  post-move with the same call shape.
9
9
 
10
10
  Contract:
11
11
 
12
12
  - ``artefact_roots()`` returns every directory that contains source
13
- ``.md`` artefacts. Pre-move that is ``.agent-src.uncompressed/`` at
14
- the repo root. Post-move it is every ``packages/*/.agent-src.uncompressed/``.
13
+ ``.md`` artefacts. Pre-move that is ``.agent-src.uncondensed/`` at
14
+ the repo root. Post-move it is every ``packages/*/.agent-src.uncondensed/``.
15
15
  Both can coexist during the migration window.
16
16
  - ``iter_artefacts()`` yields every source ``.md`` path under those roots.
17
17
  - ``logical_relpath(p)`` returns the artefact's stable identity path
@@ -19,7 +19,7 @@ Contract:
19
19
  root contains it. This is what manifests, hash maps, and projections
20
20
  use as the artefact key.
21
21
  - ``strip_source_prefix(p)`` returns the same as ``logical_relpath``
22
- but accepts repo-relative POSIX strings (used by the compressor's
22
+ but accepts repo-relative POSIX strings (used by the condenseor's
23
23
  output-path computation and the LEGACY_SRC_PREFIX logic).
24
24
  """
25
25
  from __future__ import annotations
@@ -28,22 +28,22 @@ from pathlib import Path
28
28
  from typing import Iterator
29
29
 
30
30
  ROOT = Path(__file__).resolve().parents[2]
31
- LEGACY_SRC = ROOT / ".agent-src.uncompressed"
31
+ LEGACY_SRC = ROOT / ".agent-src.uncondensed"
32
32
  PACKAGES = ROOT / "packages"
33
33
 
34
34
  # Repo-relative POSIX path prefixes that anchor an artefact source tree.
35
35
  # Order: legacy first (kept until the move lands), then packages/*. Each
36
36
  # entry is the prefix that gets stripped to obtain the logical path.
37
- _LEGACY_PREFIX = ".agent-src.uncompressed/"
38
- _PACKAGE_SUFFIX = "/.agent-src.uncompressed/"
37
+ _LEGACY_PREFIX = ".agent-src.uncondensed/"
38
+ _PACKAGE_SUFFIX = "/.agent-src.uncondensed/"
39
39
 
40
40
 
41
41
  def artefact_roots() -> list[Path]:
42
42
  """Every existing directory that contains source ``.md`` artefacts.
43
43
 
44
- Returns at most one ``.agent-src.uncompressed/`` root (legacy) plus
44
+ Returns at most one ``.agent-src.uncondensed/`` root (legacy) plus
45
45
  one root per ``packages/*/`` subdirectory that exposes its own
46
- ``.agent-src.uncompressed/`` tree. Order is stable: legacy first,
46
+ ``.agent-src.uncondensed/`` tree. Order is stable: legacy first,
47
47
  then ``packages/`` entries sorted alphabetically.
48
48
  """
49
49
  roots: list[Path] = []
@@ -51,7 +51,7 @@ def artefact_roots() -> list[Path]:
51
51
  roots.append(LEGACY_SRC)
52
52
  if PACKAGES.exists():
53
53
  for pkg in sorted(PACKAGES.iterdir()):
54
- sub = pkg / ".agent-src.uncompressed"
54
+ sub = pkg / ".agent-src.uncondensed"
55
55
  if sub.is_dir():
56
56
  roots.append(sub)
57
57
  return roots
@@ -111,11 +111,11 @@ def logical_relpath(path: Path) -> str:
111
111
  """Return the artefact's logical identity path (POSIX, no prefix).
112
112
 
113
113
  Examples:
114
- ``.agent-src.uncompressed/skills/laravel/SKILL.md``
114
+ ``.agent-src.uncondensed/skills/laravel/SKILL.md``
115
115
  → ``skills/laravel/SKILL.md``
116
- ``packages/pack-laravel/.agent-src.uncompressed/skills/laravel/SKILL.md``
116
+ ``packages/pack-laravel/.agent-src.uncondensed/skills/laravel/SKILL.md``
117
117
  → ``skills/laravel/SKILL.md``
118
- ``packages/core/.agent-src.uncompressed/rules/scope-control.md``
118
+ ``packages/core/.agent-src.uncondensed/rules/scope-control.md``
119
119
  → ``rules/scope-control.md``
120
120
 
121
121
  Raises ``ValueError`` if ``path`` is not under any known source root.
@@ -130,15 +130,15 @@ def logical_relpath(path: Path) -> str:
130
130
 
131
131
 
132
132
  def strip_source_prefix(rel: str) -> str | None:
133
- """Strip the ``.agent-src.uncompressed/`` anchor from a repo-relative path.
133
+ """Strip the ``.agent-src.uncondensed/`` anchor from a repo-relative path.
134
134
 
135
135
  Accepts both the legacy flat layout and the monorepo packages layout.
136
136
  Returns ``None`` if the path is not under any source root.
137
137
 
138
138
  Examples:
139
- ``".agent-src.uncompressed/rules/foo.md"`` → ``"rules/foo.md"``
140
- ``"packages/core/.agent-src.uncompressed/rules/foo.md"`` → ``"rules/foo.md"``
141
- ``"packages/pack-laravel/.agent-src.uncompressed/skills/x/SKILL.md"``
139
+ ``".agent-src.uncondensed/rules/foo.md"`` → ``"rules/foo.md"``
140
+ ``"packages/core/.agent-src.uncondensed/rules/foo.md"`` → ``"rules/foo.md"``
141
+ ``"packages/pack-laravel/.agent-src.uncondensed/skills/x/SKILL.md"``
142
142
  → ``"skills/x/SKILL.md"``
143
143
  ``"docs/architecture.md"`` → ``None``
144
144
  """
@@ -0,0 +1,162 @@
1
+ """Baseline-cache helpers for the package-impact A/B bench.
2
+
3
+ Phase 2 Step 2 of `agents/roadmaps/road-to-package-impact-benchmark.md`.
4
+
5
+ A daily `task bench:ab` run wants to skip re-running the `without` arm when
6
+ nothing the model would see has changed. We define "changed" by a three-part
7
+ key:
8
+
9
+ (corpus_hash, claude_cli_version, target_shape_hash)
10
+
11
+ Cached `without` reports live under `internal/bench/reports/ab/`. Each report
12
+ header records the cache key inputs; this module reads the directory, picks
13
+ the latest matching report, and reports freshness.
14
+ """
15
+ from __future__ import annotations
16
+
17
+ import hashlib
18
+ import json
19
+ import os
20
+ import shutil
21
+ import subprocess
22
+ from dataclasses import dataclass
23
+ from pathlib import Path
24
+
25
+ REPO_ROOT = Path(__file__).resolve().parents[2]
26
+ REPORTS_DIR = REPO_ROOT / "internal" / "bench" / "reports" / "ab"
27
+
28
+
29
+ @dataclass(frozen=True)
30
+ class CacheKey:
31
+ corpus_hash: str
32
+ claude_cli_version: str
33
+ target_shape_hash: str
34
+
35
+ def to_dict(self) -> dict[str, str]:
36
+ return {
37
+ "corpus_hash": self.corpus_hash,
38
+ "claude_cli_version": self.claude_cli_version,
39
+ "target_shape_hash": self.target_shape_hash,
40
+ }
41
+
42
+ @classmethod
43
+ def from_dict(cls, data: dict[str, str]) -> "CacheKey":
44
+ return cls(
45
+ corpus_hash=data.get("corpus_hash", ""),
46
+ claude_cli_version=data.get("claude_cli_version", ""),
47
+ target_shape_hash=data.get("target_shape_hash", ""),
48
+ )
49
+
50
+
51
+ @dataclass(frozen=True)
52
+ class CacheLookup:
53
+ found: bool
54
+ fresh: bool
55
+ report_path: Path | None
56
+ cached_key: CacheKey | None
57
+ reason: str # human-readable: "missing", "fresh", "stale: corpus", etc.
58
+
59
+
60
+ def hash_file(path: Path) -> str:
61
+ """SHA-256 of a single file (used for corpus_hash)."""
62
+ h = hashlib.sha256()
63
+ with path.open("rb") as fh:
64
+ for chunk in iter(lambda: fh.read(65536), b""):
65
+ h.update(chunk)
66
+ return h.hexdigest()[:16]
67
+
68
+
69
+ def claude_cli_version() -> str:
70
+ """Best-effort: `claude --version` or fallback to the env CLAUDE_CLI_VERSION.
71
+
72
+ When the CLI is missing, return "unavailable:<reason>" so the cache key
73
+ still varies meaningfully when the CLI is later installed.
74
+ """
75
+ override = os.environ.get("CLAUDE_CLI_VERSION")
76
+ if override:
77
+ return override.strip()
78
+ if shutil.which("claude") is None:
79
+ return "unavailable:not-on-path"
80
+ try:
81
+ out = subprocess.run(
82
+ ["claude", "--version"],
83
+ capture_output=True,
84
+ text=True,
85
+ timeout=10,
86
+ check=False,
87
+ )
88
+ except (OSError, subprocess.TimeoutExpired) as err:
89
+ return f"unavailable:{type(err).__name__}"
90
+ if out.returncode != 0:
91
+ return f"unavailable:exit-{out.returncode}"
92
+ return (out.stdout or out.stderr).strip().splitlines()[0] if out.stdout or out.stderr else "unknown"
93
+
94
+
95
+ def target_shape_hash() -> str:
96
+ """Re-export the shape hash from the clone script for a single source of truth."""
97
+ import importlib.util
98
+
99
+ spec = importlib.util.spec_from_file_location(
100
+ "bench_ab_clone", REPO_ROOT / "scripts" / "bench_ab_clone.py"
101
+ )
102
+ if spec is None or spec.loader is None:
103
+ return "unknown"
104
+ module = importlib.util.module_from_spec(spec)
105
+ spec.loader.exec_module(module)
106
+ return module.target_shape_hash() # type: ignore[no-any-return]
107
+
108
+
109
+ def build_key(corpus_path: Path) -> CacheKey:
110
+ return CacheKey(
111
+ corpus_hash=hash_file(corpus_path),
112
+ claude_cli_version=claude_cli_version(),
113
+ target_shape_hash=target_shape_hash(),
114
+ )
115
+
116
+
117
+ def iter_cached_reports(variant: str = "without") -> list[Path]:
118
+ """Return all report JSON paths under reports/ab/ for the given variant.
119
+
120
+ Filenames follow `{stamp}-{corpus}-{variant}.json` (Phase 2 Step 3).
121
+ """
122
+ if not REPORTS_DIR.exists():
123
+ return []
124
+ matches = sorted(REPORTS_DIR.glob(f"*-{variant}.json"))
125
+ return list(matches)
126
+
127
+
128
+ def read_report_key(report_path: Path) -> CacheKey | None:
129
+ try:
130
+ data = json.loads(report_path.read_text())
131
+ except (OSError, json.JSONDecodeError):
132
+ return None
133
+ raw = data.get("cache_key")
134
+ if not isinstance(raw, dict):
135
+ return None
136
+ return CacheKey.from_dict({k: str(v) for k, v in raw.items()})
137
+
138
+
139
+ def lookup(corpus_path: Path) -> CacheLookup:
140
+ """Find the latest cached `without` report and report freshness vs. the current key."""
141
+ if not corpus_path.exists():
142
+ return CacheLookup(False, False, None, None, f"missing corpus: {corpus_path}")
143
+ current = build_key(corpus_path)
144
+ candidates = iter_cached_reports("without")
145
+ if not candidates:
146
+ return CacheLookup(False, False, None, None, "no cached `without` report")
147
+ # Reports sorted by filename — last is latest given UTC stamps
148
+ latest = candidates[-1]
149
+ cached_key = read_report_key(latest)
150
+ if cached_key is None:
151
+ return CacheLookup(True, False, latest, None, "cached report missing cache_key")
152
+ if cached_key == current:
153
+ return CacheLookup(True, True, latest, cached_key, "fresh")
154
+ # Diagnose which input drifted
155
+ drift_parts = []
156
+ if cached_key.corpus_hash != current.corpus_hash:
157
+ drift_parts.append("corpus")
158
+ if cached_key.claude_cli_version != current.claude_cli_version:
159
+ drift_parts.append("claude_cli_version")
160
+ if cached_key.target_shape_hash != current.target_shape_hash:
161
+ drift_parts.append("target_shape")
162
+ return CacheLookup(True, False, latest, cached_key, "stale: " + ",".join(drift_parts))