Skip to content

Commit ed23290

Browse files
avrabeclaude
andauthored
docs: spar moves CLI documentation + Track E v0.8.0 close-out (commit 7/8) (#175)
Adds docs/cli/moves.md — comprehensive user-facing documentation for `spar moves verify` and `spar moves enumerate`, covering flags, exit codes, JSON/text output schemas, candidate-set derivation, multi-objective ranking, rivet-variant integration, and a worked example. Updates COMPLIANCE.md: - Header date + version line (v0.7.1 released / v0.8.0 in progress). - Renames "In progress / v0.7.0" -> "v0.7.1 (released 2026-04-27)". - Promotes Track B from "foundation only" to including spar-variants consumer crate (#162). - New "v0.8.0 (in progress on main)" section with Track D Phase 1 (6/6) + Track E (7/8 with this commit) + Track F. - New "v0.9.0 horizon" listing Track E commit 8 (MCP), spar-insight, Track D Phase 2 conditional on demand. Track E commit 7 of 8. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f0eaa33 commit ed23290

2 files changed

Lines changed: 262 additions & 28 deletions

File tree

COMPLIANCE.md

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# AS5506 AADL v2.2 Compliance Gap Analysis
22

3-
**Updated**: 2026-04-25 (v0.7.0 in progress)
3+
**Updated**: 2026-04-27 (v0.7.1 released; v0.8.0 in progress)
44
**Source**: 102 HTML files from OSATE2 (`org.osate.help/html/std/`)
5-
**Toolchain**: spar (1900+ tests passing across 17 crates)
5+
**Toolchain**: spar (2200+ tests passing across 18 crates)
66

77
---
88

@@ -214,7 +214,10 @@
214214

215215
---
216216

217-
## v0.7.0 (delivered) / v0.8.0 (in progress)
217+
## v0.7.1 (released 2026-04-27)
218+
219+
Headline release for the v0.7.x line. Tagged `v0.7.1`. Binary release
220+
artifacts at github.com/pulseengine/spar/releases/tag/v0.7.1.
218221

219222
**Track A — IRQ-aware RTA (4/4 commits delivered)**
220223

@@ -225,48 +228,67 @@
225228

226229
**Out of scope for v0.7.0, deferred to v0.7.1+**: priority inheritance (PIP) / priority ceiling (PCP) blocking; multi-processor ISR migration; cache-aware interference inflation (research-grade, v1.0+).
227230

228-
**Track B — Variants (foundation only)**
231+
**Track B — Variants foundation**
229232

230-
- Variant binding contract v1 (#144): `docs/contracts/rivet-spar-variant-v1.md` — rivet owns the PLE truth (feature model, variant configs, bindings, SAT), spar consumes a JSON context blob and filters HIR. Implementation of the consumer crate (`spar-variants`) waits for rivet to emit its first context blob; tracked separately.
233+
- Variant binding contract v1 (#144): `docs/contracts/rivet-spar-variant-v1.md` — rivet owns the PLE truth (feature model, variant configs, bindings, SAT), spar consumes a JSON context blob and filters HIR.
234+
- spar-variants consumer crate (#162): reads the v1 context blob, applies intersection-semantics binding rules, exposes `keep_in_variant` predicate.
231235

232-
**v0.7.x infrastructure landed alongside Track A**
236+
**v0.7.x infrastructure**
233237

234238
- Kani harnesses for spar-solver and spar-codegen invariants (#141, closes #136).
235239
- cargo-fuzz scaffolding for parser, solver, codegen-roundtrip targets (#142, closes #138).
236240
- Criterion benchmarks for scheduling solver and codegen (#143, closes #137).
237241
- Lean / Bazel / proptest CI gates (#151, closes #135) — Lean proofs now machine-checked in CI for the first time.
238-
- Track D and Track E research design docs landed (#152, #153) anchoring v0.8.0+ scope.
242+
- Track D and Track E research design docs (#152, #153) and Track F engagement strategy (#160) anchoring v0.8.0+ scope.
239243

240-
**Track D — TSN/Ethernet WCTT analysis (Phase 1, 5/6 commits delivered)**
244+
---
241245

242-
- Foundation: Spar_Network property set + spar-network crate skeleton (#155)
243-
- NetworkGraph extraction from SystemInstance (#157)
244-
- NC primitives — arrival/service curves + min-plus operators (#161)
245-
- WcttAnalysis pass with per-stream end-to-end bounds (#168)
246-
- Lean theorems for NC primitives (commit 5; in flight as a sibling to this PR)
247-
- latency.rs integration — RTA-derived WCET on compute hops + wctt-derived WCTT
248-
on network hops, end-to-end. Bus_Properties::Latency scalar remains the
249-
fallback for unannotated buses, preserving v0.7.0 behaviour. (this commit)
246+
## v0.8.0 (in progress on main)
250247

251-
Phase 2 (TSN-shaped service curves with TAS, CBS, frame preemption) is
252-
v0.8.x scope.
248+
**Track D — TSN/Ethernet WCTT analysis, Phase 1 (6/6 commits delivered)**
253249

254-
**Track E — Frozen-platform / mobile-application split (commit 3 delivered)**
250+
- Foundation: `Spar_Network::{Switch_Type, Queue_Depth, Forwarding_Latency, Output_Rate}` property set + `spar-network` crate skeleton (#155).
251+
- NetworkGraph extraction from SystemInstance (#157).
252+
- Network Calculus primitives (#161): `ArrivalCurve`, `ServiceCurve`, `backlog_bound`, `delay_bound`, `residual_service`, `output_bound`. All values in `u64` picoseconds / bytes / bits-per-second — no floating-point drift.
253+
- `WcttAnalysis` pass (#168): per-stream end-to-end traversal-time bounds. New diagnostics `WcttBound`, `WcttExceedsBudget`, `WcttUnservable`, `WcttSwitchOverloaded`. New `Spar_Network::WCTT_Budget` property.
254+
- Lean theorems for NC primitives (#169): `proofs/Proofs/Network/MinPlus.lean` mirrors classical NC closed-forms with monotonicity proved + `sorry`-with-`TODO(v1.0.0)` for the universally-quantified arithmetic statements.
255+
- `latency.rs` integration (#171): RTA-derived WCET on compute hops alternates with WCTT-derived bounds on network hops, end-to-end, replacing the placeholder `Bus_Properties::Latency` scalar when `Spar_Network::*` is annotated. Models without `Spar_Network::*` keep the scalar — non-regression.
255256

256-
- `spar moves verify` CLI subcommand for hypothetical-rebinding oracle
257-
is live; the deterministic-apply path is v0.8.x. The MCP read-only
258-
surface (`spar.verify_move`, `spar.enumerate_moves`) remains v0.9.0
259-
scope per Track E roadmap.
257+
Phase 2 (TSN-shaped service curves: TAS, CBS, frame preemption) is v0.8.x scope.
260258

261-
---
259+
**Track E — Frozen-platform / mobile-application + hypothetical-rebinding oracle (6/8 commits delivered)**
260+
261+
- Foundation: `Spar_Migration::{Frozen, Mobile, Allowed_Targets, Pinned_Reason}` property set + `is_frozen` / `is_mobile` helpers (#156).
262+
- `BindingOverlay` (#164): HIR-level overlay so any analysis can run on a hypothetical binding without mutating the SystemInstance. Validates against Frozen / Allowed_Targets returning structured `FrozenViolation` / `AllowedTargetsViolation` diagnostics.
263+
- `spar moves verify` (#166): CLI command — first user-facing surface of the migration oracle. Builds a `BindingOverlay`, runs validation + analyses, returns structured pass/fail JSON with violations. Exit codes 0/1/2 distinguish ok / analysis-error / binding-violation.
264+
- `spar moves enumerate` (#170): CLI command — design-space exploration. Lists every valid hypothetical rebinding target for a component within `Allowed_Targets` (or every processor if `Allowed_Targets` is absent), each with verification status and an optional ranking metric.
265+
- Multi-objective enumeration ranking (#174): replaces the simple slack metric with a configurable score across `max-response | total-load | total-power | total-weight | balanced`. Adds `Spar_Power::Power_Budget` property. Score uses the same RTA + property-accessor machinery as direct verification, so verify/enumerate stay consistent.
266+
- Rivet variant integration (#173): `spar moves verify --variant NAME` and `--variant-context PATH` accepted by both `verify` and `enumerate`. Variant filter applies before overlay validation; non-variant components dropped from the analysis surface per the v1 contract's intersection semantics.
267+
268+
Remaining v0.8.0 work:
269+
- Commit 7 (this commit): documentation + COMPLIANCE close-out narrative
270+
- Commit 8 (v0.9.0 territory): MCP tool surface (`spar.verify_move`, `spar.enumerate_moves`) — read-only / idempotent only, deterministic apply stays CLI-exclusive
262271

263-
## v0.8.0 planning
272+
**Track F — SysML v2 / KerML community engagement (strategy doc on main)**
264273

265-
Two parallel tracks scoped from the v0.7.0 research:
274+
- `docs/designs/track-f-sysml-kerml-engagement.md` (#160): research-backed engagement plan for the OMG SysML v2 ecosystem. Anchors on the `Systems-Modeling/SysML-v2-AADL-Release` repo + named contacts at Galois/CMU-SEI/Ellidiss. Includes verified spar-sysml2 audit (production-grade with full requirements roundtrip) + Rust ecosystem positioning (`syster`, `Sysand`, `tree-sitter-sysml`).
275+
276+
**v0.8.0 release readiness criteria**
277+
278+
- Track D Phase 1 complete ✅
279+
- Track E commits 1-6 complete ✅
280+
- Track E commit 7 (docs + this close-out) ⏳ in this commit
281+
- Track E commit 8 (MCP) deferred to v0.9.0
282+
- Tag `v0.8.0` once Track E commit 7 lands and Phase 2 TSN scope is decided.
283+
284+
---
266285

267-
**Track D — TSN/Ethernet WCTT analysis (#149)**: WCTT is a foundational primitive for honest end-to-end timing, not a TSN-specific feature. Phase 1 (v0.8.0) ships a Network Calculus engine for FIFO+priority networks (classical Ethernet, CAN, FlexRay) and replaces `latency.rs`'s scalar bus-latency lookup with per-stream NC-derived bounds. Phase 2 (v0.8.x) adds TSN-specific service curves (TAS, CBS, frame preemption). Roadmap: 7 weeks across 6 commits.
286+
## v0.9.0 horizon
268287

269-
**Track E — Frozen-platform / mobile-application split + hypothetical-rebinding oracle (#150)**: Adds `Spar_Migration::{Frozen, Mobile, Allowed_Targets, Pinned_Reason}` plus a verification mode (`spar moves verify`) and an enumeration mode (`spar moves enumerate`). The MCP tool surface (`spar.verify_move`, `spar.enumerate_moves`) ships in v0.9.0 — read-only / idempotent only, deterministic apply via CLI. LLM agents propose moves; spar deterministically verifies; certification chain stays in spar. Roadmap: 8 weeks across 8 commits for v0.8.0; another 8.5 weeks across the v0.9.0 MCP surface.
288+
- Track E commit 8: MCP tool surface (`spar.verify_move`, `spar.enumerate_moves`) per Track E research §6.5. Read-only and idempotent only; deterministic apply stays CLI-exclusive. LLM agents propose moves; spar deterministically verifies; certification chain stays in spar.
289+
- spar-insight (statistical discrepancy assistant): rules-based first; Lean-foundation statistical methods (proof-assistant choice still parked per project memory). Per Track F's R2/R1 discussion.
290+
- Track D Phase 2 if user demand surfaces: TSN-shaped service curves (TAS, CBS, frame preemption).
291+
- syster license-clarification issue (per Track F amendments) — minimum-viable engagement only, conditional on strategic value.
270292

271293
---
272294

docs/cli/moves.md

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
# `spar moves` — hypothetical-rebinding oracle
2+
3+
Available since v0.8.0. `spar moves` answers questions of the form
4+
*"if I move component X to processor Y, would my system still close
5+
its deadlines / bandwidth budgets / frozen-platform contracts?"*
6+
without mutating any source file.
7+
8+
There are two subcommands today: `verify` (single-target check) and
9+
`enumerate` (list valid alternatives ranked by an objective).
10+
11+
## `spar moves verify`
12+
13+
Verifies a single hypothetical rebinding. Returns structured pass/fail
14+
JSON with violations.
15+
16+
### Usage
17+
18+
```
19+
spar moves verify \
20+
--root Pkg::Sys.Impl \
21+
--component Pkg::Sys.Impl.handler \
22+
--to Pkg::CPU_x86 \
23+
[--format json | text] \
24+
[--variant NAME | --variant-context PATH] \
25+
model.aadl
26+
```
27+
28+
### Flags
29+
30+
| Flag | Purpose |
31+
|---|---|
32+
| `--root <FQN>` | Root system implementation, e.g. `Engines::Top.Battery` |
33+
| `--component <FQN>` | Fully-qualified name of the component to (hypothetically) move. Must be Mobile (`Spar_Migration::Mobile => true`) or unannotated. |
34+
| `--to <FQN>` | Target processor. Must be a processor / virtual processor instance reachable from the root. |
35+
| `--format` | `text` (default; human-readable) or `json` (machine-readable, schema below). |
36+
| `--variant <NAME>` | Implicit form: shells out to `rivet resolve --variant NAME --format spar-context-json`. Requires `rivet` on `$PATH` or `$RIVET_BIN`. |
37+
| `--variant-context <PATH>` | Explicit form: read JSON from `PATH` (`-` for stdin). Mutually exclusive with `--variant`. |
38+
39+
### Exit codes
40+
41+
- `0` — OK, no violations.
42+
- `1` — Analysis-error severity diagnostic produced (e.g. RTA reports a
43+
deadline miss after the move).
44+
- `2` — Binding-violation detected (Frozen / Allowed_Targets).
45+
- non-zero from `1`/`2` — argument errors (missing component, unknown
46+
target, etc.) report descriptive text on stderr.
47+
48+
### Output (JSON)
49+
50+
```json
51+
{
52+
"ok": false,
53+
"component": "Engines::Top.Battery.app.bh",
54+
"target": "Engines::Top.Battery.cpu_slow",
55+
"variant": null,
56+
"feature_model_hash": null,
57+
"violations": [
58+
{ "kind": "AnalysisError",
59+
"pass": "rta",
60+
"severity": "Error",
61+
"message": "thread 'bh' on processor 'cpu_slow' misses deadline: response time 1.2 ms > deadline 1 ms" }
62+
],
63+
"diagnostics_by_pass": { ... }
64+
}
65+
```
66+
67+
When `--variant`/`--variant-context` is set, `variant` and
68+
`feature_model_hash` carry the resolved-variant metadata.
69+
70+
## `spar moves enumerate`
71+
72+
Lists every valid hypothetical rebinding target for a component, each
73+
with its verification status and a configurable ranking metric.
74+
75+
### Usage
76+
77+
```
78+
spar moves enumerate \
79+
--root Pkg::Sys.Impl \
80+
--component Pkg::Sys.Impl.handler \
81+
[--target-filter <FQN-PREFIX>] \
82+
[--objective max-response | total-load | total-power | total-weight | balanced] \
83+
[--format json | text] \
84+
[--variant NAME | --variant-context PATH] \
85+
model.aadl
86+
```
87+
88+
### Candidate-set derivation
89+
90+
If `Spar_Migration::Allowed_Targets` is set on the component, that list
91+
is the candidate set. Otherwise: every processor (or virtual processor)
92+
component reachable from the root.
93+
94+
`--target-filter <PREFIX>` narrows the candidate set to entries whose
95+
fully-qualified name starts with `<PREFIX>` *after* `Allowed_Targets`
96+
has been applied — i.e. a filter cannot bypass the platform's
97+
`Allowed_Targets` declaration.
98+
99+
### Ranking objectives
100+
101+
| Objective | Metric (lower = better) |
102+
|---|---|
103+
| `max-response` (default) | Maximum thread response time on the candidate target. Negative values indicate deadline miss. |
104+
| `total-load` | Sum of utilization (`exec / period`) of threads bound under the candidate. |
105+
| `total-power` | Sum of `Spar_Power::Power_Budget` for components bound under the candidate. |
106+
| `total-weight` | Sum of `Weight_Properties::Weight`. |
107+
| `balanced` | Equal-weight composite of the four metrics above. |
108+
109+
Candidates are sorted: `ok=true` first, then by score ascending (lower
110+
is better), then by FQN.
111+
112+
### Output (JSON)
113+
114+
```json
115+
{
116+
"component": "Engines::Top.Battery.app.bh",
117+
"objective": "max-response",
118+
"variant": null,
119+
"feature_model_hash": null,
120+
"total": 3,
121+
"valid": 2,
122+
"candidates": [
123+
{ "target": "Engines::Top.Battery.cpu_fast",
124+
"ok": true,
125+
"violations": [],
126+
"diagnostics_count": 0,
127+
"rank": { "max_response_ns": 800000, "total_load": 0.4, ..., "score": 800000.0 } },
128+
...
129+
]
130+
}
131+
```
132+
133+
### Exit codes
134+
135+
- `0` — at least one valid candidate found.
136+
- `1` — argument errors (unknown component, malformed flag).
137+
- enumeration with zero valid candidates still exits `0`, with `valid: 0`.
138+
139+
## Worked example
140+
141+
```aadl
142+
package Engines
143+
public
144+
with Spar_Migration;
145+
146+
thread Brake_Handler end Brake_Handler;
147+
thread implementation Brake_Handler.Impl
148+
properties
149+
Spar_Migration::Mobile => true;
150+
Spar_Migration::Allowed_Targets => (reference (cpu_fast), reference (cpu_safety));
151+
end Brake_Handler.Impl;
152+
153+
processor M4 end M4;
154+
155+
system Top end Top;
156+
system implementation Top.Battery
157+
subcomponents
158+
cpu_fast: processor M4;
159+
cpu_safety: processor M4;
160+
cpu_legacy: processor M4;
161+
app_thread: thread Brake_Handler.Impl;
162+
properties
163+
Actual_Processor_Binding => (reference (cpu_fast)) applies to app_thread;
164+
end Top.Battery;
165+
end Engines;
166+
```
167+
168+
```sh
169+
$ spar moves enumerate \
170+
--root Engines::Top.Battery \
171+
--component Engines::Top.Battery.app_thread \
172+
model.aadl
173+
174+
(variant=none) component=Engines::Top.Battery.app_thread total=2 valid=2
175+
176+
ok target score
177+
-- ---------------------------------------- ------
178+
✓ Engines::Top.Battery.cpu_fast 0.80 ms
179+
✓ Engines::Top.Battery.cpu_safety 0.80 ms
180+
```
181+
182+
`cpu_legacy` is not listed because it isn't in `Allowed_Targets`.
183+
184+
## Use with rivet variants
185+
186+
```sh
187+
$ spar moves verify \
188+
--variant diesel-eu5 \
189+
--component Engines::Top.Battery.app_thread \
190+
--to Engines::Top.Battery.cpu_safety \
191+
model.aadl
192+
```
193+
194+
The `--variant diesel-eu5` flag invokes `rivet resolve --variant
195+
diesel-eu5 --format spar-context-json` and applies the resulting binding
196+
rules before the move is verified. Only items in the variant's
197+
resolved set participate in the analysis.
198+
199+
## Integration target — MCP tool surface (v0.9.0)
200+
201+
The `--format json` shape is the canonical machine-readable form. In
202+
v0.9.0 it will also be exposed as MCP tools `spar.verify_move` and
203+
`spar.enumerate_moves` so LLM agents can drive design-space exploration
204+
with spar as the deterministic correctness oracle. The tools will be
205+
`readOnlyHint: true` and `idempotentHint: true`; the deterministic
206+
apply path stays CLI-exclusive (no `spar.apply_move` over MCP) so the
207+
certification chain remains in spar's existing analysis primitives.
208+
209+
## See also
210+
211+
- [`docs/contracts/rivet-spar-variant-v1.md`](../contracts/rivet-spar-variant-v1.md) — variant context blob format.
212+
- [`docs/designs/track-e-migration-research.md`](../designs/track-e-migration-research.md) — research backing this surface.

0 commit comments

Comments
 (0)