---
name: edc-update-impl
description: Incrementally updates edc-context/ files based on branch changes (v2 layout)
---

# Update Context (v2)

**Arguments:** optional `--base <ref>` for comparison reference and repeatable `--ignore <glob>` to exclude files from this run. Default base: auto-detect merge base with main/master.

## Ignore Rules

Before computing changed files, resolve ignore patterns in this order:

1. If one or more `--ignore <glob>` arguments were provided, use only those patterns.
2. Otherwise, if `.edcignore` exists in the repo root, read non-empty, non-comment lines from it.
3. Otherwise, do not exclude any additional files.

Apply ignore rules to repo-relative file paths before mapping changed files to modules.

## Preconditions (orchestrator-owned)

This skill is invoked by `plugins/edc/scripts/edc-update.sh` AFTER the orchestrator has gated the on-disk state. By the time this skill runs you can assume:

- `edc-context/manifest.json` exists, parses as JSON, and `schemaVersion == 2`
- `edc-context/index.md` exists
- v1 markers (`edc-context/.meta.json`, top-level `context.md` etc.) are NOT present

If any of those assumptions are violated when this skill runs, that's an orchestrator bug — fail loudly rather than trying to repair the layout from inside the skill. Do NOT call `edc-clean-slate.sh` from this skill.

If `git diff --name-only "$BASE"..HEAD` returns no source-file changes (only `edc-context/` or unrelated tracked paths), the update is a no-op. Skip to Step 10 (Validate) and exit 0. Never declare success when `manifest.json` is missing or invalid — the orchestrator's `edc-doctor.sh` post-check will catch that, but a clean exit from this skill on a broken layout is itself a bug.

## Process

### Step 1 — Detect what changed

```bash
# Auto-detect base if not provided
BASE=$(git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null)

# Get changed files since base
git diff --name-only "$BASE"..HEAD
```

Read `edc-context/manifest.json` to get `sourceCommit` (last analyzed commit) and `modules[]` with their `name`, `doc`, and `match` rules.

### Step 2 — Identify affected modules and contextless paths

Classify each changed file by invoking the shared classifier:

```bash
printf '%s\n' <file-path> | node plugins/edc/hooks/lib/classify-cli.mjs edc-context/manifest.json
```

`classify-cli.mjs` returns `<path>\t<state>` lines where state is exactly one of: `ignored`, `context-module:<module>`, `contextless:<entryId>:<reviewPolicy>`, `uncovered`, or `ambiguous`. Do not reimplement classification.

Collect affected real modules from `context-module:*`. For changed `contextless:*` paths, inspect the diff and either keep them contextless, promote them to a real context module, or report a promotion candidate; do not silently skip them. `reviewPolicy` controls review behavior only — update owns actual context promotion/status changes. `uncovered` and `ambiguous` paths must be fixed by manifest/context changes before the update is considered healthy.

Also include any modules that `edc-context/modules/<name>.md` documents as coupled to an affected module (read the cross-module coupling sections).

### Step 3 — Re-analyze affected modules

`edc-build-plan.sh` expects the FULL module list on stdin and a comma-separated `--changed` filter as a single argument. Build the input from the existing manifest, then pipe it in:

```bash
# Comma-join the affected module names (no spaces)
CHANGED="$(IFS=,; echo "${affected[*]}")"

# Project the manifest's modules[] into the script's expected {name, paths} shape,
# then pipe and filter
jq '{
  modules: [
    .modules[] | {
      name,
      paths: ((.match.exactFiles // []) + (.match.prefixes // []) + (.match.globs // []))
    }
  ]
}' edc-context/manifest.json \
| bash plugins/edc/scripts/edc-build-plan.sh --changed "$CHANGED"
```

Execute the resulting `module-context` task list the same way as the build flow (see `edc-build-impl` step 2): spawn one clean subagent per task using the embedded `prompt` verbatim, run in parallel batches, collect summaries. Do not interpret, edit, or skip tasks.

### Step 4 — Update `edc-context/modules/<name>.md` files

Rewrite each affected module's `edc-context/modules/<name>.md` with the new analysis. Preserve the file format (`<!-- generated by /edc:edc-build -->` header).

