Skip to content

fix(review): six more — reporting honesty, surface parity, two vacuous tests - #35

Merged
henleda merged 1 commit into
mainfrom
fix-review-tail
Aug 5, 2026
Merged

fix(review): six more — reporting honesty, surface parity, two vacuous tests#35
henleda merged 1 commit into
mainfrom
fix-review-tail

Conversation

@henleda

@henleda henleda commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Sixth PR from the deep-dive review. 26 of 27 findings now closed.

Reporting honesty

1. report.html claimed "✓ code fix drafted" for a dependency upgrade. The badge keyed on the mere presence of a remediation. There is no file to patch in someone else's package and pr.py writes no diff for one — so the card described work that does not exist, contradicting the hero on the same page. Three outcomes now:

dependency upgrade   -> ↑ dependency upgrade — log4j-core → 2.17.1
real code fix        -> ✓ code fix drafted
plan with no patch   -> cure planned — no patch drafted

2. The blast-radius table reported an unmeasured replay as safe. simulate computes evaluated, errored, enforcement_confirmed and reason, and the table used none of them. A replay in which every request failed in transit rendered as green "within threshold" at 0.0% — a rate that means "we measured nothing", presented as "safe to promote". Now four verdicts (not measured / unconfirmed / within / over) plus a caveats column carrying the reason and the transit-failure count.

3. reconcile reported a transport failure as "no runnable probe". {} is what "no probe recorded" returns — a permanent condition an operator can only fix by re-scanning. A probe that exists and blew up in transport is transient. Reporting the second as the first sends someone to fix the wrong thing. It now has its own hold code that says the next pass will retry. (auth_failed already existed for exactly this reason — the pattern was one case short.)

Surface parity

4. MCP ignored VPCOPILOT_SIM_THRESHOLD. The threshold was a lookup each surface had to remember. The CLI, console and refiner remembered; MCP did not — so an operator who tightened the blast-radius threshold got the default silently applied to every simulation an agent ran, and the number they set was the number they believed was in force.

Now simulate.effective_threshold, one resolver all four call, pinned by a test that asserts no caller re-implements the lookup — because the defect was one caller not calling it. A malformed value is refused rather than silently defaulted: substituting the default would apply a threshold the operator did not choose, on the gate that decides whether a policy is safe to promote, and they would never be told. An empty value is treated as unset, not malformed.

Two vacuous tests

5. test_safe_rollback_restores_and_verifies never tested "verifies". FakeXC genuinely applies the PUT, so the restore succeeded on its own and verify returned True whatever it did — delete the verify call from safe_rollback entirely and the test still passed. It was asserting the behaviour of the fake.

The new test uses an appliance that accepts the rollback PUT and applies nothing — a 200 that changed nothing, which is what a partially degraded control plane looks like. Without the verify step, safe_rollback returns True and the caller reports a clean rollback while the band-aid is still attached to a live load balancer: the "silent half-rollback" the module docstring calls the worst outcome on a live LB.

6. The four-place registration guard was a whole-file substring search. It asserted "resolve" in report.py — which the unrelated word "resolved" elsewhere in that module already satisfied. It passed with the agent missing from the very list it guarded. report.py now exposes REPORTED_AGENTS and the test asserts the list; a second test asserts all four sites agree with each other, which holds for the next agent rather than for this one by name.

One fixture corrected, called out

tests/test_report.py's remediation carried empty diff and patched_content, so it was asserting the drafted-fix badge for a plan with no patch. Given a real patch — the fixture was unrealistic (a code_fix with no patch is nothing for pr.py to write), not a behaviour change I am papering over.

Verification

  • 10 new tests, suite 1067 → 1077, ruff clean.
  • Mutation-verified: reverting the four source fixes fails 7 of them; the two vacuous tests now fail against the mutations they previously survived (dropping verify from safe_rollback, removing resolve from REPORTED_AGENTS).
  • Live suite: 18 passed against the real tenant and BIG-IP, with the estates confirmed restored afterwards — 0 ASM policies on the appliance, Larkspur LK-1001 at 48215, vpcopilot-lab back to baseline.

What is left

