Review follow-up on 56f24e1:
1. moveSpecPanelToTop's collapse detection was too sensitive: a normal
scroll-to-top on a multi-dimension panel can legitimately drop the
heading count (a lower heading scrolls out of view) without losing
any spec values. SPEC_PANEL_TOP_COLLAPSED is now only raised when
every collected spec dimension value vanishes (count goes from >0
to 0) or the spec panel is no longer recognized as open
(!specPanelOpen or specPanelType == UNKNOWN). Heading count alone
no longer triggers it.
2. A collector failure during the purchase spec probe (e.g.
SPEC_PANEL_TOP_COLLAPSED) previously vanished into
collectPurchaseProbe returning null, so probeOutcome() reported
the generic PURCHASE_SPEC_NOT_MATCHED "商品规格探测失败" — the same
as an ordinary spec mismatch. collectPurchaseProbe now encodes a
failed collect() result (code + message) into the opaque probe
JSON via PurchaseSpecProbePolicy.encodeCollectorFailure, and
PurchaseSpecProbePolicy.demote (replacing demoteIfEmpty, kept as a
deprecated alias) surfaces it as an explicit
PURCHASE_SPEC_PROBE_FAILED failure with a purchaser-readable
message ("规格探测时规格面板被拖动,规格标题消失" for
SPEC_PANEL_TOP_COLLAPSED, a generic message naming the code
otherwise). This keeps PurchaseRehearsalExecutor's probeSpecs
callback contract opaque, so its existing unit tests are untouched.
Tests: PddProductDetailCollectorTest (heading count dropping while
dimensions remain present must not fail collection, still collects
colors/sizes), PurchaseSpecProbePolicyTest (encode/extract collector
failure, demote surfaces SPEC_PANEL_TOP_COLLAPSED and unrecognized
codes explicitly).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NTDbDcwbDw1TSAcE6wfh2F
PddProductDetailCollector.moveSpecPanelToTop always swiped DOWN at
least once even when the panel already showed its topmost color
heading, and required two identical viewport signatures to stop. On
a real device that extra swipe could drag the bottom sheet and make
the color/size headings disappear, after which the purchase spec
probe silently reported spec_probe_completed with zero dimensions
and the server reported the generic PURCHASE_SPEC_NOT_MATCHED,
hiding the real cause (goods 8580, tasks 551/552).
- moveSpecPanelToTop now skips the restore swipe when the panel is
already at top (the first parsed dimension is "color" with visible
values), and stops and fails explicitly (SPEC_PANEL_TOP_COLLAPSED)
if a restore swipe makes headings/dimensions vanish, instead of
swiping further or returning an empty success.
- New AgentDiagnosticReason.SPEC_PANEL_TOP_ALREADY /
SPEC_PANEL_TOP_COLLAPSED record swipe count and heading/dimension
counts before/after (booleans/counts only, no page text).
- New PurchaseSpecProbePolicy demotes an Agent spec_probe_completed
outcome with zero collected dimensions into an explicit
PURCHASE_SPEC_PROBE_EMPTY failure ("规格探测未读取到任何颜色或尺码")
before it is persisted/reported, instead of reaching the server as
a normal empty probe.
- Server resolveProbedSpecs uses the same explicit
PURCHASE_SPEC_PROBE_EMPTY code/message when a probe result has zero
colors and zero sizes, as defense in depth for older Agent builds.
Tests: PddProductDetailCollectorTest (already-at-top skips the
restore swipe; not-at-top restores and still collects; vanishing
headings stop swiping and fail), PurchaseSpecProbePolicyTest, and
service_test.go TestLiveProbeWithNoDimensionsFailsWithExplicitEmptyProbeCode.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NTDbDcwbDw1TSAcE6wfh2F
- PddScreenParser: add REQUIRED_EVIDENCE fallback type after all existing
branches; requires address entry (masked phone in a nearby clickable row),
payment entry (specPanel.paymentAreaAliases in a nearby clickable row) and
one enabled quantity EditText, plus at least one auxiliary signal
(options, summary, close, +/- or submit action). +/- no longer required
on this path; existing branches unchanged.
- The three required items must share one panel container: their lowest
common ancestor must not be a window root and must not cover the whole
screen. Items from an address dialog, a payment dialog and an unrelated
input box are not recognized.
- Purchaser hints on SPEC_PANEL_EVIDENCE_NOT_MATCHED, the spec-panel wait
diagnostic and the address-save timeout when a required item is missing
(default WeChat Pay / default address / quantity input). No Alipay alias.
- Purchase spec-entry wait and post address-save wait: bounded 5000 ms,
fallback panels need two identical structure samples, no Back while
waiting, explicit failure on timeout; boolean/count diagnostics only.
- Final submit target additionally rejects zero-size labels/containers.
- Diagnostics: evidence flags (incl. same-container) in panel evidence and
spec-panel entry event.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NTDbDcwbDw1TSAcE6wfh2F
- PddScreenParser: nested clickable nodes of one labelled option block
(outer block, image, inner text with a badge such as "零差评") are
collapsed into one spec value named by the outer block (task 535). The
click node is still chosen by safeOptionRank; selected/checked flags are
merged from the block members; no badge-text stripping.
- PurchaseRehearsalExecutor: on SPEC_SELECTION_UNCONFIRMED emit a
specSelectionUnconfirmed diagnostic with the dimension, the target value
and the parsed option texts (each truncated to 40 chars) with selected
flags. Spec values are product attributes only.
- Tests: SpecOptionDedupTest with a sanitized task 535 fixture.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NTDbDcwbDw1TSAcE6wfh2F
Allow up to two consecutive evidence-free PayActivity transition samples after the single safe Back; fail on the third post-Back sample (200ms cadence) to preserve a finite no-click payment boundary.