library: the last three protocols speak the envelope
These were the awkward ones. Each began with an operation packed into a single byte — two of them with a version wedged in beside it — so there was no wrapping them: the layouts had to be rebuilt. The device manager's own enumerate and subscribe become the reserved verbs that mean the same thing everywhere, its replies lose three status structs the envelope already carries, and a device id becomes the packet's target. Power drops the version it repeated on every request, because describe is the handshake, and stops claiming a 64-byte ceiling it never needed for calls. USB moves a control transfer's data to the packet tail in both directions, which makes the status length the transferred length and retires a field that had been saying the same thing twice. The danger in this one was not the protocols but their readers. Init recognised a power button by two bytes at the head of a message, the ACPI service dispatched on the first byte, the xHCI driver read its operation with a raw integer load, and the HID drivers reinterpreted a report wholesale — none of which would have failed to compile once the layouts moved. They would simply have stopped: no shutdown on the power button, no reports from the keyboard. Every one of them now reads through the generated types, and the shutdown gate that answers only a subscriber is the same code it was. Two sizes were decided by measuring rather than assuming. The child-added message is both a request and the event broadcast to subscribers, and alignment rounds it to 48 bytes, which puts its packet exactly on the 64-byte push floor — a test pins that, because a field added carelessly would now overflow it. The interrupt report gives up eight bytes of inline room to make space for the header; the two drivers that produce reports send eight and four. Suite 110/110.
This commit is contained in:
@@ -36,10 +36,10 @@ plain `main` checkout always tells the truth about where the work is.**
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Working on | **P4b** — device-manager, power, usb-transfer onto `Define` |
|
||||
| Working on | **P4c** — harness subscriber lift + badge-scoped client ids |
|
||||
| Branch carrying it | `feat/security-group-3` (pushed to origin) |
|
||||
| On `main` | Phase 0, PM, H1, P1, P2, P3 — groups 1 and 2 merged |
|
||||
| Awaiting merge | P4a — lands with the group 3 merge |
|
||||
| Awaiting merge | P4a, P4b — land with the group 3 merge |
|
||||
| Suite | 110 cases, all passing |
|
||||
| Last updated | 2026-08-01 |
|
||||
|
||||
@@ -66,7 +66,7 @@ group boundary.
|
||||
bind attestation and every refusal it makes untouched (suite 109/109)
|
||||
- [x] **merge** group 2 → main, push
|
||||
- [x] **P4a** — clean protocols rebased onto `Define` (vfs, block, display, scanout, input; display's one overloaded request split per-operation and its field abuse ended, scanout's bogus 64-byte maximum deleted, directory EOF re-spelled as a nameless entry, input moved onto the service harness; new `protocol-conformance` case asks every reachable provider for `describe` and requires `-ENOSYS` for an undefined verb; suite 110/110)
|
||||
- [ ] **P4b** — misfit protocols rebased (device-manager, power, usb-transfer)
|
||||
- [x] **P4b** — misfit protocols rebased (device-manager, power, usb-transfer; every leading operation byte folded into the header, and with it the `device_id`/`device_token` that followed it — `Header.target` now carries the device in all three. device-manager's own `enumerate`/`subscribe` became the reserved verbs and its three `{status, reserved}` reply structs the envelope's `Status`; `ChildAdded` is one struct under two numbers, a call and an event, landing exactly on the 64-byte push floor. power's kinds became one declared event each, the input protocol's shape, so init reads *what happened* from the header; usb-transfer's control data stage moved to the packet tail in both directions, which made `Status.len` the transferred length and `actual_length` redundant. The two silent-breakage sites — init's byte-offset power parse and acpi's `message[0]` dispatch — are gone, the shutdown badge gate unchanged; three more rows in the conformance table. Suite 110/110)
|
||||
- [ ] **P4c** — harness subscriber lift + badge-scoped per-client integers
|
||||
- [ ] **merge** group 3 → main, push
|
||||
- [ ] **H2** — SMEP on every core
|
||||
@@ -413,6 +413,32 @@ re-layouts and raw-offset readers):
|
||||
USB storage/HID all exercise these wires); the conformance case now covers
|
||||
three more providers. Suite 110.
|
||||
|
||||
*Landed. Three judgment calls the plan left open, recorded because a reader of
|
||||
the wire formats will want them:*
|
||||
|
||||
- *`ChildAdded` is 48 bytes, not the 44 the "60 B" estimate assumed: three `u64`s
|
||||
give the struct eight-byte alignment, so 41 bytes of content round up whatever
|
||||
order the fields sit in. The packet is therefore **exactly** 64 — on the push
|
||||
floor, not under it — which `Define` accepts and the module pins in a test. The
|
||||
fields are ordered small-tail-last deliberately, so the slack the rounding pays
|
||||
for is where the small ones live.*
|
||||
- *power's events are declared **per kind** (`power_button`, `lid`, `ac`,
|
||||
`battery`, `notify`), not one `event` with the kind in the payload. That is the
|
||||
shape P4a gave input — "the class is the header's operation, so a subscriber
|
||||
reads the kind from the packet rather than from a tag inside the payload" — and
|
||||
it is what makes `Header.operation` carry information here at all. It also kept
|
||||
every call site's spelling: `Protocol.Event` is re-exported as the protocol's
|
||||
own `Event`, with the members it always had.*
|
||||
- *the conformance case still checks two providers, and the three new rows report
|
||||
as unbound. All three P4b contracts arrive with the device manager — it is the
|
||||
first, it spawns the discovery service that binds the second, and the xHCI
|
||||
driver that binds the third — so booting one means booting the driver tree, and
|
||||
the fixture takes **one snapshot** of `/protocol`: a scenario whose bound set
|
||||
depends on how far that tree got would make the case's own summary line a boot
|
||||
race. The rows still earn their place — a future scenario that binds one gets it
|
||||
checked with no edit here, and `/test/*` already holds the `open` grant for
|
||||
`device-manager`.*
|
||||
|
||||
## P4c — harness subscriber lift + badge scoping
|
||||
|
||||
- `library/kernel/service.zig` grows the subscriber table, exit-
|
||||
|
||||
Reference in New Issue
Block a user