@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,159 @@
1
+ ---
2
+ adr: 018
3
+ status: accepted
4
+ date: 2026-05-21
5
+ decision: trust-and-safety-layer
6
+ supersedes: —
7
+ superseded_by: —
8
+ phase: v2.x · monorepo-phase-5-trust-safety-layer
9
+ type: prospective
10
+ ---
11
+
12
+ # ADR-018 — Trust & Safety Layer
13
+
14
+ ## Status
15
+
16
+ **Accepted** · 2026-05-21 · external AI Council pass on the Phase 5
17
+ roadmap (`claude-sonnet-4-5` + `gpt-4o`, `design` lens). Council
18
+ confirmed the closed-enum trust ladder, the per-pack safety-floor
19
+ rule, and the compressor-injected HRR banner; refinement folded into
20
+ the lint script and the installer's confirm copy.
21
+
22
+ Session: [`agents/runtime/council/responses/phase-5-trust-safety.json`](../../agents/runtime/council/responses/phase-5-trust-safety.json) <!-- council-ref-allowed: ADR decision-trace -->
23
+
24
+ Companion artefacts:
25
+ - Contract: [`docs/contracts/trust-and-safety.md`](../contracts/trust-and-safety.md)
26
+ - Roadmap: [`agents/roadmaps/monorepo-phase-5-trust-safety-layer.md`](../../agents/roadmaps/monorepo-phase-5-trust-safety-layer.md)
27
+ - Lint: [`scripts/lint_trust_coherence.py`](../../scripts/lint_trust_coherence.py) + [`tests/test_lint_trust_coherence.py`](../../tests/test_lint_trust_coherence.py)
28
+ - Compressor: [`scripts/compress.py`](../../scripts/compress.py) (`_inject_hrr_banner`)
29
+ - Installer: [`packages/core/installer/src/trust-escalation.ts`](../../packages/core/installer/src/trust-escalation.ts)
30
+
31
+ ## Context
32
+
33
+ [`ADR-013`](ADR-013-discovery-frontmatter-contract.md) added the three
34
+ trust fields (`trust.level`, `trust.confidence`,
35
+ `trust.human_review_required`) as the discovery-frontmatter contract
36
+ in Phase 1 of the monorepo migration. Phase 2's discovery manifest
37
+ ([`ADR-015`](ADR-015-discovery-manifest-contract.md)) rolled them up
38
+ into `packs[].trust_summary`. Phases 3 and 4 wired the TypeScript
39
+ installer ([`ADR-016`](ADR-016-installer-architecture.md)) and moved
40
+ sources into `packages/` ([`ADR-017`](ADR-017-monorepo-physical-layout.md)).
41
+
42
+ After Phase 4 we had the **metadata** end-to-end but **no enforcement**:
43
+
44
+ - Installer treated all packs identically — no surface for advisory
45
+ content, no confirm step before opting into legally-flavoured
46
+ finance / strategy material.
47
+ - Compressor preserved frontmatter but did not propagate the
48
+ `human_review_required` signal into the compiled artefact, so the
49
+ runtime had no parser-stable hook to gate output on.
50
+ - Domain-specific safety floors (finance, founder-strategy,
51
+ engineering) existed only as drafts under
52
+ `agents/tmp/refactor-package.txt`; they were not first-class
53
+ artefacts shipped with their packs.
54
+ - No lint existed to catch drift between declared trust level and
55
+ the absence of the matching guardrail rule.
56
+
57
+ The existing universal floors (`non-destructive-by-default`,
58
+ `commit-policy`, `scope-control § git-ops`, `security-sensitive-stop`)
59
+ covered the **action** surface — destruction, push, secrets, prod —
60
+ but said nothing about **output** quality on advisory domains
61
+ (investment calls, valuation verdicts, strategic recommendations).
62
+ Without a Phase 5, a user installing `pack-finance-basic` could
63
+ receive a final "yes, invest" answer with no review banner and no
64
+ sensitivity required.
65
+
66
+ ## Decision
67
+
68
+ Ship a four-piece trust & safety layer:
69
+
70
+ 1. **Closed-enum trust ladder.** `core` · `professional` · `advisory`
71
+ · `restricted` · `experimental`. Authoritative table and meaning
72
+ live in [`trust-and-safety § 1`](../contracts/trust-and-safety.md#-1--trust-levels).
73
+ 2. **HRR banner injection.** The compressor scans frontmatter and
74
+ prepends `<!-- agent-config:human-review-banner -->\n> HUMAN REVIEW
75
+ REQUIRED · trust: <level> · owner: <domain>` to any artefact with
76
+ `trust.human_review_required: true`. Idempotent on re-compression.
77
+ 3. **Per-pack safety-floor rules.** `core` ships
78
+ `engineering-safety-floor.md`; `pack-finance-basic` ships
79
+ `finance-safety-floor.md`; `pack-founder-strategy` ships
80
+ `strategy-safety-floor.md`. Each is itself `advisory` +
81
+ `human_review_required: true`, so it carries the banner and loads
82
+ automatically with the pack.
83
+ 4. **Installer confirm + lockfile escalation.** The pack picker shows
84
+ the trust mix per pack; selecting an advisory/restricted pack
85
+ triggers a confirm prompt (or `--accept-advisory=<pack-id>` in
86
+ non-interactive mode). Accepted trust counts are recorded in
87
+ `.agent-config.lock.json`. Subsequent `sync` runs that find an
88
+ escalation re-confirm before applying.
89
+ 5. **Coherence lint.** `scripts/lint_trust_coherence.py` enforces:
90
+ (a) safety-floor presence per advisory/restricted pack;
91
+ (b) HRR banner presence in compiled output;
92
+ (c) kernel rules declare `trust.level: core`. Wired into
93
+ `ci-fast` and `ci-full`.
94
+
95
+ ## Consequences
96
+
97
+ ### Good
98
+
99
+ - **Single source of trust truth.** The frontmatter field is the
100
+ one input; the installer, compressor, lint, and runtime all read
101
+ it. No parallel registry, no duplicated copy.
102
+ - **Banner is parser-stable.** The HTML-comment marker survives every
103
+ downstream surface (Augment, Claude, Cursor, Windsurf) because it is
104
+ Markdown comment syntax, not prose. Runtime detection greps the
105
+ marker, never the human-readable line.
106
+ - **Coherence is enforceable in CI.** A pack that ships advisory
107
+ content without its safety-floor rule fails the build. A kernel
108
+ rule downgraded to advisory fails the build. A
109
+ `human_review_required` artefact whose compiled output drifted
110
+ fails the build.
111
+ - **Lockfile catches drift across releases.** An upgrade that
112
+ escalates a previously-`professional` artefact to `advisory`
113
+ re-confirms with the user instead of silently applying.
114
+
115
+ ### Trade-offs
116
+
117
+ - **One more lint** (~200 LOC + 7 tests) added to `ci-fast`. Live
118
+ manifest run is sub-second; budget impact negligible.
119
+ - **Closed enum** means new trust levels (e.g. a future `regulated`)
120
+ require a follow-on ADR. Accepted as the price for stable lint
121
+ invariants.
122
+ - **Banner is visible in compiled output**, so users browsing
123
+ `.agent-src/` will see "HUMAN REVIEW REQUIRED" on advisory rules.
124
+ Treated as a feature, not a leak: the banner is the gate.
125
+
126
+ ### Rejected alternatives
127
+
128
+ - **Per-user permission system.** Considered and rejected: trust is a
129
+ property of artefacts, not users. The installer's once-per-install
130
+ confirm is the gate; a runtime per-action authorisation would
131
+ duplicate the universal floors (`non-destructive-by-default` etc.)
132
+ without adding signal.
133
+ - **Re-declaring the Iron-Law floors here.** The four floors stay
134
+ where they live (`kernel-membership`, `safety-model`); this ADR
135
+ references them, never restates them. Avoids contradictory edits.
136
+ - **Open-ended trust enum.** A free-form string would let packs invent
137
+ their own levels and bypass the lint. Closed enum keeps the
138
+ contract enforceable.
139
+
140
+ ## Open questions
141
+
142
+ - A future `regulated` level for healthcare / regulated-finance content
143
+ is anticipated but not in scope; will follow `pack-healthcare` or
144
+ similar.
145
+ - Per-artefact `owner` field is currently derived (first pack id).
146
+ Future ADR may promote `trust.owner` to an explicit frontmatter
147
+ key when more than one pack ships the same artefact under different
148
+ ownership stories.
149
+
150
+ ## References
151
+
152
+ - Contract: [`docs/contracts/trust-and-safety.md`](../contracts/trust-and-safety.md)
153
+ - Roadmap: [`agents/roadmaps/monorepo-phase-5-trust-safety-layer.md`](../../agents/roadmaps/monorepo-phase-5-trust-safety-layer.md)
154
+ - Predecessors: [`ADR-013`](ADR-013-discovery-frontmatter-contract.md)
155
+ · [`ADR-015`](ADR-015-discovery-manifest-contract.md)
156
+ · [`ADR-016`](ADR-016-installer-architecture.md)
157
+ · [`ADR-017`](ADR-017-monorepo-physical-layout.md)
158
+ - Sibling: [`safety-model`](../contracts/safety-model.md) ·
159
+ [`kernel-membership`](../contracts/kernel-membership.md)
@@ -0,0 +1,124 @@
1
+ ---
2
+ adr: 019
3
+ status: accepted
4
+ date: 2026-05-23
5
+ decision: router-json-dist-location
6
+ supersedes: —
7
+ superseded_by: —
8
+ phase: v2.x · post-monorepo cleanup
9
+ type: retrospective
10
+ ---
11
+
12
+ # ADR-019 — `router.json` relocated to `dist/router.json`
13
+
14
+ ## Status
15
+
16
+ **Accepted** · 2026-05-23. Moves the compiled router-kernel artefact
17
+ from the repo root to `dist/router.json`, aligning it with the
18
+ existing `dist/discovery/` build-artefact slot established by
19
+ ADR-015.
20
+
21
+ Companion artefacts:
22
+ - Contract: [`docs/contracts/rule-router.md`](../contracts/rule-router.md)
23
+ - Compiler: [`scripts/compile_router.py`](../../scripts/compile_router.py)
24
+ - ADR-rule-kernel-and-router: [`ADR-rule-kernel-and-router.md`](ADR-rule-kernel-and-router.md)
25
+ - Tier ADR: [`docs/adrs/router/0001-three-tier-routing.md`](../adrs/router/0001-three-tier-routing.md)
26
+
27
+ ## Context
28
+
29
+ `router.json` was emitted at the repo root by the original
30
+ kernel-and-router shipping (ADR-rule-kernel-and-router, P3.2). The
31
+ root location pre-dated the `dist/` convention; once
32
+ ADR-015 codified `dist/discovery/` as the build-artefact slot and
33
+ ADR-012 introduced `dist/cli/` for the TS shell, the router
34
+ artefact's root location became the outlier — visually equivalent
35
+ to hand-edited project files like `AGENTS.md` or
36
+ `.agent-settings.yml`, even though it is regenerated from rule
37
+ frontmatter on every `task compile-router` / `task sync` run.
38
+
39
+ The artefact is still a **public contract**: external host agents
40
+ (Claude.ai bundle, Skills API per
41
+ [`package-self-orientation`](../contracts/package-self-orientation.md))
42
+ read it once per session to resolve the always-loaded kernel and the
43
+ tier-1/2 routing tables. Moving it is therefore a one-time breaking
44
+ change for consumers — they update the read path or fail to resolve
45
+ rules at session start.
46
+
47
+ ## Decision
48
+
49
+ **Compile to `dist/router.json` and ship the file tracked in git
50
+ under a `!/dist/router.json` allowlist exception.** `dist/` remains
51
+ gitignored; only the router artefact is committed.
52
+
53
+ Rationale:
54
+
55
+ 1. **Slot consistency.** Build outputs live under `dist/`. Two
56
+ pre-existing slots (`dist/discovery/`, `dist/cli/`) already
57
+ commit selected artefacts via `.gitignore` allowlists. The
58
+ router follows the same pattern.
59
+ 2. **Thin-Root contract.** `AGENTS.md` and the repo root are
60
+ pointer-heavy and human-curated; generated artefacts at the root
61
+ create review noise on every regen.
62
+ 3. **Single read path.** Host agents already read
63
+ `dist/discovery/discovery-manifest.json`; adding the router to
64
+ the same parent dir collapses the "where does the package emit
65
+ its public contracts" answer to a single directory.
66
+
67
+ ## Trade-offs accepted
68
+
69
+ - **Breaking change for consumers.** Pinned external readers (the
70
+ Claude.ai bundle, any Skills API caller, third-party tooling
71
+ reading the kernel) must update their read path from
72
+ `<root>/router.json` to `<root>/dist/router.json`. No deprecation
73
+ shim — the path is in the artefact body for one
74
+ release window, surfaced via the changelog, and that is the
75
+ contract update.
76
+ - **Allowlist drift risk.** A future `dist/` purge that forgets the
77
+ `!/dist/router.json` line will silently regress the public
78
+ contract. The `task release-prepare` and `task ci` runs both call
79
+ `compile_router.py`, which re-creates the file before any
80
+ packaging step that would notice its absence.
81
+
82
+ ## Implementation footprint
83
+
84
+ - **Compiler / CLI.** `scripts/compile_router.py`,
85
+ `scripts/lint_trust_coherence.py`, `scripts/_cli/cmd_explain.py`,
86
+ `scripts/_cli/explain_last/route.py` — output path constants
87
+ point at `dist/router.json`.
88
+ - **Smoke.** `scripts/smoke/kernel.sh`, `scripts/smoke/router.sh`
89
+ read from the new path; `.github/workflows/smoke.yml` path-trigger
90
+ globs updated via `docs/contracts/smoke-contracts.md`.
91
+ - **Tests.** `tests/test_lint_trust_coherence.py`,
92
+ `tests/test_cmd_explain.py`, `tests/cli/explain_last/conftest.py`
93
+ patch the new constants; `tests/test_one_liner_entrypoints.sh`
94
+ stages `dist/router.json` (not the whole `dist/`, to avoid pulling
95
+ in the TS-compiled CLI which needs `node_modules`).
96
+ - **`.gitignore`.** `/dist/` stays ignored; `!/dist/router.json`
97
+ allowlist exception added.
98
+ - **Docs.** `AGENTS.md`, `docs/architecture.md`,
99
+ `docs/customization.md`, `docs/contracts/{rule-router,
100
+ namespace, trust-and-safety, smoke-contracts, kernel-membership}.md`,
101
+ `docs/contracts/explain-trace.schema.json`,
102
+ `docs/adrs/router/0001-three-tier-routing.md`,
103
+ `docs/adrs/smoke/0001-per-tier-smoke-scripts.md`.
104
+ - **Source rules.** Uncompressed rule sources referencing the path
105
+ (`caveman-speak.md`, `git-history-discipline.md`) updated and
106
+ re-projected.
107
+
108
+ ## Reversal cost
109
+
110
+ Two-edit revert: move the file back, flip the constants, drop the
111
+ allowlist line. `git mv` history is preserved through the rename,
112
+ so a `git revert` of the commit suffices. The contract update would
113
+ be a second breaking change for any consumer that adopted the new
114
+ path — so reversal is **possible but expensive after first
115
+ external uptake**.
116
+
117
+ ## References
118
+
119
+ - [`docs/contracts/rule-router.md`](../contracts/rule-router.md) — frontmatter + read-path contract.
120
+ - [`docs/contracts/kernel-membership.md`](../contracts/kernel-membership.md) — kernel cap.
121
+ - [`dist/router.json`](../../dist/router.json) — compiled output.
122
+ - [`scripts/compile_router.py`](../../scripts/compile_router.py) — compiler.
123
+ - [`ADR-015-discovery-manifest-contract.md`](ADR-015-discovery-manifest-contract.md) — precedent for `dist/` allowlist.
124
+ - [`ADR-rule-kernel-and-router.md`](ADR-rule-kernel-and-router.md) — original kernel-and-router decision.
@@ -0,0 +1,123 @@
1
+ ---
2
+ adr: 020
3
+ status: accepted
4
+ date: 2026-05-23
5
+ decision: global-only-consumer-scope
6
+ supersedes: —
7
+ superseded_by: —
8
+ phase: v3.x · global-only install rollout
9
+ type: forward-looking
10
+ ---
11
+
12
+ # ADR-020 — Global-only consumer scope
13
+
14
+ ## Status
15
+
16
+ **Accepted** · 2026-05-23. Phases 1-5 of
17
+ `road-to-global-only-install` shipped (Setup-Wizard, consumer scope
18
+ gate, surface + bridge, migration tooling). Phase 6 (docs sweep)
19
+ in progress. The ADR locks the decision; the roadmap locks the
20
+ mechanics.
21
+
22
+ Companion artefacts:
23
+ - Roadmap: [`agents/roadmaps/road-to-global-only-install.md`](../../agents/roadmaps/road-to-global-only-install.md)
24
+ - Bridge contract: [`docs/contracts/consumer-bridge.md`](../contracts/consumer-bridge.md)
25
+ - Wizard contract: [`docs/contracts/gui-wizard.md`](../contracts/gui-wizard.md)
26
+ - Predecessor ADR: [`ADR-007`](ADR-007-agent-discovery-scopes.md) — scope precedence, global-default amendment
27
+ - Perms entry-gate: [`scripts/lint_global_paths.py`](../../scripts/lint_global_paths.py)
28
+ - Payload schema: [`schemas/wizard-apply-payload.schema.json`](../../schemas/wizard-apply-payload.schema.json)
29
+
30
+ ## Context
31
+
32
+ ADR-007 (2025-Q4) established that the agent-config consumer can run
33
+ in two scopes — **project** (`<repo>/.augment/`, `<repo>/.claude/`, …)
34
+ or **global** (`~/.claude/`, `~/.cursor/`, `~/.augment/`, …) — and
35
+ that newly-onboarded consumers default to **global**. Six months of
36
+ field use surfaced three structural problems:
37
+
38
+ 1. **Settings drift.** Per-project `.agent-settings.yml` files
39
+ accumulate stale `personal.*` keys that disagree with the user's
40
+ real preferences. Multi-repo developers ship the wrong
41
+ `personal.autonomy` into PRs.
42
+ 2. **Onboarding fragmentation.** New users land in `wizard.md` from
43
+ one tool, `getting-started-by-role.md` from another, and a
44
+ project-local `.agent-user.md` from a third. Three near-identical
45
+ surfaces, each subtly inconsistent.
46
+ 3. **Update lag.** Consumer projects pin an installer version in
47
+ `package.json`. Skill / rule / command edits ship to the package
48
+ but never reach the consumer until someone manually bumps.
49
+
50
+ The amendment in ADR-007 (2026-05-13) flipped the **default** to
51
+ global for Augment. This ADR finishes the job: the consumer surface
52
+ becomes **global-only** end-to-end. The project tree retains exactly
53
+ one piece of agent state — `agents/overrides/` plus the bridge marker
54
+ documented in [`consumer-bridge`](../contracts/consumer-bridge.md).
55
+
56
+ ## Decision
57
+
58
+ Consumer installations of `@event4u/agent-config` write **only** to
59
+ `~/.event4u/agent-config/` (global root) and `agents/.event4u-bridge.yml`
60
+ (in-repo marker). The Setup-Wizard and the legacy Installer-GUI
61
+ converge on a single `/api/apply` endpoint behind a `schema_version`
62
+ discriminator. Per-tool adapters resolve their rules / skills /
63
+ commands by reading the bridge marker, expanding `global_root`, and
64
+ fanning out from there.
65
+
66
+ The single project-local exception is `agents/overrides/`, which
67
+ remains the canonical place to override or extend a shared skill /
68
+ rule / command per [override-management](../../.agent-src.uncompressed/skills/override-management/SKILL.md).
69
+
70
+ The maintainer-side dev experience is preserved by the
71
+ `AGENT_CONFIG_DEV_MODE=1` environment gate documented in
72
+ [`docs/maintainers/dev-mode.md`](../maintainers/dev-mode.md). With the
73
+ flag set, `scripts/install.py` treats the package repo as both source
74
+ and project surface (Phase 3 contract).
75
+
76
+ ## Alternatives considered
77
+
78
+ - **Status quo (project default + global opt-in).** Keeps the drift
79
+ problem; multi-repo developers continue to ship stale
80
+ `personal.*` keys. Rejected.
81
+ - **Dual-endpoint `/api/apply` (one per payload shape).** Doubles
82
+ the CSRF + idle-timer surface with no observability gain. Rejected;
83
+ see `gui-wizard § D12`.
84
+ - **Per-project bridge YAML pointing to multiple global roots.**
85
+ Enables team-shared globals via NFS but introduces a tenancy model
86
+ the rest of the system is not designed for. Deferred to a future
87
+ ADR; v1 of the bridge marker is single-root.
88
+
89
+ ## Consequences
90
+
91
+ **Positive.**
92
+ - One source of truth for `personal.*`, `agent_council.*`, and `personas:`.
93
+ - New skills / rules / commands reach every consumer the moment they
94
+ install or run `task dev:install-global` — no per-repo bump.
95
+ - The onboarding wizard becomes the only authoring surface for
96
+ `.agent-user.md`. Three duplicate flows collapse into one.
97
+
98
+ **Negative.**
99
+ - Phase 3 SCOPE_SUPPORT flip is breaking for any tool that still
100
+ hard-codes a project-local lookup. Migration order is locked in
101
+ the roadmap (Phase 5) — `agent-config migrate-to-global` runs the
102
+ perms entry-gate, copies, verifies, then deletes the project
103
+ shadow.
104
+ - The bridge marker is a new failure mode: a stale `global_root` on
105
+ disk yields a fail-closed error instead of a silent project-local
106
+ fallback. The trade-off is intentional; silent fallback is what
107
+ produced the drift in the first place.
108
+
109
+ **Operational.**
110
+ - `scripts/lint_global_paths.py` becomes a required precondition for
111
+ `migrate-to-global`. Wrong perms (e.g. `0755` on the global root
112
+ when `0700` is expected) abort the migration before any write.
113
+ - The Augment, Claude, and Cursor adapters get free-form-tested by
114
+ the maintainer dev install every CI run, so a regression in the
115
+ bridge-resolver surfaces immediately instead of at consumer time.
116
+
117
+ ## References
118
+
119
+ - [`ADR-007`](ADR-007-agent-discovery-scopes.md) — discovery scope precedence and the 2026-05-13 global-default amendment.
120
+ - [`ADR-018`](ADR-018-trust-and-safety-layer.md) — trust levels and HRR banner; unchanged by this decision.
121
+ - [`road-to-global-only-install`](../../agents/roadmaps/road-to-global-only-install.md) — phased rollout, cross-phase gates A1-A7.
122
+ - [`consumer-bridge`](../contracts/consumer-bridge.md) — bridge marker schema and reader contract.
123
+ - [`gui-wizard § Apply payload`](../contracts/gui-wizard.md#apply-payload--versioning-handshake-road-to-global-only-install-phase-04--d12) — payload discriminator.
@@ -0,0 +1,153 @@
1
+ ---
2
+ adr: 021
3
+ status: accepted
4
+ date: 2026-05-24
5
+ decision: deployment-shape
6
+ supersedes: —
7
+ superseded_by: —
8
+ phase: v3.x · internal-AI-OS deployment Phase 1
9
+ type: forward-looking
10
+ ---
11
+
12
+ # ADR-021 — Deployment shape (internal AI OS, Phase 1)
13
+
14
+ ## Status
15
+
16
+ **Accepted** · 2026-05-24. Phase 1 of
17
+ [`road-to-internal-ai-os-deployment.md`](../../agents/roadmaps/road-to-internal-ai-os-deployment.md)
18
+ ships the container image + Compose topology + host binding +
19
+ healthcheck. Phases 2–5 (identity, central policy, team context,
20
+ connectors) are tracked but **not yet implemented**; their ADRs
21
+ (022–025) are reserved but unwritten.
22
+
23
+ Companion artefacts:
24
+
25
+ - Roadmap: [`agents/roadmaps/road-to-internal-ai-os-deployment.md`](../../agents/roadmaps/road-to-internal-ai-os-deployment.md)
26
+ - Artefacts: [`packages/core/deploy/`](../../packages/core/deploy/)
27
+ - Env contract: [`docs/deploy/env-vars.md`](../deploy/env-vars.md)
28
+ - Council question (drafted, not invoked — no keys): [`agents/tmp/council-question-deployment-shape.md`](../../agents/tmp/council-question-deployment-shape.md)
29
+ - Predecessor ADR: [`ADR-016`](ADR-016-installer-architecture.md) — installer architecture (agent-mode protocol the GUI server wraps).
30
+
31
+ ## Context
32
+
33
+ For the first two years `@event4u/agent-config` shipped as a
34
+ developer-local tool: `npx @event4u/agent-config init` writes files
35
+ into the consumer repo, the wizard runs on `127.0.0.1`, no state
36
+ persists beyond the lockfile. Field signal (multiple companies asking
37
+ "can we host this for the team?") motivates a second shape: a
38
+ **single deployed instance per organization**, hosting wizard +
39
+ Council + memory for 5–50 engineers behind their SSO.
40
+
41
+ Three structural questions had to settle before code:
42
+
43
+ 1. **Topology** — bare Compose vs Helm vs both.
44
+ 2. **Process shape** — single Node container vs Node + Python sidecar.
45
+ 3. **Boot-time safety** — what happens when the operator inevitably
46
+ flips `127.0.0.1:8787` to `0.0.0.0:8787` before authentication
47
+ lands in Phase 2.
48
+
49
+ ## Decision
50
+
51
+ ### 1. Topology — Compose-first, Helm deferred
52
+
53
+ A single `docker-compose.yml` under `packages/core/deploy/` is the
54
+ shipped artefact. Three services: `agent-config` (the Node image),
55
+ `redis`, `postgres`. Three named volumes for runtime state, Postgres
56
+ data, and the per-user `~/.event4u/agent-config/` mount.
57
+
58
+ Helm / k8s manifests are **deferred** to a future v2 deployment
59
+ roadmap. Compose covers the 5–50-person band; larger teams author
60
+ their own chart using this Compose as the reference until v2 ships.
61
+
62
+ ### 2. Process shape — single-process Node
63
+
64
+ The GUI server (`packages/core/installer/src/gui/server.ts`) is the
65
+ only long-running process. The Python install supervisor is spawned
66
+ per-install, not a sidecar. The Compose image stays Node-only to keep
67
+ the budget under 600 MB compressed and the surface area minimal.
68
+
69
+ If Phase 2+ needs a separate identity-broker process, it lands in a
70
+ separate service in the same Compose; the agent-config container stays
71
+ single-process.
72
+
73
+ ### 3. Host binding — `127.0.0.1` default, `0.0.0.0` opt-in with safety gate
74
+
75
+ `startGuiServer` accepts `host` + `allowedHosts` options. CLI
76
+ exposes `--host` and `--allowed-hosts`; container defaults
77
+ `BIND_HOST=0.0.0.0` + `ALLOWED_HOSTS=localhost:8787,127.0.0.1:8787`.
78
+
79
+ **Hard rule**: non-loopback bind without `allowedHosts` refuses to
80
+ boot. Enforced at the CLI surface (`commands/gui.ts`) and at the
81
+ server entry (`gui/server.ts`). This is the structural mitigation
82
+ against operators flipping the host port mapping before Phase 2 SSO
83
+ ships.
84
+
85
+ ### 4. Health endpoint — `/api/v1/health`, read-only, rate-limited
86
+
87
+ CSRF-exempt, GET-only. Returns `status`, `version`, `pack_version`,
88
+ `uptime_seconds`, `storage_mode`, `session_backend`, and
89
+ `manifest_sha256`. No secrets, no auth state, no PII.
90
+
91
+ Rate-limited to 1 request per second per remote IP via an in-memory
92
+ token bucket. Wide margin over the docker-default 10 s healthcheck
93
+ cadence; resilient to spoofed probes (the bucket map is bounded at
94
+ 1024 entries and self-prunes).
95
+
96
+ ### 5. Redis + Postgres in compose but unwired in Phase 1
97
+
98
+ Both services ship in the Compose topology with healthchecks and named
99
+ volumes, but the agent-config code does **not** read them in Phase 1:
100
+
101
+ - `STORAGE_MODE=postgres` is documented but the implementation still
102
+ uses filesystem.
103
+ - `SESSION_BACKEND=redis` is documented but the implementation still
104
+ uses in-memory state.
105
+
106
+ Surfacing both connection strings in `/api/v1/health` lets operators
107
+ verify connectivity *before* Phase 2 wires Postgres and Phase 3 wires
108
+ Redis.
109
+
110
+ ### 6. No TLS in the container
111
+
112
+ The reverse-proxy (nginx / Caddy / Traefik / ALB) owns TLS
113
+ termination. The container speaks plain HTTP on the bound interface.
114
+ Out-of-scope for this ADR; documented in `packages/core/deploy/README.md`.
115
+
116
+ ## Consequences
117
+
118
+ **Positive**
119
+
120
+ - Operators can `docker compose up` and reach a working wizard
121
+ without writing infrastructure.
122
+ - The shape locks before Phases 2–5 add auth / policy / connectors —
123
+ those phases extend the topology without rewriting it.
124
+ - `ALLOWED_HOSTS` gate eliminates the DNS-rebinding class of
125
+ vulnerability at the boot layer.
126
+
127
+ **Negative**
128
+
129
+ - Teams already on k8s need to translate Compose to their own
130
+ charts. Mitigated by the README pointing at the Compose as the
131
+ reference.
132
+ - Postgres + Redis run unused in Phase 1, adding 60–80 MB RAM idle
133
+ to the deployment footprint. Mitigated by being able to remove
134
+ both services from the Compose if Phase 1 is the only phase the
135
+ operator wants.
136
+
137
+ **Reversal cost** — low. Compose → Helm migration is mechanical once
138
+ the v2 deployment roadmap kicks off; the agent-config image itself is
139
+ orchestrator-agnostic.
140
+
141
+ ## Open questions (council-deferred)
142
+
143
+ The accompanying council question file
144
+ [`agents/tmp/council-question-deployment-shape.md`](../../agents/tmp/council-question-deployment-shape.md)
145
+ has not yet been run (no provider keys configured). A maintainer with
146
+ keys should run it and either ratify or supersede this ADR.
147
+
148
+ ## Cross-references
149
+
150
+ - Phase 1 artefacts: [`packages/core/deploy/`](../../packages/core/deploy/)
151
+ - Env contract: [`docs/deploy/env-vars.md`](../deploy/env-vars.md)
152
+ - Installer architecture: [`ADR-016`](ADR-016-installer-architecture.md)
153
+ - Global-only consumer scope: [`ADR-020`](ADR-020-global-only-consumer-scope.md) (orthogonal — local install model)
@@ -18,6 +18,13 @@ _Auto-generated by `scripts/adr/regenerate_index.py`. Do not edit._
18
18
  | [ADR-012](ADR-012-typescript-cli-shell.md) | Typescript Cli Shell | accepted | 2026-05-19 | — |
19
19
  | [ADR-013](ADR-013-discovery-frontmatter-contract.md) | Discovery Frontmatter Contract | accepted | 2026-05-19 | — |
20
20
  | [ADR-014](ADR-014-gui-framework-choice.md) | Gui Framework Choice | accepted | 2026-05-20 | — |
21
+ | [ADR-015](ADR-015-discovery-manifest-contract.md) | Discovery Manifest Contract | accepted | 2026-05-21 | — |
22
+ | [ADR-016](ADR-016-installer-architecture.md) | Installer Architecture | accepted | 2026-05-21 | — |
23
+ | [ADR-017](ADR-017-monorepo-physical-layout.md) | Monorepo Physical Layout | accepted | 2026-05-21 | — |
24
+ | [ADR-018](ADR-018-trust-and-safety-layer.md) | Trust And Safety Layer | accepted | 2026-05-21 | — |
25
+ | [ADR-019](ADR-019-router-json-dist-location.md) | Router Json Dist Location | accepted | 2026-05-23 | — |
26
+ | [ADR-020](ADR-020-global-only-consumer-scope.md) | Global Only Consumer Scope | accepted | 2026-05-23 | — |
27
+ | [ADR-021](ADR-021-deployment-shape.md) | Deployment Shape | accepted | 2026-05-24 | — |
21
28
 
22
29
  ## Unnumbered (legacy)
23
30