Skip to content

row 155 (L1#1): the llm door keeps a retried unit for the kernel's next attempt, and ends a final one - #890

Open
MattJackson wants to merge 132 commits into
lane-p3-plane-cut-finalfrom
lane-p3-llm-retry
Open

MattJackson wants to merge 132 commits into
lane-p3-plane-cut-finalfrom
lane-p3-llm-retry

Conversation

@MattJackson

Copy link
Copy Markdown
Collaborator

Row 155, row-159 audit plane-llm L1#1 (HIGH). Stacked on #840 (PIECE_CUT/PIECE_FINAL).

Before: the door ended every done unit, VERDICT_RETRY included. The kernel's next attempt then found no unit, so no plane-judged failover ever reached a second member.

Now: the door keeps a unit whose done answer carries VERDICT_RETRY, unless the kernel marked the answer PIECE_FINAL; in that case the unit ends. A piece whose flags the contract refuses (check_piece_in) is a FAULT.

1.5.5 served the next member (v1.5.5 ingress/tests test_real_failover_serves_second_member_after_first_5xx).

RED-able (busbar-plane-llm/tests/door_retry.rs):

  • a_retry_verdict_keeps_the_unit_and_the_failover_reaches_the_next_member
  • a_final_answer_ends_the_unit_whatever_its_verdict
  • a_final_mark_off_the_status_piece_is_a_fault

…te seal (K2-H3)

The caller-facing ask-state seal is the plane's own: its crate seals the
payload over the host's `sign` (ARCHITECT Q-L3B-ASK). The kernel still
carried a dead copy, with AskState, Sealer, Rejected, digest_arguments and
the two MAC domains, spelled with the plane token escaped. Nothing called it.

Core keeps the spent-approval ledger, DEFAULT_TTL_SECS and nonce. The
copy's tests (askstate_tests.rs) go with it, and the signing_secret docs no
longer name the deleted sealer.

RED: approvals_tests the_kernel_holds_no_plane_named_seal_domain scans the
kernel's sources for the escaped plane token and the seal's domain segment.
… 117 -> 116

Deleting the kernel's dead ask-state seal (K2-H3) drained one secret-instance
hit from busbar-kernel, leaving a law0-slack finding that raised the
kind-isolation:law0 figure 18 -> 19 on both kind-isolation and
kind-isolation-ship. Lower the ceiling in the commit that drained it.
Proved with busbar-release dev cargo xtask gate kind-isolation and
kind-isolation-ship: law0 back to 18 (base figure).
Deleting the kernel's dead ask-state seal (K2-H3) drains four plane hits from
busbar-kernel: the two crate::mcp::roots doc links and the two \x6dcp seal
domains (the decoded scanner reads them as mcp). The re-armed ledger (#725)
pinned the row at predev's 1175, so the drain read as 4 hits of law0 slack
(figure 29 -> 33 on kind-isolation and kind-isolation-ship).

Not proved on Latchkey: the run budget is spent (RUN_CAP); reasoned from the
CI verdict and the deleted source, and the PR's CI is the proof.
The kind-isolation:law0 row this branch arms reported law0-slack
busbar-kernel × plane 1169 hit(s) under a ceiling of 1171; the ledger
row now sits at the measured value (Law 9). Not proved on Latchkey:
the run budget is spent (RUN_CAP), so the PR's CI is the proof.
qa/kind-isolation.toml: two busbar-kernel [[law0]] rows conflicted.
- instance:secret: predev lowered it 117 -> 115 (R-FIX3); this branch
  lowered it by the dead ask-state seal. Merged tree measures 114.
- plane: predev lowered it 1175 -> 1173 (#570); this branch lowered it by
  the seal's two crate::mcp::roots doc links and two \x6dcp domains.
  Merged tree measures 1169.
Both rows are pinned at the merged measure, both reasons kept in the cite
(Law 9: the ceiling ratchets down to today's number).
…o-socket pin armed (E7)

The inbound listener's accept/serve loop (hyper-util's auto builder, graceful shutdown, the body
read bounds, the accept backoff and the connection-placement balancer) moves verbatim from
busbar-kernel/src/tls.rs into the composition root, crates/busbar/src/root/listener.rs. The
connector binds every listener (Listening::bind_stream) and hands each admitted stream up; the
accept-source trait (Admits, Admitted) moves to busbar-core-connector's listen.rs beside the
listener that implements it. tls.rs keeps read_pem for its outbound callers. The kernel drops
tokio-util. BUSBAR-1.6.0.md l.475-483 (INBOUND-LISTEN: the root's stream hand-up) and the ARCHITECT
ruling on #710 (2026-10-10). This is #741's change on current predev; it supersedes #741.

Tests move with the code: the kernel's tls_tests.rs and busbar/tests/tls_listener_h2.rs become
root/tests/listener_tests.rs and listener_h2_tests.rs; the connector's TLS-listener rows join them
(their scratch PEM name keeps predev's unique-per-call suffix).

Ledgers: law0 busbar-kernel x transport 285 -> 268 and busbar x transport 208 -> 225 (the move, total
flat, per the #710 ruling); population floor 947 -> 948 (root/listener.rs is a new file; tls.rs stays).

E7: crates/busbar-kernel/tests/no_socket.rs holds busbar-kernel to a drain-only pin of every
(file, needle) naming a socket, resolver or HTTP client/server stack, and every manifest ask for
one; tls.rs is not in it. A new offender is RED, a drained pin left standing is RED, and the RED
arm plants a dial, a resolver and a server stack and sees each.
…me itself

busbar-kernel/src/net_guard.rs was a glob re-export of the egress unit's guard
(busbar_kernel_egress::trust::net) plus SystemResolver, a getaddrinfo on a thread of its own: the
one piece of the guard that touched the network. Deleted.

- The kernel's call sites name the guard in its homes: the pure host atoms from busbar_contract::net
  (observability, config_validate, plane_host/guard), the pre-dial guard from
  busbar_kernel_egress::trust::net (plane_host/egress, egress/duplex_ws, config_validate's
  ssrf_blocked_host re-export). Same items, same answers.
- The name lookup is the connector's. busbar_core_connector::process::SystemNames is the deleted
  SystemResolver, verbatim, implementing the unit's Resolver seam. The root installs it behind the
  egress-trust capability (GuardedEgressTrust's third field) with the guard and the TLS wrap, at the
  same boot step. The kernel's two resolve-then-pin dials (the plane-host egress open and the
  duplex_ws dial) ask plane_host::egress_trust::InstalledResolver, which reads the capability. With
  no guarded capability, a production kernel refuses the name (fail closed); a test build resolves
  through egress::fixtures::system_names, the same body, in test scaffolding. No new static.
- The connector reads split_url from the unit instead of through the shim, and depends on
  busbar-kernel-egress (kind-isolation [[dep]] row, cleanliness -> kernel, allowed). core-oauth2
  reads parse_url from busbar_contract::net. busbar-a2a and busbar-voice (legacy, deleted by #787 and
  #503) reach the unit through the kernel's existing busbar_kernel::proxy::egress_unit re-export, so
  no new legacy edge.
- Tests: the shim suites' four rows the unit's suite did not already hold move to
  busbar-kernel-egress trust/tests/net_tests.rs; the other 32 were duplicates of it.
  egress_trust_tests gains the_guarded_seam_resolves_by_the_resolver_behind_it. The root's
  net_guard_one_judge compares config_validate's re-exports with the unit. no_socket strikes
  ("src/net_guard.rs", "lookup_host").
- Population floor 948 -> 947 (one non-test file deleted, reviewed).
…ed (audit plane-decisions#1, #2)

THE DESIGN section 2, the decisions bullet: "a request routes by its model; one configured model
and none named is the default (byte-identical); more than one and none named is 400; an unknown
model is 404. `upstream_model` rewrites only the top-level model value, by span splice, when it is
set and differs; otherwise the body passes through." DECISIONS D8b (BUSBAR-1.6.0.md:4798, :4802)
lifts the exactly-one-model mount and adds /model to REQUEST_PTRS.

plane-decisions#1: the snapshot claimed POST /v1/systemone only when exactly one model was
configured, and arrive routed every request over that one model whatever its body named. Now the
claim is published whenever at least one model is configured (none: nothing is claimed, and the
kernel's unclaimed-route 404 stands byte for byte), and arrive reads the top-level `model`
(driven::route_model): the named model routes ROUTE_DIRECT; one configured and none named is the
default; several and none named is a refused arrival at 400; a name no model has is 404; a `model`
that is not a string is 400. The refusals render in jev's error shape through the refusal slot.
The door keeps every configured model of the latest generation (name -> upstream_model) in place
of the single routed name.

plane-decisions#2: `decisions.models.<m>.upstream_model` was read nowhere. The routed model's
upstream_model is kept on the unit at arrive, and the caller's body bound for the far end has its
top-level `model` value alone replaced (driven::spliced) when the two differ; every other byte is
the caller's.

The jev rig gains a second boot with two models (one with upstream_model) and three checks:
models.unnamed-400, models.unknown-404, models.upstream-model; the plane's conformance inputs
expect the claim on the two-model refresh.

RED: tests/door.rs every_generation_with_a_model_claims_systemone,
a_request_routes_by_its_model, upstream_model_is_spliced_into_the_top_level_model (over the door's
ABI); src/tests/driven.rs one_or_more_models_mount_the_claim.
…in family decision (audit plane-decisions#4, #5)

THE DESIGN section 7, owner money rulings 2026-09-28: "The decisions plane bills one `decision`
per successful, settled answer from every provider; its card prices `decision`, `input_tokens` and
`output_tokens` (family `decision`, all three required, 0 = free); the hosted provider keeps
1.5.5's `/usage/units` as the decision count (DECISIONS D9, 2026-09-30)." DECISIONS Q1-5
(BUSBAR-1.6.0.md:4780): the usage pointers /usage/units, /usage/input_tokens and
/usage/output_tokens are dialect data. Finding 395 is kept (:4690): a usage member present but not
a whole count is located, never dropped.

plane-decisions#4: the decision count was read with no regard to the status (a 500 carrying
/usage/units billed decisions), a success with no count billed no decision at all, and a count
that was negative, fractional, a string or past i64::MAX was dropped silently. Now one success
rule (FarEndReading::success: a 2xx status and no /error member, a null one being none) gates every
count: a non-success bills nothing; a success bills its whole /usage/units, or one decision when it
reports none, and its request fee; a usage member that is present but not a whole count fails the
far end's last piece (Outcome::Failed, the plane fault the kernel ends the unit on) naming the
member, never a silent 0.

plane-decisions#5: the tail declared `decision` and the fee unit only. It now declares
`input_tokens` and `output_tokens` in family `decision`, appended after the fee unit (the fee
keeps index 1), and a success reports each where its answer carries a whole count. The jev rig's
cards price both at 0, and the docs' declared-class list names them.

RED: tests/door.rs a_success_with_no_count_bills_one_decision, a_non_success_bills_nothing,
a_success_with_an_unreadable_count_fails_loudly,
the_tokens_a_success_reports_are_billed_in_family_decision (over the door's ABI);
src/tests/driven.rs a_success_bills_one_decision_or_the_count_it_reports,
a_non_success_bills_nothing, a_usage_member_that_is_not_a_whole_count_fails_loudly,
a_success_bills_the_tokens_it_reports, the_tail_names_the_decision_class_at_its_index.
…icted, and an answer is read as it passes (audit plane-decisions#6, #8)

THE DESIGN section 11.2 (the shared mechanism): "memory a plugin returns is plugin-owned and valid
until that plugin's next refresh generation; no allocation and no blocking on the hot path". And
section 7: a settled success's count is billed, so a live unit's reading must not be lost.

plane-decisions#6: arrive kept state for every claimed unit, but only a unit's last far-end piece
removed it: a refused unit (rate limit, budget, grant) or a cancelled one stayed until eviction,
and past 4096 the smallest key was popped, which in steady state was a live unit (its ATTEMPT or
its reading lost, so its body was held or its count unbilled). `cancel` dropped nothing and
answered CANCEL_ABORTED even after far-end bytes were relayed. Now `refusal` drops its unit
(RefusalIn.unit); each piece records its ticket and `cancel` drops the unit on the cancelled
ticket, answering CANCEL_ABORTED before the far end answered and CANCEL_OK_PARTIAL after; at
MAX_UNITS a new arrival is refused at 503 about the entry it routed over (the ABI's refused-arrival
rule 6, before anything is charged) and no live unit is dropped. A unit that arrived and never
crossed a piece while MAX_UNITS arrivals followed is reclaimed, so an arrival the kernel never
started cannot leave the instance refusing every arrival for good.

plane-decisions#8: every far-end piece was appended to a growing whole-answer buffer (no bound)
and copied again into the unit's owed bytes before it was written; the caller's fields were a
vector of vectors per arrival. Now the answer is read as it passes (FarEndReading scans the JSON
structure in fixed space for /error and the three /usage counts, wherever the pieces split it),
a piece is written straight into the host's reply buffer and only what does not fit is kept for
the `more` re-calls, and the caller's relayed fields are one buffer sized once per unit. Nothing
caps the answer's size (#41: never a size-based refusal).

RED: tests/door.rs a_refused_unit_is_dropped_and_a_live_unit_kept,
a_cancelled_unit_is_dropped_and_a_live_unit_kept,
a_unit_cancelled_after_its_far_end_answered_is_cut_partway,
past_the_cap_an_arrival_is_refused_and_no_live_unit_dropped (over the door's ABI);
tests/door_alloc.rs relaying_an_answer_piece_by_piece_allocates_nothing; src/tests/driven.rs
the_reading_is_the_pointers_reading_wherever_the_pieces_split.
llm codec: event-stream drain linearity counted in work units, not timed (quarantined flake)
$ llm codec: image answers record their token counts and bill none, as in 1.5.5
llm codec: no per-thread or process-global state in the entropy seam and the transcription boundary (row-159 L1#4, L2#6, L3#1)
…g_self_convention, row 132)

clippy -D warnings refused `fn into_host(&mut self, ..)`: an into_* method takes self by value. The
rig hands one datagram to the host; deliver says so and names no conversion. Every call site is
renamed; nothing else changes.
…to lane-webrtc-terminate-dial; the dial tests' calls renamed with it
…brtc-terminate-port; the port tests' calls renamed with it
row 132 (piece 3a): one datagram port, associations found by check user name then path; the port on the reactor
row 155: the door path serves budget on_exhaust: downgrade as 1.5.5 did ($, ahead of #824)
… beside its units and the kernel counts it

The codec's USAGE_TAP_FAULT_REPORTER and USAGE_TAP_FAULT_LATCH statics, their install and report
ports, and the hot vtable's tap_fault_latch service are gone. OperationHandler::extract_usage returns
the fault (UsageTapFault: decode, bad_json, unknown_protocol) as data; the llm door carries it on
OnPieceOut::tap_fault (laid in the padding after fault, pre-tag v1, size unchanged), once per answer;
the kernel's route driver hands it to the steps, and the root counts it on
busbar_billing_tap_decode_fail_total{protocol,reason} under the unit's dialect and warns once per
(protocol, reason).

qa/contract-stateless.toml 44 -> 39 rows (codec.rs USAGE_TAP_FAULT_LATCH, USAGE_TAP_FAULT_REPORTER;
services.rs KEPT, FILLING, once-cell OnceLock). qa/abi-freeze.toml hot 6224 -> 6100.
…he kernel's count too

The default build serves the llm plane through busbar-llm's engine, which drives the plane's Relay
itself: its stream end now counts end.tap_fault through busbar_kernel::handlers::usage_tap_fault
under the relay's ingress dialect, the same increment the contract latch made before. The import
rides the engine's existing busbar_kernel::handlers line (ports-only count unchanged).
…T_NONE by path; the kernel test sits mid-file)
@MattJackson

Copy link
Copy Markdown
Collaborator Author

Rule 20 note from #1030/#1031 (row 155): disjoint hunks in plane_door.rs (Answer.tap_fault, to_caller, deliver; far_end's ReplyCtx gains translate_cap). The import list and the end of route_tests.rs were left to you, and test merges are clean.

…ther value as reason=unknown, and a door's fault reaches the kernel counter (RED)

Coordinator conditions on the #1030 seam: OnPieceOut::tap_fault is 0 = none plus the named reasons;
check_on_piece no longer refuses a value past the vocabulary (only a fault on a non-READY answer),
and UsageTapFault::reason_of reads any other value as reason="unknown", counted and warned once,
never ignored and never read as none. RED: plane_driver_cases' a_usage_tap_fault_the_door_returns_
reaches_the_kernel_counter drives the kernel double and the linked and dropped test plane through
the one loop: a door answering a bad_json fault, and one answering an unknown byte, each reach
busbar_billing_tap_decode_fail_total once per unit under their reason.
…hrough busbar_kernel::handlers::usage_tap_fault, the same kernel counter path; merged origin/predev
row 159: stdio serve mode drains the journal lane and plane-record write-behind before exit (audit busbar-src #1, HIGH)
…t (the call names it by path); merged origin/predev
row 88: the suite steps build the example cdylibs their tests load by name, always (stacked on #831)
…e: both sides kept in .ci/predev.yaml

#924's test-gated check (the example cdylibs built by name) beside #909's absolute move
(q128-audit requires git-history). test-gated runs absolute like every check of this move: no
baseline: target, dev holds no suites to be measured against.
row 155: the usage-tap fault latch leaves the contract; the door returns the fault beside its units and the kernel counts it
row 163: the predev→dev move is judged absolute and from predev's own oracle pin (dev holds no xtask, ledgers, pin or golden)
row 163: bin/oracle fetches the pinned judge (busbar-release's published busbar-oracle at the base pin's sha256, .sig verified) or refuses: no judge
…ance.rs, the one file a plugin's tests may name the loader from

kind-isolation:test-deps grants a plugin crate its dev-edge on busbar-plugin-loader only when
every source file that names the loader as code is its tests/conformance.rs (the both-ways
witness rule, xtask kind_isolation.rs conformance_witness_edges). #890's tests/door_retry.rs named
the loader too, so the edge stopped being granted and read as an unlisted plane -> plugin-tooling
test edge. The retry tests move verbatim into tests/conformance.rs as `mod door_units`; no ledger
row is raised.
MattJackson added a commit that referenced this pull request Oct 14, 2026
…d cut) live in tests/conformance.rs as mod door_units (kind isolation's witness rule)

This branch has not been deployed

No deployments
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