Skip to content

fix(heal): address Copilot review findings on heal CLI - #20

Merged
philmcneely merged 1 commit into
mainfrom
fix/heal-cli-review-findings
Oct 5, 2026
Merged

philmcneely merged 1 commit into
mainfrom
fix/heal-cli-review-findings

Conversation

@philmcneely

Copy link
Copy Markdown
Owner

Addresses the Copilot review findings on #16 (scripts/heal.py).

Fixed

  • Unvalidated model output executed - the reply is now ast-validated: single-line expression, chain of approved Playwright locator methods, literal arguments only, same receiver as the original. Anything else is discarded (reported "no usable replacement").
  • Empty run counted as pass - verify_passed requires the exact target test (name + classname) to have run, passed, and pytest to exit 0. No tests selected / collection error / no report => reverted.
  • git commit -a - now git add -- <healed files> + git commit -- <healed files>; --open-pr also refuses to start on a dirty tracked tree.
  • grep selector as regex / Unix-only - replaced by an in-process pathlib scan with literal matching.
  • str.replace hits every occurrence - edit is applied by source span to the single located call; a selector appearing more than once is flagged ambiguous and left to a human.
  • --max dropped failures - capped failures are recorded as "not attempted" so they appear in the PR's human-review list.
  • No tests - tests/unit/test_heal_cli.py (27 cases: extraction, literal/ambiguous location, validation incl. injection payloads, verification, revert-on-failure, malicious-output-never-written, --max).

Partly addressed / pushed back

  • Stateful-page snapshot: full replay of the failing test's actions is a larger redesign. Mitigations: optional HEAL_STORAGE_STATE so authenticated pages are snapshotted as a signed-in user (documented), and the snapshot is only grounding - the verified re-run is the real gate, so a wrong snapshot yields a revert, not a bad change. Left as follow-up for true replay.

Verified: unit suite 94 passed; ruff clean.

…ts, stage only healed files

- Reject model replacements that are not a chain of approved Playwright
  locator calls with literal args on the original receiver (ast-validated)
- Accept a heal only if the exact target test ran and pytest exited 0; empty
  selection / collection error / missing report now reverts
- git add/commit only healed files; --open-pr requires a clean tracked tree
- Literal, in-process (pathlib) selector search instead of grep regex
- Replace only the diagnosed occurrence; duplicate locators go to human review
- Failures beyond --max are reported as untouched
- HEAL_STORAGE_STATE for authenticated snapshots
- Unit tests for all of the above
Copilot AI balanced review requested due to automatic review settings October 5, 2026 15:46
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown

✅ All smoke tests passed! View report

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

The validator accepts trailing comments that can suppress code following the replaced locator.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Strengthens the locator-healing CLI’s safety, verification, source editing, and Git handling.

Changes:

  • Validates model-generated locators and verifies exact test outcomes.
  • Applies targeted edits, reports capped failures, and limits commits.
  • Adds authentication-state support, documentation, and unit tests.
File Description
scripts/​heal.py Hardens healing and verification workflows.
tests/​unit/​test_heal_cli.py Tests validation, editing, verification, and reversion.
docs/​USAGE.md Documents safety guarantees and authenticated snapshots.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread scripts/heal.py
Comment on lines +157 to +163
if not proposed or "\n" in proposed or ";" in proposed:
return None
try:
tree = ast.parse(proposed, mode="eval").body
original_tree = ast.parse(original, mode="eval").body
except SyntaxError:
return None
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown

✅ All chromium login tests passed! View report

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown

✅ All firefox login tests passed! View report

@philmcneely
philmcneely merged commit 53c3e83 into main Oct 5, 2026
12 checks passed
@philmcneely
philmcneely deleted the fix/heal-cli-review-findings branch October 5, 2026 17:18
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.

2 participants