Skip to content

Commit 5b4e9b2

Browse files
committed
docs(apply): complete Phase A — architecture, glossary, agents, close direction plan
Expand apply transport/policy in architecture and glossary; README and agent-content discover→apply workflow; lift rejected items into utilization plan and delete apply-engine-direction.md.
1 parent 6739499 commit 5b4e9b2

11 files changed

Lines changed: 156 additions & 202 deletions

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,20 +211,28 @@ codemap affected --changed-since origin/main --json # committed de
211211
# Moat-A twin: `affected-tests` recipe. Output: [{test_path, impact_depth}] — CI composes the runner command.
212212

213213
# Apply — substrate-shaped fix executor (recipe SQL describes hunks; codemap validates + writes)
214+
# Row contract (same as --format diff-json): {file_path, line_start, before_pattern, after_pattern}
215+
# Preview first: codemap query --recipe rename-preview --params old=foo,new=bar --format diff-json
214216
codemap apply rename-preview --params old=usePermissions,new=useAccess,kind=function --dry-run
215217
codemap apply rename-preview --params old=usePermissions,new=useAccess,kind=function --yes # TTY prompts without --yes
216-
# Consumes the --format diff-json row contract ({file_path, line_start, before_pattern, after_pattern}).
217-
# All-or-nothing: any conflict aborts before any file is written. Pair with --format diff-json preview first.
218+
codemap apply migrate-import-source --params old=legacy,new=@app/core --dry-run
219+
codemap apply replace-marker-kind --params old_kind=TODO,new_kind=FIXME --yes --force # when not auto_fixable
220+
# Agent/codemod rows (no recipe policy gates): echo '[{...}]' | codemap apply --rows - --yes
221+
# External unified diff: codemap apply --diff-input /tmp/patch.diff --dry-run
222+
# Fixpoint (recipe mode): codemap apply rename-preview --params old=a,new=b --until-empty --yes
223+
# Optional git commit after clean apply: codemap apply ... --yes --commit "chore: rename a→b"
224+
# Bundled diff-shape recipes: rename-preview, migrate-import-source, replace-marker-kind, add-jsdoc-deprecated
225+
# All-or-nothing: any conflict aborts before any file is written. MCP: apply + apply_rows (yes: true for writes).
218226

219227
# Live agent content (pointer protocol — full body served from installed package version)
220228
codemap skill # full codemap SKILL markdown to stdout
221229
codemap rule # full codemap rule markdown to stdout
222230

223231
# MCP server (Model Context Protocol) — for agent hosts (Claude Code, Cursor, Codex, generic MCP clients)
224232
codemap mcp # JSON-RPC on stdio (18 tools; watcher default-ON)
225-
# Tools (17): query, query_batch, query_recipe, audit, save_baseline,
233+
# Tools (18): query, query_batch, query_recipe, audit, save_baseline,
226234
# list_baselines, drop_baseline, context, validate, show, snippet, impact,
227-
# affected, trace, explore, node, apply
235+
# affected, trace, explore, node, apply, apply_rows
228236
# CLI twins: query batch, trace, explore, node, file, schema, symbols, context --include-snippets (same JSON as MCP/HTTP).
229237
# Resources: codemap://schema, codemap://skill, codemap://rule, codemap://mcp-instructions (lazy-cached);
230238
# codemap://recipes, codemap://recipes/{id} (live read-per-call — recency fields stay fresh);

docs/architecture.md

Lines changed: 21 additions & 1 deletion
Large diffs are not rendered by default.

docs/glossary.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,13 @@ See **language adapter**.
3131

3232
A `.agents/rules/<name>.md` file with YAML frontmatter. Distinct from a **skill** (longer, scenario-specific). Distinct from a **bundled recipe** (which is SQL, not Markdown).
3333

