@event4u/agent-config 8.13.0 → 9.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 (316) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +183 -0
  3. package/MIGRATION.md +14 -0
  4. package/README.md +2 -2
  5. package/dist/agent-src/commands/agent-handoff.md +35 -0
  6. package/dist/agent-src/commands/agents/init.md +1 -0
  7. package/dist/agent-src/commands/agents/optimize.md +1 -0
  8. package/dist/agent-src/commands/agents/user/accept.md +3 -2
  9. package/dist/agent-src/commands/agents/user/init.md +5 -4
  10. package/dist/agent-src/commands/agents/user/update.md +3 -2
  11. package/dist/agent-src/commands/agents/user.md +1 -0
  12. package/dist/agent-src/commands/agents.md +1 -0
  13. package/dist/agent-src/commands/analytics/show.md +1 -0
  14. package/dist/agent-src/commands/analytics.md +1 -0
  15. package/dist/agent-src/commands/analyze/decision.md +1 -0
  16. package/dist/agent-src/commands/analyze/incident.md +1 -0
  17. package/dist/agent-src/commands/analyze/near-miss.md +1 -0
  18. package/dist/agent-src/commands/analyze/postmortem.md +1 -0
  19. package/dist/agent-src/commands/analyze/premortem.md +1 -0
  20. package/dist/agent-src/commands/analyze/reference-repo.md +1 -0
  21. package/dist/agent-src/commands/analyze.md +3 -2
  22. package/dist/agent-src/commands/brand/identity.md +6 -5
  23. package/dist/agent-src/commands/brand/review.md +6 -5
  24. package/dist/agent-src/commands/brand/strategy.md +6 -4
  25. package/dist/agent-src/commands/brand/tokens.md +7 -6
  26. package/dist/agent-src/commands/brand/voice.md +5 -4
  27. package/dist/agent-src/commands/brand.md +9 -7
  28. package/dist/agent-src/commands/bug/fix.md +1 -0
  29. package/dist/agent-src/commands/bug/investigate.md +1 -0
  30. package/dist/agent-src/commands/bug.md +2 -1
  31. package/dist/agent-src/commands/challenge-me/vision.md +1 -0
  32. package/dist/agent-src/commands/challenge-me/with-docs.md +1 -0
  33. package/dist/agent-src/commands/challenge-me.md +28 -6
  34. package/dist/agent-src/commands/chat-history.md +1 -0
  35. package/dist/agent-src/commands/check-current-md.md +1 -0
  36. package/dist/agent-src/commands/commit.md +1 -0
  37. package/dist/agent-src/commands/context/create.md +3 -2
  38. package/dist/agent-src/commands/context.md +1 -0
  39. package/dist/agent-src/commands/cost/profile.md +1 -0
  40. package/dist/agent-src/commands/cost.md +2 -1
  41. package/dist/agent-src/commands/council/analysis.md +1 -0
  42. package/dist/agent-src/commands/council/debate.md +1 -0
  43. package/dist/agent-src/commands/council/default.md +21 -20
  44. package/dist/agent-src/commands/council/design.md +1 -0
  45. package/dist/agent-src/commands/council/optimize.md +1 -0
  46. package/dist/agent-src/commands/council/pr.md +1 -0
  47. package/dist/agent-src/commands/council.md +1 -0
  48. package/dist/agent-src/commands/estimate-ticket.md +1 -0
  49. package/dist/agent-src/commands/explain-run.md +88 -0
  50. package/dist/agent-src/commands/feature/dev.md +1 -0
  51. package/dist/agent-src/commands/feature/explore.md +1 -0
  52. package/dist/agent-src/commands/feature/plan.md +1 -0
  53. package/dist/agent-src/commands/feature/refactor.md +1 -0
  54. package/dist/agent-src/commands/feature/roadmap.md +1 -0
  55. package/dist/agent-src/commands/feature.md +2 -1
  56. package/dist/agent-src/commands/fix/pr-comments.md +19 -0
  57. package/dist/agent-src/commands/fix.md +2 -1
  58. package/dist/agent-src/commands/ghostwriter/delete.md +1 -0
  59. package/dist/agent-src/commands/ghostwriter/fetch.md +1 -0
  60. package/dist/agent-src/commands/ghostwriter/show.md +1 -0
  61. package/dist/agent-src/commands/ghostwriter/write.md +1 -0
  62. package/dist/agent-src/commands/ghostwriter.md +1 -0
  63. package/dist/agent-src/commands/grill-me.md +17 -12
  64. package/dist/agent-src/commands/humanize.md +1 -0
  65. package/dist/agent-src/commands/image/analyse.md +2 -1
  66. package/dist/agent-src/commands/image/create.md +1 -0
  67. package/dist/agent-src/commands/image/verify.md +1 -0
  68. package/dist/agent-src/commands/image.md +16 -12
  69. package/dist/agent-src/commands/implement-ticket.md +1 -0
  70. package/dist/agent-src/commands/judge/on-diff.md +1 -0
  71. package/dist/agent-src/commands/judge/solo.md +1 -0
  72. package/dist/agent-src/commands/judge/steps.md +1 -0
  73. package/dist/agent-src/commands/judge.md +1 -0
  74. package/dist/agent-src/commands/knowledge/cross-repo.md +1 -0
  75. package/dist/agent-src/commands/knowledge/forget.md +1 -0
  76. package/dist/agent-src/commands/knowledge/ingest.md +1 -0
  77. package/dist/agent-src/commands/knowledge/list.md +10 -0
  78. package/dist/agent-src/commands/knowledge.md +1 -0
  79. package/dist/agent-src/commands/memory/learn-low-impact.md +1 -0
  80. package/dist/agent-src/commands/memory/mine-session.md +1 -0
  81. package/dist/agent-src/commands/memory/promote.md +3 -2
  82. package/dist/agent-src/commands/memory.md +1 -0
  83. package/dist/agent-src/commands/mission/upgrade.md +45 -24
  84. package/dist/agent-src/commands/mode.md +1 -0
  85. package/dist/agent-src/commands/module/create.md +1 -0
  86. package/dist/agent-src/commands/module/explore.md +1 -0
  87. package/dist/agent-src/commands/module.md +1 -0
  88. package/dist/agent-src/commands/optimize/agents-dir.md +1 -0
  89. package/dist/agent-src/commands/optimize/project.md +1 -0
  90. package/dist/agent-src/commands/optimize/prompt.md +1 -0
  91. package/dist/agent-src/commands/optimize.md +2 -1
  92. package/dist/agent-src/commands/orchestrate.md +1 -0
  93. package/dist/agent-src/commands/override.md +1 -0
  94. package/dist/agent-src/commands/package.md +2 -1
  95. package/dist/agent-src/commands/post-as/ghostwriter.md +1 -0
  96. package/dist/agent-src/commands/post-as/me.md +1 -0
  97. package/dist/agent-src/commands/post-as.md +1 -0
  98. package/dist/agent-src/commands/pr/create/description-only.md +139 -8
  99. package/dist/agent-src/commands/pr/create.md +35 -22
  100. package/dist/agent-src/commands/prediction-pool.md +7 -6
  101. package/dist/agent-src/commands/prepare-for-review.md +1 -0
  102. package/dist/agent-src/commands/profile/activate.md +1 -0
  103. package/dist/agent-src/commands/profile/deactivate.md +1 -0
  104. package/dist/agent-src/commands/profile.md +1 -0
  105. package/dist/agent-src/commands/project.md +2 -1
  106. package/dist/agent-src/commands/refine-ticket.md +7 -0
  107. package/dist/agent-src/commands/research/deep.md +1 -0
  108. package/dist/agent-src/commands/research.md +1 -0
  109. package/dist/agent-src/commands/review/routing.md +1 -0
  110. package/dist/agent-src/commands/review.md +2 -1
  111. package/dist/agent-src/commands/roadmap/ai-council.md +1 -0
  112. package/dist/agent-src/commands/roadmap/materialize.md +1 -0
  113. package/dist/agent-src/commands/roadmap/process-full.md +1 -0
  114. package/dist/agent-src/commands/roadmap/process-phase.md +1 -0
  115. package/dist/agent-src/commands/roadmap/process-step.md +1 -0
  116. package/dist/agent-src/commands/roadmap.md +1 -0
  117. package/dist/agent-src/commands/security-audit-config.md +2 -1
  118. package/dist/agent-src/commands/skill/preview.md +1 -0
  119. package/dist/agent-src/commands/skill.md +1 -0
  120. package/dist/agent-src/commands/skills/discover.md +1 -0
  121. package/dist/agent-src/commands/skills.md +1 -0
  122. package/dist/agent-src/commands/sync/agent-settings.md +1 -0
  123. package/dist/agent-src/commands/sync.md +2 -1
  124. package/dist/agent-src/commands/team/adversarial.md +3 -2
  125. package/dist/agent-src/commands/team/delegate.md +3 -2
  126. package/dist/agent-src/commands/team/review.md +3 -2
  127. package/dist/agent-src/commands/team/status.md +49 -18
  128. package/dist/agent-src/commands/team-knowledge.md +8 -6
  129. package/dist/agent-src/commands/team.md +21 -16
  130. package/dist/agent-src/commands/tests/e2e-heal.md +1 -0
  131. package/dist/agent-src/commands/tests/e2e-plan.md +1 -0
  132. package/dist/agent-src/commands/tests/execute.md +1 -0
  133. package/dist/agent-src/commands/tests.md +2 -1
  134. package/dist/agent-src/commands/update-form-request-messages.md +1 -0
  135. package/dist/agent-src/commands/upstream-contribute.md +1 -0
  136. package/dist/agent-src/commands/video/from-script.md +3 -2
  137. package/dist/agent-src/commands/video/from-song.md +22 -21
  138. package/dist/agent-src/commands/video/scene.md +1 -0
  139. package/dist/agent-src/commands/video/stitch.md +2 -1
  140. package/dist/agent-src/commands/video/storyboard.md +1 -0
  141. package/dist/agent-src/commands/video.md +1 -0
  142. package/dist/agent-src/commands/work.md +1 -0
  143. package/dist/agent-src/commands/worktree/cleanup.md +8 -7
  144. package/dist/agent-src/commands/worktree/create.md +1 -0
  145. package/dist/agent-src/commands/worktree/verify.md +1 -0
  146. package/dist/agent-src/commands/worktree.md +1 -0
  147. package/dist/agent-src/rules/active-remediation.md +12 -36
  148. package/dist/agent-src/rules/artifact-drafting-protocol.md +7 -64
  149. package/dist/agent-src/rules/context-hygiene.md +19 -113
  150. package/dist/agent-src/rules/design-fidelity.md +4 -60
  151. package/dist/agent-src/rules/domain-adoption-policy.md +10 -106
  152. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +12 -60
  153. package/dist/agent-src/rules/improve-before-implement.md +4 -0
  154. package/dist/agent-src/rules/minimal-safe-diff.md +6 -86
  155. package/dist/agent-src/rules/size-enforcement.md +10 -0
  156. package/dist/agent-src/rules/tool-safety.md +17 -3
  157. package/dist/agent-src/skills/agent-security-review/SKILL.md +12 -1
  158. package/dist/agent-src/skills/ai-council/SKILL.md +11 -0
  159. package/dist/agent-src/skills/bug-analyzer/SKILL.md +24 -2
  160. package/dist/agent-src/skills/code-review/SKILL.md +105 -93
  161. package/dist/agent-src/skills/code-review/checklists/backend.md +50 -0
  162. package/dist/agent-src/skills/code-review/checklists/database.md +19 -0
  163. package/dist/agent-src/skills/code-review/checklists/dependency.md +18 -0
  164. package/dist/agent-src/skills/code-review/checklists/docs.md +14 -0
  165. package/dist/agent-src/skills/code-review/checklists/frontend.md +19 -0
  166. package/dist/agent-src/skills/code-review/checklists/infra.md +17 -0
  167. package/dist/agent-src/skills/code-review/checklists/producing-the-review.md +62 -0
  168. package/dist/agent-src/skills/code-review/checklists/test-only.md +13 -0
  169. package/dist/agent-src/skills/code-review/evals/evals.json +53 -15
  170. package/dist/agent-src/skills/condense-memory/SKILL.md +3 -2
  171. package/dist/agent-src/skills/conventional-commits-writing/evals/evals.json +15 -0
  172. package/dist/agent-src/skills/docker/SKILL.md +10 -0
  173. package/dist/agent-src/skills/docx-authoring/SKILL.md +102 -0
  174. package/dist/agent-src/skills/github-ci/evals/evals.json +25 -0
  175. package/dist/agent-src/skills/humanizer/SKILL.md +79 -3
  176. package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +112 -0
  177. package/dist/agent-src/skills/humanizer/references/fixtures.md +70 -0
  178. package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +7 -1
  179. package/dist/agent-src/skills/laravel/SKILL.md +10 -0
  180. package/dist/agent-src/skills/launch-readiness/SKILL.md +35 -0
  181. package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +146 -0
  182. package/dist/agent-src/skills/llm-provider-knowledge/evals/triggers.json +20 -0
  183. package/dist/agent-src/skills/merge-conflicts/SKILL.md +30 -0
  184. package/dist/agent-src/skills/pdf-tools/SKILL.md +101 -0
  185. package/dist/agent-src/skills/quality-tools/evals/evals.json +15 -0
  186. package/dist/agent-src/skills/security-audit/SKILL.md +29 -0
  187. package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +90 -0
  188. package/dist/agent-src/skills/security-maturity-assessment/evals/triggers.json +52 -0
  189. package/dist/agent-src/skills/skill-writing/SKILL.md +79 -0
  190. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +11 -3
  191. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +11 -0
  192. package/dist/agent-src/skills/subagent-orchestration/schemas/team-review-status.json +103 -0
  193. package/dist/agent-src/skills/terraform/SKILL.md +10 -0
  194. package/dist/agent-src/skills/test-driven-development/SKILL.md +31 -0
  195. package/dist/agent-src/skills/threat-modeling/SKILL.md +15 -0
  196. package/dist/agent-src/skills/token-optimizer/SKILL.md +10 -4
  197. package/dist/agent-src/templates/agent-settings.md +28 -0
  198. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  199. package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  200. package/dist/agent-src/templates/scripts/telemetry/engagement.ts +30 -0
  201. package/dist/agent-src/templates/scripts/telemetry/report_renderer.ts +22 -9
  202. package/dist/agent-src/templates/scripts/telemetry_record.ts +5 -0
  203. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +4 -1
  204. package/dist/discovery/deprecation-report.md +1 -1
  205. package/dist/discovery/discovery-manifest.json +314 -194
  206. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  207. package/dist/discovery/discovery-manifest.summary.md +5 -5
  208. package/dist/discovery/orphan-report.md +1 -1
  209. package/dist/discovery/packs.json +23 -18
  210. package/dist/discovery/trust-report.md +8 -8
  211. package/dist/discovery/workspaces.json +18 -13
  212. package/dist/install/install.mjs +48 -33
  213. package/dist/mcp/registry-manifest.json +3 -3
  214. package/dist/router.json +1 -1
  215. package/dist/scripts/_lib/agent_settings.js +4 -1
  216. package/dist/scripts/_lib/agent_settings.js.map +1 -1
  217. package/dist/scripts/condense.js +5 -0
  218. package/dist/scripts/condense.js.map +1 -1
  219. package/dist/server/schemas/settings.js +10 -1
  220. package/dist/server/schemas/settings.js.map +1 -1
  221. package/docs/CLAIMS.md +9 -2
  222. package/docs/MIGRATION.md +20 -0
  223. package/docs/SKILL_CENSUS.md +8 -0
  224. package/docs/architecture.md +3 -3
  225. package/docs/benchmark.md +67 -2
  226. package/docs/catalog.md +2 -2
  227. package/docs/command-flows.md +1 -1
  228. package/docs/contracts/agents-layout.md +1 -1
  229. package/docs/contracts/ai-council-config.md +9 -2
  230. package/docs/contracts/ai-team-config.md +37 -4
  231. package/docs/contracts/consumer-bridge.md +55 -63
  232. package/docs/contracts/install-layout.md +1 -1
  233. package/docs/contracts/migrate-command.md +1 -1
  234. package/docs/contracts/prelaunch-diagnostics.md +151 -0
  235. package/docs/contracts/release-pr-gating.md +1 -0
  236. package/docs/customization.md +22 -1
  237. package/docs/decisions/ADR-020-global-only-consumer-scope.md +34 -0
  238. package/docs/decisions/ADR-049-configuration-trust-boundary.md +9 -1
  239. package/docs/featured-skills.md +2 -2
  240. package/docs/getting-started-by-role.md +1 -1
  241. package/docs/getting-started.md +17 -6
  242. package/docs/governance-advantage.md +1 -1
  243. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +45 -0
  244. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +28 -0
  245. package/docs/guidelines/agent-infra/api-cost-levers.md +126 -0
  246. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +76 -0
  247. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +90 -0
  248. package/docs/guidelines/agent-infra/domain-adoption-gates.md +112 -0
  249. package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +66 -0
  250. package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +99 -0
  251. package/docs/guidelines/agent-infra/skill-quality-checklist.md +13 -0
  252. package/docs/guidelines/design-fidelity-mechanics.md +76 -0
  253. package/docs/installation.md +2 -1
  254. package/docs/maintainers/dev-mode.md +3 -2
  255. package/docs/parity/command-frontmatter.md +60 -0
  256. package/docs/proof.md +7 -6
  257. package/package.json +1 -1
  258. package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  259. package/src/agent-src/templates/scripts/telemetry/engagement.ts +30 -0
  260. package/src/agent-src/templates/scripts/telemetry/report_renderer.ts +22 -9
  261. package/src/agent-src/templates/scripts/telemetry_record.ts +5 -0
  262. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +4 -1
  263. package/src/config/agent-settings.template.yml +73 -10
  264. package/src/config/gitignore-block.txt +16 -6
  265. package/src/config/prelaunch-areas.yml +36 -0
  266. package/src/scripts/_cli/cmd_conformance.ts +2 -2
  267. package/src/scripts/_cli/cmd_doctor.ts +280 -39
  268. package/src/scripts/_cli/cmd_refresh.ts +35 -118
  269. package/src/scripts/_lib/agent_settings.ts +4 -1
  270. package/src/scripts/_lib/claude_plugin.ts +77 -2
  271. package/src/scripts/_lib/orchestration_record.ts +5 -0
  272. package/src/scripts/_lib/tool_adapter_registry.ts +120 -0
  273. package/src/scripts/ai_council/clients.ts +68 -6
  274. package/src/scripts/ai_council/pricing.ts +62 -0
  275. package/src/scripts/ai_team/config.ts +73 -1
  276. package/src/scripts/ai_team/review_gate.ts +636 -0
  277. package/src/scripts/ai_team/team_dispatch.ts +612 -0
  278. package/src/scripts/bench_ab_task_runner.ts +11 -1
  279. package/src/scripts/bench_parity_count.ts +279 -0
  280. package/src/scripts/build_linear_digest.ts +3 -1
  281. package/src/scripts/check_bridge_derivation.ts +172 -0
  282. package/src/scripts/check_consumer_scope_flip.ts +179 -0
  283. package/src/scripts/check_council_config_location.ts +115 -15
  284. package/src/scripts/check_host_loadability.ts +81 -0
  285. package/src/scripts/condense.ts +5 -0
  286. package/src/scripts/council_cli.ts +19 -3
  287. package/src/scripts/hook_manifest.yaml +12 -1
  288. package/src/scripts/install.ts +44 -45
  289. package/src/scripts/lint_agents_layout.ts +10 -4
  290. package/src/scripts/lint_breaking_changes_index.ts +303 -0
  291. package/src/scripts/lint_handoffs.ts +42 -0
  292. package/src/scripts/lint_skill_descriptions.ts +228 -0
  293. package/src/scripts/lint_skill_descriptions_allowlist.json +1 -0
  294. package/src/scripts/lint_skill_scripts_readonly.ts +145 -0
  295. package/src/scripts/lint_skill_scripts_readonly_allowlist.json +8 -0
  296. package/src/scripts/lint_supported_tools_matrix.ts +35 -0
  297. package/src/scripts/mcp_server/tools.ts +1 -3
  298. package/src/scripts/optimize_skill_description.ts +144 -0
  299. package/src/scripts/orchestration_record.ts +2 -1
  300. package/src/scripts/prelaunch_diagnostics.ts +248 -0
  301. package/src/scripts/run_skill_evals.ts +70 -4
  302. package/src/scripts/schemas/agent-settings.schema.json +17 -0
  303. package/src/scripts/schemas/command.schema.json +7 -0
  304. package/src/scripts/schemas/evals.schema.json +105 -14
  305. package/src/scripts/schemas/prelaunch-report.schema.json +107 -0
  306. package/src/scripts/schemas/skill.schema.json +18 -1
  307. package/src/scripts/schemas/subagent.schema.json +6 -0
  308. package/src/scripts/self_review_gate.test.ts +11 -0
  309. package/src/scripts/self_review_gate.ts +7 -1
  310. package/src/scripts/skill_eval_coverage.ts +4 -1
  311. package/src/scripts/skill_linter.ts +43 -3
  312. package/src/scripts/smoke_host_loadability.sh +73 -0
  313. package/src/scripts/team_review_gate_hook.ts +115 -0
  314. package/src/scripts/trigger_eval_grandfather.json +1 -2
  315. package/src/scripts/utilization_report.ts +225 -0
  316. package/src/server/schemas/settings.ts +24 -1
