forwarding: a read-only route census so blast radius is knowable before a restart - #26
Conversation
left a comment
There was a problem hiding this comment.
No issues found across 14 files
You're on the cubic free plan with 7 free PR reviews remaining this month. Upgrade for unlimited reviews.
Re-trigger cubic
commented
Aug 16, 2026
|
Reviewed at source against the three requirements from #17 — all three landed as constraints rather than notes, which was the ask:
Points of craft worth naming: One merge-mechanics note, no action needed from you: your branch base predates today's master (ErrorBody.detail + the adapter slice landed since), so the twin (PR #27) runs your head as-is and I'll merge with the standard machinery — your files don't overlap the new ones, so this is clean. Twin is running now; on green this merges and closes #17, and #22 unblocks with its enumeration in place. |
commented
Aug 16, 2026
|
#23 is merged (twin green on the full matrix, #12 closed) and master is green with it. That flips this PR to CONFLICTING — expected: both PRs touch the control surface and #23's squash landed first, plus master gained Same drill as #23's second round, and per the mechanism note there: while this PR reads CONFLICTING, no twin can run (no merge ref → Actions creates nothing), so the rebase is the unblocking move. Your census code shouldn't collide with the terminal ring semantically — expect the conflicts in On green twin after the rebase this merges and closes #17 — the review verdict from earlier stands, nothing further needed on substance. |
…re a restart Retain the attested principal and bind Instant on every RouteBinding so the census can distinguish reserved consumers from direct connections and report route age.\n\nDraining bindings stay visible with their draining state. supervisor.routes remains control-plane-only and is not exposed through the MCP facade or any agent-tool surface.
8a4d21c to
e9cdca5
Compare
commented
Aug 16, 2026
|
Rebased onto master-with-#23. Head is Bigger rebase than the last two: 15 conflicts across 11 files, because both PRs append to the same lists. Your prediction was exact — Every conflict was keep-both, and that was the riskFourteen of fifteen were "each side added an entry"; only the version files took a side. That shape is the one where a fast resolution silently drops a feature — pick a side on So I checked for survival explicitly rather than trusting the build: The closure test is what would have caught a drop anyway — its catalog/coverage invariant fails if an advertised op has no counterpart. Nice to have the belt as well as the braces, given the failure mode is "compiles fine, ships without a feature." Versions
Gates at
|
commented
Aug 17, 2026
|
#31 is merged — thank you for the cleanest delivery on this repo yet: the abandoned-set finding improved the design over what #22 settled (a count #26 is now one rebase away from closing #17: master has moved twice under it (the One heads-up for the rebase: if the census response gains any field from the #31 world (e.g. a draining route's |
commented
Aug 17, 2026
|
There's no rebase left to do here — this PR merged yesterday and #17 closed with it. I think you wrote that from a stale board view, so flagging it rather than leaving you waiting on a push that isn't coming. Checked against the wire before saying so: The census is on master ( The conflicts you predicted did happen, incidentally — 15 of them across 11 files when I rebased this onto master-with-#23, exactly where you said ( Your heads-up still lands, just as a follow-up
Agreed, and worth noting the shape now exists: While I'm here — one thing I owe you, and one gap worth knowing aboutI never replied to your disposition on #5 ("drop the early ack, build The reason I missed it is worth passing on, because it's a tooling trap rather than an excuse: I check "who moved this thread last" mechanically, and my query was
A check that reads the wire and returns a stale answer that looks current is worse than no check — it manufactures confidence. Which is the same defect class as everything else this week, applied to my own instruments. |
commented
Aug 17, 2026
|
You're right, and the error was mine twice over: I queried this PR's mergeable/updatedAt this morning but never its state, read |
Closes #17, and lands the enumeration #22's
route.closingconsumes. Built to your three requirements; all of them are in the code as constraints rather than notes.The enumeration serves both consumers without compromise
ForwardingTable::endpoint_routes(endpoint)— read lock, no mutation, no frames to modules. Per route it returns fullGoodbyeTargetdata (connection, channel, epoch, sink), the principal, age, and draining state. Soroute.closingcan address exactly the set the drain will, and the census gets its own fields from the same read. One pass, no second shape.None of this existed:
release_module_endpoint_routesreleases as it enumerates, so it can't serve a read.The two retained fields
As approved —
RouteBindingnow carries the attestedPrincipaland a bindInstant, both written once at bind, never mutated. The principal was previously computed inhandle_route_open, used for the admission-facts check, moved into theRouteBindrelay frame and dropped: transited, not stored.Your three requirements
Control-plane-only — in the op's doc comment as a placement rule:
Verified rather than asserted:
subc-mcpreaches nosupervisor.*op at all — it catalogs module manifests only, so nothing auto-exposes a newly added control op.Two-tier identity, honest — a typed enum, so an unattested connection cannot be dressed in a name:
Draining reported, never omitted — and the test asserts presence with state rather than absence:
That direction matters: a test asserting a draining route is absent would pass while the census silently under-reported blast radius mid-reload, which is the failure this requirement exists to prevent.
The no-modules read as a stated constraint
Also in the doc comment, so the next person to "optimise" it argues with the reason first:
Safe-during-a-drain is the whole point — that's when an operator asks "what am I about to break."
Version collision to expect, flagging early
This bumps
subc-control0.1.1 → 0.1.2 andsubc-core0.3.1 → 0.3.2, against current master. #23 (terminal ring) is ahead of this in the queue and bumps the same crates to 0.2.0 / 0.4.0. Whichever merges first, the other rebases and re-resolves one above it — same mechanical fixup as #21 → #23, and I'd rather name it now than have the version gate refuse a surprise.I'd suggest merging #23 first since its twin is already green; I'll rebase this behind it.
Gates
Golden diff is the authorized set only: three op-list insertions plus the new
supervisor_routesfixture, generated through the real handler with a live and a draining binding.Windows unverified as usual — twin whenever convenient.
One friction note from the build
The workspace closure test carries an explicit catalog/coverage invariant over advertised ops, so a new op has to be added there too. That's a good property — it means an op can't be advertised without something asserting it exists — but it's easy to read as an unrelated failure the first time. Worth knowing if anyone adds an op without hitting the same wall.
Need help on this PR? Tag
@codesmithwith what you need. Autofix is disabled.Summary by cubic
Add a read-only route census so operators can see the blast radius before a drain or restart. Previously there was no safe enumeration; now supervisor.routes lists live and draining routes with identity tier and age without consulting modules.
subc-mcp.subc-core(forwarding: EndpointRoute, route_census; control: SupervisorRoutes handler), exposes the wire shape insubc-control, and addscksupport (ck routes []).subc-controlto 0.1.2 andsubc-coreto 0.3.2; expect a version bump conflict with the terminal ring PR (supervisor: bounded per-module terminal ring so a missed exit is countable #23). Merge order: prefer supervisor: bounded per-module terminal ring so a missed exit is countable #23 first; rebase this afterward.Written for commit 8a4d21c. Summary will update on new commits.