@event4u/agent-config 3.0.0 → 3.1.1

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 (208) hide show
  1. package/.agent-src/commands/install-via-agent.md +129 -0
  2. package/.agent-src/commands/video/from-script.md +1 -1
  3. package/.agent-src/commands/video.md +1 -1
  4. package/.agent-src/contexts/execution/cheap-question-mechanics.md +81 -0
  5. package/.agent-src/rules/caveman-speak.md +2 -2
  6. package/.agent-src/rules/context-hygiene.md +36 -0
  7. package/.agent-src/rules/engineering-safety-floor.md +102 -0
  8. package/.agent-src/rules/finance-safety-floor.md +114 -0
  9. package/.agent-src/rules/git-history-discipline.md +1 -1
  10. package/.agent-src/rules/no-cheap-questions.md +34 -32
  11. package/.agent-src/rules/provider-lifecycle-discipline.md +4 -4
  12. package/.agent-src/rules/strategy-safety-floor.md +114 -0
  13. package/.agent-src/skills/agents-md-thin-root/SKILL.md +15 -9
  14. package/.agent-src/skills/async-python-patterns/SKILL.md +1 -1
  15. package/.agent-src/skills/project-analysis-node-express/SKILL.md +1 -1
  16. package/.agent-src/skills/readme-reviewer/SKILL.md +52 -3
  17. package/.agent-src/skills/readme-writing/SKILL.md +52 -4
  18. package/.agent-src/skills/readme-writing-package/SKILL.md +48 -5
  19. package/.agent-src/skills/systematic-debugging/SKILL.md +41 -0
  20. package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  21. package/.agent-src/templates/hooks/pre-commit-frontmatter +66 -0
  22. package/.agent-src/templates/hooks/pre-commit-roadmap-progress +78 -39
  23. package/.agent-src/templates/scripts/work_engine/_lib/agent_settings.py +4 -1
  24. package/.agent-src/templates/scripts/work_engine/orchestration.py +25 -11
  25. package/.claude-plugin/marketplace.json +2 -1
  26. package/AGENTS.md +10 -8
  27. package/CHANGELOG.md +233 -123
  28. package/README.md +165 -553
  29. package/config/agent-settings.template.yml +0 -7
  30. package/config/discovery/packs.yml +20 -0
  31. package/config/discovery/unassigned-artefacts.yml +2 -0
  32. package/config/gitignore-block.txt +19 -3
  33. package/dist/cli/commands/uiServe.js +13 -4
  34. package/dist/cli/commands/uiServe.js.map +1 -1
  35. package/dist/cli/registry.js +2 -0
  36. package/dist/cli/registry.js.map +1 -1
  37. package/dist/discovery/deprecation-report.md +7 -0
  38. package/dist/discovery/discovery-manifest.json +2107 -1409
  39. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  40. package/dist/discovery/discovery-manifest.summary.md +9 -9
  41. package/dist/discovery/orphan-report.md +10 -0
  42. package/dist/discovery/packs.json +1002 -0
  43. package/dist/discovery/trust-report.md +26 -0
  44. package/dist/discovery/workspaces.json +705 -0
  45. package/dist/mcp/registry-manifest.json +4 -4
  46. package/dist/router.json +1623 -0
  47. package/dist/server/app.js +11 -3
  48. package/dist/server/app.js.map +1 -1
  49. package/dist/server/io/atomicMultiWrite.js +3 -1
  50. package/dist/server/io/atomicMultiWrite.js.map +1 -1
  51. package/dist/server/io/yamlIO.js +22 -0
  52. package/dist/server/io/yamlIO.js.map +1 -1
  53. package/dist/server/routes/ping.js +8 -0
  54. package/dist/server/routes/ping.js.map +1 -1
  55. package/dist/server/routes/schema.js +2 -2
  56. package/dist/server/routes/schema.js.map +1 -1
  57. package/dist/server/routes/settings.js +104 -23
  58. package/dist/server/routes/settings.js.map +1 -1
  59. package/dist/server/routes/userMd.js +37 -27
  60. package/dist/server/routes/userMd.js.map +1 -1
  61. package/dist/server/routes/wizard.js +256 -20
  62. package/dist/server/routes/wizard.js.map +1 -1
  63. package/dist/server/schemas/settings.js +0 -1
  64. package/dist/server/schemas/settings.js.map +1 -1
  65. package/dist/server/token.js +10 -3
  66. package/dist/server/token.js.map +1 -1
  67. package/dist/server/writeRoot.js +28 -11
  68. package/dist/server/writeRoot.js.map +1 -1
  69. package/dist/server/writeRoot.test.js +22 -4
  70. package/dist/server/writeRoot.test.js.map +1 -1
  71. package/dist/shared/userMd/formAdapter.js +29 -51
  72. package/dist/shared/userMd/formAdapter.js.map +1 -1
  73. package/dist/shared/userMd/schema.js +32 -104
  74. package/dist/shared/userMd/schema.js.map +1 -1
  75. package/dist/shared/userMd/utils.js +64 -50
  76. package/dist/shared/userMd/utils.js.map +1 -1
  77. package/dist/ui/assets/index-D-DY1ywI.js +35 -0
  78. package/dist/ui/assets/index-D-DY1ywI.js.map +1 -0
  79. package/dist/ui/index.html +1 -1
  80. package/docs/adrs/router/0001-three-tier-routing.md +5 -5
  81. package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +1 -1
  82. package/docs/architecture.md +3 -3
  83. package/docs/archive/CHANGELOG-pre-3.1.0.md +167 -0
  84. package/docs/catalog.md +30 -26
  85. package/docs/contracts/CHANGELOG-conventions.md +1 -1
  86. package/docs/contracts/agent-user-schema.md +6 -9
  87. package/docs/contracts/consumer-bridge.md +79 -0
  88. package/docs/contracts/discovery-manifest.md +209 -0
  89. package/docs/contracts/discovery-manifest.schema.json +77 -4
  90. package/docs/contracts/explain-trace.schema.json +1 -1
  91. package/docs/contracts/file-ownership-matrix.json +197 -13
  92. package/docs/contracts/frontmatter-contract.md +140 -0
  93. package/docs/contracts/gui-wizard.md +223 -0
  94. package/docs/contracts/installer-agent-mode.md +137 -0
  95. package/docs/contracts/kernel-membership.md +1 -1
  96. package/docs/contracts/mcp-tool-inventory.md +9 -9
  97. package/docs/contracts/namespace.md +6 -6
  98. package/docs/contracts/provider-lifecycle.md +5 -5
  99. package/docs/contracts/rule-router.md +4 -4
  100. package/docs/contracts/settings-api.md +53 -6
  101. package/docs/contracts/smoke-contracts.md +3 -3
  102. package/docs/contracts/trust-and-safety.md +144 -0
  103. package/docs/customization.md +2 -2
  104. package/docs/decisions/ADR-007-agent-discovery-scopes.md +12 -0
  105. package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +24 -0
  106. package/docs/decisions/ADR-015-discovery-manifest-contract.md +146 -0
  107. package/docs/decisions/ADR-016-installer-architecture.md +189 -0
  108. package/docs/decisions/ADR-017-monorepo-physical-layout.md +261 -0
  109. package/docs/decisions/ADR-018-trust-and-safety-layer.md +159 -0
  110. package/docs/decisions/ADR-019-router-json-dist-location.md +124 -0
  111. package/docs/decisions/ADR-020-global-only-consumer-scope.md +123 -0
  112. package/docs/decisions/ADR-021-deployment-shape.md +153 -0
  113. package/docs/decisions/INDEX.md +7 -0
  114. package/docs/deploy/connector-setup.md +129 -0
  115. package/docs/deploy/env-vars.md +70 -0
  116. package/docs/deploy/policy-cookbook.md +130 -0
  117. package/docs/deploy/quickstart.md +112 -0
  118. package/docs/distribution/public-install-smoke.md +68 -0
  119. package/docs/distribution/registries.md +55 -0
  120. package/docs/distribution/telemetry-privacy.md +128 -0
  121. package/docs/distribution/telemetry-schema.md +174 -0
  122. package/docs/featured-skills.md +95 -0
  123. package/docs/getting-started-by-role.md +19 -1
  124. package/docs/getting-started.md +2 -2
  125. package/docs/guidelines/agent-infra/installed-tools-manifest.md +11 -8
  126. package/docs/guidelines/docs/readme-size-and-splitting.md +53 -1
  127. package/docs/installation.md +27 -14
  128. package/docs/maintainers/dev-mode.md +105 -0
  129. package/docs/setup/per-ide/claude-desktop.md +3 -2
  130. package/docs/wizard.md +39 -4
  131. package/package.json +18 -1
  132. package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
  133. package/scripts/_cli/cmd_doctor.py +150 -2
  134. package/scripts/_cli/cmd_explain.py +2 -1
  135. package/scripts/_cli/cmd_migrate_to_global.py +415 -0
  136. package/scripts/_cli/cmd_settings_migrate.py +146 -0
  137. package/scripts/_cli/explain_last/route.py +2 -1
  138. package/scripts/_dispatch.bash +36 -3
  139. package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
  140. package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
  141. package/scripts/_lib/agent_settings.py +4 -1
  142. package/scripts/_lib/agent_src.py +157 -0
  143. package/scripts/agent-config +17 -6
  144. package/scripts/audit_skill_descriptions.py +18 -6
  145. package/scripts/build_discovery_manifest.py +373 -17
  146. package/scripts/check_artefact_checksums.py +104 -0
  147. package/scripts/check_cluster_patterns.py +20 -4
  148. package/scripts/check_command_count_messaging.py +33 -14
  149. package/scripts/check_council_references.py +43 -4
  150. package/scripts/check_overlay_cascade_subdirs.py +7 -3
  151. package/scripts/check_references.py +5 -2
  152. package/scripts/check_reply_consistency.py +32 -9
  153. package/scripts/check_template_pin_drift.py +24 -7
  154. package/scripts/check_token_optimizer_freshness.py +18 -3
  155. package/scripts/compile_router.py +34 -2
  156. package/scripts/compress.py +162 -44
  157. package/scripts/config/presets.py +19 -1
  158. package/scripts/config/profiles.py +16 -1
  159. package/scripts/discovery_stats.py +70 -0
  160. package/scripts/expected_perms.json +47 -0
  161. package/scripts/generate_index.py +78 -46
  162. package/scripts/generate_ownership_matrix.py +98 -43
  163. package/scripts/generate_pack_manifests.py +183 -0
  164. package/scripts/install +18 -1
  165. package/scripts/install.py +934 -59
  166. package/scripts/install.sh +27 -9
  167. package/scripts/lint_agents_layout.py +93 -13
  168. package/scripts/lint_agents_md.py +1 -1
  169. package/scripts/lint_archived_skills.py +32 -16
  170. package/scripts/lint_bench_corpus.py +14 -2
  171. package/scripts/lint_command_tiers.py +15 -2
  172. package/scripts/lint_featured_skills.py +139 -0
  173. package/scripts/lint_framework_leakage.py +33 -6
  174. package/scripts/lint_global_paths.py +147 -0
  175. package/scripts/lint_orchestration_dsl.py +6 -3
  176. package/scripts/lint_pack_boundaries.py +147 -0
  177. package/scripts/lint_pack_first_win.py +103 -0
  178. package/scripts/lint_readme_jargon.py +131 -0
  179. package/scripts/lint_readme_size.py +33 -0
  180. package/scripts/lint_rule_interactions.py +23 -5
  181. package/scripts/lint_rule_tiers.py +12 -3
  182. package/scripts/lint_trust_coherence.py +212 -0
  183. package/scripts/measure_rule_budget.py +22 -4
  184. package/scripts/move_artefact.py +143 -0
  185. package/scripts/new_skill.py +148 -0
  186. package/scripts/plan_physical_move.py +353 -0
  187. package/scripts/refine_ticket_detect.py +30 -7
  188. package/scripts/release.py +22 -2
  189. package/scripts/schemas/command.schema.json +4 -0
  190. package/scripts/skill_linter.py +248 -118
  191. package/scripts/skill_trigger_eval.py +28 -8
  192. package/scripts/smoke/kernel.sh +1 -1
  193. package/scripts/smoke/router.sh +24 -5
  194. package/scripts/smoke/skills.sh +15 -7
  195. package/scripts/smoke_quickstart.py +11 -2
  196. package/scripts/snapshot_agent_outputs.py +144 -0
  197. package/scripts/update_counts.py +45 -17
  198. package/scripts/validate_decision_engine.py +9 -1
  199. package/scripts/validate_discovery_manifest.py +94 -0
  200. package/scripts/validate_frontmatter.py +39 -20
  201. package/scripts/verify_physical_move.py +185 -0
  202. package/templates/agent-user.md +0 -1
  203. package/templates/agent-user.yml +21 -0
  204. package/templates/minimal/agents-overrides-readme.md +46 -0
  205. package/templates/minimal/overrides-gitkeep +2 -0
  206. package/dist/ui/assets/index-BTRcKDlB.js +0 -39
  207. package/dist/ui/assets/index-BTRcKDlB.js.map +0 -1
  208. package/templates/minimal/agents-gitkeep +0 -2