One finding remains open, and it deserves its own PR rather than being folded in here: the spec-vs-code orphan comparison (pipeline.py:152). It is not a small bug — served is never derived from code in any configuration, so with no in-repo spec every declared endpoint is reported as unserved, and with one the comparison is spec-vs-spec and a genuinely undeclared route is reported nowhere. It also synthesises a Finding that bypasses the verify agent and can draw a real api_schema band-aid, so a wrong answer there is load-bearing. The honest fix likely involves declining the comparison when route extraction found nothing, which is a design decision worth reviewing on its own.

The two remaining cli.py items (scan-path existence, run-dir existence — both "enforced only on MCP") go with it.

🤖 Generated with Claude Code

…s tests

1. report.html claimed "✓ code fix drafted" for a dependency upgrade.

   The badge keyed on the mere PRESENCE of a remediation, so a
   `dependency_upgrade` — where there is no file to patch and pr.py writes no
   diff — claimed a drafted code fix, contradicting the hero on the same page.
   Three outcomes now: upgrade (naming package and version), drafted code fix,
   and "cure planned — no patch drafted" for a plan carrying neither a diff nor
   patched_content.

2. The blast-radius table reported an unmeasured replay as safe.

   `simulate` computes evaluated / errored / enforcement_confirmed / reason and
   the table used NONE of them, so a replay in which every request failed in
   transit (evaluated=0, errored=12, reason="nothing measurable") rendered as a
   green "within threshold" at 0.0% — a rate that means "we measured nothing",
   presented as "safe to promote". Now: not measured / unconfirmed / within
   threshold / over threshold, with a caveats column carrying the reason.

3. reconcile reported a transport failure as "no runnable probe".

   `{}` is what "no probe recorded" returns — a PERMANENT condition an operator
   can only fix by re-scanning. A probe that exists and blew up in transport is
   TRANSIENT. Reporting the second as the first sends someone to fix the wrong
   thing. Now its own hold code, saying the next pass will retry.

4. MCP ignored VPCOPILOT_SIM_THRESHOLD.

   The threshold was a lookup each surface had to REMEMBER. CLI, console and
   refiner remembered; MCP did not — so an operator's tightened blast-radius
   threshold was silently replaced by the default for every simulation an agent
   ran. Now `simulate.effective_threshold`, one resolver all four call, and a
   malformed value is REFUSED rather than silently defaulted: substituting the
   default would apply a threshold the operator did not choose to the gate that
   decides whether a policy is safe to promote.

5. test_safe_rollback_restores_and_verifies never tested "verifies".

   FakeXC genuinely applies the PUT, so the restore succeeded on its own and
   `verify` returned True whatever it did — delete the verify call from
   safe_rollback and the test still passed. It was asserting the behaviour of
   the fake. A new test uses an appliance that ACCEPTS the rollback PUT and
   applies nothing (a 200 that changed nothing), which is what a partially
   degraded control plane looks like, and asserts RollbackError plus the audit
   record. Without it, safe_rollback reports a clean rollback while the band-aid
   is still attached to a live LB — the "silent half-rollback" the module
   docstring calls the worst outcome.

6. The four-place agent registration guard was a whole-file substring search.

   It asserted `"resolve" in report.py`, which the unrelated word "resolved"
   already satisfied — so it passed with the agent missing from the very list it
   guarded. report.py now exposes REPORTED_AGENTS and the test asserts the LIST;
   a second test asserts all four sites AGREE, which holds for the next agent
   rather than for this one by name.

Also: tests/test_report.py's remediation fixture carried empty `diff` and
`patched_content`, so it was asserting the drafted-fix badge for a plan with no
patch. Given a real patch — an unrealistic fixture, not a behaviour change.

10 new tests; suite 1067 -> 1077. Mutation-verified: reverting the four source
fixes fails 7, and the two vacuous tests fail against the mutations they
previously survived. Live suite: 18 passed, estates restored (0 ASM policies,
Larkspur balance 48215, vpcopilot-lab at baseline).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@henleda
henleda merged commit 6d75865 into main Aug 5, 2026
4 checks passed
@henleda
henleda deleted the fix-review-tail branch August 5, 2026 13:21
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.

1 participant