34+
### `apply_rows` (MCP tool / CLI mode)
35+
36+
Second apply transport for **caller-supplied** hunks — same `{file_path, line_start, before_pattern, after_pattern}` contract as [`codemap apply`](#codemap-apply--apply-tool) but **no recipe policy gates** (`auto_fixable`, `apply.autoApplyRecipes`, or `--force`). CLI: `codemap apply --rows -` (stdin JSON array) or `codemap apply --rows path.json`. MCP / HTTP: `apply_rows` with `{rows, dry_run?, yes?}`. Use when an agent or external codemod already materialised rows; use `apply` + a recipe id when the index should synthesise rows from SQL. Writes still require non-TTY consent (`--yes` / `yes: true`). Distinct from `query --format diff-json` (read-only preview).
37+
3438
### `codemap apply` / apply tool
3539

36-
Substrate-shaped fix executor — reads the same `{file_path, line_start, before_pattern, after_pattern}` row contract `--format diff-json` emits and applies the hunks to disk. Recipe SQL is the synthesis surface; codemap is the executor (Moat-A clean — verdict-shape "should we fix this?" stays on the recipe author). CLI: `codemap apply <recipe-id> [--params k=v[,k=v]] [--dry-run] [--yes] [--json]`. MCP: `apply` tool. HTTP: `POST /tool/apply`. **Phase 1** validates every row against current disk via `actual.includes(before_pattern)` (substring match — mirrors `buildDiffJson`'s contract); collects five conflict reasons (`file missing` / `line out of range` / `line content drifted` / `path escapes project root` / `duplicate edit on same line`). The path-containment guard rejects absolute `file_path` inputs and `../`-traversal that resolves outside `projectRoot`; the overlap guard rejects two-or-more rows targeting the same `(file_path, line_start)`. **Phase 2** (gated on `!dryRun && conflicts.length === 0`) writes each modified file via sibling temp + `renameSync` for POSIX-atomic per-file writes, with `$`-pre-escape on `after_pattern` per `String.prototype.replace` GetSubstitution rule. **Q2 (c) all-or-nothing** — any conflict in any file aborts phase 2 entirely; partial writes never ship. **Q6 gate** — TTY no `--yes` triggers a `Proceed? [y/N]` prompt (default-N) on stderr; non-TTY contexts (CI / agents / MCP / HTTP) require `--yes` (or `yes: true`) explicitly. Result envelope (Q5; identical across modes): `{mode, applied, files, conflicts, summary}`. Re-running on already-applied code reports a `line content drifted` conflict whose `actual_at_line` shows the post-rename content — user re-runs `codemap` to refresh the index, then re-runs apply for a vacuous clean pass (Q7). Engine: `application/apply-engine.ts` (pure; `applyDiffPayload`). Boundary: only `cli/cmd-apply.ts` + `application/tool-handlers.ts` may import the engine — re-runnable kit at [`docs/architecture.md` § Boundary verification — apply write path](./architecture.md#boundary-verification--apply-write-path). Floor "No fix engine" preserved — codemap doesn't synthesise edits, it only executes the hunks the recipe row described.
40+
Substrate-shaped fix executor — reads the same row contract `--format diff-json` emits and applies hunks to disk. Recipe SQL is the synthesis surface; codemap is the executor (Moat-A — verdict-shape "should we fix this?" stays on the recipe author). **Three CLI input modes** (mutually exclusive): (1) **recipe** — `codemap apply <recipe-id> [--params k=v[,k=v]]`; MCP/HTTP `apply` `{recipe, params?, dry_run?, yes?, force?}`. (2) **rows** — `codemap apply --rows -|<file.json>`; MCP/HTTP [`apply_rows`](#apply_rows-mcp-tool--cli-mode). (3) **diff** — `codemap apply --diff-input <unified-diff>` (CLI only; `parseUnifiedDiffToRows`). Shared flags: `--dry-run` (phase-1 only), `--yes` (skip TTY prompt; required for non-TTY writes), `--json`. **Recipe-only flags:** `--force` (bypass `auto_fixable` + allowlist), `--until-empty` + `--max-passes N` (fixpoint loop: apply → reindex touched files → repeat; adds `passes` + `terminated_by` ∈ `{empty, cap, conflicts, complete}` to the envelope), `--commit "<msg>"` (git add + commit touched paths after clean apply). **Policy (recipe mode only):** recipes with `auto_fixable: false` in `<id>.md` frontmatter reject writes unless `--force` / MCP `force: true`; `apply.autoApplyRecipes` in [user config](./architecture.md#user-config) allowlists recipe ids for non-interactive CLI without `--yes` (MCP/HTTP writes still need `yes: true`). Bundled diff-shape recipe ids today: `rename-preview`, `migrate-import-source`, `replace-marker-kind` (auto-fixable); `add-jsdoc-deprecated` (force-gated). **Phase 1** validates every row via `actual.includes(before_pattern)` (substring match); five conflict reasons (`file missing` / `line out of range` / `line content drifted` / `path escapes project root` / `duplicate edit on same line`). **Phase 2** (gated on `!dryRun && zero conflicts`) writes via sibling temp + `renameSync` per file; **all-or-nothing** across files on conflicts (no cross-file rollback on crash mid-phase-2). **Q6 gate** — TTY without `--yes` prompts `Proceed? [y/N]`; MCP/HTTP have no prompt path. Result envelope: `{mode, applied, files, conflicts, summary}` (+ optional `passes`, `terminated_by`). Re-apply on stale disk → `line content drifted`; re-index then vacuous zero-row pass (Q7). Engine: `application/apply-engine.ts` (`applyDiffPayload`); orchestration: `application/apply-run.ts`. Full transport matrix: [`architecture.md` § Apply — input modes](./architecture.md#apply--input-modes-transport-and-policy). Boundary kit: [§ Boundary verification — apply write path](./architecture.md#boundary-verification--apply-write-path).
3741

3842
### audit
3943

docs/plans/apply-engine-direction.md

Lines changed: 0 additions & 103 deletions
This file was deleted.

0 commit comments

Comments
 (0)