@@ -1,12 +1,9 @@
1
1
  # Agent config — tool-scope leftovers (ADR-020 § global-only consumer
2
2
  # install). After the Phase-5 migration the entire `.augment/`, `.claude/`,
3
3
  # `.cursor/` trees live under `~/.event4u/agent-config/`; consumers carry
4
- # only `agents/overrides/` + `agents/.event4u-bridge.yml`. The per-tool
5
- # bridge pointer files for Windsurf / Cline / Gemini-CLI live under
6
- # `.windsurf/`, `.clinerules/`, `.gemini/` and ARE committed — those
7
- # directories stay tracked (not listed here). Pre-Phase-5 entries kept
8
- # as a defence-in-depth ignore list for legacy installs that have not
9
- # migrated yet — Phase 5 unstages them on first migrate run.
4
+ # only `agents/overrides/`. Pre-Phase-5 entries kept as a defence-in-depth
5
+ # ignore list for legacy installs that have not migrated yet — Phase 5
6
+ # unstages them on first migrate run.
10
7
  .augment/skills/
11
8
  .augment/commands/
12
9
  .augment/guidelines/
@@ -21,6 +18,19 @@
21
18
  .claude/CLAUDE.md
22
19
  .cursor/rules/
23
20
 
21
+ # Agent config — consumer bridge marker + per-tool project anchors.
22
+ # The bridge marker was retired (ADR-020 amendment 2026-07-13): it carried
23
+ # no project-specific data (global_root resolves from `~/.event4u/agent-config`)
24
+ # yet was committed and rewritten by every developer's install. The global
25
+ # root is now the well-known path. The Windsurf / Cline / Gemini-CLI anchors
26
+ # remain (those tools cannot read user scope) but are gitignored — each
27
+ # developer regenerates them on install; they are never shared. The install
28
+ # deletes any legacy committed marker; this entry keeps a stale one ignored.
29
+ /agents/.event4u-bridge.yml
30
+ .windsurf/agent-config.bridge.yml
31
+ .clinerules/agent-config.bridge.yml
32
+ .gemini/agent-config.bridge.yml
33
+
24
34
  # Agent config — Phase 5 migration snapshot (ADR-020). Written by
