wai.delivery.fleet: an organisation's nodes enrolled by their keys, their records verified, and a report it signs (wai-fleet, the fleet's operations, corpus and second verifier) #518
Loading…
Reference in a new issue
No description provided.
Delete branch "wai/fleet"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The open fleet engine waiOS operates: an organisation enrols its nodes by their signing keys, each node contributes the records it already signs, the fleet verifies them, and the organisation signs a report that traces every line to its records and never counts unmetered energy as zero. Everything here is open (Apache-2.0); no accounts, quotas, billing or console.
What is in it
wai/extensions/fleet.mdregisters the recordwai.delivery.fleet. It is namedfleet.md, not after its report, because it defines the fleet itself: the organisation key, the enrolment, and what a node contributes. Sections:WFE1: the node's key, its role (1 relay, 2 compositor, 3 ingest gateway, which are live-metering's codes; 4 room service, 5 ledger, 6 audit collector), a label and a span, signed by the organisation. Also what each role contributes.joule-moq-relay/session-summary/2, read in the exact line form the relay writes and verified by its own signature;WMH1, with their ledgers;sessions,hops) and per class, withmax_ppm; four coverages; citations.WFR1: its layout, signature and rules.*.wai-fleet.json) and its verification steps.wai-rsmodulefleet(featurefleet): the enrolment, records, figures, report, bundle verification andHeld(what a service holds). Alsowai_fleet_vectors,tests/fleet.rs, andstrict_jsonenabled for the fleet.wai/wai-fleet(binarywai-fleet):/v1/fleet/..., over a directory with two append-only logs (synced before the answer; a torn last line is cut off on start) and reports written whole;wai-fleet collect URL SOURCEreads a node's summary file (a path, or anhttp/httpsaddress) into a running service;smoke.shchecks the service over HTTP.Operations in
wai, on the agent rules (the JSON envelope when stdout is not a terminal, the exit table,--dry-runon writes,--confirmbefore a service changes or a file is replaced):enrolment.createwai enrolment createenrolment.listwai enrolment listreport.createwai report createreport.exportwai report export(the bundle is verified locally before it is written)wai verifychecks*.wai-fleet.jsonbundles.quickstartnow carriesfleet.Corpus
live-conformance/fleet/(63 vectors) andfleet_verify.py.CI:
wai-conformance.yml: the extension inpaths,fleetin the feature lists,tests/fleet.rs,tests/cli_fleet.rs, and a step running the module's tests andfleet_verify.py;wai-fleet.yml: the service's tests, clippy-D warningsand the smoke run on Linux; the release build and the smoke run on macOS.Also: the registry (
wai.delivery.fleet; wire identifiersWFE1,WFR1,wai-fleet-bundle,.wai-fleet.json) and its export, a SPEC §5 paragraph, and a CHANGELOG entry.Design decisions
Energy (§5.4). Each summary states one figure in scope
sessionsand each hop record one in scopehops. A row is per scope and class, never summed across either.unmeteredcounts the unmetered markers, which are in no row.whole,partial,unmeteredornone. A partial scope's rows MUST NOT be presented as the energy.unmeteredcount is below its records' is refusedunmetered_summed. This covers a figure that is dropped and one restated as a metered figure of zero joules.ModelBasedorEstimator, because the summary has no members to carry anOnChipCounterorCalibratedInstrumentclass's evidence.Two accounts of bytes, never added. A node line states its summaries' bytes (client sessions and hop links kept apart) and its hop records' bytes separately. Room lines come from hop records. Totals sum the node lines.
Silent is not unmetered. An enrolled node with no records in the period is listed in the report's enrolments and marked silent. It gets no line, so no line is ever unsourced (
line_unsourced).Placement. Every record falls in exactly one of consecutive periods.
Composition with the ledger (§8). A hop record keeps receipt-ledger §5.2's kind 2 and identity. It is carried with its ledger in exactly the
hopsmember of a ledgerroomsource, andGET /v1/fleet/rooms/{room}/hopsserves it in that form. The fleet prices nothing.Operation ids follow N3. The closed verb list that #506's catalogue tests enforce rules out
fleet.enrol,fleet.nodesandfleet.report, so the provisional names became:fleet.enrolenrolment.createfleet.nodesenrolment.listfleet.reportreport.createfleet.exportreport.exportThey join the catalogue once #506 lands.
Checks (all builds and tests on the Framework box through
rb)cargo test --features fleet --lib fleet::cargo test --features fleet --test fleet, and with the CI's full$WAI_FEATURESwai_fleet_vectors verify ../live-conformance/fleetcargo test --features $WAI_FEATURES --lib codecs::registry;--lib codecs::registrywith no featurecargo test --features $WAI_FEATURES --test receipt_ledger --test live_meteringcargo test --features quickstart --bin wai --test floor --test cli_dx --test cli_fleetcli_fleetloopedcargo clippy --all-targetsonfleet,quickstart, and thewaibin with no features,mcpandhttpcargo check --features fleet --testswai-fleet:cargo test --lockedwai-fleet:cargo clippy --all-targets -- -D warningsbash smoke.shagainst a running instancepython3 -I live-conformance/fleet_verify.py live-conformance/fleetavatar_face,browser_sink,sink_energy,synthesis_mark,synthesis,upscale,receipt_ledgerandlive_metering_verify.py(they read SPEC/registry text)registry export --checkcargo metadata --locked --offlinefor wai-rs, wai-fleet and wai-ledgercheck-tests-in-ci,check-workflow-concurrency,check-spec-refs,check-wai-section-refs, vanity, public-text, comparative-prose,check-orphan-sources, public names (files and commit messages)Falsifications
Each was committed first, then mutated in the rb snapshot (anchors checked), run, and restored with
git checkout. Each failed on its assertions, not on a build error.tests/fleet.rsfails each time:summed_acrossalways false;OnChipCounterread without evidence;report_mismatch.fleet_verify.py, exit 1 each time:report_mismatchwas not caught at first. The verifier now also requires §10 to name every reason the corpus raises, and the falsification now fails as it should.wai-fleet:a_record_cut_short…fails;the_corpus_summaries_are_the_relays_own_formfails.cli_fleet:confirmed()always true: all three tests fail;report.export's local verification removed: the altered-bundle test fails.The read-only production trial
wai-fleetran on the Framework box with a fresh trial organisation key, deleted afterwards. It enrolled:ccf347d3…and the ash-1 edge relay26e28bd6…, by their public ids, withwai enrolment create --target;GET /room-api/health;GET /room-api/room, the live room's signed descriptor (room18afdf24…, authorityb413084c…). The fleet verified the authority's signature and held it.summary.out_path), and the public front routes nothing to it. No production relay signs per-hop records either:hop_recordis a library call that nothing in production makes.wai verifyand withfleet_verify.py:none.smoke.shand in the tests, gives:partial(OnChipCounter 18.4 J, ±20 000 ppm, plus the recorded relay hop as the marker);whole;unmetered;partial; fleet sessions:unmetered(7).Not done
wai-fleet: these wait for #506.collectfrom a timer.session/1,WMR1, invoices, audit reports).httpstargets for thewaioperations (the service is reached overhttp://;collectspeakshttps).Questions for the owner
--confirm(as on main) or--yes(as on #506)?🤖 Generated with Claude Code