RUL-025 — the conformance gate ignores test_id-tagged nodes

Ruling

_scan_non_canonical_nodes (SPEC-106 FR-001, REQ-106-006 — the canonical-schema conformance gate behind kg_schema.py check) counts a keyless canonical-label node as drift only when it carries no test_id property (decision made 2026-08-05, chosen from presented options).

Rationale: the gate's target is production drift — real data written by a non-conforming writer. A node carrying test_id is ephemeral test-fixture data by construction: the per-band session sweep (tests/knowledge_graph/conftest.py::_graph_session_sweep) deletes it at session end. Counting it made the batch-mode conformance test (tests/scripts/test_kg_schema.py) report phantom drift whenever a fixture-seeding module shared its batch — test fixtures legitimately seed minimal keyless nodes (Project by name, Class/Function/File/Test without id) mid-session. Production nodes never carry test_id, so the exemption cannot mask a real non-conforming writer.

The rejected alternative — rewriting every fixture seed to carry canonical keys — is whack-a-mole: any future keyless seed would reintroduce the flake.

Note the asymmetry: a fixture node that lacks BOTH the canonical key AND test_id is still counted (and also leaks past the sweep) — the 2026-08-05 GatewayEvent residue (test_relevance.py's id-keyed seeds) was exactly that case and was fixed on the seed side.

Evidence

Enforcement

Verification

ORCHESTRATA_ENV_PROFILE=test python scripts/run_tests_streaming.py tests/knowledge_graph/test_canonical_schema.py tests/scripts/test_kg_schema.py — green; full gate 2026-08-05 green with zero batch failures.