25
35
  # `agent-config migrate-to-global` as a copy-then-move safety net so a
26
36
  # migration can be rolled back. Local-only — never commit.
@@ -0,0 +1,36 @@
1
+ # Pre-launch diagnostic — fixed coverage-area vocabulary
2
+ # (road-to-ecosystem-harvest-prelaunch-diagnostics Phase 1, Source L).
3
+ #
4
+ # The AREA code is the middle segment of the immutable finding-ID grammar
5
+ # `AC-<AREA>-NNN` (docs/contracts/prelaunch-diagnostics.md). Codes are
6
+ # append-only: renaming or re-using a code would re-assign IDs and break
7
+ # every committed baseline. Add new areas at the end; never delete.
8
+ #
9
+ # `launch_gate: true` areas participate in the regression gate's
10
+ # Pass→Finding CI trigger and block a "ready" verdict while Unknown.
11
+ schema_version: prelaunch-areas-v1
12
+ areas:
13
+ auth:
14
+ code: AUTH
15
+ launch_gate: true
16
+ description: Authentication, authorization, tenancy boundaries on the launch surface.
17
+ migrations:
18
+ code: MIG
19
+ launch_gate: true
20
+ description: Schema/data migrations shipped with the launch — reversibility, expand-contract, backfill safety.
21
+ secrets:
22
+ code: SEC
23
+ launch_gate: true
24
+ description: Secrets, tokens, key handling touched by the launch — storage, rotation, exposure paths.
25
+ observability:
26
+ code: OBS
27
+ launch_gate: false
28
+ description: Telemetry proving rollout health — the metric, alert, and pager path for the new surface.
29
+ rollback:
30
+ code: RBK
31
+ launch_gate: true
32
+ description: Rollback contract — trip wires, decision windows, abort paths, named irreversible steps.
33
+ agent-governance:
34
+ code: AGOV
35
+ launch_gate: false
36
+ description: AI/agent surfaces shipped with the launch — tool grants, egress paths, injection exposure.
@@ -47,7 +47,7 @@ import {
47
47
  _run_checks_no_manifest,
48
48
  _scan_foreign,
49
49
  ArgparseExit,
50
- BRIDGE_MARKER_RELATIVE,
50
+ _is_global_only_consumer,
51
51
  STATUS_SYMBOLS,
52
52
  } from './cmd_doctor.js';
