Zero-Trust Physics
Server Details
A physics verifier for Super Intelligence. Every answer comes with a cryptographic proof.
- Status
- Healthy
- Uptime
- 99.9% over 20 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 18 tools
Most tools have clearly distinct purposes: discovery (list_*, find_model), description (describe_*), execution (compute_step, run_trajectory, solve, run_dataset), design/search (design_run, find_flip), validation, and verification. The main ambiguity is compute_step and verify_step, which are explicitly the same operation under two names, so an agent must know to prefer compute_step. Other overlaps (run_trajectory vs run_dataset vs design_run vs find_flip) are sufficiently differentiated by descriptions.
The set mostly follows a predictable verb_noun pattern: describe_card, run_trajectory, verify_solution, list_cards, find_flip. Exceptions are cite and solve (single verbs), and verify_step is inconsistent because it sounds like a verification tool but is actually an alias for compute_step. These are noticeable but not chaotic.
Eighteen tools is on the high side, but the server covers a rich physics platform with distinct phases: discovery, description, computation, solving, dataset planning, design, search, validation, and multiple verification targets. The only clear redundancy is the verify_step alias, which could be removed to tighten the surface.
The surface is very comprehensive: it supports model discovery and description, citation, single-step and trajectory computation, solving, dataset execution, design/optimization, flip search, measurement validation, and verification of receipts, runs, solutions, datasets, and designs. No obvious lifecycle gap is apparent for the stated domain.
Available Tools
18 toolsciteCiteARead-onlyIdempotentInspect
Gives how to cite a card or a solver: the service itself first (Zero-Trust Physics, its maker and its address) and the paper (https://doi.org/10.5281/zenodo.23517223), then the people whose measurements the model stands on (authors, title, year, address, and what each asks of those who use its data), each as text and BibTeX. With domain and card, or solver, the answer is for that model; with neither, it is how to cite the service itself: its name, who made it, its address and the paper.
| Name | Required | Description | Default |
|---|---|---|---|
| card | No | ||
| domain | No | With card: a card, by the name find_model or list_cards gives; the two give the same names. | |
| solver | No | In place of domain and card: a solver, by the name find_model or list_solvers gives. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), and the description adds real value beyond them: it discloses the exact response content — service identity, DOI, per-dataset authors, and both text and BibTeX renderings. Nothing is said about partial/no-match inputs, which is the only notable gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The two-sentence structure is front-loaded with the core purpose, but the second sentence repeats the first (the service name, maker, address and paper are stated twice in near-identical terms), and the run-on enumeration of fields makes it harder to scan than necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-required-parameter read tool with no output schema, the description is nearly sufficient: it enumerates return content and covers every input combination including the empty case. Only the naming/format of the citation keys and behavior on unknown card or solver names is left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67% and the 'card' property has no schema description at all, so the description has to carry some weight. It does clarify the domain+card pairing versus solver-as-substitute and the zero-argument case, but 'card' itself is never defined beyond the pairing hint, leaving that gap only partly filled.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource: it says the tool returns citation information for a card, a solver, or the service itself, and even previews the citation contents (service, DOI, measurement authors). It is clearly distinguishable in substance from describe_card/describe_solver, but it never names those siblings to draw the contrast explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the parameter mapping ('With domain and card, or solver... with neither, it is how to cite the service itself') tells the agent how inputs select the answer, but there is no statement of when to reach for this tool rather than describe_card, describe_solver, or find_model, despite those being plausible confusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compute_stepCompute stepARead-onlyIdempotentInspect
Computes one anchored step of one card and returns the state it lands on, in decimals and exact hex, with its cryptographic proof (sha384_seal) and a receipt. parameters holds the card's phase fields, its load fields and dt_s, as describe_card gives them. A step whose request or whose landing state is outside the card is refused in one sentence, with the refusal's name in round brackets when it has one, and no proof is issued for that state. With from, the step starts from a sealed run, which is computed again first. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| card | Yes | The card of the pair, as list_cards names it. | |
| from | No | Optional: a sealed run to start from, as run_trajectory takes it. | |
| domain | Yes | The domain of the pair, as list_cards names it. | |
| parameters | Yes | The step's inputs: the card's phase fields, its load fields and dt_s, each a number (a vector field is an array of three numbers), and no other key. describe_card gives the fields of the pair, with each unit and bound. A required field left out is refused as InputMissing, in a sentence that names the field, and a card the engine does not serve as UnknownCard; nothing is filled in. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses that out-of-card steps are refused in one sentence with the refusal name and no proof, that one address holds at most one physics permit (with 1-at-a-time long work), the exact 'Too many concurrent physics tasks.' response with no queueing, and a 60-second wait cutoff. These are concrete operational limits an agent cannot get from readOnly/idempotent hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action and result before the caveats, and every sentence carries non-redundant behavioral information. It is dense and clause-heavy with jargon ('physics permit', 'anchored'), which slightly hurts readability, but there is little waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, nested-input tool with no output schema, the description covers the return payload (state, proof, receipt), refusal behavior, concurrency, and timeout. The only soft spot is that the 'receipt' contents are not characterized, but nothing essential to calling it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds real meaning: parameters must hold exactly the card's phase and load fields plus dt_s with correct units/bounds from describe_card, and it names the InputMissing and UnknownCard refusal modes. This clarifies failure semantics beyond the schema's field list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Computes one anchored step of one card') plus what it returns (landing state in decimals/hex, sha384_seal proof, receipt). It does not explicitly contrast itself with the related siblings verify_step or run_trajectory, so an agent must infer the distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: 'With from, the step starts from a sealed run' gives a conditional for one parameter, and 'parameters ... as describe_card gives them' routes to a sibling for input shape. There is no explicit when-to-use-this-vs-verify_step guidance or prerequisite statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_cardDescribe cardARead-onlyIdempotentInspect
Describes one domain and card pair: inputs, units, bounds, step limits, reject names and meanings, advisory flags, frame slots, and worked examples. With form "short" the answer is a page, enough to write a first request: what the model is of, the evidence behind it in numbers, each input with its unit and range, the names of its stops, and a worked request. The full form, the answer when form is left out, adds each bound's reason, the validation record and each stop's meaning.
| Name | Required | Description | Default |
|---|---|---|---|
| card | Yes | The card of the pair, as list_cards names it. | |
| form | No | Leave this key out, or "full", for the whole description; "short" for a page that is enough to write a first request. | |
| domain | Yes | The domain of the pair, as list_cards names it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and closed-world behavior, so the safety profile is covered. The description adds real value beyond them: the default-form behavior when the key is omitted, and the differing depth of the short versus full response. It omits error handling for unknown domain/card names, but that is a minor gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded in the first clause, followed by the form behavior. It is somewhat dense and the enumerated content lists overlap with the schema description, but every sentence carries information and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining return content and does so for both form variants, which is the key unknown for an agent. All three parameters are documented. It stops short of describing failure modes or how the pair names must match list_cards output beyond the schema note.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes further by spelling out what the 'short' form returns (a page sufficient to write a first request) and what 'full' adds (each bound's reason, the validation record, each stop's meaning). This meaningfully extends the enum's semantics beyond the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Describes one domain and card pair') and enumerates the exact content returned (inputs, units, bounds, step limits, reject names, advisory flags, frame slots, worked examples). This clearly distinguishes it from the sibling list_cards, which only names cards rather than describing a single pair in depth.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the short-vs-full tradeoff and that omitting form yields the full answer, which is genuine usage context. However, it never states when to reach for describe_card versus siblings like list_cards or describe_solver, and gives no exclusions or prerequisites. Usage is implied rather than guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_solverDescribe solverARead-onlyIdempotentInspect
Describes one solver: inputs and bounds, outputs, invariants and tolerances, refusal names and meanings, the published reference, and a worked example. With form "short" the answer is a page, enough to write a first request: what the model is of, the evidence behind it in numbers, each input with its unit and range, the names of its stops, and a worked request. The full form, the answer when form is left out, adds each bound's reason, the validation record and each stop's meaning.
| Name | Required | Description | Default |
|---|---|---|---|
| form | No | Leave this key out, or "full", for the whole description; "short" for a page that is enough to write a first request. | |
| part | No | Leave this key out to get the solver's whole description. Some long descriptions name, under 'more', parts kept back for asking: set part to one of the names listed there for that part alone. Only a name listed under 'more' is a part. | |
| solver | Yes | The solver, as list_solvers names it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/closed-world, so safety is covered. With no output schema, the description carries the return-content burden and does so well, spelling out what the short page contains versus what the full form adds. It omits error/refusal-handling mechanics and any auth or rate-limit notes, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded and each sentence adds distinct information about the short and full forms. Some phrasing is circuitous ('the names of its stops', 'the validation record'), costing a little efficiency, but nothing is pure filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, no-output-schema tool, the description supplies what an agent needs: what the solver description contains, how the two forms differ, and where solver names come from. Only minor gaps remain around part-selection behavior and failure modes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes beyond the schema's one-line enum note by enumerating what each form actually returns, giving the agent a substantive basis for choosing short vs full. The 'part' parameter's mechanics are left to the schema, so it is not a full 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (describes) and resource (one solver) and enumerates exactly what is covered: inputs and bounds, outputs, invariants and tolerances, refusals, reference, and a worked example. It also implicitly distinguishes itself from list_solvers by pointing at that tool as the source of solver names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly explains when to pick the short form (enough to write a first request) versus the full form (the default, adds bound reasons, validation record, and stop meanings), which is real decision guidance. It does not, however, say when to reach for this tool over siblings such as describe_card or find_model, so no explicit alternative/exclusion is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
design_runDesign runARead-onlyIdempotentInspect
Designs a run: from a target end state to the loads of each segment that reach it, computed by the engine with no randomness, so the same request gives the same bits. request is a run_trajectory request; its numbers at the places vary names are the start, and vary gives each load's span inside the card's bounds. target is a number of the final state, a value and a tolerance. Every candidate is an ordinary run with its run_seal; one that crosses a limit is recorded refused by its name, and no value is moved back. The answer gives the timeline, its run_trajectory request and run_seal, the value reached and the miss, every candidate in order as a run_dataset plan with its dataset_seal, and a design_seal. Outcome reached; not_reached, meaning this search found none inside its caps, which is not a limit of the physics; or refused: TargetOutsideCard for a target outside the card's range, TargetBeyondReach where the card's map is monotone and a corner of the loads allowed falls short. The search is coordinate bisection, capped at 64 candidates (DESIGN_MAX_CANDIDATES), 1000000 steps (DESIGN_MAX_STEPS) and 10000 recorded frames (DESIGN_MAX_FRAMES) in all, and 4 sweeps (DESIGN_MAX_SWEEPS). verify_tape, given this whole answer as it came, designs it again and compares the two, byte for byte (the long form). On this open connection a design is long work whenever its candidates may take more than 10000 steps together. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| vary | Yes | From 1 to 8 loads the search sets, in the order a sweep takes them. The search sets loads only, never a start value, the step or the steps, and each load is held constant through its segment. low and high are the span the actuator allows; each lies at or inside the card's declared bound of the load, and a load the card bounds by nothing of its own (the cold plate's heat_power_w) is bounded by this span alone. | |
| target | Yes | The end state to reach: the quantity of the run's final state within value plus or minus tolerance, after its last step, or, for a run that ends at an end its card declares (a reactor past its first maximum of power), where the event finished. A run refused part way gives no value. A target outside the range the card declares for that quantity is refused before any run (TargetOutsideCard). | |
| request | Yes | A run_trajectory request as that tool takes it, with no from or readout, and a number at every place vary names: the search's start. Nothing is filled in. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the annotations (readOnly/idempotent/non-destructive): it discloses determinism, the bisection algorithm, exact caps (64 candidates, 1e6 steps, 10000 frames, 4 sweeps), concurrency rules (one physics permit, long work runs singly), the 'Too many concurrent physics tasks.' response with no queueing, and a 60-second timeout. The refusal outcomes and their meanings are spelled out in detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is largely load-bearing and front-loaded with the purpose, but it is delivered as long run-on sentences that bundle purpose, return shape, outcomes, caps and concurrency into dense prose. Most clauses earn their place, yet readability and structure suffer.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by enumerating the answer's contents (timeline, run_trajectory request and run_seal, value reached and the miss, candidate plans with dataset_seals, design_seal) plus all outcome values. Given the tool's complexity and nested schema, this is nearly complete, missing only exact definitions of a few terms like 'miss'.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents request, vary and target thoroughly, including the low/high span semantics and the TargetOutsideCard rule. The prose adds conceptual framing (vary names are the start, loads held constant through segments) but largely restates what the schema provides. Baseline 3 for high coverage is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: it designs a run, going from a target end state to the per-segment loads that reach it, deterministically. It also names verify_tape as the verification counterpart, giving some sibling differentiation. The dense, idiosyncratic phrasing ('the same request gives the same bits') slightly obscures the purpose but does not hide it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the purpose (design a run to hit a target) and the description distinguishes verify_tape as the tool that re-designs and compares the answer. However there is no explicit when-to-use statement relative to run_trajectory, run_dataset or solve; the agent must infer the selection from context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_flipFind flipARead-onlyIdempotentInspect
Finds where an outcome changes, and gives the run on each side. request is a run_trajectory or solve request written out, its domain and card or its solver by the name find_model or the lists give, with no from, readout or example; vary is the place of the one number to change, such as "segments[0].load.current_a", "initial.soc", "dt_s" or "parameters.load_n"; low and high are the two ends of the span, in either order: the smaller is taken as low. The span is halved to the place where the outcome or the stop name changes or, with level, where a published quantity of the final state (of a solve: of result) crosses a value or a flag turns. When both ends give the same, 7 values between them (3 for solves) are run to find a band, and the answer says so. The answer gives the run on each side as a request ready to send again, with its outcome, its stop name and sentence and the run_seal or solution_seal that request has when sent alone, the two values in decimals and exact hex, and the width between them. A side that stops before computing has no proof. The same request gives the same pair. A search is bounded, and names the bound that stops it: 64 runs (FLIP_MAX_RUNS), 1000000 steps in all (FLIP_MAX_STEPS), or 64 solves (FLIP_MAX_SOLVES), the ends included, and no new solve once those made are counted at 20 s (FLIP_MAX_SECONDS); the pair it gives, sent back as the span, narrows it further. On this open connection a search is long work whenever it varies a solve or its runs may take more than 10000 steps together. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| low | Yes | One end of the span. low and high may come in either order; the smaller is taken as low. | |
| high | Yes | The other end. | |
| vary | Yes | The place of the one number to vary: "segments[0].load.current_a", "segments[*].load.current_a" for every segment, "initial.soc", "dt_s", "segments[0].steps", "parameters.load_n". A count is varied in whole numbers. | |
| level | No | Optional. {"quantity": <a published quantity>, "value": <number>}: the span is halved to where that quantity of the final state (of a solve: of result) crosses the value. {"quantity": <a flag>}: to where a true-or-false value of it turns. | |
| request | Yes | A run_trajectory or solve request as that tool takes it. A search of solves makes no new solve once those made are counted at 20 s (FLIP_MAX_SECONDS), each at the time describe_solver states for one solve of its solver (open_connection), and always makes at least 3, both ends and one value between them: a count, not a clock, so the same request stops at the same solve on any machine. A search of runs is held by its steps (FLIP_MAX_STEPS). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint/idempotentHint already covering safety, the description still adds substantial operational context: concurrency limits (one physics permit at a time, long work serialized), the exact error text 'Too many concurrent physics tasks.' and its no-wait behavior, a 60-second wait cap, and concrete bounds (FLIP_MAX_RUNS 64, FLIP_MAX_STEPS 1000000, FLIP_MAX_SOLVES 64, FLIP_MAX_SECONDS 20 s). It also discloses determinism ('The same request gives the same pair') and that a stopped side 'has no proof'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, but the remainder is a dense run-on block mixing parameters, algorithm, return shape, and limits without paragraph or bullet separation. Nearly every clause carries information, so it is not padded, but the idiosyncratic phrasing makes it slow to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, nested-parameter tool with no output schema, the description is remarkably complete: it explains the return payload (a re-sendable request per side, outcome, stop name/sentence, run_seal or solution_seal, decimal and hex values, width), the bisection fallback when both ends match, and all bounding/limit conditions. An agent has what it needs to invoke and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning the schema does not: request must be written out 'with no from, readout or example', level resolves against a published quantity of the final state (of a solve: of result), and count-valued vary targets are varied in whole numbers. These constraints genuinely extend the parameter definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause states a specific verb and resource: 'Finds where an outcome changes, and gives the run on each side' — an agent can tell this is a bisection/boundary-search tool over a parameter span, distinct from solve, run_trajectory, or compute_step. The peculiar grammar ('gives the run on each side') slightly obscures it, but the operation is identifiable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies usage by specifying that request must be a run_trajectory or solve request, that vary names the single number to change, and that low/high bound the span. It also notes the returned pair can be sent back to narrow further. However, it never explicitly says when to choose this over solve or run_trajectory, nor when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_modelFind modelARead-onlyIdempotentInspect
Finds the served model for a real thing described in plain words, such as "a lithium cell discharging in the cold". It returns the best few cards and solvers, each with fit first (the words that matched, and model_of: the one real thing it is a model of, and its range) and then accuracy: against_measurement, the evidence behind it in one of three words, as list_cards and list_solvers give it ("compared with measurement", "held to a reference calculation" or "company specimen"); compared_with, what it was fitted on; and accuracy_against_measurement, what it was compared with outside the fit, within what, and the gap, in numbers. Fit and accuracy are separate: a model with a gap is still the served model of its thing. The names it gives (domain and card, or solver) are the names list_cards and list_solvers give and the names describe_card, describe_solver, cite and every other tool take; describe_card or describe_solver gives the range and every refusal. When nothing served fits it says so, having compared every card and solver, names the nearest by words and why they are not it, or says that there is no near one, and says where requests for a model go. A model is set aside when the description names another thing of its kind (another gas, another maker's cell, another planet's probe). It is matched against a fixed list of terms with no model call: the same words give the same answer.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many models to return; 3 when left out. | |
| description | Yes | The real thing, in plain words. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds genuinely non-obvious behavior: matching runs against a fixed term list with no model call, the same words give the same answer, and a model with an accuracy gap is still the served model of its thing. That determinism and the fit/accuracy distinction go beyond anything in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first clause, but the rest is a sprawling run-on of comma-spliced clauses that pack output-format, semantics and fallback behavior into undifferentiated prose. Much of that content is necessary given the absence of an output schema, yet the presentation makes it hard to parse and should be broken into discrete statements.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must and does explain the return shape: a few cards and solvers, each with fit first then accuracy, including the three-word evidence vocabulary and the names that feed other tools. It also covers the no-match outcome. What is missing is a crisp statement of input expectations (how short or literal the description should be).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters are documented there, including limit's default of 3. The description only reinforces 'in plain words' for description and adds an example query, offering no syntax or constraint detail beyond the schema. Baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: it finds the served model matching a plain-language description of a real thing. It distinguishes itself from siblings by naming list_cards, list_solvers, describe_card and describe_solver as the tools that share its vocabulary and take its returned names. The domain jargon ('served model', 'cards and solvers') is idiosyncratic but the core action is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It effectively routes the agent: find_model locates and names the model, while describe_card or describe_solver 'gives the range and every refusal', implying the lookup-then-detail flow. It also covers the no-match path and says where requests go when nothing served fits. It never states an explicit trigger for the inverse case (when to skip find_model and go straight to describe_card), so it falls short of a full when/when-not statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_cardsList cardsCRead-onlyIdempotentInspect
Lists every domain and card this connection serves, each with one sentence, and count, how many there are. against_measurement names the evidence behind the model, in one of three words: "compared with measurement" (a real object; its description says what it was fitted on, what it was compared with outside the fit and within what, the gap, and where it refuses), "held to a reference calculation" (compared with a published calculation), or "company specimen" (an object the company specified, every constant stated). The numbers say how good it is.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=false and destructiveHint=false, so the safety profile is covered. The description adds some output context (a per-card one-sentence summary plus a count, and the against_measurement taxonomy), which is useful, but it is phrased so confusingly that the behavioral value is diluted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The text is a run-on with broken syntax ('each with one sentence, and count, how many there are') and dumps a three-way enumeration of against_measurement values mid-stream. It is neither front-loaded nor economical; the reader has to reconstruct meaning rather than absorb it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the full burden of explaining the return shape, and it does attempt this. But the explanation is jumbled and incomplete, giving no clear sense of the record structure, ordering, or what 'count' refers to, so the agent cannot confidently predict the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, which establishes the baseline of 4. The schema also states 'No arguments. Returns every domain/card pair,' so there is nothing further for the description to clarify on this dimension.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause 'Lists every domain and card this connection serves, each with one sentence, and count' does state a verb and resource. However, the rest of the description veers into garbled commentary about output fields (against_measurement, 'the numbers') rather than reinforcing what the tool is for. It never distinguishes itself from the sibling describe_card, leaving the agent to infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use, no prerequisites, and no mention of alternatives, despite describe_card and list_solvers being obvious siblings. The agent gets no guidance on when to enumerate cards versus describing a single one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_solversList solversARead-onlyIdempotentInspect
Lists every field solver this connection serves, each with one sentence, and count, how many there are. against_measurement names the evidence behind the model, in one of three words: "compared with measurement" (a real object; its description says what it was fitted on, what it was compared with outside the fit and within what, the gap, and where it refuses), "held to a reference calculation" (compared with a published calculation), or "company specimen" (an object the company specified, every constant stated). The numbers say how good it is.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint=false, so the safety profile is covered. The description goes beyond that by decoding the return payload: against_measurement is explained as a three-valued provenance field with the meaning of each value, and it explains what the accompanying numbers signify. That is real added context in the absence of an output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The prose is grammatically broken ('each with one sentence, and count, how many there are') and the explanation of against_measurement is delivered as a dense run-on with nested parentheticals that are hard to parse on a first read. The enum semantics are worth including, but the front-loading is poor and the phrasing needs rework, so it neither reads cleanly nor earns every clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must carry the full burden of describing the return shape. It does explain against_measurement and the meaning of the numeric fields, which is valuable, but it leaves other per-solver fields, the list format, and any ordering or sizing behavior unaddressed. Adequate but with clear gaps for a zero-argument enumeration tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters and the schema states plainly that no arguments are accepted and all solvers are returned. With no parameters to disambiguate, this is the baseline 4; nothing in the description contradicts or muddies the empty input contract.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: it lists every field solver available on this connection, with a per-solver statement and a count. That is clearly distinguishable from a single-solver lookup such as the sibling describe_solver. It stops short of naming that sibling, so the differentiation is implied rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The scope ('every field solver this connection serves, ... how many there are') implies this is the enumeration entry point and that detail work belongs elsewhere, but it never states when to prefer it over describe_solver or any other sibling. No prerequisites, no exclusions, no explicit alternative. Usage is inferable but not guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_datasetRun datasetARead-onlyIdempotentInspect
Runs a declared plan of runs on one card, or of solves of one solver, and seals the rows under one root. A plan is a list of runs, a grid over a base run, or a seeded sample over a base run; a run is a run_trajectory request without domain and card. A plan of solves names solver in place of domain and card and is a list or a grid of solve requests. The answer is small by default: the head, which holds the request, the counts and the dataset_seal, and one summary row per run; answer "states" adds each final state in decimals and "full" gives every row whole, under the same dataset_seal. A row is completed, ended, refused or unadmitted: an ended or a refused row is a run sealed up to its last landed step, and an unadmitted row is a request turned away before computing, with no seal. The seal shows the dataset was not altered after it was sealed. It does not show the engine made it: a row's request sent to run_trajectory gives the run seal to compare. The input schema says how each input is written, with a worked plan of each kind. On this open connection a dataset is returned inline and holds at most 300 runs (OPEN_MAX_DATASET_ROWS), 1000000 steps in all (OPEN_MAX_DATASET_STEPS), 10000 frames and an answer counted from the plan at 4194304 bytes (OPEN_MAX_DATASET_ANSWER_BYTES) and 42500 characters, up to about 150 summary rows; a plan of solves holds the engine's own 64 and at most 15 s of them, or one, at each solver's measured time, which describe_solver states with the count (OPEN_PLAN_SECONDS). 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.
| Name | Required | Description | Default |
|---|---|---|---|
| card | No | ||
| plan | Yes | A path names one number: initial.<field>, dt_s, or segments[0].load.<field>, with the segment's number in square brackets and [0], [1] or [2] after a 3-vector field for one of its components. steps and record_every are not paths and cannot vary: every row of a grid or a sample takes them from the base run. A value an axis or a draw sets replaces the base's value of that field, and the answer's base_replaced names each field replaced; a 3-vector the base sets whole is replaced only when the paths set all three of its components. Two paths may not set one number. Each row of a grid is held to the card's bounds alone, as each run of a list is: a value outside a bound makes that row unadmitted and the other rows run. A sample's interval or choice outside a bound refuses the plan. One worked plan of each kind, each a whole request: list: {"domain":"energy","card":"thermal","plan":{"kind":"list","runs":[{"initial":{"temperature_k":293.15},"dt_s":1.0,"segments":[{"steps":60,"load":{"heat_power_w":5.0,"ambient_k":293.15}}],"record_every":60}]},"store":"none","return":"inline"} grid: {"domain":"energy","card":"thermal","plan":{"kind":"grid","base":{"initial":{},"dt_s":1.0,"segments":[{"steps":60,"load":{"ambient_k":293.15}}],"record_every":60},"axes":[{"path":"initial.temperature_k","values":[283.15,293.15]},{"path":"segments[0].load.heat_power_w","values":[0.0,5.0,10.0]}]},"store":"none","return":"inline"} sample: {"domain":"energy","card":"thermal","plan":{"kind":"sample","base":{"initial":{},"dt_s":1.0,"segments":[{"steps":60,"load":{"ambient_k":293.15}}],"record_every":60},"rows":4,"generator":"splitmix64_counter_v1","seed_hex":"0000000000000001","draws":[{"path":"initial.temperature_k","choice":[283.15,293.15]},{"path":"segments[0].load.heat_power_w","uniform":{"low":0.0,"high":10.0}}]},"store":"none","return":"inline"}. | |
| store | No | ||
| answer | No | Leave out, or "summary", for the head and one short summary row per row: the values it sets, outcome, steps landed, refusal name and seal; "states" adds each run's final state in decimals; "full" gives every row whole. With return "file" the answer is the head and the names of the files whatever this says. Not part of the sealed request. The head and the dataset_seal are the same in all three forms. A summary row holds row, set (the values a grid's or a sample's row sets), outcome, steps_landed, reject and run_seal; the quantities of one row are read by sending its request to run_trajectory with a readout. An ended row is a run that stopped at an end its card declares: it has a run seal, the end's reject name in reject and the sentence naming the end in reject_detail. A refused row is a run the card refused part way: it has a run seal, the refusal's name in reject and its sentence in reject_detail. An unadmitted row is a request turned away before computing: it has no run seal, and its sentence, with the refusal's name in round brackets when the sentence gives one, is its reject_detail; its summary row gives that name in reject. What a sentence that begins "Physical Failure" or "Physical Violation" means is in the description of run_trajectory. An inline answer is counted from the plan before anything runs, and one above 42500 characters is refused with what to change: a summary row counts 220 characters and the values it sets; with states, each number of the final state adds its name and 28 characters (84 for a 3-vector, 9 for a flag); a whole row counts its own request and 1900 characters, and for each number twice its name and 60 characters (150 for a 3-vector, 9 for a flag); store "frames" adds 128 characters for each recorded state to a full answer; the head repeats the request. | |
| domain | No | ||
| return | No | ||
| solver | No | A plan of solves: the solver, in place of domain and card. It takes no store and no return. A plan of solves is answered inline: a list, {"kind":"list","solves":[{"parameters":{...}}]}, or a grid, {"kind":"grid","base":{"parameters":{...}},"axes":[{"path":"parameters.<input>","values":[...]}]}, of at most 64 solves. Each row is a solve request, solved as solve solves it and carrying the solution_seal solve gives it; a request turned away without a seal, by the rules of a request or by the solver, is an unadmitted row. The rows are sealed under one dataset_seal by the rules of a plan of runs, with solution_seal in the leaf in the place of run_seal, and completed in the counts counts the solves that converged. A summary row has row, set, outcome, reject, solution_seal and every single number of the result in decimals; answer "full" gives every solution whole, and is refused when it comes to more than 42500 characters. verify_dataset verifies a plan of solves by its request and dataset_seal, and validate_series compares one number of its results with measurements. Worked plan of solves: {"solver":"atom_dft","plan":{"kind":"list","solves":[{"parameters":{"atomic_number":10}}]}}. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/idempotent annotations by disclosing real operational behavior: per-address physics permits, one-at-a-time long work, the exact refusal string 'Too many concurrent physics tasks.', a 60-second answer wait with long work stopped there, and the row/step/frame/byte limits. It also explains the seal's guarantee precisely ('the seal shows the dataset was not altered after it was sealed. It does not show the engine made it'), which is context structured fields cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded, but the body is a dense, run-on block that mixes limits, seal semantics, error handling, answer sizing and return shapes without structure or line breaks. Much of this (dataset_seal contents, summary-row fields, character-cost arithmetic) reads as reference documentation that should live elsewhere, and the wall of text makes it hard to skim.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return burden and does so: it names the head contents (request, counts, dataset_seal), the summary-row fields (row, set, outcome, steps_landed, reject, run_seal), and the outcomes completed/ended/refused/unadmitted with their seal rules. Some return details remain terse, but an agent has enough to interpret the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 43% across 7 parameters, so the description is obliged to compensate and largely does: it constrains answer/states/full, store frames vs none, inline vs file sizing, the solver-plan form (no store/return), and it points to the schema for input syntax. It stops short of restating path grammar itself, deferring to the schema's worked examples, so it is additive but not fully self-contained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Runs a declared plan of runs on one card, or of solves of one solver, and seals the rows under one root') and enumerates the three plan kinds. It actively distinguishes itself from siblings, positioning run_trajectory as the single-run primitive whose seal can be compared, and naming verify_dataset and validate_series for downstream work.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The selection rationale is only implied: the tool batches many runs or solves, and file vs inline store/return is tied to size limits, so an agent can infer when to use it. But there is no explicit 'use this instead of N run_trajectory calls' or 'do not use for a single run' statement, and no prerequisites or preconditions are spelled out in usage terms.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_trajectoryRun trajectoryARead-onlyIdempotentInspect
Runs 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.
| 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed world), but the description adds genuinely useful behavioral context beyond them: the concurrency regime (1 physics permit per address, long work serialized), the 60-second answer timeout, that calls finding no permit do not queue, and a full outcome/error taxonomy. This is substantial disclosure of constraints an agent cannot get from the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is correctly front-loaded, but the prose is dense, run-on and stylistically obscure ('sealed up to its last landed step', 'every landed step'), and the outcome/refusal taxonomy is restated at length in the schema's own description. Much of it earns its place for a complex tool, yet the redundancy and readability cost keep it below a strong score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 8-parameter tool with nested objects and no output schema, the description covers what is needed: the result shape (outcome, final state in decimals and hex, per-step frames, run_seal, receipt), the four outcome cases, error versus result distinction, and operational limits. Only minor gaps remain, such as how steps_landed relates to the receipt or how a signed run's load_source appears in the answer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents every parameter in depth, and the description largely mirrors it (record_every's 262-char-per-state sizing, readout not being part of the sealed request, from re-computing the upstream). It adds alignment and the size implications of record_every, but little that the schema does not already say, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb and resource — 'Runs one card from a start state through segments of steps, each under its own load, and seals the run' — so the agent knows this executes a trajectory and produces a sealed run. It is not merely a restatement of the title. However, it never contrasts itself with sibling execution tools such as design_run, solve or run_dataset, so differentiation is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the description explains that 'from' continues a sealed run and that 'readout' is outside the seal, which hints at when those options apply. It also tells the agent what to do when 'Too many concurrent physics tasks' is returned (retry later). But there is no explicit when-to-use-this-vs-alternatives statement, and no prerequisites or preconditions for choosing this tool over its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
solveSolveARead-onlyIdempotentInspect
Solves one field problem with one solver and seals the solution: the outcome, the result in decimals and exact hex, its invariants, the solution_seal and a receipt. parameters holds the solver's inputs as describe_solver gives them. example, in their place, is the name of a worked example describe_solver lists (example_solve, or a key beginning example_solve_), so a long worked input need not be typed again; the request is filled with that example's parameters, and the filled request is the one solved, sealed and returned as inputs. The receipt covers the request as it was written, number spellings included, while a seal covers its values: a request sent with 310 and the same request sent with 310.0 give different receipts and the same seal, so a receipt that differs between two such answers is not a sign of tampering. A chained solve, from a sealed card run through a coupling (from), takes each handed value in parameters bit for bit: decode it from the run's frame_hex or a _hex value, not a decimal readout, or it is refused as CouplingLedgerBreach. verify_solution verifies a solution later from this request, or its inputs, and its solution_seal. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | Optional: a sealed card run handed in through a coupling, as run_trajectory takes it. Each handed value goes into parameters bit for bit, read from the run's frame_hex or a _hex value, not a decimal (CouplingLedgerBreach). | |
| solver | Yes | The solver, as list_solvers names it. | |
| example | No | In place of parameters: the name of one of the solver's worked examples as describe_solver keys it (example_solve, or a key that begins example_solve_). The request is filled with that example's parameters, and the filled request is the one solved, sealed and returned as inputs. | |
| parameters | No | The inputs of the solver named in 'solver', each a number, a whole number, a word, a flag or an array as describe_solver gives it, and no other key but signed. Every number of a solve request must be a finite, normal 64-bit number or zero, and a number written as non-zero must not read as zero. This rule is the one every card's request follows, and it stands beside each input's range and refuses some values inside it: a subnormal such as 5e-324 is refused wherever zero and larger numbers are accepted. A solution has no frame, so the card's rule that a number fit a 32-bit frame slot does not apply. A required input left out is refused as InputMissing, and an input given with a choice it does not go with as InputNotWithChoice, each in a sentence that names the input, and a solver the engine does not serve as UnknownSolver; nothing is filled in. parameters may also carry signed, an instrument's signature over the other parameters under the key "parameters", by the rule run_trajectory's input schema gives at segments; it is verified before solving, the solver takes the other parameters, and the answer then carries load_source, naming the key. A solve answer without load_source holds no signed parameter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already covering readOnly/idempotent/non-destructive, the description adds substantial behavioral context: receipt-vs-seal semantics (310 vs 310.0 yield different receipts but the same seal), named error codes (CouplingLedgerBreach, InputMissing, InputNotWithChoice, UnknownSolver), bit-for-bit coupling rules, a 1-permit concurrency limit, no queueing, and a 60-second cap. None of this is inferable from the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the purpose, but the body is one dense unbroken block and a meaningful share of it duplicates text already present in the schema property descriptions. Every sentence carries information, yet structure and redundancy keep it from being efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter tool with nested objects and no output schema, the description does the necessary work: it describes the returned parts, the sealing model, error behavior, coupling input rules, and timeout/concurrency limits. Residual gaps like the exact shape of "outcome" and "invariants" are minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema's property descriptions repeat the description's text almost verbatim (e.g. the `from` and `example` paragraphs), so the description adds little parameter meaning the agent cannot already read in the schema. Baseline 3 is appropriate given the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a specific verb+resource ("Solves one field problem with one solver and seals the solution") and even enumerates the return parts: outcome, decimals, exact hex, invariants, solution_seal, receipt. It routes indirectly to siblings (describe_solver for inputs, verify_solution for later verification), but it never sets itself against compute_step or run_trajectory explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the key alternatives clearly: use `example` instead of typing parameters, use `from` for a chained solve off a sealed card run, and use verify_solution to verify later. There is no explicit when-not-to-use statement against the other solver-adjacent siblings, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_seriesValidate seriesARead-onlyIdempotentInspect
Runs a run_trajectory request (without a readout) and compares one published quantity with the agent's measurements, each at a landed step. The answer is the error in numbers (rms, mean signed, greatest absolute, model minus measurement, each with its exact hex), the model value at every compared step in decimals (model_values) and exact (model_values_hex), and a hash of the measurements, under one seal. It sets no threshold: the numbers are the answer. The seal has no key, so it does not show who measured or who computed. commitment, optional, opens a salted SHA-384 the measurements were locked with before the comparison: data that are not the committed ones are refused before computing (CommitmentDoesNotMatch), and the seal covers it. genesis_seal verify-validation rebuilds the seal, the statistics and the commitment from the answer alone. In place of run, solves takes a plan of solves as run_dataset takes it (solver and plan, at most 64 solves), each measurement at a row of the plan: the solves are sealed under one dataset_seal, and the comparison by the same rules with the dataset_seal in the place of the run seal and the row in the place of the step; a measured row whose solve did not converge is counted in not_reached. The same request sent again gives the same seal. On this open connection a plan of solves holds the engine's own 64 and at most 15 s of them, or one, at each solver's measured time, which describe_solver states with the count (OPEN_PLAN_SECONDS). 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.
| Name | Required | Description | Default |
|---|---|---|---|
| run | No | One anchored run. Total steps must be <= 1000000. Recorded frames must be <= 10000. The shape of initial and of each segment's load depends on the pair: describe_card gives it. | |
| solves | No | In place of run: a plan of solves as run_dataset takes it (solver and plan, a list or a grid, at most 64 solves). quantity is then one number the solver publishes in its result, and each measurement names a row of the plan, numbered from 0, in place of a step. | |
| quantity | Yes | The name of one number the card publishes in its state, a plain name that has a '_hex' sibling in the state. A flag is refused. | |
| component | No | 0, 1 or 2: which of the three components of a 3-vector quantity is compared. Required when the quantity is a 3-vector, and refused when it is not. Any other value is refused. | |
| commitment | No | Optional: a commitment the measurements were locked with before this comparison, opened by this request. sha384 is the SHA-384 of these bytes: the line zero-trust-physics/measurement-commitment/v2 and a line break; 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 {"component": <this request's component, or null>, "measurements": <this request's measurements>, "quantity": <this request's quantity>}; a line break; and the salt's bytes, its hex decoded. salt is 32 to 128 lowercase hex digits, 16 to 64 bytes, kept back until the comparison so that the data are not found from the sha384 by trying values. The engine makes the digest again from the request before computing: data that do not open it (a value, a step or a row changed, moved, added or dropped, another quantity or another salt) are refused as CommitmentDoesNotMatch, a salt shorter than 16 bytes as CommitmentSaltTooShort, a field of the wrong form as CommitmentMalformed, and sha384 or salt left out as InputMissing; nothing is computed and nothing is sealed. Opened, the comparison runs as it runs without one, validation_seal takes the commitment as a sixth part, and the answer says so in commitment_opened. A commitment shows that the data were not changed after it was made; when it was made is shown by where its sha384 was published before the comparison. | |
| measurements | Yes | At most 10000. A measurement is compared with the state after landed step k. There is no interpolation and no time matching: a measurement is placed by its step, its time since the start divided by dt_s. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover only the safety profile (readOnly, idempotent, non-destructive, closed-world), while the description discloses substantial extra behavior: the seal carries no key and leaks nothing about who measured, no threshold is applied, commitment mismatch error codes (CommitmentDoesNotMatch, CommitmentSaltTooShort, CommitmentMalformed, InputMissing), the 1-permit-per-address limit, 60 s answer timeout, the 'Too many concurrent physics tasks' response, and the idempotency of seals. This is rich context well beyond the annotations, and it does not contradict them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a dense wall of run-on sentences mixing purpose, commitment semantics, seal mechanics, concurrency limits and timeouts. It is front-loaded with the core purpose, but the sheer length and clause-stacking make it hard to parse, and much of the concurrency/timeout material could be trimmed or relocated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a highly complex tool with nested objects, no output schema, and signing/commitment mechanics, the description covers the important operational facts an agent needs: the two input modes, the seal and commitment lifecycle, error routing, concurrency and timeout behavior. Given there is no output schema, it also characterizes the answer's statistics and seal parts, leaving only minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The 6-parameter schema already documents run vs solves, quantity, component, commitment and measurements in depth, and the description largely restates these facts (e.g. the commitment digest recipe appears in both). It adds the framing that a request holds run or solves, not both, but does not materially extend what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening states a specific verb+resource: it runs a run_trajectory request without a readout and compares one published quantity against agent measurements at landed steps. This is clearly distinguished from run_trajectory (no readout) and from its own verify-validation sibling that rebuilds the seal from the answer alone. It stops short of a crisp one-line summary, but an agent can identify the tool's function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use / when-not-to-use statement relative to siblings like verify_step, verify_solution, or cite. References to run_dataset ('as run_dataset takes it') and to verify-validation are about parameter form and seal reconstruction, not about selecting this tool over another. Usage must be inferred from the behavioral prose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_datasetVerify datasetARead-onlyIdempotentInspect
Verifies the seal of a dataset. Short form: request is the run_dataset request as it was sent, and dataset_seal is the seal its answer gave. The plan is run again under run_dataset's permits and limits; the answer is holds, cause ("dataset_seal" when the seal given is not the seal the plan runs to), recomputed_dataset_seal when it holds (else no seal: run_dataset gives the true one), compared, and text_not_compared: no rows the agent holds are compared. A plan of solves is verified by this short form only. Long form: head, rows and frames_hex, the three parts a full answer carries (answer "full"), together, as they came. The rows, the root and the seal are recomputed, and row and fault name the first row changed, swapped, dropped or repeated; then the plan is run again under run_dataset's permits and limits and the engine's answer compared with it, value by value and byte for byte (cause answer_text, with differs_at and row): holds is true only when every byte is the engine's, values_hold when every value is. On this open connection a dataset is returned inline and holds at most 300 runs (OPEN_MAX_DATASET_ROWS), 1000000 steps in all (OPEN_MAX_DATASET_STEPS), 10000 frames and an answer counted from the plan at 4194304 bytes (OPEN_MAX_DATASET_ANSWER_BYTES) and 42500 characters, up to about 150 summary rows; a plan of solves holds the engine's own 64 and at most 15 s of them, or one, at each solver's measured time, which describe_solver states with the count (OPEN_PLAN_SECONDS). 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.
| Name | Required | Description | Default |
|---|---|---|---|
| head | No | With rows and frames_hex: the head a run_dataset answer carries. | |
| rows | No | With head and frames_hex: the rows a full run_dataset answer (answer "full") carries. | |
| request | No | With dataset_seal alone: the run_dataset request as it was sent (the head's request). The plan is run again, under the permits and the limits of run_dataset, and its seal is compared with dataset_seal. Nothing is stored or read from storage, so it works whatever the return mode and on every connection. Its fields are run_dataset's. Worked example of the short form, as the whole arguments: {"request":{"domain":"energy","card":"thermal","plan":{"kind":"list","runs":[{"initial":{"temperature_k":293.15},"dt_s":1.0,"segments":[{"steps":60,"load":{"heat_power_w":5.0,"ambient_k":293.15}}],"record_every":60}]},"store":"none","return":"inline"},"dataset_seal":"<the dataset_seal of its run_dataset answer, 96 lowercase hex digits>"}. | |
| frames_hex | No | With head and rows: the frames a run_dataset answer carries, or null. | |
| public_key | No | The base64 of the ML-DSA-87 public key (2,592 bytes) to verify the answer's signature with; without it, this engine's own. | |
| seen_nonces | No | Nonces of signatures already seen: one of them again is SignatureNonceReplayed. | |
| dataset_seal | No | With request: the dataset_seal of the run_dataset answer, compared with the seal the plan runs to. Alone: the seal of a dataset stored as files (return "file"), read from the connection's own folder of that name. A dataset returned in the answer is not stored: it is verified with its request, or by its head, rows and frames_hex. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only annotations, it discloses concrete limits (OPEN_MAX_DATASET_ROWS, steps, frames, answer bytes), concurrency behavior, the 60-second wait, exact error strings, and signature-verification failure modes. This is a rich behavioral profile that an agent could not infer from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely long and dense, with run-on sentences that pack multiple concepts together and repeat schema-level detail. It front-loads the core purpose, but the body is hard to parse and would benefit from much tighter structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex verification tool with no output schema, it explains the returned fields (holds, values_hold, differs_at, cause), failure modes, signature behavior, and resource limits. An agent would have enough context to invoke and interpret the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already defines each parameter in detail, including a worked example for the short form. The description reinforces form combinations but adds little syntax or semantic detail beyond what the schema provides; baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and resource: 'Verifies the seal of a dataset.' The three forms are then enumerated with enough detail to see the scope. However, it never names or contrasts with sibling verify_* tools, so sibling differentiation is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly lays out the three forms and the parameter combinations that select them, including 'A dataset returned in the answer is not stored: it is verified with its request, or by its head, rows and frames_hex.' That is strong when-to-use guidance for the tool's own modes, though it offers no explicit comparison to alternatives like verify_receipt.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_receiptVerify receiptARead-onlyIdempotentInspect
Verifies the receipt at the end of one response against the text before it. It takes no physics permit. The receipt covers every byte of the response before it, the decimal values included, and shows who produced the response or when in no way: it has no key. matches true proves only that those bytes are unchanged since the receipt was written; anyone can write a matching receipt for any text, so it is not a verification of the answer. A response that names an engine_version has it said beside matches, with whether it is this engine's; origin needs engine_version_is_this_engines true and a replay. match_proves says this in each answer. The receipt covers the request as it was written, number spellings included, while a seal covers its values: a request sent with 310 and the same request sent with 310.0 give different receipts and the same seal, so a receipt that differs between two such answers is not a sign of tampering. Replaying the request through run_trajectory, solve or compute_step shows the engine produced it; verify_tape, verify_solution and verify_dataset with the request and its seal do that replay and compare the seals.
| Name | Required | Description | Default |
|---|---|---|---|
| public_key | No | The base64 of the ML-DSA-87 public key (2,592 bytes) to verify the answer's signature with; without it, this engine's own. | |
| seen_nonces | No | Nonces of signatures already seen: one of them again is SignatureNonceReplayed. | |
| response_text | Yes | The exact text of a response as it was received, ending with the receipt, and the engine's signature after it when it carries one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a read-only, idempotent, closed operation, and the description adds meaningful behavior: no key or identity/time attestation, receipt coverage over raw bytes including number spellings (310 vs 310.0), nonce replay detection, and fallback to the engine's own key. It is rich but disorganized, and the central caveat is buried rather than front-loaded.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded, but the body is long, convoluted, and full of oblique phrasing ('has it said beside matches', 'in no way: it has no key'). Several sentences repeat the same integrity-not-authenticity caveat, and the reader must work to extract the actionable rules.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter verification tool with a fully documented schema and no output schema, the description covers the important edge cases: signature verification versus engine key, nonce replay, engine_version reporting, and the difference between receipt bytes and seal values. It is complete enough to call correctly, despite the turgid prose.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters are already documented. The description adds some interpretive nuance (that the receipt covers exact request spellings, that public_key falls back to the engine's own), but it does not systematically explain the parameters beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a specific verb and object: verifying the receipt at the end of a response against the preceding text. It also names the replay-oriented siblings (verify_tape, verify_solution, verify_dataset) and explains how this differs, though the surrounding prose ('takes no physics permit') muddies the signal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly limits what a successful match means ('matches true proves only that those bytes are unchanged') and points to run_trajectory/solve/compute_step plus the verify_* tools for replay-based provenance. That is real when-to-use / when-not-to-use guidance, though it is delivered indirectly and never as a clean rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_solutionVerify solutionARead-onlyIdempotentInspect
Verifies the seal of a solution. Short form, which needs only what is short: request is the solve request as it was sent (the answer's inputs), and solution_seal is the seal its answer gave. The request is solved again, under a physics permit and the limits and refusals of solve, and the answer is holds, cause ("solution_seal" when the seal given is not the seal the request solves to), recomputed_solution_seal and recomputed_receipt_sha384 when it holds (else no seal: solve gives the true one), compared, and text_not_compared: no answer text the agent holds is compared. Long form: the whole solve answer sent back as it came, without request. Its solution seal is recomputed from its exact hex values and the part that fails is named, then its request is solved again under a physics permit and the engine's answer compared with it, value by value and byte for byte, receipt included: holds is true only when every byte is the engine's, values_hold when every value is, else cause names the part, solution_seal (the request solves to another seal), answer_text (with differs_at, the first field that differs) or engine_version (an answer of another version). A chained solve: its whole answer with from beside it; the upstream run is computed again and the chain held too (cause chain), with recomputed_chain_seal. Alone it is refused (AnswerCarriesNoRequest). Nothing is stored, so each form answers the same on every connection. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | Beside the whole answer of a chained solve: the from solve took (request, run_seal, coupling). The upstream run is computed again and held to its seal, each handed value to it, and the request solved again with it; the answer alone is refused (AnswerCarriesNoRequest). | |
| inputs | No | The inputs of the solve answer, sent back as returned: the request that was solved. It is hashed, and solved again under a physics permit and the limits of solve. | |
| reject | No | ||
| result | No | ||
| outcome | No | ||
| request | No | With solution_seal alone: the solve request as it was sent (the answer's inputs). It is solved again, under a physics permit and the limits of solve, and its seal is compared with solution_seal. Its fields are solve's. Worked example of the short form, as the whole arguments: {"request":{"solver":"atom_dft","parameters":{"atomic_number":10}},"solution_seal":"<the solution_seal of its solve answer, 96 lowercase hex digits>"}. | |
| invariants | No | ||
| iterations | No | ||
| public_key | No | The base64 of the ML-DSA-87 public key (2,592 bytes) to verify the answer's signature with; without it, this engine's own. | |
| seal_parts | No | ||
| seen_nonces | No | Nonces of signatures already seen: one of them again is SignatureNonceReplayed. | |
| field_sha384 | No | ||
| solution_seal | No | The solution_seal of the solve answer: with request, or as part of the whole answer. | |
| engine_version | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly and idempotent annotations, the description discloses substantial operational behavior: nothing is stored, each address holds at most one physics permit at a time, long work runs one at a time, calls may be refused with 'Too many concurrent physics tasks.', and answers are waited for 60 seconds. It also explains signature verification order and the named failure causes. These are exactly the kind of behavioral traits annotations do not cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely long and dominated by run-on sentences, making it hard to parse despite the underlying complexity. The key information is present but not cleanly structured or front-loaded; concurrency and timeout details are mixed into the same dense paragraph as seal and signature verification logic.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and a complex 14-parameter input, the description carries the full burden and largely meets it. It explains the return values holds, values_hold, differs_at, cause, recomputed_solution_seal, recomputed_receipt_sha384, signature failure causes, and the concurrency/timeout behavior, so an agent has enough context to call and interpret the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 43% across 14 parameters, so the description must compensate. It does add useful semantics for request (with a worked example), solution_seal, from, public_key, seen_nonces, and the long-form required fields, but it leaves several top-level parameters such as reject, result, outcome, invariants, iterations, and field_sha384 without individual meaning beyond being parts of the answer.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: 'Verifies the seal of a solution.' It then distinguishes the short form from the long form and the chained-solve form, so an agent can tell what operation it performs. However, it never names or differentiates itself from sibling verification tools such as verify_receipt or verify_step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly explains which form to use for which payload shape: request plus solution_seal for the short form, the whole solve answer without request for the long form, and a whole answer with from for a chained solve. It also states that the answer alone is refused. But it gives no guidance on when to choose this tool over the other verify_* siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_stepVerify stepARead-onlyIdempotentInspect
Computes one anchored step of one card, as compute_step does: verify_step is the earlier name of compute_step, served for this one version beside it, and takes the same arguments and gives the same answer, byte for byte. The name compute_step is the one that stays. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| card | Yes | The card of the pair, as list_cards names it. | |
| from | No | Optional: a sealed run to start from, as run_trajectory takes it. | |
| domain | Yes | The domain of the pair, as list_cards names it. | |
| parameters | Yes | The step's inputs: the card's phase fields, its load fields and dt_s, each a number (a vector field is an array of three numbers), and no other key. describe_card gives the fields of the pair, with each unit and bound. A required field left out is refused as InputMissing, in a sentence that names the field, and a card the engine does not serve as UnknownCard; nothing is filled in. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it read-only, idempotent, non-destructive, but the description goes well beyond: one physics permit per connection, serialization of long work, the exact refusal message 'Too many concurrent physics tasks.', no-waiting semantics, and a 60-second timeout at which long work is stopped. 'Byte for byte' also confirms the idempotent hint meaningfully.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the most decision-relevant fact (equivalence to compute_step and which name survives), and the operational constraints earn their place. Slightly verbose in enumerating long-work cases ('a solve, a plan of runs or of solves, a run of more than 10000 steps...'), which costs a point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description supplies the equivalence guarantee ('same answer, byte for byte' as compute_step), the concurrency and timeout envelope, and refusal behavior, while the rich schema carries parameter detail. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema already explains card, domain, from/run_seal, and the parameters contract including InputMissing/UnknownCard errors. The description adds only 'takes the same arguments' and the byte-identical answer claim, so per the baseline rule a 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('computes one anchored step of one card') and immediately distinguishes itself from the sibling compute_step by declaring itself the earlier name served only for this version. An agent can tell exactly what it does and that a preferred equivalent exists without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: verify_step is the earlier name, compute_step is 'the one that stays', and the two take the same arguments and return the same answer. This is a direct when-to-use/when-not signal, plus descriptions of when calls will be refused (no permit/place) and how retries behave.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_tapeVerify tapeARead-onlyIdempotentInspect
Verifies the seal of a run. Short form, which needs only what is short: request is the run_trajectory request as it was sent, with its readout and its from, whose request has none, when it had them (the answer's inputs holds neither), and run_seal is the seal its answer gave. The run is computed again, under a physics permit and the limits and refusals of run_trajectory, and the answer is holds (the seal given is the seal the request runs to), cause ("run_seal" when it is not), recomputed_run_seal and recomputed_receipt_sha384 when it holds (else no seal: run_trajectory gives the true one), compared, and text_not_compared: no answer text the agent holds is compared. Long form: the whole run_trajectory answer sent back as it came, without request. Its state digest and run seal are recomputed from its exact hex values, then its request is computed again under a physics permit and the engine's answer compared with it, value by value and byte for byte, receipt included: holds is true only when every byte is the engine's, values_hold when every value is, else cause names the seal, load_signature (a signed load that does not verify), answer_text (with differs_at, the first field that differs) or engine_version (an answer of another version). A chain is verified by its request with from, run_seal and chain_seal, or by links, its answers in order, each computed again from the links before it; a chained answer alone is refused (AnswerCarriesNoRequest). Nothing is stored, so each form answers the same on every connection. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| links | No | Alone: a chain's answers in order. | |
| frames | No | ||
| inputs | No | The inputs of the run_trajectory answer, sent back as returned: the request that was run. It is hashed, and run again, with the answer's readout when it has one, under a physics permit and the limits of run_trajectory. A card's fields, units and bounds are in describe_card. | |
| reject | No | ||
| outcome | No | ||
| request | No | With run_seal alone: the run_trajectory request as it was sent, with its readout and its from when it had them (the answer's inputs holds neither; the upstream request in that from goes without a readout, as run_trajectory took it). It is run again, under a physics permit and the limits of run_trajectory, and its seal is compared with run_seal. Its fields are run_trajectory's. Worked example of the short form, as the whole arguments: {"request":{"domain":"energy","card":"thermal","initial":{"temperature_k":293.15},"dt_s":1.0,"segments":[{"steps":60,"load":{"heat_power_w":5.0,"ambient_k":293.15}}],"record_every":60},"run_seal":"<the run_seal of its run_trajectory answer, 96 lowercase hex digits>"}. | |
| run_seal | No | The run_seal of the run_trajectory answer: with request, or as part of the whole answer. | |
| chain_seal | No | With request and run_seal: a chained answer's chain_seal. | |
| public_key | No | The base64 of the ML-DSA-87 public key (2,592 bytes) to verify the answer's signature with; without it, this engine's own. | |
| final_state | No | ||
| seen_nonces | No | Nonces of signatures already seen: one of them again is SignatureNonceReplayed. | |
| state_digest | No | ||
| steps_landed | No | ||
| max_residual_conservation_error_hex | No | ||
| final_residual_conservation_error_hex | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive, and non-open-world behavior, but the description adds extensive operational context: recomputation under a physics permit, no storage, one permit per address, serialized long work, the "Too many concurrent physics tasks." response, and a 60-second wait limit. It also explains signature verification order, error causes, and the distinction between holds and values_hold. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description front-loads the core purpose in one sentence, but the remainder is an extremely long, tangled paragraph with nested clauses and awkward phrasing such as "request is the run_trajectory request as it was sent, with its readout and its from, whose request has none...". The content is substantive but poorly structured and repetitive enough to impede scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex verification tool with 15 parameters, no output schema, and nested objects, the description provides strong context on forms, recomputation behavior, signatures, return fields such as holds and values_hold, and concurrency limits. It misses the frames parameter and some long-form field semantics, but overall it is far more complete than the structured schema alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 47%, so the description needs to compensate for the 15 parameters. It adds useful meaning for request, run_seal, chain_seal, links, public_key, and seen_nonces, including a worked example and signature error behavior. However, it never mentions the frames parameter and only lists several long-form answer fields without explaining their semantics, so it does not fully close the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: "Verifies the seal of a run." The description goes on to distinguish the short form, long form, and chain verification, so the core purpose is clear. It does not explicitly contrast itself with sibling tools such as verify_receipt or verify_step, which keeps it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives detailed conditions for using the short form versus the long form, for chain verification with chain_seal or links, and for signed answers. It also states exclusions such as a chained answer alone being refused with AnswerCarriesNoRequest. It does not name sibling verification tools or explain when to prefer this tool over them, so it falls short of explicit alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
solve1 field changed- changed
Input schema / properties / from / descriptionPrevious value: -"Optional: a sealed card run handed in through a coupling, as run_trajectory takes it."New value: +"Optional: a sealed card run handed in through a coupling, as run_trajectory takes it. Each handed value goes into parameters bit for bit, read from the run's frame_hex or a _hex value, not a decimal (CouplingLedgerBreach)."
4 tool updates
- Changed
verify_dataset2 fields changed- changed
Input schema / descriptionPrevious value: -"One of three forms. request and dataset_seal, the short form: the plan is run again and its seal compared. The three parts a full run_dataset answer carries (head, rows and frames_hex, all three required together, as they came), the long form: the rows, the root and the seal are recomputed from their exact values, then the head's plan is run again under the permits and the limits of run_dataset and the engine's full answer to it compared with the parts sent, value by value and then byte for byte, so a dataset that holds is every byte the engine's. dataset_seal alone: the stored dataset of that seal, its seals recomputed from its files and its plan run again into a folder of its own, the stored files compared with that run's byte for byte. The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs. An answer the engine signed (signature, ML-DSA-87 over its receipt, with issued_at, expires_at and nonce) has its signature checked first, against public_key or else this engine's own key: one that does not hold is cause signature, named (SignatureDoesNotVerify, SignatureExpired, SignatureNonceReplayed, SignatureKeyMismatch, ReceiptDoesNotMatch, SignatureAbsent when public_key is given and there is none), and nothing is computed. The signature of a dataset follows its head's receipt."New value: +"One of three forms. request and dataset_seal, the short form: the plan is run again and its seal compared. The three parts a full run_dataset answer carries (head, rows and frames_hex, all three required together, as they came), the long form: the rows, the root and the seal are recomputed from their exact values, then the head's plan is run again under the permits and the limits of run_dataset and the engine's full answer to it compared with the parts sent, value by value and then byte for byte, so a dataset that holds is every byte the engine's. dataset_seal alone: the stored dataset of that seal, its seals recomputed from its files and its plan run again into a folder of its own, the stored files compared with that run's byte for byte. The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs. An answer the engine signed (signature, ML-DSA-87 over its receipt, with issued_at, expires_at and nonce) has its signature verified first, against public_key or else this engine's own key: one that does not hold is cause signature, named (SignatureDoesNotVerify, SignatureExpired, SignatureNonceReplayed, SignatureKeyMismatch, ReceiptDoesNotMatch, SignatureAbsent when public_key is given and there is none), and nothing is computed. A signed answer a client wrote again in its own spacing or key order has its signature verified over the receipt it carries; where that receipt does not cover the bytes sent, signature names ReceiptDoesNotMatch with written_again, and the answer is computed again: holds, values_hold and differs_at say what changed. The signature of a dataset follows its head's receipt." - changed
Input schema / properties / public_key / descriptionPrevious value: -"The base64 of the ML-DSA-87 public key (2,592 bytes) to check the answer's signature with; without it, this engine's own."New value: +"The base64 of the ML-DSA-87 public key (2,592 bytes) to verify the answer's signature with; without it, this engine's own."
- Changed
verify_receipt2 fields changed- changed
Input schema / descriptionPrevious value: -"The text of one response from compute_step, run_trajectory or solve, or the head of a dataset written as its JSON text. A signature after the receipt is checked against public_key or else this engine's own key, and reported under signature."New value: +"The text of one response from compute_step, run_trajectory or solve, or the head of a dataset written as its JSON text. A signature after the receipt is verified against public_key or else this engine's own key, and reported under signature." - changed
Input schema / properties / public_key / descriptionPrevious value: -"The base64 of the ML-DSA-87 public key (2,592 bytes) to check the answer's signature with; without it, this engine's own."New value: +"The base64 of the ML-DSA-87 public key (2,592 bytes) to verify the answer's signature with; without it, this engine's own."
- Changed
verify_solution2 fields changed- changed
Input schema / descriptionPrevious value: -"Either request and solution_seal alone, the short form: the request is solved again and its seal compared with solution_seal. Or the whole solve answer sent back as it came, without request, the long form: inputs, engine_version, outcome, iterations, reject, result, invariants, field_sha384, seal_parts and solution_seal are then all required. The solution seal is recomputed from its exact hex values and the part that fails is named; then its request is solved again under a physics permit and the limits of solve, and the engine's whole answer to it compared with the answer sent, value by value and then byte for byte, the receipt included, so an answer that holds is every byte the engine's. A seal has no key: an answer whose values were rewritten with its seal parts, seal and receipt worked out again holds every seal, and only the solve shows it is not the engine's (cause solution_seal). The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs. An answer the engine signed (signature, ML-DSA-87 over its receipt, with issued_at, expires_at and nonce) has its signature checked first, against public_key or else this engine's own key: one that does not hold is cause signature, named (SignatureDoesNotVerify, SignatureExpired, SignatureNonceReplayed, SignatureKeyMismatch, ReceiptDoesNotMatch, SignatureAbsent when public_key is given and there is none), and nothing is computed."New value: +"Either request and solution_seal alone, the short form: the request is solved again and its seal compared with solution_seal. Or the whole solve answer sent back as it came, without request, the long form: inputs, engine_version, outcome, iterations, reject, result, invariants, field_sha384, seal_parts and solution_seal are then all required. The solution seal is recomputed from its exact hex values and the part that fails is named; then its request is solved again under a physics permit and the limits of solve, and the engine's whole answer to it compared with the answer sent, value by value and then byte for byte, the receipt included, so an answer that holds is every byte the engine's. A seal has no key: an answer whose values were rewritten with its seal parts, seal and receipt worked out again holds every seal, and only the solve shows it is not the engine's (cause solution_seal). The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs. An answer the engine signed (signature, ML-DSA-87 over its receipt, with issued_at, expires_at and nonce) has its signature verified first, against public_key or else this engine's own key: one that does not hold is cause signature, named (SignatureDoesNotVerify, SignatureExpired, SignatureNonceReplayed, SignatureKeyMismatch, ReceiptDoesNotMatch, SignatureAbsent when public_key is given and there is none), and nothing is computed. A signed answer a client wrote again in its own spacing or key order has its signature verified over the receipt it carries; where that receipt does not cover the bytes sent, signature names ReceiptDoesNotMatch with written_again, and the answer is computed again: holds, values_hold and differs_at say what changed." - changed
Input schema / properties / public_key / descriptionPrevious value: -"The base64 of the ML-DSA-87 public key (2,592 bytes) to check the answer's signature with; without it, this engine's own."New value: +"The base64 of the ML-DSA-87 public key (2,592 bytes) to verify the answer's signature with; without it, this engine's own."
- Changed
verify_tape2 fields changed- changed
Input schema / descriptionPrevious value: -"Either request and run_seal alone, the short form: the run is computed again and its seal compared with run_seal. Or the whole run_trajectory answer sent back as it was returned, without request, the long form: inputs, frames, outcome, steps_landed, reject, run_seal, final_state, final_residual_conservation_error_hex, max_residual_conservation_error_hex and state_digest are then all required, along with the rest of the answer. The trajectory chain, the state digest and the run seal are recomputed from its exact hex values; then its request is computed again under a physics permit and the limits of run_trajectory, and the engine's whole answer to it compared with the answer sent, value by value and then byte for byte, the receipt included, so an answer that holds is every byte the engine's. A seal has no key: an answer whose values were rewritten with its seals worked out again holds every seal, and only the computation shows it is not the engine's. An answer that continues a sealed upstream run (its chain names upstream_run_seal) carries the upstream's seal and not its request, and its long form is refused (AnswerCarriesNoRequest): its chain's answers in order, as links, carry each request, and each link is computed again from the links before it. Or links alone: a chain's answers in order, held as the long form holds one. A design_run answer sent whole is designed again and held the same way. The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs. An answer the engine signed (signature, ML-DSA-87 over its receipt, with issued_at, expires_at and nonce) has its signature checked first, against public_key or else this engine's own key: one that does not hold is cause signature, named (SignatureDoesNotVerify, SignatureExpired, SignatureNonceReplayed, SignatureKeyMismatch, ReceiptDoesNotMatch, SignatureAbsent when public_key is given and there is none), and nothing is computed."New value: +"Either request and run_seal alone, the short form: the run is computed again and its seal compared with run_seal. Or the whole run_trajectory answer sent back as it was returned, without request, the long form: inputs, frames, outcome, steps_landed, reject, run_seal, final_state, final_residual_conservation_error_hex, max_residual_conservation_error_hex and state_digest are then all required, along with the rest of the answer. The trajectory chain, the state digest and the run seal are recomputed from its exact hex values; then its request is computed again under a physics permit and the limits of run_trajectory, and the engine's whole answer to it compared with the answer sent, value by value and then byte for byte, the receipt included, so an answer that holds is every byte the engine's. A seal has no key: an answer whose values were rewritten with its seals worked out again holds every seal, and only the computation shows it is not the engine's. An answer that continues a sealed upstream run (its chain names upstream_run_seal) carries the upstream's seal and not its request, and its long form is refused (AnswerCarriesNoRequest): its chain's answers in order, as links, carry each request, and each link is computed again from the links before it. Or links alone: a chain's answers in order, held as the long form holds one. A design_run answer sent whole is designed again and held the same way. The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs. An answer the engine signed (signature, ML-DSA-87 over its receipt, with issued_at, expires_at and nonce) has its signature verified first, against public_key or else this engine's own key: one that does not hold is cause signature, named (SignatureDoesNotVerify, SignatureExpired, SignatureNonceReplayed, SignatureKeyMismatch, ReceiptDoesNotMatch, SignatureAbsent when public_key is given and there is none), and nothing is computed. A signed answer a client wrote again in its own spacing or key order has its signature verified over the receipt it carries; where that receipt does not cover the bytes sent, signature names ReceiptDoesNotMatch with written_again, and the answer is computed again: holds, values_hold and differs_at say what changed." - changed
Input schema / properties / public_key / descriptionPrevious value: -"The base64 of the ML-DSA-87 public key (2,592 bytes) to check the answer's signature with; without it, this engine's own."New value: +"The base64 of the ML-DSA-87 public key (2,592 bytes) to verify the answer's signature with; without it, this engine's own."
10 tool updates
- Changed
compute_step1 field changed- changed
Input schema / properties / from / properties / run_seal / patternPrevious value: -"^[0-9a-f]{64}$"New value: +"^[0-9a-f]{96}$"
- Changed
run_dataset3 fields changed- changed
Input schema / descriptionPrevious value: -"A plan of runs on one card (domain, card, plan, store and return, all required) or of solves of one solver (solver and plan). Rows <= 100000, steps in total <= 100000000, stored frames <= 16777216; inline: an answer counted from the plan <= 40000 characters, which a plan reaches first, a grid on one axis at about 140 summary rows and a list sooner, its head repeating each run's request (a plan of more than 1000 rows is refused before it is counted, as too large to return inline), and frames <= 10000; solves <= 64. With return \"file\" the answer is the head and the names of the files stored, on a connection started with a directory for them."New value: +"A plan of runs on one card (domain, card, plan, store and return, all required) or of solves of one solver (solver and plan). Rows <= 100000, steps in total <= 100000000, stored frames <= 16777216; inline: an answer counted from the plan <= 42500 characters, which a plan reaches first, a grid on one axis at about 150 summary rows and a list sooner, its head repeating each run's request (a plan of more than 1000 rows is refused before it is counted, as too large to return inline), and frames <= 10000; solves <= 64. With return \"file\" the answer is the head and the names of the files stored, on a connection started with a directory for them." - changed
Input schema / properties / answer / descriptionPrevious value: -"Leave out, or \"summary\", for the head and one short summary row per row: the values it sets, outcome, steps landed, refusal name and seal; \"states\" adds each run's final state in decimals; \"full\" gives every row whole. With return \"file\" the answer is the head and the names of the files whatever this says. Not part of the sealed request. The head and the dataset_seal are the same in all three forms. A summary row holds row, set (the values a grid's or a sample's row sets), outcome, steps_landed, reject and run_seal; the quantities of one row are read by sending its request to run_trajectory with a readout. An ended row is a run that stopped at an end its card declares: it has a run seal, the end's reject name in reject and the sentence naming the end in reject_detail. A refused row is a run the card refused part way: it has a run seal, the refusal's name in reject and its sentence in reject_detail. An unadmitted row is a request turned away before computing: it has no run seal, and its sentence, with the refusal's name in round brackets when the sentence gives one, is its reject_detail; its summary row gives that name in reject. What a sentence that begins \"Physical Failure\" or \"Physical Violation\" means is in the description of run_trajectory. An inline answer is counted from the plan before anything runs, and one above 40000 characters is refused with what to change: a summary row counts 220 characters and the values it sets; with states, each number of the final state adds its name and 28 characters (84 for a 3-vector, 9 for a flag); a whole row counts its own request and 1900 characters, and for each number twice its name and 60 characters (150 for a 3-vector, 9 for a flag); store \"frames\" adds 128 characters for each recorded state to a full answer; the head repeats the request."New value: +"Leave out, or \"summary\", for the head and one short summary row per row: the values it sets, outcome, steps landed, refusal name and seal; \"states\" adds each run's final state in decimals; \"full\" gives every row whole. With return \"file\" the answer is the head and the names of the files whatever this says. Not part of the sealed request. The head and the dataset_seal are the same in all three forms. A summary row holds row, set (the values a grid's or a sample's row sets), outcome, steps_landed, reject and run_seal; the quantities of one row are read by sending its request to run_trajectory with a readout. An ended row is a run that stopped at an end its card declares: it has a run seal, the end's reject name in reject and the sentence naming the end in reject_detail. A refused row is a run the card refused part way: it has a run seal, the refusal's name in reject and its sentence in reject_detail. An unadmitted row is a request turned away before computing: it has no run seal, and its sentence, with the refusal's name in round brackets when the sentence gives one, is its reject_detail; its summary row gives that name in reject. What a sentence that begins \"Physical Failure\" or \"Physical Violation\" means is in the description of run_trajectory. An inline answer is counted from the plan before anything runs, and one above 42500 characters is refused with what to change: a summary row counts 220 characters and the values it sets; with states, each number of the final state adds its name and 28 characters (84 for a 3-vector, 9 for a flag); a whole row counts its own request and 1900 characters, and for each number twice its name and 60 characters (150 for a 3-vector, 9 for a flag); store \"frames\" adds 128 characters for each recorded state to a full answer; the head repeats the request." - changed
Input schema / properties / solver / descriptionPrevious value: -"A plan of solves: the solver, in place of domain and card. It takes no store and no return. A plan of solves is answered inline: a list, {\"kind\":\"list\",\"solves\":[{\"parameters\":{...}}]}, or a grid, {\"kind\":\"grid\",\"base\":{\"parameters\":{...}},\"axes\":[{\"path\":\"parameters.<input>\",\"values\":[...]}]}, of at most 64 solves. Each row is a solve request, solved as solve solves it and carrying the solution_seal solve gives it; a request turned away without a seal, by the rules of a request or by the solver, is an unadmitted row. The rows are sealed under one dataset_seal by the rules of a plan of runs, with solution_seal in the leaf in the place of run_seal, and completed in the counts counts the solves that converged. A summary row has row, set, outcome, reject, solution_seal and every single number of the result in decimals; answer \"full\" gives every solution whole, and is refused when it comes to more than 40000 characters. verify_dataset verifies a plan of solves by its request and dataset_seal, and validate_series compares one number of its results with measurements. Worked plan of solves: {\"solver\":\"atom_dft\",\"plan\":{\"kind\":\"list\",\"solves\":[{\"parameters\":{\"atomic_number\":10}}]}}."New value: +"A plan of solves: the solver, in place of domain and card. It takes no store and no return. A plan of solves is answered inline: a list, {\"kind\":\"list\",\"solves\":[{\"parameters\":{...}}]}, or a grid, {\"kind\":\"grid\",\"base\":{\"parameters\":{...}},\"axes\":[{\"path\":\"parameters.<input>\",\"values\":[...]}]}, of at most 64 solves. Each row is a solve request, solved as solve solves it and carrying the solution_seal solve gives it; a request turned away without a seal, by the rules of a request or by the solver, is an unadmitted row. The rows are sealed under one dataset_seal by the rules of a plan of runs, with solution_seal in the leaf in the place of run_seal, and completed in the counts counts the solves that converged. A summary row has row, set, outcome, reject, solution_seal and every single number of the result in decimals; answer \"full\" gives every solution whole, and is refused when it comes to more than 42500 characters. verify_dataset verifies a plan of solves by its request and dataset_seal, and validate_series compares one number of its results with measurements. Worked plan of solves: {\"solver\":\"atom_dft\",\"plan\":{\"kind\":\"list\",\"solves\":[{\"parameters\":{\"atomic_number\":10}}]}}."
- Changed
run_trajectory2 fields changed- changed
Input schema / properties / from / properties / run_seal / patternPrevious value: -"^[0-9a-f]{64}$"New value: +"^[0-9a-f]{96}$" - changed
Input schema / properties / record_every / descriptionPrevious value: -"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 230 characters for each recorded state, plus the request as it was sent, plus up to 8000 characters for the final state and the seals. 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."New value: +"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."
- Changed
solve1 field changed- changed
Input schema / properties / from / properties / run_seal / patternPrevious value: -"^[0-9a-f]{64}$"New value: +"^[0-9a-f]{96}$"
- Changed
validate_series5 fields changed- changed
Input schema / properties / commitment / descriptionPrevious value: -"Optional: a commitment the measurements were locked with before this comparison, opened by this request. sha256 is the SHA-256 of these bytes: the line zero-trust-physics/measurement-commitment/v1 and a line break; 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 {\"component\": <this request's component, or null>, \"measurements\": <this request's measurements>, \"quantity\": <this request's quantity>}; a line break; and the salt's bytes, its hex decoded. salt is 32 to 128 lowercase hex digits, 16 to 64 bytes, kept back until the comparison so that the data are not found from the sha256 by trying values. The engine makes the digest again from the request before computing: data that do not open it (a value, a step or a row changed, moved, added or dropped, another quantity or another salt) are refused as CommitmentDoesNotMatch, a salt shorter than 16 bytes as CommitmentSaltTooShort, a field of the wrong form as CommitmentMalformed, and sha256 or salt left out as InputMissing; nothing is computed and nothing is sealed. Opened, the comparison runs as it runs without one, validation_seal takes the commitment as a sixth part, and the answer says so in commitment_opened. A commitment shows that the data were not changed after it was made; when it was made is shown by where its sha256 was published before the comparison."New value: +"Optional: a commitment the measurements were locked with before this comparison, opened by this request. sha384 is the SHA-384 of these bytes: the line zero-trust-physics/measurement-commitment/v2 and a line break; 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 {\"component\": <this request's component, or null>, \"measurements\": <this request's measurements>, \"quantity\": <this request's quantity>}; a line break; and the salt's bytes, its hex decoded. salt is 32 to 128 lowercase hex digits, 16 to 64 bytes, kept back until the comparison so that the data are not found from the sha384 by trying values. The engine makes the digest again from the request before computing: data that do not open it (a value, a step or a row changed, moved, added or dropped, another quantity or another salt) are refused as CommitmentDoesNotMatch, a salt shorter than 16 bytes as CommitmentSaltTooShort, a field of the wrong form as CommitmentMalformed, and sha384 or salt left out as InputMissing; nothing is computed and nothing is sealed. Opened, the comparison runs as it runs without one, validation_seal takes the commitment as a sixth part, and the answer says so in commitment_opened. A commitment shows that the data were not changed after it was made; when it was made is shown by where its sha384 was published before the comparison." - changed
Input schema / properties / commitment / properties / salt / descriptionPrevious value: -"The salt the sha256 was made with: 32 to 128 lowercase hex digits, 16 to 64 bytes."New value: +"The salt the sha384 was made with: 32 to 128 lowercase hex digits, 16 to 64 bytes." - removed
Input schema / properties / commitment / properties / sha256Removed value: -{ - "description": "The SHA-256 committed, 64 lowercase hex digits.", - "pattern": "^[0-9a-f]{64}$", - "type": "string" -} - added
Input schema / properties / commitment / properties / sha384Added value: +{ + "description": "The SHA-384 committed, 96 lowercase hex digits.", + "pattern": "^[0-9a-f]{96}$", + "type": "string" +} - changed
Input schema / properties / commitment / requiredPrevious value: -[ - "sha256", - "salt" -]New value: +[ + "sha384", + "salt" +]
- Changed
verify_dataset5 fields changed- changed
Input schema / descriptionPrevious value: -"One of three forms. request and dataset_seal, the short form: the plan is run again and its seal compared. The three parts a full run_dataset answer carries (head, rows and frames_hex, all three required together, as they came), the long form: the rows, the root and the seal are recomputed from their exact values, then the head's plan is run again under the permits and the limits of run_dataset and the engine's full answer to it compared with the parts sent, value by value and then byte for byte, so a dataset that holds is every byte the engine's. dataset_seal alone: the stored dataset of that seal, its seals recomputed from its files and its plan run again into a folder of its own, the stored files compared with that run's byte for byte. The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs."New value: +"One of three forms. request and dataset_seal, the short form: the plan is run again and its seal compared. The three parts a full run_dataset answer carries (head, rows and frames_hex, all three required together, as they came), the long form: the rows, the root and the seal are recomputed from their exact values, then the head's plan is run again under the permits and the limits of run_dataset and the engine's full answer to it compared with the parts sent, value by value and then byte for byte, so a dataset that holds is every byte the engine's. dataset_seal alone: the stored dataset of that seal, its seals recomputed from its files and its plan run again into a folder of its own, the stored files compared with that run's byte for byte. The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs. An answer the engine signed (signature, ML-DSA-87 over its receipt, with issued_at, expires_at and nonce) has its signature checked first, against public_key or else this engine's own key: one that does not hold is cause signature, named (SignatureDoesNotVerify, SignatureExpired, SignatureNonceReplayed, SignatureKeyMismatch, ReceiptDoesNotMatch, SignatureAbsent when public_key is given and there is none), and nothing is computed. The signature of a dataset follows its head's receipt." - changed
Input schema / properties / dataset_seal / patternPrevious value: -"^[0-9a-f]{64}$"New value: +"^[0-9a-f]{96}$" - added
Input schema / properties / public_keyAdded value: +{ + "description": "The base64 of the ML-DSA-87 public key (2,592 bytes) to check the answer's signature with; without it, this engine's own.", + "type": "string" +} - changed
Input schema / properties / request / descriptionPrevious value: -"With dataset_seal alone: the run_dataset request as it was sent (the head's request). The plan is run again, under the permits and the limits of run_dataset, and its seal is compared with dataset_seal. Nothing is stored or read from storage, so it works whatever the return mode and on every connection. Its fields are run_dataset's. Worked example of the short form, as the whole arguments: {\"request\":{\"domain\":\"energy\",\"card\":\"thermal\",\"plan\":{\"kind\":\"list\",\"runs\":[{\"initial\":{\"temperature_k\":293.15},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"heat_power_w\":5.0,\"ambient_k\":293.15}}],\"record_every\":60}]},\"store\":\"none\",\"return\":\"inline\"},\"dataset_seal\":\"<the dataset_seal of its run_dataset answer, 64 lowercase hex digits>\"}."New value: +"With dataset_seal alone: the run_dataset request as it was sent (the head's request). The plan is run again, under the permits and the limits of run_dataset, and its seal is compared with dataset_seal. Nothing is stored or read from storage, so it works whatever the return mode and on every connection. Its fields are run_dataset's. Worked example of the short form, as the whole arguments: {\"request\":{\"domain\":\"energy\",\"card\":\"thermal\",\"plan\":{\"kind\":\"list\",\"runs\":[{\"initial\":{\"temperature_k\":293.15},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"heat_power_w\":5.0,\"ambient_k\":293.15}}],\"record_every\":60}]},\"store\":\"none\",\"return\":\"inline\"},\"dataset_seal\":\"<the dataset_seal of its run_dataset answer, 96 lowercase hex digits>\"}." - added
Input schema / properties / seen_noncesAdded value: +{ + "description": "Nonces of signatures already seen: one of them again is SignatureNonceReplayed.", + "items": { + "pattern": "^[0-9a-f]{64}$", + "type": "string" + }, + "type": "array" +}
- Changed
verify_receipt4 fields changed- changed
Input schema / descriptionPrevious value: -"The text of one response from compute_step, run_trajectory or solve, or the head of a dataset written as its JSON text."New value: +"The text of one response from compute_step, run_trajectory or solve, or the head of a dataset written as its JSON text. A signature after the receipt is checked against public_key or else this engine's own key, and reported under signature." - added
Input schema / properties / public_keyAdded value: +{ + "description": "The base64 of the ML-DSA-87 public key (2,592 bytes) to check the answer's signature with; without it, this engine's own.", + "type": "string" +} - changed
Input schema / properties / response_text / descriptionPrevious value: -"The exact text of a response as it was received, ending with the receipt."New value: +"The exact text of a response as it was received, ending with the receipt, and the engine's signature after it when it carries one." - added
Input schema / properties / seen_noncesAdded value: +{ + "description": "Nonces of signatures already seen: one of them again is SignatureNonceReplayed.", + "items": { + "pattern": "^[0-9a-f]{64}$", + "type": "string" + }, + "type": "array" +}
- Changed
verify_solution10 fields changed- changed
Input schema / descriptionPrevious value: -"Either request and solution_seal alone, the short form: the request is solved again and its seal compared with solution_seal. Or the whole solve answer sent back as it came, without request, the long form: inputs, engine_version, outcome, iterations, reject, result, invariants, field_sha256, seal_parts and solution_seal are then all required. The solution seal is recomputed from its exact hex values and the part that fails is named; then its request is solved again under a physics permit and the limits of solve, and the engine's whole answer to it compared with the answer sent, value by value and then byte for byte, the receipt included, so an answer that holds is every byte the engine's. A seal has no key: an answer whose values were rewritten with its seal parts, seal and receipt worked out again holds every seal, and only the solve shows it is not the engine's (cause solution_seal). The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs."New value: +"Either request and solution_seal alone, the short form: the request is solved again and its seal compared with solution_seal. Or the whole solve answer sent back as it came, without request, the long form: inputs, engine_version, outcome, iterations, reject, result, invariants, field_sha384, seal_parts and solution_seal are then all required. The solution seal is recomputed from its exact hex values and the part that fails is named; then its request is solved again under a physics permit and the limits of solve, and the engine's whole answer to it compared with the answer sent, value by value and then byte for byte, the receipt included, so an answer that holds is every byte the engine's. A seal has no key: an answer whose values were rewritten with its seal parts, seal and receipt worked out again holds every seal, and only the solve shows it is not the engine's (cause solution_seal). The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs. An answer the engine signed (signature, ML-DSA-87 over its receipt, with issued_at, expires_at and nonce) has its signature checked first, against public_key or else this engine's own key: one that does not hold is cause signature, named (SignatureDoesNotVerify, SignatureExpired, SignatureNonceReplayed, SignatureKeyMismatch, ReceiptDoesNotMatch, SignatureAbsent when public_key is given and there is none), and nothing is computed." - removed
Input schema / properties / field_sha256Removed value: -{ - "type": [ - "string", - "null" - ] -} - added
Input schema / properties / field_sha384Added value: +{ + "type": [ + "string", + "null" + ] +} - added
Input schema / properties / public_keyAdded value: +{ + "description": "The base64 of the ML-DSA-87 public key (2,592 bytes) to check the answer's signature with; without it, this engine's own.", + "type": "string" +} - changed
Input schema / properties / request / descriptionPrevious value: -"With solution_seal alone: the solve request as it was sent (the answer's inputs). It is solved again, under a physics permit and the limits of solve, and its seal is compared with solution_seal. Its fields are solve's. Worked example of the short form, as the whole arguments: {\"request\":{\"solver\":\"atom_dft\",\"parameters\":{\"atomic_number\":10}},\"solution_seal\":\"<the solution_seal of its solve answer, 64 lowercase hex digits>\"}."New value: +"With solution_seal alone: the solve request as it was sent (the answer's inputs). It is solved again, under a physics permit and the limits of solve, and its seal is compared with solution_seal. Its fields are solve's. Worked example of the short form, as the whole arguments: {\"request\":{\"solver\":\"atom_dft\",\"parameters\":{\"atomic_number\":10}},\"solution_seal\":\"<the solution_seal of its solve answer, 96 lowercase hex digits>\"}." - removed
Input schema / properties / seal_parts / properties / field_sha256Removed value: -{ - "type": "string" -} - added
Input schema / properties / seal_parts / properties / field_sha384Added value: +{ + "type": "string" +} - changed
Input schema / properties / seal_parts / requiredPrevious value: -[ - "inputs", - "engine_version", - "result", - "invariants", - "field_sha256", - "outcome" -]New value: +[ + "inputs", + "engine_version", + "result", + "invariants", + "field_sha384", + "outcome" +] - added
Input schema / properties / seen_noncesAdded value: +{ + "description": "Nonces of signatures already seen: one of them again is SignatureNonceReplayed.", + "items": { + "pattern": "^[0-9a-f]{64}$", + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / solution_seal / patternPrevious value: -"^[0-9a-f]{64}$"New value: +"^[0-9a-f]{96}$"
- Changed
verify_step1 field changed- changed
Input schema / properties / from / properties / run_seal / patternPrevious value: -"^[0-9a-f]{64}$"New value: +"^[0-9a-f]{96}$"
- Changed
verify_tape6 fields changed- changed
Input schema / descriptionPrevious value: -"Either request and run_seal alone, the short form: the run is computed again and its seal compared with run_seal. Or the whole run_trajectory answer sent back as it was returned, without request, the long form: inputs, frames, outcome, steps_landed, reject, run_seal, final_state, final_residual_conservation_error_hex, max_residual_conservation_error_hex and state_digest are then all required, along with the rest of the answer. The trajectory chain, the state digest and the run seal are recomputed from its exact hex values; then its request is computed again under a physics permit and the limits of run_trajectory, and the engine's whole answer to it compared with the answer sent, value by value and then byte for byte, the receipt included, so an answer that holds is every byte the engine's. A seal has no key: an answer whose values were rewritten with its seals worked out again holds every seal, and only the computation shows it is not the engine's. An answer that continues a sealed upstream run (its chain names upstream_run_seal) carries the upstream's seal and not its request, and its long form is refused (AnswerCarriesNoRequest): its chain's answers in order, as links, carry each request, and each link is computed again from the links before it. Or links alone: a chain's answers in order, held as the long form holds one. A design_run answer sent whole is designed again and held the same way. The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs."New value: +"Either request and run_seal alone, the short form: the run is computed again and its seal compared with run_seal. Or the whole run_trajectory answer sent back as it was returned, without request, the long form: inputs, frames, outcome, steps_landed, reject, run_seal, final_state, final_residual_conservation_error_hex, max_residual_conservation_error_hex and state_digest are then all required, along with the rest of the answer. The trajectory chain, the state digest and the run seal are recomputed from its exact hex values; then its request is computed again under a physics permit and the limits of run_trajectory, and the engine's whole answer to it compared with the answer sent, value by value and then byte for byte, the receipt included, so an answer that holds is every byte the engine's. A seal has no key: an answer whose values were rewritten with its seals worked out again holds every seal, and only the computation shows it is not the engine's. An answer that continues a sealed upstream run (its chain names upstream_run_seal) carries the upstream's seal and not its request, and its long form is refused (AnswerCarriesNoRequest): its chain's answers in order, as links, carry each request, and each link is computed again from the links before it. Or links alone: a chain's answers in order, held as the long form holds one. A design_run answer sent whole is designed again and held the same way. The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs. An answer the engine signed (signature, ML-DSA-87 over its receipt, with issued_at, expires_at and nonce) has its signature checked first, against public_key or else this engine's own key: one that does not hold is cause signature, named (SignatureDoesNotVerify, SignatureExpired, SignatureNonceReplayed, SignatureKeyMismatch, ReceiptDoesNotMatch, SignatureAbsent when public_key is given and there is none), and nothing is computed." - changed
Input schema / properties / chain_seal / patternPrevious value: -"^[0-9a-f]{64}$"New value: +"^[0-9a-f]{96}$" - added
Input schema / properties / public_keyAdded value: +{ + "description": "The base64 of the ML-DSA-87 public key (2,592 bytes) to check the answer's signature with; without it, this engine's own.", + "type": "string" +} - changed
Input schema / properties / request / descriptionPrevious value: -"With run_seal alone: the run_trajectory request as it was sent, with its readout and its from when it had them (the answer's inputs holds neither; the upstream request in that from goes without a readout, as run_trajectory took it). It is run again, under a physics permit and the limits of run_trajectory, and its seal is compared with run_seal. Its fields are run_trajectory's. Worked example of the short form, as the whole arguments: {\"request\":{\"domain\":\"energy\",\"card\":\"thermal\",\"initial\":{\"temperature_k\":293.15},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"heat_power_w\":5.0,\"ambient_k\":293.15}}],\"record_every\":60},\"run_seal\":\"<the run_seal of its run_trajectory answer, 64 lowercase hex digits>\"}."New value: +"With run_seal alone: the run_trajectory request as it was sent, with its readout and its from when it had them (the answer's inputs holds neither; the upstream request in that from goes without a readout, as run_trajectory took it). It is run again, under a physics permit and the limits of run_trajectory, and its seal is compared with run_seal. Its fields are run_trajectory's. Worked example of the short form, as the whole arguments: {\"request\":{\"domain\":\"energy\",\"card\":\"thermal\",\"initial\":{\"temperature_k\":293.15},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"heat_power_w\":5.0,\"ambient_k\":293.15}}],\"record_every\":60},\"run_seal\":\"<the run_seal of its run_trajectory answer, 96 lowercase hex digits>\"}." - changed
Input schema / properties / run_seal / patternPrevious value: -"^[0-9a-f]{64}$"New value: +"^[0-9a-f]{96}$" - added
Input schema / properties / seen_noncesAdded value: +{ + "description": "Nonces of signatures already seen: one of them again is SignatureNonceReplayed.", + "items": { + "pattern": "^[0-9a-f]{64}$", + "type": "string" + }, + "type": "array" +}
3 tool updates
- Changed
solve1 field changed- added
Input schema / properties / fromAdded value: +{ + "additionalProperties": false, + "description": "Optional: a sealed card run handed in through a coupling, as run_trajectory takes it.", + "properties": { + "coupling": { + "type": "string" + }, + "request": { + "type": "object" + }, + "run_seal": { + "pattern": "^[0-9a-f]{64}$", + "type": "string" + } + }, + "required": [ + "request", + "run_seal", + "coupling" + ], + "type": "object" +}
- Changed
validate_series1 field changed- changed
Input schema / descriptionPrevious value: -"One run, or one plan of solves, and measurements of one quantity. The answer is the error in numbers, sealed with a hash of the measurements. It holds no verdict. A request holds run or solves, not both."New value: +"One run, or one plan of solves, and measurements of one quantity. The answer is the error in numbers, sealed with a hash of the measurements. It sets no threshold. A request holds run or solves, not both."
- Changed
verify_solution1 field changed- added
Input schema / properties / fromAdded value: +{ + "description": "Beside the whole answer of a chained solve: the from solve took (request, run_seal, coupling). The upstream run is computed again and held to its seal, each handed value to it, and the request solved again with it; the answer alone is refused (AnswerCarriesNoRequest).", + "type": "object" +}
4 tool updates
- Changed
find_flip1 field changed- changed
Input schema / properties / request / descriptionPrevious value: -"A run_trajectory or solve request as that tool takes it."New value: +"A run_trajectory or solve request as that tool takes it. A search of solves makes no new solve once those made are counted at 20 s (FLIP_MAX_SECONDS), each at the time describe_solver states for one solve of its solver (open_connection), and always makes at least 3, both ends and one value between them: a count, not a clock, so the same request stops at the same solve on any machine. A search of runs is held by its steps (FLIP_MAX_STEPS)."
- Changed
run_dataset1 field changed- changed
Input schema / descriptionPrevious value: -"A plan of runs on one card (domain, card, plan, store and return, all required) or of solves of one solver (solver and plan). Rows <= 100000, steps in total <= 100000000, stored frames <= 16777216; inline: rows <= 1000, frames <= 10000, an answer counted from the plan <= 40000 characters; solves <= 64. With return \"file\" the answer is the head and the names of the files stored, on a connection started with a directory for them."New value: +"A plan of runs on one card (domain, card, plan, store and return, all required) or of solves of one solver (solver and plan). Rows <= 100000, steps in total <= 100000000, stored frames <= 16777216; inline: an answer counted from the plan <= 40000 characters, which a plan reaches first, a grid on one axis at about 140 summary rows and a list sooner, its head repeating each run's request (a plan of more than 1000 rows is refused before it is counted, as too large to return inline), and frames <= 10000; solves <= 64. With return \"file\" the answer is the head and the names of the files stored, on a connection started with a directory for them."
- Changed
run_trajectory1 field changed- changed
Input schema / properties / from / descriptionPrevious value: -"Optional: start from a sealed run. request: that run_trajectory request as sent (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."New value: +"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."
- Changed
verify_tape1 field changed- changed
Input schema / properties / request / descriptionPrevious value: -"With run_seal alone: the run_trajectory request as it was sent, with its readout and its from when it had them (the answer's inputs holds neither). It is run again, under a physics permit and the limits of run_trajectory, and its seal is compared with run_seal. Its fields are run_trajectory's. Worked example of the short form, as the whole arguments: {\"request\":{\"domain\":\"energy\",\"card\":\"thermal\",\"initial\":{\"temperature_k\":293.15},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"heat_power_w\":5.0,\"ambient_k\":293.15}}],\"record_every\":60},\"run_seal\":\"<the run_seal of its run_trajectory answer, 64 lowercase hex digits>\"}."New value: +"With run_seal alone: the run_trajectory request as it was sent, with its readout and its from when it had them (the answer's inputs holds neither; the upstream request in that from goes without a readout, as run_trajectory took it). It is run again, under a physics permit and the limits of run_trajectory, and its seal is compared with run_seal. Its fields are run_trajectory's. Worked example of the short form, as the whole arguments: {\"request\":{\"domain\":\"energy\",\"card\":\"thermal\",\"initial\":{\"temperature_k\":293.15},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"heat_power_w\":5.0,\"ambient_k\":293.15}}],\"record_every\":60},\"run_seal\":\"<the run_seal of its run_trajectory answer, 64 lowercase hex digits>\"}."
2 tool updates
- Changed
run_trajectory1 field changed- changed
Input schema / descriptionPrevious value: -"One anchored run. Total steps must be <= 1000000. Recorded frames must be <= 10000. The shape of initial and of each segment's load depends on the pair: describe_card gives it. A run can be refused in two ways, and they come back differently. A request turned away before computing is an error, not a result: its text is one sentence, nothing is sealed, and when the sentence gives the card's name for the refusal the name is in round brackets. A run that starts and is refused part way is a result: outcome is \"refused\", reject holds the name (null when the cause has none), reject_detail holds the sentence, which ends \"The run is sealed to step N. The state at step N+1 was refused and is not sealed.\", and the run is sealed up to that last landed step N: steps_landed is N, the count of steps that landed, so the step that was refused is steps_landed + 1. A run that reaches an end its card declares (the first maximum of power of a reactor burst, a capsule's flown parachute deployment, a mission's last day, the end of a record's clock or track) is not refused: outcome is \"ended\", reject holds the end's name, reject_detail a sentence beginning \"Ended\" that names the end, and the run is sealed up to its last landed step; describe_card lists a card's declared ends under declared_ends. A sentence that begins \"Physical Failure\" says the state asked for or reached is outside the card: past a published bound, a limit of the specimen, or the conservation ledger. A sentence that begins \"Physical Violation\" says the request, or a number in it or computed from it, is not one the engine takes: its shape, a missing or unknown key, the number rule, the step floor or ceiling, a load rule, a size limit, or a value that is not finite. A required key left out is named InputMissing, and a card the engine does not serve UnknownCard. A sentence with no name in round brackets is of a request that is not well formed (a key unknown, a value of the wrong type, a number the number rule refuses, a count or a size past the tool's own limit) or of a value that is not finite: no model stopped, and the request is what is corrected."New value: +"One anchored run. Total steps must be <= 1000000. Recorded frames must be <= 10000. The shape of initial and of each segment's load depends on the pair: describe_card gives it. A run can be refused in two ways, and they come back differently. A request turned away before computing is an error, not a result: its text is one sentence, nothing is sealed, and when the sentence gives the card's name for the refusal the name is in round brackets. A run that starts and is refused part way is a result: outcome is \"refused\", reject holds the name (null when the cause has none), reject_detail holds the sentence, which ends \"The run is sealed to step N. The state at step N+1 was refused and is not sealed.\", and the run is sealed up to that last landed step N: steps_landed is N, the count of steps that landed, so the step that was refused is steps_landed + 1. A run that reaches an end its card declares (the first maximum of power of a reactor burst, a capsule's flown parachute deployment, a crater that stops growing, a cell's runaway once every reactant is consumed) is not refused: outcome is \"ended\", reject holds the end's name, reject_detail a sentence beginning \"Ended\" that names the end, and the run is sealed up to its last landed step; describe_card lists a card's declared ends under declared_ends. A sentence that begins \"Physical Failure\" says the state asked for or reached is outside the card: past a published bound, a limit of the specimen, or the conservation ledger. A sentence that begins \"Physical Violation\" says the request, or a number in it or computed from it, is not one the engine takes: its shape, a missing or unknown key, the number rule, the step floor or ceiling, a load rule, a size limit, or a value that is not finite. A required key left out is named InputMissing, and a card the engine does not serve UnknownCard. A sentence with no name in round brackets is of a request that is not well formed (a key unknown, a value of the wrong type, a number the number rule refuses, a count or a size past the tool's own limit) or of a value that is not finite: no model stopped, and the request is what is corrected."
- Changed
validate_series1 field changed- added
Input schema / properties / commitmentAdded value: +{ + "additionalProperties": false, + "description": "Optional: a commitment the measurements were locked with before this comparison, opened by this request. sha256 is the SHA-256 of these bytes: the line zero-trust-physics/measurement-commitment/v1 and a line break; 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 {\"component\": <this request's component, or null>, \"measurements\": <this request's measurements>, \"quantity\": <this request's quantity>}; a line break; and the salt's bytes, its hex decoded. salt is 32 to 128 lowercase hex digits, 16 to 64 bytes, kept back until the comparison so that the data are not found from the sha256 by trying values. The engine makes the digest again from the request before computing: data that do not open it (a value, a step or a row changed, moved, added or dropped, another quantity or another salt) are refused as CommitmentDoesNotMatch, a salt shorter than 16 bytes as CommitmentSaltTooShort, a field of the wrong form as CommitmentMalformed, and sha256 or salt left out as InputMissing; nothing is computed and nothing is sealed. Opened, the comparison runs as it runs without one, validation_seal takes the commitment as a sixth part, and the answer says so in commitment_opened. A commitment shows that the data were not changed after it was made; when it was made is shown by where its sha256 was published before the comparison.", + "properties": { + "salt": { + "description": "The salt the sha256 was made with: 32 to 128 lowercase hex digits, 16 to 64 bytes.", + "type": "string" + }, + "sha256": { + "description": "The SHA-256 committed, 64 lowercase hex digits.", + "pattern": "^[0-9a-f]{64}$", + "type": "string" + } + }, + "required": [ + "sha256", + "salt" + ], + "type": "object" +}
11 tool updates
- Added
compute_step - Added
design_run - Changed
run_dataset1 field changed- changed
Input schema / properties / solver / descriptionPrevious value: -"A plan of solves: the solver, in place of domain and card. It takes no store and no return. A plan of solves is answered inline: a list, {\"kind\":\"list\",\"solves\":[{\"parameters\":{...}}]}, or a grid, {\"kind\":\"grid\",\"base\":{\"parameters\":{...}},\"axes\":[{\"path\":\"parameters.<input>\",\"values\":[...]}]}, of at most 64 solves. Each row is a solve request, solved as solve solves it and carrying the solution_seal solve gives it; a request turned away without a seal, by the rules of a request or by the solver, is an unadmitted row. The rows are sealed under one dataset_seal by the rules of a plan of runs, with solution_seal in the leaf in the place of run_seal, and completed in the counts counts the solves that converged. A summary row has row, set, outcome, reject, solution_seal and every single number of the result in decimals; answer \"full\" gives every solution whole, and is refused when it comes to more than 40000 characters. verify_dataset checks a plan of solves by its request and dataset_seal, and validate_series compares one number of its results with measurements. Worked plan of solves: {\"solver\":\"atom_dft\",\"plan\":{\"kind\":\"list\",\"solves\":[{\"parameters\":{\"atomic_number\":10}}]}}."New value: +"A plan of solves: the solver, in place of domain and card. It takes no store and no return. A plan of solves is answered inline: a list, {\"kind\":\"list\",\"solves\":[{\"parameters\":{...}}]}, or a grid, {\"kind\":\"grid\",\"base\":{\"parameters\":{...}},\"axes\":[{\"path\":\"parameters.<input>\",\"values\":[...]}]}, of at most 64 solves. Each row is a solve request, solved as solve solves it and carrying the solution_seal solve gives it; a request turned away without a seal, by the rules of a request or by the solver, is an unadmitted row. The rows are sealed under one dataset_seal by the rules of a plan of runs, with solution_seal in the leaf in the place of run_seal, and completed in the counts counts the solves that converged. A summary row has row, set, outcome, reject, solution_seal and every single number of the result in decimals; answer \"full\" gives every solution whole, and is refused when it comes to more than 40000 characters. verify_dataset verifies a plan of solves by its request and dataset_seal, and validate_series compares one number of its results with measurements. Worked plan of solves: {\"solver\":\"atom_dft\",\"plan\":{\"kind\":\"list\",\"solves\":[{\"parameters\":{\"atomic_number\":10}}]}}."
- Changed
run_trajectory4 fields changed- changed
Input schema / descriptionPrevious value: -"One anchored run. Total steps must be <= 1000000. Recorded frames must be <= 10000. The shape of initial and of each segment's load depends on the pair: describe_card gives it. A run can be refused in two ways, and they come back differently. A request turned away before computing is an error, not a result: its text is one sentence, nothing is sealed, and when the sentence gives the card's name for the refusal the name is in round brackets. A run that starts and is refused part way is a result: outcome is \"refused\", reject holds the name (null when the cause has none), reject_detail holds the sentence, which ends \"The run is sealed to step N. The state at step N+1 was refused and is not sealed.\", and the run is sealed up to that last landed step N: steps_landed is N, the count of steps that landed, so the step that was refused is steps_landed + 1. A run that reaches an end its card declares (the first maximum of power of a reactor burst, a capsule's flown parachute deployment, a mission's last day, the end of a record's clock or track) is not refused: outcome is \"ended\", reject holds the end's name, reject_detail a sentence beginning \"Ended\" that names the end, and the run is sealed up to its last landed step; describe_card lists a card's declared ends under declared_ends. A sentence that begins \"Physical Failure\" says the state asked for or reached is outside the card: past a published bound, a limit of the specimen, or the conservation ledger. A sentence that begins \"Physical Violation\" says the request, or a number in it or computed from it, is not one the engine takes: its shape, a missing or unknown key, the number rule, the step floor or ceiling, a load rule, a size limit, or a value that is not finite. A sentence with no name in round brackets is of a request that is not well formed (a key missing or unknown, a value of the wrong type, a number the number rule refuses, a count or a size past the tool's own limit) or of a value that is not finite: no model stopped, and the request is what is corrected."New value: +"One anchored run. Total steps must be <= 1000000. Recorded frames must be <= 10000. The shape of initial and of each segment's load depends on the pair: describe_card gives it. A run can be refused in two ways, and they come back differently. A request turned away before computing is an error, not a result: its text is one sentence, nothing is sealed, and when the sentence gives the card's name for the refusal the name is in round brackets. A run that starts and is refused part way is a result: outcome is \"refused\", reject holds the name (null when the cause has none), reject_detail holds the sentence, which ends \"The run is sealed to step N. The state at step N+1 was refused and is not sealed.\", and the run is sealed up to that last landed step N: steps_landed is N, the count of steps that landed, so the step that was refused is steps_landed + 1. A run that reaches an end its card declares (the first maximum of power of a reactor burst, a capsule's flown parachute deployment, a mission's last day, the end of a record's clock or track) is not refused: outcome is \"ended\", reject holds the end's name, reject_detail a sentence beginning \"Ended\" that names the end, and the run is sealed up to its last landed step; describe_card lists a card's declared ends under declared_ends. A sentence that begins \"Physical Failure\" says the state asked for or reached is outside the card: past a published bound, a limit of the specimen, or the conservation ledger. A sentence that begins \"Physical Violation\" says the request, or a number in it or computed from it, is not one the engine takes: its shape, a missing or unknown key, the number rule, the step floor or ceiling, a load rule, a size limit, or a value that is not finite. A required key left out is named InputMissing, and a card the engine does not serve UnknownCard. A sentence with no name in round brackets is of a request that is not well formed (a key unknown, a value of the wrong type, a number the number rule refuses, a count or a size past the tool's own limit) or of a value that is not finite: no model stopped, and the request is what is corrected." - changed
Input schema / properties / initial / descriptionPrevious value: -"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. describe_card gives them, with each unit and bound."New value: +"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." - added
Input schema / properties / segments / descriptionAdded value: +"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." - added
Input schema / properties / segments / items / properties / signedAdded value: +{ + "additionalProperties": false, + "description": "An instrument's Ed25519 signature over this reading, by the rule run_trajectory's input schema gives at segments.", + "properties": { + "alg": { + "enum": [ + "ed25519" + ], + "type": "string" + }, + "challenge": { + "type": [ + "string", + "null" + ] + }, + "instrument": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "key": { + "pattern": "^[0-9a-f]{64}$", + "type": "string" + }, + "prev": { + "type": [ + "string", + "null" + ] + }, + "seq": { + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "sig": { + "pattern": "^[0-9a-f]{128}$", + "type": "string" + }, + "time": { + "type": "string" + } + }, + "required": [ + "alg", + "key", + "instrument", + "time", + "seq", + "prev", + "challenge", + "sig" + ], + "type": "object" +}
- Changed
solve1 field changed- changed
Input schema / properties / parameters / descriptionPrevious value: -"The inputs of the solver named in 'solver', each a number, a whole number, a word, a flag or an array as describe_solver gives it, and no other key. Every number of a solve request must be a finite, normal 64-bit number or zero, and a number written as non-zero must not read as zero. This rule is the one every card's request follows, and it stands beside each input's range and refuses some values inside it: a subnormal such as 5e-324 is refused wherever zero and larger numbers are accepted. A solution has no frame, so the card's rule that a number fit a 32-bit frame slot does not apply."New value: +"The inputs of the solver named in 'solver', each a number, a whole number, a word, a flag or an array as describe_solver gives it, and no other key but signed. Every number of a solve request must be a finite, normal 64-bit number or zero, and a number written as non-zero must not read as zero. This rule is the one every card's request follows, and it stands beside each input's range and refuses some values inside it: a subnormal such as 5e-324 is refused wherever zero and larger numbers are accepted. A solution has no frame, so the card's rule that a number fit a 32-bit frame slot does not apply. A required input left out is refused as InputMissing, and an input given with a choice it does not go with as InputNotWithChoice, each in a sentence that names the input, and a solver the engine does not serve as UnknownSolver; nothing is filled in. parameters may also carry signed, an instrument's signature over the other parameters under the key \"parameters\", by the rule run_trajectory's input schema gives at segments; it is verified before solving, the solver takes the other parameters, and the answer then carries load_source, naming the key. A solve answer without load_source holds no signed parameter."
- Changed
validate_series3 fields changed- added
Input schema / properties / measurements / items / properties / signedAdded value: +{ + "additionalProperties": false, + "description": "An instrument's Ed25519 signature over this reading, by the rule run_trajectory's input schema gives at segments.", + "properties": { + "alg": { + "enum": [ + "ed25519" + ], + "type": "string" + }, + "challenge": { + "type": [ + "string", + "null" + ] + }, + "instrument": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "key": { + "pattern": "^[0-9a-f]{64}$", + "type": "string" + }, + "prev": { + "type": [ + "string", + "null" + ] + }, + "seq": { + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "sig": { + "pattern": "^[0-9a-f]{128}$", + "type": "string" + }, + "time": { + "type": "string" + } + }, + "required": [ + "alg", + "key", + "instrument", + "time", + "seq", + "prev", + "challenge", + "sig" + ], + "type": "object" +} - changed
Input schema / properties / run / properties / initial / descriptionPrevious value: -"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. describe_card gives them, with each unit and bound."New value: +"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." - added
Input schema / properties / run / properties / segments / items / properties / signedAdded value: +{ + "additionalProperties": false, + "description": "An instrument's Ed25519 signature over this reading, by the rule run_trajectory's input schema gives at segments.", + "properties": { + "alg": { + "enum": [ + "ed25519" + ], + "type": "string" + }, + "challenge": { + "type": [ + "string", + "null" + ] + }, + "instrument": { + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "key": { + "pattern": "^[0-9a-f]{64}$", + "type": "string" + }, + "prev": { + "type": [ + "string", + "null" + ] + }, + "seq": { + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "sig": { + "pattern": "^[0-9a-f]{128}$", + "type": "string" + }, + "time": { + "type": "string" + } + }, + "required": [ + "alg", + "key", + "instrument", + "time", + "seq", + "prev", + "challenge", + "sig" + ], + "type": "object" +}
- Changed
verify_dataset2 fields changed- changed
Input schema / descriptionPrevious value: -"One of three forms. request and dataset_seal, the short form: the plan is run again and its seal compared. The three parts a run_dataset answer carries (head, rows and frames_hex, all three required together): the rows, the root and the seal are recomputed with no physics run. dataset_seal alone: the stored dataset of that seal is checked with no physics run."New value: +"One of three forms. request and dataset_seal, the short form: the plan is run again and its seal compared. The three parts a full run_dataset answer carries (head, rows and frames_hex, all three required together, as they came), the long form: the rows, the root and the seal are recomputed from their exact values, then the head's plan is run again under the permits and the limits of run_dataset and the engine's full answer to it compared with the parts sent, value by value and then byte for byte, so a dataset that holds is every byte the engine's. dataset_seal alone: the stored dataset of that seal, its seals recomputed from its files and its plan run again into a folder of its own, the stored files compared with that run's byte for byte. The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs." - changed
Input schema / properties / dataset_seal / descriptionPrevious value: -"With request: the dataset_seal of the run_dataset answer, compared with the seal the plan runs to. Alone: the seal of a dataset stored as files (return \"file\"), read from the connection's own folder of that name. A dataset returned in the answer is not stored: it is checked with its request, or by its head, rows and frames_hex."New value: +"With request: the dataset_seal of the run_dataset answer, compared with the seal the plan runs to. Alone: the seal of a dataset stored as files (return \"file\"), read from the connection's own folder of that name. A dataset returned in the answer is not stored: it is verified with its request, or by its head, rows and frames_hex."
- Changed
verify_receipt1 field changed- changed
Input schema / descriptionPrevious value: -"The text of one response from verify_step, run_trajectory or solve, or the head of a dataset written as its JSON text."New value: +"The text of one response from compute_step, run_trajectory or solve, or the head of a dataset written as its JSON text."
- Changed
verify_solution2 fields changed- changed
Input schema / descriptionPrevious value: -"Either request and solution_seal alone, the short form: the request is solved again and its seal compared with solution_seal. Or the whole solve answer sent back, without request: inputs, engine_version, outcome, iterations, reject, result, invariants, field_sha256, seal_parts and solution_seal are then all required, the solution seal is recomputed and the part that fails is named, with no physics run."New value: +"Either request and solution_seal alone, the short form: the request is solved again and its seal compared with solution_seal. Or the whole solve answer sent back as it came, without request, the long form: inputs, engine_version, outcome, iterations, reject, result, invariants, field_sha256, seal_parts and solution_seal are then all required. The solution seal is recomputed from its exact hex values and the part that fails is named; then its request is solved again under a physics permit and the limits of solve, and the engine's whole answer to it compared with the answer sent, value by value and then byte for byte, the receipt included, so an answer that holds is every byte the engine's. A seal has no key: an answer whose values were rewritten with its seal parts, seal and receipt worked out again holds every seal, and only the solve shows it is not the engine's (cause solution_seal). The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs." - changed
Input schema / properties / inputs / descriptionPrevious value: -"The inputs of the solve answer, sent back as returned: the request that was solved. It is hashed, not solved."New value: +"The inputs of the solve answer, sent back as returned: the request that was solved. It is hashed, and solved again under a physics permit and the limits of solve."
- Changed
verify_step1 field changed- changed
Input schema / properties / parameters / descriptionPrevious value: -"The step's inputs: the card's phase fields, its load fields and dt_s, each a number (a vector field is an array of three numbers), and no other key. describe_card gives the fields of the pair, with each unit and bound."New value: +"The step's inputs: the card's phase fields, its load fields and dt_s, each a number (a vector field is an array of three numbers), and no other key. describe_card gives the fields of the pair, with each unit and bound. A required field left out is refused as InputMissing, in a sentence that names the field, and a card the engine does not serve as UnknownCard; nothing is filled in."
- Changed
verify_tape2 fields changed- changed
Input schema / descriptionPrevious value: -"Either request and run_seal alone, the short form: the run is computed again and its seal compared with run_seal. Or the whole run_trajectory answer sent back as it was returned, without request: inputs, frames, outcome, steps_landed, reject, run_seal, final_state, final_residual_conservation_error_hex, max_residual_conservation_error_hex and state_digest are then all required, and the trajectory chain, the state digest and the run seal are recomputed with no physics run."New value: +"Either request and run_seal alone, the short form: the run is computed again and its seal compared with run_seal. Or the whole run_trajectory answer sent back as it was returned, without request, the long form: inputs, frames, outcome, steps_landed, reject, run_seal, final_state, final_residual_conservation_error_hex, max_residual_conservation_error_hex and state_digest are then all required, along with the rest of the answer. The trajectory chain, the state digest and the run seal are recomputed from its exact hex values; then its request is computed again under a physics permit and the limits of run_trajectory, and the engine's whole answer to it compared with the answer sent, value by value and then byte for byte, the receipt included, so an answer that holds is every byte the engine's. A seal has no key: an answer whose values were rewritten with its seals worked out again holds every seal, and only the computation shows it is not the engine's. An answer that continues a sealed upstream run (its chain names upstream_run_seal) carries the upstream's seal and not its request, and its long form is refused (AnswerCarriesNoRequest): its chain's answers in order, as links, carry each request, and each link is computed again from the links before it. Or links alone: a chain's answers in order, held as the long form holds one. A design_run answer sent whole is designed again and held the same way. The long form's answer carries holds, true when the answer sent is every byte the engine's, and values_hold beside it, true when every value of it is the engine's answer to its request computed again, whatever its spelling: each number by its 64-bit value, strings, flags and null exactly, keys and their order, the receipt string among them. A copy whose numbers a client wrote again in its own spelling (0.0001 for 1.0e-4, 12 for 12.0) has holds false and values_hold true, and differs_at names the first place its text differs." - changed
Input schema / properties / inputs / descriptionPrevious value: -"The inputs of the run_trajectory answer, sent back as returned: the request that was run. It is hashed, not run. A card's fields, units and bounds are in describe_card."New value: +"The inputs of the run_trajectory answer, sent back as returned: the request that was run. It is hashed, and run again, with the answer's readout when it has one, under a physics permit and the limits of run_trajectory. A card's fields, units and bounds are in describe_card."
10 tool updates
- Changed
cite1 field changed- changed
Input schema / properties / domain / descriptionPrevious value: -"With card: a card, by the name find_model or list_cards gives. When find_model has given it, no list need be read."New value: +"With card: a card, by the name find_model or list_cards gives; the two give the same names."
- Changed
find_flip2 fields changed- added
Input schema / properties / level / descriptionAdded value: +"Optional. {\"quantity\": <a published quantity>, \"value\": <number>}: the span is halved to where that quantity of the final state (of a solve: of result) crosses the value. {\"quantity\": <a flag>}: to where a true-or-false value of it turns." - changed
Input schema / properties / vary / descriptionPrevious value: -"The place of the one number to vary."New value: +"The place of the one number to vary: \"segments[0].load.current_a\", \"segments[*].load.current_a\" for every segment, \"initial.soc\", \"dt_s\", \"segments[0].steps\", \"parameters.load_n\". A count is varied in whole numbers."
- Changed
run_dataset4 fields changed- changed
Input schema / descriptionPrevious value: -"A plan of runs on one card (domain, card, plan, store and return, all required) or of solves of one solver (solver and plan). Rows <= 100000, steps in total <= 100000000, stored frames <= 16777216; inline: rows <= 1000, frames <= 10000, an answer counted from the plan <= 40000 characters; solves <= 64. With return \"file\" the answer is the head and the names of the files the gateway stored, and the gateway must have been started with a directory for them."New value: +"A plan of runs on one card (domain, card, plan, store and return, all required) or of solves of one solver (solver and plan). Rows <= 100000, steps in total <= 100000000, stored frames <= 16777216; inline: rows <= 1000, frames <= 10000, an answer counted from the plan <= 40000 characters; solves <= 64. With return \"file\" the answer is the head and the names of the files stored, on a connection started with a directory for them." - changed
Input schema / properties / answer / descriptionPrevious value: -"Leave out, or \"summary\", for the head and one short summary row per row: the values it sets, outcome, steps landed, refusal name and seal; \"states\" adds each run's final state in decimals; \"full\" gives every row whole. With return \"file\" the answer is the head and the names of the files whatever this says. Not part of the sealed request."New value: +"Leave out, or \"summary\", for the head and one short summary row per row: the values it sets, outcome, steps landed, refusal name and seal; \"states\" adds each run's final state in decimals; \"full\" gives every row whole. With return \"file\" the answer is the head and the names of the files whatever this says. Not part of the sealed request. The head and the dataset_seal are the same in all three forms. A summary row holds row, set (the values a grid's or a sample's row sets), outcome, steps_landed, reject and run_seal; the quantities of one row are read by sending its request to run_trajectory with a readout. An ended row is a run that stopped at an end its card declares: it has a run seal, the end's reject name in reject and the sentence naming the end in reject_detail. A refused row is a run the card refused part way: it has a run seal, the refusal's name in reject and its sentence in reject_detail. An unadmitted row is a request turned away before computing: it has no run seal, and its sentence, with the refusal's name in round brackets when the sentence gives one, is its reject_detail; its summary row gives that name in reject. What a sentence that begins \"Physical Failure\" or \"Physical Violation\" means is in the description of run_trajectory. An inline answer is counted from the plan before anything runs, and one above 40000 characters is refused with what to change: a summary row counts 220 characters and the values it sets; with states, each number of the final state adds its name and 28 characters (84 for a 3-vector, 9 for a flag); a whole row counts its own request and 1900 characters, and for each number twice its name and 60 characters (150 for a 3-vector, 9 for a flag); store \"frames\" adds 128 characters for each recorded state to a full answer; the head repeats the request." - added
Input schema / properties / plan / descriptionAdded value: +"A path names one number: initial.<field>, dt_s, or segments[0].load.<field>, with the segment's number in square brackets and [0], [1] or [2] after a 3-vector field for one of its components. steps and record_every are not paths and cannot vary: every row of a grid or a sample takes them from the base run. A value an axis or a draw sets replaces the base's value of that field, and the answer's base_replaced names each field replaced; a 3-vector the base sets whole is replaced only when the paths set all three of its components. Two paths may not set one number. Each row of a grid is held to the card's bounds alone, as each run of a list is: a value outside a bound makes that row unadmitted and the other rows run. A sample's interval or choice outside a bound refuses the plan. One worked plan of each kind, each a whole request: list: {\"domain\":\"energy\",\"card\":\"thermal\",\"plan\":{\"kind\":\"list\",\"runs\":[{\"initial\":{\"temperature_k\":293.15},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"heat_power_w\":5.0,\"ambient_k\":293.15}}],\"record_every\":60}]},\"store\":\"none\",\"return\":\"inline\"} grid: {\"domain\":\"energy\",\"card\":\"thermal\",\"plan\":{\"kind\":\"grid\",\"base\":{\"initial\":{},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"ambient_k\":293.15}}],\"record_every\":60},\"axes\":[{\"path\":\"initial.temperature_k\",\"values\":[283.15,293.15]},{\"path\":\"segments[0].load.heat_power_w\",\"values\":[0.0,5.0,10.0]}]},\"store\":\"none\",\"return\":\"inline\"} sample: {\"domain\":\"energy\",\"card\":\"thermal\",\"plan\":{\"kind\":\"sample\",\"base\":{\"initial\":{},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"ambient_k\":293.15}}],\"record_every\":60},\"rows\":4,\"generator\":\"splitmix64_counter_v1\",\"seed_hex\":\"0000000000000001\",\"draws\":[{\"path\":\"initial.temperature_k\",\"choice\":[283.15,293.15]},{\"path\":\"segments[0].load.heat_power_w\",\"uniform\":{\"low\":0.0,\"high\":10.0}}]},\"store\":\"none\",\"return\":\"inline\"}." - changed
Input schema / properties / solver / descriptionPrevious value: -"A plan of solves: the solver, in place of domain and card. It takes no store and no return."New value: +"A plan of solves: the solver, in place of domain and card. It takes no store and no return. A plan of solves is answered inline: a list, {\"kind\":\"list\",\"solves\":[{\"parameters\":{...}}]}, or a grid, {\"kind\":\"grid\",\"base\":{\"parameters\":{...}},\"axes\":[{\"path\":\"parameters.<input>\",\"values\":[...]}]}, of at most 64 solves. Each row is a solve request, solved as solve solves it and carrying the solution_seal solve gives it; a request turned away without a seal, by the rules of a request or by the solver, is an unadmitted row. The rows are sealed under one dataset_seal by the rules of a plan of runs, with solution_seal in the leaf in the place of run_seal, and completed in the counts counts the solves that converged. A summary row has row, set, outcome, reject, solution_seal and every single number of the result in decimals; answer \"full\" gives every solution whole, and is refused when it comes to more than 40000 characters. verify_dataset checks a plan of solves by its request and dataset_seal, and validate_series compares one number of its results with measurements. Worked plan of solves: {\"solver\":\"atom_dft\",\"plan\":{\"kind\":\"list\",\"solves\":[{\"parameters\":{\"atomic_number\":10}}]}}."
- Changed
run_trajectory4 fields changed- changed
Input schema / descriptionPrevious value: -"One anchored run. Total steps must be <= 1000000. Recorded frames must be <= 10000. The shape of initial and of each segment's load depends on the pair: read describe_card for it."New value: +"One anchored run. Total steps must be <= 1000000. Recorded frames must be <= 10000. The shape of initial and of each segment's load depends on the pair: describe_card gives it. A run can be refused in two ways, and they come back differently. A request turned away before computing is an error, not a result: its text is one sentence, nothing is sealed, and when the sentence gives the card's name for the refusal the name is in round brackets. A run that starts and is refused part way is a result: outcome is \"refused\", reject holds the name (null when the cause has none), reject_detail holds the sentence, which ends \"The run is sealed to step N. The state at step N+1 was refused and is not sealed.\", and the run is sealed up to that last landed step N: steps_landed is N, the count of steps that landed, so the step that was refused is steps_landed + 1. A run that reaches an end its card declares (the first maximum of power of a reactor burst, a capsule's flown parachute deployment, a mission's last day, the end of a record's clock or track) is not refused: outcome is \"ended\", reject holds the end's name, reject_detail a sentence beginning \"Ended\" that names the end, and the run is sealed up to its last landed step; describe_card lists a card's declared ends under declared_ends. A sentence that begins \"Physical Failure\" says the state asked for or reached is outside the card: past a published bound, a limit of the specimen, or the conservation ledger. A sentence that begins \"Physical Violation\" says the request, or a number in it or computed from it, is not one the engine takes: its shape, a missing or unknown key, the number rule, the step floor or ceiling, a load rule, a size limit, or a value that is not finite. A sentence with no name in round brackets is of a request that is not well formed (a key missing or unknown, a value of the wrong type, a number the number rule refuses, a count or a size past the tool's own limit) or of a value that is not finite: no model stopped, and the request is what is corrected." - changed
Input schema / properties / from / descriptionPrevious value: -"Optional: start from a sealed run. request: that run_trajectory request as sent (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. The run_seal is that of this request without from; chain.chain_seal commits it to the upstream."New value: +"Optional: start from a sealed run. request: that run_trajectory request as sent (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." - changed
Input schema / properties / readout / descriptionPrevious value: -"Optional. The named quantities in decimals at the recorded steps, each one's minimum and maximum over every landed step with its step, its time and every other listed quantity at that step (at_minimum, at_maximum), and first_past when asked. Not part of the sealed request: the run_seal is that of the same run without it."New value: +"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." - added
Input schema / properties / record_every / descriptionAdded value: +"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 230 characters for each recorded state, plus the request as it was sent, plus up to 8000 characters for the final state and the seals. 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."
- Changed
solve1 field changed- changed
Input schema / descriptionPrevious value: -"One sealed solution. The same request as POST /solve."New value: +"One sealed solution."
- Changed
validate_series3 fields changed- changed
Input schema / descriptionPrevious value: -"One run, or one plan of solves, and measurements of one quantity. The answer is the error in numbers, sealed with a hash of the measurements. It holds no verdict. Send run, or solves, not both."New value: +"One run, or one plan of solves, and measurements of one quantity. The answer is the error in numbers, sealed with a hash of the measurements. It holds no verdict. A request holds run or solves, not both." - changed
Input schema / properties / measurements / descriptionPrevious value: -"At most 10000. A measurement is compared with the state after landed step k. There is no interpolation and no time matching: map your sample times to steps."New value: +"At most 10000. A measurement is compared with the state after landed step k. There is no interpolation and no time matching: a measurement is placed by its step, its time since the start divided by dt_s." - changed
Input schema / properties / run / descriptionPrevious value: -"One anchored run. Total steps must be <= 1000000. Recorded frames must be <= 10000. The shape of initial and of each segment's load depends on the pair: read describe_card for it."New value: +"One anchored run. Total steps must be <= 1000000. Recorded frames must be <= 10000. The shape of initial and of each segment's load depends on the pair: describe_card gives it."
- Changed
verify_dataset3 fields changed- changed
Input schema / descriptionPrevious value: -"Send one of three forms. request and dataset_seal, the short form: the plan is run again and its seal compared. The three parts a run_dataset answer carries (head, rows and frames_hex, all three required together): the rows, the root and the seal are recomputed with no physics run. dataset_seal alone: the stored dataset of that seal is checked with no physics run."New value: +"One of three forms. request and dataset_seal, the short form: the plan is run again and its seal compared. The three parts a run_dataset answer carries (head, rows and frames_hex, all three required together): the rows, the root and the seal are recomputed with no physics run. dataset_seal alone: the stored dataset of that seal is checked with no physics run." - changed
Input schema / properties / dataset_seal / descriptionPrevious value: -"With request: the dataset_seal of the run_dataset answer, compared with the seal the plan runs to. Alone: the seal of a dataset the gateway stored in files (return \"file\"); the gateway reads its own folder of that name. A dataset returned in the answer is not stored: send it with its request, or send its head, rows and frames_hex."New value: +"With request: the dataset_seal of the run_dataset answer, compared with the seal the plan runs to. Alone: the seal of a dataset stored as files (return \"file\"), read from the connection's own folder of that name. A dataset returned in the answer is not stored: it is checked with its request, or by its head, rows and frames_hex." - changed
Input schema / properties / request / descriptionPrevious value: -"With dataset_seal alone: the run_dataset request as it was sent (the head's request). The plan is run again, under the permits and the limits of run_dataset, and its seal is compared with dataset_seal. Nothing is stored or read from storage, so it works whatever the return mode and on every connection. Its fields are run_dataset's."New value: +"With dataset_seal alone: the run_dataset request as it was sent (the head's request). The plan is run again, under the permits and the limits of run_dataset, and its seal is compared with dataset_seal. Nothing is stored or read from storage, so it works whatever the return mode and on every connection. Its fields are run_dataset's. Worked example of the short form, as the whole arguments: {\"request\":{\"domain\":\"energy\",\"card\":\"thermal\",\"plan\":{\"kind\":\"list\",\"runs\":[{\"initial\":{\"temperature_k\":293.15},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"heat_power_w\":5.0,\"ambient_k\":293.15}}],\"record_every\":60}]},\"store\":\"none\",\"return\":\"inline\"},\"dataset_seal\":\"<the dataset_seal of its run_dataset answer, 64 lowercase hex digits>\"}."
- Changed
verify_solution1 field changed- changed
Input schema / properties / request / descriptionPrevious value: -"With solution_seal alone: the solve request as it was sent (the answer's inputs). It is solved again, under a physics permit and the limits of solve, and its seal is compared with solution_seal. Its fields are solve's."New value: +"With solution_seal alone: the solve request as it was sent (the answer's inputs). It is solved again, under a physics permit and the limits of solve, and its seal is compared with solution_seal. Its fields are solve's. Worked example of the short form, as the whole arguments: {\"request\":{\"solver\":\"atom_dft\",\"parameters\":{\"atomic_number\":10}},\"solution_seal\":\"<the solution_seal of its solve answer, 64 lowercase hex digits>\"}."
- Changed
verify_step1 field changed- changed
Input schema / descriptionPrevious value: -"One anchored step. The same request as POST /verify_physics. The shape of parameters depends on the pair: read describe_card for it."New value: +"One anchored step. The shape of parameters depends on the pair: describe_card gives it."
- Changed
verify_tape1 field changed- changed
Input schema / properties / request / descriptionPrevious value: -"With run_seal alone: the run_trajectory request as it was sent, with its readout and its from when it had them (the answer's inputs holds neither). It is run again, under a physics permit and the limits of run_trajectory, and its seal is compared with run_seal. Its fields are run_trajectory's."New value: +"With run_seal alone: the run_trajectory request as it was sent, with its readout and its from when it had them (the answer's inputs holds neither). It is run again, under a physics permit and the limits of run_trajectory, and its seal is compared with run_seal. Its fields are run_trajectory's. Worked example of the short form, as the whole arguments: {\"request\":{\"domain\":\"energy\",\"card\":\"thermal\",\"initial\":{\"temperature_k\":293.15},\"dt_s\":1.0,\"segments\":[{\"steps\":60,\"load\":{\"heat_power_w\":5.0,\"ambient_k\":293.15}}],\"record_every\":60},\"run_seal\":\"<the run_seal of its run_trajectory answer, 64 lowercase hex digits>\"}."
2 tool updates
- Changed
describe_card1 field changed- added
Input schema / properties / formAdded value: +{ + "description": "Leave this key out, or \"full\", for the whole description; \"short\" for a page that is enough to write a first request.", + "enum": [ + "short", + "full" + ], + "type": "string" +}
- Changed
describe_solver1 field changed- added
Input schema / properties / formAdded value: +{ + "description": "Leave this key out, or \"full\", for the whole description; \"short\" for a page that is enough to write a first request.", + "enum": [ + "short", + "full" + ], + "type": "string" +}
1 tool update
- Changed
verify_tape1 field changed- changed
Input schema / properties / request / descriptionPrevious value: -"With run_seal alone: the run_trajectory request as it was sent (the answer's inputs). It is run again, under a physics permit and the limits of run_trajectory, and its seal is compared with run_seal. Its fields are run_trajectory's."New value: +"With run_seal alone: the run_trajectory request as it was sent, with its readout and its from when it had them (the answer's inputs holds neither). It is run again, under a physics permit and the limits of run_trajectory, and its seal is compared with run_seal. Its fields are run_trajectory's."
16 tool updates
- First observed
cite - First observed
describe_card - First observed
describe_solver - First observed
find_flip - First observed
find_model - First observed
list_cards - First observed
list_solvers - First observed
run_dataset - First observed
run_trajectory - First observed
solve - First observed
validate_series - First observed
verify_dataset - First observed
verify_receipt - First observed
verify_solution - First observed
verify_step - First observed
verify_tape
Related MCP Connectors
Signed Buildability Oracle for AI-for-science papers. ed25519 receipts, Wave proofs, divergence.
Verifiable, deterministic risk math for autonomous agents; re-runnable proof on every answer.
Deterministic signed verification of numeric & financial claims for AI agents & spreadsheets.
AI agents post reproducible tests, answer questions and verify each other's results.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables AI assistants and autonomous agents to intercept arithmetic and algebraic hallucinations via exact rational verification, seal multi-step reasoning chains with SHA-256 Merkle commitments, and optionally bridge deep verification to a remote sovereign enclave. It also supports BFT epistemic consensus across multi-agent proposals and tamper-evident session sealing.9MIT
- FlicenseBqualityCmaintenanceEnables AI agents to query verifiable physical-world ground truth for any point on Earth — water availability, seismic and space-weather hazard, ground stability, and resource indications — with every answer backed by a Bitcoin-anchored provenance record that can be independently verified. It also lets agents check whether an Earth-science hypothesis has already been tested, list documented nulls and retractions, and run bounded controlled tests that return UNTESTABLE rather than fabricate a result.11-
- AlicenseNot gradedqualityFmaintenanceEnables physicists to perform computer algebra calculations, create scientific plots, solve differential equations, work with tensor algebra and quantum mechanics, and parse natural language physics problems. Supports unit conversion, physical constants, and generates comprehensive reports with optional GPU acceleration.10MIT
- AlicenseBqualityBmaintenanceThis server enables decidable, hardware-attested semantic verification of AI outputs using on-chip ballistic walks, providing reproducible receipts that can be recomputed byte-for-byte.12345 npm1MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.