Run trajectory
run_trajectoryRuns one card from a start state through segments of steps, each under its own load, and seals the run. The answer holds the outcome, the final state in decimals and exact hex, a frame for each recorded step, the run_seal and a receipt. record_every sets which steps are recorded, about 262 characters each; the final state comes back in full whatever is recorded. readout gives named quantities in decimals without the frames, with each one's minimum and maximum over every landed step and the first step past a level; it is not part of the sealed request. from starts the run from a sealed run, which is computed again first. A run comes back in one of four ways. outcome "completed": every step landed. outcome "ended": the run reached an end its card declares, which describe_card lists under declared_ends; reject holds the end's name. outcome "refused": a step part way was refused; reject holds the name (null when the cause has none) and reject_detail the sentence. An ended or a refused run is sealed up to its last landed step, steps_landed. An error, not a result: the request was turned away before computing, in one sentence with the refusal's name in round brackets when it has one, and nothing is sealed. A sentence that begins "Physical Failure" says the state asked for or reached is outside the card; one that begins "Physical Violation" says the request, or a number in it or computed from it, is not one the engine takes. A load may be signed; load_source says by whom. The input schema says each of these in full. On this open connection one address holds at most 1 physics permit at a time, and long work (a solve, a plan of runs or of solves, a run of more than 10000 steps, or a verification that computes one again) runs 1 at a time. A call that finds no permit or no place is answered "Too many concurrent physics tasks." and nothing waits: the same call sent later is answered once one is free. An answer is waited for 60 seconds, and long work is stopped there.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| card | Yes | The card of the pair, as list_cards names it. | |
| dt_s | Yes | Step, in seconds. Held for the whole run. | |
| from | No | Optional: start from a sealed run. request: that run_trajectory request as sent, less its readout if it had one: a readout is not part of a run's seal, and a request here that carries one is refused (it may hold its own from); run_seal: its seal; coupling: absent to continue the same card (describe_card says how), or a coupling's name. The upstream is computed again; each carried value must equal its sealed value bit for bit, and a request whose upstream seal or carried value does not hold is refused by name. The run_seal is that of this request without from; chain.chain_seal commits it to the upstream. | |
| domain | Yes | The domain of the pair, as list_cards names it. | |
| initial | Yes | The phase fields of the card at the start of the run, each a number (a vector field is an array of three numbers), and no other key but signed: an instrument's signature over the rest of initial, under the key "initial", by the rule of a segment's signed. describe_card gives the fields, with each unit and bound. | |
| readout | No | Optional. Reads quantities without the frames: {"quantities": [names the card publishes], "first_past": {"quantity": <one of them>, "above" or "below": <level>}}. The answer then holds the named quantities in decimals at the recorded steps, each one's minimum and maximum over every landed step with its step, its time (the step times dt_s) and every other listed quantity at that step (at_minimum, at_maximum), and first_past when asked. With record_every equal to the steps, one state is recorded and the readout gives the extremes of every step. Not part of the sealed request: the run_seal is that of the same run without it, and the receipt covers it. | |
| segments | Yes | A segment may carry signed beside its load: an instrument's signature over the load. signed holds alg "ed25519"; key, the instrument's public key as 64 hex digits, its identity; instrument, the name it gives itself, a label of at most 200 characters; time, its clock, RFC 3339 in UTC ending in Z; seq, its reading counter, below 2^53; prev, the SHA-256 of its previous reading's signed text, or null; challenge, hex the relying party chose, or null; and sig, the signature as 128 hex digits. The instrument signs the bytes "zero-trust-physics/signed-reading/v1" and a line break, then the sealed form (the text a request's seal is taken over: keys sorted by their bytes, each number x and the 16 hex digits of its 64-bit float, no spaces) of the object of alg, key, instrument, time, seq, prev and challenge with the reading under its place's key: "load" for a segment's load, "initial", "parameters" or "measurement" for the object it sits in, without signed. Ed25519 as RFC 8032 section 5.1.7, strict: the key and R canonical points of more than small order, S below the group order, the cofactorless equation. It is verified before computing, every field required and none filled in: a signature that does not verify is refused as LoadSignatureDoesNotVerify, a field of the wrong form as LoadSignatureMalformed, an alg other than "ed25519" as LoadSignatureAlgorithmNotServed, and a plan or search that would set a signed value as SignedLoadReplaced. The seal covers the signature, since it covers the request. A signature shows that the holder of the key stated the reading; whether the key is a real instrument's is the verifier's list. Every run answer carries load_source: for a run with no signed load, the count of segments, none signed, and a sentence that each load is the number the request states; for a signed run, how many loads are signed, whether initial is, whether each key's readings form one unbroken stream (prev and seq), and for each key its fingerprint, the name it gives itself, its places, times, seq and challenges. It is outside the run seal, follows from inputs, which the seal covers, and is covered by the receipt. | |
| record_every | Yes | A state is recorded at each multiple of record_every and at the last landed step. The size of the answer follows from the request: about 262 characters for each recorded state, plus the request as it was sent, plus up to 8000 characters for the final state and the seals; a flagged state adds about 400 characters for each limit it is past (exceedances). So 10,000 steps with record_every 1 answer with about 2.3 million characters, and the same steps with record_every 10000 with one recorded state. What keeps it small: a larger record_every; the final state is returned in full whatever is recorded. |