Skip to content

row 155: the codec's entropy and wall clock leave the contract; a codec is handed a CodecHost (stacked on #974) - #1028

Draft
MattJackson wants to merge 5 commits into
predevfrom
lane-p3-llm-codec-host-services
Draft

MattJackson wants to merge 5 commits into
predevfrom
lane-p3-llm-codec-host-services

Conversation

@MattJackson

Copy link
Copy Markdown
Collaborator

Row 155 (lane-p3-llm), coordinator/contract-ABI ruling. busbar-contract is the ABI's single home of shapes and holds no state (BUSBAR-1.6.0.md Part 4; spec l.3701: "Services are reached only through the host tables handed at open"; l.4589: no static/OnceLock in the contract). This PR removes two of the codec host-service statics from crates/busbar-contract/src/codec.rs: ENTROPY_SOURCE and WALL_CLOCK.

STACKED ON #974 (DRAFT until #974 lands, rule 19). #974 rewrites the same DialectCodec error-head hunk this PR threads the host through (attach_error_response_headers → error_response_fields), so this branch carries #974's head. After #974 lands: retarget is already predev; merge origin/predev, push once, undraft.

What

  • The contract keeps only the shape: codec::CodecHost (fill_entropy, wall_clock_now). The free ports (install_entropy_source, fill_entropy, install_wall_clock, wall_clock_now) and their two statics are deleted.
  • Every codec entry point that mints an id or stamps a time now takes a borrowed &dyn CodecHost, passed down the codec call graph:
    • OperationHandler: read_response, read_response_value, extract_usage
    • IrHandle: write_egress_request, write_ingress_response(_bytes), wrap_buffered_as_stream
    • DialectCodec: probe_body, write_error, write_response_exception, write_error_frame, error_response_fields, ingress_response_request_id
    • StreamTranslator: feed, finish, terminal_error_frame
    • the plane's ProtocolReader/ProtocolWriter and the exchange layer (refuse, reply, relay, whole, attempt, probe)
    • synth_rng::fill_entropy
  • Who hands which host:
    • Linked engine (busbar-llm) and the kernel's error path: busbar_kernel::proto::CodecHostServices, which is the OS CSPRNG and store::now. These are exactly the sources the kernel armed before.
    • The llm door: DoorHost, built over the instance's own Services handed at open (random.fill, chunked at MAX_RANDOM_FILL, and clock.now). There is no global.
    • The Plane-trait surface (plane.rs): the context's clock and no random source. A plane holds none, and nothing drives this surface in production.
  • Hot ABI: the entropy_fill/wall_clock slots are now served by the kernel's vtable. The contract's SERVICES no longer answers them, and arm no longer installs them. The latch and cap slots are unchanged.
  • a2a/voice test clocks read the system clock directly. That is the same reading store::now gives, and it adds no busbar_kernel:: line (ports-only ceilings unchanged).

Bytes unchanged

The values and the draws are the same. Each draw is one host call (synth_rng holds no pool since #869). Ids keep their prefix, shape and alphabet. created falls back to the host clock as before. The kernel's entropy and clock are the same functions it armed before.

RED

  1. CodecHost's compile_fail doctests: busbar_contract::codec::fill_entropy(..) / wall_clock_now() no longer compile, so a codec cannot reach the host without the handle.
  2. qa/contract-stateless.toml: struck the codec.rs contract-stateless:static rows ENTROPY_SOURCE and WALL_CLOCK, 44 → 42 rows. A static put back is a NEW finding (Law 9: the ceiling only falls).
  3. crates/busbar-plane-llm/src/codec/tests/codec_host_tests.rs has two tests:
    • A minted id and a stamped created come only from the handed host (fixed bytes give a uniform token, and a fixed clock gives that second).
    • A host with nothing to give mints from nothing (an all-0 token, created: 0).

Ledger

  • qa/contract-stateless.toml: struck 2 rows (static ENTROPY_SOURCE, static WALL_CLOCK), 44 → 42. The codec.rs once-cell OnceLock row stays: USAGE_TAP_FAULT_* and TRANSLATE_CAP_READER remain until their own change.

Next in this row (own PRs, per the coordinator's rulings)

  • USAGE_TAP_FAULT_REPORTER/LATCH: the kernel keeps busbar_billing_tap_decode_fail_total and the process-wide warn-once; the door reports the fault as data on its existing return.
  • TRANSLATE_CAP_READER: the cap reaches the plane as settings at open/refresh.

Overlap (rule 20)

…2, TODO 34c; BUSBAR-1.6.0.md Part 2 #49)

protocol.rs names http::HeaderMap (ClaimsFn, attach_error_response_headers),
http::HeaderName/HeaderValue (EgressAuthHeaders, header_map) and
http::StatusCode (quota_exceeded_status, auth_failure_status_and_kind). This
source scan fails on each of those lines until the seam drains.
…he kernel converts at its edges (TODO 34c drain (a))

BUSBAR-1.6.0.md Part 2 #49 (core names zero plane types) and Part 4 (every ABI
shape in busbar-contract is neutral): protocol.rs names no http type.

- ClaimsFn takes HeadFields; claims fns read a field through the new
  protocol::head_field (first legal value, name in any case), which is what the
  struck header_map + HeaderMap::get/contains_key read. Bedrock's SigV4 sniff
  keeps to_str's visible-ASCII condition (is_ascii on a legal value).
- DialectCodec::attach_error_response_headers is struck; error_response_fields
  is the required method. busbar-plane-llm's DialectRef builds its writer's
  header map on its own side; proxy::ingress_error inserts the pairs.
- quota_exceeded_status and auth_failure_status_and_kind are u16; the kernel
  converts in ingress::limit_refusal and proxy::auth_failure_status_and_kind
  (same fallbacks).
- EgressAuthHeaders returns (String, Vec<u8>) pairs; bound_credential's
  DeclaredBuilder converts them.
- detect_protocol (proto/installed.rs) hands the claims fold its HeaderMap as
  field pairs, in the map's order.

codec.rs's WireBody and the `pub use http` re-export stay. Header order,
multiplicity, case and statuses are unchanged from 1.5.5.
…dec is handed a CodecHost

busbar-contract is the ABI's single home of shapes and holds no state (BUSBAR-1.6.0.md Part 4,
gate contract-stateless). Its codec.rs carried two host services as process-wide OnceLock
ports, ENTROPY_SOURCE and WALL_CLOCK, which the llm plane's codecs called as free functions.

