Skip to content

Fabric switch reader: RouterOS response → typed lane readings - #11525

Merged
briansrls merged 3 commits into
mainfrom
session/calm-badger-275-switch-read
Sep 17, 2026
Merged

briansrls merged 3 commits into
mainfrom
session/calm-badger-275-switch-read

Conversation

@briansrls

@briansrls briansrls commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

First code increment of the modeled switch-convergence path (design in #11524). This is the read path's functional core: it turns a RouterOS /rest/interface/ethernet response into the Crs812LaneReading values gunbc.spark.fabric_switch_assessment was written to receive. Today fabric_switch_subject() passes readings: [], so every lane resolves to unknown; this is the producer that closes that gap on the read side.

What's here

  • extdeps.mikrotik.crs812 — the inverse wire parsers (DESIGN §4, one grammar both directions): crs812_lane_speed_from_wire, crs812_fec_mode_from_wire, crs812_wire_bool, and the Crs812EthernetWire record. Each is partial and fail-closed: a wire value the corpus doesn't model decodes to an explicit Unmodelled arm carrying the string, never a silent default.
  • gunbc.spark.fabric_switch_read — the workflow-layer decode: filters the GET response to our fabric legs (by the RouterOS comment the switch carries), and turns each per-lane wire record into either a Crs812LaneReading or a located refusal naming the interface, field, and raw wire that didn't parse.
  • Witness — 6 claims, green by execution against the real response captured from gunbc-fabric-switch (192.168.1.240) on 2026-09-17: the 8 legs decode to 50G/fec91/enabled, a non-fabric interface is filtered, an unmodelled speed refuses at speed, an unmodelled FEC refuses at fec-mode, a disabled lane reads not-enabled.

Scope boundaries (deliberate)

  • No live transport. Fetching the JSON over the switch's basic-auth REST is blocked on the same capability extdeps.bmc.http declared as debt (redfish_http_hardwired_transport_dissolution_trigger: the shared transport rest machinery doesn't yet realize transport-level basic auth). So this is the pure decode — wire records in, typed readings out — fully testable with no network. The live fetch lands beside it on the BMC precedent. A pure decode is also the right seam: the same function serves a live read and a replayed fixture without branching.
  • No autoneg axis yet. The reading type stays as-is (speed/fec/enabled); adding the autoneg dimension (gap G1) is a separate change to the load-bearing assessment type.
  • No converge apply. Deferred until the hardware links at 100G (§4d — its FEC/autoneg specifics are inferred, not witnessed).

🤖 Generated with Claude Code

@gunbai-bot gunbai-bot Bot changed the title MikroTik CRS812-8DS-2DQ-2DDQ-RM convergence Fabric switch reader: RouterOS response → typed lane readings Sep 17, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 17, 2026 16:33
…ty comment

review 67287 (claude/opus), all four findings:

- §3c dangling reader: crs812_fabric_lane_read_outcomes was consumed only
  by its own witness. The reviewer is right that the stated BMC-transport
  frontier blocks the FETCH, not the JOIN -- turning LaneReadOk outcomes
  into the List<Crs812LaneReading> crs812_switch_subject already takes is
  pure and network-free. Landed that chain: crs812_fabric_read (the join,
  fail-closed -- one bad lane refuses the whole read) and
  fabric_switch_subject_from_wire, which builds the real Crs812SwitchSubject
  inspect_fabric_switch consumes. The ONLY declared frontier is now that
  terminal function, whose trigger genuinely is the live fetch (BMC
  basic-auth transport debt), stated on it.

- §3c unread fields: dropped auto_negotiation and running from
  Crs812EthernetWire -- no fold read them. They return with their consumers
  (autoneg axis G1, live link-state G3), not before.

- §4b rung honesty: the witness comment claimed the decode executes "over
  the captured bytes". There are no captured bytes -- the fixture is
  hand-authored, transcribed from the 2026-09-17 response. Reworded to say
  the records are supplied inputs and the real JSON->wire producer is the
  declared frontier; the claim discriminates the DECODE, not the fetch.

- predicate-for-a-test (advisory): crs812_lane_read_outcome_refused now has
  a production consumer -- crs812_fabric_read folds it -- rather than only
  the witness.

Evidence: claim_batch, 9 claims green, including the join produces eight
readings, one bad lane refuses the whole read, and the frontier builds a
subject.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

All four findings in review 67287 addressed in the latest commit; 9 claims green by execution.

1. §3c dangling reader — fixed by landing the join. You're exactly right: the stated BMC-transport frontier blocks the fetch, not the join, and turning LaneReadOk outcomes into the List<Crs812LaneReading> that crs812_switch_subject already takes is pure and network-free. Landed that chain:

  • crs812_fabric_read — the join, fail-closed at the read grain (one unparseable lane refuses the whole read rather than handing the assessment seven readings where the switch reported eight).
  • fabric_switch_subject_from_wire — builds the real Crs812SwitchSubject that inspect_fabric_switch consumes.

So crs812_fabric_lane_read_outcomes is now consumed by the join, the join by the subject-builder, and the only declared frontier is that terminal function — whose trigger genuinely is the live fetch (the BMC basic-auth transport debt), stated on it.

2. §3c unread fields — dropped. auto_negotiation and running are gone from Crs812EthernetWire; no fold read them. They return with their consumers (autoneg axis G1, live link-state G3), not before.

3. §4b rung honesty — comment fixed. You caught the real thing: the fixture is hand-authored (transcribed from the 2026-09-17 response), so "executing over the captured bytes" was rung inflation. Reworded — the records are supplied inputs, the claim discriminates the decode not the fetch, and the inhabitance pairing (a real JSON→wire producer emitting this shape) lands with that fetch.

4. Predicate-for-a-test (advisory) — resolved by #1. crs812_lane_read_outcome_refused now has a production consumer: crs812_fabric_read folds it.

New discriminating claims: the join produces eight readings for the subject, one bad lane refuses the whole read, and the frontier builds a subject from a clean read. Thanks — the dangling-reader call was the right one; the join was pure all along and I'd left it on the wrong side of the frontier.

@briansrls
briansrls added this pull request to the merge queue Sep 17, 2026
Merged via the queue into main with commit e26bf3a Sep 17, 2026
4 checks passed
@briansrls
briansrls deleted the session/calm-badger-275-switch-read branch September 17, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant