# Code Module Summaries

> Use when scanning an arbitrary Git repository to create, refresh, or selectively update Markdown summaries of code modules, especially when changes must be traced from each module's last successful update.

- Skill: `demondamon/code-module-summaries` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add demondamon/code-module-summaries`
- Raw SKILL.md: https://api.skillmd.com/api/skills/demondamon/code-module-summaries/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: DemonDamon (https://skillmd.com/u/demondamon)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/demondamon/code-module-summaries

---


# Code Module Summaries

## Overview

Build and maintain evidence-backed Markdown summaries for an arbitrary Git
repository. Treat each module's last successful commit SHA as its incremental
checkpoint. Timestamps and Markdown mtimes are display metadata only.

The tracked control directory is the source of truth:

- `registry.json`: stable module boundaries, layout, and summary paths.
- `state/<module-id>.json`: one independent checkpoint per module.
- `modules/*.md`: summaries when using the centralized layout.
- `INDEX.md`: links and module ownership; update only when mappings change.

## Invocation

Interpret user arguments with this contract:

```text
/code-module-summaries [repo]
  [--output <control-dir>]
  [--layout centralized|colocated|custom]
  [--update]
  [--module <id-or-exact-name>]...
  [--target <git-ref>]
  [--refresh-modules]
  [--summary-name <filename.md>]
  [--head-only]
  [--accept-summary-drift]
  [--adopt-existing-summary]
  [--rebaseline --reason <text>]
```

Defaults:

- `repo`: current Git root.
- `--output`: `code-summaries/`.
- `--layout`: `centralized`.
- `--target`: the registry's `tracked_ref`, normally `HEAD`.
- `--summary-name`: `MODULE_SUMMARY.md` for colocated summaries.

`--layout custom` places each module's Markdown at an arbitrary in-repository
`.md` path declared per module in `registry.json` (`summary_path`), with no
fixed directory shape. This is the layout for a shared `conclusions/`-style
tree, for example `enterprise/conclusions/apps/gateway_conclusion.md`. A custom
registry may also declare a top-level `index_path` (e.g.
`enterprise/conclusions/README.md`): a managed overview file the agent
maintains, excluded from module source diffs and unassigned-path checks. See
[REFERENCE.md](REFERENCE.md) §9 for exact rules. `centralized` and `colocated`
are unchanged.

`--module` is repeatable and case-sensitive. It selects exact IDs first, then
an exact unique name. Never use fuzzy matching for a write operation.

## Required Reference and Helper

Before the first scan, mapping refresh, deletion, or history recovery, read
[REFERENCE.md](REFERENCE.md) completely.

Use the deterministic helper for every update:

```bash
python <skill-dir>/scripts/scan_changes.py --help
```

Do not replace it with `git log --since`, file mtimes, or an improvised diff.

## Workflow

### 1. Validate scope

1. Resolve the Git root and freeze the full target commit OID.
2. Confirm the control directory is inside the repository and intended to be
   tracked by Git. It must not be the repository root or an ancestor of any
   module root.
3. Default to committed Git objects. If selected-module source files are
   dirty, stop. `--head-only` may explicitly ignore those worktree changes.
4. Never run fetch, pull, stash, reset, checkout, clean, or rebase implicitly.

### 2. First scan

When `registry.json` does not exist:

1. Discover real module boundaries from workspace/package manifests, runtime
   entry points, deploy units, ownership, tests, and import cohesion.
2. Aim for a useful map, not exactly ten modules. Do not split or merge strong
   package boundaries merely to hit a count.
3. Ensure every tracked source path has an owner. When needed, use one
   repository-root module with root `.`; deeper module roots take precedence.
   A new package first appears there and triggers a mapping refresh.
4. Present the candidate map and output paths before writing unless the user
   already supplied explicit module roots.
5. Create `registry.json` using the schema in [REFERENCE.md](REFERENCE.md).
6. Run `plan` before creating summaries and retain each returned
   `checkpoint_token`. If a summary already exists without state, read and
   preserve it before explicitly using `--adopt-existing-summary`.
7. Generate each summary from code at the frozen target. Cite real paths and
   symbols; do not turn plans or README claims into implemented behavior.
8. Run `checkpoint` separately for each successfully verified module. A failed
   module must not advance its state.

### 3. Incremental update

Run a read-only plan first:

```bash
python <skill-dir>/scripts/scan_changes.py plan \
  --repo <repo> \
  --control-dir <output> \
  [--module <selector>]... \
  [--target <ref>] \
  [--head-only] \
  [--accept-summary-drift] \
  [--adopt-existing-summary]
```

Exit code `2` or `has_blockers: true` means zero summary writes until the
reported blocker is resolved. For a multi-module plan with one blocked module,
either resolve all blockers and rerun, or run a new plan selecting only the
unblocked module; never partially execute the blocker-containing plan.

A full plan also blocks on tracked paths not owned by any module or excluded by
the registry. This catches newly added top-level packages instead of silently
ignoring them.

Use `--accept-summary-drift` only after an earlier plan actually reported
`SUMMARY_DRIFT` and the existing edits were reviewed. It cannot pre-authorize a
future summary change.

Handle each selected module by plan status:

- `new`: read the whole declared module scope and create its summary.
- `changed`: inspect every reported `A/M/D/R` path, including both sides of a
  rename, then read only the surrounding code and dependencies needed to
  explain the behavioral change. Apply the minimum accurate summary edit.
- `unchanged`: do not reread source and do not rewrite the Markdown; only
  checkpoint the target so the same range is not scanned again.
- `deleted`: do not delete or archive automatically. Confirm whether to retire,
  remap, or replace the module.
- `blocked`: stop for that module and follow the recovery table in
  [REFERENCE.md](REFERENCE.md).

After verifying one module's Markdown:

```bash
python <skill-dir>/scripts/scan_changes.py checkpoint \
  --repo <repo> \
  --control-dir <output> \
  --module <module-id> \
  --target <full-target-oid> \
  --target-ref <same-ref-used-by-plan> \
  --plan-token <token-returned-for-this-module> \
  --summary-sha256-at-plan <hash-returned-for-this-module> \
  [--head-only] \
  [--accept-summary-drift] \
  [--adopt-existing-summary] \
  [--summary-unchanged]
```

Pass the same plan options to `checkpoint`. Use `--summary-unchanged` only
after inspecting every reported change and confirming that none changes the
maintainer-facing summary.

Checkpoint successful modules independently. This is what lets one long-stale
module retain its own baseline while another is updated frequently.

### 4. Strict single-module mode

With `--module`:

- Do not rediscover all modules.
- Do not modify another module's summary or state.
- Do not update `INDEX.md` or `registry.json`.
- Treat a missing root, new package boundary, split, merge, or ambiguous rename
  as mapping drift; require `--refresh-modules`.
- Before finishing, verify the write set contains only the selected summaries
  and `state/<selected-id>.json`.

### 5. Mapping refresh

`--refresh-modules` is the only normal operation allowed to change module
roots, IDs, summary paths, or layout. Produce a before/after mapping and ask
before applying ambiguous splits, merges, or relocations. Retire old IDs; never
silently reuse them for unrelated code.

After an approved mapping edit, run `plan --mapping-refresh`, rebuild the
affected summary, then checkpoint with `--mapping-refresh --reason <text>` and
the returned token/hash. Mapping-refresh plans also validate whole-repository
ownership. Never delete state to bypass a revision mismatch.

After verified history rewriting, run `plan --rebaseline`, fully review the
module at the new target, then checkpoint with `--rebaseline --reason <text>`
and the returned token/hash. Rebaseline is not a date-based diff.

`--refresh-modules`, layout selection, and summary generation are Skill-level
operations. The helper deliberately implements only deterministic `plan` and
`checkpoint`; it does not guess repository architecture.

### 6. Batch subagent orchestration

For a whole-repository or large-scope initial generation (many `new`/`changed`
modules), generate summaries in parallel. The helper never dispatches agents;
you orchestrate them using the `dispatching-parallel-agents` skill. The
per-module `summary_path` isolation is what makes this safe — each subagent
writes exactly one file and shares no state.

#### 6.1 Subagent model selection (mandatory, cost-first)

**Never silently inherit the parent chat's model for batch subagents.**
Conclusion writing is mostly structured code reading + Markdown drafting; a
top-tier parent model (e.g. Opus) is usually wasteful when multiplied across
dozens of modules.

Before the first `Task` dispatch in a batch run:

1. Ask the user which model slug to use for the subagents (the `model`
   parameter on `Task`). Present a short recommendation table; do not invent
   slugs outside the currently available Task model list.
2. Wait for an explicit choice (or an explicit "use your recommended
   default"). Do not start parallel generation until confirmed.
3. Pass that slug as `model` on every summary-writing subagent in the run.
   Parent-side `plan` / `checkpoint` / registry edits stay on the parent
   model; only the per-module Markdown writers use the chosen cheap model.
4. Optional: allow a two-tier split if the user wants it — cheap default for
   stubs/small packages, a mid-tier model only for a few heavy modules the
   user names. Do not up-tier the whole batch without asking.

Recommended defaults (prefer the cheapest tier that still produces accurate
maintainer docs; update names when the Task model list changes):

| Module kind | Suggested `Task` model | Why |
|---|---|---|
| Default / most modules (CRUD packages, stubs, thin apps, deploy notes) | `composer-2.5-fast` | Lowest cost; enough for template-shaped conclusions |
| Code-heavy but bounded modules (single service, clear entry points) | `kimi-k2.7-code` or `glm-5.2-max` | Cheap code-specialist; good when symbol/path fidelity matters |
| Few high-risk / cross-stack modules the user flags (e.g. gateway + policy + IAM together) | `gpt-5.6-sol-medium` or `claude-sonnet-5-thinking-medium` | Mid-tier reasoning only where cheap models keep missing contracts |
| Never the default for batch writers | Opus / other top-tier parent models | Reserve for parent planning/review, not N-way parallel drafting |

If the user declines to pick, use **`composer-2.5-fast` for the whole batch**
and state that choice in the final report. Re-ask before switching tiers mid-run.

#### 6.2 Dispatch steps

1. As the parent, run `plan` (full or a selected set) at a single frozen
   `target_commit`. Confirm zero blockers, then record each module's
   `checkpoint_token`, `summary_sha256_at_plan`, and `summary_path`.
2. Complete §6.1 (user-chosen or confirmed-default subagent model) before any
   parallel `Task` calls.
3. For every `new`/`changed` module, dispatch one subagent with that `model`
   and a self-contained prompt that includes: the module `roots`, the frozen
   `target_commit` (instruct it to read exact versions via
   `git show <TARGET>:path`), the exact output `summary_path`, the summary
   template (REFERENCE §7), the repository's existing conclusion style, and a
   hard boundary: write only its own summary file — never touch other
   summaries, `registry.json`, `state/`, or the `index_path` overview.
4. When all subagents return, the parent runs `checkpoint` for each module with
   that module's own token and hash. A failed or unverified module is left
   without a checkpoint so the next run still reports it as `new`/`changed`.
5. `unchanged` modules get no subagent; the parent checkpoints them directly
   (with `--summary-unchanged` only after review) or skips them.
6. Keep the overview/index file (`INDEX.md`, or the custom `index_path`
   README) as a final parent-authored step after the module summaries settle,
   never inside a module subagent.

## Accuracy Invariants

- Persist full commit OIDs, never abbreviated SHAs.
- Compare Git trees from `BASE` to frozen `TARGET`; commit dates do not define
  the range.
- Require `BASE` to exist and be an ancestor of `TARGET`.
- Record one baseline per module; a repository-global baseline is insufficient
  for selective updates.
- Keep centralized and colocated layouts on the same tracked control plane.
- Exclude summaries, state, generated files, dependencies, build output, and
  caches from module source inputs.
- Preserve manual summary edits. `--accept-summary-drift` permits a merge only
  after those edits have been read and retained.
- A normal checkpoint requires the exact token from a blocker-free plan. Never
  invent, reuse, or omit it.
- Tokens bind the module state generation, target ref, target OID, mapping,
  source fingerprint, plan-time summary hash, and safety options; they are
  single-use.
- Never claim an update is complete before the summary and its checkpoint both
  succeed.

## Summary Quality

Preserve each existing document's structure and tone. A summary should help a
maintainer use, change, or extend the module:

- responsibility and explicit non-responsibilities;
- entry points, public interfaces, and core execution path;
- important classes/functions and data/config contracts;
- upstream/downstream dependencies;
- tests and operational boundaries;
- unresolved facts clearly marked as unverified.

Remove descriptions of deleted or renamed implementation. Do not add changelog
noise unless the repository explicitly uses summaries as changelogs.

## Final Response

Report:

1. frozen target commit;
2. selected modules and each module's previous checkpoint;
3. `A/M/D/R` evidence grouped by module;
4. summaries and state files written;
5. skipped unchanged modules;
6. blockers or mapping decisions still requiring confirmation.

## Common Mistakes

- Using “ten days ago” or summary mtime as the baseline.
- Advancing one global checkpoint after updating only one module.
- Reading every module before checking the Git plan.
- Losing the old side of a rename or treating deletion as an addition.
- Rebuilding all summaries because one module changed.
- Overwriting manually edited Markdown without explicit acceptance.
- Guessing after force-push, shallow history, module split, or missing state.
- Dispatching batch summary subagents on the parent’s expensive model
  (e.g. Opus) without asking — always complete §6.1 first; default writers to
  `composer-2.5-fast` unless the user picks another slug.

