| 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:
- If one or more
--ignore <glob> arguments were provided, use only those patterns.
- Otherwise, if
.edcignore exists in the repo root, read non-empty, non-comment lines from it.
- 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
BASE=$(git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null)
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:
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:
CHANGED="$(IFS=,; echo "${affected[*]}")"
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:
## How to use
## Route by path/task
## Critical global invariants
## 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:
cat /tmp/partial-manifest.json | bash plugins/edc/scripts/edc-manifest.sh > edc-context/manifest.json
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.