feat(s2): sub-component containment (spec v0.4 §5.1) — 0.3.0 - #53
Merged
Conversation
…oop (0.3.0) The ratified invariant: a sub-declared component id may appear only within the subtree of an instance of a declaring compound, unless the contract also declares the id as a top-level component (independently usable). Ownership comes only from composition.subComponents — never names, prefixes, adjacency, or examples. Owner may be ANY ancestor (intermediate structure allowed); root orphans and sibling placement are the same refusal; findings are pathed and name the orphan and its owner(s). Fail-first (containment.test.ts written against unmodified code): Tests 7 failed | 2 passed (9) all four measured production shapes PASSED S2 as membership — root-level form-label, select-trigger beside its select, bare alert-dialog-content duplicated next to a nested one, and the dspack#40 field-trio exemplar (which also PASSES under the corrected ownership in the same test — the amendment and the contract fix converge). Repair wiring (the amendment's point): S2 gate errors now ride the repair message in their own section ahead of governance findings — previously renderRepairMessage received S3 findings only, so an S2-failing surface got a repair prompt claiming zero violations. Byte-compatible when no vocabulary errors exist (F1 repair golden unchanged). Collateral: pipeline.test.ts's emitter-REFUSAL fixture (stray table-footer under card) is exactly the shape §5.1 makes lint-catchable, so it no longer reaches the emitter; the lint-clean-but-refused class it pins is now exercised via its other member, a declared casualty (dropdown-menu). Suite: 138/138.
There was a problem hiding this comment.
Pull request overview
This PR updates the S2 “contract vocabulary” gate to enforce the spec v0.4 §5.1 sub-component containment invariant, and ensures S2 gate errors are surfaced to (and actionable within) the bounded repair loop.
Changes:
- Add S2 containment checking so sub-declared component IDs are only valid under a declaring compound’s subtree (unless also declared top-level).
- Thread S2 gate error strings into
renderRepairMessage, rendering them in a dedicated section ahead of governance findings. - Update/extend tests to cover containment semantics and adjust the “emitter refusal” fixture to remain lint-clean under the new S2 behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/run/pipeline.test.ts | Updates the refusal fixture to use a lint-clean “casualty” component now that stray subs are caught by S2 containment. |
| src/run/orchestrator.ts | Passes S2 gate errors into the repair message so containment/vocabulary defects are repairable in-loop. |
| src/repair/render.ts | Extends repair rendering to include S2 vocabulary errors in their own section while keeping output byte-identical when absent. |
| src/core/lint/vocabulary.ts | Implements containment validation (spec v0.4 §5.1) as part of S2 vocabulary checking. |
| src/core/lint/containment.test.ts | Adds focused tests for containment failure modes, exemptions, walk parity (children + slots), and repair-loop plumbing. |
| package.json | Bumps package version to 0.3.0. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the ratified containment invariant in S2 and wires S2 errors into the repair loop. Companion to aestheticfunction/dspack#41 (the spec amendment).
composition.subComponents; both-declared ids exempt; pathed findings naming orphan + owner(s).renderRepairMessage— an S2-failing surface got a "0 violations" repair prompt. Now they render in their own section; byte-identical when absent (F1 golden untouched).pipeline.test.tsrefusal fixture repointed at a casualty (dropdown-menu) — the stray-sub shape is now lint-catchable by design.138/138 green.
🤖 Generated with Claude Code