Skip to main content
Glama

Run trajectory

run_trajectory
Read-onlyIdempotent

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.

Input Schema

NameRequiredDescriptionDefault
cardYesThe card of the pair, as list_cards names it.
dt_sYesStep, in seconds. Held for the whole run.
fromNoOptional: 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.
domainYesThe domain of the pair, as list_cards names it.
initialYesThe 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.
readoutNoOptional. 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.
segmentsYesA 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_everyYesA 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.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / from / properties / run_seal / pattern
      Previous value: -"^[0-9a-f]{64}$"New value: +"^[0-9a-f]{96}$"
    • changedInput schema / properties / record_every / description
      Previous 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."
  2. Changed1 schema field changed
    • changedInput schema / properties / from / description
      Previous 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."
  3. Changed1 schema field changed
    • changedInput schema / description
      Previous 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."
  4. Changed4 schema fields changed
    • changedInput schema / description
      Previous 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."
    • changedInput schema / properties / initial / description
      Previous 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."
    • addedInput schema / properties / segments / description
      Added 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."
    • addedInput schema / properties / segments / items / properties / signed
      Added 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"
      +}
  5. Changed4 schema fields changed
    • changedInput schema / description
      Previous 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."
    • changedInput schema / properties / from / description
      Previous 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."
    • changedInput schema / properties / readout / description
      Previous 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."
    • addedInput schema / properties / record_every / description
      Added 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."
  6. First observed

TDQS

A3.6/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources