@event4u/agent-config 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.agent-src/commands/fix/{pr-bots.md → pr-bot-comments.md} +3 -3
  2. package/.agent-src/commands/fix/{pr.md → pr-comments.md} +6 -6
  3. package/.agent-src/commands/fix/{pr-developers.md → pr-developer-comments.md} +3 -3
  4. package/.agent-src/commands/fix.md +6 -6
  5. package/.agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +2 -2
  6. package/.agent-src/rules/no-cheap-questions.md +11 -2
  7. package/.agent-src/skills/readme-writing-package/SKILL.md +24 -0
  8. package/.claude-plugin/marketplace.json +4 -4
  9. package/CHANGELOG.md +79 -0
  10. package/README.md +76 -12
  11. package/docs/architecture.md +2 -2
  12. package/docs/catalog.md +3 -3
  13. package/docs/contracts/command-clusters.md +3 -3
  14. package/docs/contracts/file-ownership-matrix.json +9 -9
  15. package/docs/contracts/tier-3-contrib-plugin.md +129 -0
  16. package/docs/decisions/ADR-007-agent-discovery-scopes.md +278 -0
  17. package/docs/decisions/ADR-008-installed-tools-manifest.md +160 -0
  18. package/docs/decisions/INDEX.md +2 -0
  19. package/docs/getting-started.md +16 -25
  20. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +32 -0
  21. package/docs/guidelines/agent-infra/installed-tools-manifest.md +135 -0
  22. package/docs/installation.md +116 -49
  23. package/docs/migrations/commands-1.15.0.md +3 -3
  24. package/docs/setup/per-ide/claude-desktop.md +8 -4
  25. package/docs/skills-catalog.md +23 -2
  26. package/docs/troubleshooting.md +20 -32
  27. package/llms.txt +22 -1
  28. package/package.json +1 -1
  29. package/scripts/_cli/cmd_export.py +157 -0
  30. package/scripts/_cli/cmd_sync.py +162 -0
  31. package/scripts/_cli/cmd_update.py +23 -1
  32. package/scripts/_cli/cmd_validate.py +164 -0
  33. package/scripts/_lib/installed_lock.py +160 -0
  34. package/scripts/_lib/installed_tools.py +237 -0
  35. package/scripts/agent-config +62 -0
  36. package/scripts/install +68 -13
  37. package/scripts/install.py +984 -33
  38. package/scripts/install.sh +6 -11
  39. package/templates/agent-config-wrapper.sh +40 -25
  40. package/templates/consumer-settings/README.md +2 -2
  41. package/scripts/setup.sh +0 -230
