R82.D — Launcher Config Contract
Task: R82.D · launcher config reality
Scope: .mcp.json, .vscode/mcp-settings.example.json
Round: R82 phase-0-1-stabilization, Wave 2
Author: T3 executor
Date: 2026-04-19
1. Behavioral contract
After R82.D lands, the two launcher configs at the repo root MUST:
- Parse as valid JSON (strict —
json.load()/JSON.parse()accepts them without error). - Never reference the nonexistent
src/server.jsfile. - Never declare any
AMS_*environment variable. - Never declare
COLIBRI_WATCH_MODE(not a read key — the reader isCOLIBRI_MODE). - Never declare bare
COLIBRI_DB(the reader isCOLIBRI_DB_PATH). - Never declare
COLIBRI_ROOT(no live reader insrc/). - Never contain the “Phase 0 not started” banner text.
- Use
COLIBRI_MODEas the mode-env key (only when overriding default FULL). - Use
COLIBRI_DB_PATHwhen overriding the default DB path. - Name the Colibri server entry “colibri” (not “ams-unified”).
- Launch
src/server.tsvia a tsx invocation (same invocation pattern as the VS Code example).
The github MCP server entries in both files remain unchanged (not in scope).
2. Acceptance gates
2.1. Negative grep sweeps (MUST return 0)
# Gate G1: src/server.js phantom eliminated across both files.
grep -cF "src/server.js" .mcp.json .vscode/mcp-settings.example.json
# Expected output: ".mcp.json:0" and ".vscode/mcp-settings.example.json:0"
# Gate G2: AMS_ROOT + AMS_WATCH_MODE eliminated from .mcp.json.
grep -cE "AMS_ROOT|AMS_WATCH_MODE" .mcp.json
# Expected output: "0"
# Gate G3: COLIBRI_WATCH_MODE eliminated from both files
# (the real reader is COLIBRI_MODE per src/modes.ts:90).
grep -cE "COLIBRI_WATCH_MODE" .mcp.json .vscode/mcp-settings.example.json
# Expected output: ".mcp.json:0" and ".vscode/mcp-settings.example.json:0"
# Gate G4: Bare COLIBRI_DB (not followed by underscore) eliminated from
# .vscode example. Only COLIBRI_DB_PATH may appear.
grep -cE '"COLIBRI_DB"[^_]' .vscode/mcp-settings.example.json
# Expected output: "0"
# Gate G5: "Phase 0 not started" banner eliminated from .mcp.json.
grep -cE "Phase 0 not started" .mcp.json
# Expected output: "0"
2.2. Positive grep sweeps (MUST be ≥ 1)
# Gate G6: COLIBRI_DB_PATH present in .vscode example.
grep -cF "COLIBRI_DB_PATH" .vscode/mcp-settings.example.json
# Expected: >= 1
# Gate G7: COLIBRI_MODE present somewhere across both files.
grep -cF "COLIBRI_MODE" .mcp.json .vscode/mcp-settings.example.json
# Expected: sum >= 1 (each file's count line combined)
2.3. JSON parse (MUST be valid on both)
python -c "import json; \
json.load(open('.mcp.json')); \
json.load(open('.vscode/mcp-settings.example.json')); \
print('json-valid')"
# Expected output: "json-valid"
2.4. Server identity (MUST match)
After edit, .mcp.json must contain the top-level key "colibri" under mcpServers (not "ams-unified"). Verified by:
python -c "import json; cfg=json.load(open('.mcp.json')); \
keys=list(cfg['mcpServers'].keys()); \
assert 'colibri' in keys, 'colibri key missing, got '+str(keys); \
assert 'ams-unified' not in keys, 'ams-unified key persists'; \
print('colibri server key OK')"
# Expected output: "colibri server key OK"
2.5. No regression in github server block
mcpServers.github stays structurally identical between pre- and post-edit in both files. Verified by:
# In .mcp.json: url shape preserved
python -c "import json; cfg=json.load(open('.mcp.json')); \
assert cfg['mcpServers']['github']['url'] == 'http://localhost:3000/sse'; \
print('.mcp.json github OK')"
# In .vscode example: command + args shape preserved
python -c "import json; cfg=json.load(open('.vscode/mcp-settings.example.json')); \
gh = cfg['mcpServers']['github']; \
assert gh['command'] == 'npx'; \
assert gh['args'] == ['-y', '@modelcontextprotocol/server-github']; \
print('.vscode github OK')"
3. Non-goals
- No
src/runtime code change. - No test suite change. This task has no
npmgate; the acceptance gates above are exhaustive. - No edit to
CONTRIBUTING.md$COLIBRI_ROOTplaceholder text (author-facing doc, not runtime env). - No edit to
.env.example(already correct; scope is the two launcher configs only). - No new documentation banner claims that must later be reconciled (the R75 Wave H annotation stays, with one appended R82 note as authorised by manifest definition-of-done).
4. Risk register
| Risk | Likelihood | Mitigation |
|---|---|---|
| JSON parse error after edit | Low | Edit tool is line-surgical; post-edit json.load check before commit |
| tsx invocation differs from VS Code example after edit | Low | Copy verbatim pattern from .vscode/mcp-settings.example.json as-is (node --loader tsx ${workspaceFolder}/src/server.ts), but in .mcp.json swap ${workspaceFolder} for the absolute E:/AMS that the existing file already uses |
COLIBRI_ROOT turns out to be read by something I missed |
Low | Already grepped src/ for process.env.COLIBRI_ and COLIBRI_ROOT — zero hits outside docs. Decision: remove from both files |
| Downstream tooling relies on “ams-unified” key name | Low | No evidence of such reference; MCP client boots by iterating mcpServers keys, not by a hard-coded lookup |
| R82 manifest says “any COLIBRI_ROOT reference is verified against code (kept if read, removed if not)” — an auditor may challenge removal | Low | Audit doc §3 D7 + §4 table cite the zero-reader finding explicitly |
5. Rollback
If a gate fails at Step 5 verification, revert via git reset --hard HEAD~1 back to the packet commit, re-investigate, and re-implement.
6. Next step
Packet — see docs/packets/r82-d-launcher-packet.md (Step 3).
R82.D contract. Five negative gates + two positive gates + JSON parse gate + server-identity gate + github-preservation gate. All gates deterministic; no test-suite coupling.