test(loadbearing): positive controls for the vacuous-negative class

STATE pkt. 2 scoped a measurement of the substring guards against tmp_path-
GENERATED artefacts. Measured, not reasoned: every one of the 18 assertions
behind those 11 line refs was detached for real and each is individually
load-bearing. Mutation matrix (src/lib mutated in place, restored + sha-verified,
`git status` clean before and after):

  M1  render_table drops rows            -> ingest_lb:91, sql_lb:104,105   RED
  M2  SQL NULL -> naive str() "None"     -> sql_lb:61,62                   RED
  M3  whole REAL loses its .0            -> sql_lb:69                      RED
  M4  _update_index_lines over-reaches   -> ingest_lb:165,166,189 sql:162  RED
  M5  _update_index_lines under-reaches  -> ingest_lb:188 (negative)       RED
  M6  _link_in_index no-op               -> ingest_lb:169, sql_lb:164      RED
  M7  collision gate clobbers first      -> test_ingest:141                RED
  M8  index label leaks the rationale    -> step8:179,180,194 (negative)   RED
  M9  index label varies per verdict     -> step8:186,187,188              RED
  M10 re-promotion double-links          -> step8:170                      RED
  M11 fold drops the rationale prose     -> step8:151                      RED
  M12 seeding re-mints the verdict id    -> step8:163,164                  RED

A second pass was required because pytest stops at the FIRST failing assert:
six assertions sat behind a failing one and were therefore unmeasured at test
level. Re-run with the preceding assertion neutralised, each of those six is
load-bearing too (ingest_lb:91-B, :166; sql_lb:62, :105; step8:180, :164).

The finding is structural, and it is the reason this commit is not empty. Five
NEGATIVE assertions carried no positive control, so they measure an absence
without ever establishing the presence. Proven by value-proof (not merely a red
proof): under a plausible drift — `_link_in_index` detached, or `description`
stopped carrying the rationale — all three tests stayed GREEN with the control
removed and go RED with it present. green-without / red-with is what makes these
controls value-adding rather than decorative.

  test_ingest_loadbearing.py       the ingest-edge link is asserted PRESENT, in
                                   exactly the form the removal assertion seeks
  test_step8_promotion_loadbearing the marker/rationale are asserted live in the
                                   promoted file before the index/context
                                   exclusions are allowed to mean anything

Next lens, enumerated rather than assumed: the class reaches 23 test files, not
the 4 STATE named — ~34 negative substring assertions in total. "Negative without
a positive control" is the sharp, cheap successor to "substring assertion".

Suite 688 passed; ruff + ruff format + mypy --strict clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PzEtJzL6SKYbYtSQRY5o57
This commit is contained in:
Kjell Tore Guttormsen 2026-07-31 21:15:57 +02:00
commit 123ecc3113
2 changed files with 15 additions and 2 deletions

View file

@ -174,6 +174,10 @@ class TestReingestLayerSafety:
# over-reaches or under-reaches).
bundle = _materialized(tmp_path)
self._promote(bundle)
# Positive control for the negative assertion below: the link is present, in
# EXACTLY the form the removal assertion searches for. Without this the `not in`
# would also pass if the link form drifted — green for the wrong reason.
assert "](ingest-edge.md)" in (bundle / "index.md").read_text(encoding="utf-8")
# The shrunk manifest must sit beside its own fixture/ (root resolves relative to
# the manifest dir), so copy the golden case and rewrite the manifest there.
case = tmp_path / "case"

View file

@ -174,7 +174,13 @@ class TestNeutralLabel:
"""LOAD-BEARING (§11): the index label carries NO verdict signal."""
def test_index_never_carries_the_rationale_or_marker(self, bundle: Path) -> None:
_promote(_document(), bundle)
path = _promote(_document(), bundle)
# Positive control: the signal IS live in the promoted file, in exactly the form
# the index assertions search for. Without it both `not in` checks would also
# pass if the marker stopped being written at all — green for the wrong reason.
promoted_text = path.read_text(encoding="utf-8")
assert MARKER in promoted_text
assert RATIONALE in promoted_text
index_text = (bundle / "index.md").read_text(encoding="utf-8")
assert MARKER not in index_text
assert RATIONALE not in index_text
@ -190,7 +196,10 @@ class TestNeutralLabel:
def test_rendered_read_context_never_carries_the_marker(self, bundle: Path) -> None:
# Belt and braces: the index body flows verbatim into the rendered
# read-context — after promotion it must still exclude the signal.
_promote(_document(), bundle)
path = _promote(_document(), bundle)
# Positive control (same reason as above): the marker is live on disk, so the
# exclusion below measures the RENDERING boundary and not a missing marker.
assert MARKER in path.read_text(encoding="utf-8")
assert MARKER not in bundle_context(bundle)