From 8918cdc68eda67715e8ee76f3dc65c04273f3277 Mon Sep 17 00:00:00 2001 From: DavertMik Date: Tue, 15 Sep 2026 11:29:29 +0300 Subject: [PATCH] Read which precondition a disabled control names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pilot had one explanation for a disabled control: a required field is missing, fill it. A form can withhold its action for reasons that are not a field at all — an empty selection, an unmet count, a choice made elsewhere — and the page usually says which: the control that states the unsatisfied constraint is itself in the disabled list, and the form marks the fields it actually requires. With a single cause on offer, Pilot attributed the block to whichever field the running scenario happened to be about. It then steered the entire test at that field, looking for validation feedback the app had no reason to show, while the real constraint sat unread in the same state block it was given. A scenario premised on a field being required survived contact with a page that marks the field optional, and the run was judged on a guard that does not exist. Pilot now identifies which precondition is unmet before acting on it, and reports the difference when the page names a constraint the scenario did not predict. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 12 ++++++++++++ src/ai/pilot.ts | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 054ca15e..3c73a994 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 2026-09-15 + +### Fixes + +- [Pilot] A control the page has disabled is no longer read as one missing required field. Pilot had a + single explanation for a disabled control, so it attributed the block to whichever field the scenario + happened to be about and steered the whole test at that field — hunting validation feedback that the + app never had a reason to show. It now identifies which precondition is unmet from what the page + states: other disabled controls name the unsatisfied constraint, and the form marks its required + fields. Where the page names a constraint the scenario did not predict, Pilot reports the difference + instead of testing a premise the app contradicts. + ## 2026-09-14 ### Changes diff --git a/src/ai/pilot.ts b/src/ai/pilot.ts index 2421e77f..c55d3020 100644 --- a/src/ai/pilot.ts +++ b/src/ai/pilot.ts @@ -1134,7 +1134,9 @@ export class Pilot implements Agent { ${interactive ? '- Use askUser() only as last resort.' : ''} Diagnostic patterns (use , executed/element/skipped fields, ariaDiff): - - Click failed + button in "disabled buttons" → required field missing. Instruct fill first. + - Scenario's target control in "disabled buttons" → a precondition is unmet; identify which before acting. + Other disabled controls often name the unsatisfied constraint; "active form" marks [required] fields. + Aim Tester at the constraint the page names, not the one the scenario assumed — note the difference in PROGRESS. - "overlay: none" but Tester targets an overlay → overlay closed; re-trigger. - "region:" in → a large area appeared in place without navigation (subview, wizard step, panel). Direct Tester to act inside it; the rest of the page is still usable. - Action SUCCESS but ariaDiff empty → may have worked without visible DOM change; check result message.