Both are gone. The contract now carries only the shape, `codec::CodecHost` (fill_entropy,
wall_clock_now). Every codec entry point that mints an id or stamps a time takes a borrowed
`&dyn CodecHost`, threaded down the codec call graph:
- OperationHandler: read_response, read_response_value, extract_usage
- IrHandle: write_egress_request, write_ingress_response(_bytes), wrap_buffered_as_stream
- DialectCodec: probe_body, write_error, write_response_exception, write_error_frame,
  attach_error_response_headers, error_response_fields, ingress_response_request_id
- StreamTranslator: feed, finish, terminal_error_frame
- the plane's ProtocolReader/ProtocolWriter, the exchange layer (refuse, reply, relay, whole,
  attempt, probe), and synth_rng::fill_entropy

Who hands which host:
- The linked engine (busbar-llm) and the kernel's own error path hand kernel
  `proto::CodecHostServices`: the OS CSPRNG and `store::now`, the same sources the kernel armed.
- The llm door hands `DoorHost`, built over the instance's own `Services` handed at open
  (`random.fill`, chunked at MAX_RANDOM_FILL, and `clock.now`). No global.
- The Plane-trait surface (plane.rs) hands the context's clock and no random source.
The hot vtable's entropy_fill/wall_clock slots are now served by the kernel. The contract's
SERVICES no longer answers them, and `arm` no longer installs them.

The values and the draws are the same. Each draw is one host call, ids keep their shape and
alphabet, and `created` falls back to the host clock exactly as before.

REDs:
- `CodecHost`'s compile_fail doctests: the free ports no longer exist.
- The struck contract-stateless rows: a static put back in codec.rs is a NEW finding.
- codec_host_tests: a minted id and a stamped time come only from the handed host, and a host
  with nothing to give mints from nothing.

qa/contract-stateless.toml: struck the codec.rs `contract-stateless:static` rows ENTROPY_SOURCE
and WALL_CLOCK (44 -> 42 rows). The usage-tap latch/reporter and the translate cap get their own
change (coordinator rulings: the kernel counts the latch from the door's return; the cap reaches
the plane as settings).
…vices: DialectCodec::error_response_fields is the one error-head seam, so it takes the host (a Bedrock error head mints its request id there)
…lane path mints from them

The Plane-trait surface (busbar-plane-llm plane.rs) handed its codecs a host with no entropy,
so an identifier minted there was a silent '0' fill: fail-open. The context now carries the host:
`Ctx::new` takes a `&dyn CodecHost` (no default) and `Ctx::host` hands it out. A caller that
cannot supply one does not compile. plane.rs's CtxHost draws every byte from `ctx.host()` and
keeps the context's own clock.

Every Ctx builder passes a host. All of them are test fixtures today (the contract's
object-safety test, and the a2a, decisions, streaming and llm harnesses). The kernel hands its
CodecHostServices when it builds one.

RED: tests/plane_host_entropy.rs runs a Bedrock answer (no id) through the Plane path to an
OpenAI caller, with a host whose fill is a known non-zero byte, and asserts that every
character of the minted `chatcmpl-` token is that byte's base62 symbol, never the zero fill.

synth_rng.rs stays on predev's (#869) poolless version and only takes the host.

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