Repository navigation
Samples gate: six known-debt entries name NodeTypes that no longer exist (#1786) - #2472
Conversation
… exist (#1786) `.github/samples-gate.allow` still carried six `compile` entries for `FutuRe/{AmericasIns,AsiaRe,EuropeRe}/{LineOfBusiness,TransactionMapping}` — NodeTypes that `b63fbf057`/`091a57a6c` retired to plain `Markdown` nodes when #2030 landed. Read from the file, those six lines say "six NodeTypes are still failing to compile in production", which is exactly the condition #1786 reports and exactly what a reader will believe. They have named nothing for a week. **Why the ratchet could not retire them.** The gate's stale-detection asks *did this subject pass?* — `bake.Types.Any(t => t.Success && t.NodePath == e.Scope)` — so it retires an entry whose type now COMPILES. A subject that no longer EXISTS never passes and never fails: the tester prints `unverifiable allow entry (check skipped or scope absent this run)` and stays green. That is the right default THERE and stays unchanged: the tester is shared with the satellite repos, which stage a SUBSET of their tree, so "listed but absent" is genuinely unknowable for them and failing it would break them. It is not unknowable here. `stage-samples-gate.sh` copies all eight packages and `stage-doc-gate.sh` copies the whole Doc tree, unconditionally — so in THIS repo "absent" means retired, and it can be decided statically off the files. **`GateAllowEntrySubjectGuard`** does that: every entry in both allow files must name a subject the repo still ships — a type-level check (`compile`/`render`/ `tests`) must resolve to a node file whose content is a `NodeTypeDefinition`, a package-level check (`install`/`idempotence`) to a package directory, and the package must be one the lane's staging script actually stages (parsed from the script, so the two cannot drift). It complements the gate rather than duplicating it: stale-detection catches "fixed", this catches "gone". Proven non-vacuous, not asserted to be: with the six lines restored the guard fails naming all six and saying what each became — .github/samples-gate.allow:1 'FutuRe/AmericasIns/LineOfBusiness compile' — samples/Graph/Data/FutuRe/AmericasIns/LineOfBusiness.json is not a NodeType any more (nodeType: Markdown) and the second test pins the resolver from both sides (a live NodeType resolves AS a NodeType; the six retired files resolve and are rejected; a fabricated path resolves to nothing; the Doc lane's `Doc/` prefix really addresses the tree), so it cannot degrade into a check that answers "found" for everything. The two `PensionFund` entries stay: both are separately diagnosed debt this issue does not own, and both still name live subjects. No What's New entry — CI-internal, no user-visible effect. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR keeps the samples content gate’s “known debt” allowlist accurate by removing entries that refer to NodeTypes that have been retired, and adds a unit-test guard to ensure allowlist entries always point at subjects that this repo still ships (so “gone” debt can’t silently persist as “unverifiable”).
Changes:
- Added
GateAllowEntrySubjectGuardtests to validate that each allowlist entry resolves to an existing, correctly-typed subject within the staged trees. - Removed six obsolete
compileallowlist entries for retiredFutuRe/*/{LineOfBusiness,TransactionMapping}NodeTypes from.github/samples-gate.allow.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| test/MeshWeaver.Graph.Test/GateAllowEntrySubjectGuard.cs | Adds the guard tests that resolve allowlist scopes to actual shipped node files/directories and fail on retired/absent subjects. |
| .github/samples-gate.allow | Removes six allow entries that referred to NodeTypes that no longer exist as NodeTypes. |
Suppressed comments (1)
test/MeshWeaver.Graph.Test/GateAllowEntrySubjectGuard.cs:55
- Static collections are forbidden across the repo (AGENTS.md “No static collections — ever”, and enforced by NoStaticCollectionsTest). This static HashSet will be flagged by the architecture guard; make it an instance field to avoid process-wide state.
private static readonly IReadOnlySet<string> PackageLevelChecks =
new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "install", "idempotence" };
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Copilot flagged the `static readonly` sets against AGENTS.md's "No static collections". They are the sanctioned shape — immutable, write-once reserved-word lookups, the same shape `GateAllowlist.Checks` already ships — and `NoStaticCollectionsTest` would not have fired either (it reflects over `MeshWeaver.*.dll` in its OWN bin, which never contains another test assembly, and matches on the FIELD type, which was `IReadOnlySet<>`). But the collections policy also says `HashSet<T>` → `ImmutableHashSet<T>`, and a `new HashSet<…>` initializer behind a read-only interface is exactly the shape a reader has to reason about rather than see. Making the type immutable removes the question instead of answering it, and costs nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Test Results (shard 3)994 tests 990 ✅ 16m 14s ⏱️ Results for commit 3f3b0af. |
Test Results (shard 5)4 482 tests 4 376 ✅ 12m 18s ⏱️ Results for commit 3f3b0af. |
Test Results (shard 2)1 480 tests 1 480 ✅ 6m 50s ⏱️ Results for commit 3f3b0af. |
Test Results (shard 4) 10 files 10 suites 7m 59s ⏱️ Results for commit 3f3b0af. |
Test Results (shard 0)959 tests 959 ✅ 6m 23s ⏱️ Results for commit 3f3b0af. |
Test Results (shard 1) 8 files 8 suites 7m 34s ⏱️ Results for commit 3f3b0af. |
Test Results 52 files 52 suites 57m 20s ⏱️ Results for commit 3f3b0af. |
.github/samples-gate.allowstill carried sixcompileentries forFutuRe/{AmericasIns,AsiaRe,EuropeRe}/{LineOfBusiness,TransactionMapping}— NodeTypes thatb63fbf057/091a57a6cretired to plainMarkdownnodes when #2030 landed. Read from the file, those six lines assert that six NodeTypes are still failing to compile in production, which is the condition #1786 reports. They have named nothing for a week.Why the gate's own ratchet could not retire them
Stale-detection asks did this subject pass? (
bake.Types.Any(t => t.Success && t.NodePath == e.Scope)), so it retires an entry whose type now compiles. A subject that no longer exists never passes and never fails — the tester printsunverifiable allow entry (check skipped or scope absent this run)and stays green. Six such lines were printed on everymainrun since #2030.That default is correct there and is left unchanged: the tester is shared with the satellite repos, which stage a subset of their tree, so "listed but absent" is genuinely unknowable for them.
It is not unknowable here:
stage-samples-gate.shcopies all eight packages andstage-doc-gate.shcopies the whole Doc tree, unconditionally. So in this repo "absent" means retired, and it is decidable statically.GateAllowEntrySubjectGuardEvery entry in both allow files must name a subject this repo still ships:
compile/render/tests) → a node file whosecontent.$typeisNodeTypeDefinition;install/idempotence) → a package directory;It complements the gate rather than duplicating it: stale-detection catches fixed, this catches gone.
Proven non-vacuous
With the six lines restored the guard fails naming all six and saying what each became:
TheResolverIsNotVacuouspins the resolver from both sides — a live NodeType resolves as a NodeType, the six retired files resolve and are rejected, a fabricated path resolves to nothing, and the Doc lane'sDoc/prefix really addresses the documentation tree — so it cannot degrade into a check that answers "found" for everything.The two
PensionFundentries stay: separately diagnosed debt this issue does not own, both still naming live subjects.Verification
dotnet build test/MeshWeaver.Graph.Test/MeshWeaver.Graph.Test.csproj -c Release -warnaserror→0 Warning(s), 0 Error(s)No What's New entry — CI-internal, no user-visible effect.
Part of #1786.
🤖 Generated with Claude Code