Summarize subsystems (community summaries)
Cluster the base code graph into subsystems (by module path) and write a short, grounded
summary for each, persisted for ask / PR-walkthrough to use as a cheap high-level prior. This
skill reads code and writes summaries to the reviewer store; it does NOT modify code or post to
GitHub.
Always write summaries and answer the user in Russian (the project language), regardless of this
file's language. Tool calls, code identifiers and path:line stay verbatim.
Tools
Plus list_subsystem_clusters, get_subsystem_summary_work, get_file_skeletons,
index_subsystem_summary, prune_subsystem_summaries and backfill_summary_embeddings
(reviewer MCP). File-summary jobs read source ONLY through get_file_skeletons; the harness
Read is not used on source files in this skill.
Pipeline
- Resolve repo/branch.
List clusters (compact, paginated). Walk every page: call
list_subsystem_clusters(repo, branch, compact=True, limit=100), then repeat withoffset += 100while the response hashas_more == true. Stop only whenhas_more == false— a partial walk is not a full pass. Empty /noteabout an empty index → tell the user (in Russian) to runrag-reviewer:sync-codebasefirst, then stop.Every page carries the same whole-set fields:
depth(the applied cluster depth),layout_token(server-owned identity of the effective default depth plus sorted per-prefix overrides),depth_source(env|.review.yml|arg),deferred(stale clusters held back this pass under the cost cap, envSUMMARY_REBUILD_CAP),deferred_files(their pending file jobs),orphans(stored summaries whosecluster_keyis no longer a current cluster), andtotal_clusters(non-deferred clusters across the whole set, page-independent).The compact listing deliberately does not carry file-level data: each cluster gives
cluster_key,num_members,source_hash,stale,bootstrap,full_rebuild,reused_filesand the numeric countersadded,changed,removed,moved— no paths and no fingerprints. That keeps the listing O(clusters) instead of O(files). Per-cluster file detail comes fromget_subsystem_summary_workin step 5.Accumulate across pages:
expected_source_hashes = {cluster_key: source_hash}from every returned cluster, and the counter totals for the preflight. Save thelayout_token; these exact list-snapshot values are required for finalization.Preflight — echo the applied depth and ask for confirmation (gate the run). BEFORE summarizing, show the user (in Russian):
- the applied
depthand where it came from (depth_source: envSUMMARY_CLUSTER_DEPTH, the repo's.review.yml, or an explicit arg); - how many clusters there are (
total_clusters) and at what path level — e.g. «depth=2 → 15 кластеров уровняreviewer/index» — sampling a fewcluster_keys from the accumulated pages; - how many are
stalevs fresh, how many requirebootstrap, plusdeferredclusters anddeferred_files(held back by the cap). Compute these from the accumulated compact records — theadded/changed/removed/movedcounters are enough; never re-list in full format. - If
orphans > 0, warn: the depth changed or modules were removed, so N summaries are orphaned; a full (uncapped) pass will rebuild and prune them. - If any cluster has
bootstrap == true, explain that this is the first post-upgrade fragment bootstrap: all current files in selected clusters get fragments, cap-deferred clusters wait for later passes, and old cluster summaries remain available until their replacements are stored. - State the invariant explicitly:
cluster_keyand the layout identity depend on the whole layout policy — the default depth, every depth override, and thesummary_paths.ignoreclustering filter (which keeps test trees out of summaries without touching the review index) — so changing any of them triggers a full rebuild of every summary (old-layout summaries orphan and get pruned). Then ask the user to confirm before running. If they decline, stop without summarizing or pruning.
- the applied
Choose the summary model (only if work is selected). Select clusters where
stale == true OR bootstrap == true; full rebuilds already arrive as stale. A subsystem summary is a coarse, high-level prior — a small/cheap model is appropriate, and reviewing on an expensive model burns tokens. Ask the user which model tier to use for writing summaries, defaulting to a cheap tier (e.g. Haiku/Sonnet/Fable). Remember the choice for this run. If no cluster is selected, skip this step. Where model override is supported, dispatch a subagent on the chosen model.Build selected clusters from file fragments. Initialize run totals for
created,reused,removed,moved,raced, andembedded; initializedeferredfrom step 2. For each selected cluster:- Call
get_subsystem_summary_work(repo, branch, cluster_key, source_hash)once, passing the cluster's listedsource_hash. Ifready=false, count the cluster as deferred/raced, incrementraced, and continue without jobs or persistence. - Let pending work be exactly
added_files + changed_files. Split it into batches of at most 15 paths, preserving order, and dispatch exactly one file-summary job per batch on the chosen model — and no other source-reading jobs. Each batch prompt must name only its own paths and tell the job to fetch their skeletons with a singleget_file_skeletons(repo, paths, branch)call. A job must read nothing else: no harnessReadof a source file, noread_file. The skeleton is deliberately the whole input — it is exactly the material a fragment's freshness hash is computed from, so a summary derived from it cannot silently go stale. A skeleton value that starts with(or contains the(…усечено)truncation marker is not source: the job must not summarize it. Treat that path as not done for this batch and count it towarddeferred. The job returns one Russian result per path:{path, summary, provenance}. A job must never compute, guess, or return afingerprint: that value is server-side and the orchestrator supplies it. If a job returns apathoutside its batch, or omits a path of its batch — other than a path already treated as not done for this batch under the note/truncated-skeleton rule above — discard that batch's results and re-dispatch that batch once; on a second mismatch count the cluster as deferred, incrementraced, and persist nothing for it. The orchestrator and every job must not read unchanged source files. If per-subagent model override is unavailable, generate the same per-file results inline and note that fallback in the report. - Build the ordered reused/moved/new fragment texts by merging
reused_fragments,moved_files, and the new file results, then sorting bypath. The orchestrator attaches each new fragment'sfingerprintby joining onpathwith the authoritativeadded_files/changed_filesentries of theget_subsystem_summary_workresponse — never from a job's answer. Dispatch exactly one cluster composer on the chosen model with only those ordered fragment records; do not passfiles,top_symbols, or source text. Its prompt must say: composer must not callReadand must not make source-code claims absent from the fragments. It returns{title, summary}in Russian: a one-line subsystem title and a compact paragraph about responsibilities, key symbols, and invariants supported by the fragments. - Persist the bundle:
index_subsystem_summary(repo, branch, cluster_key, title, summary, source_hash, fragments=[new file results])(the fingerprint-enriched records from 5.3). Pass only the newly generated pending-file results infragments; reused and moved fragments are committed server-side. If the response hasstored=false, count the cluster as deferred/raced, incrementraced, and must not count it as success or add its metrics. Forstored=true, add returnedcreated,reused,removed, andmovedto the run totals, and add one toembeddedwhen itsembeddedis true.
- Call
Prune orphaned summaries (only on a full pass). If the pass was full — you walked every page to
has_more == false,deferred == 0, you haveraced == 0, and you did NOT pass an explicitdepth/capoverride (so the accumulated clusters covered every current cluster) — callprune_subsystem_summaries(repo, branch, layout_token, expected_source_hashes)with the exact values saved from step 2. The server re-derives the layout/hashes and verifies complete same-generation fragment coverage under its branch lock before deleting summaries whosecluster_keyis no longer current. If prune returnscompleted=false, count the prune as raced/partial, incrementraced, do not treat depth/layout as finalized, and report itsdeferred/note; do not add prune metrics. Forcompleted=true, accumulate both returnedprunedandfragments_pruned. On a partial pass (deferred > 0, any race, or an override) skip pruning — deferred clusters are not orphans and an incomplete bootstrap must not finalize depth state — and say so in the report (mirrorssync_board --limit).Pagination is not an override: paging through the listing with
offset/limitstill yields a full pass, as long as you walked tohas_more == false.
6.5. Backfill summary embeddings (every pass). Call backfill_summary_embeddings(repo, branch) so
any summaries still missing an embedding (older summaries written before vectorization, or where a
prior pass's Voyage call failed) become searchable by proximity. It embeds from stored title+summary
(no LLM), is idempotent (a warm corpus embeds nothing), and is fail-soft. Add its returned
embedded count to the run total.
- Report (Russian). The applied
depth+depth_source; clusters stored vs skipped-as-fresh; cap-deferred clusters/files and optimisticracedclusters (the report's deferred/raced total); fragment metricscreated,reused,removed, andmoved; summariesprunedandfragments_pruned, or that pruning was skipped on a partial pass; and totalembedded. Never silently truncate. If file summaries or composers were written inline (no model override), say so.
Grounding (hard rule)
Each new file fragment must reflect exactly its own pending file's skeleton and nothing else's. Cluster composers ground only on provided fragments and never read source. If the fragments leave a cluster unclear, say so briefly rather than guessing.
Notes
- Precondition: base index built (
reviewer index). Re-running is incremental at file-skeleton fingerprint granularity: unchanged source files are not read or summarized again. - Read-only on code and GitHub; only writes summaries to the reviewer store.