@@ -0,0 +1,137 @@
1
+ ---
2
+ stability: beta
3
+ keep-beta-until: 2026-08-19
4
+ ---
5
+
6
+ # Installer agent-mode protocol — JSON-over-stdio contract
7
+
8
+ > Companion to [ADR-016](../decisions/ADR-016-installer-architecture.md)
9
+ > § 4 and § 6. The ADR is the decision; this file is the worked-example
10
+ > reference that agents (Claude, Cursor, GPT, …) and the installer
11
+ > CLI share at runtime.
12
+
13
+ ## Source of truth
14
+
15
+ The agent-mode state machine lives in
16
+ [`packages/core/installer/src/agent-mode/machine.ts`](../../packages/core/installer/src/agent-mode/machine.ts).
17
+ Envelope construction and `--answer` parsing live in
18
+ [`protocol.ts`](../../packages/core/installer/src/agent-mode/protocol.ts).
19
+ Both are unit-tested under
20
+ [`packages/core/installer/tests/agent-mode-*.test.ts`](../../packages/core/installer/tests/).
21
+
22
+ ## Design constraints
23
+
24
+ - **Stateless across invocations** — the installer keeps no
25
+ server-side session. Every turn carries the full conversation as
26
+ repeated `--answer key=value` flags. An agent may re-issue from
27
+ scratch at any time.
28
+ - **Strict question-id sequencing** — answers must arrive in the
29
+ order the installer asks them (`q1.workspaces`, then `q2.packs`,
30
+ then optional `q3.confirm`). Out-of-order or unknown ids return
31
+ an `error` envelope, exit code 2.
32
+ - **Single-line JSON per turn** — stdout emits exactly one
33
+ newline-terminated JSON object per invocation; stderr is reserved
34
+ for diagnostics and is not part of the contract.
35
+ - **`protocol_version: 1`** — every envelope carries it; agents
36
+ refusing the version negotiate by aborting.
37
+
38
+ ## Envelope shapes
39
+
40
+ ### `question`
41
+
42
+ The installer is waiting for the next answer.
43
+
44
+ ```json
45
+ {
46
+ "status": "question",
47
+ "protocol_version": 1,
48
+ "id": "q1.workspaces",
49
+ "prompt": "Which workspaces does this project need? (multi, comma-separated)",
50
+ "choices": [
51
+ { "value": "engineering", "label": "Engineering" },
52
+ { "value": "product", "label": "Product" }
53
+ ],
54
+ "multi": true,
55
+ "next_call": "init --agent --answer q1.workspaces=<value>"
56
+ }
57
+ ```
58
+
59
+ - `id` — the canonical question identifier; the agent echoes it as
60
+ `--answer <id>=<value>`.
61
+ - `multi: true` — comma-separated values allowed; `multi: false` —
62
+ exactly one value.
63
+ - `next_call` — the literal command the agent should issue next,
64
+ with `<value>` (and prior answers) substituted in.
65
+
66
+ ### `done`
67
+
68
+ Terminal success; no further calls needed.
69
+
70
+ ```json
71
+ {
72
+ "status": "done",
73
+ "protocol_version": 1,
74
+ "summary": { "files_written": 83, "lockfile_sha256": "c45b3035…" }
75
+ }
76
+ ```
77
+
78
+ ### `error`
79
+
80
+ Terminal failure; exit code 2.
81
+
82
+ ```json
83
+ {
84
+ "status": "error",
85
+ "protocol_version": 1,
86
+ "reason": "out_of_order",
87
+ "expected_question_id": "q1.workspaces",
88
+ "received": "q2.packs"
89
+ }
90
+ ```
91
+
92
+ Defined `reason` values: `answer_malformed`, `out_of_order`,
93
+ `unknown_workspace`, `unknown_pack`, `aborted_by_agent`.
94
+
95
+ ## Turn-by-turn worked example
96
+
97
+ ```bash
98
+ # Turn 1 — discover workspaces
99
+ $ installer init --agent
100
+ {"status":"question","id":"q1.workspaces", … "next_call":"… --answer q1.workspaces=<value>"}
101
+
102
+ # Turn 2 — answer workspaces, discover packs
103
+ $ installer init --agent --answer q1.workspaces=engineering
104
+ {"status":"question","id":"q2.packs", … "next_call":"… --answer q1.workspaces=engineering --answer q2.packs=<value>"}
105
+
106
+ # Turn 3 — answer packs, install completes
107
+ $ installer init --agent --answer q1.workspaces=engineering --answer q2.packs=engineering-base
108
+ {"status":"done","summary":{"files_written":83,"lockfile_sha256":"c45b3035…"}}
109
+ ```
110
+
111
+ When the pack selection pulls in extras via `requires_hint`, the
112
+ installer inserts a `q3.confirm` turn before completing:
113
+
114
+ ```bash
115
+ $ installer init --agent --answer q1.workspaces=engineering --answer q2.packs=symfony
116
+ {"status":"question","id":"q3.confirm", "prompt":"Auto-added packs: php. Continue?", "choices":[{"value":"yes","label":"yes"},{"value":"no","label":"no"}], "multi":false, … }
117
+ ```
118
+
119
+ `q3.confirm=no` returns `reason: "aborted_by_agent"`.
120
+
121
+ ## Flags relevant to agent mode
122
+
123
+ - `--manifest <path>` — override the manifest location (defaults to
124
+ walking up for `dist/discovery/discovery-manifest.json`).
125
+ - `--project-root <path>` — destination project root.
126
+ - `--dry-run` — resolve and emit the `done` envelope without
127
+ touching disk; used by agents that want a plan preview.
128
+
129
+ ## Failure modes guarded against
130
+
131
+ - **Agent loops** — `protocol_version` mismatch on any side aborts
132
+ immediately; no implicit version negotiation.
133
+ - **State drift between turns** — the installer never reads
134
+ workdir state to recover answers; every fact must be carried in
135
+ `--answer` flags.
136
+ - **Silent partial install** — on any error after `q2.packs`,
137
+ exit code 2 with no disk writes (atomic via `StagingSession`).
@@ -231,7 +231,7 @@ that fires on every action decision. Swap proposal: `agent-authority`
231
231
  the 9-rule set through P2.2. Re-evaluation trigger fires at P3.2
