PaymentVerification standalone install · one product

Collection

The rest of this console is about refusing data that will not hold a decision up. This page is the other half: what to collect, in what order, from whom, and what a contribution turned out to be worth.

A refusal that names what would fix it is a task list. The same refusal without it is a wall. Everything below is computed by running the modules while this page was built — the role table, the authority figures and the worked assessment are all whatever the code actually returned.

Who is sending it

Four populations put data in: people typing it, instruments measuring it, public feeds supplying it, and software writing about its own work. The console has to be able to tell a supervisor which of the four a number came through, so the channel is derived from the observer and there is no field an integrator can set.

Derived by calling channelOf() on one actor of each kind while this page was built. A record that SAYS it came from an instrument is not evidence that it did — no declared channel field is read anywhere.
ChannelWhat it meansBest class this door can reachIn basis points
CREATORa person typed itSELLER-ASSERTED5000
AGENTsoftware wrote it about its own workMODELED8000
DEVICEan instrument measured itVERIFIED9500
APIa public feed supplied itVERIFIED9500
ORGan organisation asserted itSELLER-ASSERTED5000
UNCLASSIFIEDthe actor is not of a recognised kindMODELED8000

Naming yourself a laboratory earns nothing

The table above turns an actor into a class ceiling, so the obvious attack is to pick a good-looking name. Two things stop it, and both are worth seeing.

A record has to come in through the door. One that has not been through the engine's own intake is refused before it can decide anything:

TIRESIAS_RECORD_NOT_AUTHENTICATED

And with no signed register of who is who, nobody exceeds “an interested party said so”. Under that setting the self-named laboratory and the honest small supplier land in exactly the same place — which is the right answer, because nothing has told the system they are different:

Computed by running the engine's intake under its secure default while this page was built. Before this rule was enforced the first row scored 9500 bp and was PAID on a $2,000,000 decision while the second was refused — the product turning away the truthful supplier and rewarding the one who lied.
The recordWhat it asked to beWhat it gotWas it floored?
a self-named “LAB-TOTALLYREAL”VERIFIEDSELLER-ASSERTEDyes
an honest small supplierSELLER-ASSERTEDSELLER-ASSERTEDno

An operator who really does control their own intake can say so, and that choice is stamped on every record it admits, so a receipt says years later what its classes rested on. What earns a class properly is enrolment in a signed register — then a laboratory is a laboratory because somebody signed for it, not because of how it spelled its name.

What we are collecting, in what order

An operator writes a collection spec: the claims they want, what counts as an acceptable answer for each, which must be present before the next stage opens, and which to chase first. Below is a real spec, planned by spec.plan().

Sealed as sha256:443f297ace57b362… — 2 of 3 fields bind. A receipt cites that digest, so the configuration a decision was made under can be produced years later.
#StageClaimBinds?What is acceptable
11custodyyescustody — as a custody_log, from an organisation or a person
22purityyespurity — as a lab_report, in ppm, between 0 and 1000, at VERIFIED provenance or better, no older than 30 days
32temperaturenotemperature — from an instrument, in C, between -40 and 80

Priority orders collection. It is never a weight.

Priority decides what a contributor is asked for first. It does not reach the engine and it never touches a confidence. Every claim marked binds binds equally, whatever the operator ranked it, because the confidence is the weakest required claim and not an average of all of them.

The task this spec compiles to is {"exposureUSD":250000,"critical":[{"key":"supplier:VOLTCORE|custody"},{"key":"supplier:VOLTCORE|purity","min_class":"VERIFIED","max_age_days":30}]}. There is no priority in it, no stage, and no weight — because the engine has nowhere to put them, and a value handed to a function that discards it is a lie told to the next reader.

The following stream is refused until the one before it is met

Stage 2 does not open until every claim that binds in stage 1 is conformingly held. Data addressed to a stage that is shut is refused, not queued — a queue is where non-conforming data waits to be forgotten about and then used. The same six records were screened twice, once without the custody log and once with it.

