Skip to content

feat: phase 10 cross-cutting invariants and conformance (XCUT-1..-24, NFR-1..-17, appendix B) - #102

Merged
Wahbeh-Mohammad merged 45 commits into
mainfrom
99-phase-10-cross-cutting-invariants
Oct 19, 2026
Merged

Wahbeh-Mohammad merged 45 commits into
mainfrom
99-phase-10-cross-cutting-invariants

Conversation

@Wahbeh-Mohammad

Copy link
Copy Markdown
Contributor

What and why

Phase 10 of the v1 roadmap: cross-cutting invariants and non-functional requirements. Design and plan: docs/work/mvp/phase10/ (planning #99, #100). Checklist: docs/work/mvp/phase10/2026-10-13-phase10-cross-cutting-invariants-checklist.md. User page: docs/sdk-documentation/cross-cutting-invariants.md, suites in docs/sdk-documentation/conformance.md.

Closes #99

Phase 10 measures and routes; it changes no production behaviour. The only src/ edits outside the kit are two RS0030 bans in BannedSymbols.txt and one scoped pragma at BoundedMap's single construction site. The plan's four stacked PRs were built as four commit groups on this one branch, each green at its gate task.

  • Kit contract: the runner is generic over the suite context (SuiteRunnerCore), TransportFace.None (additive), SuiteOptions, per-suite preambles, ConformanceReport.Combine.
  • Invariant suite (28 assertions, XCUT-1..XCUT-24, NFR-11) over InvariantSubject hooks that default to core; driven by a core driver (Dexpace.Sdk.Core.Tests/Conformance/, SEAM-2's allow-list admits the core-only kit) and a DI driver.
  • Codec suite (11 assertions, the 7a SERDE/SEAM-20 lift) with public probe models; STJ driver.
  • Packaging suite (8 assertions, NFR-1, -2, -3, -8, -10, -13, -14, -15) over the packed .nupkg files with BCL-only readers; a CI step (scripts/ci/packaging-conformance.cs) with policy parity against the dependency audit.
  • NFR gates: Nfr11PublicSurfaceArchitectureTests, NFR4ArchitectureTests, LicenseHeaderTests (incl. scripts/ci/*.cs), AnalyzerWaiverTests (every .editorconfig exemption carries a # Re-enable when:), CiWorkflowTests (no advisory gate), cross-path reproducible-pack.sh.
  • Appendix B and coverage: APPENDIX_B.md maps all 61 items with an evidence gate (AppendixBCoverageTests); scripts/ci/requirement-coverage.cs counts appendix C against every checklist (645 of 645 owned) with a shell self-test, run in CI.
  • AOT smoke: CheckPhase10Async runs the invariant and codec suites in the published binary.

Every new assertion has a negative control under tests/Dexpace.Sdk.Conformance.Tests/Controls/. The transport drivers keep exactly their two permanent waivers.

Requirements

41 owned rows (XCUT-1..-24, NFR-1..-17; 26 MUST, 15 SHOULD): 39 ✅ / 0 🚫 / 2 ⏳ / 0 N/A. Eleven ✅ are split (on existing §10 entries, vacuous or declined clauses, or readings). ⏳: NFR-16 (release path, phase 12) and NFR-17's merge half (see the lead's action below).

Verification

Linux, .NET SDK 10.0.401, re-run after the review fixes.

  • dotnet build (Release, 0 warnings), dotnet format --verify-no-changes, dotnet test --solution Dexpace.Sdk.sln: 7 356 tests, 0 failed, 27 skipped
  • Coverage 97.46% (floor 80%) and its self-test; dotnet pack; dependency audit (5 libraries conform); packaging conformance (8/8); requirement coverage (645/645) and its self-test
  • Reproducible pack byte-identical across two checkouts at different paths
  • NativeAOT smoke publishes with no trim/AOT warnings and prints all checks passed
  • Tools solution (438 tests), scripts/knowledge verify-structure, housekeeping probe (no drift found)
  • Security folders unchanged; only the kit's PublicAPI.Unshipped.txt moved; lock files: the two test projects' new kit reference

Records

  • CHANGELOG.md [Unreleased] (Added; TransportFace.None additive)
  • Checklist with rulings, deviations, review resolution and gate results; roadmap status note; docs/first-release.md; CLAUDE.md
  • Frozen-tree corrections (design, product spec) listed as proposals in the checklist, not made

Lead rulings and open action

P10-1..P10-30 accepted at their recommended defaults; plan readings R2, R3, R5, R6, R7, R15, R17 accepted as written.

Admin action needed (NFR-17): main's ruleset has no required_status_checks rule, so a red CI job does not block a merge. Request text is in the checklist's Open items for the lead.

One row per requirement ID for XCUT-1..24 and NFR-1..17 (39 done, NFR-16 and NFR-17 deferred), the contributed-evidence and hand-off table, the gate table, deviations, rulings, findings and the ruleset request for the lead.
Roadmap Phase 10 card, Phase List row and the dated phase 10 exit note; first-release.md (SHOULD declined, post-release triggers, the ruleset blocker, public-surface candidates); the earlier checklists' hand-off rows marked taken by phase 10; CLAUDE.md and README.md for the four suites and the new scripts; knowledge notes for Stryker on Microsoft.Testing.Platform, the cross-path reproducible pack, the missing required status checks and the HTAB edge.
Two Linux-row steps after the knowledge structure check: the coverage self-test and requirement-coverage.cs --check. CiWorkflowTests gains both rows in its gate table and its conditional allow-list in the same change; dropping the check turns it red.
…se; every built component is closed (phase 10, #99)
…x of the body as the error snapshot (phase 10, #99)
… not only 32 lower-case hex characters (phase 10, #99)
…ontinue-on-error or matrix exclude (phase 10, #99)
@Wahbeh-Mohammad

Copy link
Copy Markdown
Contributor Author

Review record

Implemented by an sdk-implementer agent (Sonnet), reviewed by an independent sdk-auditor (Opus) against the design, the plan, the lead rulings and the product-spec rows (ch.19 XCUT, ch.20 NFR, appendices B and C). The auditor re-verified every candidate before reporting; a fresh sdk-implementer fixed them test-first (each negative control shown failing before the fix), then re-ran the full gate set.

8 verified findings (2 major, 6 minor), all resolved:

Finding Resolution
major — xcut-17 never built an auth step Composes Auth.Basic and Auth.Bearer under the redirect loop (re-stamp on the seed's origin, none on a foreign host, none on a retried foreign hop); three new controls. Before: all eight control rows passed.
major — xcut-18 pinned the HTAB-edge trim, inbound too Refusal or trim accepted both ways; row ✅ split; the inbound trim is a possible HTTP-19 gap routed to phase 11.
minor — docs/first-release.md named the wrong 16 MUST rows Recomputed from the coverage script's own owning-row logic.
minor — xcut-13.dispose-non-blocking passed with nothing to close Fails on an empty hook; every component built for a round is closed.
minor — xcut-24 checked upper bounds only Requires a body preview in the log and a non-empty prefix of the body as the error snapshot; two new controls.
minor — XCUT-12's lock-free clause had no evidence named Cited by reference to AccessTokenCacheTests.The_hot_path_takes_no_lock (not asserted by the suite).
minor — CiWorkflowTests ignored triggers and job settings Pins the triggers; rejects a job-level if:, continue-on-error, matrix exclude:; parses steps per job.
minor — xcut-21 demanded exactly 32 lower-hex characters Accepts ≥128 bits in hex (either case), base64 or base64url.

Gates after the fixes: build 0 warnings, format clean, 7 356 tests / 0 failed / 27 skipped, coverage 97.46%, pack + dependency audit, packaging conformance 8/8, requirement coverage 645/645, reproducible pack, NativeAOT smoke, tools solution, knowledge structure, housekeeping probe — all green. Security folders untouched.

Routed onward (checklist Findings / Open items): ServiceResponseException dead surface and XCUT-24's >1 MiB snapshot (phase 11); the HttpResponseException constructor guard (phase 12); the required_status_checks ruleset rule (admin).

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.

docs: phase 10 design and implementation plan (cross-cutting invariants and conformance)

1 participant