Skip to content

Commit e4f6087

Browse files
committed
docs(plans): add agent-ready bootstrap map and tiered lookup plans
Fact-checked against context-engine, show-search-mode, and db indexes. Roadmap links both backlog items to executable tracer-bullet slices.
1 parent 8bd841b commit e4f6087

3 files changed

Lines changed: 236 additions & 2 deletions

File tree

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Codebase map in bootstrap responses — plan
2+
3+
> **Status:** open · **Priority:** P2 (agent warm-path) · **Effort:** S–M (~3–5 days)
4+
>
5+
> **Motivator:** Agents call `context` at session start today but lack a compact, hash-stable routing card: which codemap CLI/MCP verbs to reach for first, and whether the structural summary changed since the last session. Roadmap marks this **partial**`hubs`, `start_here.index_summary`, `index_freshness`, and `codemap.schema_version` already ship on `context`; **`cli_entry_hints`** and **`map_id`** do not.
6+
>
7+
> **Roadmap:** [§ Agent session & warm-path economics — Codebase map](../roadmap.md#agent-session--warm-path-economics)
8+
>
9+
> **Not in scope:** Framework entry-point substrate (`files.is_entry`) — tracked separately at [`c9-plugin-layer.md`](./c9-plugin-layer.md). “CLI entry hints” here means **codemap command/tool routing**, not app runtime entry files.
10+
11+
---
12+
13+
## Agent start here
14+
15+
Read **`ContextEnvelope`** and **`composeStartHere`** in [`context-engine.ts`](../../src/application/context-engine.ts) first. Do not re-implement `start_here` — add a sibling **`codebase_map`** object and **`map_id`** at the envelope root.
16+
17+
### Shipped today (do not rebuild)
18+
19+
| Surface | Ships | Does not ship |
20+
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
21+
| **`context` tool** / `codemap context` | `codemap.cli_version`, `codemap.schema_version`, `project.*`, `recipes[]`, `index_freshness`, optional `hubs`, `sample_markers`, `start_here` (`index_summary`, intent recipe cards, `hub_leaders` + signatures) | `map_id`, `codebase_map`, `cli_entry_hints` |
22+
| **MCP `initialize`** | Markdown `instructions` from [`assembleMcpInstructions()`](../../src/application/agent-content.ts) (`templates/agent-content/mcp-instructions.md`) | JSON structural map; no auto-`context` call at boot ([`runMcpServer`](../../src/application/mcp-server.ts) only bootstraps DB + optional watch) |
23+
| **Opt-out** | `--compact` / MCP `compact: true` drops `hubs`, `sample_markers`, `start_here` ([`context-engine.ts:297-323`](../../src/application/context-engine.ts)) | No dedicated codebase-map opt-out flag |
24+
25+
### Key touchpoints
26+
27+
| File | Role |
28+
| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
29+
| [`src/application/context-engine.ts`](../../src/application/context-engine.ts) | `ContextEnvelope` type, `buildContextEnvelope`, `composeStartHere`, `resolveContextBudget` |
30+
| [`src/application/index-freshness.ts`](../../src/application/index-freshness.ts) | `computeIndexFreshness` (already merged into envelope) |
31+
| [`src/application/tool-handlers.ts`](../../src/application/tool-handlers.ts) | `contextArgsSchema`, `handleContext` |
32+
| [`src/cli/cmd-context.ts`](../../src/cli/cmd-context.ts) | `--compact`, `--for`, `--include-snippets` argv |
33+
| [`src/application/mcp-server.ts`](../../src/application/mcp-server.ts) | `registerContextTool`, `createMcpServer` initialize `instructions` |
34+
| [`src/application/agent-content.ts`](../../src/application/agent-content.ts) | `assembleMcpInstructions` (Slice 2 hook) |
35+
| [`src/cli/aliases.ts`](../../src/cli/aliases.ts) | `OUTCOME_ALIASES` — five outcome-shaped CLI aliases |
36+
| [`src/application/mcp-tool-allowlist.ts`](../../src/application/mcp-tool-allowlist.ts) | `MCP_TOOL_NAMES` (21 tools) |
37+
| [`src/hash.ts`](../../src/hash.ts) | `hashContent` (SHA-256) for `map_id` |
38+
| [`src/application/context-engine.test.ts`](../../src/application/context-engine.test.ts) | Envelope + `composeStartHere` tests |
39+
| [`src/application/mcp-server.test.ts`](../../src/application/mcp-server.test.ts) | MCP `context` + initialize instructions |
40+
| [`templates/agent-content/mcp-instructions.md`](../../templates/agent-content/mcp-instructions.md) | Session-start playbook (Slice 2 cross-ref) |
41+
42+
---
43+
44+
## Pre-locked decisions
45+
46+
| # | Decision | Source |
47+
| --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
48+
| L.1 | Add **`codebase_map`** on `ContextEnvelope` — sibling to `start_here`, not a replacement. | Preserve shipped `start_here` consumers |
49+
| L.2 | **`map_id`** = first **16** hex chars of `hashContent(JSON.stringify(canonical))` where `canonical` uses **sorted** `hub_paths: string[]`, `index_summary` object, `schema_version`, `file_count`, `last_indexed_commit` (from existing envelope fields). Same inputs → same id across transports. | [`hash.ts`](../../src/hash.ts); stable agent cache key |
50+
| L.3 | **`cli_entry_hints`** = structured static routing rows sourced from code constants — **not** inferred from indexed repo files. Minimum rows: (a) five [`OUTCOME_ALIASES`](../../src/cli/aliases.ts) (`dead-code``untested-and-dead`, …); (b) session-start MCP tools: `context`, `show`, `query_recipe`, `trace`, `explore`, `node`, `validate` (matches [`mcp-instructions.md` Session start](../../templates/agent-content/mcp-instructions.md)). Shape: `{ surface: "cli" \| "mcp", id: string, maps_to: string, note?: string }`. | Roadmap “CLI entry hints”; distinct from C.9 `is_entry` |
51+
| L.4 | **Opt-out:** new `--no-codebase-map` CLI flag + MCP/HTTP `include_codebase_map?: boolean` (default **true** when not `compact`). When `compact: true`, omit `codebase_map` and `map_id` regardless of flag. | Roadmap “opt-out via flag”; keep `compact` semantics |
52+
| L.5 | **No `SCHEMA_VERSION` bump** — JSON-only envelope fields. | Moat B discipline; no DDL |
53+
| L.6 | **MCP initialize Slice 2 (optional):** append a short auto-generated block to `assembleMcpInstructions()` output: `map_id` + top 3 `hub_paths` + link to call `context` for full map. MCP SDK exposes no structured initialize JSON beyond `instructions` ([`createMcpServer`](../../src/application/mcp-server.ts:157-164)). | Factual transport constraint |
54+
55+
---
56+
57+
## Target envelope shape (Slice 1)
58+
59+
```typescript
60+
// Added to ContextEnvelope in context-engine.ts
61+
map_id?: string; // omitted when compact / --no-codebase-map
62+
codebase_map?: {
63+
hub_paths: string[]; // from start_here.hub_leaders[].file_path (same budget cap)
64+
cli_entry_hints: {
65+
surface: "cli" | "mcp";
66+
id: string;
67+
maps_to: string;
68+
note?: string;
69+
}[];
70+
};
71+
```
72+
73+
`map_id` is computed **after** `hub_paths` are known so agents can compare ids without re-fetching full `start_here`.
74+
75+
---
76+
77+
## Implementation slices
78+
79+
| Slice | Scope | Ship gate |
80+
| ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
81+
| **1** | Types + `buildCodebaseMap()` + `computeMapId()` in `context-engine.ts`; wire `handleContext` / `cmd-context`; tests in `context-engine.test.ts` + `tool-handlers.test.ts` | Tracer bullet — land first |
82+
| **2** | MCP initialize instructions append (requires DB at `assembleMcpInstructions` time **or** lazy placeholder + “call `context`”) — pick one in PR; update `mcp-instructions.md` + `mcp-server.test.ts` | Only after Slice 1 green |
83+
| **3** | Docs: [`architecture.md` § Context wiring](../architecture.md), [`agents.md`](../agents.md) bootstrap table; roadmap item → check `[x]` + delete this plan when closed | Same PR as Slice 1–2 or follow-up |
84+
85+
### Tracer bullet (Slice 1)
86+
87+
1. Add `buildCodebaseMap({ hubLeaders, compact, include })` returning `undefined` when `compact || !include`.
88+
2. Add `computeMapId(canonical)` using `hashContent`.
89+
3. Extend `contextArgsSchema` + `parseContextRest` with opt-out flag.
90+
4. Test: stable `map_id` for fixed fixture DB; opt-out omits fields; `compact` omits fields.
91+
92+
### Out of scope
93+
94+
- `files.is_entry` / framework route substrate ([`c9-plugin-layer.md`](./c9-plugin-layer.md), [`framework-route-extraction.md`](./framework-route-extraction.md))
95+
- Auto-invoking `context` inside `runMcpServer` (extra index work on every MCP boot)
96+
- New MCP resource `codemap://map` (defer unless a consumer requests it)
97+
- Verdict / pass-fail on map freshness (Moat A)
98+
99+
---
100+
101+
## Acceptance
102+
103+
- [ ] `codemap context --json` includes `map_id` + `codebase_map.cli_entry_hints` with all five outcome aliases and seven session-start MCP tools (L.3)
104+
- [ ] Re-running `context` on unchanged index returns identical `map_id`
105+
- [ ] `codemap context --compact` and `--no-codebase-map` omit `map_id` and `codebase_map`
106+
- [ ] MCP `context` JSON matches CLI envelope (parity via `handleContext`)
107+
- [ ] `bun test src/application/context-engine.test.ts src/application/tool-handlers.test.ts src/application/mcp-server.test.ts`
108+
109+
---
110+
111+
## Verification
112+
113+
```bash
114+
bun test src/application/context-engine.test.ts src/application/tool-handlers.test.ts
115+
bun src/index.ts context --json | jq '.map_id, .codebase_map.cli_entry_hints | length'
116+
bun src/index.ts context --no-codebase-map --json | jq 'has("map_id")' # expect false after implementation
117+
bun src/index.ts context --compact --json | jq 'has("codebase_map")' # expect false after implementation
118+
```
119+
120+
---
121+
122+
## Dependencies
123+
124+
- Shipped: `start_here`, `index_freshness`, `OUTCOME_ALIASES`, 21-tool MCP allowlist
125+
- Independent of: C.9 plugin layer, FTS default-on, tiered lookup fast paths

0 commit comments

Comments
 (0)