Skip to content

feat(hir-def): project component EMV2 model onto instances (REQ-EMV2-PROPAGATION-002, L3/4)#315

Merged
avrabe merged 1 commit into
mainfrom
feat/emv2-instance-projection
Jul 2, 2026
Merged

feat(hir-def): project component EMV2 model onto instances (REQ-EMV2-PROPAGATION-002, L3/4)#315
avrabe merged 1 commit into
mainfrom
feat/emv2-instance-projection

Conversation

@avrabe

@avrabe avrabe commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

What

Layer 3 of 4 of the EMV2 annex→instance foundation (#294). During instantiation, the EMV2 model retained on a component's classifier (L2) is now projected onto the corresponding ComponentInstance, so Layer 4 can build the Emv2Overlay (keyed by ComponentInstanceIdx).

  • SystemInstance gains a side-table emv2_models: FxHashMap<ComponentInstanceIdx, Vec<Emv2Model>> + an emv2_for(idx) accessor, mirroring the existing property_maps side-tables. Deliberately a side-table, not a ComponentInstance field — that keeps ~103 ComponentInstance constructors untouched and pays only ~56 SystemInstance literals (mostly test fixtures). (Blast-radius lesson from L2.)
  • Builder::project_emv2(idx, type_loc, impl_loc) clones tree.emv2_subclauses[..].model, unioning the component's TYPE and IMPLEMENTATION subclauses (direct only), called at the two production alloc sites (main recursive path = type∪impl; type-only leaf = type only).
  • Projection happens at instantiation time by necessity: Analysis::analyze receives only &SystemInstance, which has no back-reference to the item-tree — L4 can't re-read .emv2 later.
  • Extends-chain EMV2 inheritance is deferred (features inherit; EMV2 intentionally does not yet — flagged in the field doc).

Verification

  • Oracle-first, full pipeline (hand-authored AADL → item-tree → instantiate → assert), non-vacuous exact counts (a bare == item-tree model would only prove the clone ran): (a) EMV2 on the TYPE, root is the IMPLEMENTATION → root carries it (2 props + 1 flow), exercising the main path's type∪impl union; (b) a type-only leaf sub : device Sensor carries the device type's model (1 prop + 1 flow) while the EMV2-less root is empty — the distinct leaf alloc site a main-path-only projection would miss; (c) no annex ⇒ empty.
  • Verified workspace-wide (the L2 lesson applied up-front): cargo test --workspace --all-targets --no-run 0 errors; cargo clippy --workspace 0 real warnings (the nested if let collapsed to a let-chain); spar-hir-def 467 tests pass; fmt clean; mutation on project_emv2 0-missed (2 caught, 2 unviable).
  • Traceability: TEST-EMV2-INSTANCE-PROJECT verifies REQ-EMV2-PROPAGATION-002 (umbrella stays proposed until L4's end-to-end oracle).

Scope

Stops at instance projection — no Emv2Overlay, no analysis wiring. Layer 4 builds the overlay from emv2_for + wires spar analyze (the end-to-end ">0 propagation chains" oracle that closes #294 and flips the requirement to implemented).

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Jul 1, 2026

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.

@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.74214% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/spar-hir-def/src/instance.rs 98.18% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

…PROPAGATION-002)

Layer 3 of 4 for the EMV2 annex→instance foundation (#294). During
instantiation, the EMV2 model retained on a component's classifier (L2) is
projected onto the corresponding ComponentInstance so a later layer can build
the Emv2Overlay (which is keyed by ComponentInstanceIdx).

- `SystemInstance` gains a SIDE-TABLE `emv2_models:
  FxHashMap<ComponentInstanceIdx, Vec<Emv2Model>>` (+ an `emv2_for(idx)`
  accessor), mirroring the existing property_maps side-tables. Deliberately a
  side-table rather than a ComponentInstance field: that keeps the ~103
  ComponentInstance constructors untouched and pays only the ~56 SystemInstance
  literals (mostly test fixtures) — the blast-radius lesson from L2.
- `Builder::project_emv2(idx, type_loc, impl_loc)` reads `.emv2` off the
  classifier item(s) and clones `tree.emv2_subclauses[..].model`, UNIONing the
  component's TYPE and IMPLEMENTATION subclauses (direct only). Called at the
  two production ComponentInstance alloc sites: the main recursive path
  (type ∪ impl) and the type-only leaf subcomponent (type only). The anonymous
  (classifier-less) site projects nothing.
- Projection happens AT instantiation time by necessity: `Analysis::analyze`
  receives only `&SystemInstance`, which holds no back-reference to the
  item-tree/scope — L4 cannot re-read `.emv2` later.
- Extends-chain EMV2 inheritance is DEFERRED (features inherit via
  collect_type_chain_features; EMV2 intentionally does not yet — flagged in the
  field doc-comment).

Oracle-first, full pipeline (hand-authored AADL → item-tree → instantiate →
assert), NON-VACUOUS exact counts (a bare `== item-tree model` would only prove
the clone ran): (a) EMV2 on the TYPE, root is the IMPLEMENTATION → root carries
it (2 propagations + 1 flow), exercising the main path's type∪impl union;
(b) a type-only leaf `sub : device Sensor` carries the device type's model
(1 propagation + 1 flow) while the EMV2-less root is empty — the distinct leaf
alloc site a main-path-only projection would miss; (c) no annex ⇒ empty.

Verified workspace-wide (the L2 lesson): `cargo test --workspace --all-targets
--no-run` 0 errors; `cargo clippy --workspace` 0 real warnings (the project_emv2
nested if-let collapsed to a let-chain); spar-hir-def 467 tests pass; fmt clean;
mutation on project_emv2 0-missed (2 caught, 2 unviable). Stops at instance
projection — no Emv2Overlay, no analysis wiring (that is L4).
TEST-EMV2-INSTANCE-PROJECT verifies REQ-EMV2-PROPAGATION-002.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@avrabe avrabe force-pushed the feat/emv2-instance-projection branch from 81244b6 to 7e674a7 Compare July 1, 2026 22:49
@avrabe avrabe merged commit 592e6b7 into main Jul 2, 2026
19 checks passed
@avrabe avrabe deleted the feat/emv2-instance-projection branch July 2, 2026 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

friction: emv2_propagation reports 0 chains for all real models — AADL .emv2 annex not ingested into the propagation overlay

1 participant