| name | topology |
| description | Scaffold, read, and audit subsystem topology entries — pointer-only yaml linking each subsystem's canonical code, decision record, operational doc, and test surface. |
| argument-hint | [subsystem | write | read | audit] |
| allowed-tools | Bash Read Edit Write |
| user-invocable | true |
| created_by | human |
| created_at | 2026-05-18T00:00:00.000Z |
| pinned | true |
/orb:topology
Architecture-level investigation discipline made cheap. Sibling to /orb:code-investigate — that skill makes file-level investigation cheap; this one makes the same investment at the architecture level. The agent owns the codebase at both granularities.
Substrate shape (per choice 0025 — topology-substrate-folder): each subsystem is one yaml file at .orbit/topology/<subsystem>.yaml, parsed against schema::TopologyEntry by the existing orbit-state machinery. Pruning a stale subsystem is rm. Drift detection is structural (serde + validate), not markdown-heuristic.
Three modes:
- Write mode — agent passes a subsystem name and the skill scaffolds a new entry (interview-style) or updates an existing one (targeted edit).
- Read mode — agent passes a subsystem name (or a question like how does X work?) and the skill returns the entry, citing the canonical sources by path.
- Audit mode — agent invokes without a subsystem name and the skill reports drift: dangling pointers, validate failures, missing entries for subsystems detected in the codebase.
Usage
/orb:topology [subsystem-name | question | --audit]
- A subsystem name (or a question naming a subsystem) → write mode if no entry exists, read mode if it does.
--audit (or no argument) → audit mode.
The entry shape
Pointer-only. Each entry references the canonical sources but carries no content of its own — when the authoritative file's docstring updates, the entry stays correct because there's nothing to update.
subsystem: <slug — kebab-case, lowercase, ≥ 5 chars>
canonical_code:
- <path to authoritative implementation>
decision_record:
- <choice id (e.g. 0025) or path to MADR>
operational_doc:
- <path to runbook, SKILL.md, or operational notes>
test_surface:
- <path to test surface>
subsystem and canonical_code are required; the others are optional but expected for any well-documented subsystem.
- All four pointer fields are lists — most subsystems span multiple files. The schema accepts a single-entry list when only one path applies.
subsystem must be slug-shaped (lowercase letters, digits, hyphens; ≥ 5 chars; no leading/trailing/double hyphens) and equal the file stem.
decision_record entries are typically choice ids (0025) — the audit resolves them via resolve_numeric_slug then layout.choice_file. Direct paths also work and are checked as-is.
Write mode
When invoked with a subsystem name and no existing entry:
- Scaffold the yaml. Ask the agent (or the author, if interactive) for each field in turn — keep the prompt tight: subsystem slug → canonical_code paths → decision_record (choice id or path) → operational_doc path → test_surface path.
- Refuse hand-waved pointers. Each path must resolve on disk at write time. If a field is genuinely empty, leave the list out — the schema treats absent optional fields as empty.
- Write the file at
.orbit/topology/<subsystem>.yaml via the Write tool. The canonical writer is invoked at substrate-side (orbit canonicalise after write) to normalise byte form.
- Quote the entry back so the author can confirm before the next invocation.
When invoked with a subsystem name that already has an entry, this is an update — show the current entry, ask which field changed, edit in place. Don't re-interview the whole entry.
Read mode
When invoked with a subsystem name (or a question that resolves to one):
- Resolve the subsystem. The canonical lookup is
Read the file at .orbit/topology/<subsystem>.yaml. If absent, try slug-prefix match (e.g. "how does cards work?" → look for .orbit/topology/cards.yaml).
- Return the entry verbatim then load the cited sources — read the
canonical_code files, the decision_record MADRs, and the test_surface files at minimum. Cite each by path + line number when surfacing facts back.
- Don't extrapolate. If the answer to the agent's question isn't visible in the cited sources, say so. Substrate beats extrapolation — the skill's job is to route to the canonical sources, not to manufacture answers from one of them.
Audit mode
When invoked without a subsystem name (or with --audit):
orbit audit topology
The verb walks the .orbit/topology/ directory and reports drift in these categories (envelope shape stable for parity with spec 2026-05-18-topology-substrate-wires):
| Category | Detected when |
|---|
stale_pointer | An entry's pointer (any of canonical_code / decision_record / operational_doc / test_surface) names a path that no longer exists |
missing_entry | A subsystem detected in the codebase (top-level directory under src/ or crates/) has no entry in .orbit/topology/ |
invalid_field | An entry parses as yaml but fails TopologyEntry::validate (subsystem slug too short, not slug-shaped, or empty canonical_code) |
parse_failed | An entry can't be parsed as TopologyEntry yaml (unknown field, wrong type, missing required) |
audit_topology(...).configured is true iff .orbit/topology/ exists AND contains ≥ 1 entry (populated == configured). Exit code is 0 for all outcomes. Discrimination is via the envelope's topology_drift array — never $?. Symmetric with orbit audit drift's exit-0-even-on-drift contract.
Discipline
- Pointer-only. Entries carry no content of their own. If you find yourself writing prose into a topology yaml, extract it to the canonical source and link to it.
- Substrate beats extrapolation. Before reasoning about how a subsystem works, read its topology entry and load the cited sources. Don't extrapolate from a single file when the topology entry names four others.
- Update at learning moments, not edit moments. The trigger surface is
/orb:distill completion, orbit memory remember --label topology, and orbit session prime's drift surface — not every code edit. The substrate accretes as the codebase does.
- Quality-gate the writes. Not every code change warrants a topology update. Subsystem-level changes do — a new module, a moved authoritative file, a shifted boundary. Single-file fixes do not.
- Prune cheaply. When a subsystem is genuinely gone,
rm .orbit/topology/<subsystem>.yaml. The per-file shape makes the prune trivial; substrate hygiene depends on it actually happening.
After using this skill
If something non-obvious surfaced — a subsystem boundary that was unclear, an investigation pattern worth keeping, or an entry-shape question worth surfacing — write a short memory:
orbit memory remember <key> "<body>" --label topology
The label topology is the substrate seam the learning loop pivots on. When a memory carries this label, orbit memory remember emits a nudge prompting the agent to consider whether the topology substrate itself should be updated — closing the loop between insight and substrate.
Architecture-level analogue framing
/orb:code-investigate makes file-level investigation cheap; /orb:topology makes architecture-level investigation cheap. The two share a design contract — token-frugal default, pointer-only over duplication, reach-as-default rather than reach-on-demand. The agent owns the code at both granularities.