53
53
 
@@ -630,7 +630,7 @@ function main(argv: string[] | null = null): number {
630
630
  let doctorChecks: Dict[];
631
631
  let drift: Record<string, Dict[]> = { missing: [], modified: [], foreign: [], tag_drift: [] };
632
632
  if (manifest === null) {
633
- const bridge_present = fs.existsSync(path.join(project_root, BRIDGE_MARKER_RELATIVE));
633
+ const bridge_present = _is_global_only_consumer(project_root);
634
634
  doctorChecks = _run_checks_no_manifest(project_root, bridge_present, null);
635
635
  } else {
636
636
  const [records, known] = _collect_manifest_entries(project_root, manifest);
@@ -99,6 +99,13 @@ import {
99
99
  } from '../_lib/agent_settings.js';
100
100
  import * as ai_council_clients from '../ai_council/clients.js';
101
101
  import * as ai_council_config from '../ai_council/config.js';
102
+ import { review_gate_doctor_signal } from '../ai_team/review_gate.js';
103
+ import {
104
+ LEGACY_ALL,
105
+ excludedRuleBasenames,
106
+ ruleScopeFromSettings,
107
+ type RuleScope,
108
+ } from '../../install/rule_scope.js';
102
109
 
103
110
  type Dict = Record<string, unknown>;
104
111
 
@@ -737,6 +744,7 @@ const CHECK_IDS = [
737
744
  'surface-state',
738
745
  'hook-wiring',
739
746
  'stale-orphans',
747
+ 'rule-scope-drift',
740
748
  'manifest-integrity',
741
749
  'lockfile-freshness',
742
750
  'bridge-drift',
@@ -763,6 +771,7 @@ const GLOBAL_CHECK_IDS: ReadonlySet<string> = new Set([
763
771
  'surface-state',
764
772
  'hook-wiring',
765
773
  'stale-orphans',
774
+ 'rule-scope-drift',
766
775
  'mcp-mode',
767
776
  'mcp-beta-readiness',
768
777
  'offline-readiness',
@@ -782,8 +791,20 @@ const MANIFEST_REQUIRED_CHECK_IDS: ReadonlySet<string> = new Set([
782
791
  'unsupported-combos',
783
792
  ]);
784
793
 
785
- /** Project-root-relative path of the ADR-020 global-only consumer marker. */
786
- const BRIDGE_MARKER_RELATIVE = 'agents/.event4u-bridge.yml';
794
+ /**
795
+ * Signals a set-up global-only consumer. The `.event4u-bridge.yml` marker was
796
+ * retired (ADR-020 amendment 2026-07-13); the durable project-side signal is
797
+ * the install-mode marker (written on every install) or the `agents/overrides/`
798
+ * scaffold. Either is sufficient.
799
+ */
800
+ const INSTALL_MODE_MARKER_RELATIVE = 'agents/.agent-state/install-mode.txt';
801
+
802
+ function _is_global_only_consumer(project_root: string): boolean {
803
+ return (
804
+ isFile(path.join(project_root, INSTALL_MODE_MARKER_RELATIVE)) ||
805
+ isDir(path.join(project_root, 'agents', 'overrides'))
806
+ );
807
+ }
787
808
 
788
809
  /** Repair targets that `--repair <id>` accepts. */
789
810
  const REPAIR_IDS = ['wizard-state'] as const;
@@ -1090,15 +1111,16 @@ function _check_global_binary(project_root: string): Dict {
1090
1111
  remedy: 'agent-config upgrade (refresh the global install + plugin)',
1091
1112
  };
1092
1113
  }
1093
- const bridge = path.join(project_root, 'agents', '.event4u-bridge.yml');
1094
- const bridge_note = isFile(bridge) ? '' : ' · no project bridge marker';
1114
+ const consumer_note = _is_global_only_consumer(project_root)
1115
+ ? ''
1116
+ : ' · no project install marker';
1095
1117
  return {
1096
1118
  id: 'global-binary',
1097
1119
  status: 'ok',
1098
- message: `on PATH (${binary}); version ${binary_v || 'unknown'}${bridge_note}`,
1099
- remedy: !bridge_note
1120
+ message: `on PATH (${binary}); version ${binary_v || 'unknown'}${consumer_note}`,
1121
+ remedy: !consumer_note
1100
1122
  ? ''
1101
- : 'agent-config refresh --project (scaffold the bridge marker)',
1123
+ : 'agent-config refresh --project (scaffold agents/overrides/)',
1102
1124
  };
1103
1125
  }
1104
1126
 
@@ -1589,6 +1611,130 @@ function _check_stale_orphans(): Dict {
1589
1611
  };
1590
1612
  }
1591
1613
 
1614
+ /**
1615
+ * Per-file rule projection trees a consumer install writes (basenames match
1616
+ * the shipped `dist/agent-src/rules` tree). The first one that exists and
1617
+ * holds ≥ 1 `.md` rule is the surface we diff against the consumer's scope.
1618
+ */
1619
+ const _RULE_PROJECTION_DIRS: readonly string[] = [
1620
+ '.augment/rules',
1621
+ '.windsurf/rules',
1622
+ '.cursor/rules',
1623
+ '.clinerules',
1624
+ ];
1625
+
1626
+ /**
1627
+ * Rule-scope drift (road-to-request-scoped-rule-load, 9.0 consumer flip).
1628
+ *
1629
+ * After the 9.0 default flip to consumer-scoped rule projection, a consumer
1630
+ * whose settings now exclude maintainer-only workspaces may still carry a
1631
+ * pre-flip FULL/GLOBAL rule projection on disk. This check diffs the scope
1632
+ * the consumer's settings imply against the rules actually projected and
1633
+ * reports the leftover set as an ACTIONABLE diff (not a bare boolean).
1634
+ *
1635
+ * The scope-derived expected set reuses the ONE install-time scoping surface
1636
+ * (`rule_scope.ts`), so doctor's diagnosis can never drift from the install
1637
+ * semantics. `excludedRuleBasenames` returns exactly the rules PRESENT in the
1638
+ * projected tree that the current scope says should NOT arrive.
1639
+ *
1640
+ * Degrades gracefully: `skipped` in the agent-config source repo (the in-repo
1641
+ * `.augment/rules` is the full generated projection, not a consumer surface)
1642
+ * and `skipped` when no projected rule tree is present to inspect.
1643
+ */
1644
+ function _check_rule_scope_drift(project_root: string): Dict {
1645
+ if (_is_source_repo(project_root)) {
1646
+ return {
1647
+ id: 'rule-scope-drift',
1648
+ status: 'skipped',
1649
+ message: 'agent-config source repo — no consumer rule projection to inspect',
1650
+ remedy: '',
1651
+ };
1652
+ }
1653
+
1654
+ // Consumer projection scope (absent / empty settings → legacy-all: every
1655
+ // rule ships, so nothing is ever out of scope).
1656
+ let scope: RuleScope = LEGACY_ALL;
1657
+ const settings_file = project_settings_path(project_root);
1658
+ if (isFile(settings_file)) {
1659
+ const loaded = yamlSafeLoad(readText0(settings_file));
1660
+ const raw =
1661
+ typeof loaded === 'object' && loaded !== null && !Array.isArray(loaded)
1662
+ ? (loaded as Dict)
1663
+ : {};
1664
+ scope = ruleScopeFromSettings(raw);
1665
+ }
1666
+
1667
+ // First projected rule tree that exists and holds a `.md` rule.
1668
+ let rules_dir: string | null = null;
1669
+ let found = 0;
1670
+ for (const rel of _RULE_PROJECTION_DIRS) {
1671
+ const cand = path.join(project_root, rel);
1672
+ if (!isDir(cand)) {
1673
+ continue;
1674
+ }
1675
+ let count = 0;
1676
+ try {
1677
+ for (const name of fs.readdirSync(cand)) {
1678
+ if (name.endsWith('.md') && isFile(path.join(cand, name))) {
1679
+ count += 1;
1680
+ }
1681
+ }
1682
+ } catch {
1683
+ continue;
1684
+ }
1685
+ if (count > 0) {
1686
+ rules_dir = cand;
1687
+ found = count;
1688
+ break;
1689
+ }
1690
+ }
1691
+ if (rules_dir === null) {
1692
+ return {
1693
+ id: 'rule-scope-drift',
1694
+ status: 'skipped',
1695
+ message: 'no projected rule tree found (.augment/rules, .windsurf/rules, …) — nothing to inspect',
1696
+ remedy: '',
1697
+ };
1698
+ }
1699
+
1700
+ let unexpected: string[];
1701
+ try {
1702
+ unexpected = excludedRuleBasenames(rules_dir, scope);
1703
+ } catch (exc) {
1704
+ const rel = relativeTo(rules_dir, project_root) ?? rules_dir;
1705
+ return {
1706
+ id: 'rule-scope-drift',
1707
+ status: 'fail',
1708
+ message: `cannot inspect ${rel}: ${osErrorStr(exc)}`,
1709
+ remedy: 'check read permissions on the projected rule tree',
1710
+ };
1711
+ }
1712
+
1713
+ const rel_dir = relativeTo(rules_dir, project_root) ?? rules_dir;
1714
+ if (unexpected.length === 0) {
1715
+ return {
1716
+ id: 'rule-scope-drift',
1717
+ status: 'ok',
1718
+ message: `rule projection matches scope (${found} rules in ${rel_dir})`,
1719
+ remedy: '',
1720
+ };
1721
+ }
1722
+ const expected = found - unexpected.length;
1723
+ const sample = unexpected.slice(0, 8);
1724
+ const more = unexpected.length - sample.length;
1725
+ const names = sample.join(', ') + (more > 0 ? `, +${more} more` : '');
1726
+ return {
1727
+ id: 'rule-scope-drift',
1728
+ status: 'warn',
1729
+ message:
1730
+ `rule-scope drift in ${rel_dir}: expected ${expected} rules, found ${found} — ` +
1731
+ `${unexpected.length} unexpected (out of scope): ${names}`,
1732
+ remedy:
1733
+ 're-run `agent-config init --project` (or `agent-config global`) to re-project rules ' +
1734
+ 'under the current scope — these are leftover from a pre-9.0 full/global projection',
1735
+ };
1736
+ }
1737
+
1592
1738
  function _check_python_runtime(): Dict {
1593
1739
  // Post-teardown: the package runtime is TypeScript-on-`tsx`. python3 is no
1594
1740
  // longer a runtime dependency, so this check no longer probes for an
@@ -2028,6 +2174,79 @@ function _settings_flag(val: unknown): boolean {
2028
2174
  return false;
2029
2175
  }
2030
2176
 
2177
+ /**
2178
+ * Decode a JWT payload's `exp` claim (epoch seconds) — base64 decode only,
2179
+ * NO signature verification, no network. Non-JWT / undecodable → null.
2180
+ */
2181
+ function _jwt_exp(token: unknown): number | null {
2182
+ if (typeof token !== 'string') return null;
2183
+ const parts = token.split('.');
2184
+ if (parts.length !== 3) return null;
2185
+ try {
2186
+ const payload: unknown = JSON.parse(
2187
+ Buffer.from(parts[1] as string, 'base64url').toString('utf-8'),
2188
+ );
2189
+ if (typeof payload !== 'object' || payload === null) return null;
2190
+ const exp = (payload as Record<string, unknown>)['exp'];
2191
+ return typeof exp === 'number' && Number.isFinite(exp) && exp > 0 ? exp : null;
2192
+ } catch {
2193
+ return null;
2194
+ }
2195
+ }
2196
+
2197
+ /** Coerce an explicit expiry field to epoch seconds (number or ISO string). */
2198
+ function _epoch_seconds(value: unknown): number | null {
2199
+ if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
2200
+ // Heuristic: values past ~2286 in seconds are epoch milliseconds.
2201
+ return value > 1e12 ? value / 1000 : value;
2202
+ }
2203
+ if (typeof value === 'string' && value.trim() !== '') {
2204
+ const ms = Date.parse(value);
2205
+ return Number.isNaN(ms) ? null : ms / 1000;
2206
+ }
2207
+ return null;
2208
+ }
2209
+
2210
+ /**
2211
+ * Latest locally-derivable expiry (epoch seconds) from a codex `auth.json`,
2212
+ * or null when none is derivable. Sources, all offline:
2213
+ *
2214
+ * - explicit `expires_at` / `expiry` / `exp` fields (top level; numbers in
2215
+ * seconds or ms, or ISO date strings), and
2216
+ * - the `exp` claim of JWT tokens under `tokens.{access_token,id_token}`
2217
+ * (or the same keys top-level) — base64 payload decode only, never
2218
+ * signature verification.
2219
+ *
2220
+ * LATEST wins: the real codex auth.json holds a refresh_token, so an
2221
+ * expired id_token sitting next to a live access_token is not an auth
2222
+ * failure — WARN only when everything derivable is past.
2223
+ */
2224
+ function _codex_auth_expiry(auth_path: string): number | null {
2225
+ let data: unknown;
2226
+ try {
2227
+ data = JSON.parse(fs.readFileSync(auth_path, 'utf-8'));
2228
+ } catch {
2229
+ return null;
2230
+ }
2231
+ if (typeof data !== 'object' || data === null) return null;
2232
+ const d = data as Record<string, unknown>;
2233
+ const candidates: number[] = [];
2234
+ for (const key of ['expires_at', 'expiry', 'exp']) {
2235
+ const v = _epoch_seconds(d[key]);
2236
+ if (v !== null) candidates.push(v);
2237
+ }
2238
+ const tokens_raw = d['tokens'];
2239
+ const tokens =
2240
+ typeof tokens_raw === 'object' && tokens_raw !== null && !Array.isArray(tokens_raw)
2241
+ ? (tokens_raw as Record<string, unknown>)
2242
+ : {};
2243
+ for (const key of ['access_token', 'id_token']) {
2244
+ const v = _jwt_exp(tokens[key] ?? d[key]);
2245
+ if (v !== null) candidates.push(v);
2246
+ }
2247
+ return candidates.length > 0 ? Math.max(...candidates) : null;
2248
+ }
2249
+
2031
2250
  /** The `ai_team` block from `.agent-settings.yml` — lenient, `{}` when absent. */
2032
2251
  function _read_ai_team_block(project_root: string): Dict {
2033
2252
  const settings_file = project_settings_path(project_root);
@@ -2049,14 +2268,21 @@ function _read_ai_team_block(project_root: string): Dict {
2049
2268
  * `team` health check — three sub-signals folded into one result:
2050
2269
  *
2051
2270
  * (a) codex binary present (council-probe binary discovery reused) AND
2052
- * auth present. Auth is a READ-ONLY presence probe of
2053
- * `$CODEX_HOME/auth.json` (default `~/.codex/auth.json`) — token
2054
- * expiry cannot be validated without a billable call; runtime expiry
2055
- * is caught by `OpenAICliClient._AUTH_FAILURE_PATTERNS`.
2271
+ * auth present. Auth is a READ-ONLY probe of `$CODEX_HOME/auth.json`
2272
+ * (default `~/.codex/auth.json`): presence, plus locally-derivable
2273
+ * expiry evidence (`_codex_auth_expiry` — explicit expiry fields or
2274
+ * JWT `exp` payloads; no network, no signature verification). Past
2275
+ * expiry → WARN; no derivable expiry → presence-only note in the
2276
+ * detail. Runtime expiry is still caught authoritatively by
2277
+ * `OpenAICliClient._AUTH_FAILURE_PATTERNS`.
2056
2278
  * (b) on Claude-Code hosts (claude binary on PATH or the Claude config dir
2057
2279
  * present): the official codex plugin recorded in
2058
- * `plugins/installed_plugins.json`. Detection is read-only — doctor
2059
- * never writes under `~/.claude/`.
2280
+ * `plugins/installed_plugins.json`, with namespace-resistant identity
2281
+ * via `codex_plugin_identity()` — a prefix match whose marketplace
2282
+ * source repo cannot be verified against `openai/codex-plugin-cc`
2283
+ * keeps ✅ but is annotated "identity not fully verified (prefix
2284
+ * match)". Detection is read-only — doctor never writes under
2285
+ * `~/.claude/`.
2060
2286
  * (c) Review-Gate consistency: `ai_team.review_gate.managed` on while the
2061
2287
  * loop bound (`max_consecutive_blocks`, Phase 4 — unbuilt) is absent
2062
2288
  * → WARN.
@@ -2074,8 +2300,6 @@ function _check_team(project_root: string): Dict {
2074
2300
  ? (gateRaw as Dict)
2075
2301
  : {};
2076
2302
  const gate_managed = _settings_flag(gate['managed']);
2077
- const bound = gate['max_consecutive_blocks'];
2078
- const bound_present = typeof bound === 'number' && Number.isInteger(bound) && bound > 0;
2079
2303
 
2080
2304
  if (!enabled) {
2081
2305
  if (gate_managed) {
@@ -2110,12 +2334,26 @@ function _check_team(project_root: string): Dict {
2110
2334
  remedies.push('install the codex CLI: `npm install -g @openai/codex`');
2111
2335
  }
2112
2336
 
2113
- // (a, cont.) codex auth — presence probe of $CODEX_HOME/auth.json.
2337
+ // (a, cont.) codex auth — READ-ONLY probe of $CODEX_HOME/auth.json:
2338
+ // presence + locally-derivable expiry evidence (no network).
2114
2339
  const auth_path = path.join(_codex_home(), 'auth.json');
2115
2340
  const authed = pathExists(auth_path);
2116
- const auth_glyph = authed ? '✅' : '❌';
2341
+ let auth_str: string;
2117
2342
  if (!authed) {
2343
+ auth_str = `codex auth ❌ (${auth_path})`;
2118
2344
  remedies.push('run `codex login`');
2345
+ } else {
2346
+ const expiry = _codex_auth_expiry(auth_path);
2347
+ if (expiry !== null && expiry * 1000 < Date.now()) {
2348
+ auth_str = `codex auth ⚠️ expired (${auth_path})`;
2349
+ remedies.push('auth token appears expired — run `codex login`');
2350
+ } else if (expiry === null) {
2351
+ auth_str =
2352
+ `codex auth ✅ (${auth_path}; ` +
2353
+ 'presence-only check — expiry not verifiable locally)';
2354
+ } else {
2355
+ auth_str = `codex auth ✅ (${auth_path})`;
2356
+ }
2119
2357
  }
2120
2358
 
2121
2359
  // (b) official codex plugin — Claude-Code hosts only.
@@ -2123,34 +2361,33 @@ function _check_team(project_root: string): Dict {
2123
2361
  shutilWhich('claude') !== null || pathExists(claude_plugin.claude_config_dir());
2124
2362
  let plugin_str: string;
2125
2363
  if (is_claude_host) {
2126
- const plugin_present = claude_plugin.codex_plugin_installed();
2127
- plugin_str = `codex plugin ${plugin_present ? '✅' : '❌'}`;
2128
- if (!plugin_present) {
2364
+ const identity = claude_plugin.codex_plugin_identity();
2365
+ if (!identity.installed) {
2366
+ plugin_str = 'codex plugin ❌';
2129
2367
  remedies.push(
2130
2368
  'install the official codex plugin: ' +
2131
2369
  claude_plugin.CODEX_PLUGIN_INSTALL_HINT.map((c) => `\`${c}\``).join(' then '),
2132
2370
  );
2371
+ } else if (!identity.identity_verified) {
2372
+ plugin_str = 'codex plugin ✅ — identity not fully verified (prefix match)';
2373
+ } else {
2374
+ plugin_str = 'codex plugin ✅';
2133
2375
  }
2134
2376
  } else {
2135
2377
  plugin_str = 'codex plugin — (not a Claude Code host; fallback path applies)';
2136
2378
  }
2137
2379
 
2138
- // (c) Review-Gate consistency.
2139
- let gate_str: string;
2140
- if (gate_managed && !bound_present) {
2141
- gate_str = 'review-gate ⚠️ on, loop bound absent';
2142
- remedies.push(
2143
- 'set `ai_team.review_gate.max_consecutive_blocks` (loop bound; ' +
2144
- 'ships with the Review-Gate governance phase) or set ' +
2145
- '`ai_team.review_gate.managed: false`',
2146
- );
2147
- } else {
2148
- gate_str = `review-gate ${gate_managed ? 'on' : 'off'}`;
2149
- }
2380
+ // (c) Review-Gate governance (Phase 4) — logic lives in
2381
+ // src/scripts/ai_team/review_gate.ts (upstream gate probe + WARN
2382
+ // states, incl. plugin-gate-on-while-unmanaged with the quoted
2383
+ // upstream cost warning).
2384
+ const gate_signal = review_gate_doctor_signal(project_root, gate);
2385
+ const gate_str = gate_signal.gate_str;
2386
+ remedies.push(...gate_signal.remedies);
2150
2387
 
2151
2388
  const detail =
2152
2389
  `codex binary ${binary_glyph} (${binary_name}) · ` +
2153
- `codex auth ${auth_glyph} (${auth_path}) · ${plugin_str} · ${gate_str}`;
2390
+ `${auth_str} · ${plugin_str} · ${gate_str}`;
2154
2391
  if (remedies.length > 0) {
2155
2392
  return {
2156
2393
  id: 'team',
@@ -2433,6 +2670,7 @@ function _run_checks(
2433
2670
  'surface-state': _check_surface_state,
2434
2671
  'hook-wiring': _check_hook_wiring,
2435
2672
  'stale-orphans': _check_stale_orphans,
2673
+ 'rule-scope-drift': () => _check_rule_scope_drift(project_root),
2436
2674
  'manifest-integrity': () => _check_manifest_integrity(manifest),
2437
2675
  'lockfile-freshness': () => _check_lockfile_freshness(manifest),
2438
2676
  'bridge-drift': () =>
@@ -2490,8 +2728,8 @@ function _check_bridge_drift_no_manifest(bridge_present: boolean): Dict {
2490
2728
  id: 'bridge-drift',
2491
2729
  status: 'skipped',
2492
2730
  message:
2493
- 'no project lockfile and no bridge marker → drift check ' +
2494
- 'not applicable',
2731
+ 'no project lockfile and no consumer install marker → drift ' +
2732
+ 'check not applicable',
2495
2733
  remedy:
2496
2734
  'run `agent-config init` (project install) or ' +
2497
2735
  '`agent-config refresh --project` (global-only consumer)',
@@ -2512,6 +2750,7 @@ function _run_checks_no_manifest(
2512
2750
  'surface-state': _check_surface_state,
2513
2751
  'hook-wiring': _check_hook_wiring,
2514
2752
  'stale-orphans': _check_stale_orphans,
2753
+ 'rule-scope-drift': () => _check_rule_scope_drift(project_root),
2515
2754
  'manifest-integrity': () => _skipped_manifest_check('manifest-integrity'),
2516
2755
  'lockfile-freshness': () => _skipped_manifest_check('lockfile-freshness'),
2517
2756
  'bridge-drift': () => _check_bridge_drift_no_manifest(bridge_present),
@@ -2555,7 +2794,7 @@ function _run_no_manifest(
2555
2794
  print(` 📍 project_root: ${project_root} (origin: ${origin})`);
2556
2795
  if (bridge_present) {
2557
2796
  print(
2558
- ' ℹ️ global-only consumer: bridge marker present, no ' +
2797
+ ' ℹ️ global-only consumer: install marker present, no ' +
2559
2798
  'project lockfile (expected under ADR-020)',
2560
2799
  );
2561
2800
  print(
@@ -2563,7 +2802,7 @@ function _run_no_manifest(
2563
2802
  'to project-local distributed tools',
2564
2803
  );
2565
2804
  } else {
2566
- eprint(` ⚠️ no project lockfile and no bridge marker at ${project_root}`);
2805
+ eprint(` ⚠️ no project lockfile and no consumer install marker at ${project_root}`);
2567
2806
  eprint(
2568
2807
  ' run `agent-config init` (project install) or ' +
2569
2808
  '`agent-config refresh --project` (global-only consumer)',
@@ -2906,7 +3145,7 @@ function main(argv: string[] | null = null): number {
2906
3145
  const manifest_pth = installed_tools.manifest_path(project_root);
2907
3146
  const manifest = installed_tools.read_manifest(manifest_pth);
2908
3147
  if (manifest === null) {
2909
- const bridge_present = isFile(path.join(project_root, BRIDGE_MARKER_RELATIVE));
3148
+ const bridge_present = _is_global_only_consumer(project_root);
2910
3149
  return _run_no_manifest(opts, project_root, origin, bridge_present);
2911
3150
  }
2912
3151
 
@@ -3007,6 +3246,7 @@ export {
3007
3246
  _check_mcp_mode,
3008
3247
  _check_offline_readiness,
3009
3248
  _check_stale_orphans,
3249
+ _check_rule_scope_drift,
3010
3250
  _check_python_runtime,
3011
3251
  _check_humanizer_runtime,
3012
3252
  _check_mcp_beta_readiness,
@@ -3030,7 +3270,8 @@ export {
3030
3270
  CHECK_IDS,
3031
3271
  GLOBAL_CHECK_IDS,
3032
3272
  MANIFEST_REQUIRED_CHECK_IDS,
3033
- BRIDGE_MARKER_RELATIVE,
3273
+ INSTALL_MODE_MARKER_RELATIVE,
3274
+ _is_global_only_consumer,
3034
3275
  REPAIR_IDS,
3035
3276
  MCP_BETA_GATES,
3036
3277
  STATUS_SYMBOLS,