Step 5 · Routing (engineering order, net by net; bounded self-help in place; wall review report before escalation; DRC clean or gap honestly documented)
Installs into .claude/skills of the current project.
Are you the author of Step5 Routing?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/raisoninme-step5-routing)
---
name: step5-routing
description: "Step 5 · Routing (engineering order, net by net; bounded self-help in place; wall review report before escalation; DRC clean or gap honestly documented)"
disable-model-invocation: true
---
# Step 5 · Routing
## Session & state check (before touching anything)
1. One step per session: if this session already did substantive work for another step, stop and ask for a fresh session.
2. Read `docs/flow-state.md` (canonical header line; foreign file → stop and ask). Confirm step 4 is `done`; read the placement deliverables, the critical-signal definitions in `docs/dev-plan.md`, and the BOM. Not satisfied → stop and report.
3. This step already `done` with no issue targeting it → re-run: ask intent first. Already `in-progress` → aborted or concurrent session: ask before proceeding. Marked `rework` (usually cascaded from a placement/schematic fix) → redo what the rework note requires, then wrap up. Marked `parked` (the user accepted an unconverged draft) → **this re-entry IS the un-park**: confirm the user means to resume, then continue the convergence loop from the copper as it stands; when it converges, close the `deferred` issue that carries the gap, citing the run that closed it — nothing else ever retires that entry, and step 7's definition-of-done would otherwise re-present a gap that no longer exists.
4. **Orphan-fix scan**: check `docs/rework-log-*.md` for self-help attempts journaled but never marked adopted/rejected — a previous session died mid-change. Reconcile against the live EDA first (the journal lists touched objects and prior values): roll back or complete the check, then proceed.
5. Issues-table entries with target step = 5 → fix mode.
6. Set step 5 `in-progress`. Rebuild context from disk only.
## Execute
**Adopt-and-audit path**: inherited routing recorded in flow-state (`inherited: <path>`, same-EDA only) is ingested, then audited by this step's own bar — DRC plus all three closing checks below. The bar doesn't move; only the labor does.
**Routing disciplines**
- **Engineering order**: reference planes / return paths and net classes established first, then wide power traces → critical signals (switch nodes / differential pairs / sense lines) → buses → the rest → GND stitching and pours last (pouring last is tool sequencing — return paths were designed first, not last)
- A missing high-level convenience API (autoroute, pour) ≠ the capability doesn't exist: drop to primitive APIs (draw track / place via) and build the routing net by net; exhaust the low-level interface before giving up
- **The EDA's own autorouter is off-limits to the AI.** Autorouted copper bypasses the engineering order and lands un-audited; driving a GUI autorouter by blind clicking is a proven tar pit (hours of zero output in practice). Being stuck is never a reason to reach for it — the sanctioned outlets for stuck are self-help and then the wall procedure, in that order. Copper the USER chooses to produce in the GUI, by whatever means, is their call — it re-enters through DRC + the closing checks + verification like everything else.
- API/bridge discipline (e.g. EasyEDA's websocket bridge — any asynchronous execution channel): after a timeout the EDA-side script may still be running — poll for completion, never re-send; batch scripts must be idempotent (an interrupted run leaves half-finished state)
- Impedance control: compute **electrical length vs. rise time** first (lumped/distributed boundary ≈ t_r·v/6 — a screening estimate, not sign-off); short lumped-region links need matched length at most, and only where a skew budget actually exists
- Critical loops (switch nodes, high dV/dt): shortest path, fewest vias
**The convergence loop (pseudocode)**
```text
route in engineering order
while not (connectivity == 100% and DRC clean):
progress ← harden(routing) # reroute, whole-net re-anchoring (a "disconnected"
# net may attach at ANY point of either same-net
# island — don't grind the ratsnest's nearest
# pair), via/layer moves — everything within the
# current structure; NEVER the EDA's autorouter
if violations/opens still falling: continue
# stuck → bounded self-help, IN PLACE — this is NOT a step-4 rollback:
# the four placement self-checks are a validation procedure, not a step re-entry
option ← next_self_help_candidate()
# move/rotate a part to unlock a route (inductor orientation is the classic) /
# pin remap: another capable MCU pin often dissolves a knot no track rework
# untangles — check target-pin capabilities first (boot/strapping role, wake
# capability, analog channel, peripheral mux — per the target MCU's
# datasheet), then sync ALL carriers: the firmware pin-map carrier (path in
# flow-state) / pinmap.md / schematic / netlist — journal evidence must show
# the dual-source check + reset/strap/wake safety + host tests updated /
# …examples, not the menu: anything inside the four hard lines qualifies
if option exists:
journal(option, objects touched, prior values) # WRITE-AHEAD, before the EDA
# changes (session check #4
# finds orphans by this);
# journal file = docs/rework-log-N.md,
# N = last verification-rounds row + 1
# (the round that will VERIFY this fix)
apply(option); re-run the four placement self-checks
(overlap / out-of-bounds / clearance / keep-out)
if the blocked routing now completes: journal_update(adopted); continue
rollback(option); journal_update(rejected, reason) # exhaustion evidence
continue
if violations have not shrunk for two consecutive passes AND self-help exhausted:
break # → STRUCTURAL WALL confirmed
# wall procedure — invariant: every remedy below is one the AI may NOT take alone;
# that is exactly why the loop stops here (everything autonomous was exhausted above)
evidence ← violation clustering + connectivity plateau + the journal of tried options
candidates ← user-owned remedies, e.g.:
structural: layer-count change / larger outline / assembly change …
OPEN requirement relaxation: lower an interface clock to relax length/impedance
constraints, descope a feature — a documented plan amendment made BEFORE any
implementation; relaxation changes the spec, patching hides from it — the
anti-patching line stands
user-authorized exceptions: swap a do-not-substitute part / amend a budget line
for each candidate assess:
what it closes (mapped to the violation evidence) / what it does NOT close /
rework scope (which steps go `rework`) / cost axes (fab cost, enclosure impact,
product impact, schedule) / residual risk
write the REVIEW REPORT → docs/routing-wall-review.md
present as multiple-choice with a recommendation → ⛔ WAIT for the user
on the user's decision:
structural / cross-step remedy → issues entry (source = step 5, target = the
owning step — usually 4, 3 if the schematic is touched; status = open,
severity, approval noted) → new session, that step's command (its fix mode executes
the change and cascades `rework` back through here)
requirement relaxation → amend requirements.md / dev-plan.md FIRST,
then resume the loop under the relaxed constraint
keep grinding / finish in GUI / accept draft → the capability-gap choices below
```
**Local bounds (the four hard lines — inside them self-help is autonomous, beyond them only the user decides):**
- Board outline, component side, assembly mode, or any enclosure-level decision
- Layer-count change
- Parts flagged "do-not-substitute" in the BOM
- The top-priority metric's budget lines
**Three closing checks** (mandatory beyond DRC, after convergence):
1. Re-check trace width per net against actual current (IPC-2221 as a first screen; for tight margins use IPC-2152 with the fab's actual stackup — copper weight, inner/outer layer, ambient) — some tools' auto-repair/reconnect functions silently drop power nets to a default width
2. Netlist consistency: when the EDA reports a mismatch, read the **direction of the diff** first; if it wants to change exactly what you just fixed, its snapshot is stale — never apply blindly
3. Platform ordering discipline audit (EasyEDA: delete → vias → tracks → pours)
**Done criteria**: **`done` means 100% connectivity + DRC clean against the frozen fab profile (`docs/fab-profile.md`) — nothing less.** DRC clean against generic rules is not clean — it's a bet. A capability gap (violations scattered, connectivity still climbing — more effort can close it; no wall confirmed) goes to the user as:
- **keep hardening** → step 5 stays `in-progress`
- **finish in the GUI** → set `rework` with the note "manual GUI finishing required"; after the manual pass, re-enter this command to re-run DRC + the closing checks and mark `done`
- **accept the draft as-is** → set step 5 **`parked`** and record a `deferred` issue (target `5`; severity filled honestly — a routing gap is usually `nondeferrable`, and `deferred` is legal here ONLY because the flow is parked and not advancing: the declared exception to the defer prohibition) carrying the gap and the user's sign-off; the flow deliberately stops here — not fab-ready — and status will say so plainly (evidence gathered on unconverged copper is invalidated by every later routing change, and step 7's definition of done requires DRC clean anyway)
A confirmed structural wall is handled by the wall procedure above — never grind past it, never park it silently.
## Fix mode (entries with target step = 5)
Fix only the listed issues; after changing tracks, re-run DRC + the affected closing checks. Append to `docs/rework-log-N.md` (symptom / root cause / fix; N = last verification round + 1) → set the issue `fixed-pending-verify`, **citing the rework-log entry in the same edit** (a bare status flip looks like tampering to the guard hook). Route the user: **step6-verify** (Claude Code: `/boardless-pcb:step6-verify`) in a fresh session.
## Wrap up
⛔ **Design-delta acknowledgement (per-item accept / reject)**: present every adopted self-help change (part moves/rotations, pin remaps with their carrier syncs) — the loop ran autonomously by design; the human trail catches up here. A **rejected** item is rolled back using its journal entry's prior values, its dependent routing reverted, the option logged as rejected (never retried), and the convergence loop re-entered to close the gap another way — rejection ends the fix, not the requirement.
Mark step 5 `done` only on 100% connectivity + DRC clean + closing checks; otherwise set the status per the user's choice above. Tell the user: **new session, run **step6-verify** (Claude Code: `/boardless-pcb:step6-verify`)** (its gate opens only once step 5 is `done`).