Repository navigation
#74 ticket half: generation = keyed permutation of the slot counter; a never-minted generation is a forgery (stacked on #1007) - #1018
Draft
MattJackson wants to merge 8 commits into
Draft
MattJackson wants to merge 8 commits into
MattJackson wants to merge 8 commits into
Conversation
…lot's counter; a never-minted one is a forgery
Coordinator ruling C. A ticket's generation was a bare per-slot counter: predictable, so a plugin
could name a generation it was never handed. It is now PRP_k(count): a six-round balanced Feistel
network of 16-bit halves whose rounds are SipHash-2-4 under the handle key, tweaked by
("bb.tick1", worker, slot), mapped onto the nonzero values by cycle-walking. A permutation of the
counter is a bijection, so uniqueness per slot is exact, as the counter's was, and the contract line
("unique per instance across all workers") is unchanged; the layout does not move (Ticket stays
{slot u32, generation u32}). The instance is not part of the tweak: a slab ticket is minted before
any instance is chosen for it.
The worker's equality check is the MAC check. A wake whose generation does not match the live one
is judged by the inverse: a generation the slot really minted (its count reached) is a late wake
(H2), dropped and counted stale as before -- exact, no ring needed; any other is a FORGERY:
handle::forged_ticket counts it, and the instance that woke it from inside its crossing (carried on
the wake message: Msg::Wake(ticket, culprit)) is quarantined (plugin::quarantine_entry, via the
entry's back-reference to its instance); with no crossing to blame it counts to #1007's latch.
Worker replacement carries the slot COUNTERS. Inline and connection tickets are unchanged.
REDs: handle_tests -- the permutation exhausted at an 8-bit width (bijection, nonzero, inverse) under
three keys/tweaks; consecutive generations hide their counter and invert exactly. dispatch_tests --
a forged ticket generation quarantines the instance that woke it (honest control); a stale wake for a
generation the slot minted is counted stale and not as a forgery; the stale-wake script mode now
wakes two recycled tickets the plugin really held.
…e counter Per the #1007 re-review (no test reads the global forgery counter): the stale-wake RED wakes from inside a crossing of its own instance, so a misjudged forgery would quarantine it, and asserts it is not; the forged-generation RED asserts the quarantine and a revoked handle on a latch of its own.
…quarantine outside the worker's lock - A slot whose mint counter reaches u32::MAX is retired: never back on the free list, carried retired across a worker replacement; the next mint takes a fresh slot. - The supplier of a ticket is carried with its wake (ticket::Waking): host_wake names its resolved instance; Completer, TicketWaker and Routed carry the instance whose context made them. No wake reads the thread's crossing; the host's own wakes carry none and count to the latch. - apply collects forged suppliers; the worker quarantines once its lock is dropped. - The ticket key is a TicketKey drawn at the dispatcher's boot and held in Env; no zero fallback. - REDs: counter wrap, attribution across crossings, worker-tweak separation, a supplier-less forged ticket counting toward the latch.
…cket's supplier - conn::ConnWake = Arc<dyn Fn(InstanceId, Ticket)>: the connector's TicketWake carries the owner the read, wait, accept or upgrade registered under; TcpConns and the test doubles name it too. - One numbering: an instance's connection-table identity is its handle's id (handle::instance_id); NEXT_INSTANCE is gone. conn_waker maps the owner to its entry (handle::supplier_of); the root's own identity 0 names none, and only its wakes count to the latch. - REDs: a forged ticket through the read slot quarantines its supplier with the latch unmoved; the connector's wake names the caller it parked for; instance identities name their own entry.
… worker no one runs is a forgery - Inline slots carry a mint counter; their generation is ticket_generation(key, INLINE_WORKER, slot, count), retired at u32::MAX (generation 0, never back on the free list). A wake that matches no held inline ticket is judged by the inverse: minted = late wake, never minted (or no such slot) = Judged::Forged, and the pool calls forged_ticket(supplier, latch) with the inline table's lock let go. - Pool::wake: a slot naming a worker index past the dispatcher's workers (short of the inline worker) is a forgery blamed on its supplier, judged there, lock-free. - recycled_generation is gone: no ticket generation is a plain counter any more. - REDs: a guessed small inline generation quarantines its guesser, a never-used inline slot is a forgery; an inline slot is retired at its counter's end and its late wakes are not forgeries; a wake for encode(workers, 0) is a forgery.
…a held waker is bound to its generation - Slot keeps (generation, waker) under one Mutex: recycle bumps or retires the generation and clears the waker there; a wake checks the generation and takes the waker there, waking once the section is let go, so a wake never takes a later generation's task's waker. - waker_of hands out a GenerationWaker bound to (slot, generation): fired after a recycle and re-mint it wakes nothing and blames no one. - REDs: an I/O-held waker fired after recycle + re-mint wakes neither task; a wake interleaved with recycle + re-mint (test hook between lookup and section) reaches no task, judged Stale.
MattJackson
added a commit
that referenced
this pull request
Oct 15, 2026
…eversing an unbounded zip; PB-29 cites its four tests by path; the deleted cold lane's paths are declared to qa-names - plugin-loader dispatch worker: zip(0u32..) is not double-ended, so the free list is collected and reversed (lowest index popped first, as before). Compile red on every check (#1018). - qa/design-bindings.json, qa/DESIGN-BINDINGS.md: PB-29's four 503-literal tests are declared in both busbar-llm and busbar-plane-llm's on_driver seam (#912's rehome), so each is cited as path::name. - xtask abi_freeze CONDEMNED and one_memory_abi COLD_HOME keep naming abi/cold after #961 deleted it; each carries its qa-names declaration.
MattJackson
added a commit
that referenced
this pull request
Oct 15, 2026
…onns wrapper follow the merged shapes From the full logs of 2382599: - root door_steps PresentingConns: bind_auth/auth_of take and hand on the registration `member` (the connector's per-member binding, DeclaredConns; E0050/E0061 x2 each). - root tests: the datagram cell's Got states fault/declared_len/end (#893 over #837); the two upgrade-row builds take the settings alone (HostWire build, #932 over #997); the two userinfo cells hand provider_routes a ResolvedProvider (#957 over #876/#936). - tests/plane_blackbox.rs: the step's (key, text) pairs are a type (clippy type_complexity). - config-schema snapshot: `type WakeTicket` is now an alias of ConnWake (#1018), recorded. - Law 0: busbar x instance:export 25 -> 24 (measure); kernel x plane: a test doc names a plane's own webhooks section, not the llm plane's (1050 measured against w2's 1049).
MattJackson
added a commit
that referenced
this pull request
Oct 15, 2026
…ippy build named (bundle of d543b25) - busbar-kernel tests: the rehomed lane-caps cells (#912) and the tenant merge cell read the resolved entry's table through LegacyLaneKeys, as #957's resolved provider carries the plane keys (E0599 lane_caps_for x15, E0609 organization/project x3). - busbar-core-connector tests: the wake closures take (instance, ticket) (ConnWake since #1018, E0593 x3); the datagram head piece states fault/declared_len (E0063). - busbar-plane-llm tests/conformance.rs: hydrate and start are the plane kind's slots (E0425). - busbar-contract tests/object_safety.rs: StreamId is no longer imported (unused since #932). - voice-conformance harness twilio_legs: std::slice::from_ref (clippy cloned_ref_to_slice_refs).
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Coordinator ruling C. DRAFT, stacked on #1007 (rule 19).
PRP_k(per-slot count): a 6-round Feistel network on 16-bit halves, SipHash-2-4 rounds under the #74 ABI half: HostCtx is a kernel-tagged handle verified before use (no host pointer crosses) #1007 key, tweak ("bb.tick1", worker, slot), mapped to nonzero values by cycle-walking.handle::ticket_key(), aTicketKeyonly that function makes) and held in the dispatcher'sEnv. Every worker gets it at construction. There is no fallback key: a failed draw refusesDispatcher::try_new/try_with_serviceswithLoadError::Entropy.u32::MAXis retired. It is never put back on the free list, and the next mint takes a fresh slot. Worker replacement carries a retired slot as retired. A wrapped counter would re-mint generations the slot already handed out.Msg::Wake(ticket, supplier)), never read off the thread the wake fires on.host_wakenames the instance its context resolved to.Completer, the connector'sTicketWakerand the I/ORoutedwaker each carry the instance whose context created them (ticket::Waking).conn::ConnWake = Arc<dyn Fn(InstanceId, Ticket)>; the connector'sWakeTicketis that type, and itsTicketWakecarries the owner. The dispatcher'sconn_wakermaps the owner to its handle entry, which becomes the supplier.handle::instance_id). The separateNEXT_INSTANCEcounter is gone, so no second registry exists. The id is never0, which stays the root's own (ROOT_OWNER). A wake under0names no supplier, and only such host-own wakes count to #74 ABI half: HostCtx is a kernel-tagged handle verified before use (no host pointer crosses) #1007's latch.applycollects each supplier; the worker quarantines after the lock is dropped.INLINE_WORKER) are permuted as a worker slot's are:ticket_generation(key, INLINE_WORKER, slot, count), with a per-slot counter, retirement atu32::MAX(generation0, never re-issued), and the same judgement.Judged::Forged. The pool then callsforged_ticket(supplier, latch)with the inline table's lock already dropped.waker_of(whatio.*hands the reactor) returns a waker bound to(slot, generation)that performs the same check. If it fires after a recycle and re-mint, it wakes nothing and blames no one.encode(w, _)withworkers <= w < INLINE_WORKERis a forgery blamed on its supplier, judged lock-free inPool::wake. It is no longer just a stale wake.What this claims, and what it does not:
RED tests:
conn_waker. The supplier is quarantined; the latch hasforged == 1, unattributed == 0.OWNERon ticket 7 is(OWNER, 7).0, never repeat, and name their own handle entry. The root's identity and an unminted one name none.encode(INLINE_WORKER, i)at generation 1, which the old counter handed out first. No held inline generation is in1..=1024. The miss quarantines the guesser and leaves another instance alone. A never-used inline slot is a forgery too, and the latch hasforged == 2, unattributed == 0.u32::MAX - 1is handed out atu32::MAX, then retired and never re-issued. Late wakes for both of its generations are not forgeries.Stale, not a forgery.encode(workers, 0)quarantines its supplier, and the latch has(1, 0).u32::MAX - 1, the slot is handed out atu32::MAX, then retired, and never re-issued. A late wake on its last generation is not a forgery.