All checks were successful
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 6s
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 39s
standards workspaces build + test / arl-rs (arl/arl-rs, arl-rs, linux) (pull_request) Successful in 1m9s
standards workspaces build + test / jcp-rs (jcp-conformance, jcp/jcp-rs, -p jcp-energy --features nvml, jcp-rs, linux) (pull_request) Successful in 1m49s
standards workspaces build + test / eoc-rs (eoc/eoc-rs, -p eoc-meter --features cuda, eoc-rs, linux) (pull_request) Successful in 2m10s
standards workspaces build + test / joule-ui-rs (joule-ui/joule-ui-rs, joule-ui-rs, linux) (pull_request) Successful in 1m11s
standards workspaces build + test / joulehook-rs (joulehook/joulehook-rs, joulehook-rs, linux) (pull_request) Successful in 1m13s
standards workspaces build + test / pool-rs (pool/pool-rs, pool-rs, linux) (pull_request) Successful in 1m7s
standards workspaces build + test / proof-rs (proof-conformance, proof/proof-rs, proof-rs, linux, true) (pull_request) Successful in 1m28s
standards workspaces build + test / sense-rs (sense/sense-rs, sense-rs, linux) (pull_request) Successful in 1m17s
standards workspaces build + test / sandbox-rs (sandbox-conformance, sandbox/sandbox-rs, sandbox-rs, linux) (pull_request) Successful in 2m21s
standards workspaces build + test / smart-byte-rs (smart-byte/smart-byte-rs, smart-byte-rs, linux) (pull_request) Successful in 3m35s
standards workspaces build + test / jouleclaw-rs (-nodebug, jouleclaw/jouleclaw-rs, -p jouleclaw-energy --features rapl,nvml, jouleclaw-rs, linux-arm64, -C target-feature=+fp16) (pull_request) Successful in 3m57s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 3m9s
standards workspaces build + test / joulecontract-rs (joulecontract/joulecontract-rs, joulecontract-rs, linux-arm64, true) (pull_request) Successful in 1m52s
standards workspaces build + test / aac-rs (aac-conformance, aac/aac-rs, aac-rs, linux-arm64) (pull_request) Successful in 6m11s
standards workspaces build + test / map-rs (map-conformance, map/map-rs, map-rs, linux-arm64) (pull_request) Successful in 2m18s
standards workspaces build + test / mesh-rs (mesh/mesh-rs, -p mesh-engine-gguf -p mesh-openai --features mesh-engine-gguf/gguf,mesh-openai/server, mesh-rs, linux-arm64) (pull_request) Successful in 2m17s
standards workspaces build + test / openpay (openpay, openpay, linux-arm64) (pull_request) Successful in 7m35s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 8m35s
standards workspaces build + test / jouledesk-rs (jouledesk/jouledesk-rs, jouledesk-rs, macos) (pull_request) Successful in 2m39s
A workload holding accelerators while consuming almost no energy is holding
capacity it is not using. A device ledger cannot see that — a held device is a
held device, saturated or parked at a prompt — so idle reclamation is a question
only an energy-denominated scheduler can ask.
It is also the most dangerous question in this standard, because the obvious
implementation destroys running work. "This workload spent 0 µJ" arrives
identically from a parked workload and from a meter that is not there:
meter unavailable → 0 µJ → "idle" → reclaim → running work destroyed
That is this family's "unknown conflated with a value" defect in its most
destructive form, so the module is built around refusing it:
- **Unknown is not idle.** An `Estimator` figure cannot establish idleness
whatever its value, and the grade is tested **before** the value meets any
threshold — so no threshold setting lets a guess through, including one high
enough to catch everything. A workload is reclaimed on evidence that it is
idle, never on the absence of evidence that it is busy.
- **Idleness is a rate over a stated window, never an instant.** Any workload
is momentarily between steps. An observation shorter than the policy's window
yields no verdict: startup is not idleness. An empty window yields no rate —
`mean_uw()` returns `None`, not zero, because zero is the one value that
reads as idle.
- **Nothing held, nothing to reclaim.**
- **Four verdicts, and only one permits reclamation.** A workload with no
verdict is *absent* from `reclamation_order`, not ranked last in it: it is not
a worse candidate than an idle workload, it is not a candidate.
Check order is normative: nothing held, then the window, then the grade, then
the rate. A later check never rescues an earlier refusal.
`IdlePolicy::default()` reclaims **nothing**. A threshold must sit above the
hardware's idle draw or nothing is ever idle, and below its working draw or
everything is, and both are properties of the device rather than of this
standard — so §2.7 declines to guess and makes the unconfigured failure "nobody
reclaimed" rather than "everybody reclaimed".
This is not preemption. §5.2 ranks who is spending badly under contention; this
asks who is not spending at all. A workload burning energy while completing
nothing is thrashing, not idle, and §5.2 is what catches it.
Conformance gains §7.25–28. Also fixes three broken intra-doc links left by
earlier slices (`WitnessReceipt`, the `derive` function/attribute ambiguity, and
a public doc linking the private first pass), so `cargo doc` is clean.
Co-Authored-By: Claude Opus 5 <[email protected]>
549 lines
25 KiB
Markdown
549 lines
25 KiB
Markdown
# Pool v0.1 — A Standard for Energy-Accounted Multi-Tenant Scheduling
|
|
|
|
| | |
|
|
|---|---|
|
|
| **Standard** | pool |
|
|
| **Status** | v0.1.0 draft for review |
|
|
| **Profile** | `pool/1` |
|
|
| **Licence** | Specification text CC-BY-4.0 ([`LICENSE-SPEC`](LICENSE-SPEC)); reference code Apache-2.0 ([`LICENSE`](LICENSE)) |
|
|
| **Reference** | [`pool-rs/`](pool-rs/) |
|
|
|
|
A vendor-neutral standard for **deciding who gets contended compute, on a
|
|
budget denominated in energy**. Pool specifies an entitlement tree whose
|
|
guarantees are microjoules and devices together, an admission rule for
|
|
all-or-nothing gangs, and a preemption order derived from what workloads have
|
|
actually delivered per joule.
|
|
|
|
Pool is one of the [Transaction Science open standards](../README.md).
|
|
Transaction Science is the steward, not the proprietor.
|
|
|
|
---
|
|
|
|
## 1. Scope and doctrine
|
|
|
|
### 1.1 What Pool decides
|
|
|
|
Pool decides three questions and no others: **may this claim start**, **what is
|
|
reserved against whom**, and **if capacity must be reclaimed, in what order**.
|
|
It does not place workloads on hosts, does not read counters, and does not
|
|
execute anything. Placement is the caller's; energy figures arrive already
|
|
graded from whatever meter produced them (§2.3).
|
|
|
|
### 1.2 Energy is the unit of entitlement
|
|
|
|
A device count is a proxy for the thing consumed. The quantity that is paid
|
|
for, drawn from a grid, and reported under an energy-disclosure regime is
|
|
energy. A guarantee of "eight accelerators" cannot express "this team may spend
|
|
40 MJ this window", so under a device-denominated quota the energy budget is
|
|
enforced nowhere and reconciled, if at all, after the fact.
|
|
|
|
In `pool/1` an entitlement carries **both** a microjoule guarantee and a device
|
|
guarantee, and both bind (§2.1). Devices describe what is occupied; joules
|
|
describe what is spent. A claim that fits one and not the other does not fit.
|
|
|
|
### 1.3 A figure's grade is part of the decision
|
|
|
|
Every energy figure in `pool/1` carries the grade of whatever produced it
|
|
(§2.3). The grade is not a label attached after the decision; it changes the
|
|
decision (§4.3). An estimate nobody measured is the figure most likely to be
|
|
wrong in the direction that overcommits, and a scheduler that cannot tell a
|
|
reading from a guess cannot bound that error.
|
|
|
|
### 1.4 Unknown is not an extreme
|
|
|
|
Where `pool/1` lacks a figure it says so, and never substitutes a best or worst
|
|
value for it. A ratio with no denominator is undefined (§5.1); a claim that
|
|
cannot be satisfied today is distinct from one that can never be satisfied
|
|
(§4.5). Both substitutions change outcomes: an undefined cost read as zero
|
|
makes a workload unreclaimable, and read as infinity makes it the first victim.
|
|
|
|
---
|
|
|
|
## 2. Objects
|
|
|
|
### 2.1 The entitlement
|
|
|
|
An **entitlement** is a node of a tree — a department, a project, a team. It
|
|
carries:
|
|
|
|
| field | meaning |
|
|
|---|---|
|
|
| `id` | the node's name |
|
|
| `parent` | its parent, or absent for a root |
|
|
| `guarantee_uj` | microjoules it is owed and may always spend |
|
|
| `guarantee_devices` | devices it is owed and may always occupy |
|
|
| `over_quota_weight` | its relative share of a parent's surplus; `0` never borrows |
|
|
| `limit_uj` | a hard ceiling including anything borrowed; absent means the only ceiling is available surplus |
|
|
| `priority` | declared ordering, used only where evidence is absent (§5.2) |
|
|
|
|
Both guarantees bind. An implementation **MUST** refuse a claim that exceeds
|
|
either (§4).
|
|
|
|
### 2.2 Surplus and borrowing
|
|
|
|
Surplus is the part of a sibling's guarantee it has not spent. Siblings are
|
|
nodes sharing one parent; surplus **MUST NOT** cross roots.
|
|
|
|
A borrower's share is its `over_quota_weight` against the summed weight of
|
|
every node under that parent, rounded down. A borrower **MUST NOT** receive
|
|
more than its weighted share merely by claiming first: the share is a property
|
|
of the tree, not of arrival order.
|
|
|
|
### 2.3 Energy and its grade
|
|
|
|
An energy figure is a microjoule count and a **provenance**, one of:
|
|
|
|
| grade | meaning |
|
|
|---|---|
|
|
| `HwShunt` | a counter read for this work, at its honest resolution |
|
|
| `ModelBased` | a model the host calibrated — a real curve, not a reading |
|
|
| `Estimator` | a default-power guess; nobody measured or modelled this host |
|
|
|
|
`HwShunt` and `ModelBased` are **observed**. `Estimator` is not. The grade
|
|
never silently improves.
|
|
|
|
### 2.4 The claim
|
|
|
|
A **claim** requests capacity for a **gang** — one or more members that must
|
|
start together. Its figures describe the whole gang, never a member:
|
|
`gang_size`, `devices_per_member`, and an `estimate` for the gang's total
|
|
energy at its grade.
|
|
|
|
### 2.5 Shared devices, and what division does to a figure
|
|
|
|
Fractional accelerators are how a scheduler stops stranding capacity: several
|
|
workloads on one device, each bounded by a memory fence. The fence is
|
|
enforceable because memory is partitioned. **Energy is not.** A device-level
|
|
counter reports one figure for the whole device and has no notion of which
|
|
tenant caused which joule.
|
|
|
|
An attributed per-tenant figure is therefore a **split of a measurement, not a
|
|
measurement**, and two rules follow.
|
|
|
|
**Provenance degrades on division.** A `HwShunt` device total becomes
|
|
`ModelBased` the moment it is divided between two or more occupants, because
|
|
the division is a model however good the counter was. It degrades no further
|
|
and never improves: an `Estimator` total stays `Estimator`, since dividing a
|
|
guess does not make it a model. Dividing by one is not a division, so a sole
|
|
occupant keeps the device's own grade.
|
|
|
|
An implementation **MUST NOT** report a per-tenant figure from a shared device
|
|
as `HwShunt`. That grade asserts a counter was read for *this* work, and on a
|
|
shared device none was.
|
|
|
|
**The shares sum to the measurement, exactly.** Attribution is integer
|
|
microjoules and **MUST** conserve the total: no joule invented, none lost. The
|
|
remainder left by flooring is distributed by a deterministic rule — largest
|
|
remainder first, ties broken on a stable key — so two implementations divide
|
|
the same device the same way. Conservation is what makes a tenant's figure
|
|
reconcilable against the device that produced it.
|
|
|
|
A weight basis is the operator's to choose (allotted memory, time slices,
|
|
partitions). `pool/1` requires only that one basis is used for every occupant
|
|
of one device, and that the result is graded as the model it is.
|
|
|
|
An implementation **MUST** refuse to attribute a device with no occupants, or
|
|
one whose occupants all carry zero weight: there is then no basis to divide
|
|
on, and discarding the figure would lose energy the counter really read.
|
|
|
|
### 2.6 Earning an observed estimate
|
|
|
|
§4.4 refuses a guess the right to spend a neighbour's capacity. That rule is
|
|
only fair if a guess can **stop** being a guess. On its own it is a permanent
|
|
penalty with no exit: a tenant nobody has measured can never be measured,
|
|
because it can never run against surplus.
|
|
|
|
The evidence already exists. Every completed claim appended a `Released`
|
|
carrying what it actually consumed, at the grade of whatever read it (§6.2).
|
|
An implementation **MAY** derive a claim's estimate from that history, and
|
|
where it does, four rules bind.
|
|
|
|
**A guess is not evidence.** An observation whose own figure is `Estimator` is
|
|
**excluded**, not averaged in. Nobody measured or modelled it, so it says
|
|
nothing about what the work costs, and counting it would launder guesses into a
|
|
grade asserting they were observed. This is what makes the exit real rather
|
|
than circular: a tenant earns an observed estimate by being *measured*, not by
|
|
having run.
|
|
|
|
**A derived estimate is a model, never a reading.** Its grade **MUST** be
|
|
capped at `ModelBased`, even where every observation was read by a hardware
|
|
counter, because a figure for the *next* run is a prediction. The cap is a
|
|
ceiling and not a floor: modelled inputs give a modelled output.
|
|
|
|
**One run is not a sample.** Below a required count of evidence an
|
|
implementation **MUST NOT** derive an estimate, and **MUST** report what it
|
|
had — how many observations of the class it saw, and how many of those were
|
|
evidence. The two say different things to an operator: plenty of history that
|
|
is all guesses needs a meter, while little history needs patience. The required
|
|
count is a **policy value, not a derived one**; `pool/1` states a default of
|
|
three and does not pretend to know the right number for a workload it has never
|
|
seen.
|
|
|
|
**The absence of a class is not a class.** Comparability is the operator's
|
|
assertion (§2.4), and an empty class asserts nothing. Deriving across an empty
|
|
class, or across differing classes, **MUST** be refused rather than pooling
|
|
unlike work into one figure.
|
|
|
|
A derived reservation **SHOULD** take the upper end of the observed figures
|
|
rather than their mean. Under-reserving is the failure §4.4 exists to prevent —
|
|
a reservation below what the work costs is admitted and then overspends, and
|
|
the joules it overspends may be a sibling's — and a mean under-reserves roughly
|
|
half the time by construction. The spread **SHOULD** be reported beside the
|
|
reservation so a reader can see how thin the evidence is.
|
|
|
|
**The limit.** The maximum of a small sample is itself an underestimate of the
|
|
true tail. A derived reservation is better evidence than a guess; it is not a
|
|
bound on what the work can cost, and `pool/1` does not claim it is one.
|
|
|
|
### 2.7 Reclaiming capacity from work that is not working
|
|
|
|
A workload holding accelerators while consuming almost no energy is holding
|
|
capacity it is not using. A device ledger cannot see this: a held device is a
|
|
held device, whether it is saturated or parked at an interactive prompt. Energy
|
|
can, which makes idle reclamation a question `pool/1` can ask at all.
|
|
|
|
It is also the most dangerous question in this standard, because the obvious
|
|
implementation destroys running work. The reading *"this workload spent 0 µJ"*
|
|
arrives identically from a workload that is genuinely parked and from a meter
|
|
that is not there:
|
|
|
|
```
|
|
meter unavailable → 0 µJ → "idle" → reclaim → running work destroyed
|
|
```
|
|
|
|
**Unknown is not idle.** A figure nobody measured or modelled (`Estimator`)
|
|
**MUST NOT** establish idleness, whatever its value. A workload is reclaimed on
|
|
evidence that it *is* idle, never on the absence of evidence that it is busy.
|
|
An implementation **MUST** test the grade **before** comparing the value to any
|
|
threshold, so that no threshold setting can let a guess through.
|
|
|
|
**Idleness is a rate over a stated window, never an instant.** Any workload is
|
|
momentarily between steps. An implementation **MUST** state the window a
|
|
verdict rests on, and **MUST NOT** reach a verdict from an observation shorter
|
|
than the window it requires: startup is not idleness. A window of zero yields
|
|
no rate — **not** a rate of zero, which is the one value that reads as idle.
|
|
|
|
**A workload holding no devices is not a candidate.** It occupies no contended
|
|
capacity, so there is nothing to reclaim.
|
|
|
|
**The verdicts are distinct.** *Idle*, *working*, *no verdict* and *nothing
|
|
held* are four answers, and only the first permits reclamation. A workload with
|
|
no verdict **MUST** be absent from a reclamation ordering rather than ranked
|
|
last in it: it is not a worse candidate than an idle workload, it is not a
|
|
candidate.
|
|
|
|
The check order is therefore normative: **nothing held, then the window, then
|
|
the grade, then the rate.** A later check never rescues an earlier refusal.
|
|
|
|
**Why there is no default threshold.** A parked accelerator still draws power.
|
|
A threshold has to sit *above* the hardware's idle draw or nothing is ever
|
|
idle, and *below* its working draw or everything is — and both are properties
|
|
of the device, not of this standard. `pool/1` does not guess them. An
|
|
unconfigured policy **MUST** reclaim nothing: the failure of an unconfigured
|
|
destructive action should be a missed optimisation, not destroyed work.
|
|
|
|
**This is not preemption.** §5.2 answers *who is spending badly under
|
|
contention*, ranking by cost per completed unit. This answers *who is not
|
|
spending at all*. A workload burning energy while completing nothing is
|
|
thrashing, not idle, and §5.2 is the question that catches it.
|
|
|
|
---
|
|
|
|
## 3. Reservation
|
|
|
|
On admission the claim's whole estimated energy is **reserved** against the
|
|
entitlement before the work runs. Two claims decided in the same window
|
|
therefore cannot both spend the same joule.
|
|
|
|
A reservation is only as sound as the figure behind it, so the verdict carries
|
|
that figure's grade (§4.6). An implementation **MUST NOT** report a reservation
|
|
without it.
|
|
|
|
---
|
|
|
|
## 4. Admission
|
|
|
|
An implementation **MUST** evaluate a claim in the order below. The order is
|
|
normative because a different order yields a different verdict.
|
|
|
|
### 4.1 Resolution and shape
|
|
|
|
A claim naming an entitlement the pool does not hold is refused. A gang of no
|
|
members, or members occupying no devices, is refused: it is not a claim on
|
|
anything.
|
|
|
|
### 4.2 Impossibility before pendency
|
|
|
|
A claim whose devices exceed `guarantee_devices`, or whose energy exceeds
|
|
`limit_uj`, is refused **before** any test that could queue it. Queueing a
|
|
claim that can never be satisfied fills a queue with work that will never run
|
|
and reports it as pending.
|
|
|
|
### 4.3 Inside the guarantee
|
|
|
|
If the entitlement's spent energy plus the claim's estimate is within
|
|
`guarantee_uj`, and its held devices plus the claim's devices are within
|
|
`guarantee_devices`, the claim is **admitted** — at any grade. A tenant may
|
|
spend its own guarantee on a guess.
|
|
|
|
### 4.4 Past the guarantee: an unobserved estimate does not borrow
|
|
|
|
A claim exceeding `guarantee_uj` may be admitted only against borrowed surplus,
|
|
and only if **all** hold:
|
|
|
|
1. its estimate is **observed** (§2.3) — an `Estimator` figure **MUST NOT**
|
|
draw on surplus;
|
|
2. its entitlement's `over_quota_weight` is non-zero;
|
|
3. the total after admission is within `limit_uj`, where one is set;
|
|
4. the borrowed part is within the entitlement's weighted share (§2.2).
|
|
|
|
Rule 1 is the substance of §1.3. Inside its own guarantee a tenant bears its
|
|
own mis-estimate. Surplus belongs to a sibling that has not spent it, and an
|
|
unobserved estimate is not a sound basis for spending it.
|
|
|
|
### 4.5 Pending and refused are different verdicts
|
|
|
|
A claim that does not fit **now** is `Queue`, with the reason: the guarantee is
|
|
exhausted and it may not borrow, the surplus is insufficient, or the devices
|
|
are held. A claim that can never fit **as written** is `Deny`, with the reason.
|
|
An implementation **MUST NOT** report the second as the first.
|
|
|
|
### 4.6 The verdict
|
|
|
|
An admission carries the reserved microjoules, the devices, how much of the
|
|
reservation was borrowed, and the grade of the estimate it rests on.
|
|
|
|
---
|
|
|
|
## 5. Preemption
|
|
|
|
### 5.1 Realised cost
|
|
|
|
A running workload's realised cost is its spent microjoules divided by the
|
|
units it has **completed** — not attempted. Where nothing has completed the
|
|
ratio is **undefined**, and an implementation **MUST** represent it as such
|
|
(§1.4).
|
|
|
|
Completion is what makes the ratio meaningful: energy spent on work that was
|
|
abandoned is waste, and a denominator of attempts would score a workload well
|
|
for failing quickly.
|
|
|
|
### 5.2 The order
|
|
|
|
Capacity is reclaimed in this order:
|
|
|
|
1. **Workloads with a defined realised cost, most expensive first.** There is
|
|
evidence they are spending badly.
|
|
2. **Workloads with an undefined realised cost, lowest `priority` first.** They
|
|
are unmeasured, not wasteful.
|
|
|
|
Ties **MUST** break on a stable key so the order is total and a replay
|
|
reproduces it.
|
|
|
|
An implementation **MUST NOT** rank an unmeasured workload as though its cost
|
|
were known. Reclaiming unmeasured work first destroys the work that would have
|
|
produced the measurement, so the scheduler never learns anything about it.
|
|
|
|
---
|
|
|
|
## 6. The entitlement ledger
|
|
|
|
### 6.1 Usage is derived, not stored
|
|
|
|
A scheduler that restarts with empty usage hands every tenant its whole
|
|
guarantee back, and admits the next claim against a budget already spent. A
|
|
quota that refills on every deploy, crash or config reload is not a quota.
|
|
|
|
An implementation **MUST** be able to rebuild every entitlement's usage by
|
|
replaying its own ledger. The ledger is the durable state; there is no second
|
|
store to drift from it.
|
|
|
|
### 6.2 What moves the ledger
|
|
|
|
Two events, and only two:
|
|
|
|
| event | effect |
|
|
|---|---|
|
|
| `Admitted` | the claim's estimate is reserved against its entitlement, and the **class** it declared is recorded beside it |
|
|
| `Released` | the reservation is lifted and the **actual** figure charged in its place |
|
|
|
|
The class is recorded in the `Admitted` entry rather than kept by the
|
|
scheduler. §6.1 makes the ledger the only durable state, and a caller-side map
|
|
from claim to class would be exactly the second store that can drift from it.
|
|
Without it the history cannot be read back as evidence about a *kind* of work,
|
|
which is what §2.6 needs.
|
|
|
|
A `Queue` or a `Deny` reserves nothing and changes no tenant's usage, so it is
|
|
not a ledger event. Recording it would make the ledger a decision log — a
|
|
different artifact, with a different retention story.
|
|
|
|
On release the actual figure **replaces** the reservation; it is not added to
|
|
it. The reservation was a hold on capacity, and what the tenant spent is what
|
|
it spent. An admission still open at the end of a stream keeps its
|
|
reservation, because the work is still running and the capacity is still held.
|
|
|
|
### 6.3 Overrun
|
|
|
|
A workload that exceeds its estimate is charged what it cost (§6.2). The
|
|
reservation bounded what could **start**, not what was ultimately **spent**
|
|
(§8). Attribution of the overrun is what the grade on each figure is for.
|
|
|
|
### 6.4 The chain
|
|
|
|
Entries are hash-chained: each records the hash of the entry before it, from a
|
|
genesis sentinel. Replay **MUST** verify the chain before deriving any usage,
|
|
and **MUST** report the index of the first broken link rather than a shorter
|
|
history.
|
|
|
|
A release naming a claim that was never admitted, or was released already, is
|
|
an inconsistent stream and **MUST** be refused at its index. It is not a
|
|
shorter history; it is a history that did not happen.
|
|
|
|
### 6.5 The sealed entry
|
|
|
|
Each entry is a **`pool/1` JCR-1 receipt**: a canonical det-CBOR signed core
|
|
(RFC 8949 §4.2.1 — length-first key order, shortest integer form, no floats,
|
|
bools or nulls) inside a COSE_Sign1 envelope (RFC 9052, EdDSA/Ed25519,
|
|
`alg = -8`), with the steward's identifier as `kid`. The core carries
|
|
`pool_receipt`, `seq`, `prev`, `steward`, and the event's own fields.
|
|
|
|
This is the wire format the rest of this family seals with, so a `pool/1`
|
|
receipt verifies under a tool that has never heard of Pool.
|
|
|
|
Two properties, kept distinct because they fail separately, and an
|
|
implementation **MUST** check both:
|
|
|
|
- **Authenticity.** Every entry verifies under the steward's key. An entry
|
|
this steward did not seal is refused, whoever wrote the file.
|
|
- **Sequence.** Every entry's `seq` is its position and its `prev` is the
|
|
content address of the entry before it, from a genesis sentinel.
|
|
|
|
Neither alone suffices. Signatures without a chain admit a bag of valid
|
|
receipts in any order with any subset removed; a chain without signatures
|
|
admits a consistent stream written by anyone.
|
|
|
|
### 6.6 Canonicity is checked, not assumed
|
|
|
|
A signature covers exact bytes. A verifier that accepted a non-canonical
|
|
encoding of the same document would let two distinct byte strings share one
|
|
signature, so an implementation **MUST** refuse a core that decodes but does
|
|
not re-encode to the bytes it arrived as.
|
|
|
|
### 6.7 Witnessing
|
|
|
|
A steward seals its own decisions, so a ledger alone establishes that *this*
|
|
steward wrote *this* sequence — nothing more. A steward able to rewrite its
|
|
whole stream can rewrite a consistent one, because it holds the only key
|
|
involved.
|
|
|
|
A **witness** is a party holding a key the steward does not. It signs the
|
|
ledger's head at a stated length, producing a `pool-witness/1` receipt: a
|
|
statement that the chain reached exactly that head at exactly that length. A
|
|
steward that later rewrites its history produces a different head, and the
|
|
receipt no longer covers it.
|
|
|
|
An implementation **MUST** refuse a witness whose key is the steward's. A
|
|
countersignature from the party being countersigned establishes nothing, and
|
|
reporting it as a witnessed ledger would be the most misleading reading of the
|
|
word available.
|
|
|
|
### 6.8 Attestation is a grade, not a gate
|
|
|
|
An unwitnessed ledger is still a ledger. An implementation **MUST** grade it
|
|
`self-attested` rather than refuse it, and **MUST NOT** report a self-attested
|
|
ledger and a witnessed one as the same thing. The reader weighs the
|
|
difference; the standard's duty is to make it legible.
|
|
|
|
A receipt that verifies but covers a different head or length is distinct from
|
|
one that does not verify at all, and an implementation **MUST** distinguish
|
|
them. The second is a bad signature; the first is what a rewritten history
|
|
looks like from the outside, and it is the more interesting of the two.
|
|
|
|
---
|
|
|
|
## 7. Conformance
|
|
|
|
A conforming implementation **MUST**:
|
|
|
|
1. Enforce both guarantees of §2.1, refusing a claim that exceeds either.
|
|
2. Confine surplus to siblings under one parent, and bound a borrower by its
|
|
weighted share (§2.2).
|
|
3. Carry a grade with every energy figure, and never improve it silently
|
|
(§2.3).
|
|
4. Evaluate admission in the order of §4, refusing the impossible before
|
|
queueing anything (§4.2).
|
|
5. Refuse surplus to an unobserved estimate (§4.4).
|
|
6. Distinguish `Queue` from `Deny`, with a reason on each (§4.5).
|
|
7. Report a reservation together with the grade it rests on (§3, §4.6).
|
|
8. Represent an undefined realised cost as undefined (§5.1).
|
|
9. Order preemption by evidence before declaration (§5.2).
|
|
10. Rebuild usage by replaying its own ledger (§6.1), verifying the chain
|
|
before deriving anything from it (§6.4).
|
|
11. Charge the actual figure in place of the reservation on release, not in
|
|
addition to it (§6.2).
|
|
12. Refuse an inconsistent stream at its index rather than treating it as a
|
|
shorter history (§6.4).
|
|
13. Seal every ledger entry as a `pool/1` JCR-1 receipt, and verify both its
|
|
authenticity and its place in the chain before deriving anything from it
|
|
(§6.5).
|
|
14. Refuse a signed core that is not canonical (§6.6).
|
|
15. Refuse a witness whose key is the steward's (§6.7).
|
|
16. Grade an unwitnessed ledger `self-attested` rather than refusing it, and
|
|
never report it as witnessed (§6.8).
|
|
17. Distinguish a witness receipt that does not verify from one that verifies
|
|
and covers a different head (§6.8).
|
|
18. Degrade a divided figure's provenance, never report a shared device's
|
|
per-tenant figure as `HwShunt`, and never improve a grade by dividing it
|
|
(§2.5).
|
|
19. Conserve a device total exactly across its occupants, distributing the
|
|
remainder by a deterministic rule (§2.5).
|
|
20. Refuse to attribute a device with no occupants or no weight (§2.5).
|
|
|
|
An implementation that derives estimates from history **MUST** also:
|
|
|
|
21. Exclude `Estimator` observations from the evidence rather than averaging
|
|
them in, and report the two counts separately when it declines (§2.6).
|
|
22. Cap a derived estimate's grade at `ModelBased`, however the observations
|
|
were read (§2.6).
|
|
23. Derive nothing below the required count of evidence, and treat a required
|
|
count of zero as one (§2.6).
|
|
24. Refuse an empty class, and never pool observations of differing classes
|
|
into one figure (§2.6).
|
|
|
|
An implementation that reclaims idle capacity **MUST** also:
|
|
|
|
25. Refuse to establish idleness from an `Estimator` figure, testing the grade
|
|
before comparing any value to a threshold (§2.7).
|
|
26. Require a stated window, reach no verdict below it, and treat an empty
|
|
window as no rate rather than a rate of zero (§2.7).
|
|
27. Omit a workload with no verdict from a reclamation ordering rather than
|
|
ranking it last (§2.7).
|
|
28. Reclaim nothing under an unconfigured policy (§2.7).
|
|
|
|
---
|
|
|
|
## 8. The honest limit
|
|
|
|
`pool/1` decides. It does not measure, place or execute, and a verdict is only
|
|
as sound as the figures handed to it: a mis-graded estimate produces a sound
|
|
decision about an unsound number. The grade travels with every figure (§2.3) so
|
|
that a reader of a verdict can see which it was, but nothing here can detect a
|
|
meter that lies about its own provenance.
|
|
|
|
Reservation (§3) bounds what may be *started*, not what is ultimately *spent*.
|
|
A workload that overruns its estimate is a reconciliation problem for the
|
|
accounting layer, not an admission problem; `pool/1` reserves the estimate and
|
|
records its grade so that the overrun is attributable.
|
|
|
|
**A witness is available, and nothing compels one.** §6.7 gives a second party
|
|
a way to sign the ledger's head, so a rewritten history stops being covered.
|
|
What `pool/1` does not do is require it: an unwitnessed ledger is graded
|
|
`self-attested` and still verifies (§6.8). So the guarantee a reader actually
|
|
holds depends on a deployment choice the standard makes legible rather than
|
|
makes for them.
|
|
|
|
**A witness attests the sequence, not the decisions.** A countersigned head
|
|
establishes that the steward did not rewrite what it had already published. It
|
|
does not establish that an admission was correct, that an estimate was honest,
|
|
or that the witness examined anything beyond the head it signed. A witness is
|
|
evidence against revision, not a second opinion on the scheduling.
|