whatif
Server Details
Conversational what-if simulation: build, diagnose and compare Petri-net models; CC0 catalog.
- Status
- Healthy
- Uptime
- 55.5% over 59 days
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-06-18
- URL
TDQS
Scored across 55 tools
Most tools are individually well-described, but several clusters overlap: sim_scenario/sim_compare/sim_run_pipeline/sim_receipt, sim_calibrate/sim_conformance/sim_conformance_stream, sim_classify/sim_refine/sim_propose_types, and sim_prove/sim_canonical/sim_check_witness require careful reading to distinguish. Descriptions help, but subtle boundaries between run/analyse/prove/publish variants remain.
All tools use a consistent sim_ snake_case prefix with a predictable noun/verb pattern (sim_get_model, sim_list_models, sim_create_model). Minor variants like sim_code_to_flow and sim_param_heatmap remain readable and do not break the convention.
55 tools is far above a reasonable MCP surface size and exceeds the 50+ threshold, making selection and maintenance unwieldy even for a broad Petri-net platform. Most tools cover distinct functions, but the set should be split or aggregated.
The surface covers model CRUD, simulation, calibration/conformance, structural proof, provenance, querying, publishing, systems/bindings, and auxiliary maps/collections. Only minor immutability-driven lifecycle gaps exist (e.g., no delete for maps, bindings, or collection members).
Available Tools
56 toolssim_accept_migrationADestructiveInspect
Carry offered taxonomic edges of a superseded model forward to its current successor. edges lists 1 to 25 edge ids that sim_migration_offers(model) offered; pass successor (the current it returned) so a different current successor — a re-point or a chain that grew since — is refused rather than followed. Every edge is checked before anything is written (it must touch model, be offered, pass sim_link's check, you must own model or have authored the edge, and the edge it becomes must pass its predicate's write rule for you — hasMember only for the collection's owner); one failure refuses the call and writes nothing. Each accepted edge is written on the successor attributed to you, with no timestamp, plus a migratedFrom edge from it to the old edge (provenance; sim_edges() shows it, and sim_query closure over migratedFrom traces it back across several supersessions). The old edge stays. Re-running converges on the same ids; an edge you already linked the same way is reused (existing: true, keeping its own timestamp). A call stopped after some edges were written says which were and which were not. Needs sign-in with write scope (opens OAuth the first time); MCP only. Costs 1 compute token per call.
| Name | Required | Description | Default |
|---|---|---|---|
| edges | Yes | 1 to 25 edge ids sim_migration_offers(model) offered | |
| model | Yes | content id of the superseded model | |
| successor | No | the current successor sim_migration_offers returned; a different current successor now is refused |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the annotations: it enumerates every precondition (edge touches model, is offered, passes sim_link's check, ownership or authorship, target predicate's write rule), states atomic validation (all edges checked before anything is written; one failure writes nothing), describes partial-failure reporting, confirms the old edge survives, explains attribution/timestamps and migratedFrom provenance, and documents OAuth write scope, MCP-only availability, and the 1-compute-token cost. destructiveHint/openWorldHint give almost no detail on their own, so the description carries the load well.
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?
One dense paragraph, front-loaded with purpose followed by preconditions, then write semantics, idempotency, partial failure, auth and cost. Every sentence conveys distinct information, though the packing is heavy enough that a reader must hold several clauses at once.
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 still covers return-relevant behavior: attribution to the caller, existing: true for reused links, migratedFrom provenance edges, and what a partially completed call reports. Auth, availability and cost are all stated, so nothing needed to invoke 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 the baseline is 3, but the description adds real meaning beyond the schema field text: the 1–25 bound's source, that edges must touch model, be offered, and satisfy sim_link plus the predicate's write rule for the caller, and that successor is validated against the currently returned successor (a re-point or extended chain is refused rather than followed).
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 — carry a superseded model's offered taxonomic edges forward to its current successor — and names the exact upstream source (sim_migration_offers(model)) and the successor argument that selects the target. An agent can distinguish this from sim_link (creating new edges) and sim_supersede_model (creating the successor) without opening any 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?
Makes the trigger clear: edges must be ones sim_migration_offers(model) offered, and successor must be the current one it returned, otherwise the call is refused. It also points to sim_edges and sim_query for verifying the result. It stops short of explicitly naming an alternative tool for the case where you want a different migration shape, so it is clear context rather than full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_bindADestructiveInspect
Record a checked connection between two stored models' declared ports, fromModel's fromPort (a place tagged port.output) feeding toModel's toPort (a transition tagged port.input), as a content-addressed Binding (ROADMAP.md Phase 9/11f). Checked now, by the same binds-port-v1 rule sim_run_pipeline applies: both ports exist with the right direction and element kind, the output is a token place, the input is not a delayed transition, the declared kinds are equal, port.unit agrees exactly where both ends declare one (a unit missing on either end is reported unchecked, never agreed), and a numeric transform is at most 1000000. Differing units bind only with a declared conversion, never inferred from the unit names ("order" and "orders" are two units): pass convertFrom, convertTo and convertFactor together (1 convertFrom = convertFactor convertTo), checked by binds-port-v2 — both ports declare port.unit, the two differ, convertFrom and convertTo are exactly those units, the factor is between 1e-06 and 1000000, and the transform times the factor is at most 1000000; sim_run_pipeline multiplies the resampled rate by the transform and then by the factor. A binding without a conversion is checked by binds-port-v1 exactly as before and keeps its id. A delay (hours, in (0, 10000]) is checked by binds-port-v3 (v2 plus check 12: a finite number in range; 0 is no delay and keeps the binding's id): the target receives the source's flow that many hours later and runs on its own declared rate before then, and a loop between models runs only through a binding that declares one. A self-binding is refused, with or without a delay: a model driving its own input is a loop inside one net, built with sim_extend. Set-level checks (a loop with no delayed binding, two bindings into one input, the schedule-segment cap, a loop over 4 models) belong to sim_run_pipeline and sim_create_system; a binding that closes a loop with bindings already stored is not refused here, since a loop exists only in a set someone runs or defines. A refusal stores nothing. It records binding→fromModel "from", binding→toModel "to" and fromModel→toModel "feeds"; storing the same binding twice returns the same id. A recorded binding passes every run's per-binding check; a run still applies the set-level checks to the set it is given and can stop on what only the run decides (a resampled rate that overflows at a very short horizon, the step budget, the deadline). Costs 1 compute token (it stores a Binding).
| Name | Required | Description | Default |
|---|---|---|---|
| delay | No | hours after the source's flow that toPort receives it, in (0, 10000]; default unset, no delay. Before the delay ends toPort runs on its own declared rate. A loop between models runs only through a binding with a delay (binds-port-v3) | |
| toPort | Yes | element id of the declared input port on toModel: a rated transition tagged port.input | |
| toModel | Yes | id of the model receiving the connection | |
| fromPort | Yes | element id of the declared output port on fromModel: a token place tagged port.output (see GET /api/models/{id}/ports) | |
| convertTo | No | a declared unit conversion's target unit: exactly toPort's port.unit, which must differ from fromPort's | |
| fromModel | Yes | id of the model supplying the connection's output | |
| transform | No | how fromPort's value becomes toPort's. A plain non-negative number is applied by sim_run_pipeline as a scale factor on the resampled rate; it scales, never converts a unit. Any other text (a unit note, a resample window, an aggregation) is recorded, reported by sim_run_pipeline as an assumption, and treated as 1:1 | |
| convertFrom | No | a declared unit conversion's source unit: exactly fromPort's port.unit. Pass convertFrom, convertTo and convertFactor together or none of them | |
| convertFactor | No | how many convertTo one convertFrom is (1 convertFrom = convertFactor convertTo), between 1e-06 and 1000000; sim_run_pipeline multiplies the resampled rate by it, after any numeric transform |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without relying on the schema, it discloses cost (1 compute token), refusal semantics ('a refusal stores nothing'), and exactly what edges get stored (binding->fromModel 'from', etc.). It broadly matches the annotations (destructive, not read-only), but 'storing the same binding twice returns the same id' reads as de-facto idempotent while the annotation sets idempotentHint=false, a mild tension rather than a flat contradiction.
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 body is a very dense wall of parenthetical validation clauses, several of which duplicate parameter-schema text (conversion triples, transform semantics, delay range). Much of the volume does not earn its place against the 100%-covered schema.
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 9-parameter mutation tool with no output schema, the description is thorough: validation rules, conversion requirements, delay behavior, what is returned (same id on re-store), refusal behavior, and cost are all covered, so an agent has enough to invoke it 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?
With schema description coverage at 100%, the schema already documents all nine parameters in detail (delay, transform, convertFactor, etc.). The description largely restates those same rules for unit conversions, transform scaling and delay, adding little syntax or meaning beyond the structured fields.
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 records a checked connection between two models' declared ports as a content-addressed Binding. It also distinguishes scope from siblings by assigning set-level checks to sim_run_pipeline and sim_create_system, and self-loops to sim_extend.
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 routes several boundary cases explicitly (set-level checks belong to sim_run_pipeline/sim_create_system; a self-binding is refused and loops inside one net are built with sim_extend), and explains when a refusal occurs. However, it never addresses the obvious alternative sim_link or states a plain 'use this when' condition for the primary record-a-connection case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_calibrateADestructiveInspect
Calibrate a model against YOUR event log — the reading that meets reality. Upload CSV (case_id, activity, timestamp; the shape sim_dataset emits, activities = transition ids), and rates are learned from the observed timings: sources from inter-arrival times, services from the gap before their completions, all per hour. Instant-pickup transitions (declared rate >= 100) keep their declared rate — their observed gap is the queue wait, and learning it would destroy the calibration discipline. A transition declaring a delay (a fixed-duration timer, not a rate) is fit differently and returned in learnedDelays instead of learnedRates: the MEDIAN observed gap, in hours, written onto the transition itself since a delay has no solver-map slot — a gapCV in rateEvidence far from 0 means the log looks exponential, not fixed, and the calibration says so in a caveat rather than trusting the median anyway. Returns a NEW content-addressed model (learned rates in the solver map, learned delays on the transitions, declared values otherwise untouched, lineage recorded) plus a conformance report: fittingPercent (full replays) is the headline, worst traces named with the activities that could not fire. tokenFitness is a second, harsher reading of the same replay (raw tokens present vs. required at every step, not full-trace success) that under-reads any net with a resource pool — read fittingPercent, not tokenFitness, unless you specifically want the raw-token number. Every learned rate or delay has an entry in rateEvidence: n (gaps it rests on), gapCV (sample std dev over mean of those gaps; ~1 for exponential timings, near 0 for a true timer) and insufficient when n < 2 — n=0 yields nothing, n=1 a value with no spread. Learned values on a structure that cannot replay the traces would be numerology — read fittingPercent before trusting them. Costs 3 tokens from your account's compute bucket (a replay of the log, 2, and the stored model, 1).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id to calibrate | |
| log | Yes | the event log, as CSV text |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations covering safety profile, the description goes far beyond them: it discloses the cost (3 tokens split 2 for replay + 1 for stored model), the exact shape of the returned evidence (rateEvidence with n, gapCV, insufficient flags), edge behavior at n=0 and n=1, the caveat emitted when gapCV suggests non-exponential timings, and why instant-pickup transitions are excluded. This is unusually rich operational disclosure for a mutation tool.
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 and cost are front-loaded, but the body is one dense paragraph that packs in evidence-field semantics, edge cases, and caveat mechanics without structural breaks. All of it is relevant, but the sheer length makes it harder to scan than a shorter, sectioned statement would be.
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?
There is no output schema, so the description carries the full burden of explaining return values, and it does: the new model, the learned rates/delays placement, lineage, and the conformance report fields (fittingPercent, worst traces, tokenFitness, rateEvidence). Nothing an agent needs to interpret results 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 the baseline is 3, but the description adds real semantics the schema lacks: the log parameter must be CSV text with columns case_id, activity, timestamp, activities are transition ids, and the id names the model to calibrate. The CSV column contract is essential invocation knowledge not present in the schema.
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+resource (calibrate a model against an event log) plus the exact artifact consumed (CSV with case_id, activity, timestamp as emitted by sim_dataset). It distinguishes itself from siblings by tying its output to a NEW content-addressed model plus a conformance report, so an agent can separate it from sim_conformance or sim_create_model.
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?
Gives clear context for invocation (upload a log of the sim_dataset shape) and a conditional routing cue ('read fittingPercent, not tokenFitness, unless you specifically want the raw-token number'), plus the precondition that fittingPercent should be checked before trusting learned values. It never names a concrete alternative tool for the no-learning case, so it stops 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.
sim_canonicalADestructiveInspect
Tell whether two differently-labelled models are actually the same net: an isomorphism-invariant id computed from the model's EXACT automorphism orbits (orbits.go), not the colour-refinement (WL) kind sim_classify falls back to when the exact search can't decide. Two models differing only by renaming places or transitions share the same canonicalId even though their content-addressed ids (from sim_get_model) differ — this is the id to compare, not the model id, when checking whether a catalog already holds this net. Also returns the non-trivial automorphism orbits and generator count the id was computed from: zero generators means the net is rigid (no symmetry at all), which is itself a fact about the net's structure. Refuses (as a tool error) when the exact search would spend more than its 1,000,000-step budget (refinement steps, about half a second) — too large or too symmetric for this implementation, per orbits.go — rather than silently falling back to a weaker answer; sim_classify's own fallback covers that case for classification specifically. Costs 1 compute token (one search), as GET /api/models/{id}/canonical does. Equal canonical ids mean the same net under the comparison sim_prove uses for isomorphicTo; to get the place/transition bijection and record it as a witnessed edge, call sim_prove(subject, "isomorphicTo", object).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Extraordinarily rich disclosure beyond the annotations: the 1,000,000-step budget, refusal-as-tool-error instead of silent fallback, cost of 1 compute token, and the meaning of the returned orbits/generator count (zero generators = rigid). The only gap is that it never reconciles the purely computational GET semantics it describes with the sibling annotations declaring destructiveHint=true and readOnlyHint=false, leaving the agent to guess whether hidden mutation occurs.
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 core definition in the first clause, and nearly every sentence carries new information (orbits, budget, cost, witness path). It is dense and somewhat long-winded, with mild repetition around 'this is the id to compare, not the model id', but no filler sentences.
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 takes on the burden of explaining returns and does so: the canonicalId, the non-trivial automorphism orbits, and the generator count, plus the error condition. An agent has everything needed to call it and interpret the result.
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 real meaning by clarifying which identifier this is (a model id, explicitly not the content-addressed id and not the canonical id to compare against), which resolves a genuine ambiguity in the single 'id' parameter.
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 precise verb+resource: it computes an isomorphism-invariant canonical id from exact automorphism orbits. It explicitly distinguishes itself from the colour-refinement (WL) approach of sim_classify and from content-addressed ids returned by sim_get_model, so an agent can tell it apart from siblings without opening schemas.
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?
Gives explicit routing: 'this is the id to compare, not the model id, when checking whether a catalog already holds this net', names sim_classify's fallback as the alternative for classification, and points to sim_prove for the actual bijection/witness. When-to-use and when-to-use-something-else are both covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_check_witnessDestructiveInspect
Re-check a stored structural witness against both stored models with the independent checker (pkg/morphism), which does no search. Given a structural edge's id, checks every witness of that edge; an edge with none answers unwitnessed (unproven, not disproved). Verdicts: valid, invalid (the map is not a morphism of the stored models), or uncheckable (a model was deleted, a net is malformed, or the predicate is now checked under a newer definition). Public: no sign-in. A witness or edge id is free (no compute tokens). With derivation (from sim_query): re-checks every step's witness, the chain, the composed map's digest and the composed map against both end models, and answers {verdict, reason, hops} (the body POST /api/derivation/check returns); a derivation naming a definition other than the predicate's current one is uncheckable; costs 1 compute token. With reach (a sim_reach answer): replays a trace through metamodel.Enabled/Fire and the guards, or re-checks an invariant witness against the stored model, answering {verdict, reason}; from and to are held to the scenario caps (1,000,000 per place, 4,000,000 in total), and a replay is priced before its first firing and is uncheckable over 200,000,000 work units; an exhaustive no is uncheckable (re-run sim_reach); an unknown answer is refused; costs 1 compute token (POST /api/reach/check). With reach on a system's answer, via is re-checked whole with it: the system is stored and holds the net, every other model has exactly one embedding, each embedding's witness or derivation re-checks valid now, and any translation of component places follows them. With reachResult (the result id sim_reach returns): re-checks a stored answer end to end — the record (its bytes hash to its id, its stored question asks what the answer answers under the budgets it records, and over names what it rests on), via as above, and the witness — answering {verdict, reason, parts, answer, currency}; an unknown answer stays unknown (its witness part is uncheckable, never a no); currency says whether this server would compute the same result (definition, budgets, registry, view, every model still stored) and lists superseded models without flipping current; costs 1 compute token (POST /api/reach/check with {"result": …}, or GET /api/lineage/). With refutation (a refuted sim_prove answer's refutation, ROADMAP.md Phase 12i): re-checks its counterexample against both stored models with pkg/morphism — a refines trace replayed through the shared firing rule on both nets, or for preservesInvariant each embedding re-checked as an induced embedding, its invariant re-checked as a P-invariant of the object (y·C = 0 for every transition) and its pullback shown to break at the subject transition named (that the list holds every embedding is the search's claim and is not re-checked) — answering {verdict, reason}; costs 1 compute token (POST /api/refutation/check). A preservesInvariant or refines witness id re-checks its cover or simulation relation the same way (free, bounded: at most 4,096 cover terms, or 4,096 pairs and 20,000,000 firing-rule units). Give exactly one of id, derivation, reach, reachResult or refutation. Writes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | a witness id, or a structural edge's relation id | |
| reach | No | a sim_reach answer, the object exactly as returned (or that object serialized as a string) | |
| derivation | No | a sim_query derivation (JSON, as an object or a string holding one): {"predicate", "definition", "subject", "object", "steps": [{"edge", "witness", "inverse"}], "composed"} | |
| refutation | No | a refuted sim_prove answer's refutation, the object exactly as returned (or that object serialized as a string): {"predicate", "subject", "object", "counterexample"} | |
| reachResult | No | the content id of a stored sim_reach answer (sim_reach's result) |
sim_classifyADestructiveInspect
Discover the parameter classes of a stored model and return them as JSON-LD with empty annotation slots for you to fill in (label, comment, unit, domain, substitutes — nothing else; membership/kind/evidence are derived and settled by measurement, not yours to edit). With verify=true a shared colour is checked by exact automorphism proof where the search can decide it (settling interchangeability outright, the stronger claim), falling back to the sampled permutation experiment only where it can't — the exact search refuses past its 1,000,000 refinement-step budget on nets too large or too symmetric for it. Read the sim://docs/classification resource once for the colour-refinement caveat and the annotation contract in full.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| verify | No | run the permutation experiment (costs simulation; default false, and classes then say they are candidates) | |
| inline_context | No | embed the full JSON-LD @context map in the result instead of the URL it is served from (https://sim.pflow.xyz/ns/v1/context). Default false: the URL resolves to the identical map, so only set this for an offline consumer that cannot fetch it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations: it discloses that verify costs simulation, that the exact search refuses past a 1,000,000 refinement-step budget on large/symmetric nets, and that it falls back to a sampled permutation experiment. The one gap is that destructiveHint=true is never explained — nothing says what is mutated or destroyed (presumably the annotation slots), so the safety profile is left to the 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?
Front-loaded with the core action and return shape, and every clause carries information (annotation slot scope, verify behavior, budget, caveat pointer). It is dense and parenthetical-heavy, which slows parsing slightly, but there is little outright 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 tool with no output schema and three parameters, the description covers what is returned (JSON-LD with empty annotation slots), the mutation contract ('nothing else'), and where to find the full colour-refinement caveat and annotation contract. It is nearly complete; only the destructiveHint implication is left implicit.
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 genuinely enriches verify beyond the schema by explaining the exact-proof vs sampled-experiment distinction and the budget cutoff. inline_context and id merely restate what the schema already documents in detail.
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+resource: 'Discover the parameter classes of a stored model and return them as JSON-LD with empty annotation slots.' It also clarifies what the tool does NOT do ('membership/kind/evidence are derived and settled by measurement, not yours to edit'). It never names a sibling tool to differentiate itself, so it stops short of 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?
It gives conditional guidance for verify=true (exact proof where the search can decide, sampled experiment as fallback) and points to a resource for the annotation contract. However, it never states when to use this tool versus siblings like sim_propose_types or sim_param_heatmap, and offers no exclusions. Usage is implied rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_code_to_flowDestructiveInspect
Derive a Petri-net model from source code with the configured LLM (control-flow, state-machine, resources or concurrency focus) and store it as a NEW model you own when it passes sim_create_model's decode and the model validator. Stored, it returns stored: true with id, url, name, usage and warnings (what sim_create_model would warn about the model, omitted when there is nothing to say). Otherwise nothing is stored, and it returns stored: false with the LLM's model JSON as model, usage, and either error — one string: the decode failure ("response is not a model: ...") or the unknown-field refusal worded as sim_create_model words it, each misspelt key by path with the key it most likely meant and the structural reasons after them — or errors, the validator's list (each with code, message and fix); fix the JSON and store it with sim_create_model. A reply with no JSON object in it, or a model the store's own validation still refuses, is a tool error naming why. Runs generator.CodeToFlow directly; this tool is its only surface on sim.pflow.xyz, which mounts no code-to-flow HTTP endpoint. Needs sign-in; refused when this deployment has no LLM provider configured.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | source code to analyse | |
| name | No | name for the derived model; the LLM is asked to use it, and it is filled in, before any check, when the model comes back without one | |
| focus | No | control-flow (default), state-machine, resources or concurrency | |
| language | No | source language hint, e.g. go, python, javascript |
sim_compareDestructiveInspect
Run several scenarios against one model on one shared seed and return them side by side — the seed sharing is server-enforced, so differences are the scenarios, not the dice. Returns a summary by default (finals with finalStdDev, each final count's spread across realizations, throughput/mean/P95 metrics, depletion and contention — no time series); pass full=true for the complete trajectories, which run to hundreds of KB. A scenario carrying "summary": true stays summarized even under full=true, so one comparison can chart some scenarios and only read the rest. Unset hours default to 8, samples to 60 (the trajectory grid, which only matters under full=true — metrics are time-weighted and do not depend on it) and realizations to 16 per scenario. Each scenario can set its own "engine" (see sim_scenario / docs/engine-selection.md); comparing an "ode" run against an "ssa" one is legitimate but the shared seed only removes dice from scenarios using the same engine. Costs 1 token per scenario from the compute bucket (per address, or per account when signed in). Each result's contention is split exactly as sim_scenario's is: contended holds only what the run was short of (kind conserved or bounded), waitingForWork the entries of kind queue (the work had not arrived) or state (the model was in another phase of its cycle), neither of them a shortage, and neverFired one note per place that never held a token in any run while its transitions never fired; sim_scenario's description lists what the run cannot tell apart behind such a note.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| full | No | include the sample-grid time series in every result (large; default false); a scenario with its own "summary": true is left summarized regardless | |
| scenarios | Yes | JSON array of at most 20 scenarios, each with a name, e.g. [{"name":"today","hours":8},{"name":"one more","hours":8,"marking":{"staff/available":3}},{"name":"bigger batches","hours":8,"params":{"batch_size":6}}]; each is held to sim_scenario's caps |
sim_componentsADestructiveInspect
List the component registry: pre-baked subnet templates (arrivals, service, hazard, inventory, decision, mailbox, datastore) with the calibration discipline baked into the arcs and rates. Each entry names its ports (places you can attach onto existing places), its params with recommended defaults, and the discipline notes explaining WHY the template is shaped the way it is. Compose them with sim_compose.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description says 'List the component registry' which clearly implies a read-only operation, but the annotations declare destructiveHint: true. This is a direct contradiction – the description does not disclose any destructive behavior and instead suggests a non-mutating action. No additional behavioral context is provided beyond this contradiction.
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 two sentences long and packs relevant information: the resource being listed, the types of templates, the content of each entry, and a pointer to the next step. It is slightly verbose with the parenthetical list of template types, but this is informative and aids clarity.
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?
The description explains the output format (ports, params, discipline notes) and how to proceed after listing (compose with sim_compose). It is complete for a listing tool with no parameters and no output schema. However, the contradiction with the destructiveHint annotation introduces confusion about whether the tool has side effects, which detracts from completeness.
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 coverage is 100% (since no params exist). The description adds value by explaining what the registry entries contain (ports, params, discipline notes), which helps the agent understand the output structure. Since there are no parameters to document, the description correctly avoids parameter details.
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 clearly states the tool's purpose: 'List the component registry' with a specific verb and resource. It enumerates the template types and explains what each entry contains, making it easy to distinguish from other sim_* tools. The mention of sim_compose further differentiates it as a discovery tool rather than a composition tool.
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 provides a clear usage hint by stating 'Compose them with sim_compose', indicating the typical workflow of listing then composing. It does not explicitly list when not to use this tool, but the context strongly implies it is for browsing available templates before composition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_composeADestructiveInspect
Instantiate a registry component into a model and store the result as a NEW content-addressed model you own (lineage recorded when composing onto an existing id). Omit id to start a model from the component alone; pass attach to fuse a component port onto one of the model's existing places (e.g. attach {"queue": "tickets_queue"} wires a hazard onto the service's queue). Prefix namespaces the created elements (defaults to the component name). Three calls build a working helpdesk: arrivals, then service attached to its queue, then hazard attached to the same queue — the result passes diagnose because the discipline is in the template.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | model to compose onto; omit to start fresh | |
| name | No | model name for the stored result (kept from the base when composing onto an id) | |
| attach | No | JSON object mapping port name -> existing place id | |
| params | No | JSON object overriding param defaults, e.g. {"staff": 3} | |
| prefix | No | instance prefix for created elements (default: component name) | |
| component | Yes | registry component name (see sim_components) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already indicating destructiveHint and openWorldHint, the description adds valuable context: the result is a new content-addressed model 'you own', lineage is recorded when composing onto an existing id, and attach fuses ports. It does not contradict annotations and expands on the operational behavior.
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?
Three sentences, each packed with useful information: core action, key parameter semantics, and a worked example. No fluff, front-loaded with the main purpose, and the example at the end reinforces usage without bloating.
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 the complexity (6 params, no output schema), the description covers main usage patterns, attach mechanics, prefixes, and an example. It does not state the return value or error conditions, but the annotations and parameter schemas fill much of the gap, making this sufficiently complete.
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%, but the description adds operational semantics beyond the schema: 'omit id to start fresh', 'name kept from the base', attach maps port names to existing place ids, and prefix defaults to the component name. This meaningfully clarifies how parameters interact in the composition workflow.
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 states a specific verb (instantiate/compose) and resource (registry component into a model), and clarifies it stores a NEW content-addressed model with lineage. It distinguishes itself from siblings like sim_create_model or sim_extend by emphasizing 'registry component' and 'compose onto an existing id'.
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 provides clear when-to-use guidance: omit id to start fresh, pass attach to fuse a component port onto existing places, and uses a concrete three-call helpdesk example. It does not explicitly name alternative sibling tools or exclusions, but the context is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_conformanceDestructiveInspect
Check how well a stored model matches an observed event log WITHOUT rewriting its rates — the read sim_calibrate bundles into calibration, offered on its own and in full: fitness (can the model replay each case?), precision (does it allow behaviour never observed?), generalization and simplicity, with per-trace diagnostics naming the activities that could not fire. Also returns a residual block: the same replay read as a trajectory — at which position along the cases (and for which activity) the model first lacks the tokens the log shows, how many tokens short, and a summary that says where fidelity holds and where it breaks. Log is CSV (case_id, activity, timestamp; the shape sim_dataset emits, activities = transition ids). The log is replayed one case at a time from the model's initial marking, so the model should be the per-case workflow; a resource net whose places are shared across cases will not fit. Caveats name what the analysable net encoded lossily. Costs 2 tokens from your account's compute bucket.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| log | Yes | the event log, as CSV text |
sim_conformance_streamDestructiveInspect
Online conformance: replay an ORDERED event stream against a stored model and get a running verdict — does the model still match, or which event was the first that did not, and why. Unlike sim_conformance (whole finished cases, aggregate fitness) the order of events IS the stream's order, cases may interleave, and the answer names the first non-conforming event: its position, case, activity, whether the activity is unknown to the model or the transition was not enabled, the places that blocked it (need vs have), the case's marking just before it, and repair — the shortest unobserved transitions that would have enabled it (a local alignment of that one step, bounded; absent when none is found within repairDepth). This is token replay, not trace alignment. A divergent event is force-fired so the case resynchronises and later events are judged on their own. fitness is conforming events / events; tokenFitness is 1 - missing/consumed tokens. Give the stream as events (JSON array of {case, activity, timestamp?}) or log (CSV with a case_id, activity header, timestamp optional; rows are taken in the order given, not sorted). Activities are transition ids. Each case replays from the model's initial marking, so the model should be the per-case workflow; guard expressions are not evaluated and timestamps are not checked against delays (caveats says so). keepSteps adds the per-event running signal. Costs 2 tokens from your account's compute bucket.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| log | No | the stream as CSV text (case_id, activity[, timestamp]) in stream order; used when events is not given | |
| events | No | JSON array of {"case": ..., "activity": ..., "timestamp": ...} in stream order | |
| keepSteps | No | include the per-event running fitness (one entry per event) | |
| repairDepth | No | most unobserved transitions a repair may use (default 4, at most 64; negative turns repair off) |
sim_create_collectionADestructiveInspect
Mint a named Collection you own and return its content id. A collection carries no member list of its own — a mutable list would change the collection's own id every time something joined it, the same reason Lineage lives beside a model rather than inside it. Add members with sim_link(collectionID, "hasMember", memberID) — members must be stored entities — and read them back with sim_neighbors(collectionID, "hasMember") or sim_edges(collectionID). Only you, the owner, may add members: hasMember's write rule is subject-owner (https://sim.pflow.xyz/ns/predicates/v1), so sim_link refuses anyone else, naming the rule. The name and your account together are the content id: creating a collection with a name you already used returns your existing id, and another account's collection with the same name is a different collection. A collection created before collections had owners has none, so its membership is frozen as it stands (still readable); create your own to add to. Members cannot be removed: an edge, once written, is immutable. Needs sign-in with write scope (opens OAuth the first time); costs 1 compute token.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | collection name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses that sign-in with write scope is required (OAuth opens on first use), that it costs 1 compute token, that only the owner may add members because hasMember's write rule is subject-owner, that edges are immutable and members cannot be removed, and that name+account deterministically form the content id. Minor tension with idempotentHint=false (same name returns the existing id), but the description reads as the more specific statement of identity semantics rather than an inversion of the annotation.
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 core action and its return value, and most sentences carry operational facts (auth, cost, write rule, immutability). Slightly overwritten for a one-parameter tool — the 'Lineage lives beside a model' analogy is a digression that does not help invocation.
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 supplies the return value (content id) plus auth, cost, ownership enforcement, immutability and legacy-collection edge cases. An agent has everything needed to call it correctly on the first attempt.
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% for the single 'name' parameter, so the baseline is 3. The description adds real meaning beyond the schema: name combined with account forms the content id, duplicate names return the existing id, and another account's identically-named collection is a distinct entity.
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?
Opening sentence states a specific verb+resource+outcome: 'Mint a named Collection you own and return its content id.' It is immediately distinguishable from siblings sim_link, sim_neighbors and sim_edges, which are named as the member-manipulation/read tools rather than the create tool.
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: add members via sim_link(collectionID, "hasMember", memberID), read them back via sim_neighbors or sim_edges, and create your own collection when you encounter a pre-ownership legacy collection whose membership is frozen. Alternatives and the conditions selecting them are spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_create_modelDestructiveInspect
Store a Petri-net model and return its content id and url, plus warnings (omitted when there are none) for a model that stores but probably does not say what was meant: transitions with no rate, which simulations run at the engine default of 1 per hour (each stage of a staged one, in a run without a schedule); a net in which nothing can fire at its declared initial marking; a guard no simulation enforces; an inhibitor arc drawn transition -> place; a pool (staff, machines) one transition takes and gives back in the same firing beside the work it serves, which is never busy, so its headcount multiplies that rate (or, through a "kinetic": false arc, changes nothing) instead of capping work in progress; a pool a transition only reads, through a read arc beside the work it takes, declared above the read arc's weight (staff at 2 read by serve beside queue), which is never taken and stays out of the rate, so every count above the weight runs exactly as the weight does (at the weight, such as an open sign at 1, it is a gate and draws no warning). At most 10 of each per-element warning are listed, the rest counted. The model is JSON with name, places, transitions and arcs; rates are per hour. Read resource sim://docs/authoring once for a worked example and the fields a simulation reads. Refused, with every reason at once: a key the schema does not define, named by its path with the key it most likely meant (unknown field places[0].intial (did you mean "initial"?)) or, when none is close, to be removed, a key repeated across elements written once (arcs[0..6].source); a value of the wrong kind, by its path and the kind wanted (the first one only, and the structure is checked once every value has the right kind); and otherwise every structural defect, leaving out the ones a misspelt key caused. At most 20 of each are listed, the rest counted. Models are immutable; a changed model is a new id. Costs 1 compute token (the account's bucket when signed in, the client address's otherwise); the model JSON is at most 262144 bytes.
Signed in with write scope, the model is yours (mine: true): it appears only in your own listing until you dedicate it to the commons with sim_license_model, and you can remove it with sim_delete_model. An identical model stored before this call keeps the envelope it has, so the reply is then mine: false with a note saying whose it is: another account's, the catalog's, or nobody's (created without sign-in). Without sign-in it is stored unowned, for good (mine: false, and a note saying so): reachable by id, listed for nobody, and nobody can delete, license or supersede it — creating the identical model signed in later returns the same id, still unowned. To own a model, sign in before creating it; a changed model (a new name is enough) is a new id. A call whose token has expired or lacks write scope is asked to sign in, not stored unowned. Anyone you give the id to can use the model either way.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | the model JSON: name, places, transitions, arcs (sim://docs/authoring has the fields and a worked example) |
sim_create_systemADestructiveInspect
Define a System (ROADMAP.md Phase 11f): a content-addressed, stored set of models and the bindings between them, so the catalog can answer questions about them together. Pass collection (snapshot its model and binding members now; other members are listed under skipped, and a grown collection is a new system, the old id still readable) or models and bindings (JSON arrays of ids), not both. Every binding's endpoints join the models (listed under implied); every binding must pass the check sim_bind applies now (binds-port-v1, or binds-port-v2 for one that declares a unit conversion, or binds-port-v3 for one that declares a delay, and the system then records bindingCheck binds-port-v2 or binds-port-v3, v3 first; a legacy binding sim_bind would refuse today is refused here) and the set must close no loop without a delayed binding, take each input port once, fit the schedule-segment cap and hold no loop over the model limit — the checks sim_run_pipeline applies before it knows the hours. At most 64 models and 64 bindings, and a snapshotted collection of at most 256 members. The id is the hash of the sorted lists, the name and the snapshotted collection (if any), so the same call gives the same id; a snapshot and an explicit list of the same ids are different systems. Returns the id and the view sim_system computes (checks, the structural edges among the models with up to 128 witnesses re-checked now, and the shape: one-net, pipeline, separate or unknown). This is not refines: a system's edges are isomorphicTo and subnetOf (embeds by wiring / is the same coloured net). refines (trace inclusion with transitions matched by id) and preservesInvariant (the object's P-invariants pull back along an embedding) are proved one pair at a time by sim_prove and are never walked by closure, since neither is declared transitive. For "what contains this pattern?" ask sim_query with closure: {"select":["?m"],"where":[{"subject":"","predicate":"subnetOf","object":"?m","mode":"closure"}]} (isomorphicTo for copies; add {"subject":"","predicate":"hasMember","object":"?m"} to scope it), each row carrying a derivation sim_check_witness re-checks; a subnetOf row claims no behaviour inclusion. For "what does this model refine?" ask sim_query for one hop: {"select":["?m"],"where":[{"subject":"","predicate":"refines","object":"?m"}]}, each row an edge sim_prove recorded. A loop between models runs only through a binding that declares a delay (sim_bind delay; ROADMAP.md Phase 12j): a system may hold one, of at most 4 models, and its view lists it under pipeline.loops with pipeline.maxHours, the longest horizon sim_run_pipeline runs it at (0 when no horizon of 0.01 h or more does; pipeline.runnable covers only the checks that do not depend on the hours), where it is solved as an exact fixed point over the horizon (pipeline-loop-v1). A loop with no delayed binding is refused when a system is defined and by sim_run_pipeline, and sim_bind refuses a self-binding. A port search with among a system (bindable-v3) lists a candidate that closes a loop already holding a delayed binding, with that loop's models under closesLoop, and counts one that would close a loop of undelayed bindings under excluded as closes-loop (sim_bind with a delay can close it); a catalog or collection search does not consult stored bindings, so sim_create_system or sim_run_pipeline is where such a loop is refused. Needs sign-in (opens OAuth the first time); costs 2 compute tokens; writes one System.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | a name for the system (at most 256 bytes); part of its id | |
| models | No | JSON array of model ids, e.g. ["id1","id2"] | |
| bindings | No | JSON array of binding ids sim_bind returned; their models are included automatically | |
| collection | No | a collection id whose model and binding members to snapshot (instead of models/bindings); at most 256 members; part of the id |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=false, destructive=true, idempotent=false, and openWorld=true, but the description adds substantial context: it writes one System, needs sign-in with OAuth the first time, costs 2 compute tokens, snapshots collections, enforces caps, applies binding checks, and explains determinism of the id. These are meaningful behavioral traits beyond the annotation layer.
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 nested clauses and tangential query examples that are not necessary for selecting or invoking sim_create_system. While the opening sentence is front-loaded, the remainder reads as an unstructured wall of constraints and sibling behavior rather than a concise tool definition.
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 creation tool with four parameters, no output schema, and rich annotations, the description is complete enough to call correctly: it covers inputs, mutual exclusivity, id determinism, stored checks, loop constraints, auth, cost, and what is returned. No critical invocation detail 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%, so the baseline would be 3, but the description adds important semantics not in the schema: collection and models/bindings are mutually exclusive, collection snapshots members and affects the id, explicit lists and snapshots of the same ids are different systems, and size limits apply. It stops short of fully documenting every edge case in the parameter 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?
The description states a specific verb and resource: it defines a System as a content-addressed, stored set of models and bindings so the catalog can answer questions about them together. It also distinguishes the tool from closely related siblings such as sim_refine, sim_prove, sim_query, sim_bind, and sim_run_pipeline, so an agent can tell what this tool is for without opening another 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?
It gives explicit when/when-not guidance: pass either collection or models and bindings, not both. It also names alternatives for related questions (use sim_query for containment or refinement queries; use sim_prove for pair proofs) and clarifies where loop refusal happens versus where it is not consulted, leaving little ambiguity about routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_crosscheckBDestructiveInspect
Run every applicable READING of a model against the others and report agreement or divergence with the reason: discrete SSA means vs the continuous mean-field solve, algebraically derived conservation laws vs simulated means, and (for game-schema models) the closed-form incidence ranking vs rollouts vs exact search. Divergence is a finding, not an error — small-count mean-field gaps and the prior's threat-blindness are named as such. Trust is agreement between independent readings of one structure. Gated nets (read arc, inhibitor, reached capacity, guard) have no ODE reading to compare against at all — see docs/engine-selection.md for the four-rule decision behind which readings even apply.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| hours | No | horizon (default 8, max 168) | |
| realizations | No | SSA runs averaged, max 200 (default 24) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds real behavioral context beyond the annotations: divergence is framed as a finding rather than an error, mean-field gaps and threat-blindness are named, and the gated-net exception is disclosed. It does not, however, reconcile or explain the heavy side of the annotation profile (destructiveHint=true, openWorldHint=true, non-idempotent) for what reads as an analytical report tool, and says nothing about the compute cost of the SSA realizations it runs.
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 clause, and every subsequent sentence carries distinct information (the enumerated readings, the divergence policy, the gated-net exclusion, the docs pointer). The dense em-dash parentheticals make it heavier than necessary but not wasteful.
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 partially compensates by naming what is reported (agreement or divergence plus reason), which is valuable. It still leaves the agent without an idea of response shape, runtime, or why a cross-check tool carries destructive/open-world hints, leaving gaps for a tool with three parameters and non-read-only annotations.
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 all three parameters (id, hours, realizations) carry descriptions with defaults and maxima, so the schema does the heavy lifting. The description adds no parameter-level meaning, such as how hours interacts with the comparison or what realizations imply for result stability, making the baseline 3 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: runs every applicable 'reading' of a model against the others and reports agreement or divergence, enumerating the concrete comparisons (discrete SSA vs mean-field, conservation laws vs simulated means, incidence ranking vs rollouts vs search). This is a distinct capability an agent can separate from sim_verify or sim_conformance, though it never explicitly names a sibling to route against.
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 through the applicability rules: gated nets have no ODE reading, and readers are pointed at docs/engine-selection.md for the four-rule decision. However, there is no explicit 'use this instead of X when Y' statement, nor a clear precondition beyond an id.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_datasetADestructiveInspect
Generate a synthetic event log from a stored model (seeded SSA playout; case-per-arrival). Returns CSV. Deterministic: same id, same seed, same bytes.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| seed | No | PRNG seed (default 1) | |
| cases | No | cases to generate (default 200, max 2000 over MCP) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds useful behavioral traits beyond annotations: determinism ('same id, same seed, same bytes') and the return format ('Returns CSV'). Annotations already indicate readOnlyHint false and destructiveHint true, but the description does not explain the nature of the destructive side effect. It provides some added context but leaves side-effect clarity to 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 is two short sentences that front-load the core purpose and then give determinism and output format. Every sentence contributes new information with no redundancy, making it appropriately sized for a tool with only three parameters.
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?
The description covers what the tool generates, its source, output format, and determinism, which is adequate for a simple tool with fully documented parameters. However, with no output schema, the CSV structure and columns are not described, and the destructiveHint true is not elaborated in the description. An explicit note about side effects would make the definition more complete.
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 (id, seed, cases) are already documented in the input schema. The description reiterates the role of id and seed in determinism but does not add new semantic details for the cases parameter or the CSV content. Since the schema carries the parameter meaning, the description meets the baseline without substantial additional value.
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 states a specific verb ('Generate'), a resource ('synthetic event log from a stored model'), and a method ('seeded SSA playout; case-per-arrival'). This clearly distinguishes it from the many sim_* siblings by emphasizing deterministic synthetic data generation from a model. It also mentions the CSV output, making the tool's purpose unmistakable.
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 no when-to-use or when-not-to-use guidance, and it does not reference any alternative sibling tools such as sim_scenario or sim_run_pipeline. The purpose implies use for generating synthetic event logs, but an agent cannot determine prerequisites, exclusions, or when a different sim tool would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_delete_modelDestructiveInspect
Delete a model you created signed in. Refused for the curated catalog, for models you do not own (a model created without sign-in is nobody's, for good), and for models already dedicated to the commons (a dedication is irrevocable).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id to delete |
sim_diagnoseDestructiveInspect
Returns what one more of each resource (and a change in each rate) is worth to the outcome, each ranked against a measured noise floor — no fitness test to write. Also reports generic gates (mass balance, dormant sources, staffing knee and practical knee, whether any knob binds), parameter classes among the controls, and four structural readings needing no run (T-invariants, siphons/traps with deadlock witnesses, CTMC lumpability, constrained lumping); a lumping or siphon reading that does not apply is one "not applicable" line unless verbose. Pure read. Loss/success inference and objective framing can be corrected by tagging places or declaring simulation.objective — read the sim://docs/classification resource once for how to read influence, noise, the knee and structural readings.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| seed | No | seed shared by every run, so differences measure the knob and not the dice (default 7) | |
| hours | No | horizon per run (default 8, max 168) | |
| verbose | No | default false: a structural reading that does not apply (ctmcLumping, constrainedLumping, or siphons when its search did not finish) keeps applicable: false and one refusals line, "not applicable: <reason>", without its fixed scope text. true returns every refusal and scope in full. Changes no measurement and costs nothing extra. | |
| realizations | No | runs averaged per measurement, max 200. Leave unset and the default ADAPTS: a 24-realization pilot that doubles while the baseline outcome sits inside its own noise floor, up to 200 (or maxRealizations, if set); the report's realizations field and sample-size finding record where it settled and why. Set it and that exact count is used, never more. If the report still says underpowered after adapting, raise hours or set a count explicitly. | |
| inline_context | No | embed the full JSON-LD @context map in the result instead of the URL it is served from (https://sim.pflow.xyz/ns/v1/context). Default false: the URL resolves to the identical map, so only set this for an offline consumer that cannot fetch it. | |
| maxRealizations | No | bounds how far the adaptive default may escalate (default 200, the same ceiling an explicit realizations refuses above). Ignored once realizations is set. For a caller with its own latency budget, not for narrowing a report. |
sim_diffCDestructiveInspect
Structural difference between two stored models: places, transitions and arcs added or removed, and surviving elements whose numbers changed (initial, capacity, rate, stages, arc weight or kind). The readout for what a builder turn, a sim_extend or a sim_refine actually changed between two ids in a lineage.
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | model id (before) | |
| b | Yes | model id (after) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description says it produces a 'readout' (a non-mutating report), but the annotations include destructiveHint=true. This is a contradiction: a readout implies no destruction, and the description does not mention any destructive side effects. No additional behavioral context is added beyond 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 is two sentences that are packed with specifics, no filler, and the core concept (structural difference) is front-loaded. The second sentence adds context about when it's useful.
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 gives the categories of changes detected but does not describe the shape or format of the returned readout, nor does it address the destructive behavior indicated by annotations. For a diff tool, this leaves an agent uncertain about what response to expect and what side effects may occur.
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 schema provides full descriptions for both parameters (a: model id before; b: model id after), and the description adds the notion that these are ids in a lineage, which is a small semantic enhancement. But overall the schema already carries the meaning, so 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 description clearly states it computes a structural difference between two stored models, listing specific categories of changes (places, transitions, arcs, numeric attribute changes). It connects to the lineage context of builder turns, sim_extend, and sim_refine, which helps distinguish from those tools. However, it doesn't explicitly differentiate from sim_compare, so there is some ambiguity among siblings.
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 implies when to use it: when you need the readout of what a builder turn, sim_extend, or sim_refine changed between two ids in a lineage. But it doesn't provide explicit guidance on when not to use it or mention alternatives like sim_compare. The context is helpful but not prescriptive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_distillADestructiveInspect
Distill exact search into the play scorer: fit rate multipliers for named transition groups so play's rankings agree with exact minimax, on positions sampled by random self-play and labeled by search. This is TACTICAL calibration — the counterpart of sim_calibrate, which learns rates from an event log. The division of labor is deliberate (petri-pilot experiments/ode-minimax): structure carries the tactic, and no fitting of an unmodified net's rates can express what its final state cannot separate — declare the structural prior as transitions in the model (e.g. forced-reply copies of the plays, catalyzed by the opponent's pattern) and distill the magnitudes it introduced. Zero agreement improvement is a finding about the structure, not a failed fit. Read agreementBefore/agreementAfter, not the loss: the hinge loss can overstate failure while every argmax is right. At most 16 groups, each non-empty, and no transition in two groups; the estimated work (loss evaluations × candidate moves × realizations × horizon) must stay under a fixed cap, and an over-cap request is refused with the estimate. Costs 5 tokens from your account's compute bucket at the defaults, scaled by that work estimate (rounded up).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id (needs simulation.objective, players with turnPlace) | |
| groups | Yes | JSON object: group name -> transition ids sharing one fitted multiplier, e.g. {"detectors":["x_win_0","o_win_0"],"draw":["call_draw"]} | |
| options | No | JSON: {"games":20,"positions":40,"iters":40,"horizon":3,"realizations":40,"seed":11,"engine":""} (the defaults shown; 0 or unset takes the default). Caps: games at most 100, positions at most 100, iters at most 100, realizations at most 200, horizon at most 10000; over a cap, a negative value or an unknown key is refused |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare mutation (readOnlyHint=false, destructiveHint=true, idempotentHint=false, openWorldHint=true), so the safety bar is lower. The description nevertheless adds real behavioral context beyond them: the token cost (5 from the compute bucket, scaled and rounded up), refusal on over-cap requests with the estimate returned, and guidance to read agreementBefore/agreementAfter rather than loss. Minor gap: it doesn't say whether the fitted multipliers persist or are reversible.
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 and every sentence carries information, but the prose is dense and jargon-laden, mixing rationale and constraints into long clauses. It is longer than needed for a 3-parameter tool and could be tightened without losing content.
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-value burden and does it ('Read agreementBefore/agreementAfter, not the loss'), plus caps, cost, and refusal semantics. An agent has everything required to build a valid, in-budget request.
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 genuine constraint semantics: at most 16 groups, each non-empty, no transition in two groups, and the work-estimate cap formula (loss evaluations × candidate moves × realizations × horizon). These are usage rules the schema fields do not encode.
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 ('Distill exact search into the play scorer: fit rate multipliers for named transition groups') with the goal condition ('so play's rankings agree with exact minimax'). It explicitly names the sibling it is not (sim_calibrate) and the axis that separates them, so an agent can route without opening schemas.
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?
Provides explicit when-to-use via the counterpart framing ('This is TACTICAL calibration — the counterpart of sim_calibrate, which learns rates from an event log') and the deliberate division of labor. It even tells the agent how to interpret a null result ('Zero agreement improvement is a finding about the structure, not a failed fit').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_edgesADestructiveInspect
List every relation touching an entity, as either subject or object. Answered from an index by subject and object; each call re-lists the store so edges written by other instances are seen. Legacy edges whose predicate predates the registry are included with axis "unregistered". Structural edges (isomorphicTo, subnetOf, preservesInvariant, refines) list the witnesses that prove them; one listing none is marked unwitnessed and proves nothing. An isomorphicTo edge is the same net up to renaming, not the same behaviour: its definition (coloured-net-v1) does not compare guards, stages, schedules, constraints, objectives or non-refine tags such as outcome — read the witness (GET /api/lineage/{witnessId}, whose notCompared lists what that pair carries; sim_check_witness re-checks it) before treating two models as behaving alike.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | entity id to look up |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description frames this as a pure read served 'from an index', and its only behavioral caveat is eventual consistency across instances. Annotations instead declare readOnlyHint=false, destructiveHint=true and idempotentHint=false; the non-idempotency is loosely supported by the re-listing sentence, but nothing in the description accounts for a destructive, non-read-only profile. It also adds genuinely useful semantic disclosure (unregistered axis, unwitnessed structural edges), so the conflict, while real, is partial rather than total.
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 core purpose, then layered: indexing/consistency, legacy edges, structural edges, and the isomorphicTo caveat. Dense and long, but nearly every sentence carries decision-relevant information; the isomorphicTo paragraph is the one place that could be trimmed.
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 compensates well by explaining result semantics: the 'unregistered' axis for legacy predicates, 'unwitnessed' edges that prove nothing, and witness ids. Missing pagination/volume behaviour and any mention of ordering, which for an all-relations-of-an-entity query an agent would want.
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?
One required parameter with 100% schema coverage, so the schema already carries the meaning ('entity id to look up'). The description adds the nuance that the id matches against both subject and object positions, but no format or id-scheme guidance beyond that. 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?
Opens with a specific verb+resource+scope: 'List every relation touching an entity, as either subject or object.' That scope statement distinguishes it from directional siblings like sim_neighbors, and the description goes on to define exactly what kinds of edges appear in the result set.
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 gives clear activation context ('each call re-lists the store so edges written by other instances are seen') and routes the agent to concrete alternatives for follow-up — GET /api/lineage/{witnessId} and sim_check_witness. It stops short of an explicit when-not-to-use statement, so it is a strong 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_evaluateADestructiveInspect
Score a player's legal next moves with the PLAY method (the blog post's move picker): apply each candidate hypothetically and score the expected objective of the position it leads to, by seeded SSA rollouts (seed 11, shared across candidates so a difference measures the move, not the dice) — the best move scores highest. Needs the game schema (simulation.objective + simulation.players). The response names the engine. This tool always uses play on SSA: next-move elimination (rate-zero ablation, which reads an ungated net through the continuous ODE relaxation), the closed-form incidence reduction and exact search are the HTTP evaluate endpoint's method option (eliminate | incidence | search), not selectable here.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| player | Yes | player name from simulation.players | |
| horizon | No | model time to explore ahead (default 3, max 10000) | |
| marking | No | JSON object, sparse marking override (the position to evaluate from); default = the initial marking | |
| realizations | No | SSA rollouts per candidate move (default 40, max 200) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag this as non-read-only, non-idempotent, and destructive, so the safety profile is covered. The description adds substantive behavioral context beyond the schema: deterministic seeding (seed 11 shared across candidates so differences measure the move, not the dice), the mandatory 'play on SSA' method, and that the response names the engine. No contradiction with 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 reasonably front-loaded, but the text is a dense single block of em-dashes and stacked parentheticals, and the final sentence about the HTTP endpoint's eliminate/incidence/search methods is lengthy. It is informative but not tightly structured for quick 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?
With no output schema, the description mentions what the response contains (the engine name), and it covers inputs, prerequisites, method constraints, and the seeding model. For a scoring/simulation tool this is close to complete, with only the return payload's scoring shape left implicit.
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 five parameters are already documented. The description adds conceptual framing for realizations (seeded SSA rollouts) and marking (the position to evaluate from), but does not extend syntax or format beyond the schema. Baseline 3 applies.
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+resource: scoring a player's legal next moves with the PLAY method via seeded SSA rollouts, and indicates which move scores highest. It clearly distinguishes itself from the HTTP evaluate endpoint's eliminate/incidence/search methods, though it does not differentiate from its sim_* siblings.
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 prerequisites (needs the game schema with simulation.objective + simulation.players) and clarifies what the tool does NOT do (the elimination/incidence/search methods belong to the HTTP endpoint), which is useful boundary-setting. However, it gives no guidance on when to pick this over sibling tools like sim_optimize or sim_scenario.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_extendADestructiveInspect
Apply structural edits to a stored model and store the result as a NEW model you own, with lineage back to the original — the same vocabulary the guided builder uses behind its interview, now callable directly. Operations (JSON array, each with "op"): add_place {id, initial}, add_transition {id, guard, event}, add_arc {from, to, weight, kinetic, type}, remove_place, remove_transition, remove_arc {from, to}, set_rate {id, rate}, set_initial {id, initial}, set_capacity {id, capacity}. The edited model is validated before it is stored; a set of operations that leaves the net malformed is refused with every reason, and nothing is written. Returns the new id, the operations applied, and the structural diff.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id to edit | |
| name | No | optional name for the edited model | |
| operations | Yes | JSON array of operations |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses validation before storage, refusal with reasons and nothing written on malformed nets, and the exact return payload (new id, applied ops, diff). This goes well beyond the annotations (which only hint at destructive potential) and adds no contradiction.
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 front-loaded with the core purpose and then systematically lists operations, validation behavior, and return values. It is somewhat long due to the operation catalog, but every section earns its place and is logically ordered.
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 tool with a variable operations array and no output schema, the description covers invocation, exact operation shapes, validation, failure atomicity, and return values. An agent has everything needed to call it correctly without further reference.
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 description enumerates each operation type and its required fields (add_place, add_transition, etc.), giving the operations parameter rich semantics far beyond the schema's generic 'JSON array of operations'. This significantly helps an agent construct valid input.
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 clearly states it applies structural edits to a stored model and stores the result as a new owned model with lineage, which is a specific verb+resource+outcome. It enumerates the full operation vocabulary, distinguishing it from creation, comparison, and deletion tools in the sibling list.
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 provides strong context: edit a stored model, receive a new model, use the same operations as the guided builder. However, it does not explicitly name when not to use it or how it differs from siblings like sim_create_model or sim_supersede_model, so it falls short of full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_get_artifactDestructiveInspect
Fetch a stored prompt or artifact by id as JSON-LD: the two records sim_prompt and sim_reroll store besides a model. An artifact (@type Artifact) is an LLM reply that was not stored as a model — a report, code, or model JSON that failed validation — returned whole as content (the store caps an artifact at 262144 bytes), with contentKind. A prompt (@type Prompt) is what was asked: text, system, llmProvider, llmModel and requestTemplate (the version of the fixed instruction and settings sim_prompt wrapped them in). A prompt with no requestTemplate was stored before sim_prompt's description said a stored prompt and its results are readable by anyone with an id, so its text and system are withheld, and so is the content of an artifact it produced: withheld names the fields left out, and note says why. parent is the id it was run against (a prompt) or produced by (an artifact), and lineage is the derivation record for it (wasDerivedFrom, activity, ancestry nearest first, wasAttributedTo, generatedAtTime), absent when none was recorded. A model id, or an id of another stored kind, is refused naming what it is and the tool or route that reads it. Public: no sign-in and no compute tokens; writes nothing. GET /api/artifacts/{id} serves the same document.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | prompt or artifact id (content hash): sim_prompt's promptId, or its id when kind is "artifact" |
sim_get_bindingBDestructiveInspect
Fetch a stored Binding by id, with its check computed now (binds-port-v1; binds-port-v2 for a binding that declares a unit conversion, which is returned as convert; binds-port-v3 for one that declares a delay, returned as delay in hours): ok (with the unit verdict: agree, converted or unchecked), refused (a binding recorded before the check that sim_bind and sim_run_pipeline would refuse today, flagged legacy) or uncheckable (a model it names was deleted).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | binding id |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations carry the safety profile, and the description usefully adds the versioning scheme and the three outcome states (ok/refused/uncheckable) plus unit verdicts. However, it never explains the surprising destructiveHint=true / readOnlyHint=false for what it calls a "Fetch" — the one behavioral trait an agent most needs reconciled is left implicit (only "flagged legacy" hints at a side effect).
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 core verb+resource, which is good, but then condenses versions, verdicts, and three result states into one heavily nested sentence with stacked parentheses. The content is relevant (no output schema), yet the structure is dense enough to slow an agent's parsing.
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-value burden and does so thoroughly, enumerating ok/refused/uncheckable and unit verdicts. What remains unexplained is the destructive/read-only status of a tool named "get", leaving one meaningful behavioral gap.
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 sole id parameter is documented as "binding id", so the schema does the heavy lifting. The description restates "by id" without adding format, lookup, or error semantics, matching the baseline 3 for high-coverage schemas.
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 ("Fetch a stored Binding by id") and elaborates on the computed check, so the retrieval intent is unambiguous. It distances itself from write tools like sim_bind and sim_run_pipeline, but never explicitly contrasts with the obvious sibling sim_list_bindings, so full sibling differentiation is missing.
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: an agent can infer you call this to inspect one binding's stored state and current check verdict. There is no explicit when-to-use, when-not-to-use, or named alternative (e.g., use sim_list_bindings to enumerate), so guidance stays at the implied level.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_get_modelDestructiveInspect
Fetch a stored model's full Petri-net JSON by its content id. A name in place of an id is refused saying to search with sim_list_models' query, and that a model created without sign-in is listed for nobody, so its id is the one its create returned; or naming the curated model's id when a curated model has exactly that name. An id of another stored kind (a prompt or artifact, a sim_reach question or answer, a system, binding, map, collection, witness, relation, or sim_query query or result) is refused naming what it is and the tool or route that reads it. Public and free.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id (content hash) |
sim_invariantsADestructiveInspect
Derive a model's full algebraic invariant structure: conservation laws (Farkas P-invariants — weighted place sums every run preserves, the arithmetic a trust panel should show), firing cycles (T-invariants, named per-cycle with a readable detail sentence, each tagged StructuralProof), and the siphon/trap report (every minimal siphon and trap found from the arc structure, plus deadlock witnesses — minimal siphons holding no tokens at this model's own initial marking, which proves every transition needing one permanently disabled). This is the same computation sim_diagnose's structural fields read from, not a lesser copy of it. Pure structure, no simulation; every claim holds for every trajectory from this initial marking.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations mark destructiveHint=true and readOnlyHint=false, yet the description only presents a read-only-looking 'derive/computation' profile and never explains what side effect or destruction may occur. It does add useful semantic context about the absence of simulation and the universal claims, but the mutation/destructive behavior is undisclosed. This is not a direct contradiction because the description never claims to be side-effect-free.
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 longer than average but front-loads its main purpose and structures the three result families into clear clauses. The sim_diagnose clarification and the no-simulation caveat earn their place; mild verbosity in the first sentence keeps it from a perfect 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 one-parameter tool with no output schema, it explains all three result families, their provenance from the arc structure, and the meaning of deadlock witnesses. That is enough for an agent to know what it will get back. The main gap is the unexplained destructiveHint, which leaves the overall invocation contract incomplete.
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 schema already documents id with 100% coverage, so the description adds little about the parameter itself. It does reinforce that id refers to a model and adds meaningful context about 'this model's own initial marking', which helps an agent understand how the invariants are grounded.
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 uses a specific verb, 'Derive', and a precise resource, 'a model's full algebraic invariant structure', then enumerates three concrete output families: P-invariants, T-invariants, and the siphon/trap report. It also differentiates itself from sim_diagnose by explicitly saying this is the same computation, not a lesser copy, so an agent can distinguish it from siblings.
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 gives clear context: this is for static algebraic structure, explicitly excludes simulation, and points out the relationship to sim_diagnose's structural fields as an alternative access point. It stops short of a broader decision rule against simulation-oriented siblings, but the boundary is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_license_modelADestructiveInspect
Dedicate a model you created to the commons under CC0-1.0, CC-BY-4.0, CC-BY-SA-4.0. It then appears in every user's listing with the license shown, and the dedication is IRREVOCABLE — it cannot be changed or deleted afterwards, which is what makes it safe for others to build on. CC0-1.0 is the cleanest choice for a model: attribution terms are hard to honor for a net someone folds into a larger one.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id to dedicate | |
| license | Yes | one of CC0-1.0, CC-BY-4.0, CC-BY-SA-4.0 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true, and the description goes beyond this by explaining the irrevocable nature, the global visibility effect, and the safety rationale for others building on the model. This adds meaningful behavioral context about consequences that annotations alone do not convey.
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 efficiently structured: main action first, then the key consequence (irrevocability), then practical licensing advice. Every sentence contributes value, and the warning is front-loaded in a way that helps an agent avoid misuse.
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 two-parameter operation with annotations covering read/write and destructive behavior, the description fully covers the purpose, side effects, permanence, and licensing nuance. There is no output schema, but the description's explanation of what happens after dedication is sufficient for an agent to invoke 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 coverage is 100%, but the description adds important semantic meaning beyond the schema by clarifying that the model must be one 'you created', which is not explicit in the schema's 'model id to dedicate'. It also reinforces the license options and provides guidance on choosing CC0, though it does not describe exact parameter syntax.
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 clearly states the action ('Dedicate a model you created to the commons'), the specific licenses accepted, and the observable effect (appears in every user's listing with the license shown). It is specific and distinct from sibling tools like sim_publish or sim_delete_model.
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 provides strong context for when to use the tool by emphasizing that the dedication is IRREVOCABLE and cannot be changed or deleted, signaling caution before use. It also gives licensing guidance (CC0 is the cleanest choice for models), though it does not explicitly name alternative tools or state when not to use it beyond the irreversibility warning.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_linkADestructiveInspect
Record a typed edge between two stored entities (models, prompts, artifacts, maps, collections, bindings, relations — not witnesses), using a registered predicate. sim_link writes these (subject → object): @type (model → a https://sim.pflow.xyz/ns/models/v1 type name); about (artifact/prompt/map/collection → model/collection/binding/system); broader (model/collection/system → model/collection/system); cites (any entity → any entity); closeMatch (model → model); hasMember (collection → any entity); related (model/collection/system → model/collection/system). from, to and feeds are recorded only by sim_bind, produced only by sim_prompt/sim_reroll, supersededBy only by sim_supersede_model, migratedFrom only by sim_accept_migration; narrower is broader read backwards and is never stored; structural predicates (isomorphicTo, subnetOf, preservesInvariant, refines) are recorded only by sim_prove, together with the witness that proves them. Each is refused here, naming the tool that records it (or the reversed call, for narrower). Subject and object must be stored entities of the kinds the predicate relates, passed by content id (for @type, the object is a /ns/models/v1 type name). Full definitions at https://sim.pflow.xyz/ns/predicates/v1. Distinct from the Lineage a model/prompt/artifact already carries, which is specifically derivation (parent -> prompt -> child). Who may write an edge is its predicate's write rule (writeRule in the registry): hasMember is subject-owner — only the collection's owner (who created it with sim_create_collection) adds members, and a collection created before collections had owners takes no new ones; every other predicate sim_link writes is any-signed-in, an assertion attributed to you. A refusal names the rule. Edges are immutable and are never retracted. Linking the same subject/predicate/object again as the same user — either direction for a symmetric predicate — is idempotent: it returns the existing relation's id (existing: true) rather than recording a duplicate edge. Needs sign-in (opens OAuth the first time); the edge is attributed to you; costs 1 compute token. Writes one Relation, or nothing when it already exists.
| Name | Required | Description | Default |
|---|---|---|---|
| object | Yes | content id of the stored entity the edge points to; for @type, a type name from https://sim.pflow.xyz/ns/models/v1 | |
| subject | Yes | content id of the stored entity the edge starts from | |
| predicate | Yes | one of @type, about, broader, cites, closeMatch, hasMember, related |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly claims 'Linking the same subject/predicate/object again as the same user ... is idempotent: it returns the existing relation's id ... rather than recording a duplicate edge', while the annotations declare idempotentHint=false. The text says the annotation is wrong, which is a direct contradiction an agent could act on. (The otherwise rich detail — auth, attribution, cost, immutability, refusal rules — cannot offset the conflict.)
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 and almost every clause carries operational information (refusals, ownership, idempotency, cost). It is, however, a single dense paragraph with long semicolon chains that could be broken into predicate list vs. behavior, making it harder to scan than its content warrants.
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?
There is no output schema, and the description closes the loop itself by stating what is written ('one Relation, or nothing when it already exists') and the existing:true signal. Combined with the auth requirement, compute-token cost, attribution, immutability, and refusal semantics, an agent has everything needed to invoke and interpret this call.
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%, but the 'predicate' parameter has no enum in the schema, so the description carries the load: it enumerates every accepted predicate, gives each one's subject→object type signature, and specifies that 'object' is a /ns/models/v1 type name for @type and a content id otherwise. That is substantive semantics well beyond the field descriptions.
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 states a specific verb+resource+scope ('Record a typed edge between two stored entities ... using a registered predicate') and immediately distinguishes this tool from siblings (sim_bind, sim_supersede_model, sim_prove, sim_accept_migration) by naming the predicates each of those owns. An agent can tell exactly what this tool writes and what it does not.
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 exhaustively specified: the valid predicate set is enumerated with subject→object type constraints, predicates refused here are listed together with the tool that records them instead, and 'narrower' is called out as the reversed form of 'broader'. It also states when the call will be refused and why (write rule / ownership).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_list_bindingsCDestructiveInspect
List the content id of every stored Binding.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description says 'List', which is a read-only enumeration operation, but the annotations set readOnlyHint=false and destructiveHint=true, implying the tool may mutate or destroy data. This directly contradicts the description and nothing in the description reconciles the destructive hint.
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?
A single, front-loaded sentence with no filler. It communicates the operation, the resource, and the return value without redundancy.
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-parameter list tool, the description adequately names what is returned. However, given the annotation-implied destructive behavior, it is incomplete and potentially misleading. There is also no output schema, so the brief description must carry more weight than it does.
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 has zero parameters and the schema has 100% coverage since the schema is an empty object. The baseline of 4 applies because there are no parameter semantics the description needs to clarify.
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 ('List'), a specific resource ('stored Binding'), and the exact output ('content id'). The word 'every' signals exhaustive enumeration, which helps distinguish it from sim_get_binding, though it doesn't explicitly name any sibling alternative.
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 guidance about when to use this tool versus alternatives such as sim_get_binding. No exclusions, prerequisites, or context are provided; the intended usage is only implicitly that it enumerates all stored bindings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_list_modelsDestructiveInspect
List the models visible to you, as a JSON array of {id, name, description, license, curated, mine} sorted by name (a field that does not apply is left out): the curated catalog (curated: true), models dedicated to the commons (each carries its license), and your own (mine: true). The curated models are complete, working examples of the model JSON: read one with sim_get_model and copy its shape when writing a model for sim_create_model. scope narrows the list to one of those groups and query to the models matching every term; the two compose. With neither, every visible model is still listed, but compactly: each description except a curated model's is cut to its first 64 bytes, ending in "…" where cut; pass scope or query (scope "commons", or query "clinic") for each listed description in full (its first line, at most 200 bytes), which is also the text query searches. Free (no compute token) and writes nothing. Public, except that scope "mine" needs sign-in (opens OAuth the first time). Other users' undedicated models are not listed, but any model id works with every sim_* tool — an id someone shares with you is the model.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | whitespace-separated terms; lists only the models whose name, description or id contains every term, case-insensitively (each term may match a different field). The description searched is the one listed: its first line, at most 200 bytes. At most 256 bytes; longer is refused. Unset matches everything. | |
| scope | No | which group to list: "curated" (the catalog this server seeds, the worked examples), "commons" (models dedicated to the commons, none of them curated) or "mine" (the models you own, dedicated or not; needs sign-in). Unset lists all three; any other value is refused. |
sim_map_getCDestructiveInspect
Fetch a stored Map's key->value data by id.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | map id |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations mark the tool as destructiveHint=true and readOnlyHint=false, directly contradicting the description's 'Fetch' behavior. Because the description conflicts with the annotations, an agent cannot trust whether the operation is actually a read or has destructive side effects.
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 single sentence with no filler and the action is front-loaded. It is appropriately concise for a one-parameter lookup tool.
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?
The description is too sparse relative to the annotations: it does not clarify the destructive behavior implied by destructiveHint=true, nor does it address not-found behavior or return shape in the absence of an output schema. An agent would not have enough coherent context to invoke the tool safely.
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 the id parameter, and the description only restates it as 'by id'. The description adds no extra semantic detail beyond what the input schema 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 description states a specific verb (Fetch), a resource (a stored Map's key->value data), and a selector (by id), so an agent can identify this as a single-map lookup. It is distinguishable from siblings like sim_map_list or sim_map_put, but it does not explicitly name those alternatives, so it misses 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?
No guidance is given about when to use sim_map_get instead of sim_map_list or sim_map_put, and there are no when-not-to-use conditions. The only clue is the phrase 'by id', which is more parameter semantics than guidance for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_map_listBDestructiveInspect
List the content id of every stored Map.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations declare readOnlyHint=false and destructiveHint=true, yet the description only says 'List', which implies a safe, read-only operation. The description does not disclose any destructive side effects or mutation behavior, and it directly conflicts 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?
A single, front-loaded sentence states the action, resource, and output with no filler. Every word contributes to understanding the tool's purpose.
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?
The tool is simple and the return value is described, but the annotations indicate potentially destructive or non-read-only behavior that the description completely omits. An agent cannot safely invoke this tool without knowing those side effects, so the description is not contextually complete.
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 has zero parameters, so no parameter documentation is required. The description clarifies that the result scope is 'every stored Map', which is sufficient context for the single available operation.
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 uses a specific verb, 'List', names the exact resource, 'stored Map', and the output, 'content id'. It is clearly distinct from sibling tools like sim_map_get, sim_map_put, sim_list_models, and sim_list_bindings.
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 guidance on when to use this tool versus alternatives such as sim_map_get or sim_map_put. The intended use case can be inferred from the description, but no explicit conditions, exclusions, or alternative comparisons are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_map_putADestructiveInspect
Store a key->value lookup table as its own content-addressed entity — a generated parameter sweep, a rate table, a component registry, anything shaped as key->value rather than free text (an artifact) or a Petri net (a model). Returns its content id; the same data, even with keys inserted in a different order, returns the same id.
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | the table as a JSON object |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description adds meaningful behavior: content-addressed identity, order-insensitive key insertion, and the fact that the return value is a content id. This enriches the agent's understanding without contradicting the provided annotation 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?
Two sentences with the core action front-loaded, followed by clarifying examples and the content-addressing identity behavior. Every clause earns its place; there is no 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 one-parameter store operation, the description covers what is stored, what is returned (content id), and the deduplication behavior. Annotations cover side-effect hints, and no output schema is needed given the simple return value.
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 schema already documents the single data parameter as 'the table as a JSON object,' so the baseline is 3. The description adds semantic value by framing it as a key->value lookup table and giving concrete examples such as parameter sweeps, rate tables, and component registries.
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 opens with a specific verb-resource pair: 'Store a key->value lookup table as its own content-addressed entity.' It further distinguishes itself from free-text artifacts and Petri-net models, making its purpose unmistakable and differentiating it from sibling tools.
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 a clear decision rule: use this for anything shaped as key->value rather than free text or a Petri net. It doesn't explicitly name retrieval siblings like sim_map_get or sim_map_list, but for a store operation the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_migration_offersADestructiveInspect
List what happens to the edges of a superseded model. Taxonomic edges (hasMember, @type, broader, related, closeMatch, cites, about) are OFFERED: each row gives the edge as it would read on the model's current successor (followed through its supersession chain), whether sim_link's checks pass for it now (passes, refused, or unchecked when the store could not answer), any earlier migrations of it, and the sim_accept_migration call that accepts it. Nothing moves automatically, the old edge stays, and this read writes nothing: offers are computed on read and never stored. Tool-written edges (from/to/feeds, produced, supersededBy), structural edges (isomorphicTo, subnetOf, preservesInvariant, refines) and legacy unregistered predicates STAY with the old model, each with its reason; a structural row names its witnesses and the sim_prove call that would make a new edge for the successor. Stored systems naming the model are listed under systems (sim_system {naming}'s answer, at most 100 rows): a System names exact ids, so supersession changes none of them, and systemsNote names the sim_create_system call with the successor. A chain that cycles, runs past 64 hops, ends at a deleted model or reaches a model now owned by someone else is reported as such, with no target. Accepting needs you to own the superseded model or to have authored the edge, and the edge it becomes must pass its predicate's write rule for you, as sim_link would (hasMember: you own the collection); youMayAccept says whether you may, per edge, and writeRule says why not when only the write rule refuses. 100 edges per page (pass next as after); predicate narrows to one stored predicate (narrower is refused: pass broader). Needs sign-in with read scope (opens OAuth the first time); anonymous over HTTP as GET /api/models/{id}/migrations, with no youMayAccept. Costs 1 compute token per call.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | the next value a previous call returned, for the following page | |
| model | Yes | content id of the superseded model | |
| predicate | No | read only this predicate's edges |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations declare readOnlyHint=false and destructiveHint=true, but the description asserts 'Nothing moves automatically... this read writes nothing: offers are computed on read and never stored.' That is a direct, serious inconsistency about whether the tool mutates state or destroys anything. Per the rubric this contradiction forces the lowest score despite the otherwise rich behavioral detail (pagination, auth, cost, cycle/hop limits).
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 long and written as a single dense block, but it is front-loaded with the core distinction (offered vs stays) and proceeds in topical order: offered edges, staying edges, systems, error cases, permissions, pagination, auth, cost. Almost every clause carries information; the length is justified by the tool's complexity, though line breaks would improve scanability.
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 tool with no output schema and unreliable annotations, the description covers what a caller needs: the shape of each row class, per-edge fields (passes/refused/unchecked, youMayAccept, writeRule), pagination, auth scopes, anonymous HTTP access, cost, and the cycle/hop/ownership failure modes. Nothing material about invoking 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 the baseline is 3, but the description earns above that by adding real semantics: 'after' is the next token from a previous call (100 edges per page), 'predicate' narrows to one stored predicate and a narrower predicate is refused so you must pass broader, and 'model' must be the superseded model. This genuinely enriches the terse schema descriptions.
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 — listing what happens to the edges of a superseded model — and immediately differentiates the two edge classes (taxonomic edges OFFERED vs tool-written/structural/legacy edges STAYING). An agent can tell it apart from siblings like sim_edges, sim_accept_migration, or sim_supersede_model without opening any 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?
It routes the agent to the right follow-up tools: sim_accept_migration to accept an offer, sim_prove to generate a structural successor edge, sim_system/sim_create_system for naming systems. It also states the preconditions for accepting (you own the superseded model or authored the edge, plus the predicate write rule). It stops short of an explicit 'call this before/never instead of X' framing, so it is slightly more context than explicit when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_my_sheetsBDestructiveInspect
List the sheets this user has published, with their URLs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, which is surprising for a 'List' operation and suggests the tool may have side effects or destructive behavior. The description does not explain this contradiction or disclose what destructive action might occur, nor does it clarify the 'openWorldHint' meaning. The description adds no behavioral context beyond the annotations and actually conflicts with the expected read-only nature of listing.
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 single, front-loaded sentence with no filler. Every word earns its place: it names the action, the resource, the scope ('this user'), and the output ('URLs').
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 parameterless tool with no output schema, the description is mostly complete in terms of what it returns. However, the annotations signal destructive behavior and an open world, which the description fails to address. An agent cannot tell whether calling this tool will mutate or delete published sheets, which is a critical gap for a tool that sounds read-only.
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 has zero parameters, so the schema provides no parameter documentation. The description compensates by clearly stating the resource being listed and the output (URLs), which is sufficient for an agent to know what the tool operates on. Baseline 4 is appropriate for a parameterless tool.
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 states a specific verb ('List') and resource ('sheets this user has published'), and mentions URLs as the key output. It is clear enough to distinguish from most siblings, though it does not explicitly name a sibling alternative.
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 implies a read-only listing use case ('List the sheets this user has published'), which is clear context. However, it does not state when to use this tool versus alternatives like sim_list_models or sim_list_bindings, nor does it mention any exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_neighborsADestructiveInspect
One-hop traversal from an entity, read through the predicate registry. With no predicate: the object of every relation where the entity is the subject. With a predicate: the entities one hop along it — for an inverse name that is never stored (narrower) the stored predicate is read backwards (the subjects of the broader edges pointing at the entity), and for a symmetric one (related, closeMatch) both directions count, since an edge recorded from the other end says the same thing. A legacy free-form predicate still answers from its stored edges; a name that is neither registered nor used by any stored edge is refused. Pass a collection's id with predicate hasMember to list its members. A structural neighbour (isomorphicTo, subnetOf, preservesInvariant, refines) is a bare id here: sim_edges lists the edge's witnesses, and isomorphicTo does not compare guards, objectives or outcome tags. Ordered by timestamp, then relation id: tool-recorded edges (from/to/feeds, supersededBy, and edges carried forward by sim_accept_migration, unless it reused one you had already linked) carry no timestamp, come first and are in no particular order among themselves, so the last supersededBy neighbor is not necessarily the current successor. Not de-duplicated.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | subject id to traverse from | |
| predicate | No | restrict to this predicate; omit for every outgoing relation |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states the operation is a read/traversal ('read through the predicate registry'), while the annotations declare readOnlyHint=false and destructiveHint=true. This is a direct conflict about the tool's safety profile, so no amount of extra detail (inverse/symmetric predicate handling, ordering, no de-duplication) can be credited as consistent transparency.
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 almost every clause carries operational information (ordering rules, no de-duplication, supersededBy caveat), so there is little waste. However, the middle sentences are dense run-ons packed with parentheticals, which makes the block harder to scan than it needs to be.
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?
There is no output schema, so the description carries the return-value burden itself, and it does: ordering by timestamp then relation id, the untimestamped tool-recorded edges, and the 'not de-duplicated' caveat. For a two-parameter traversal tool this is complete enough to call 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 coverage is already 100%, but the description adds substantial meaning beyond it: predicate semantics for inverse names (read backwards), symmetric predicates (related, closeMatch, both directions), legacy free-form names answered from stored edges, and the special id+hasMember collection case. This is well above the baseline for a fully documented schema.
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 clause gives a specific verb+resource ('one-hop traversal from an entity, read through the predicate registry') and the description explicitly distinguishes itself from siblings such as sim_edges ('sim_edges lists the edge's witnesses') and implicitly from multi-hop tools. An agent can tell exactly what graph operation this performs.
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 gives strong usage conditions: omit predicate for all outgoing relations, pass predicate to restrict, use hasMember with a collection id to list members, and unknown names are refused. It never explicitly names an alternative for multi-hop traversal (e.g. sim_reach), so the sibling routing is only partial.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_optimizeADestructiveInspect
Multi-objective optimisation over transition rates for a stored model: Monte Carlo samples the rate ranges, runs each combination to the horizon with the continuous engine, and returns every sample with a Pareto flag — the non-dominated set is the trade-off frontier ('which staffing is non-dominated on served vs walked out'). Continuous reading: a model with a schedule or a gate is refused with the reason (use sim_compare with explicit scenarios for those). Costs 1 token per 50 samples (rounded up) from your account's compute bucket; rate ranges must be non-negative.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| seed | No | sampling seed, a whole number (default 42) | |
| hours | No | horizon per run (default 8, above 0 and at most 10000) | |
| samples | No | Monte Carlo samples (default 100, 1..1000; outside that is refused) | |
| objectives | Yes | JSON array of {"place": id, "direction": "max"|"min"} | |
| parameters | Yes | JSON object transition_id → [min, max] rate range, e.g. {"finish_brew": [10, 40]} |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (destructive, non-idempotent, open-world), and the description adds genuinely non-obvious behavior: token cost per 50 samples, refusal conditions with reason, non-negative rate-range constraint, and that every sample is returned with a Pareto flag. It stops short of explaining what the destructiveHint actually means (whether runs persist artifacts), which is the remaining 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?
Front-loads the core operation, then cost and refusal rules in order of decision relevance. The parenthetical example and cost sentence are dense but each earns its place; slightly crowded overall.
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 6-parameter tool with no output schema, the description supplies what the schema cannot: return content (all samples with Pareto flags), cost model, refusal semantics, and the routing fallback. Nothing essential for a correct call 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 the baseline is 3, but the description adds real meaning: the non-negativity rule for rate ranges, the purpose of the horizon and sampling loop, and the interpretation of objectives for the caller. It does not re-specify defaults or bounds already in the schema.
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+resource ('multi-objective optimisation over transition rates for a stored model') and elaborates the mechanism (Monte Carlo sampling, horizon runs on the continuous engine, Pareto flagging). It also names the sibling it is not (sim_compare) for models it refuses.
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?
Gives the when (trade-off frontier over rate ranges, with a concrete example: 'which staffing is non-dominated on served vs walked out'), the when-not (models with a schedule or a gate are refused), and the alternative (use sim_compare with explicit scenarios).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_param_heatmapADestructiveInspect
Two-rate grid for a stored model: vary two transition rates over ranges, run each combination to the horizon with the continuous engine, and return the observable's final value as a grid — 'which regime of arrivals × restock keeps the queue empty'. Continuous reading: a model with a schedule or a gate is refused with the reason. Costs 1 token per 50 grid cells (rounded up; a 40x40 grid empties the bucket) from your account's compute bucket.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| hours | No | horizon per run (default 8, above 0 and at most 10000) | |
| param_x | Yes | first transition id | |
| param_y | Yes | second transition id | |
| range_x | Yes | JSON [start, stop, n] for param_x: non-negative rates, n a whole number 2..40 | |
| range_y | Yes | JSON [start, stop, n] for param_y: non-negative rates, n a whole number 2..40 | |
| log_scale | No | space the grid in log10 (default false) | |
| observable | Yes | place id whose final value fills the grid |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and openWorldHint=true, and the description usefully explains the source of that cost: 1 token per 50 grid cells, with a 40x40 grid emptying the bucket. It also discloses the refusal condition for non-continuous models. It does not explain failure behavior beyond that, keeping 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?
Three sentences, front-loaded with purpose, then the constraint, then the cost. Dense but every clause carries information; the quoted example earns its place by anchoring the abstract grid concept.
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?
Covers what the tool does, what it returns, the input constraint, and the cost for an 8-parameter tool with no output schema. The only gap is not explaining what happens on failure or how refused models should be handled, but the core call semantics are complete.
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 all 8 parameters including range format and bounds. The description adds conceptual framing (two rates varied together, run to the horizon) but no syntax or format detail beyond the schema, so the baseline 3 applies.
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: vary two transition rates over ranges, run each combination to the horizon, return the observable's final value as a grid. The concrete example ('which regime of arrivals × restock keeps the queue empty') makes the operation unambiguous and unlikely to be confused with siblings like sim_optimize or sim_scenario.
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?
Gives a clear use case and an explicit exclusion: 'Continuous reading: a model with a schedule or a gate is refused with the reason.' It does not name a sibling alternative to use instead when a model has a schedule or gate, so it stops short of full when/when-not/alternatives guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_promptDestructiveInspect
Ask an LLM to derive something from a stored entity: a variant model, a report, a piece of generated code — whatever the prompt asks for. The parent's JSON rides along as context after a fixed instruction: answer a request for a new or changed model with only the complete model JSON (the shape sim_create_model takes), and anything else in plain text or markdown. The parent is looked up as a model first, then a prompt, then an artifact, then a map — whichever resolves — and the context block is labelled by what kind it found ("## Parent model", "## Parent prompt", ...), so the LLM is never told a report is a Petri net. When the parent is a prompt with no requestTemplate, its text and system are withheld from its readers (sim_get_artifact says why), and so is the content of an artifact such a prompt produced; unless you are its author, the LLM gets the document sim_get_artifact serves in its place, without them. The prompt is stored first and content-addressed like a model, so it has an id of its own before the LLM ever answers; both the prompt and whatever came back are placed in lineage under the parent (sim_prompt as the activity), so Ancestry walks parent -> prompt -> result. A Relation{prompt, "produced", result} is recorded alongside — sim_reroll's forward index, and queryable directly via sim_edges/sim_neighbors. Returns promptId, id, kind and url. A reply that decodes and passes the validation sim_create_model applies is stored as a NEW model you own (kind "model"; read it with sim_get_model), with warnings, when there are any, saying what sim_create_model would warn about it (a transition left at the default rate, a guard no run enforces, staff taken and given back in one firing, ...). Any other reply is stored as an artifact (kind "artifact") and returned inline as content, cut at 16384 bytes with truncated: true and contentBytes (the whole reply's length) when longer; sim_get_artifact reads all of it. When that reply held model JSON (an object with places or transitions) that failed to decode or validate, modelErrors lists every reason at once, as sim_create_model words its refusal (a key repeated across elements once, at most 20 of each kind with the rest counted). Needs sign-in (opens OAuth the first time). Refused if this deployment has no LLM provider configured. The stored prompt, text and system both, is readable without sign-in through sim_get_artifact by anyone who has its promptId or the id of anything derived from it, since lineage names the prompt behind every result: leave out of text and system what you would not share with whoever gets a result's id.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | the natural-language instruction; stored with the prompt, and readable by anyone with its id or a result's | |
| parent | Yes | id to run the prompt against — a model, prompt, artifact, or map | |
| system | No | optional system-level instructions, in addition to the parent context this tool always supplies; stored with the prompt, and readable by anyone with its id or a result's |
sim_propose_typesADestructiveInspect
Propose candidate @type values for one or more stored models, e.g. "QueueingSystem" or "ResourcePool", from a small Diagnose run this tool performs on each model (nothing is cached or reused between calls). Every rule is a hand-written assumption about what a shape of knobs/loss/siphons/classes tends to mean, not a structural proof or a measurement, so results are ASSUMPTION-grade until a human reviews one and applies it — apply with sim_link(id, "@type", ""), there is no separate apply tool. Pure read; nothing here is written to any model. Defaults to scanning the visible catalog (up to limit) when ids is omitted. Costs one Diagnose run per model — 5 tokens each from the compute bucket (per address, or per account when signed in), charged as each model is reached — so limit and realizations are both capped.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | No | JSON array of model ids to consider, e.g. ["id1","id2"]. Omit to scan every model ListFor("") would list (the public catalog), truncated to limit. | |
| limit | No | maximum number of models to diagnose (default 10, 1..25; over 25 is refused, and so are explicit ids naming more models than limit) — a cost control, since this runs a simulation per model | |
| realizations | No | realizations per model's Diagnose run (default 8, 1..16; outside that is refused) — deliberately small, this only needs to name a shape, not measure precise influence |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description asserts "Pure read; nothing here is written to any model," while the annotations declare readOnlyHint=false and destructiveHint=true. Even if the destructive hint is meant to capture compute-bucket consumption, the description's flat claim of a pure read directly contradicts the declared annotation profile.
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?
Dense but front-loaded: purpose first, then the reliability caveat, then the apply route, then cost semantics. Every sentence carries information, though the em-dash-heavy style makes it slightly longer than strictly 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 no-output-schema, zero-required-parameter tool, the description covers caching behavior, default scan scope, cost per model, grade of the result, and the apply path. The one missing piece is an honest reconciliation of the read-only claim with the annotated destructive/idempotent profile.
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 real meaning beyond the schema: it explains that limit and realizations are cost controls bounded by the per-model Diagnose charge, and that explicit ids exceeding limit are refused. That is more than restating the schema's ranges.
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 (propose candidate @type values for stored models) and names the mechanism (a small Diagnose run per model) plus the intended output shape ("QueueingSystem", "ResourcePool"). An agent can distinguish it from sim_link, which the description explicitly identifies as the apply path.
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?
Tells the agent how results get used ("apply with sim_link(id, "@type", "<Type>"), there is no separate apply tool") and what happens when ids are omitted (scan the visible catalog, truncated to limit). It stops short of an explicit when-not-to-use or prerequisite condition, so it is clear context rather than full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_proveADestructiveInspect
Prove a structural relation between two stored models and record it with its witness. isomorphicTo: an exact canonical-labelling search (the one behind sim_canonical, seeded with exactly what the check compares) finds a place/transition bijection preserving arcs (direction, type, weight, kinetic), place sort, initial marking, capacity, rate or delay and refine.* tags. It does not compare guards, stages, schedules, constraints, non-refine tags (outcome, port.*), data-place types and initial values, objectives, players or asserted classes; those the pair carries are listed as notCompared, so proved is not 'behaves the same'. subnetOf: a bounded embedding search finds an injective, sort-preserving map (token places to token places, data places to data places, transitions to transitions) of the subject's places and transitions into the object's whose arcs among the image are exactly the subject's (initial markings, capacities, rates, delays and tags are not compared). preservesInvariant (invariant-pullback-v1): an induced embedding as subnetOf's along which every P-invariant of the object pulls back to a P-invariant of the subject (the incidence the shared firing rule implies: consuming and producing arcs on token places). Proved carries the map and a cover — per subject transition, rational coefficients of object transitions with the same incidence — which proves it for every invariant at once, plus invariantDimension (0 means vacuous: the object conserves nothing). Embeddings are tried one image at a time (embeddings onto one image differ by a symmetry of the subject, which keeps or breaks the pullback with them), at most 16 images. refines (id-simulation-v1): every firing sequence of the subject from its initial marking, transitions the object has no transition of (by id) dropped as silent, is one of the object from its own; untimed, guards and fixed delays refused (unknown: a delay is a timer whose in-flight markings an atomic step skips), rates not compared, at least one shared transition id required. Proved carries a simulation relation (pairs of markings closed under the subject's firings, at most 4,096; relationPairs counts them, GET /api/lineage/ lists them), which makes the claim unbounded. Neither is declared transitive, so sim_query never closes over them. The answer is proved (with the map, in the caller's direction, or the relation), refuted (exhaustive, with the reason; a refuted refines, or a refuted preservesInvariant where the subject embeds at all, carries refutation, a counterexample sim_check_witness(refutation=…) re-checks: a trace for refines, an invariant per embedding for preservesInvariant, whose list of embeddings is the search's claim; a preservesInvariant refuted because no embedding exists carries none, as a refuted subnetOf carries none) or unknown (a search budget ran out; nothing is recorded, retrying gives the same answer, and unknown is not a no). Needs sign-in (opens OAuth the first time), including with record=false. Costs 3 compute tokens from your account's bucket, or 2 with record=false. Budgets: 1,000,000 refinement steps for both nets' canonical labelling together (isomorphicTo), 2,000,000 embedding steps (subnetOf), 4,000,000 units for elimination, embedding and tests together (preservesInvariant), 20,000,000 firing-rule units and 4,096 pairs (refines); the whole call is also bounded by the 55 s request limit. Writes, only when proved and record is true (the default): one witness, then one relation; isomorphicTo is stored with the smaller id as subject, and storedAs says so when that turned the call round. Otherwise it writes nothing. sim_check_witness re-checks either at any time. With via, sim_prove promotes instead of searching: it takes a structural fact sim_query derived (two to eight stored witnesses composed), re-derives it here from the stored witnesses — every step's witness re-checked against both stored models now, the chain, the composed map's digest, and the composed map checked against the two end models by pkg/morphism — and records the composed map as one direct witness through the same write gate as a search's, so the edge has the same id (one per subject, predicate and object) and is trusted exactly as far. The witness records the derivation as promotedFrom; re-promoting the same derivation writes nothing new (existing: true). A derivation that re-checks invalid or uncheckable is refused and nothing is written; an unknown is never promoted. Costs 2 compute tokens (a derivation re-check plus a store) instead of 3; record=false is refused with via.
| Name | Required | Description | Default |
|---|---|---|---|
| via | No | promote a fact sim_query derived instead of searching (JSON, as a string or an object): {"derivation": <a row's support[].derivation>} or {"result": "<sim_query result id>", "row": n, "support": k} (support only when the row carries more than one derivation; 0-based). The derivation must name exactly this subject, predicate and object (either order for isomorphicTo) | |
| object | Yes | content id of the stored model the edge points to | |
| record | No | when proved, store the witness and then the edge; false answers without writing (default true) | |
| subject | Yes | content id of the stored model the edge starts from | |
| predicate | Yes | isomorphicTo, subnetOf, preservesInvariant or refines |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as destructive and non-read-only, but the description adds substantial behavioral context: authentication is required even with record=false, costs are 3 tokens or 2 with record=false and 2 with via, budgets are enumerated, and writes happen only when proved and record=true. It also discloses search-budget outcomes, idempotent-like promotion behavior, and what each result status means.
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 single, very dense block with long nested clauses and repeated phrasing about predicates, budgets, and witness storage. While the opening sentence is front-loaded, the body is difficult to scan and likely overlong for an agent-facing definition. It sacrifices conciseness and structure for exhaustive detail.
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 the tool's complexity, the definition is complete: it explains all four predicates, what is compared and not compared, how witnesses and refutations are represented, authentication and cost requirements, search budgets, output statuses, and the via promotion path. No output schema exists, but the description still describes results and witness contents adequately.
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, but the description adds meaningful predicate-level semantics beyond the schema, including what each predicate proves and does not prove. It also expands on via's derivation shape and the record=false behavior. The parameter meaning is richer than the structured fields alone.
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 opens with a specific verb and resource: proving a structural relation between two stored models and recording it with a witness. It names the exact predicates it supports (isomorphicTo, subnetOf, preservesInvariant, refines) and distinguishes itself from sibling tools like sim_query and sim_check_witness. An agent can tell this is the search-and-record tool rather than a query or checker.
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 gives explicit when-to-use conditions for each predicate and explains the via alternative that promotes an existing sim_query derivation instead of searching. It also names sim_check_witness for re-checking and states that sim_query never closes over these relations because they are not declared transitive. This is unusually complete routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_publishADestructiveInspect
Publish a stored model into the signed-in user's Google Sheets: the model workbook (live formulas when honest, a refusal tab when not), a server-run scenario as data tabs, and trajectory + contention charts. Returns the sheet URL. Counts against the daily quota, and costs 1 token from your account's compute bucket for the run.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| scenario | No | optional scenario JSON to run for the data tabs; sim_scenario's defaults (hours 8, realizations 16, seed 20260809) fill whatever is omitted |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, openWorldHint=true, readOnlyHint=false, and idempotentHint=false, so the agent knows this is a mutating, open-world operation. The description adds valuable operational context: it returns the sheet URL, consumes daily quota, and costs 1 token from the account's compute bucket. It stops short of clarifying overwrite behavior or auth requirements.
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 front-loaded with purpose, then states the return value and cost implications in two short follow-up sentences. It is appropriately sized and avoids filler, though the first sentence is dense with artifact details.
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 destructive, open-world publish tool with no output schema, the description covers the key agent needs: what is published, that a sheet URL is returned, and the quota/token cost. It leaves some gaps around overwrite semantics and idempotency, but annotations already flag the destructive nature.
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 both id and scenario are already documented in the schema, including scenario's defaults. The description does not add syntax, format, or validation detail beyond what the schema provides, matching the baseline for high-coverage schemas.
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 and resource: publishing a stored model into the signed-in user's Google Sheets, and lists the concrete artifacts produced (workbook, data tabs, charts). It is clearly distinguishable from generic publish siblings, but does not explicitly distinguish itself from sim_publish_app or sim_publish_compare.
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 intended use case is implied: publish a stored model to Sheets. However, the description says nothing about when to choose this over sim_publish_app, sim_publish_compare, or sim_my_sheets, nor does it state prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_publish_appADestructiveInspect
Publish the generated application for a model you own — the single-file HTML a generator produced from the model's view prompt. Served at /app/ in a sandboxed opaque origin (no cookies, no session; only the CORS-open public API is reachable). START FROM THE RUNTIME, not from scratch: /lib/app-template.html is a working console that imports /lib/sim-console.js and composes , , , , and — the same components the generic console at /whatif/ runs. Composing them is how an app inherits role derivation, the fungible-set collapse, the influence ranking that never filters, the contention ledger and the verbatim caveats, none of which the checks below can verify you reimplemented correctly. Root-relative /lib/ imports are allowed. Off-origin loading is stopped in two places: the upload checks refuse an off-origin or , and the app is served under a Content-Security-Policy that confines scripts, styles, fetches, images and fonts to this origin — which is what stops the forms the checks do not parse (an inline module's import "https://…", a dynamic import(), a CSS @import). Checks refuse an app that is empty, oversized, never references its model id, or carries an off-origin /; behavioral correctness (does the app actually do what the view says) is on the generator and any browser gate you run.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id the app presents | |
| html | Yes | the complete self-contained HTML document |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructive, non-idempotent, and open-world behavior. The description adds substantial context beyond that: sandboxed opaque-origin serving, no cookies/session, CSP restrictions, upload checks for empty/oversized/off-origin content, and the allowed root-relative /lib/ imports. It leaves some gaps, such as replay/overwrite behavior for an existing app id and how ownership is verified.
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 front-loaded with the core purpose, but it is long and somewhat repetitive, restating off-origin enforcement in both the upload-check and CSP sentences. The component list and runtime guidance are relevant, yet the overall density is higher than necessary for a two-parameter publish tool.
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 publishing tool with no output schema, the description covers the runtime environment, import rules, and validation checks thoroughly. It does not explain what the tool returns, how ownership is enforced, or what happens when republishing over an existing app id, which are meaningful gaps for a destructive write operation.
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 meaning beyond the schema: it specifies that html must be a complete self-contained document derived from the model's view prompt, that root-relative /lib/ imports are allowed, and that checks reject empty, oversized, or off-origin content. This helps an agent construct the html parameter correctly.
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 states a specific verb and resource: 'Publish the generated application for a model you own' and defines the artifact as the single-file HTML produced from the model's view prompt. It does not, however, distinguish this tool from sibling publish tools like sim_publish or sim_publish_compare, so an agent cannot route between them from the description alone.
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?
Clear context is provided: the tool applies to a model you own and to HTML generated from that model's view prompt, with detailed runtime and template guidance. It stops short of explicitly comparing this tool to sibling alternatives such as sim_publish or sim_publish_compare, and it gives no exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_publish_compareADestructiveInspect
Publish a multi-scenario comparison into the signed-in user's Google Sheets — sim_compare's export, the counterpart of sim_publish for a single scenario. Runs every scenario on one shared seed (the same server-enforced sharing sim_compare uses, so differences are the scenarios and not the dice) and writes a comparison table plus a trajectory chart, rather than one scenario's own data tabs. Returns the sheet URL. Counts against the same daily publish quota as sim_publish, and costs 1 token per scenario from your account's compute bucket.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| scenarios | Yes | JSON array of scenarios, each with a name, e.g. [{"name":"today","hours":8},{"name":"one more","hours":8,"marking":{"staff/available":3}}]; sim_compare's defaults (hours 8 and realizations 16 per scenario, seed 20260809) fill whatever is omitted |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations by disclosing that all scenarios run on one shared server-enforced seed, what gets written (comparison table plus trajectory chart rather than per-scenario data tabs), the return value (sheet URL), a rate constraint (same daily publish quota as sim_publish), and a cost model (1 token per scenario from the compute bucket). Annotations only mark it as a non-idempotent, open-world write; the description supplies the operational details an agent needs.
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?
Three sentences, each carrying distinct payload: what it produces, how it runs scenarios, and its quota/cost constraints. Front-loaded with the primary action and zero 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 two-parameter publishing tool with no output schema, the description covers output form (sheet URL), side effects (comparison table + chart), quota and token cost, and seed-sharing semantics. Nothing an agent needs to invoke 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% (baseline 3), and the description adds interpretive meaning the schema does not: that the scenarios array is evaluated against one shared seed so differences reflect scenarios rather than random draws, and that sim_compare defaults backfill anything omitted. That context changes how an agent should construct the scenarios parameter.
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 (Publish) and resource (multi-scenario comparison into Google Sheets) and explicitly positions itself relative to two siblings: it is 'sim_compare's export' and 'the counterpart of sim_publish for a single scenario'. An agent can distinguish it from sim_compare and sim_publish 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?
Gives clear routing context by naming sim_compare (whose output this exports) and sim_publish (single-scenario alternative), which tells the agent when this tool is the right pick. It stops short of an explicit 'do not use this when…' exclusion, so it is strong but not fully specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_queryADestructiveInspect
Answer a question over the edge graph between stored models: bounded paths, closure over transitive predicates, and conjunctive patterns of up to 4 triples joined on shared ?variables. The query argument is JSON: {"select": ["?m"], "where": [{"subject": "?m", "predicate": "subnetOf", "object": "", "mode": "closure"}, {"subject": "?m", "predicate": "@type", "object": "QueueingSystem"}]}; a term starting with ? is a variable, anything else a constant (a 24-hex content id, or for @type's object a model kind). Modes: edge (default; one stored edge, read through the registry: narrower is read as broader turned round, symmetric predicates match either way round), path (1..maxHops hops, maxHops 1 to 8 required; a row says reached by a path unless the predicate is transitive), closure (no maxHops; allowed only on the transitive predicates broader, isomorphicTo, migratedFrom, narrower, subnetOf, supersededBy). Put the bound term in object to walk backwards. Unregistered (legacy) predicates are one stored edge in their stored direction only, never walked or closed over. A structural edge (isomorphicTo, subnetOf, preservesInvariant, refines) counts only when one of its stored witnesses re-checks valid now; a derived structural fact carries a derivation (the chain of witnesses and the composed map's digest) that sim_check_witness(derivation=…) re-checks, and is never stored; excluded lists the edges not walked and why. Closure runs per predicate (isomorphicTo hops never feed a subnetOf closure). status complete means complete over the eligible edges (and, for path, within maxHops: hopLimitReached names patterns with edges beyond); truncated means a bound was reached, rows is absent and the rows found so far are in partialRows (true, but not all of them). A query with no variables answers yes, no or unknown (a bound stopped it, or a stored row could not be decoded); a no's caveat says how far the search looked (only closure rules out a derived edge, and a path cut at maxHops says so), and no is not a refutation. Pattern numbers in a result (support[].pattern, hopLimitReached, unmatched, truncated.pattern) are 0-based positions in query.normalized.where; refusals number your patterns from 1. Limits: 4 patterns, 8 hops, 200 rows, 10,000 intermediate rows, 1,000,000 work units, 64 models probed, a 256 KiB result, a 16 KiB query; the whole call is bounded by the 55s request limit. Over a limit before running is a refusal naming it; reached while running is truncated, and retrying gives the same answer. Needs sign-in with read scope (opens OAuth the first time). Costs 2 compute tokens per call, cache hits and refusals included. Writes one Query and one Result entity, content-addressed (resolve either at GET /api/lineage/{id}; stored is false, with storedNote saying why, if the write failed or a composed map was refused); a repeated question is served from the cache only while the edges and witnesses it read, and the models it checked, are unchanged. An answer naming models that have since been superseded carries superseded ([{model, successor, current, chainStatus}]); the answer is still right about those versions.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | the query as JSON: {"select": [variables], "where": [{"subject", "predicate", "object", "mode", "maxHops"}]} |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations (readOnlyHint=false, destructiveHint=true, openWorldHint=true, idempotentHint=false) are consistent with a tool that writes Query and Result entities, and the description adds substantial context beyond them: sign-in with read scope, 2 compute-token cost, cache invalidation rules, hard limits, refusal-vs-truncation semantics, and how derived structural facts are never stored. This is far richer behavioral disclosure than the annotations alone provide.
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 in the first sentence, and most sentences carry load-bearing detail. But it is a single monolithic paragraph with no headings or line breaks, cramming query grammar, semantics, limits, auth, cost, and result fields together, which makes it hard to scan and slows an agent parsing 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 and a highly complex tool, the description compensates by explaining result fields (status, partialRows, rows, excluded, superseded, support[].pattern, refusals), the limits that trigger refusal vs truncation, auth/cost, and persistence effects. Nothing essential for correct invocation 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?
Although the schema already nominally covers the single query parameter, its description is a bare JSON sketch; the tool description fully specifies the grammar (?variables vs constants, 24-hex ids, model kinds), modes, maxHops ranges, which predicates allow closure, backwards walking via object, and legacy-predicate behavior. It adds meaning far beyond the schema.
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: 'Answer a question over the edge graph between stored models', immediately qualified by the three query modes (bounded paths, closure, conjunctive patterns). An agent can distinguish this from graph-walking siblings like sim_reach, sim_neighbors, and sim_edges without opening any 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?
Usage is implied by the mode semantics (edge vs path vs closure, and when closure is permitted) and it cross-references sim_check_witness for re-checking derivations. However, it never explicitly says when to choose this tool over siblings such as sim_neighbors, sim_reach, or sim_edges, nor states exclusions. Adequate but with a real routing gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_reachADestructiveInspect
Returns whether the marking to is reachable from the marking from in ONE stored net (a model, or a system that is one net): yes with a firing trace, no with a re-checkable P-invariant (or after an exhaustive search), or unknown with every reason. A sim_compose result is one fused net, so it qualifies; a sim_bind binding or a collection links rates, not tokens, and answers unknown (not-one-net). A system id (sim_create_system) is answered on its one net when one member has every other embedded in it by a witnessed subnetOf or isomorphicTo edge or a chain of edges of one predicate (the answer carries via: an edge and witness per member, or the derivation sim_check_witness(derivation=…) re-checks); otherwise it answers unknown: not-one-net when it holds bindings (they link rates, not tokens) or no member qualifies, system-truncated when its witness bound was reached or the chain search stopped at a bound. On a one-net system, a key in from or to may name a member's place as : (the member's id, or its name when no other member shares it): it is translated into the net place that member's embedding maps it to, the answer's from and to are the translated question, and via.translation lists each key's member, place and net place, which sim_check_witness(reach=…) re-checks against the stored witnesses. Refused, naming the key: a member or place the system does not have, a data place, a key that reads more than one way, a place two valid witnesses of the member's edge map differently, and two keys landing on one net place with different counts; more than 16 other witnesses to compare answers unknown (translation-budget). from is a sparse override on the model's declared initial marking (unset = declared). to constrains only the places it names, each to exactly that count; naming every token place asks for an exact marking. Unknown or data places, negative or fractional counts and counts over the scenario caps (1,000,000 per place, 4,000,000 in total) are refused. Reachability here is untimed: each firing is one atomic step under the shared firing rule (read and inhibitor arcs, capacities, guards decidable from the marking); rates, schedules, delays and stages play no part. Answers: no with a P-invariant y whose weighted sum differs between from and to (when to leaves a place of y free, to alone must already exceed it), valid whatever read arcs, inhibitors, capacities or guards allow, since those only remove firings; no (exhaustive) when every marking reachable from from was searched; yes with a firing trace (shortest among the firings the search makes; reads says when it skipped some); unknown (unknownBecause lists each cause) when neither is found within 100,000 markings or 20,000,000 work units, when a firing would pass 1,000,000 tokens on a place, when a guard fails to evaluate at a reached marking, when a transition whose guard reads action parameters (or does not parse, or whose precondition was lost) was enabled and so left out, when the invariant algebra runs past its 20,000,000-operation budget, is cut short or needs coefficients over 2147483647, or when a found trace would cost the independent checker more than 200,000,000 work units to replay. Unknown is not a no. Every answer (unknown included) is stored: question is the content id of the question as asked (the id, from and to as written, the definition and the budgets), result the id of the answer with what it was computed over (the net, every model, edge and witness via rests on, the predicate registry and system view for a system); a repeated question is served from a per-instance cache with the same bytes, and storedNote says why an answer too large to store (over 262,144 bytes) was not. Public: no sign-in; costs 2 compute tokens (a search plus a store). Re-check a yes or an invariant no with sim_check_witness(reach=), which also re-checks via whole; re-check a stored answer end to end with sim_check_witness(reachResult=) or GET /api/lineage/.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | JSON object of the places to constrain, each to exactly that count, e.g. {"done": 1}. On a system, a key may be <model>:<place> for a member's place, translated into the net's | |
| from | No | JSON object of place -> whole token count overriding the declared initial marking, e.g. {"queue": 3}; unset = the declared marking. On a system, a key may be <model>:<place> for a member's place | |
| system | Yes | content id of one stored model, or of a system (sim_create_system) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and readOnlyHint=false, implying a write operation, which the description confirms by disclosing storage of every answer and a 2 compute token cost. It also discloses refusal conditions, unknown reasons, budget limits, and caching behavior. The destructiveHint is somewhat surprising for a reachability query, but the description clarifies it is a computation that persists results, adding useful context beyond 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 is extremely long, dense, and poorly structured, containing multiple run-on sentences and nested clauses. It front-loads the core purpose but then buries essential details in an overwhelming wall of text that is hard for an agent to parse efficiently.
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 the complexity of reachability analysis, system translation, and multiple answer states, the description is remarkably complete. It covers input semantics, refusal cases, unknown conditions, storage behavior, and re-check paths, leaving no significant gaps for an agent to invoke it 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 coverage is 100%, so the schema already documents all three parameters including the sparse override and system key syntax. The description adds operational context like refusal rules for negative/fractional counts and data places, but doesn't introduce new parameter-level semantics 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?
States a specific verb and resource: returns whether a marking is reachable from another in one stored net, with the three possible outcomes spelled out. It distinguishes itself from sim_compose, sim_bind and sim_create_system by explaining exactly which inputs qualify as one net.
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?
Extensively specifies when this tool applies versus alternatives: a sim_compose result qualifies, a sim_bind binding does not, a collection is not one net, and a system qualifies only under witnessed embedding conditions. It also routes to sim_check_witness for re-checking. The when/when-not guidance is explicit and detailed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_receiptDestructiveInspect
Run a seeded scenario and get back the result PLUS a signed run receipt: an Ed25519 certificate over (model id, scenario, result hash, service revision). Anyone can check it two ways — verify the signature offline against the embedded public key (proves this service reported this result), and POST it to /api/receipts/verify (no auth) to replay the run and confirm the result hash reproduces (proves the run is reproducible, not invented). The current signing key is at GET /api/receipts/key. Reproducibility is the bottom rung of the trust ladder receipts build: play the model, check the anchors, re-run the seed, verify the certificate. The result is the engine's own form, the one POST /api/models/{id}/scenario returns: contended is the unsplit list with each entry's kind (only conserved and bounded are shortages; queue means the work had not arrived, and state that the model was in another phase of its cycle), not sim_scenario's split into contended, waitingForWork and neverFired, because the result hash covers the result exactly as returned. Costs 1 token from your account's compute bucket.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id to run | |
| scenario | No | scenario JSON (hours, samples, seed, marking, rates, schedule, summary — the same shape sim_scenario takes); sim_scenario's defaults (hours 8, realizations 16, seed 20260809) fill whatever is omitted, and the receipt's scenario records the filled-in values so its replay reproduces this run. The result hash covers the result as returned, so a summary: true scenario certifies the summarized form and replays to it |
sim_refineADestructiveInspect
Refine a model's parameter classes by editing what the model SAYS (tags on a place or transition, or assertedClasses), then re-derive. Returns a NEW model id (ids are content addresses, so the original stays reachable) plus a before/after class diff. tags can only split classes; assertedClasses declares a merge and gets re-verified and costed, never trusted blind. Read the sim://docs/classification resource once for why the two levers are not symmetric. Costs 2 tokens from your account's compute bucket (the stored model, 1, and the verified re-classification, 1).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id to refine | |
| tags | No | JSON object of place OR transition id -> {key: value}, e.g. {"nurse_avail":{"refine.shift":"night"}}. Keys not prefixed refine. are stored as metadata and refine nothing. classify.go's colour refinement seeds from both places' and transitions' tags, so either kind of id works here. | |
| signer | No | optional {"type":"eth"|"ed25519","address":"..."} — signs the lineage claim so it is the refiner's word rather than the server's account of a session | |
| signature | No | optional hex signature over the CID of the signed claim; see modelstore.SignedClaim for the exact bytes. An unverifiable signature is refused, not stored with a flag. | |
| assertedClasses | No | JSON array, e.g. [{"id":"items","members":["item0","item1"],"note":"one stocking decision"}] |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as non-read-only, destructive, non-idempotent, and open-world. The description adds substantial value beyond that: it explains that the original model remains reachable because ids are content addresses, that the result includes a before/after class diff, that assertedClasses are re-verified and costed rather than trusted blind, and that the call costs 2 compute tokens.
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 front-loaded with the core action and return value, then moves to the tag/assertedClasses distinction, the resource hint, and the token cost. Every sentence carries decision-relevant information, and the dense but organized phrasing suits a complex tool.
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, but the description explains the return value (new model id and before/after class diff). Together with annotations covering safety and cost disclosure, the description provides enough context for this multi-parameter refinement 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 coverage is 100%, so the schema already documents each parameter in detail. The description still adds conceptual meaning by distinguishing that tags can only split classes while assertedClasses declares a merge and is re-verified and costed, which helps an agent choose between the two levers.
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 states a specific verb and resource: refining a model's parameter classes by editing tags or assertedClasses, then re-deriving. It also names the return value, a new model id plus before/after class diff, making it easy to distinguish from sibling tools like sim_classify or sim_create_model.
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 two refinement levers and their different behaviors (tags split, assertedClasses merge and are re-verified), which gives clear context for how to use the tool. However, it does not explicitly name alternative tools or state when not to use this one, so it falls short of full when/when-not/alternatives guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_rerollDestructiveInspect
Re-run a stored sim_prompt against the SAME parent it originally ran against — a sibling attempt, never a chain: it never derives from the previous attempt's output, only from the original parent, so rerolling ten times leaves ten independent siblings in lineage rather than a chain of ten. Reuses the original prompt's text and system unless you override them here; a prompt with no requestTemplate (stored before sim_prompt said a stored prompt is readable by anyone with its id) has them withheld from every read, so only its author (its lineage's wasAttributedTo) may reroll it reusing them, and anyone else passes text, and system when it has one, of their own. The parent rides along as sim_prompt sends it, withheld fields left out unless you are its author. The original prompt and its result are left untouched; this stores a new prompt and a new result (model or artifact, same rule as sim_prompt) under Activity sim_reroll, and returns the same fields sim_prompt does: a model's warnings, an artifact's content inline, and modelErrors when the reply was model JSON that failed. When called with neither override and the deployment's LLM provider and model are unchanged since the original ran, the response carries a reproducibility field. If the request template (the instruction and settings sim_prompt sends; a prompt's requestTemplate) is unchanged too, it is checked against every prior result this exact prompt has ever produced (via the same forward "produced" relation sim_edges/sim_neighbors can query directly): "verified" if this result content-matches one of them, "diverged" if it doesn't, "not verified" if there's no prior result on record yet. If the template changed since the original ran, it is "not comparable", and the run is stored under a new promptId. Needs sign-in (opens OAuth the first time). Refused if this deployment has no LLM provider configured. The new prompt is readable as sim_prompt's is: without sign-in, by anyone with its id or a result's.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | override the original prompt's text; default reuses it verbatim | |
| prompt | Yes | id of the sim_prompt (or earlier sim_reroll) to re-run | |
| system | No | override the original prompt's system text; default reuses it verbatim |
sim_run_pipelineDestructiveInspect
Returns one scenario result per model that a set of stored Bindings (see sim_bind) touches, run as a composed pipeline (each result's contention split into contended, waitingForWork and neverFired exactly as sim_scenario's is), with the assumptions the composition makes, inTransit (per delayed binding, the source's flow its delay carried past the horizon) and, when the set holds a loop, the loop's reading (loop, pipeline-loop-v1: verdict, claim, components with sweepsNeeded and sweepsRun, sweepsRun, residual). Costs 1 compute token per model run, charged up front, before any model is read, for the most runs the set can take — one per model outside a loop, and a loop's models times the most sweeps it can take — and not refunded when a loop settles in fewer. Defaults: hours 8, seed 1, realizations 0 (one SSA trajectory per model; set it, e.g. 16 as sim_scenario does, since bindings and loops couple means). Caps: hours up to 10000, realizations up to 200, as sim_scenario. Each model runs through its own ordinary scenario in topological order, an output port's trajectory resampled into the target's input-transition schedule, one seed and horizon shared by every model (the discipline sim_compare enforces within one model). A declared conversion is applied exactly as declared: the resampled rate is multiplied by any numeric transform, then by the convert factor. A binding with a delay drives its target that many hours later; before then the target runs on its own declared rate. A loop between models runs only when some binding on it declares a delay. It is solved by sweeps, each running every member once with one delayed binding (cut) driven by the previous sweep, until a sweep reproduces the previous one's schedules bit for bit: verdict fixed-point, whose claim (also assumptions' first line) is that this is the unique fixed point of the coupling over 0 to hours at the seed, followed by its four limits — each model was driven by the other's mean across realizations (mean-field: for joint dynamics build one net with sim_extend), each delay is declared, not measured, before its delay a target ran on its declared rate, and nothing is claimed past the horizon (a fixed point can be a loop that grows; read the series). Verdict stopped means a run hit the step budget or token cap (from sweep 2 on, typically a loop whose gain is above 1, which grows every sweep; in sweep 1, before any feedback has gone round the loop, the model itself at these hours and realizations) and not-settled is a defect to report; neither carries steps, and models after the loop are not run. Refused before anything is charged or read, each refusal naming the value and the bound: more than 64 binding ids; realizations or hours out of range (the text sim_scenario gives); and the set-level refusals, whose tool error starts with its code — a loop with no delayed binding (closes-loop), two bindings into one input (port-taken), more than one binding into a model (segment-cap: each becomes a schedule of up to 61 segments, and a scenario holds at most 100), a loop of more than 4 models (loop-too-large), a loop whose total delay does not exceed one resample interval (hours/60) per binding (loop-lag), one needing more than 24 sweeps (loop-horizon), loops needing more than 48 model runs together (run-cap); loop-lag and loop-horizon name the delay that would run at these hours and the most hours that run at this delay, and sim_system's view of a system holding the loop reports that most as maxHours. Refused after the charge (which pays for reading the models) and before anything runs: any binding that fails the check sim_bind applies (binds-port-v1; v2 for a unit conversion; v3 for a delay; a binding recorded before a check may be refused here by the same text), and a delayed binding whose target declares so many schedule segments before the delay ends that its schedule would pass the cap at these hours (segment-cap, code first as above). Every result names its seams: no model's own fitness gates cover the join, one unit line per binding (units agree; converted, naming the factor; or unchecked where a port declares no port.unit), and that a binding couples means: a driven model ran on its source's mean, so its std_dev is its own spread given that mean, not the joint system's. A driven model's resampled schedule keeps one random stream per realization across its segments, so splitting a run into segments adds nothing where no rate changes; the resampling itself is a piecewise-constant approximation of the source's mean, which smooths anything shorter than one resample window (hours/60). Public: no sign-in; writes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | shared seed across every model's run (default 1) | |
| hours | No | horizon in hours, shared across every model in the pipeline (default 8) | |
| bindingIds | Yes | JSON array of binding ids to run together, e.g. ["id1","id2"] — every model these bindings touch is included automatically. | |
| realizations | No | realizations per model (default 0, which the engine runs as a single realization — one SSA trajectory per model, so set it, e.g. 16 as sim_scenario defaults to, when the resampled series should be a mean rather than one draw; max 200) |
sim_scenarioDestructiveInspect
Run a seeded what-if scenario against a stored model: marking overrides, rate overrides, piecewise rate schedules, and params assignments to the model's declared structural parameters (arc weights, capacities — batch sizes and shelf sizes). Pure read — asking cannot change the model. Returns trajectory, final marking, metrics, depleted, contended, waitingForWork, neverFired (all three described below), caveats and assumptions. "samples" (default 60) is the trajectory's resolution: the number of evenly spaced points from 0 to hours inclusive at which times and every place's series (mean and std_dev per point) are reported — it sizes the answer, not the run, since metrics (throughput, mean, p95, utilization, inFlight) are time-weighted over every firing and do not change with the grid. "summary": true omits the times and series arrays entirely (the keys are absent, not null) and returns just final, finalStdDev, metrics, depleted, contended, waitingForWork, neverFired, caveats and assumptions — the verdict without the chart data, and the right form when nothing will be plotted. finalStdDev, summarized or not, is each place's spread across realizations at the horizon beside final's mean (absent at one realization and on the ode engine). Transitions declaring stages (phase-type durations) run with the declared lower spread — the engine expands them structurally and reports in the model's own vocabulary. A model-declared schedule (the day shape on a transition) is honored by every run; the scenario's own schedule or rate override still wins for that transition. "engine" picks the reading: "ssa" (default, discrete Gillespie — the right choice whenever counts are small enough that variance is the answer, or a schedule is in play) or "ode" (continuous mass-action; refuses a schedule, and refuses outright rather than silently misread a model carrying a read arc, inhibitor, reached capacity, guard or non-kinetic arc — Forecast's caveats name which). See docs/engine-selection.md for the full decision rule, including why an arc weight above 1 gets a genuinely different rate law from each engine, and sim_crosscheck to run both readings side by side. Contention arrives split three ways. contended holds only what the run was short of, something an operator could buy more of: kind conserved (a fixed pool such as staff) or bounded (a shelf with a declared capacity), each entry with fraction (the share of the run, across every realization, in which that place was the only input missing for the transitions under blocking), longest wait first. waitingForWork holds the engine's other entries in the same shape, and neither of its kinds is a shortage: queue (filled only by the model's own flow, such as waiting customers or work in service) means the work had not arrived, a statement about demand; state (a marker of which phase of a cycle the model is in, such as a stoplight's colour) means the model was in another phase. neverFired is one note per entry whose place never held a token in any run and whose transitions never fired, e.g. "work" never fired in any run: its input "q" never held a token. A queue or state entry like that appears only as its note; a conserved or bounded one keeps its contended row as well, since the run was short of it. The run cannot tell why a place stayed empty. Either it starts empty and nothing fills it (check its initial count and what produces it), or its producer was switched off (a rate of 0, or a scenario marking of 0 on it or upstream of it), or what fills it is rarer than this run's hours and realizations can sample (raise either; once the place fills, the note goes). sim_receipt and the HTTP scenario routes return the engine's unsplit contended list instead, each entry with its kind.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| scenario | No | scenario JSON, e.g. {"hours":8,"samples":60,"realizations":16,"seed":7,"marking":{"staff/available":3},"params":{"batch_size":6},"schedule":{"arrive":[{"until":2,"value":12},{"until":8,"value":4}]},"engine":"ssa","summary":false}; hours defaults to 8, samples to 60, realizations to 16, seed to 20260809, summary to false (full trajectory); hours above 10000, realizations above 200 or samples above 5000 are refused |
sim_supersede_modelADestructiveInspect
Mark an old version of your model as replaced by a newer one. The old id keeps working and its commons dedication (if any) stands — only the listing moves on to the successor. Both models must be yours. It also records a supersededBy edge (old → new), so sim_edges(old) and sim_neighbors(old, "supersededBy") show that the supersession happened. Re-pointing an old model to a different successor keeps the earlier edge too, and these edges carry no timestamp, so their order says nothing about which came last: the current successor is the current this tool returns (the model's own supersededBy record), not the edge list. Taxonomic edges on the old model are offered for migration to the current successor (sim_migration_offers, accepted with sim_accept_migration), never moved; structural and tool-written edges stay with it.
| Name | Required | Description | Default |
|---|---|---|---|
| new | Yes | model id of the successor | |
| old | Yes | model id being replaced |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already flagging a destructive mutation, the description adds substantial behavioral detail the annotations cannot convey: the old id keeps working and its commons dedication stands, only the listing moves; a supersededBy edge is written; re-pointing preserves the earlier edge; edges carry no timestamps so the current successor is the returned `current` record; and taxonomic edges are offered for migration, never moved.
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 sentence and every sentence carries real information. It is dense and the edge-ordering sentence is somewhat convoluted, but there is little outright waste for a tool with this much behavior to disclose.
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 mutation tool with no output schema, the description covers the mutation's effect, ownership requirements, edge side effects, the return value (the `current` supersededBy record), and how related edge migration works. Nothing an agent needs to invoke 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% and both parameters are documented in the schema, so the baseline is 3. The description adds meaning beyond that by clarifying the ownership constraint ('Both models must be yours') and the semantic role of each id (old keeps working, new is the successor), which the schema alone doesn't state.
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: 'Mark an old version of your model as replaced by a newer one.' It is immediately distinguishable from siblings like sim_delete_model, sim_create_model, and sim_accept_migration because it defines the supersession relationship rather than deletion or creation.
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 clear preconditions ('Both models must be yours') and routes related operations to siblings: sim_migration_offers and sim_accept_migration for taxonomic edges, sim_edges/sim_neighbors for inspecting the recorded edge. It doesn't explicitly say when to choose this over an alternative, but the context is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_systemBDestructiveInspect
Returns a stored System's view ({id}), the models whose ports can bind to one declared port ({model, port, direction?, among?}), or the stored systems that name a model or a binding ({naming}); one form per call. {id}: the system's view, computed now and never stored (system-view-v2): each model (present, superseded), each binding with its binds-port check (v1, or v2 with its convert when it declares a unit conversion, or v3 with its delay when it declares one) and whether the set runs as a pipeline (with its loops and maxHours when it holds one), the isomorphicTo/subnetOf edges among the models with up to 128 witnesses re-checked (past that the view is truncated and the rest read unchecked), and the shape — one-net when one member has every other embedded in it by a direct witnessed edge or a chain of edges of one predicate through any stored model, every hop's witness and the composed map re-checked (net, embeddings: a direct one names edge and witness, a chained one its derivation, which sim_check_witness(derivation=…) re-checks; closure says what the chain search cost; sim_reach then answers on that net), pipeline when it holds bindings (they link rates, not tokens: sim_reach answers unknown), separate otherwise (notOneNet says why; a chain mixing subnetOf and isomorphicTo hops does not count), unknown when the witness bound was reached before any member qualified, or the chain search stopped at its hop, model or work bound (closure-incomplete: not a no). {model, port, direction?, among?}: what can bind to that declared port — every model with a port sim_bind would accept against it without a unit conversion (opposite direction, equal kind, units agreeing where both declare one), ranked units-agree first, then model id and port; each row carries the sim_bind arguments. A port whose declared unit differs is counted under excluded as unit-differs, not listed: it binds only through sim_bind with convertFrom, convertTo and convertFactor (binds-port-v2), and an empty answer means none binds without one. The universe is the visible catalog, or among (a collection's model members, at most 256, or a system's models, where a candidate that would take a bound port or close a loop of undelayed bindings is counted under excluded, never listed, and one that closes a loop already holding a delayed binding is listed with closesLoop: bindable-v3). Every model in the universe is searched (bindable-v2; bindable-v3 among a system), through a port index that keeps each model's ports by direction and kind, read once per content id and synced from the listing on every call (a model another instance stored is searched on the next call). At most 256 models the index does not hold yet are read per call (past it status is truncated with bound fetches and unscanned says how many were left; ask again and it continues), 100000 candidate ports checked and 50 rows listed: past any bound status is truncated, and if a member model cannot be read status is incomplete (listed under unreadable); in both cases the rows are in partialRows. candidates, scanned, unscanned, fromIndex, read and portChecks say exactly how far it searched; the index holds at most 16777216 bytes of ports (of which at most 2097152 for models no catalog-wide search has listed, such as an among search's or the asked model's) and at most 65536 bytes for one model, and a model past any of these is searched but not kept (notKept). The call's token covers its first 64 reads; each further 64 cost one more token, charged before they are read, and when the bucket cannot cover them status is truncated with bound rate. {naming}: every stored system whose models or bindings include that id (as: model or binding), sorted by system id, from an index synced from the store's listing on every call (a system another instance stored is seen on the next read). At most 100 systems listed (past it status is truncated, total says how many) and at most 256 not-yet-read systems fetched per call (past it status is incomplete and unindexed says how many are unread; ask again and it continues); the index holds at most 33554432 bytes of systems, and once full nothing more is indexed on that instance (status incomplete, unindexed says how many, and asking again does not change it); a stored system that cannot be decoded also keeps status incomplete (listed under unreadable), and asking again does not clear it; in every case the rows are in partialSystems. A system cannot be named (systems do not nest) and a collection is refused, naming the remedy; an id no entity holds any more (a deleted model) is answered when a system still names it. Systems are linkable and collectable: sim_link puts one in a collection (hasMember) and relates it with cites, about, broader and related. This is not refines: a system's edges are isomorphicTo and subnetOf (embeds by wiring / is the same coloured net). refines (trace inclusion with transitions matched by id) and preservesInvariant (the object's P-invariants pull back along an embedding) are proved one pair at a time by sim_prove and are never walked by closure, since neither is declared transitive. For "what contains this pattern?" ask sim_query with closure: {"select":["?m"],"where":[{"subject":"","predicate":"subnetOf","object":"?m","mode":"closure"}]} (isomorphicTo for copies; add {"subject":"","predicate":"hasMember","object":"?m"} to scope it), each row carrying a derivation sim_check_witness re-checks; a subnetOf row claims no behaviour inclusion. For "what does this model refine?" ask sim_query for one hop: {"select":["?m"],"where":[{"subject":"","predicate":"refines","object":"?m"}]}, each row an edge sim_prove recorded. A loop between models runs only through a binding that declares a delay (sim_bind delay; ROADMAP.md Phase 12j): a system may hold one, of at most 4 models, and its view lists it under pipeline.loops with pipeline.maxHours, the longest horizon sim_run_pipeline runs it at (0 when no horizon of 0.01 h or more does; pipeline.runnable covers only the checks that do not depend on the hours), where it is solved as an exact fixed point over the horizon (pipeline-loop-v1). A loop with no delayed binding is refused when a system is defined and by sim_run_pipeline, and sim_bind refuses a self-binding. A port search with among a system (bindable-v3) lists a candidate that closes a loop already holding a delayed binding, with that loop's models under closesLoop, and counts one that would close a loop of undelayed bindings under excluded as closes-loop (sim_bind with a delay can close it); a catalog or collection search does not consult stored bindings, so sim_create_system or sim_run_pipeline is where such a loop is refused. Public: no sign-in; costs 1 compute token (a port search, 1 more per 64 models read past its first 64); writes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | a system id from sim_create_system: describe it | |
| port | No | the element id of model's declared port | |
| among | No | a collection (at most 256 members) or system id to search instead of the visible catalog | |
| model | No | a model id: with port, what can bind to that port | |
| naming | No | a model or binding id: list the stored systems that name it | |
| direction | No | "output" or "input", needed only when the element declares both |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description closes with 'Public: no sign-in; costs 1 compute token ... writes nothing', i.e. it presents the tool as a pure read/search with no mutation and zero destructive effect. The annotations declare destructiveHint=true, readOnlyHint=false and idempotentHint=false, which directly contradicts that claim. Per the rubric this is an annotation contradiction.
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?
For a 6-parameter tool this is a massive wall of text with deeply nested parentheticals and version tags (system-view-v2, binds-port-v3, bindable-v3, pipeline-loop-v1). The three forms are listed up front, which helps, but the volume is wildly disproportionate and most sentences are not skimmable.
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 carries the return-shape burden and does so exhaustively: view fields (models, bindings, edges, shape), row contents, and failure statuses (truncated, incomplete, unreadable, notKept, partialRows/partialSystems). Combined with token charges and index bounds, an agent has nearly everything needed despite the absence of an output schema.
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 baseline is 3, and the description adds real meaning the schema lacks: 'among (a collection's model members, at most 256, or a system's models)' with its excluded/closesLoop semantics, and direction 'needed only when the element declares both'. It does not add syntax beyond that, so not a 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 first sentence enumerates the three call forms precisely ({id} system view, {model, port, direction?, among?} bindable-port search, {naming} reverse lookup) and repeatedly contrasts itself with siblings like sim_query, sim_reach and sim_bind. That is far more specific than a tautology, but the actual purpose is buried under thousands of words of nested detail, so an agent must excavate it rather than read 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?
It names alternatives explicitly and gives routing conditions: 'For "what contains this pattern?" ask sim_query with closure', the sim_query snippet for refines, and the note that 'This is not refines' and 'sim_reach then answers on that net'. That is genuine when-to-use guidance, though it is scattered rather than front-loaded and there are no clean exclusions up front.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_verifyDestructiveInspect
Verify declared properties of a stored model: a report with one verdict per property, proved, refuted or unknown (unknown is never a pass, and ok is true only when every property is proved), with evidence for a proof and a counterexample for a refutation, plus caveats naming anything the analysis net could not express. Unset properties check bounded and deadlock-free. Every check starts from the model's own initial marking. Each verdict's method says how far it reaches. structural: from the incidence matrix, with no state search. A structural bounded holds for every initial marking (every place is covered by a P-invariant), and so does a structural conserves (the token total is a P-invariant). A structural invariant or mutual-exclusion verdict rests on a P-invariant's value at this initial marking (its evidence names the P-invariant and the value), so it holds from this marking and from any other that gives that P-invariant the same value, not from every marking: two workers sharing one lock token are proved mutually exclusive, and the same net with two lock tokens is refuted. exhaustive: every state reachable from this initial marking. witness: a firing sequence found by targeted search, decisive for this initial marking (a cycle that grows a place without bound). partial: the search was truncated, so only a refutation is sound. To ask about another starting marking, store the model with that marking (sim_extend's set_initial) and verify it. Read the Verification properties section of sim://docs/authoring for each kind's fields. Free (no compute token); writes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | model id | |
| properties | No | JSON array of properties, each a kind plus the fields that kind reads: deadlock-free, bounded, live, terminating and conserves read none; reachable and unreachable read target (place → token count; places it leaves out are unconstrained); invariant reads expr (a linear relation over place ids, "a + 2*b <= 10"); mutual-exclusion reads places and bound (the token counts of places sum to at most bound at every reachable marking, default 1; for places that each hold at most one token, at most bound of them are marked at once). Any property may carry a name. E.g. [{"kind":"deadlock-free"},{"kind":"mutual-exclusion","places":["win_x","win_o"]},{"kind":"invariant","expr":"a + 2*b == 10"}]. Unset checks bounded and deadlock-free. An unknown kind or field, a field the kind does not read, a missing one, a negative target count, a bound of 0 or less, or a place named twice in places (the counts are summed, so a repeat would count that place twice) is refused with every reason at once, each with the likely meaning; a field sent as null is left out. A place id in places, target or expr that the model does not have is refused too, naming it with the place id it most likely meant, and so is a data place, which holds a value rather than a count; either is refused rather than answered unknown. |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
- Changed
sim_check_witness3 fields changed- changed
Input schema / properties / derivation / descriptionPrevious value: -"a sim_query derivation as a JSON string: {\"predicate\", \"definition\", \"subject\", \"object\", \"steps\": [{\"edge\", \"witness\", \"inverse\"}], \"composed\"}"New value: +"a sim_query derivation (JSON, as an object or a string holding one): {\"predicate\", \"definition\", \"subject\", \"object\", \"steps\": [{\"edge\", \"witness\", \"inverse\"}], \"composed\"}" - changed
Input schema / properties / reach / descriptionPrevious value: -"a sim_reach answer as a JSON string: the object exactly as returned, serialized"New value: +"a sim_reach answer, the object exactly as returned (or that object serialized as a string)" - changed
Input schema / properties / refutation / descriptionPrevious value: -"a refuted sim_prove answer's refutation as a JSON string: the object exactly as returned, serialized ({\"predicate\", \"subject\", \"object\", \"counterexample\"})"New value: +"a refuted sim_prove answer's refutation, the object exactly as returned (or that object serialized as a string): {\"predicate\", \"subject\", \"object\", \"counterexample\"}"
- Changed
sim_code_to_flow1 field changed- changed
Input schema / properties / name / descriptionPrevious value: -"name for the derived model"New value: +"name for the derived model; the LLM is asked to use it, and it is filled in, before any check, when the model comes back without one"
- Changed
sim_conformance_stream1 field changed- changed
Input schema / properties / repairDepth / descriptionPrevious value: -"most unobserved transitions a repair may use (default 4; negative turns repair off)"New value: +"most unobserved transitions a repair may use (default 4, at most 64; negative turns repair off)"
- Changed
sim_create_model1 field changed- changed
Input schema / properties / model / descriptionPrevious value: -"the model JSON"New value: +"the model JSON: name, places, transitions, arcs (sim://docs/authoring has the fields and a worked example)"
- Changed
sim_diagnose1 field changed- added
Input schema / properties / verboseAdded value: +{ + "description": "default false: a structural reading that does not apply (ctmcLumping, constrainedLumping, or siphons when its search did not finish) keeps applicable: false and one refusals line, \"not applicable: <reason>\", without its fixed scope text. true returns every refusal and scope in full. Changes no measurement and costs nothing extra.", + "type": "boolean" +}
- Added
sim_get_artifact - Changed
sim_list_models1 field changed- added
Input schema / propertiesAdded value: +{ + "query": { + "description": "whitespace-separated terms; lists only the models whose name, description or id contains every term, case-insensitively (each term may match a different field). The description searched is the one listed: its first line, at most 200 bytes. At most 256 bytes; longer is refused. Unset matches everything.", + "type": "string" + }, + "scope": { + "description": "which group to list: \"curated\" (the catalog this server seeds, the worked examples), \"commons\" (models dedicated to the commons, none of them curated) or \"mine\" (the models you own, dedicated or not; needs sign-in). Unset lists all three; any other value is refused.", + "enum": [ + "curated", + "commons", + "mine" + ], + "type": "string" + } +}
- Changed
sim_prompt2 fields changed- changed
Input schema / properties / system / descriptionPrevious value: -"optional system-level instructions, in addition to the parent context this tool always supplies"New value: +"optional system-level instructions, in addition to the parent context this tool always supplies; stored with the prompt, and readable by anyone with its id or a result's" - changed
Input schema / properties / text / descriptionPrevious value: -"the natural-language instruction"New value: +"the natural-language instruction; stored with the prompt, and readable by anyone with its id or a result's"
- Changed
sim_verify1 field changed- changed
Input schema / properties / properties / descriptionPrevious value: -"JSON array of properties, e.g. [{\"kind\":\"deadlock-free\"},{\"kind\":\"mutual-exclusion\",\"places\":[\"win_x\",\"win_o\"]},{\"kind\":\"invariant\",\"expr\":\"a + 2*b == 10\"}]. Default: bounded + deadlock-free."New value: +"JSON array of properties, each a kind plus the fields that kind reads: deadlock-free, bounded, live, terminating and conserves read none; reachable and unreachable read target (place → token count; places it leaves out are unconstrained); invariant reads expr (a linear relation over place ids, \"a + 2*b <= 10\"); mutual-exclusion reads places and bound (the token counts of places sum to at most bound at every reachable marking, default 1; for places that each hold at most one token, at most bound of them are marked at once). Any property may carry a name. E.g. [{\"kind\":\"deadlock-free\"},{\"kind\":\"mutual-exclusion\",\"places\":[\"win_x\",\"win_o\"]},{\"kind\":\"invariant\",\"expr\":\"a + 2*b == 10\"}]. Unset checks bounded and deadlock-free. An unknown kind or field, a field the kind does not read, a missing one, a negative target count, a bound of 0 or less, or a place named twice in places (the counts are summed, so a repeat would count that place twice) is refused with every reason at once, each with the likely meaning; a field sent as null is left out. A place id in places, target or expr that the model does not have is refused too, naming it with the place id it most likely meant, and so is a data place, which holds a value rather than a count; either is refused rather than answered unknown."
1 tool update
- Added
sim_conformance_stream
1 tool update
- Changed
sim_bind1 field changed- added
Input schema / properties / delayAdded value: +{ + "description": "hours after the source's flow that toPort receives it, in (0, 10000]; default unset, no delay. Before the delay ends toPort runs on its own declared rate. A loop between models runs only through a binding with a delay (binds-port-v3)", + "type": "number" +}
3 tool updates
- Changed
sim_check_witness4 fields changed- changed
Input schema / properties / derivation / descriptionPrevious value: -"a sim_query derivation as JSON: {\"predicate\", \"definition\", \"subject\", \"object\", \"steps\": [{\"edge\", \"witness\", \"inverse\"}], \"composed\"}"New value: +"a sim_query derivation as a JSON string: {\"predicate\", \"definition\", \"subject\", \"object\", \"steps\": [{\"edge\", \"witness\", \"inverse\"}], \"composed\"}" - changed
Input schema / properties / reach / descriptionPrevious value: -"a sim_reach answer as JSON, exactly as returned"New value: +"a sim_reach answer as a JSON string: the object exactly as returned, serialized" - added
Input schema / properties / reachResultAdded value: +{ + "description": "the content id of a stored sim_reach answer (sim_reach's result)", + "type": "string" +} - added
Input schema / properties / refutationAdded value: +{ + "description": "a refuted sim_prove answer's refutation as a JSON string: the object exactly as returned, serialized ({\"predicate\", \"subject\", \"object\", \"counterexample\"})", + "type": "string" +}
- Changed
sim_prove2 fields changed- changed
Input schema / properties / predicate / descriptionPrevious value: -"isomorphicTo or subnetOf"New value: +"isomorphicTo, subnetOf, preservesInvariant or refines" - added
Input schema / properties / viaAdded value: +{ + "description": "promote a fact sim_query derived instead of searching (JSON, as a string or an object): {\"derivation\": <a row's support[].derivation>} or {\"result\": \"<sim_query result id>\", \"row\": n, \"support\": k} (support only when the row carries more than one derivation; 0-based). The derivation must name exactly this subject, predicate and object (either order for isomorphicTo)", + "type": "string" +}
- Changed
sim_reach2 fields changed- changed
Input schema / properties / from / descriptionPrevious value: -"JSON object of place -> whole token count overriding the declared initial marking, e.g. {\"queue\": 3}; unset = the declared marking"New value: +"JSON object of place -> whole token count overriding the declared initial marking, e.g. {\"queue\": 3}; unset = the declared marking. On a system, a key may be <model>:<place> for a member's place" - changed
Input schema / properties / to / descriptionPrevious value: -"JSON object of the places to constrain, each to exactly that count, e.g. {\"done\": 1}"New value: +"JSON object of the places to constrain, each to exactly that count, e.g. {\"done\": 1}. On a system, a key may be <model>:<place> for a member's place, translated into the net's"
2 tool updates
- Changed
sim_bind3 fields changed- added
Input schema / properties / convertFactorAdded value: +{ + "description": "how many convertTo one convertFrom is (1 convertFrom = convertFactor convertTo), between 1e-06 and 1000000; sim_run_pipeline multiplies the resampled rate by it, after any numeric transform", + "type": "number" +} - added
Input schema / properties / convertFromAdded value: +{ + "description": "a declared unit conversion's source unit: exactly fromPort's port.unit. Pass convertFrom, convertTo and convertFactor together or none of them", + "type": "string" +} - added
Input schema / properties / convertToAdded value: +{ + "description": "a declared unit conversion's target unit: exactly toPort's port.unit, which must differ from fromPort's", + "type": "string" +}
- Changed
sim_system1 field changed- added
Input schema / properties / namingAdded value: +{ + "description": "a model or binding id: list the stored systems that name it", + "type": "string" +}
4 tool updates
- Changed
sim_bind3 fields changed- changed
Input schema / properties / fromPort / descriptionPrevious value: -"element id of the declared output port on fromModel (see GET /api/models/{id}/ports)"New value: +"element id of the declared output port on fromModel: a token place tagged port.output (see GET /api/models/{id}/ports)" - changed
Input schema / properties / toPort / descriptionPrevious value: -"element id of the declared input port on toModel"New value: +"element id of the declared input port on toModel: a rated transition tagged port.input" - changed
Input schema / properties / transform / descriptionPrevious value: -"how fromPort's value becomes toPort's. A plain non-negative number is applied by sim_run_pipeline as a scale factor on the resampled rate; any other text (a unit note, a resample window, an aggregation) is recorded, reported by sim_run_pipeline as an assumption, and treated as 1:1"New value: +"how fromPort's value becomes toPort's. A plain non-negative number is applied by sim_run_pipeline as a scale factor on the resampled rate; it scales, never converts a unit. Any other text (a unit note, a resample window, an aggregation) is recorded, reported by sim_run_pipeline as an assumption, and treated as 1:1"
- Added
sim_create_system - Changed
sim_reach1 field changed- changed
Input schema / properties / system / descriptionPrevious value: -"content id of one stored model (a sim_compose result is one fused net)"New value: +"content id of one stored model, or of a system (sim_create_system)"
- Added
sim_system
2 tool updates
- Added
sim_accept_migration - Added
sim_migration_offers
2 tool updates
- Changed
sim_check_witness1 field changed- added
Input schema / properties / reachAdded value: +{ + "description": "a sim_reach answer as JSON, exactly as returned", + "type": "string" +}
- Added
sim_reach
2 tool updates
- Changed
sim_check_witness2 fields changed- added
Input schema / properties / derivationAdded value: +{ + "description": "a sim_query derivation as JSON: {\"predicate\", \"definition\", \"subject\", \"object\", \"steps\": [{\"edge\", \"witness\", \"inverse\"}], \"composed\"}", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "id" -]
- Added
sim_query
2 tool updates
- Added
sim_check_witness - Added
sim_prove
1 tool update
- Changed
sim_link3 fields changed- changed
Input schema / properties / object / descriptionPrevious value: -"id of the entity the relation points to"New value: +"content id of the stored entity the edge points to; for @type, a type name from https://sim.pflow.xyz/ns/models/v1" - changed
Input schema / properties / predicate / descriptionPrevious value: -"the relationship, e.g. hasMember, cites, supersedes — no fixed vocabulary"New value: +"one of @type, about, broader, cites, closeMatch, hasMember, related" - changed
Input schema / properties / subject / descriptionPrevious value: -"id of the entity the relation starts from"New value: +"content id of the stored entity the edge starts from"
4 tool updates
- Changed
sim_distill1 field changed- changed
Input schema / properties / options / descriptionPrevious value: -"JSON: {\"games\":20,\"positions\":40,\"iters\":40,\"horizon\":3,\"realizations\":40,\"seed\":11,\"engine\":\"\"}"New value: +"JSON: {\"games\":20,\"positions\":40,\"iters\":40,\"horizon\":3,\"realizations\":40,\"seed\":11,\"engine\":\"\"} (the defaults shown; 0 or unset takes the default). Caps: games at most 100, positions at most 100, iters at most 100, realizations at most 200, horizon at most 10000; over a cap, a negative value or an unknown key is refused"
- Changed
sim_optimize3 fields changed- changed
Input schema / properties / hours / descriptionPrevious value: -"horizon per run (default 8)"New value: +"horizon per run (default 8, above 0 and at most 10000)" - changed
Input schema / properties / samples / descriptionPrevious value: -"Monte Carlo samples (default 100, max 1000)"New value: +"Monte Carlo samples (default 100, 1..1000; outside that is refused)" - changed
Input schema / properties / seed / descriptionPrevious value: -"sampling seed (default 42)"New value: +"sampling seed, a whole number (default 42)"
- Changed
sim_param_heatmap3 fields changed- changed
Input schema / properties / hours / descriptionPrevious value: -"horizon per run (default 8)"New value: +"horizon per run (default 8, above 0 and at most 10000)" - changed
Input schema / properties / range_x / descriptionPrevious value: -"JSON [start, stop, n] for param_x"New value: +"JSON [start, stop, n] for param_x: non-negative rates, n a whole number 2..40" - changed
Input schema / properties / range_y / descriptionPrevious value: -"JSON [start, stop, n] for param_y"New value: +"JSON [start, stop, n] for param_y: non-negative rates, n a whole number 2..40"
- Changed
sim_propose_types2 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"maximum number of models to diagnose (default 10, max 25) — a cost control, since this runs a simulation per model"New value: +"maximum number of models to diagnose (default 10, 1..25; over 25 is refused, and so are explicit ids naming more models than limit) — a cost control, since this runs a simulation per model" - changed
Input schema / properties / realizations / descriptionPrevious value: -"realizations per model's Diagnose run (default 8, max 16) — deliberately small, this only needs to name a shape, not measure precise influence"New value: +"realizations per model's Diagnose run (default 8, 1..16; outside that is refused) — deliberately small, this only needs to name a shape, not measure precise influence"
10 tool updates
- Changed
sim_bind1 field changed- changed
Input schema / properties / transform / descriptionPrevious value: -"free-text account of how fromPort's value becomes toPort's — a unit scale, a resample window, an aggregation. Not yet interpreted by anything; recorded for whoever builds the pipeline runner"New value: +"how fromPort's value becomes toPort's. A plain non-negative number is applied by sim_run_pipeline as a scale factor on the resampled rate; any other text (a unit note, a resample window, an aggregation) is recorded, reported by sim_run_pipeline as an assumption, and treated as 1:1"
- Changed
sim_compare1 field changed- changed
Input schema / properties / scenarios / descriptionPrevious value: -"JSON array of scenarios, each with a name, e.g. [{\"name\":\"today\",\"hours\":8},{\"name\":\"one more\",\"hours\":8,\"marking\":{\"staff\":3}},{\"name\":\"bigger batches\",\"hours\":8,\"params\":{\"batch_size\":6}}]"New value: +"JSON array of at most 20 scenarios, each with a name, e.g. [{\"name\":\"today\",\"hours\":8},{\"name\":\"one more\",\"hours\":8,\"marking\":{\"staff/available\":3}},{\"name\":\"bigger batches\",\"hours\":8,\"params\":{\"batch_size\":6}}]; each is held to sim_scenario's caps"
- Changed
sim_crosscheck1 field changed- changed
Input schema / properties / hours / descriptionPrevious value: -"horizon (default 8)"New value: +"horizon (default 8, max 168)"
- Changed
sim_diagnose1 field changed- changed
Input schema / properties / hours / descriptionPrevious value: -"horizon per run (default 8)"New value: +"horizon per run (default 8, max 168)"
- Changed
sim_evaluate2 fields changed- changed
Input schema / properties / horizon / descriptionPrevious value: -"model time to explore ahead (default 3)"New value: +"model time to explore ahead (default 3, max 10000)" - changed
Input schema / properties / realizations / descriptionPrevious value: -"SSA rollouts per elimination (default 40)"New value: +"SSA rollouts per candidate move (default 40, max 200)"
- Changed
sim_publish1 field changed- changed
Input schema / properties / scenario / descriptionPrevious value: -"optional scenario JSON to run for the data tabs"New value: +"optional scenario JSON to run for the data tabs; sim_scenario's defaults (hours 8, realizations 16, seed 20260809) fill whatever is omitted"
- Changed
sim_publish_compare1 field changed- changed
Input schema / properties / scenarios / descriptionPrevious value: -"JSON array of scenarios, each with a name, e.g. [{\"name\":\"today\",\"hours\":8},{\"name\":\"one more\",\"hours\":8,\"marking\":{\"staff\":3}}]"New value: +"JSON array of scenarios, each with a name, e.g. [{\"name\":\"today\",\"hours\":8},{\"name\":\"one more\",\"hours\":8,\"marking\":{\"staff/available\":3}}]; sim_compare's defaults (hours 8 and realizations 16 per scenario, seed 20260809) fill whatever is omitted"
- Changed
sim_receipt1 field changed- changed
Input schema / properties / scenario / descriptionPrevious value: -"scenario JSON (hours, samples, seed, marking, rates, schedule, summary — the same shape sim_scenario takes); defaults apply when omitted. The result hash covers the result as returned, so a summary: true scenario certifies the summarized form and replays to it"New value: +"scenario JSON (hours, samples, seed, marking, rates, schedule, summary — the same shape sim_scenario takes); sim_scenario's defaults (hours 8, realizations 16, seed 20260809) fill whatever is omitted, and the receipt's scenario records the filled-in values so its replay reproduces this run. The result hash covers the result as returned, so a summary: true scenario certifies the summarized form and replays to it"
- Changed
sim_run_pipeline1 field changed- changed
Input schema / properties / realizations / descriptionPrevious value: -"realizations per model (0 leaves each model's own Run to its adaptive default)"New value: +"realizations per model (default 0, which the engine runs as a single realization — one SSA trajectory per model, so set it, e.g. 16 as sim_scenario defaults to, when the resampled series should be a mean rather than one draw; max 200)"
- Changed
sim_scenario1 field changed- changed
Input schema / properties / scenario / descriptionPrevious value: -"scenario JSON, e.g. {\"hours\":8,\"samples\":60,\"realizations\":16,\"seed\":7,\"marking\":{\"staff\":3},\"params\":{\"batch_size\":6},\"schedule\":{\"arrive\":[{\"until\":2,\"value\":12},{\"until\":8,\"value\":4}]},\"engine\":\"ssa\",\"summary\":false}; hours defaults to 8, samples to 60, realizations to 16, summary to false (full trajectory)"New value: +"scenario JSON, e.g. {\"hours\":8,\"samples\":60,\"realizations\":16,\"seed\":7,\"marking\":{\"staff/available\":3},\"params\":{\"batch_size\":6},\"schedule\":{\"arrive\":[{\"until\":2,\"value\":12},{\"until\":8,\"value\":4}]},\"engine\":\"ssa\",\"summary\":false}; hours defaults to 8, samples to 60, realizations to 16, seed to 20260809, summary to false (full trajectory); hours above 10000, realizations above 200 or samples above 5000 are refused"
46 tool updates
- First observed
sim_bind - First observed
sim_calibrate - First observed
sim_canonical - First observed
sim_classify - First observed
sim_code_to_flow - First observed
sim_compare - First observed
sim_components - First observed
sim_compose - First observed
sim_conformance - First observed
sim_create_collection - First observed
sim_create_model - First observed
sim_crosscheck - First observed
sim_dataset - First observed
sim_delete_model - First observed
sim_diagnose - First observed
sim_diff - First observed
sim_distill - First observed
sim_edges - First observed
sim_evaluate - First observed
sim_extend - First observed
sim_get_binding - First observed
sim_get_model - First observed
sim_invariants - First observed
sim_license_model - First observed
sim_link - First observed
sim_list_bindings - First observed
sim_list_models - First observed
sim_map_get - First observed
sim_map_list - First observed
sim_map_put - First observed
sim_my_sheets - First observed
sim_neighbors - First observed
sim_optimize - First observed
sim_param_heatmap - First observed
sim_prompt - First observed
sim_propose_types - First observed
sim_publish - First observed
sim_publish_app - First observed
sim_publish_compare - First observed
sim_receipt - First observed
sim_refine - First observed
sim_reroll - First observed
sim_run_pipeline - First observed
sim_scenario - First observed
sim_supersede_model - First observed
sim_verify
Related MCP Connectors
- OkareoOAuthcom.okareo
Simulation, evaluation and monitoring for voice agents.
Deterministic what-if & scenario simulation for AI agents: projections, sensitivity & break-even.
Decision Support Network helps humans and AI agents discover verified decision-support tools for spe
Deterministic reasoning stack for AI agents: simulate, decide & compute, plus cross-domain tools.
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables natural language conversion of production and queueing systems into Petri net models, with simulation and PNML export via MCP tools.66MIT
- FlicenseNot gradedqualityFmaintenanceEnables AI-driven graphical diagram creation and manipulation using natural language, with support for BPMN workflows, analysis, and manual editing via the Model Context Protocol.1-
- AlicenseCqualityFmaintenance12 deterministic graph-theory tools for structural analysis. Describe systems in EN syntax (subject do: action needs: inputs yields: outputs) — get topology, bottlenecks, blast radius, critical paths and lot more. No AI inside the computation.12166 npm8MIT
- FlicenseNot gradedqualityDmaintenanceExposes a trained Deep Q-Network agent for business process resource allocation, enabling natural language interaction with reinforcement learning models. It provides tools for simulation control, Q-value analysis, and action explainability to make complex decision-making transparent.-
Glama MCP Gateway
Add one secure layer between your agents and this server.