Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
1e0e8ca
feat(analysis): preview tool invocations without starting the process
devin-ai-integration[bot] Sep 25, 2026
a941787
feat(analysis): report the tools a plan's runs reached
devin-ai-integration[bot] Sep 25, 2026
96b1b3b
feat(record): record the tools a run reached
devin-ai-integration[bot] Sep 25, 2026
760d8fc
feat(cli): add -tool-dry-run and %tool
devin-ai-integration[bot] Sep 25, 2026
dd93aa5
feat(examples): add the external-tool demo
devin-ai-integration[bot] Sep 25, 2026
90dc02e
feat(client): show a tool's protocol in the engine listing
devin-ai-integration[bot] Sep 25, 2026
88ebc98
docs(manual): run external programs from a model
devin-ai-integration[bot] Sep 25, 2026
6853c6b
fix(repl): name the action a dry run reached
devin-ai-integration[bot] Sep 25, 2026
cca323b
chore(corpus): record the external-tool demo's round-trip rows
devin-ai-integration[bot] Sep 25, 2026
c43969c
chore(proto): regenerate the TypeScript and Rust stubs
devin-ai-integration[bot] Sep 25, 2026
3ffae32
Merge remote-tracking branch 'origin/feature/tool-reply-formats' into…
devin-ai-integration[bot] Sep 25, 2026
7a32499
Merge remote-tracking branch 'origin/develop' into feature/tool-dry-r…
devin-ai-integration[bot] Sep 25, 2026
09f92de
Merge remote-tracking branch 'origin/develop' into feature/tool-dry-r…
devin-ai-integration[bot] Sep 25, 2026
0dd19f8
fix(analysis): attribute tool provenance to each recorded run and kee…
devin-ai-integration[bot] Sep 25, 2026
dbb81ec
fix(repl): bind the arguments of an action previewed by %tool
devin-ai-integration[bot] Sep 25, 2026
4be8210
fix(repl): release the executor a %tool preview ran
devin-ai-integration[bot] Sep 25, 2026
5e82863
fix(exec): pass a verification case's tool dry run through its error …
devin-ai-integration[bot] Sep 25, 2026
b8ac840
fix(analysis): keep every step's tool provenance in call order
devin-ai-integration[bot] Sep 25, 2026
132a04d
Merge remote-tracking branch 'origin/develop' into feature/tool-dry-r…
devin-ai-integration[bot] Sep 25, 2026
31818d7
Merge branch 'feature/tool-execution-calc' into feature/tool-dry-run-…
devin-ai-integration[bot] Sep 25, 2026
a39f73c
fix(runtime): return the tool call's context directly
devin-ai-integration[bot] Sep 25, 2026
420e107
fix(runtime): bind an action preview's arguments as its invocation does
devin-ai-integration[bot] Sep 25, 2026
1e057e9
fix(analysis): keep the uses a faulted plan's steps carried
devin-ai-integration[bot] Sep 25, 2026
f0172d9
fix(analysis): honor the engine selection in a tool dry run
devin-ai-integration[bot] Sep 25, 2026
6ed1a78
Merge remote-tracking branch 'origin/feature/tool-dry-run-and-demo' i…
devin-ai-integration[bot] Sep 25, 2026
f2ceefb
refactor(analysis): fold a faulted step's use into noteUseLocked
devin-ai-integration[bot] Sep 25, 2026
c4ee0d1
fix(analysis): render a file reply's source in a dry run as argv does
devin-ai-integration[bot] Sep 25, 2026
a4c6593
fix(analysis): record the tool calls a Monte Carlo conclusion makes
devin-ai-integration[bot] Sep 25, 2026
12d34aa
fix(runtime): bind an action preview's named arguments to their redef…
devin-ai-integration[bot] Sep 25, 2026
f171173
fix(analysis): record repeated tool calls as the calls they are
devin-ai-integration[bot] Sep 25, 2026
c886caa
Merge remote-tracking branch 'origin/feature/tool-execution-calc' int…
devin-ai-integration[bot] Sep 25, 2026
8870cfc
fix(analysis): name the file an object reply is read from in a dry run
devin-ai-integration[bot] Sep 25, 2026
b3feb27
fix(analysis): stop a tool dry run at a higher-ranked engine
devin-ai-integration[bot] Sep 25, 2026
ccce574
fix(analysis): never probe an external engine in a tool dry run
devin-ai-integration[bot] Sep 25, 2026
7442094
fix(analysis): keep a tool's own refusal in a dry run
devin-ai-integration[bot] Sep 25, 2026
385b16f
fix(repl): reject a repeated named argument in %tool as an invocation…
devin-ai-integration[bot] Sep 25, 2026
5db646c
fix(repl): leave no trace of a tool dry run in the session
devin-ai-integration[bot] Sep 25, 2026
a7b196e
fix(repl): report a tool preview reached from a condition and refuse …
devin-ai-integration[bot] Sep 25, 2026
b0208c1
fix(repl): keep the session's tool runner across a preview and row to…
devin-ai-integration[bot] Sep 25, 2026
966fe8c
docs(runtime): keep one doc comment on MonteCarloRun.Conclude
devin-ai-integration[bot] Sep 25, 2026
0975f0d
fix(repl): keep row tool provenance when a Monte Carlo sample is not …
devin-ai-integration[bot] Sep 25, 2026
e037b39
Merge remote-tracking branch 'origin/develop' into feature/tool-dry-r…
devin-ai-integration[bot] Sep 26, 2026
391ff89
fix(repl): check any loaded document for declarations in a tool dry run
devin-ai-integration[bot] Sep 26, 2026
16322ed
fix(analysis): keep every tool run's provenance and fail a preview a …
devin-ai-integration[bot] Sep 26, 2026
cd853a9
fix(analysis): preview the manifest tool under all past engines ahead…
devin-ai-integration[bot] Sep 26, 2026
3ede838
fix(analysis): decide an all preview by what the engines ahead of the…
devin-ai-integration[bot] Sep 26, 2026
b0de6fb
fix(analysis): pass external engines ahead of the tool in an all preview
devin-ai-integration[bot] Sep 26, 2026
71d5aff
Merge remote-tracking branch 'origin/develop' into feature/tool-dry-r…
devin-ai-integration[bot] Sep 26, 2026
3638841
fix(repl): run an object's existing performance under %tool as an act…
devin-ai-integration[bot] Sep 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .agents/skills/testing-pilot-corpora-gate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ gate's own helpers are package-private but reusable (`pilotCorporaGate.files(t)`