Left column: stage 2 is shut, so everything addressed to it is refused for that reason and its own faults are never reached. Right column: the stage is open and each record is refused, or accepted, on its own merits. 2 of 7 records got through.
RecordWithout the custody logWith it
P1 · puritySTAGE_NOT_OPENaccepted
P2 · purityWRONG_UNITWRONG_UNIT
P3 · purityOUT_OF_RANGEOUT_OF_RANGE
P4 · purityBELOW_MIN_CLASSBELOW_MIN_CLASS
P5 · purityTOO_OLD_FOR_SPECTOO_OLD_FOR_SPEC
X1 · colourNOT_IN_SPECNOT_IN_SPEC

A non-conforming stage-1 record does not open stage 2 either. If it did, the rule would be “something arrived about custody” rather than “custody is satisfied”, and any malformed record would unlock the chain.

Who may do what

Read from roles.GRANTS by calling can() for every pair while this page was built.
Rightline usersupervising usermanaging userdirecting userofficer useradministrator
CONTRIBUTEyesyesyesyesyes
VIEW_WORKLISTyesyesyesyesyesyes
SCREEN_STREAMyesyesyesyesyes
ACCEPT_RESIDUAL_RISKyesyesyesyes
AUTHOR_SPECyesyes
SEAL_SPECyes
GRANT_ROLEyesyesyesyes
OFFER_PAYMENTyesyesyesyes
SETTLE_PAYMENTyesyesyes
The acceptance limits are the CORE’s, asked of governance.authorityLimitCentsFor() — not a table this product keeps. An operator who tightens a role sees their own figure here, and a role they did not write down has no authority at all.
RoleWhat it doesMay accept up to
line userContributes observations. Accepts nothing.$0
supervising userReviews the line and accepts small exposures.$10,000
managing userAccepts larger exposures and grants the two roles below it.$250,000
directing userAccepts exposures beyond a manager's authority.$5,000,000
officer userAccepts the largest exposures the governance artefact permits.$50,000,000
administratorAuthors and seals the collection spec. Accepts nothing, at any exposure.$0

The administrator sets the rules and accepts nothing

This looks upside down until you ask what an administrator who could also accept would be: one person who can lower a requirement and then approve the thing the requirement was protecting against, with two signatures that are the same signature. An auditor asking “who could have done this alone?” is asking exactly that, and the answer here is nobody.

Three more separations hold at every level:

There is no waiver, at any level, including the administrator. A required claim cannot be excused. When a decision cannot be supported there are two honest moves: supply the missing evidence, or have a named person with authority for the exposure accept the residual risk. A waiver edits the record so the gap stops appearing; an acceptance leaves the gap where it is and puts a name beside it. Only the second is still true a year later.

What a contribution was worth

A contribution is not scored. It is measured. The gate is run without it and again with it, and the contribution is worth exactly what it changed.

Two contributions, equally well sourced, equally admissible, both accepted onto the record. One moved the decision and one duplicated a claim that was already covered. Computed by running assess() and priceOf() while this page was built.
The contributionWhat it didConfidence moved (bp)Earns
closes the gap that was openCLOSED_A_GAP9500$950.00
more of what is already heldADMITTED_NO_EFFECT0$0.00

The spec is enforced before anything is priced

A contribution measured against a decision the operator configured is first checked against that configuration. Here is a purity reading in the wrong units and outside the declared range, offered against the spec above:

TIRESIAS_CANDIDATE_DOES_NOT_CONFORM_TO_THE_SPEC — tiresias: this contribution does not conform to the collection spec in force (WRONG_UNIT). The spec declares different units for this claim. It declares ppm; this says brix. A number without its unit is not a measurement, and two numbers in different units are not comparable however good either one is. A contribution is measured against the decision the operator configured, so one the configuration does not ask for is not measured and not priced.

It is refused at the door, with a reason its supplier can act on, and it is never measured or priced. The same claim is also floored at the gate, because the spec's own minimum class and maximum age are compiled into the task — so a record that reached the pool by some other route still cannot hold the decision up.

Why this replaces a weighted score rather than wrapping one

As originally filed, this product ranked a contribution with a formula of the shape 0.4·V + 0.3·H + 0.2·U + 0.1·T. A weighted sum lets a strong input compensate for a weak one. Four excellent fields and one absent field average to “good”, and the absent field is the one the decision turns on. The whole engine underneath this console exists so that cannot happen, so the formula is replaced here, not carried forward.