### Step 5 — Remove stale module docs

If the manifest's `modules[]` set has changed (modules were renamed, merged, or dropped):

- For every file under `edc-context/modules/`, check whether its name corresponds to a module still listed in the post-update manifest's `modules[].doc`.
- Delete any `edc-context/modules/<name>.md` whose module no longer exists in the manifest.

This keeps the on-disk module set in sync with `manifest.modules[]`. Do not delete `edc-context/modules/` itself.

### Step 6 — Update `edc-context/reports/issues.md`

Re-read all `edc-context/modules/*.md` files. Rebuild `edc-context/reports/issues.md` from scratch:

- Keep issues that still exist in the code
- Remove issues that were fixed by the changes
- Add new issues found in the updated modules
- Preserve issue numbering where possible for traceability

### Step 7 — Update `edc-context/reports/complexity.md` if affected

If any changed module's deep-context analysis surfaced new code quality / maintainability signals (or invalidated existing ones), refresh `edc-context/reports/complexity.md` to reflect the current state. Otherwise leave it alone.

### Step 8 — Update `edc-context/index.md` if needed

Re-read all `edc-context/modules/*.md` files and preserve this section order whenever the index is rewritten:

1. `## How to use`
2. `## Route by path/task`
3. `## Critical global invariants`
4. `## Cross-module coupling / blast radius`

Optional compact sections may follow only when they materially improve first-read decisions: `## Architecture overview` and `## Module table`. Keep them tiny; do not include generated file counts, LOC estimates, manifest priority values, report links, or broad architecture essays.

Do not add a Reports section to the ordinary index read path; reports remain discoverable through `manifest.json` and explicit review/audit workflows.

Check if any of these changed:

- routing rows needed for changed paths/tasks
- module list (modules added, removed, renamed, or rerouted)
- critical global invariants
- trust boundaries
- cross-module coupling / blast radius
- key flows or actors that affect daily task routing or review scope

If any changed, rewrite `edc-context/index.md` as the same routing-first operational index described by the build contract (preserving the `##` heading requirement). If only a purely local implementation detail changed and the routing, invariants, coupling, trust boundaries, module relationships, and key flows are unchanged, leave the index alone to avoid noisy rewrites.

### Step 9 — Refresh `edc-context/manifest.json`

Re-author the LLM-owned portion of the manifest (only fields that changed: `modules[]` if modules were added/removed/renamed, `contextless.entries[]` if coverage shifted, and legacy `unmapped.allowedGlobs` only for migration compatibility). **Preserve `policy.defaultMode` from the existing `edc-context/manifest.json`** — it may have been set by `edc mode advisory|inject` and rebuilds must not revert that choice. Likewise preserve any other operator-authored `policy.*` fields (`guardedTools`, `discoveryGatedOnIndex`, `bootstrapAlwaysReadable`). Do **not** populate `generatedAt`, `sourceCommit`, or `coverage.*` — the post-step owns those.

Pipe the partial manifest through the deterministic generator to refresh `coverage.*` and `sourceCommit`:

```sh
cat /tmp/partial-manifest.json | bash plugins/edc/scripts/edc-manifest.sh > edc-context/manifest.json
# if this update was invoked with --ignore flags, pass the same flags to edc-manifest.sh
```

A non-zero exit from `edc-manifest.sh` is an update failure — surface it instead of writing a hand-edited manifest.

### Step 10 — Validate

After the update, verify the v2 layout still holds:

- `edc-context/manifest.json` parses, `schemaVersion == 2`, and every `modules[].doc` resolves to an existing file
- no orphan files remain under `edc-context/modules/` for modules dropped from the manifest
- `edc-context/index.md` contains at least one `##` heading
- `edc-context/reports/issues.md` and `edc-context/reports/complexity.md` exist

If any check fails, surface the failure; do not silently continue. `edc doctor` is the canonical end-to-end validator.

The shell orchestrator runs `edc-context-curator-impl` as a separate runtime report-only step after this skill returns and doctor validates the generated context. Do not invoke the curator from inside this update skill.