`actionlint`, `shellcheck`, `python3 scripts/check-doc-links.py`, `gofmt`, `go vet`,
`go run -C tools ./cmd/pilot-diff` (validators pre-downloaded; ~4min, prints e.g.
the headline the committed baseline holds — `379 file(s), 347 fully agreeing; 38 agreed
diagnostic(s), 38 only ours, 1582 only the pilot's` at the `2026-08` pin, so read it from
the headline the committed baseline holds — `380 file(s), 347 fully agreeing; 38 agreed
diagnostic(s), 38 only ours, 1614 only the pilot's` at the `2026-08` pin, so read it from
`docs/project/pilot-differential-baseline.json` rather than from this line)
and `make lint` (staticcheck+gosec, ~2min) all work. There is **no** `yamllint` and **no**
`circleci` CLI, so `.circleci/config.yml` can only be parsed as YAML, not schema-validated — say so
Expand Down
8 changes: 4 additions & 4 deletions .agents/skills/testing-pilot-differential/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ GNU-format diagnostics **relative to `--root`**. Consequences for testing:
- The pin `tools/referee/diff` reports comes from `build/pilot-sysml-validator/pilot-pin.txt`
(written by the new script), not from the DeciSym `pom.xml`.
- `-validator /nonexistent` now says `run ./scripts/download-pilot-sysml-validator.sh`.
- Measured at the `2026-08` pin, with a fresh library cache: `379 file(s), 347 fully agreeing; 38 agreed,
38 only ours, 1582 only the pilot's`, JSON totals `openSysMLDiagnostics 79 / pilotDiagnostics
1623 / severityMismatch 3`; ~2 min wall, byte-identical across runs *and* after a from-scratch
- Measured at the `2026-08` pin, with a fresh library cache: `380 file(s), 347 fully agreeing; 38 agreed,
38 only ours, 1614 only the pilot's`, JSON totals `openSysMLDiagnostics 79 / pilotDiagnostics
1655 / severityMismatch 3`; ~2 min wall, byte-identical across runs *and* after a from-scratch
rebuild of `build/pilot-validator`. The six `kerml-examples` pilot-only rows the `2026-07` run
carried (`The opposite features 'owningType' … do not refer to each other`) are gone: the pilot
fixed its `ownedDisjoining` delegate, and nothing on our side moved. `kerml-examples` carries no `syntax` diagnostic on either
Expand Down Expand Up @@ -137,7 +137,7 @@ The harness compares OpenSysML diagnostics against the OMG SysML v2 Pilot Implem
`build/pilot-diff/pilot-diff.{txt,json}`. `docs/project/pilot-differential-baseline.json` is the
committed result of the *last refreshed* run, so **the harness is testable by reproduction** —
but only while the baseline is current. Check that first. As of the rebaseline that came when the Legend of the Red Dragon example left for its own repository it **is**
current: a live run gives `379 file(s), 347 fully agreeing; 38 agreed, 38 only ours, 1582 only the
current: a live run gives `380 file(s), 347 fully agreeing; 38 agreed, 38 only ours, 1614 only the
pilot's`, byte-identical to the committed baseline, and `docs/project/pilot-differential.md`'s
"Results" table matches. The rebaseline before it, at the architecture self-model's landing, covered two rounds, because the succession-shorthand
removal before it landed without refreshing the baseline; a control run of its merge commit gives
Expand Down
4 changes: 2 additions & 2 deletions .agents/skills/testing-pilot-execution-referee/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ pilot answers the representation's own. See
`pilot-exec-diff: <file>:<line>: model no/such/model.sysml: stat <abs>: no
such file or directory`.
- **Additivity.** `go run -C tools ./cmd/pilot-diff` must still print the headline the
committed baseline holds (`379 file(s), 347 fully agreeing; 38 agreed
diagnostic(s), 38 only ours, 1582 only the pilot's` at the `2026-08` pin — read it from the baseline JSON, not from this line, since each
committed baseline holds (`380 file(s), 347 fully agreeing; 38 agreed
diagnostic(s), 38 only ours, 1614 only the pilot's` at the `2026-08` pin — read it from the baseline JSON, not from this line, since each
fix round moves it) and `jq -S` diff clean against
`docs/project/pilot-differential-baseline.json`; `git status --porcelain`
empty at the end.
Expand Down
4 changes: 2 additions & 2 deletions .agents/skills/testing-pilot-xpect/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ census in `w5c_census_test.go` is live two ways: perturb one pinned triple (e.g.
## Regression neighbour

`go run -C tools ./cmd/pilot-diff` (~1m12s) must still print the headline the *committed* baseline holds —
at the `2026-08` pin that is `379 file(s), 347 fully agreeing; 38 agreed diagnostic(s), 38
only ours, 1582 only the pilot's`. Read the number out of
at the `2026-08` pin that is `380 file(s), 347 fully agreeing; 38 agreed diagnostic(s), 38
only ours, 1614 only the pilot's`. Read the number out of
`docs/project/pilot-differential-baseline.json` rather than trusting this line, since a landing fix
round moves it. When the baseline is itself stale (it was at `19a3ce03`, holding 273 / 281 / 317), a
failing `cmp` against it is *not* evidence of an Xpect regression — compare the summary line, and see
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,11 @@ The project is under active development, with the core infrastructure operationa
<!-- doc-counts:begin refereed-figures -->
**Measured against the pinned reference** (`PILOT_TAG=2026-08`, artifact `0.62.0`). Every number below is generated by `make docs-counts` from the committed baselines and gated; none of them is typed in by hand.

- **Corpus agreement:** 347 of 379 files agree diagnostic-by-diagnostic; 38 diagnostics are ours alone and 1582 the reference's alone, and the first number must be read by root: our diagnostics against the reference's own corpora fell while our non-standard-notation warnings on our own example models rose ([differential](docs/project/pilot-differential.md), `go run -C tools ./cmd/pilot-diff`).
- **Corpus agreement:** 347 of 380 files agree diagnostic-by-diagnostic; 38 diagnostics are ours alone and 1614 the reference's alone, and the first number must be read by root: our diagnostics against the reference's own corpora fell while our non-standard-notation warnings on our own example models rose ([differential](docs/project/pilot-differential.md), `go run -C tools ./cmd/pilot-diff`).
- **Declared-diagnostic silence:** of the 512 declared `errors` rows in the reference's own Xpect suites, we report nothing for 0. 245 we report word-for-word; 248 wording-only and 7 location-only differences are agreement in substance and are not counted as gaps; 0 more we report as a warning and 2 elsewhere in the file ([Xpect oracle](docs/project/pilot-xpect.md), `go run -C tools ./cmd/pilot-xpect`).
- **Scope agreement:** 230 of 230 declared scope assertions match exactly (same source).
- **Permissiveness gaps:** of 306 invalid models we wrote ourselves, the reference rejects 4 that we accept by default, and 293 both reject; 4 further cases agree only when we are asked strictly. We authored every one of these cases ourselves, so the denominator measures the reach of our own corpus and not our conformance; agreement reached only under an opt-in strict mode is weaker evidence than agreement by default ([rejection oracle](docs/project/pilot-rejection.md), `go run -C tools ./cmd/pilot-reject`).
- **Declared errata:** the registry declares 12 defect(s) in the published reference material — 4 with a specification-derived correction, 8 documented without one, since no intended reading can be inferred ([OMG issues](docs/project/omg-issues.md), `tools/oracle/errata`). Every figure above is as published and stays the conformance statement; running the same oracles over the corrected text instead reports 348 of 379 files agreeing, 37 diagnostics ours alone and 1582 the reference's alone, 0 declared rows we are silent on, and 0 of 306 authored cases the reference alone rejects. The corrected figures are diagnostic only: an erratum never reclassifies a divergence category, and the published corpus is never edited.
- **Declared errata:** the registry declares 12 defect(s) in the published reference material — 4 with a specification-derived correction, 8 documented without one, since no intended reading can be inferred ([OMG issues](docs/project/omg-issues.md), `tools/oracle/errata`). Every figure above is as published and stays the conformance statement; running the same oracles over the corrected text instead reports 348 of 380 files agreeing, 37 diagnostics ours alone and 1614 the reference's alone, 0 declared rows we are silent on, and 0 of 306 authored cases the reference alone rejects. The corrected figures are diagnostic only: an erratum never reclassifies a divergence category, and the published corpus is never edited.
- **Self-assessed surface:** the action, state-machine and classifier-behavior rows have no external referee at all — the four refereed figures above cannot see them, because the pinned artifact evaluates expressions but executes neither actions nor state machines. [Spec compliance](docs/project/spec-compliance.md) counts them.

What these numbers cannot show: the OMG corpora are demonstrations rather than an official conformance suite; the differential is one-directional, comparing the diagnostics the two implementations report on the same files; the Xpect suites are the pilot authors' test intent rather than a certification oracle; and none of these is a percentage of the specification — no global compliance figure is claimed anywhere.
Expand All @@ -333,7 +333,7 @@ What these numbers cannot show: the OMG corpora are demonstrations rather than a
**Test coverage:** top-level `Test` functions (counted from the `_test.go` files, as `go test ./...` runs them) covering parsers, semantics, runtime (actions, states, instances, operators, validation), behind golden ASTs, negatives, execution conformance cases, golden traces, runtime robustness cases and gRPC conformance and robustness cases. The figures are counted from the tree when the documentation site is built into the test inventory of [spec compliance](docs/project/spec-compliance.md), never committed, so a branch adding a test does not rewrite this page. A test skips only for want of something the run did not provide, and says what: the held-image round trip declines a conformance case that creates no instance, a few gate on a PDF or Mermaid toolchain, a pinned pilot artifact, the PSSM suite, a locale, a case-insensitive filesystem or a live Flexo stack, and the OMG corpus gates skip until the corpora are downloaded unless asked to fail.
**Parser coverage:** 105/105 bundled library files parse cleanly — the 94 official SysML v2 standard library files and the non-normative `OpenSysML Libraries/OpenSysMLMathFunctions.kerml`, `OpenSysML Libraries/DocumentQueries.sysml`, `OpenSysML Libraries/IdentityMetadata.sysml`, `OpenSysML Libraries/DiagramLayout.sysml`, `OpenSysML Libraries/OOSEM.sysml`, `OpenSysML Libraries/MOSA.sysml`, `OpenSysML Libraries/StateSpaceIntegration.sysml`, `OpenSysML Libraries/Stochastic.sysml`, `OpenSysML Libraries/RandomFunctions.kerml`, `OpenSysML Libraries/Simulation.sysml` and `OpenSysML Libraries/MigrationMetadata.sysml` extensions. Conformance verified by [stdlib_conformance_test.go](internal/workspace/libs/stdlib_conformance_test.go). Grammar reference: [OMG Xtext grammar](https://github.com/Systems-Modeling/SysML-v2-Pilot-Implementation/tree/master/org.omg.kerml.xtext/src/org/omg/kerml/xtext).
**Behavioral execution:** Calc/constraint/requirement/satisfy functional. Action/state executors handle nested invocation, control flow keywords, loop and conditional statements and the send statement (<!-- doc-counts:begin conformance-passing -->every conformance case passing<!-- doc-counts:end conformance-passing -->). Coverage is self-assessed against the specification text and the normative library: the pinned OMG pilot implementation evaluates expressions but does not execute actions or state machines headlessly, so no external implementation currently adjudicates these rows. See [spec compliance](docs/project/spec-compliance.md).
**Reference differential:** 379 files compared diagnostic-by-diagnostic against the pinned OMG pilot implementation (`2026-08`), 347 in full agreement; every divergence is enumerated and adjudicated in [the differential](docs/project/pilot-differential.md), reproducible with `go run -C tools ./cmd/pilot-diff`.
**Reference differential:** 380 files compared diagnostic-by-diagnostic against the pinned OMG pilot implementation (`2026-08`), 347 in full agreement; every divergence is enumerated and adjudicated in [the differential](docs/project/pilot-differential.md), reproducible with `go run -C tools ./cmd/pilot-diff`.
**Rejection oracle:** the reverse direction — do we reject what the reference rejects? 306 hand-written invalid models validated by both implementations, 297 rejected by both, 0 the pinned pilot rejects and we accept; the remainder only we reject — the control-node succession rules the pinned pilot leaves unimplemented and a non-Boolean succession guard it accepts once the standard library types it — and every permissiveness gap is enumerated with a reproducer and likely root cause in [the rejection oracle](docs/project/pilot-rejection.md), reproducible with `go run -C tools ./cmd/pilot-reject`. We wrote every case, so the count measures our coverage of the rejection surface, not our conformance — a sample, not a proof.
**Training examples:** 100/100 files clean, gated by `tests/corpus/testdata/training_examples_expected.txt`. Download with `./scripts/download-training-examples.sh` (from the [OMG training directory](https://github.com/Systems-Modeling/SysML-v2-Pilot-Implementation/tree/master/sysml/src/training)). See [training examples](docs/project/training-examples.md) for analysis.
**Semantic layer:** a complete implementation of runtime operators, feature chains and validation rules. See [examples/semantic-layer/](examples/semantic-layer/) for a full demonstration.
Expand Down
7 changes: 5 additions & 2 deletions api/proto/sysml.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions api/proto/sysml.proto
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,11 @@ message EngineInfo {
// of the manifest entry that registered it: "tool", "engine", "policy" or
// "sampler". The fields below are empty for a built-in engine.
string kind = 9;
// How the engine is spoken to: "-" for one built in, "object" for a tool's
// one JSON object each way, "<transport>/<protocol>" for an engine entry.
// How the engine is spoken to: "-" for one built in; for a tool, "object"
// for the one-JSON-object exchange or "argv+<stdin>" when the entry has an
// invocation block, with a "/<reply format>" suffix such as "argv+none/csv"
// when the reply block reads another format (the format alone when the entry
// has no invocation); "<transport>/<protocol>" for an engine entry.
string protocol = 10;
// The manifest entry the engine was registered from, the command it resolved
// to and the version the entry declares.
Expand Down
3 changes: 3 additions & 0 deletions changes/unreleased/tool-dry-run.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- **Tools get a dry run.** `%tool <case|action>[(<args>)] [<object>]` at the prompt and `-tool-dry-run <case|action>` at the CLI show what the external tool a run's first `ToolExecution` names would be given — manifest, executable, argv, environment, working directory, standard input, input file and reply mapping — with the model's current values, without starting the process, then discards everything the preview performed; a manifest fault, an unregistered tool or an input the call does not send reports the same typed error the real run would fail with.
- **Runs record the tools they reached, and `-engines` spells the protocol.** `-record-run`/`%record` write every external tool call a run made into its `AnalysisRecords::RecordedRun` provenance as `tools`, one element per call in call order (`tool version from manifest: executable argv`); the `protocol` column a `-engines`/`%engines`/`ListEngines` listing shows for a tool spells how its manifest entry composes the process — `object` for the one-JSON-object exchange, or `argv+<stdin>` with a `/<reply format>` suffix such as `argv+none/csv` for an `invocation`/`reply` block.
- **A worked example walks the whole loop.** `examples/external-tool-demo/` registers a small Python solver as a tool, previews its invocation with `-tool-dry-run`, records a run — tools included — and renders the recorded run in a document; `docs/manual/running-external-programs.md` tells the same story end to end.
Loading
Loading