Concretely: strengthening a claim that is already strong earns nothing, because the decision is bounded somewhere else. A weighted sum would pay for it whenever that claim carried the larger coefficient.

What would help

The same measurement, inverted. Given where a decision stands, this names what a contributor could supply that would actually change it, most valuable first.

The ORDER is derived from the gate, not configured: an open gap outranks everything because it bounds the decision at zero, and after that the binding claim is the only one where better evidence moves the number at all.
#ClaimWhat is neededEffectWhy
1supplier:VOLTCORE|purityANY admissible evidencecloses a gapNothing admissible supports this required claim, so it is materialised at zero and bounds the whole decision. Until it is covered, no amount of evidence about anything else raises the outcome.

Combining, trading and exchanging

Inputs can be combined into a derived record, and records can change hands. Both are where a provenance system is defeated if it is going to be, and the attack is not subtle: average one impeccable measurement with one unsupported assertion and present the average.

A combination inherits the WEAKEST class among its parts and the age of its OLDEST part. Combining can only ever make data worse, never better — computed by calling combine() while this page was built.
ClassObserved
a lab resultVERIFIED2026-08-29
a person’s assertionSELLER-ASSERTED2024-01-01
the two combinedSELLER-ASSERTED2024-01-01

What combining does NOT check. Nothing here can tell whether the derived number follows from its parts — two readings of 99.9 and 99.8 combine to whatever the caller says. So the method has to be stated (mean here), it rides on the record and into its lineage, and the result says in its own words that the arithmetic is unverified. The provenance and the dating are checked; the sum is not, and letting the checked half lend credibility to the unchecked half is exactly the laundering this page is about.

A transfer is not an upgrade either. A record that changes hands is the same record: same class, same observation time. Selling data does not make it better sourced, and a marketplace where it did would be a laundry rather than an exchange.

Where a lot came from, where it went, and whether the mass adds up

A lot is split, blended and split again on its way to two customers. Suppose the SECOND supplier's material turns out to be bad. Which customers have it, and which decisions rested on it?

Computed by walking the genealogy while this page was built. Note what is NOT in scope: the sublot that never went near the blend, and the decision that rested on it. A recall that swept those in would be over-broad, and over-broad is how a recall stops being actionable.
QuestionAnswer
Which lots are affected?RAW-2, MIX-1, CUST-X, CUST-Y
Which decisions rested on them?CUST-X → sha256:aaa… · CUST-Y → sha256:bbb…
How much reached each?RAW-2 → MIX-1: 1000 kg · MIX-1 → CUST-X: 500 kg · MIX-1 → CUST-Y: 500 kg
What was it made from?(nothing — it is a raw input)

Why this scope is complete, rather than merely thorough

Most lineage systems have to ask, at every hop, whether a downstream lot somehow became trustworthy again — because in most systems blending, re-testing or selling can raise a record's standing. So the answer is either "recall everything that ever touched it" or a judgement somebody has to defend, hop by hop.

Here it rests on arithmetic, and the scope is COMPLETE BY CONSTRUCTION rather than by search effort. Nothing in this product can raise a class or refresh a date. A blend takes the weakest of its parts and the age of the oldest; a transfer changes custody and nothing else. So no descendant of a bad lot can have out-classed the problem, and there is no hop at which one could have escaped.

That is a property of the combining rule, not of the recall — so a test asserts it against the combining rule itself. The day blending stops flooring is the day that test fails, rather than the day somebody discovers a recall came up short.

Mass is conserved, and loss is declared rather than inferred

1,000 kg split into 400, 300 and 299 with 1 kg declared lost balances exactly. The same split with the kilogram simply missing does not:

TIRESIAS_MASS_NOT_CONSERVED — tiresias: the split of `RAW-1` does not balance.

Loss is real — trim, sampling, evaporation — and a system that forbade it would be unusable. A system that inferred it would be worse: the difference between what went in and what came out is exactly the quantity a diversion hides in. Quantities are whole numbers in a named unit, and a unit mismatch is refused rather than converted, even where converting would balance it.

What this page does not do

PaymentVerification · standalone install · one product · built by 27-console/build-console.js from the register, not typed.

This page loads nothing from another origin, makes no request at run time, and touches no browser storage. It works from a file on disk with no server.

Nothing in this console is legal advice.