Skip to content

Navigation Menu

Sign in
Sign up

fix(parser): accept annex-qualified property owners and two-token reference() categories (#434) - #435

Merged
avrabe merged 1 commit into
main from
feat/parser-owner-gaps-434
Aug 21, 2026
Merged

fix(parser): accept annex-qualified property owners and two-token reference() categories (#434) #435
avrabe merged 1 commit into
main from
feat/parser-owner-gaps-434

Conversation

@avrabe

@avrabe avrabe commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Closes #434. Lands all three SPAR-DEFECT parser gaps #427 first measured and #434 re-homed after #429's auto-close orphaned them — legal AADL that OSATE accepts with 0 diagnostics but spar too-strictly rejected. This is a too-strict fix; it is not paid for by loosening anything.

The two parser changes

(a) Annex-qualified property owners in applies to (...)arp4761.aadl:48, milstd882.aadl:50

) applies to ({emv2}**error type, {emv2}**type set, {emv2}**error behavior state, ...);

The {emv2} lexes as plain L_CURLY IDENT R_CURLY (it is not the {** annex-open token — {emv2} is { then e), so no lexer work is involved, exactly as the issue's parse --tree showed. A new branch in applies_to_category consumes {ident}** and then the owner name — which is multi-word and freely uses keywords (typeTYPE_KW, setSET_KW) — token-by-token up to the list separator (,/)), rather than expecting a single IDENT.

(b) Two-token component category inside reference(...) / classifier(...)pok.aadl:52

Slots_Allocation: list of reference (virtual processor) applies to (processor);

classifier_ref consumed only virtual as an IDENT and stopped, leaving processor to fail expect(R_PAREN). A new classifier_ref_list_element lifts the two-token virtual bus / virtual processor forms out to component_category; single-token categories and dotted classifier paths fall through unchanged.

Oracle — third_party_corpora.rs

The three files leave third-party-gaps.txt and MAX_SPAR_DEFECT walks 3 → 0, asserted two-sided in spar_defect_count_matches_ratchet. That assertion is refactored to match on Ordering so it stays clippy-clean at the floor of 0 (x >= 0 is absurd_extreme_comparisons for usize) while keeping both diagnostics — above-floor (a new gap is a regression) and below-floor (a fixed defect whose constant was not walked down).

Non-vacuity (executed against the built binary, not asserted)

Input Verdict
applies to ({emv2}**error type) parses
applies to ({emv2}**) (empty owner name) rejects — expected an annex property owner name after **
applies to ({emv2 error type) (missing }) rejects — expected R_CURLY
reference (virtual processor) parses
reference (virtual widget) (not bus/processor) rejects — expected R_PAREN
reference (processor, Pkg::Type) parses

A fabricated SPAR-DEFECT row still reds the count assertion (the ratchet bites in the regression direction).

No new too-permissive

osate_agreement.rs and three_way_conformance.rs hold their ceilings over the 120 first-party models. As a side effect of (a), the OSATE-corpus file EMV2TR_Test_Files/MyErrorProperties.aadl now parses and is re-blessed out of spar-gaps.txt; this advances REQ-PLUGFEST-005 by one file only — the other three it names (FG_System_pkg, ModalDualFGS, ThreeStateDualFGS) still fail on a separate, later construct, so -005 is not closed here.

Honest ceiling

Syntax acceptance only: the annex owner path is consumed without validating that the named element exists in the EMV2 meta-model (spar has no EMV2 semantic layer), consistent with how it treats other annex bodies. Not claimed: that these two forms are the last too-strict property-owner gaps.

Artifacts

Adds REQ-PLUGFEST-CORPUS-OWNER-001 (traces-to REQ-PLUGFEST-CORPUS-CLASSIFY-001) and TEST-PLUGFEST-CORPUS-OWNER. rivet validate → PASS.

Verification run locally

  • cargo test -p spar --test third_party_corpora --test osate_corpus --test osate_agreement --test three_way_conformance — green
  • cargo test -p spar-parser -p spar-syntax (372 tests) + full cargo test -p spar --tests — green
  • cargo fmt --all --check, cargo clippy ... -D warnings — clean
  • Independent clean-room subagent re-derived every claim above (non-vacuity, ratchet reachability, the 1-of-4 REQ-PLUGFEST-005 scoping, rivet) — all PASS, no over-claim.

🤖 Generated with Claude Code


Generated by Claude Code

...erence() categories (#434)
Closes the three SPAR-DEFECT parser gaps #427 first measured and #434
re-homed after #429's auto-close orphaned them — legal AADL that OSATE
accepts with 0 diagnostics but spar too-strictly rejected.
(a) Annex-qualified property owners in `applies to (...)`:
 `{emv2}**error type`, `{emv2}**type set`, `{emv2}**error behavior state`,
 ... (arp4761.aadl:48, milstd882.aadl:50). The `{ident}` lexes as plain
 `L_CURLY IDENT R_CURLY` (not the `{**` annex-open token), so no lexer work
 is needed; a new branch in `applies_to_category` consumes `{ident}**` then
 the multi-word owner name — which freely uses keywords (`type`->TYPE_KW,
 `set`->SET_KW) — token-by-token to the list separator. An empty name after
 `**`, or a malformed brace, still errors.
(b) Two-token component category inside `reference(...)`/`classifier(...)`:
 `reference (virtual processor)` (pok.aadl:52). `classifier_ref` consumed
 only `virtual` as an IDENT, leaving `processor` to fail `expect(R_PAREN)`.
 A new `classifier_ref_list_element` lifts the two-token `virtual bus` /
 `virtual processor` forms out to `component_category`; single-token
 categories and dotted classifier paths fall through unchanged.
Oracle: `third_party_corpora.rs`. The three files leave third-party-gaps.txt
and `MAX_SPAR_DEFECT` walks 3 -> 0. The two-sided count assertion is
refactored to match on `Ordering` so it stays clippy-clean at the floor of 0
(`x >= 0` is `absurd_extreme_comparisons` for usize) while keeping both the
above-floor (regression) and below-floor (un-walked win) diagnostics.
No new too-permissive: osate_agreement.rs and three_way_conformance.rs hold
their ceilings over the 120 first-party models. As a side effect of (a) the
OSATE-corpus file EMV2TR_Test_Files/MyErrorProperties.aadl now parses and is
re-blessed out of spar-gaps.txt; this advances REQ-PLUGFEST-005 by one file
only (the other three fail on a separate later construct).
Adds REQ-PLUGFEST-CORPUS-OWNER-001 (traces-to REQ-PLUGFEST-CORPUS-CLASSIFY-001)
and TEST-PLUGFEST-CORPUS-OWNER.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

codecov Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.23810% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/spar-parser/src/grammar/properties.rs 95.23% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown

Rivet verification gate

20/20 passed

count
Passed 20
Failed 0
Skipped (no steps) 0

Filter: (and (= type "feature") (or (has-tag "v093") (has-tag "v0100")))

Failed artifacts

(none)

Updated automatically by tools/post_verification_comment.py. Source of truth: artifacts/verification.yaml.

avrabe merged commit aee9e1c into main Aug 21, 2026
22 checks passed
avrabe deleted the feat/parser-owner-gaps-434 branch August 21, 2026 11:16
avrabe added a commit that referenced this pull request Aug 21, 2026
Version bump for v0.41.0. Feature landed in #435 — accepts annex-qualified property owners ({emv2}**error type) and two-token categories (virtual processor) in reference(...), closing the three SPAR-DEFECT parser gaps of #434. Cargo.toml / Cargo.lock (23 workspace crates) / vscode-spar/package.json 0.40.0 -> 0.41.0; REQ-PLUGFEST-CORPUS-OWNER-001 promoted to verified (release v0.41.0).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
avrabe added a commit that referenced this pull request Aug 26, 2026
... spent on
v0.41.0 and v0.42.0 were bumped and merged to main while this PR sat open —
#436 carries #435 (the three SPAR-DEFECT parser gaps of #434, MAX_SPAR_DEFECT
walked 3 -> 0) and #438 carries #437 (reject a feature named `in`/`out`, #420).
Both are real work out of this plan's own audit, landed by the autonomous loop.
Neither is tagged. The version numbers are consumed regardless: Cargo.toml on
main reads 0.42.0, so 0.41.0 and 0.42.0 cannot be reused whether they end up
signed or collapsed. The scope shifts by two and nothing else changes:
 v0.41.0 -> v0.43.0 CLAIM-LEDGER · CLI-SURFACE · SYSML2-CONFORMANCE
 v0.42.0 -> v0.44.0 HIR-FEATUREGROUP-PATH · SYSML2-VISIBILITY
 v0.43.0 -> v0.45.0 FINDINGS-LAYER
 v0.44.0 -> v0.46.0 RENDER-METRICS · RENDER-COMPOUND · RENDER-GOLDEN
 v0.45.0 -> v0.47.0 SYSML2-FLOWS-MODES
Re-verified on main at 138a693 that the scope itself is untouched: the eight
SysML v2 conformance tests still contain zero `errors()` calls, the official
corpus directories still hold zero files, no workflow mentions sysml, five
commands still dispatch without appearing in `--help`, and the
"production-grade" claim plus the SysML v2 capability badge are both still
live. Only the numbers were spent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

The 3 SPAR-DEFECT parser gaps orphaned by #427's auto-close: annex-qualified property owners, and a two-token category in reference(...)

2 participants

AltStyle によって変換されたページ (->オリジナル) /