232
232
  once the router schema and compiler ship; at that point
233
233
  `agent-authority`'s routing role becomes redundant (each kernel rule
234
- carries its own band as frontmatter, compiled into `router.json`),
234
+ carries its own band as frontmatter, compiled into `dist/router.json`),
235
235
  clearing the way for the swap under a fresh ADR.
236
236
 
237
237
  ## § 6 — Abort criteria for P2.2
@@ -23,12 +23,12 @@ keep-beta-until: 2026-08-14
23
23
 
24
24
  | Tool | Side-effect | Transports | Catalog | Handler |
25
25
  |---|---|---|---|---|
26
- | `lint_skills` | `ro` | stdio | [`consumer_tool_catalog.json:7`](../../scripts/mcp_server/consumer_tool_catalog.json#L7) | [`tools.py:510`](../../scripts/mcp_server/tools.py#L510) |
27
- | `chat_history_append` | `fs-write` | stdio | [`consumer_tool_catalog.json:24`](../../scripts/mcp_server/consumer_tool_catalog.json#L24) | [`tools.py:535`](../../scripts/mcp_server/tools.py#L535) |
28
- | `chat_history_read` | `ro` | stdio | [`consumer_tool_catalog.json:43`](../../scripts/mcp_server/consumer_tool_catalog.json#L43) | [`tools.py:571`](../../scripts/mcp_server/tools.py#L571) |
29
- | `memory_lookup` | `ro` | stdio | [`consumer_tool_catalog.json:59`](../../scripts/mcp_server/consumer_tool_catalog.json#L59) | [`tools.py:590`](../../scripts/mcp_server/tools.py#L590) |
26
+ | `lint_skills` | `ro` | stdio | [`consumer_tool_catalog.json:7`](../../scripts/mcp_server/consumer_tool_catalog.json#L7) | [`tools.py:521`](../../scripts/mcp_server/tools.py#L521) |
27
+ | `chat_history_append` | `fs-write` | stdio | [`consumer_tool_catalog.json:24`](../../scripts/mcp_server/consumer_tool_catalog.json#L24) | [`tools.py:546`](../../scripts/mcp_server/tools.py#L546) |
28
+ | `chat_history_read` | `ro` | stdio | [`consumer_tool_catalog.json:43`](../../scripts/mcp_server/consumer_tool_catalog.json#L43) | [`tools.py:586`](../../scripts/mcp_server/tools.py#L586) |
29
+ | `memory_lookup` | `ro` | stdio | [`consumer_tool_catalog.json:59`](../../scripts/mcp_server/consumer_tool_catalog.json#L59) | [`tools.py:606`](../../scripts/mcp_server/tools.py#L606) |
30
30
  | `memory_signal` | `fs-write` | _(stub)_ | [`consumer_tool_catalog.json:75`](../../scripts/mcp_server/consumer_tool_catalog.json#L75) | _stub-only_ |
31
- | `memory_status` | `ro` | stdio | [`consumer_tool_catalog.json:91`](../../scripts/mcp_server/consumer_tool_catalog.json#L91) | [`tools.py:617`](../../scripts/mcp_server/tools.py#L617) |
31
+ | `memory_status` | `ro` | stdio | [`consumer_tool_catalog.json:91`](../../scripts/mcp_server/consumer_tool_catalog.json#L91) | [`tools.py:633`](../../scripts/mcp_server/tools.py#L633) |
32
32
  | `skill_trigger_eval` | `ro` | _(stub)_ | [`consumer_tool_catalog.json:98`](../../scripts/mcp_server/consumer_tool_catalog.json#L98) | _stub-only_ |
33
33
  | `suggest_command` | `ro` | _(stub)_ | [`consumer_tool_catalog.json:114`](../../scripts/mcp_server/consumer_tool_catalog.json#L114) | _stub-only_ |
34
34
  | `suggest_skill_for_task` | `ro` | _(stub)_ | [`consumer_tool_catalog.json:129`](../../scripts/mcp_server/consumer_tool_catalog.json#L129) | _stub-only_ |
@@ -38,11 +38,11 @@ keep-beta-until: 2026-08-14
38
38
  | `sync_agent_settings` | `fs-write` | _(stub)_ | [`consumer_tool_catalog.json:186`](../../scripts/mcp_server/consumer_tool_catalog.json#L186) | _stub-only_ |
39
39
  | `run_tests` | `shell` | _(stub)_ | [`consumer_tool_catalog.json:200`](../../scripts/mcp_server/consumer_tool_catalog.json#L200) | _stub-only_ |
40
40
  | `run_quality_checks` | `shell` | _(stub)_ | [`consumer_tool_catalog.json:214`](../../scripts/mcp_server/consumer_tool_catalog.json#L214) | _stub-only_ |
41
- | `list_skills` | `ro` | stdio | [`consumer_tool_catalog.json:227`](../../scripts/mcp_server/consumer_tool_catalog.json#L227) | [`tools.py:631`](../../scripts/mcp_server/tools.py#L631) |
42
- | `list_commands` | `ro` | stdio | [`consumer_tool_catalog.json:234`](../../scripts/mcp_server/consumer_tool_catalog.json#L234) | [`tools.py:644`](../../scripts/mcp_server/tools.py#L644) |
43
- | `list_rules` | `ro` | stdio | [`consumer_tool_catalog.json:241`](../../scripts/mcp_server/consumer_tool_catalog.json#L241) | [`tools.py:657`](../../scripts/mcp_server/tools.py#L657) |
41
+ | `list_skills` | `ro` | stdio | [`consumer_tool_catalog.json:227`](../../scripts/mcp_server/consumer_tool_catalog.json#L227) | [`tools.py:647`](../../scripts/mcp_server/tools.py#L647) |
42
+ | `list_commands` | `ro` | stdio | [`consumer_tool_catalog.json:234`](../../scripts/mcp_server/consumer_tool_catalog.json#L234) | [`tools.py:660`](../../scripts/mcp_server/tools.py#L660) |
43
+ | `list_rules` | `ro` | stdio | [`consumer_tool_catalog.json:241`](../../scripts/mcp_server/consumer_tool_catalog.json#L241) | [`tools.py:673`](../../scripts/mcp_server/tools.py#L673) |
44
44
  | `compile_router` | `shell` | _(stub)_ | [`consumer_tool_catalog.json:248`](../../scripts/mcp_server/consumer_tool_catalog.json#L248) | _stub-only_ |
45
- | `read_resource_body` | `ro` | stdio | [`consumer_tool_catalog.json:261`](../../scripts/mcp_server/consumer_tool_catalog.json#L261) | [`tools.py:670`](../../scripts/mcp_server/tools.py#L670) |
45
+ | `read_resource_body` | `ro` | stdio | [`consumer_tool_catalog.json:261`](../../scripts/mcp_server/consumer_tool_catalog.json#L261) | [`tools.py:686`](../../scripts/mcp_server/tools.py#L686) |
46
46
 
47
47
  ## Glossary
48
48
 
@@ -5,8 +5,8 @@ stability: stable
5
5
  # Namespace contract — skills, rules, commands, personas
6
6
 
7
7
  > Every artefact name is a **stable identifier**: routed to from
8
- > `router.json`, cited from skills, surfaced in `/help`, embedded in
9
- > command paths, and back-referenced in test fixtures. Drift breaks
8
+ > `dist/router.json`, cited from skills, surfaced in `/help`, embedded
9
+ > in command paths, and back-referenced in test fixtures. Drift breaks
10
10
  > all five surfaces silently.
11
11
  >
12
12
  > **Source:** Step-11 Phase 5 Step 1
@@ -43,7 +43,7 @@ permitted when the stem already encodes both (`commit`, `eloquent`,
43
43
  | `claude-memories` | Reserved for the `~/.claude/CLAUDE.md` shape — host-agent state, not a package artefact. |
44
44
  | `default` | Ambiguous with profile / mode defaults; collides with `.agent-settings.yml` keys. |
45
45
  | `index` | Reserved for auto-generated INDEX.md files. |
46
- | `router` | Reserved for `router.json` and the router contract. |
46
+ | `router` | Reserved for `dist/router.json` and the router contract. |
47
47
 
48
48
  Reserved names apply at the **top level** of each artefact type. A
49
49
  sub-verb under a namespaced group (e.g. `council/default.md` →
@@ -97,8 +97,8 @@ python3 scripts/lint_namespace.py
97
97
  ```
98
98
 
99
99
  If the candidate fails, the linter prints the rule it violated.
100
- **Renames after release are expensive** — touch router.json, every
101
- skill citing the old name, the bench corpus, and consumer settings.
100
+ **Renames after release are expensive** — touch `dist/router.json`,
101
+ every skill citing the old name, the bench corpus, and consumer settings.
102
102
  Pay the naming cost once, upfront.
103
103
 
104
104
  ## 6. Relationship to the frontmatter contract
@@ -111,7 +111,7 @@ the regex string.
111
111
 
112
112
  ## 7. Why this exists
113
113
 
114
- `router.json` resolves `<kind>:<id>` strings at session start. Any
114
+ `dist/router.json` resolves `<kind>:<id>` strings at session start. Any
115
115
  artefact rename breaks every routing entry pointing at the old name
116
116
  without compile-time error. The linter catches the rename at the PR
117
117
  boundary, not at runtime in a consumer.
@@ -7,7 +7,7 @@ keep-beta-until: 2026-08-15
7
7
 
8
8
  > **Status:** active · **Stability:** beta · **Owner:** universal-platform-refinement Phase 3
9
9
  > · **Linter:** none (declarative contract; enforced agent-in-the-loop via [`provider-lifecycle-discipline`](../../.agent-src/rules/provider-lifecycle-discipline.md))
10
- > · **Source-of-truth template:** [`agents/.ai-video.xml.example`](../../agents/.ai-video.xml.example)
10
+ > · **Source-of-truth template:** [`agents/templates/.ai-video.xml.example`](../../agents/templates/.ai-video.xml.example)
11
11
 
12
12
  Locks the lifecycle tagging used on every adapter under
13
13
  `scripts/ai-video/adapters/` (and future `scripts/ai-image/`,
@@ -42,7 +42,7 @@ the human noticing.
42
42
  surface (`submit / poll / fetch / dry-run` *or* `run / dry-run`)
43
43
  matches `scripts/ai-video/lib/adapter-contract.md` verbatim.
44
44
 
45
- A maintainer flipping the tier in `agents/.ai-video.xml.example`
45
+ A maintainer flipping the tier in `agents/templates/.ai-video.xml.example`
46
46
  **and** the adapter header comment is the promotion event. There is
47
47
  no separate registry — the example file is the registry.
48
48
 
@@ -67,7 +67,7 @@ When the agent picks a provider for a `/video:*` / `/image:*` /
67
67
 
68
68
  1. **Read** the `provider_lifecycle` tag from the adapter's header
69
69
  comment **and** the matching `<provider id="…">` block in
70
- `agents/.ai-video.xml.example` (or the operator's
70
+ `agents/templates/.ai-video.xml.example` (or the operator's
71
71
  `agents/.ai-video.xml`).
72
72
  2. **Refuse-and-surface** if the operator's resolved default is a
73
73
  non-`stable` tier — name the tier and the path to this contract
@@ -103,7 +103,7 @@ so the agent surfaces the tier and asks before proceeding — the
103
103
  human is the policy decision point.
104
104
 
105
105
  The `<default-image-provider>` and `<default-video-provider>`
106
- entries in `agents/.ai-video.xml.example` remain unchanged
106
+ entries in `agents/templates/.ai-video.xml.example` remain unchanged
107
107
  (`openai-images` and `gemini-veo`). The tier tag does not change
108
108
  defaults; it changes whether the agent silently honours them.
109
109
 
@@ -118,5 +118,5 @@ snapshot — older snapshots live in git history, not in this file.
118
118
 
119
119
  - [`provider-lifecycle-discipline`](../../.agent-src/rules/provider-lifecycle-discipline.md) — the tier-2 routing rule that surfaces this contract when a provider is touched.
120
120
  - [`scripts/ai-video/lib/adapter-contract.md`](../../scripts/ai-video/lib/adapter-contract.md) — the four-method shell contract every adapter implements.
121
- - [`agents/.ai-video.xml.example`](../../agents/.ai-video.xml.example) — operator-facing provider configuration template (carries the tier tag inline).
121
+ - [`agents/templates/.ai-video.xml.example`](../../agents/templates/.ai-video.xml.example) — operator-facing provider configuration template (carries the tier tag inline).
122
122
  - [`agents/settings/policies/media/README.md`](../../agents/settings/policies/media/README.md) — the agent-in-the-loop enforcement model this contract participates in.
@@ -83,8 +83,8 @@ whose body is fully covered by an existing architectural contract.
83
83
  ## Compiled output — `router.json`
84
84
 
85
85
  `scripts/compile_router.py` reads every rule frontmatter and emits
86
- `router.json` at the repo root, used by host agents at session start.
87
- Deterministic key order, sorted lists, stable across runs.
86
+ `dist/router.json` (tracked in git), used by host agents at session
87
+ start. Deterministic key order, sorted lists, stable across runs.
88
88
 
89
89
  ```json
90
90
  {
@@ -110,7 +110,7 @@ Generated alongside `marketplace.json` during `task generate-tools`.
110
110
 
111
111
  ## Activation semantics
112
112
 
113
- The host agent reads `router.json` once per session. Per turn:
113
+ The host agent reads `dist/router.json` once per session. Per turn:
114
114
 
115
115
  1. Always evaluate kernel rules.
116
116
  2. If `profile = minimal` → stop after kernel.
@@ -151,4 +151,4 @@ start, the router lookup is keyword/phrase/path/intent matching only.
151
151
  - This file: schema specification.
152
152
  - `kernel-membership.md` § 4: kernel locked count + SHAs.
153
153
  - `rule-classification.md`: per-rule tier + disposition pre-Phase-4.
154
- - `router.json` (generated): runtime artifact, never hand-edited.
154
+ - `dist/router.json` (generated): runtime artifact, never hand-edited.
@@ -48,8 +48,22 @@ Response (200):
48
48
 
49
49
  ### `GET /api/v1/settings`
50
50
 
51
- Reads `<projectRoot>/.agent-settings.yml` and returns the parsed values
52
- plus the freshness token for optimistic locking.
51
+ Returns the **three-layer merged** settings tree plus the freshness
52
+ token for optimistic locking. Merge order (per **ADR-020** + roadmap
53
+ `road-to-global-only-install` § Phase 2.2):
54
+
55
+ ```text
56
+ defaults (config/agent-settings.template.yml)
57
+ < global (~/.event4u/agent-config/settings/.agent-settings.yml)
58
+ < project (<projectRoot>/settings/.agent-settings.yml, optional)
59
+ ```
60
+
61
+ Defaults come from the package template with `__COST_PROFILE__` /
62
+ `__USER_TYPE__` placeholders substituted for their permissive defaults
63
+ (`balanced` / `""`). Global and project layers are read with the typed
64
+ subdir preferred over the legacy flat path. The route mirrors
65
+ `scripts/install.py::read_layered_settings` 1:1 so the Python installer
66
+ and the Fastify GUI cannot drift.
53
67
 
54
68
  Response (200):
55
69
 
@@ -57,13 +71,28 @@ Response (200):
57
71
  {
58
72
  "values": { "cost_profile": "balanced", "...": "..." },
59
73
  "lastModified": 1747749791842,
60
- "path": ".agent-settings.yml"
74
+ "path": "settings/.agent-settings.yml",
75
+ "legacyHints": { "user_name": "Matze" }
61
76
  }
62
77
  ```
63
78
 
64
- Errors: **404** when the file is missing (the SPA should redirect to
65
- `/#/wizard/Welcome`); **500** with `code=YAML_PARSE` when YAML parsing
66
- fails (body includes the line/column).
79
+ `legacyHints` is an out-of-band sidecar carrying values that have moved
80
+ out of `settingsSchema` but still live in a pre-v2 file on disk. Keys
81
+ are omitted when empty, never `null`. Current hints:
82
+
83
+ | Key | Source (legacy) | New home |
84
+ | ----------- | ---------------------- | --------------------------------------- |
85
+ | `user_name` | `personal.user_name` | `.agent-user.md` &rarr; `identity.name` |
86
+
87
+ The wizard consumes hints on first run only — when `.agent-user.md`
88
+ does not yet exist — to pre-fill the merged identity field. Subsequent
89
+ PUTs strip the legacy keys (Zod-unknown), so the next read returns no
90
+ hints.
91
+
92
+ Errors: **404** when **neither** the global nor the project file
93
+ exists (defaults alone are not an "installed" state — the SPA should
94
+ redirect to `/#/wizard/Welcome`); **500** with `code=YAML_PARSE` when
95
+ either layer is on disk but unparseable (body includes the line/column).
67
96
 
68
97
  ### `POST /api/v1/settings/diff`
69
98
 
@@ -139,6 +168,24 @@ Errors: **500** with `code=TXN_PARTIAL` when the marker survives a crash
139
168
  (client should redirect the user to a "your last save is being
140
169
  recovered" screen and refetch state).
141
170
 
171
+ ## CLI: `agent-config settings migrate`
172
+
173
+ Companion to the layered reader (ADR-020). Lifts an existing
174
+ project-local `.agent-user.yml` / `.agent-settings.yml` into
175
+ `~/.event4u/agent-config/`. Idempotent — refuses to overwrite a
176
+ non-empty global file without `--force`. Order matches Phase 5
177
+ amendment A2 (`copy → verify`; the destructive `move` step is owned by
178
+ `migrate-to-global`, not this subcommand).
179
+
180
+ Flags:
181
+
182
+ - `--from <path>` — project root to read from (default: `cwd`).
183
+ - `--force` — overwrite a non-empty global file.
184
+ - `--dry-run` — list intended copies; zero writes; exit 0.
185
+
186
+ Exit codes: `0` on success or no-op; `1` on validation failure or a
187
+ non-empty global file without `--force`.
188
+
142
189
  ## Status codes summary
143
190
 
144
191
  | Code | Meaning |
@@ -34,8 +34,8 @@ the paths touched in the PR:
34
34
 
35
35
  | Tier | Globs that trigger | Script |
36
36
  |---|---|---|
37
- | kernel | `.agent-src.uncompressed/rules/**`, `.agent-src/rules/**`, `router.json`, `scripts/measure_rule_budget.py` | `scripts/smoke/kernel.sh` |
38
- | router | `router.json`, `.agent-src.uncompressed/rules/**`, `.agent-src.uncompressed/skills/**`, `docs/contracts/**`, `docs/guidelines/**` | `scripts/smoke/router.sh` |
37
+ | kernel | `.agent-src.uncompressed/rules/**`, `.agent-src/rules/**`, `dist/router.json`, `scripts/measure_rule_budget.py` | `scripts/smoke/kernel.sh` |
38
+ | router | `dist/router.json`, `.agent-src.uncompressed/rules/**`, `.agent-src.uncompressed/skills/**`, `docs/contracts/**`, `docs/guidelines/**` | `scripts/smoke/router.sh` |
39
39
  | schema | `.agent-src.uncompressed/skills/**`, `.agent-src.uncompressed/rules/**`, `scripts/schemas/**`, `scripts/skill_linter.py`, `scripts/validate_frontmatter.py` | `scripts/smoke/schema.sh` |
40
40
  | skills | `.agent-src.uncompressed/skills/**` | `scripts/smoke/skills.sh` |
41
41
 
@@ -131,7 +131,7 @@ the final baseline line) for CI summary parsing.
131
131
  | Symptom | Likely cause | Fix |
132
132
  |---|---|---|
133
133
  | `kernel.sh` reports > 9 missing fences | Kernel rule lost its Iron Law block during edit | Restore the fence; update `EXEMPT_FROM_FENCE` only for new dispatch indexes |
134
- | `router.sh` reports > 0 broken pointers | `router.json` references an id without a rule file | Add the rule or remove the route — never edit the smoke baseline up |
134
+ | `router.sh` reports > 0 broken pointers | `dist/router.json` references an id without a rule file | Add the rule or remove the route — never edit the smoke baseline up |
135
135
  | `schema.sh` reports FAILs | A skill / rule lost a required field | Restore via [`scripts/schemas/skill.schema.json`](../../scripts/schemas/skill.schema.json) |
136
136
  | `skills.sh` 5/5 random sample fails | Hand-edit broke frontmatter or renamed directory without updating `name:` | Restore filename ↔ slug coupling |
137
137
 
@@ -0,0 +1,144 @@
1
+ ---
2
+ stability: beta
3
+ keep-beta-until: 2026-08-21
4
+ ---
5
+
6
+ # Trust & Safety Layer — Phase 5 of the monorepo migration
7
+
8
+ > **Status:** active · **Stability:** beta · **Owner:** monorepo-phase-5
9
+ > · **Authoritative ADR:** [`ADR-018`](../decisions/ADR-018-trust-and-safety-layer.md)
10
+
11
+ Phase 1 stamped every artefact with `trust.level`,
12
+ `trust.confidence`, and `trust.human_review_required`. Phase 5
13
+ **enforces** those fields: the installer surfaces them at selection
14
+ time, the compressor injects banners into compiled output, the
15
+ runtime gates `human_review_required: true` artefacts before final
16
+ output, and a lint catches drift. This contract is what those four
17
+ consumers depend on.
18
+
19
+ ## § 1 — Trust levels
20
+
21
+ A closed enum on `trust.level`:
22
+
23
+ | level | meaning |
24
+ |---------------|----------------------------------------------------------------------|
25
+ | `core` | Iron-Law / structural. Cannot be downgraded. Kernel rules sit here. |
26
+ | `professional`| Domain expertise the user opted into; no human-review floor. |
27
+ | `advisory` | High-impact judgement. Installer **must** confirm; banner injected. |
28
+ | `restricted` | Reserved for future legal / regulated content. Same surface as advisory, stricter copy. |
29
+ | `experimental`| Pre-stable. May be removed without ADR. |
30
+
31
+ `trust.confidence` is a parallel signal (`high` · `medium` · `low`)
32
+ used by the manifest's summary; it does **not** gate behaviour.
33
+
34
+ `trust.human_review_required: true` is the per-artefact banner gate.
35
+ Independent of `trust.level` so a `professional` artefact can still
36
+ demand review on its specific surface.
37
+
38
+ ## § 2 — HRR banner
39
+
40
+ The compressor (`scripts/compress.py`) prepends every artefact whose
41
+ frontmatter declares `trust.human_review_required: true` with:
42
+
43
+ ```text
44
+ <!-- agent-config:human-review-banner -->
45
+ > HUMAN REVIEW REQUIRED · trust: <level> · owner: <domain>
46
+
47
+ <original body>
48
+ ```
49
+
50
+ - The HTML comment is the parser-stable marker
51
+ (`_HRR_BANNER_MARKER` in `scripts/compress.py`). Runtime detection
52
+ greps for this string, never the prose line.
53
+ - Idempotent: re-compressing a file that already carries the marker
54
+ leaves it unchanged.
55
+ - `<domain>` is the first pack id that ships the artefact (e.g.
56
+ `finance-basic`, `founder-strategy`); falls back to `core` for
57
+ unscoped artefacts.
58
+
59
+ ## § 3 — Domain safety floors
60
+
61
+ Each pack that ships any `advisory`/`restricted` artefact MUST also
62
+ ship at least one rule whose logical filename contains
63
+ `safety-floor`. The current set:
64
+
65
+ | pack | safety-floor rule |
66
+ |-------------------------|----------------------------------------------------|
67
+ | `core` (universal) | `rules/engineering-safety-floor.md` |
68
+ | `pack-finance-basic` | `rules/finance-safety-floor.md` |
69
+ | `pack-finance-advanced` | inherits `finance-safety-floor` from `pack-finance-basic` |
70
+ | `pack-founder-strategy` | `rules/strategy-safety-floor.md` |
71
+
72
+ A safety-floor rule:
73
+
74
+ - Carries `trust.level: advisory` and `trust.human_review_required: true`
75
+ itself — it ships with the banner.
76
+ - Names what the agent must **not** issue (final investment call, binding
77
+ legal advice, single-path strategic verdict) and what it must surface
78
+ instead (alternatives, sensitivity, assumptions, jurisdiction).
79
+ - Loads automatically alongside the rest of the pack — no opt-in.
80
+
81
+ ## § 4 — Installer flow
82
+
83
+ [`packages/core/installer/src/trust-escalation.ts`](../../packages/core/installer/src/trust-escalation.ts)
84
+ implements the gate:
85
+
86
+ 1. **Display.** The pack picker reads `packs[].trust_summary` from
87
+ `dist/discovery/discovery-manifest.json` and renders one line per pack:
88
+ `Finance basic: 3 advisory · 3 professional · human-review on 1`.
89
+ 2. **Confirm.** Selecting a pack with any `advisory`/`restricted`
90
+ artefact triggers a confirm prompt. Non-interactive mode (CI,
91
+ agent-mode) requires `--accept-advisory=<pack-id>[,<pack-id>...]`
92
+ explicitly; absence aborts with a non-zero exit.
93
+ 3. **Agent-mode.** Emits a structured `confirm` question type with the
94
+ trust counts inline; the host agent must relay it verbatim per
95
+ `command-suggestion-policy`.
96
+ 4. **Lockfile.** `.agent-config.lock.json` records the accepted trust
97
+ counts per pack at install time. A later `sync` that finds the
98
+ manifest's `trust_summary` has **escalated** (more advisory /
99
+ restricted artefacts than were accepted) re-runs the confirm step
100
+ before applying.
101
+
102
+ ## § 5 — Coherence lint
103
+
104
+ `scripts/lint_trust_coherence.py` (wired into `ci-fast` and `ci-full`)
105
+ asserts three invariants over `dist/discovery/discovery-manifest.json`:
106
+
107
+ 1. **Safety-floor presence.** Every pack with
108
+ `trust_summary.advisory + trust_summary.restricted > 0` ships at
109
+ least one artefact whose logical path contains `safety-floor`.
110
+ 2. **Banner presence.** Every artefact with
111
+ `trust.human_review_required: true` has its compiled output under
112
+ `.agent-src/<logical>` and that output contains
113
+ `<!-- agent-config:human-review-banner -->`.
114
+ 3. **Kernel trust floor.** Every rule listed in `dist/router.json` `kernel[]`
115
+ declares `trust.level: core`. No escalation (advisory blocks the
116
+ Iron-Law floor) and no demotion (experimental cannot guarantee it).
117
+
118
+ Exits 0 clean, 1 on any violation. Tests in
119
+ `tests/test_lint_trust_coherence.py` lock the seven failure modes.
120
+
121
+ ## § 6 — What this contract does **not** do
122
+
123
+ - **Per-user permissions.** Trust is a property of artefacts, not of
124
+ users. The installer confirms once at install / sync time; there is
125
+ no runtime per-action authorisation.
126
+ - **Rewriting the Iron Law floor.** `non-destructive-by-default`,
127
+ `commit-policy`, `scope-control § git-ops`, `security-sensitive-stop`
128
+ keep their universal scope — this contract references them, never
129
+ re-declares them. See [`safety-model`](safety-model.md) and
130
+ [`kernel-membership`](kernel-membership.md).
131
+ - **Versioning the trust enum.** A new level (e.g. a future
132
+ `regulated`) requires a follow-on ADR; this contract enumerates the
133
+ current closed set.
134
+
135
+ ## § 7 — References
136
+
137
+ - ADR: [`ADR-018 — Trust & Safety Layer`](../decisions/ADR-018-trust-and-safety-layer.md)
138
+ - Compressor implementation: [`scripts/compress.py`](../../scripts/compress.py)
139
+ (`_inject_hrr_banner`, `_HRR_BANNER_MARKER`)
140
+ - Installer implementation: [`packages/core/installer/src/trust-escalation.ts`](../../packages/core/installer/src/trust-escalation.ts)
141
+ - Lint implementation: [`scripts/lint_trust_coherence.py`](../../scripts/lint_trust_coherence.py)
142
+ - Sibling contracts: [`safety-model`](safety-model.md) ·
143
+ [`kernel-membership`](kernel-membership.md) ·
144
+ [`ADR-013` — discovery frontmatter](../decisions/ADR-013-discovery-frontmatter-contract.md)
@@ -205,7 +205,7 @@ if the key file's permissions drift.
205
205
  `cost_profile` is the master switch for rule-tier loading. The kernel
206
206
  (always-loaded Iron-Law floor, ≤ 26k chars across 9 rules) ships in every
207
207
  profile. Tier-1 and tier-2 rules are gated by profile and resolved at
208
- session start from `router.json` (compiled by `scripts/compile_router.py`).
208
+ session start from `dist/router.json` (compiled by `scripts/compile_router.py`).
209
209
 
210
210
  | Profile | Rule tiers loaded | Token footprint | Best for |
211
211
  |---|---|---|---|
@@ -218,7 +218,7 @@ The kernel-and-router architecture is documented in
218
218
  [`docs/contracts/rule-router.md`](contracts/rule-router.md) and
219
219
  [`docs/contracts/kernel-membership.md`](contracts/kernel-membership.md).
220
220
  Tier flags live in each rule's frontmatter (`tier: kernel | tier-1 | tier-2`);
221
- the router compiles them into `router.json` deterministically.
221
+ the router compiles them into `dist/router.json` deterministically.
222
222
 
223
223
  All profiles except `custom` ship with `pipelines.skill_improvement: true`,
224
224
  so the agent captures learnings after meaningful tasks by default. Set it
@@ -262,6 +262,18 @@ maintainer manifest).
262
262
  road-to-simplicity-and-everywhere" is **never built**. Roadmap
263
263
  entry should be updated to point at `export` instead.
264
264
 
265
+ ## Amendment 2026-05-23 — Global-only consumer scope (ADR-020)
266
+
267
+ [`ADR-020`](ADR-020-global-only-consumer-scope.md) finishes the job
268
+ this ADR started: the consumer surface becomes **global-only**
269
+ end-to-end. The project-default in this ADR is therefore historical;
270
+ new installs land at `~/.event4u/agent-config/` only. The project
271
+ tree retains exactly two artefacts — `agents/overrides/` and
272
+ `agents/.event4u-bridge.yml` — both written by
273
+ `scripts/install.py`. Maintainer-only project scope survives behind
274
+ `AGENT_CONFIG_DEV_MODE=1` (see
275
+ [`docs/maintainers/dev-mode.md`](../maintainers/dev-mode.md)).
276
+
265
277
  ## Amendment 2026-05-13 — Augment global-only
266
278
 
267
279
  **Status:** Accepted · 2026-05-13 · signed off by Matze.
@@ -195,6 +195,30 @@ discovery-driven action.
195
195
  - **`requires_hint:` on packs is advisory only.** The runtime does
196
196
  not act on it. Acceptable for v1 per the council's "MEDIUM" note.
197
197
 
198
+ ## Amendments
199
+
200
+ ### 2026-05-21 — Monorepo Phase 1 closure (enforcement live)
201
+
202
+ The five required keys (`workspaces`, `packs`, `lifecycle`, `trust`,
203
+ `install`) are now **strictly enforced** across every artefact under
204
+ `.agent-src.uncompressed/{skills,rules,commands,templates}` by
205
+ [`scripts/lint_artefact_frontmatter.py`](../../scripts/lint_artefact_frontmatter.py),
206
+ wired into `task lint-artefact-frontmatter`, `task ci`, and the opt-in
207
+ combined pre-commit hook (`./agent-config hooks:install`). The migration
208
+ rule's "Phase 4+" strict flip described above is therefore in effect.
209
+
210
+ Worked examples per artefact type live in
211
+ [`docs/contracts/frontmatter-contract.md`](../contracts/frontmatter-contract.md);
212
+ roundtrip stability across the `task sync` pipeline is guarded by
213
+ `tests/test_frontmatter_roundtrip.py`.
214
+
215
+ The Phase-1 roadmap initially proposed splitting the contract into a
216
+ separate `ADR-014-frontmatter-v2-contract.md`. That split was dropped —
217
+ this ADR remains the single source of truth and absorbed the worked
218
+ examples instead. No ADR-014 issued.
219
+
220
+ Driven by [`agents/roadmaps/monorepo-phase-1-frontmatter-metadata.md`](../../agents/roadmaps/monorepo-phase-1-frontmatter-metadata.md).
221
+
198
222
  ## Cross-references
199
223
 
200
224
  - [ADR-007 — Agent Discovery Scopes](ADR-007-agent-discovery-scopes.md):