@@ -0,0 +1,129 @@
1
+ ---
2
+ stability: beta
3
+ ---
4
+
5
+ # Tier-3 contrib plugin pattern
6
+
7
+ **Purpose.** Document the deferred-implementation contract for
8
+ **Tier-3 community AIs** — surfaces that have been named in scoping
9
+ discussions or council rounds but have **not yet been requested by
10
+ a real user**. Tier-3 ships when the first user request lands, not
11
+ on speculation.
12
+
13
+ **Scope.** Defines the candidate list, the manifest shape, the
14
+ promotion path from Tier-3 → Tier-2, and the non-implementation
15
+ guarantee. Does **not** ship code: `agents/manifests/contrib/` is
16
+ unmanifested until a user asks for an entry by name.
17
+
18
+ Last refreshed: 2026-05-12.
19
+
20
+ ## Tier definitions
21
+
22
+ | Tier | Status | Trigger | Implementation |
23
+ |---|---|---|---|
24
+ | **Tier-1** | Shipped | First-class surfaces with daily users | Imperative bridge in `scripts/install.py` |
25
+ | **Tier-2** | Shipped | Named in roadmaps + has plausible audience | Imperative bridge, same pattern as Tier-1 |
26
+ | **Tier-3** | **Deferred** | Named in scoping/council but zero user demand | Manifest YAML in `agents/manifests/contrib/` (not yet implemented) |
27
+
28
+ Phase 2.1 + 2.2 of
29
+ [`road-to-global-first-install`](../../agents/roadmaps/road-to-global-first-install.md)
30
+ closed Tier-1 and Tier-2 at **16 AIs**. Tier-3 is the explicit
31
+ overflow bucket.
32
+
33
+ ## Candidate list (frozen at proposal time)
34
+
35
+ The following surfaces are Tier-3 candidates as of 2026-05-12. They
36
+ were surfaced during the
37
+ [`2026-05-12-installer-expansion`](../../agents/council-sessions/2026-05-12-installer-expansion/synthesis.md)
38
+ council round and have **no entries** in `_VALID_TOOLS`,
39
+ `USER_SCOPE_PATHS`, `SCOPE_SUPPORT`, or the bash `VALID_TOOLS` set.
40
+
41
+ - `qoder` — community fork, no public adoption signal
42
+ - `trae` — ByteDance IDE, behind login wall
43
+ - `opencode` — bundled into VS Code variants; coverage already via `vscode`
44
+ - `codebuddy` — Tencent-internal, no public install path
45
+ - `droid` — proposed CLI agent, alpha
46
+ - `warp` — terminal-with-AI; integration shape unclear (PTY vs file marker)
47
+ - `antigravity` — Google research project, no shipping surface
48
+
49
+ Inclusion in this list is **not** a commitment to ship. Promotion
50
+ requires a real user asking by name (issue, PR, council session, or
51
+ recorded ask).
52
+
53
+ ## Manifest shape (when implemented)
54
+
55
+ When the first user request lands, the responder MUST:
56
+
57
+ 1. Create `agents/manifests/contrib/<tool-id>.yml` matching the
58
+ schema below.
59
+ 2. Add the tool ID to `_VALID_TOOLS`, `USER_SCOPE_PATHS`,
60
+ `SCOPE_SUPPORT`, and the bash `VALID_TOOLS` set.
61
+ 3. Implement `ensure_<tool>_bridge` in `scripts/install.py` (≤60 LOC
62
+ — if larger, escalate via ADR per Phase 2.5 gate).
63
+ 4. Append a row to the `README.md` "Supported Tools" table.
64
+ 5. Re-run `task lint-skills` + `python3 -m pytest tests/test_install_py.py`.
65
+
66
+ ```yaml
67
+ # agents/manifests/contrib/<tool-id>.yml
68
+ tool_id: <slug> # lowercase, hyphen-separated
69
+ display_name: <Pretty> # for README + CLI catalog
70
+ scope: project | global | both
71
+ discovery: marker | hook | config-merge
72
+ marker_path: <relative> # e.g. .tool-id/agent-config.md
73
+ requested_by: <ref> # GitHub issue, PR, council session, etc.
74
+ requested_date: YYYY-MM-DD
75
+ notes: |
76
+ Short rationale, integration shape, known limitations.
77
+ ```
78
+
79
+ ## Non-implementation guarantee
80
+
81
+ `agents/manifests/contrib/` does **not** exist until needed. CI does
82
+ not enforce its presence. The pattern is documented, not scaffolded.
83
+
84
+ This prevents two failure modes:
85
+
86
+ 1. **Empty-shell drift** — a directory of YAML stubs with no
87
+ corresponding code, where the manifest claims support but the
88
+ installer silently no-ops.
89
+ 2. **Speculative breadth** — adding 7 IDs to `_VALID_TOOLS` "in
90
+ case" a user asks, then carrying maintenance cost on dead code.
91
+
92
+ ## Promotion path
93
+
94
+ Tier-3 → Tier-2 promotion happens in a single PR:
95
+
96
+ 1. The first user request anchors the PR (link in commit body).
97
+ 2. Manifest YAML lands alongside the bridge.
98
+ 3. README + roadmap update in the same commit.
99
+ 4. After two reported successful installs (or one release cycle of
100
+ no bug reports), the tool moves out of `contrib/` and the manifest
101
+ YAML is deleted — the bridge stands on its own under the Tier-2
102
+ contract.
103
+
104
+ There is no Tier-3 → Tier-3 churn: a candidate either gets
105
+ requested and promoted, or stays unimplemented indefinitely. We do
106
+ not "preemptively scaffold" Tier-3 entries.
107
+
108
+ ## Out of scope
109
+
110
+ - **Capability matrices** — the manifest does not describe what the
111
+ tool _can_ do, only what the installer must emit. Capability docs
112
+ live in the consumer tool's own documentation.
113
+ - **Auto-discovery** — there is no plugin loader. The installer is
114
+ imperative (see Phase 2.5 gate); manifests are a documentation
115
+ contract, not a runtime input.
116
+ - **Third-party contribution channel** — this contract governs the
117
+ package maintainer's response to user requests, not a community
118
+ plugin marketplace. External plugins would require ADR-009+ to
119
+ introduce a stable extension surface.
120
+
121
+ ## Cross-references
122
+
123
+ - [`ADR-007`](../decisions/ADR-007-agent-discovery-scopes.md) —
124
+ project / global / both scope taxonomy that Tier-3 entries inherit.
125
+ - [`ADR-008`](../decisions/ADR-008-installed-tools-manifest.md) —
126
+ `agents/installed-tools.lock` for per-project state, distinct
127
+ from this maintainer-side contract.
128
+ - [`road-to-global-first-install`](../../agents/roadmaps/road-to-global-first-install.md)
129
+ Phase 2.6 — completion trigger for this contract.
@@ -0,0 +1,278 @@
1
+ ---
2
+ adr: 007
3
+ status: accepted
4
+ date: 2026-05-12
5
+ decision: global-default-install-with-export-subcommand
6
+ supersedes: —
7
+ superseded_by: —
8
+ phase: post-v2.1.0 · simplicity-and-everywhere
9
+ ---
10
+
11
+ # ADR-007 — Agent Discovery Scopes: Global-Default Install Model
12
+
13
+ ## Status
14
+
15
+ **Accepted** · 2026-05-12 · signed off by Matze after Council Round 3 convergence. Implementation tracked in `agents/roadmaps/road-to-global-first-install.md`.
16
+
17
+ Originates from user ask: "Es macht keinen Sinn, das paket nicht
18
+ global zu installieren." Validated through AI Council (2 + 1 rounds,
19
+ 2026-05-12 · members claude-sonnet-4-5 + gpt-4o). Council session:
20
+ [`agents/council-sessions/2026-05-12-global-first-strategy/`](../../agents/council-sessions/2026-05-12-global-first-strategy/). <!-- council-ref-allowed: ADR decision trace -->
21
+
22
+ ## Context
23
+
24
+ `event4u/agent-config` v2.1.0 ships strictly via
25
+ `npx @event4u/create-agent-config init`, project-scoped. The package
26
+ must serve **10 distinct AI agents**, each with its own discovery
27
+ rules — both user-scope (global) and project-scope (workspace) paths.
28
+ Today the CLI only installs project-locally; a `global` subcommand
29
+ in `scripts/agent-config` returns "reserved for Phase 3 of
30
+ road-to-simplicity-and-everywhere".
31
+
32
+ The user wants global to be the **default** path, not a special case.
33
+ Before flipping the default, we needed to answer four blocking
34
+ questions: (1) is global-default sound across all 10 agents? (2) how
35
+ do we detect user intent? (3) how do we handle tools that
36
+ project-scope wins? (4) how do we preserve version reproducibility
37
+ once `npx` resolves global state?
38
+
39
+ ### Relationship to the retired `--global` (commit `5388de25`)
40
+
41
+ A previous `--global` flag existed in `scripts/install.py` and was
42
+ **retired** on 2026-05-12 alongside the composer/npm drop
43
+ (`road-to-portable-runtime-and-update-check` step P0.5,
44
+ [archived roadmap](../../agents/roadmaps/archive/road-to-portable-runtime-and-update-check.md)).
45
+ The retired design was an **in-project symlink scheme** driven by
46
+ `templates/global-install-manifest.yml` — it wrote symlinks *into the
47
+ project* pointing back at a curated set in the user's home. Pain that
48
+ killed it: gitignore drift, link breakage on rebase / worktree, and a
49
+ manifest separate from the main install set that drifted out of sync.
50
+
51
+ ADR-007's `--global` is a **different mechanism with the same flag
52
+ name**:
53
+
54
+ | Dimension | Retired `--global` (pre `5388de25`) | ADR-007 `--global` (this decision) |
55
+ |---|---|---|
56
+ | Files live in | Project repo (`.claude/`, …) as symlinks | User home (`~/.claude/`, …) as **real files** |
57
+ | Manifest | Separate curated `global-install-manifest.yml` | Same full set as project install (D4) |
58
+ | Project-side artefacts | Symlinks, gitignored | None by default; opt-in via `export` (D3) |
59
+ | Version-pin governance | None — drift via symlink target swap | `~/.config/agent-config/installed.lock` (D5) |
60
+ | In-project gitignore footprint | Required and brittle | Zero |
61
+
62
+ The retired pain is structurally absent from the new design: no
63
+ in-project symlinks, no manifest split, an explicit version lockfile.
64
+ The flag name is reused; the implementation is rebuilt.
65
+
66
+ ### Verified per-agent discovery matrix (May 2026)
67
+
68
+ | Agent | User-scope (global) | Project-scope | Precedence |
69
+ |---|---|---|---|
70
+ | Claude Code | `~/.claude/{skills,commands,rules,settings.json}` + `~/.claude/CLAUDE.md` | `.claude/…` + `CLAUDE.md` | managed > user > project (skills) |
71
+ | Claude Desktop | `~/.claude/` (shared) | — | user only |
72
+ | Cursor | User Rules (app settings) + `~/.cursor/` (MCP) | `.cursor/rules/*.mdc` | team > user > project |
73
+ | Windsurf | `~/.codeium/windsurf/global_rules.md` + `…/global_workflows/` | `.windsurfrules` + `.windsurf/{rules,workflows}/` | **workspace > global** |
74
+ | Cline | `~/Documents/Cline/Rules/` | `.clinerules` (file or dir) | **workspace > global** |
75
+ | Augment Code | `~/.augment/{rules,commands}/` | `.augment/{rules,commands}` + `.augment-guidelines` + `AGENTS.md` | workspace > user (cmds); user always-on (rules) |
76
+ | GitHub Copilot | `~/.copilot/copilot-instructions.md` (CLI) + Personal Instructions (settings) | `.github/copilot-instructions.md` + `.github/instructions/*` | personal > repo > org |
77
+ | Gemini CLI | `~/.gemini/GEMINI.md` + `~/.gemini/settings.json` | `GEMINI.md` (hierarchical) + `.gemini/settings.json` | **project > user > system** |
78
+ | Aider | `~/.aider.conf.yml` + `~/.aider.conventions.md` | `.aider.conf.yml` (git root) + `CONVENTIONS.md` | last loaded wins |
79
+ | OpenAI Codex | `~/.codex/AGENTS.md` (+ override) + `$HOME/.agents/skills` | `AGENTS.md` (repo + nested) + `.agents/skills` + `.codex/config.toml` | closer-to-cwd wins |
80
+
81
+ **Finding:** every supported agent has a user-scope path. Global
82
+ install is technically viable across the entire matrix.
83
+
84
+ **Asymmetry that bit the original strategy:** Windsurf and Cline are
85
+ `workspace > global` — a project-local override silently wins. Gemini
86
+ is `project > user > system`. Claude Code is `user > project` for
87
+ skills. A symlink-bridge approach (originally proposed) cannot give a
88
+ consistent cross-tool experience because per-tool precedence rules
89
+ differ.
90
+
91
+ ## Council Process
92
+
93
+ | Round | Members | Cost (actual) | Verdict |
94
+ |---|---|---|---|
95
+ | 1 + 2 (interleaved) | claude-sonnet-4-5 + gpt-4o | $0.0443 | claude: **REJECT** · gpt-4o: **MODIFY** |
96
+ | 3 (targeted resolution) | same | $0.0252 | **3/4 convergence** |
97
+
98
+ Full responses:
99
+ [`responses.json`](../../agents/council-sessions/2026-05-12-global-first-strategy/responses.json), <!-- council-ref-allowed: ADR decision trace -->
100
+ [`responses-round3.json`](../../agents/council-sessions/2026-05-12-global-first-strategy/responses-round3.json). <!-- council-ref-allowed: ADR decision trace -->
101
+
102
+ ## Decision
103
+
104
+ Adopt **Global-Default Install with Export-Subcommand** in five parts.
105
+
106
+ ### D1 — Install scope: global is the default
107
+
108
+ `npx @event4u/create-agent-config init` defaults to **user-scope
109
+ install** (`~/.claude/`, `~/.cursor/`, `~/.codeium/windsurf/`,
110
+ `~/.augment/`, `~/Documents/Cline/Rules/`, `~/.copilot/`, `~/.gemini/`,
111
+ `~/.aider.conventions.md`, `~/.codex/`). Project-scope install is
112
+ **opt-in** via `--project[=<dir>]`. Global is no longer a flag — it
113
+ is the brand promise.
114
+
115
+ Rationale: one npx invocation = configured everywhere. Per-project
116
+ overrides remain available via existing `.agent-settings.yml` merge
117
+ chain (`~/.config/agent-config/agent-settings.yml` → project
118
+ `.agent-settings.yml` → CLI flags).
119
+
120
+ ### D2 — Init UX: prompt only on ambiguity
121
+
122
+ | Signal | Behaviour |
123
+ |---|---|
124
+ | CWD has existing `.agent-settings.yml` | Install **project** (current behaviour preserved) |
125
+ | CWD has `package.json` / `composer.json` / `pyproject.toml` AND existing AI-tool config (`.claude/`, `.cursor/`, etc.) | Prompt: `Project (current dir) / User (~/) / Custom path` |
126
+ | CWD has existing `~/.claude/CLAUDE.md` and command would overwrite | Prompt: `Merge / Backup-and-replace / Abort` — **Hard Floor** |
127
+ | Anything else (incl. CWD = `~/`, empty dir, dotfile-git repos) | Install **global**, no prompt |
128
+
129
+ `.git/` presence is **explicitly not a signal** (monorepos, dotfile
130
+ managers, Hg/SVN workspaces all break it). Replaced by multi-signal
131
+ detection + collision-triggered prompt.
132
+
133
+ ### D3 — Bridge → Export
134
+
135
+ The originally proposed symlink-bridge subcommand is **rejected**.
136
+ Replaced by:
137
+
138
+ ```
139
+ agent-config export --tool=<x> --output=<path> [--force]
140
+ ```
141
+
142
+ Behaviour:
143
+ - Writes a **real file** (no symlink) with the resolved content for
144
+ the named tool, into the user-specified path.
145
+ - Idempotent. `--force` overwrites; default refuses on existing file
146
+ with non-matching content (Hard Floor).
147
+ - User decides path — no canonical defaults baked in (tool-specific
148
+ paths drift upstream).
149
+ - Use cases: committing `.github/copilot-instructions.md` for team
150
+ sharing, versioning `AGENTS.md` or `CLAUDE.md` in repo, exporting
151
+ curated subsets to `docs/ai-context.md`.
152
+
153
+ Rejected: symlink-bridge. Reasons (council-converged):
154
+ - Tool-precedence asymmetry makes symlinks behave differently per
155
+ tool (Windsurf ignores global-bridged file; Claude Code honors it).
156
+ - Symlinks under Git track the pointer path, not content — useless
157
+ on team-mate machines where `~/` differs.
158
+ - Windows symlink privilege (`SeCreateSymbolicLinkPrivilege`) is
159
+ developer-mode / admin-only; corporate Group Policy frequently
160
+ blocks it.
161
+ - EDR tools quarantine symlinks in user-profile config directories
162
+ as "unusual script activity".
163
+
164
+ ### D4 — Manifest: single full set, no curation split
165
+
166
+ Global install ships **all** kernel + tier-1 + tier-2 + skills (same
167
+ manifest as project install). No `templates/global-install-manifest.yml`.
168
+
169
+ Council convergence is **3/4** here — anthropic strongly recommends
170
+ **(a) full** with the argument "10 MB is negligible on any dev
171
+ machine; curated subset creates drift + discovery problems + a second
172
+ command to unblock the rest". OpenAI prefers **(b) curated** but with
173
+ generic rationale.
174
+
175
+ **Residual debate:** the (b) curated camp can still be honored
176
+ post-implementation by adding an `agent-config install --minimal`
177
+ flag without changing the default, if real-world feedback shows the
178
+ full footprint hurts. The decision here is "ship full, narrow later
179
+ if needed" rather than "ship curated, broaden later".
180
+
181
+ ### D5 — Version reproducibility: lockfile
182
+
183
+ ```
184
+ ~/.config/agent-config/installed.lock
185
+ ```
186
+
187
+ Schema:
188
+ ```json
189
+ {
190
+ "version": "2.2.0",
191
+ "installed_at": "2026-05-12T10:30:00Z",
192
+ "tools": ["claude-code", "cursor", "windsurf"]
193
+ }
194
+ ```
195
+
196
+ `init` on existing lock with matching version: **skip**.
197
+ `init` on existing lock with differing version: **fail loud** with
198
+ "Installed: v2.1.0. Current: v2.2.0. Run `agent-config update` or
199
+ `init --force`."
200
+
201
+ `update` is an explicit subcommand. Writes new lock atomically. No
202
+ silent updates ever.
203
+
204
+ ### D6 — Source-repo guard stays
205
+
206
+ `AGENT_CONFIG_ALLOW_SELF_INSTALL=1` requirement when run from inside
207
+ the `agent-config` source repo applies to **both** global and
208
+ project modes (a stray `npx … init` from inside the source tree
209
+ would overwrite the maintainer's `~/.claude/` with package's own
210
+ maintainer manifest).
211
+
212
+ ## Consequences
213
+
214
+ ### Positive
215
+
216
+ - One command, every project: `npx @event4u/create-agent-config init` works
217
+ in `~/`, in a fresh project, in an existing project with no config.
218
+ - Cross-tool consistency: every supported agent gets the same skill /
219
+ rule set from one source of truth in `~/`.
220
+ - No symlink-related fragility (Windows, EDR, Git semantics).
221
+ - Version reproducibility via lockfile is auditable, inspectable, and
222
+ explicit.
223
+
224
+ ### Negative
225
+
226
+ - Behavioural change vs v2.1.0: existing project-installs continue to
227
+ work, but new installs default to a different location. Ships as a
228
+ v2.x release (v2.0.0 was the breaking npx-only cut; subsequent v2.x
229
+ work refines that line — no v3.0.0 planned). Documented migration
230
+ in the release notes is required.
231
+ - Tools with `workspace > global` precedence (Windsurf, Cline,
232
+ Gemini) require user action to bridge: either `agent-config export`
233
+ into the project or `--project` flag at install. Pure global-only
234
+ users on those tools may not see the rules apply inside specific
235
+ repos.
236
+ - A `~/.config/agent-config/installed.lock` introduces a new state
237
+ surface. Uninstall must remove it cleanly; corrupted-lock recovery
238
+ needs documenting.
239
+ - Curation decision is provisional. If `~/.claude/skills/` footprint
240
+ causes complaints, post-launch we may need to add a `--minimal`
241
+ install profile (revisits D4).
242
+
243
+ ### Neutral
244
+
245
+ - The latent `--global` flag in `scripts/install.py` becomes the new
246
+ default codepath — no longer hidden, fully exercised in CI.
247
+ - The `bridge` subcommand reserved for "Phase 3 of
248
+ road-to-simplicity-and-everywhere" is **never built**. Roadmap
249
+ entry should be updated to point at `export` instead.
250
+
251
+ ## Implementation Plan (deferred to roadmap)
252
+
253
+ Out of scope for this ADR. Sequencing target for a separate roadmap:
254
+
255
+ 1. Branch `feat/global-first-install` (requires user permission to
256
+ create — not auto-spawned by this ADR).
257
+ 2. Wire `scripts/install.py --global` through `create-agent-config`
258
+ npx entry + `scripts/agent-config global` subcommand.
259
+ 3. Implement multi-signal detection + collision prompt.
260
+ 4. Implement `agent-config export --tool=<x> --output=<path>`.
261
+ 5. Implement `~/.config/agent-config/installed.lock` + `update`
262
+ subcommand.
263
+ 6. Update `docs/installation.md`, per-IDE setup pages, `README.md`
264
+ tagline.
265
+ 7. Add CI matrix: global-install path on macOS, Linux, Windows
266
+ (lockfile, prompt suppression, Hard Floor enforcement).
267
+ 8. CHANGELOG entry + v2.x migration guide.
268
+
269
+ ## References
270
+
271
+ - Council session:
272
+ [`agents/council-sessions/2026-05-12-global-first-strategy/`](../../agents/council-sessions/2026-05-12-global-first-strategy/) <!-- council-ref-allowed: ADR decision trace -->
273
+ - User-scope discovery matrix sources: agent vendor official docs
274
+ (Claude, Cursor, Windsurf, Cline, Augment, Copilot, Gemini, Aider,
275
+ Codex) accessed 2026-05-12.
276
+ - Prior latent global code: `scripts/install.py` (~280 LOC, never
277
+ reachable from npx entry).
278
+ - Related rule: [`non-destructive-by-default`](../../.augment/rules/non-destructive-by-default.md) — Hard Floor on overwrite of user's existing `~/.claude/CLAUDE.md`.
@@ -0,0 +1,160 @@
1
+ ---
2
+ adr: 008
3
+ status: proposed
4
+ date: 2026-05-12
5
+ decision: committed-installed-tools-manifest-separate-from-settings
6
+ supersedes: —
7
+ superseded_by: —
8
+ phase: v2.x · post-global-first-install
9
+ ---
10
+
11
+ # ADR-008 — Installed-Tools Manifest
12
+
13
+ ## Status
14
+
15
+ **Proposed** · 2026-05-12 · pending implementation in Phase 3 of
16
+ [`road-to-global-first-install`](../../agents/roadmaps/road-to-global-first-install.md).
17
+
18
+ Originates from user ask (Matze, 2026-05-12): "Sollten wir auf
19
+ Projektebene festhalten, welche Agents wir initialisiert haben, damit
20
+ bei jedem Sync das Verzeichnis aktualisiert werden kann?" Validated
21
+ through AI Council Round 1 (claude-sonnet-4-5 + gpt-4o, $0.0298 actual,
22
+ both converged on "yes, separate file"). Council session:
23
+ [`agents/council-sessions/2026-05-12-project-settings-and-v1-v2/`](../../agents/council-sessions/2026-05-12-project-settings-and-v1-v2/). <!-- council-ref-allowed: ADR decision trace -->
24
+
25
+ ## Context
26
+
27
+ After ADR-007 (global-first install), each developer's AI tooling
28
+ lives in user-scope paths (`~/.claude/`, `~/.augment/`, …). A project
29
+ no longer carries the AI config in its tree — except for tools with
30
+ `workspace > global` precedence (Windsurf, Cline, Gemini-when-project-
31
+ wins) that **must** keep a project-local bridge.
32
+
33
+ **Resulting gap:** a project has no committed record of which AI
34
+ tools it expects. A new team member cloning the repo cannot tell
35
+ whether the codebase was built with Claude Code, Windsurf, both, or
36
+ five others. Onboarding is "ask the team lead, hope they remember".
37
+
38
+ **Two related but orthogonal problems:**
39
+
40
+ 1. **Bill of materials** — "Which AIs does this project use?"
41
+ 2. **Settings hierarchy** — "How do agents behave in this project?"
42
+
43
+ Today, `.agent-project-settings.yml` (committed) answers #2 (personas,
44
+ quality tools, locked keys). #1 is unanswered.
45
+
46
+ ### What we considered
47
+
48
+ | Option | Verdict |
49
+ |---|---|
50
+ | **A.** Add `installed_tools` block to `.agent-project-settings.yml` | **Rejected** — mixes behaviour with bill-of-materials, creates a "god file" that every sync command must parse and partially ignore. Settings ≠ manifest. |
51
+ | **B.** Put manifest at root: `.agent-installed-tools.lock` | Rejected — root is already crowded with 10+ AI dotfiles; adding another worsens it. |
52
+ | **C.** Separate manifest at `agents/installed-tools.lock` | **Accepted** — co-located with project-shared agent docs; clear name; clear job. |
53
+ | **D.** Skip — let team docs / README describe the tool set | Rejected — README drifts, no machine-readable contract, no drift detection. |
54
+
55
+ Council (Sonnet): _"Settings (user prefs, locked keys, override paths)
56
+ ≠ Manifest (which tools exist). Mixing them creates a god file."_ Both
57
+ members converged on a separate file; the location split (Sonnet
58
+ favoured `installed-tools.lock`, GPT-4o favoured
59
+ `.project-settings.yml`) resolved in favour of Sonnet on the
60
+ separation-of-concerns argument.
61
+
62
+ ## Decision
63
+
64
+ **Adopt option C.** Ship `agents/installed-tools.lock` as the
65
+ committed, schema-versioned bill-of-materials for AI tooling.
66
+
67
+ ### Schema (v1)
68
+
69
+ ```yaml
70
+ schema_version: 1
71
+ agent_config_version: "2.x.y" # version that wrote the file last
72
+ tools:
73
+ - name: claude-code # matches scripts/install.py _VALID_TOOLS
74
+ scope: global # one of: global, project
75
+ bridge_marker: ~/.claude/PROJECT_MANAGED_BY_AGENT_CONFIG
76
+ installed_at: "2026-05-12"
77
+ - name: windsurf
78
+ scope: project # workspace > global → must live in repo
79
+ bridge_marker: .windsurf/PROJECT_MANAGED_BY_AGENT_CONFIG
80
+ installed_at: "2026-05-12"
81
+ ```
82
+
83
+ **Fields:**
84
+
85
+ - `schema_version` — integer; bump on breaking schema changes.
86
+ - `agent_config_version` — last package version that wrote the file.
87
+ - `tools[]` — append-on-init order; not alphabetised (preserves
88
+ installation history for forensics).
89
+ - `tools[].name` — must match `_VALID_TOOLS` in `scripts/install.py`.
90
+ - `tools[].scope` — `global` (user-home install) or `project`
91
+ (workspace-wins tools that need a local bridge).
92
+ - `tools[].bridge_marker` — path to the marker file the installer
93
+ drops to claim ownership. `validate` checks this file exists.
94
+ - `tools[].installed_at` — ISO date; informational only.
95
+
96
+ ### Lifecycle
97
+
98
+ 1. `init --ai <name>` — adds an entry (idempotent). Existing entry
99
+ for same tool with **same scope** is a no-op. Existing entry with
100
+ **different scope** refuses without `--force` (loud warning:
101
+ "tool X is committed as scope=global; you are about to change it
102
+ to project").
103
+ 2. `sync` — reads the lock file, replays every listed tool's install
104
+ (skip if marker present, install if missing). Used by new team
105
+ members.
106
+ 3. `validate` — read-only drift check. Exit 1 if any listed marker
107
+ is missing or scope mismatches the file system. **No auto-fix.**
108
+ 4. Manual edit — discouraged. Lock file is machine-managed; humans
109
+ edit via CLI subcommands.
110
+
111
+ ### Relationship to `.agent-project-settings.yml`
112
+
113
+ | File | Owner | Scope | Example keys |
114
+ |---|---|---|---|
115
+ | `agents/installed-tools.lock` | this ADR | bill of materials | `tools[]`, `scope`, `bridge_marker` |
116
+ | `.agent-project-settings.yml` | layered-settings system | behaviour | `personas.default`, `quality.php.tools`, `locked_keys` |
117
+
118
+ Both committed, both have a single job, never overlap.
119
+
120
+ ## Consequences
121
+
122
+ ### Positive
123
+
124
+ - Onboarding: `git clone` + `npx @event4u/agent-config sync` brings
125
+ every team member's AI tooling to parity.
126
+ - Drift detection: `validate` catches "team lead added Windsurf but
127
+ forgot to commit the lock-file update".
128
+ - Forensics: install order preserved in `tools[]` order; `installed_at`
129
+ pins approximate timestamps.
130
+ - Separation of concerns: behaviour settings stay clean; manifest
131
+ stays focused.
132
+
133
+ ### Negative
134
+
135
+ - New committed file = one more thing to keep in sync with reality.
136
+ Mitigated by **machine-written-only** rule and `validate` CI hook.
137
+ - Scope migration (tool moves between `global` and `project`) needs
138
+ documented playbook in `installed-tools-manifest.md` (Phase 3.5).
139
+ - Single-developer projects gain little — the manifest is overhead
140
+ until a second developer joins. Mitigation: file is optional;
141
+ commands work without it (empty manifest = empty install).
142
+
143
+ ### Neutral
144
+
145
+ - File lives under `agents/`, not at repo root — consistent with
146
+ Matze's preference and council Sonnet's argument that root is
147
+ already crowded.
148
+
149
+ ## Implementation Plan
150
+
151
+ Tracked as Phase 3 of `road-to-global-first-install` (steps 3.1–3.5).
152
+ Ships in a v2.x minor release **after** Phase 2 lands. Out of scope
153
+ for this ADR.
154
+
155
+ ## References
156
+
157
+ - [`ADR-007`](ADR-007-agent-discovery-scopes.md) — global-first install (this ADR depends on it).
158
+ - [`agents/roadmaps/road-to-global-first-install.md`](../../agents/roadmaps/road-to-global-first-install.md) Phase 3.
159
+ - [`agents/council-sessions/2026-05-12-project-settings-and-v1-v2/`](../../agents/council-sessions/2026-05-12-project-settings-and-v1-v2/) — full council transcripts. <!-- council-ref-allowed: ADR decision trace -->
160
+ - [`docs/guidelines/agent-infra/layered-settings.md`](../guidelines/agent-infra/layered-settings.md) — the existing 4-layer settings precedence; this ADR adds a parallel file outside that hierarchy.
@@ -10,6 +10,8 @@ _Auto-generated by `scripts/adr/regenerate_index.py`. Do not edit._
10
10
  | [ADR-004](ADR-004-rule-governance-pruning.md) | Rule Governance Pruning | accepted | 2026-05-08 | — |
11
11
  | [ADR-005](ADR-005-subagent-worktrees.md) | Subagent Worktrees No Auto Merge | accepted | 2026-05-09 | — |
12
12
  | [ADR-006](ADR-006-skill-tools-python-pilot.md) | Skill Tools Python Pilot Pass | accepted | 2026-05-09 | — |
13
+ | [ADR-007](ADR-007-agent-discovery-scopes.md) | Global Default Install With Export Subcommand | accepted | 2026-05-12 | — |
14
+ | [ADR-008](ADR-008-installed-tools-manifest.md) | Committed Installed Tools Manifest Separate From Settings | proposed | 2026-05-12 | — |
13
15
 
14
16
  ## Unnumbered (legacy)
15
17
 
@@ -1,33 +1,23 @@
1
1
  # Getting Started
2
2
 
3
3
  `agent-config` is a stack-agnostic orchestration contract for coding
4
- agents. The installer detects the project shape (Composer / npm / both /
5
- neither) and wires the matching glue. **Pick the entrypoint that
6
- matches the project**, not the language you happen to prefer.
4
+ agents. Installation is npx-first; the package itself is npm-published
5
+ and works in any project regardless of language.
7
6
 
8
7
  ## Installation
9
8
 
10
- The installer is the same orchestrator across stacks — it reads
11
- `composer.json` and/or `package.json`, syncs the payload, and generates
12
- the tool-specific glue. Pick one entrypoint:
9
+ Pick one entrypoint:
13
10
 
14
11
  ```bash
15
- # Composer-based projects (PHP / Laravel / Symfony / Zend / Laminas)
16
- composer require --dev event4u/agent-config
17
- php vendor/bin/install.php
18
- # Equivalent: bash vendor/event4u/agent-config/scripts/install
19
-
20
- # npm-based projects (Next.js / React / Node / Vue / plain JS/TS)
21
- npm install --save-dev @event4u/agent-config
22
- # Postinstall runs the orchestrator. Re-run or pick a profile:
23
- # bash node_modules/@event4u/agent-config/scripts/install --profile=balanced
24
-
25
- # Mixed Composer + npm projects (Laravel + Inertia, Symfony + Vue, …)
26
- # Run both — the orchestrator merges results, no double-write.
27
-
28
- # Stack-less or polyglot repos (no Composer, no npm)
29
- git clone https://github.com/event4u-app/agent-config /tmp/agent-config
30
- bash /tmp/agent-config/scripts/install --target "$PWD"
12
+ # Recommended one-shot, no local dependency
13
+ npx @event4u/create-agent-config init --tools=claude-code,cursor
14
+
15
+ # No-Node fallback — curl | bash entrypoint (downloads a tarball)
16
+ curl -sSL https://raw.githubusercontent.com/event4u-app/agent-config/main/setup.sh | bash
17
+
18
+ # Global CLI (one install per machine, all projects)
19
+ npm install -g @event4u/agent-config
20
+ agent-config --help
31
21
  ```
32
22
 
33
23
  That's it. Your agent now follows your team's standards. The orchestrator
@@ -49,9 +39,10 @@ so you can run a few package scripts without installing `go-task`,
49
39
  ./agent-config help # full command list
50
40
  ```
51
41
 
52
- The wrapper is regenerated on every `npm install` / `composer install`
53
- and delegates to the copy under `node_modules/@event4u/agent-config/`
54
- or `vendor/event4u/agent-config/`.
42
+ The wrapper is regenerated on every install and delegates to (in order):
43
+ `$AGENT_CONFIG_MASTER`, `./node_modules/@event4u/agent-config/`,
44
+ `agent-config` on `$PATH` (global npm install), or
45
+ `npx @event4u/agent-config@latest`.
55
46
 
56
47
  ## First Run
57
48
 
@@ -106,3 +106,35 @@ correction pattern.
106
106
 
107
107
  Acknowledge once, in the user's language, switch behavior, no
108
108
  excuses (mirrors `language-and-tone` § slip handling).
109
+
110
+
111
+ ## No Cheap Questions — Iron Law 3 detail (paternalistic state options)
112
+
113
+ Companion to `no-cheap-questions` § Iron Law 3. The rule states the
114
+ prohibition; this file lists the patterns and the carve-outs.
115
+
116
+ **Forbidden patterns** (non-exhaustive):
117
+
118
+ - "Stop hier — du hast genug für heute"
119
+ - "Take a break and come back fresh"
120
+ - "Weitermachen wenn frisch"
121
+ - "Du wirkst genervt, sollen wir pausieren?"
122
+ - "Sleep on it"
123
+ - "That's a good stopping point" as a numbered option
124
+ - Any option whose recommendation rests on inferred fatigue,
125
+ frustration, or end-of-day mood.
126
+
127
+ **Carve-outs** — allowed because they cite **observable, in-message**
128
+ evidence, not inferred state:
129
+
130
+ - User said "ich bin müde / done for today / let's stop" **this turn**
131
+ → ack and stop (instruction, not option).
132
+ - Hard Floor confirmation per `non-destructive-by-default` → "confirm
133
+ or abort" is the option, not "rest".
134
+ - Context-window / freshness threshold tripped per `context-hygiene` →
135
+ cite the threshold ("fresh chat at 75%"), do not infer mood.
136
+
137
+ **The rule of thumb**: every numbered option must be a technical /
138
+ scope / sequencing choice with a real trade-off, not a mood-management
139
+ nudge. If the only remaining differentiator is "you might be tired" →
140
+ drop the option, recommend a concrete next step instead.