Skip to content

Bind the classifier-equivalence invariant and close the invalid-JSON target arm (#1057) - #1063

Merged
The01Geek merged 3 commits into
mainfrom
issue-1057-bind-classifier-equivalence
Aug 1, 2026
Merged

Bind the classifier-equivalence invariant and close the invalid-JSON target arm (#1057)#1063
The01Geek merged 3 commits into
mainfrom
issue-1057-bind-classifier-equivalence

Conversation

@prflow-implementer

@prflow-implementer prflow-implementer Bot commented Aug 1, 2026

Copy link
Copy Markdown

Summary

Changes

Pin-corpus test harness (lib/test/test_pin_corpus_lint.py): test_resolved_target_token_matches_the_classifier_three_shapes now derives its expectations from pin-corpus-classifier.py_portable_target for the in-repo file shape and recover_override_names for the runtime-bundle sentinel — rather than hardcoded literals, so a change to the classifier's target resolution turns the test RED. Added a load_classifier() loader mirroring the existing load_extractor(). The deliberate out-of-repo divergence stays a hardcoded assertion (the linter fails toward not-matched there, unlike the classifier).
Malformed-manifest coverage (lib/test/test_pin_corpus_lint.py): added an invalid-json-target case to test_malformed_retirement_manifest_site_fields_fail_closed exercising the json.loads(row[target_index]) decode-error arm (valid-JSON source, invalid-JSON resolved_target cell) and asserting it fails closed with InfrastructureError — the arm bundle-target rows are most likely to meet in practice.
Docstring (lib/test/pin-corpus-lint.py): _repo_relative_or_none now describes itself as the non-raising copy of the abspath/commonpath/relpath computation (the file has a second, raising copy, _relative_target_path).

Resolves

Resolves #1057

Test Plan

  • test_resolved_target_token_matches_the_classifier_three_shapes passes, and perturbing the classifier's resolution makes it fail (binding proven: equal=False after perturbation).
  • test_malformed_retirement_manifest_site_fields_fail_closed passes, with the new invalid-json-target subcase raising InfrastructureError.
  • The own-site negative control test_retirement_is_scoped_to_the_retired_site remains green (unchanged).
  • lib/test/run.sh reports zero failures and zero skips (verified locally in segments: monolith core 7752/0, test_python_scripts 3424/0, test_module_runner 120 OK, test_pin_corpus_lint 199 OK, all 15 suite modules 0 failed).

Visual Changes

N/A

Breaking Changes

None

…-JSON target arm

Derive the resolved-target-token expectations in
test_resolved_target_token_matches_the_classifier_three_shapes from
pin-corpus-classifier.py (_portable_target, recover_override_names)
instead of hardcoded literals, so a divergence between the classifier's
target resolution and the linter's retirement keying turns the test RED.

Add an invalid-JSON resolved_target case to
test_malformed_retirement_manifest_site_fields_fail_closed exercising the
json.loads(row[target_index]) decode-error arm, asserting it fails closed.

Fix the _repo_relative_or_none docstring to describe itself as the
non-raising copy of the abspath/commonpath/relpath computation.

Closes #1057

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@The01Geek

Copy link
Copy Markdown
Owner

Requesting review. Implements #1057, the deferred suggestions from PR #1044 (issue #1006). This touches a security-adjacent gate, so please weight the failure direction.

The substantive item: test_resolved_target_token_matches_the_classifier_three_shapes asserted _resolved_target_token / _site_retirement_key against hardcoded literals rather than against what the classifier actually produces — so the two agreed only coincidentally. A change to the classifier's target resolution would leave the test green while retirement keying silently diverged from it, reopening exactly the mismatch #1006 closed: a pin poisoned or spared by the wrong key, presenting as an unsatisfiable gate finding with no exit.

What matters most:

  • Does the test now genuinely bind? Deriving the expected token from the classifier is only a fix if a divergence turns it RED. Please check the mutation evidence — change the classifier's resolution and confirm failure. A test that still passes under that mutation has not closed the gap.
  • The own-site negative control must still discriminate. Pin retirement is keyed by literal while revival authorization is keyed by site #1006's fix rests on the pair ("different-site", …, 0) / ("own-site", …, 1) — a literal retired at its own site is still reported. That is what distinguishes a fix from a hole; confirm it survives intact and still fails if the gate goes quiet.
  • The invalid-JSON resolved_target decode-error arm must fail closed.
  • Re-adjudicating individual pins is out of scope per Pin retirement is keyed by literal while revival authorization is keyed by site #1006 — flag anything that amounts to one.

Adjacent context the reviewer may find useful: #1061 documents that a pin outside the existence census has no reachable disposition at all. Nothing here should widen or narrow that census; if this change touches extract_existence_sites or the adjudication key set, that is out of scope and worth flagging.

/prflow:review

@prflow-reviewer prflow-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devflow Review — APPROVE

Diff profile: engine_self_modifying (touches lib/**) → full checklist. 2 files, ~30 lines; no new types, not config-only, not a detect-all audit.
Reviewed HEAD: def7f4e9759fedac96703c1df90cf017da427bb4
Test evidence: CI lib + python tests: success for this commit; additionally ran the three affected tests locally at HEAD — all pass.

Verification

All checklist claims verified against source:

  1. Classifier-equivalence binding (test_resolved_target_token_matches_the_classifier_three_shapes) — expectations now derive from pin-corpus-classifier.py (_portable_target, recover_override_names) instead of hardcoded literals. Confirmed the derivations equal the linter's independent _resolved_target_token for both the in-repo-file shape (docs/x.md) and the runtime-bundle sentinel (/__pin_corpus_runtime__/CI_BUNDLE). The test binds the test-side expectation to the classifier while the linter remains the independent SUT, so classifier target-resolution drift turns it RED — a genuine coupling, not coincidental agreement.
  2. Invalid-JSON resolved_target arm — traced the new invalid-json-target case through csv.reader (double-encoded cells) + json.loads: source_file decodes cleanly, then resolved_target=not-json raises at json.loads(row[target_index]) (line 1804), failing closed with InfrastructureError. It exercises the intended target decode arm, not the earlier literal arm.
  3. Docstring_repo_relative_or_none catches ValueError/returns None (non-raising); _relative_target_path raises InfrastructureError. The "non-raising copy" phrasing is accurate.

Acceptance criteria (issue #1057) — all met

  • Classifier-derived expectations; binding (divergence → RED).
  • Invalid-JSON resolved_target arm exercised, fails closed.
  • No pin re-adjudicated; own-site negative control (test_retirement_is_scoped_to_the_retired_site) untouched and still green.
  • Docstring corrected.
  • Suite green (CI lib + python tests: success).

Findings

None. Well-scoped test-hardening + docstring follow-up; no correctness, silent-failure, or coverage concerns.

@The01Geek

Copy link
Copy Markdown
Owner

Verdict APPROVE (no findings) on b2c912e7; head is now 6140c8a2 and the delta is a main merge with zero authored commits, CI 7/7 green. Merging.

Closes #1057: the classifier-equivalence invariant now binds to what the classifier actually produces rather than to hardcoded literals, so a divergence between target classification and retirement keying can no longer pass green — which is the mismatch #1006 closed and this could silently have reopened.

@The01Geek
The01Geek merged commit 9bf7b7d into main Aug 1, 2026
7 checks passed
@The01Geek
The01Geek deleted the issue-1057-bind-classifier-equivalence branch August 1, 2026 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documented DevFlow docs pass has run on this PR PRFlow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bind the classifier-equivalence invariant and close the invalid-JSON target arm (deferred #1044 review suggestions)

1 participant