Forensic Repo Surgeon validation dossier
Authenticated mobile date range drawer evidence capture
Capture an authenticated mobile transaction-feed state with the date range drawer open. This page is generated from artifacts only; raw files are linked for audit.
Before And After
User Workflow
- Open the mobile sign-in route
- Log in with a seeded local user
- Wait for the transaction feed
- Open the date range filter drawer
- Capture the resulting mobile UI state and evidence bundle
Before Negative Control
- passing: expected before-state failure
- pass: date range drawer is visible
- pass: drawer close button is visible
- pass: calendar container is within the mobile viewport
- fail: calendar starts near top of the mobile viewport
- pass: no unexpected console errors appear during drawer verification
Verification Assertions
- pass: date range drawer is visible
- pass: drawer close button is visible
- pass: calendar container is within the mobile viewport
- pass: calendar starts near top of the mobile viewport
- pass: no unexpected console errors appear during drawer verification
Source Localization
- #1 src/components/TransactionDateRangeFilter.tsx score 541
Matches data-test hooks found in the captured DOM. File path/name matches the case vocabulary. - #2 src/components/TransactionListAmountRangeFilter.tsx score 342
Matches data-test hooks found in the captured DOM. File path/name matches the case vocabulary. - #3 src/components/TransactionItem.tsx score 270
Matches data-test hooks found in the captured DOM. File path/name matches the case vocabulary. - #4 src/components/TransactionDetail.tsx score 249
Matches data-test hooks found in the captured DOM. File path/name matches the case vocabulary. - #5 src/components/NavBar.tsx score 244
Matches data-test hooks found in the captured DOM.
Gate Details
- pass: artifactsComplete
- pass: negativeControlPassed
- pass: verificationPassing
- pass: localizationPresent
- pass: patchRelevant
- pass: reasonerPresent
- pass: reasonerReferencesArtifacts
- pass: doctorPassing
- pass: runCompleted
- pass: cleanupSucceeded
- pass: redactionPassed
Changed Files
src/components/TransactionDateRangeFilter.tsx
Reasoning Boundary
- provider: anthropic-messages-api
- live model used: yes
- model: claude-opus-4-7
- request id: req_011CaRqNdjdr9PnP8Au1qZWN
- latency: 14323ms
- usage: input 1094 / output 873
- intended model boundary: claude-code-or-anthropic-api
- recorded run note: This recorded run used the Anthropic Messages API to generate the reasoner diagnosis from summarized evidence artifacts.
- truth boundary: The reasoner proposes and explains. Deterministic verification, doctor, run timeline, and scorecard decide acceptance.
Model Authorship — Claude Code Agent Loop
Opus 4.7 ran inside the target repository and authored a candidate patch using Read, Glob, Grep, and Edit tools. The deterministic verifier evaluated this patch against the same gates as the fixture above.
- provider: claude-agent-sdk
- live model used: yes
- model: claude-opus-4-7
- session id: 4fa8a3cb-0649-434c-a033-b4403dfd7a68
- loaded tools: Task, AskUserQuestion, Bash, CronCreate, CronDelete, CronList, Edit, EnterPlanMode, EnterWorktree, ExitPlanMode, ExitWorktree, Glob, Grep, Monitor, NotebookEdit, PowerShell, PushNotification, Read, RemoteTrigger, ScheduleWakeup, Skill, TaskOutput, TaskStop, TodoWrite, ToolSearch, Write
- result subtype: success
- tokens: input 8 / output 3680 / cache-read 78288
- truth boundary: The agent proposes a candidate patch. The deterministic verifier evaluates it against the same gates as the fixture patch.
- recorded run note: Model-authored patch produced by Claude Code agent loop running inside the target repository. The deterministic verifier evaluates this candidate alongside the fixture patch.
Model-Authored Patch
This diff was authored by Claude Code (claude-opus-4-7) inside the target repository. The same deterministic verifier evaluated it against the same gates as the fixture patch above.
diff --git a/src/components/TransactionDateRangeFilter.tsx b/src/components/TransactionDateRangeFilter.tsx
index 9822724..d1ab232 100644
--- a/src/components/TransactionDateRangeFilter.tsx
+++ b/src/components/TransactionDateRangeFilter.tsx
@@ -139,7 +139,7 @@ const TransactionListDateRangeFilter: React.FC<TransactionListDateRangeFilterPro
id={dateRangeId}
open={dateRangeOpen}
ModalProps={{ onClose: handleDateRangeClose }}
- anchor="bottom"
+ anchor="top"
data-test="date-range-filter-drawer"
>
<Button data-test="date-range-filter-drawer-close" onClick={() => handleDateRangeClose()}>
Agent Timeline
Each turn shows what Opus 4.7 said and what tools it called. Tool calls are the substance: Read, Glob, Grep for understanding; Edit for the candidate patch.
- Turn 1
-
Turn 2
- Read:
D:/Repo/ALL HACKATHONS/Cerebral Valley & Anthropic - Built with Opus 4.7 Claude Code hackathon/.surgeon-targets/cypress-realworld-app/src/components/Transact...
- Read:
- Turn 3
-
Turn 4
Now I understand the bug. The drawer uses `anchor="bottom"`, which slides up from the bottom of the viewport. That places the calendar near the bottom, so `[data-test="transaction-list-filter-date-range"]` has a `top` far greater than 120px. The verifier needs the calendar's top within 120px of the viewport top, so changing the anchor to `"top"` will make the drawer slide from the top — placing the close button at top and the calendar just below it (well within 120px).
-
Turn 5
- Edit:
D:/Repo/ALL HACKATHONS/Cerebral Valley & Anthropic - Built with Opus 4.7 Claude Code hackathon/.surgeon-targets/cypress-realworld-app/src/components/Transact...
- Edit:
-
Turn 6
### Summary I edited `src/components/TransactionDateRangeFilter.tsx` and changed the mobile (`xsBreakpoint`) `Drawer`'s `anchor` from `"bottom"` to `"top"`. Previously the drawer slid up from the bottom of the iPhone 13 viewport, which placed the calendar (`[data-test="transaction-list-filter-date-range"]`) hundreds of pixels down — well past the 120px top threshold the verifier asserts. With `anchor="top"`, the drawer is pinned to the top of the viewport, so the close button sits at the top edge and the calendar's `top` lands roughly 36–48px down — comfortably within 120px and still inside t...
Recorded Run Environment
This section reports the machine that produced this recorded run. It does not validate the reviewer's current machine.
- passing: controller Node runtime
Node 20.11.1; target app runtime is checked separately. - passing: target Node runtime
target Node runtime: D:\Repo\ALL HACKATHONS\Cerebral Valley & Anthropic - Built with Opus 4.7 Claude Code hackathon\tools\node-v22.12.0-win-x64\node.exe - passing: pnpm package manager
9.15.0 - passing: case patch fixture
D:\Repo\ALL HACKATHONS\Cerebral Valley & Anthropic - Built with Opus 4.7 Claude Code hackathon\patches\crwa-mobile-date-range-drawer.diff - passing: demo ports
Ports 3000, 3001 are free. - passing: cypress-realworld-app target repo
D:\Repo\ALL HACKATHONS\Cerebral Valley & Anthropic - Built with Opus 4.7 Claude Code hackathon\.surgeon-targets\cypress-realworld-app - passing: case patch artifact
D:\Repo\ALL HACKATHONS\Cerebral Valley & Anthropic - Built with Opus 4.7 Claude Code hackathon\artifacts\crwa-mobile-date-range-drawer\patch.diff - passing: workspace drive
D:\Repo\ALL HACKATHONS\Cerebral Valley & Anthropic - Built with Opus 4.7 Claude Code hackathon has 17.2 GiB free. - passing: target drive
D:\Repo\ALL HACKATHONS\Cerebral Valley & Anthropic - Built with Opus 4.7 Claude Code hackathon\.surgeon-targets\cypress-realworld-app has 17.2 GiB free. - passing: target patch state
Target is in before-state and patch can be applied.
Run Timeline
- passing: preflight-doctor 966ms
- passing: reset-target-before-state 162ms
- passing: start-target 11.1s
- passing: capture-failing-evidence 9.9s
- passing: capture-before-verification 3.3s
- passing: localize-source-candidates 148ms
- passing: reason-over-artifacts 14.4s
- passing: apply-target-patch 258ms
- passing: capture-passing-verification 4.0s
- passing: write-repair-hypothesis 7ms
- passing: regenerate-pr-report 7ms
- passing: write-artifact-viewer 43ms
- passing: typecheck-controller 7.6s
- passing: restore-target-before-state 214ms
- passing: stop-target 367ms
- passing: write-proof-scorecard 22ms
- passing: write-github-summary 21ms
- passing: write-evidence-manifest 52ms
- passing: refresh-artifact-viewer 29ms
- passing: write-demo-cockpit 32ms
- passing: export-demo-package 500ms
Repair Hypothesis
# Repair Hypothesis
Case: `crwa-mobile-date-range-drawer`
## Evidence Read
- Before screenshot: `./artifacts/crwa-mobile-date-range-drawer/failure.png`
- Browser trace: `./artifacts/crwa-mobile-date-range-drawer/trace.zip`
- DOM snapshot: `./artifacts/crwa-mobile-date-range-drawer/dom-snapshot.json`
- Accessibility tree: `./artifacts/crwa-mobile-date-range-drawer/ax-tree.json`
## Localization Hypothesis
The highest-confidence source candidate is `src/components/TransactionDateRangeFilter.tsx` with score `541`.
- Matches data-test hooks found in the captured DOM.
- File path/name matches the case vocabulary.
## Root-Cause Hypothesis
Two independent issues evidenced in console.ndjson: (1) one or more XState machines (likely the auth/transaction filter machines) still declare transient transitions using `{ on: { '': ... } }` instead of `{ always: ... }`; (2) the SvgCypressLogo component renders an SVG <stop> element with the kebab-case attribute `stop-color` rather than React's camelCase `stopColor`. Neither warning is conclusively tied to TransactionDateRangeFilter.tsx from the evidence alone, despite it being the top source candidate by data-test hook match.
## Patch Hypothesis
In SvgCypressLogo, rename `stop-color` to `stopColor` on the affected <stop> element(s) to clear the React DOM property warning. Separately, in the XState machine config(s) emitting the transient-transition warning, replace `on: { '': <target> }` with `always: <target>`. Scope the change to the offending machine and SVG component without restructuring the date range drawer.
Changed files:
- `src/components/TransactionDateRangeFilter.tsx`
## Verification Evidence
- Before-state negative control: `passing`
- Verification status: `passing`
- pass: date range drawer is visible
- pass: drawer close button is visible
- pass: calendar container is within the mobile viewport
- pass: calendar starts near top of the mobile viewport
- pass: no unexpected console errors appear during drawer verification
## Truth Boundary
This hypothesis is not proof by itself. The proof is the passing verification artifact plus the before/after browser evidence.
- Residual risk: Top candidate TransactionDateRangeFilter.tsx may not be the actual source of the XState warnings; fix could land in a different machine file.
- Residual risk: Multiple machines may share the deprecated pattern; a single patch might not silence all three warnings.
- Residual risk: Renaming SVG attributes could affect snapshot tests that capture serialized DOM.
- Residual risk: Console warnings are non-blocking; underlying drawer functionality on mobile is not validated by clearing them.
Reasoner Artifact
# Reasoning Boundary
Case: `crwa-mobile-date-range-drawer`
Provider: `anthropic-messages-api`
Live model used: `yes`
Model: `claude-opus-4-7`
Request id: `req_011CaRqNdjdr9PnP8Au1qZWN`
Latency: `14323ms`
Usage: `input 1094 / output 873`
Intended model boundary: `claude-code-or-anthropic-api`
This recorded run used the Anthropic Messages API to generate the reasoner diagnosis from summarized evidence artifacts.
## Truth Boundary
The reasoner proposes and explains. Deterministic verification, doctor, run timeline, and scorecard decide acceptance.
## Evidence References
- `./artifacts/crwa-mobile-date-range-drawer/failure.png`
- `./artifacts/crwa-mobile-date-range-drawer/trace.zip`
- `./artifacts/crwa-mobile-date-range-drawer/console.ndjson`
- `./artifacts/crwa-mobile-date-range-drawer/network.ndjson`
- `./artifacts/crwa-mobile-date-range-drawer/ax-tree.json`
- `./artifacts/crwa-mobile-date-range-drawer/dom-snapshot.json`
- `./artifacts/crwa-mobile-date-range-drawer/candidates.json`
- `./artifacts/crwa-mobile-date-range-drawer/patch.diff`
- `./artifacts/crwa-mobile-date-range-drawer/verify.json`
## Top Source Candidate
- `src/components/TransactionDateRangeFilter.tsx` score `541`
- Matches data-test hooks found in the captured DOM.
- File path/name matches the case vocabulary.
## Diagnosis
- Symptom: On iPhone 13 viewport at /signin (authenticated UI flow), capturing the mobile transaction-feed with the date range drawer open surfaces console noise: repeated XState warnings about deprecated empty-string transient transition configs and a React warning about an invalid DOM property `stop-color` (should be `stopColor`) inside SvgCypressLogo.
- Likely root cause: Two independent issues evidenced in console.ndjson: (1) one or more XState machines (likely the auth/transaction filter machines) still declare transient transitions using `{ on: { '': ... } }` instead of `{ always: ... }`; (2) the SvgCypressLogo component renders an SVG <stop> element with the kebab-case attribute `stop-color` rather than React's camelCase `stopColor`. Neither warning is conclusively tied to TransactionDateRangeFilter.tsx from the evidence alone, despite it being the top source candidate by data-test hook match.
- Patch hypothesis: In SvgCypressLogo, rename `stop-color` to `stopColor` on the affected <stop> element(s) to clear the React DOM property warning. Separately, in the XState machine config(s) emitting the transient-transition warning, replace `on: { '': <target> }` with `always: <target>`. Scope the change to the offending machine and SVG component without restructuring the date range drawer.
## Verification Plan
- Re-run the crwa-mobile-date-range-drawer capture and confirm console.ndjson no longer contains the `stop-color`/`stopColor` React warning.
- Confirm the three XState 'Empty string transition configs' warnings disappear after switching to `always`.
- Visually verify in failure.png follow-up that the Cypress logo and date range drawer still render correctly on 390x844.
- Diff ax-tree.json before/after to ensure no accessibility regressions in the drawer.
- Run existing unit/e2e tests covering TransactionDateRangeFilter and auth state machine.
## Residual Risks
- Top candidate TransactionDateRangeFilter.tsx may not be the actual source of the XState warnings; fix could land in a different machine file.
- Multiple machines may share the deprecated pattern; a single patch might not silence all three warnings.
- Renaming SVG attributes could affect snapshot tests that capture serialized DOM.
- Console warnings are non-blocking; underlying drawer functionality on mobile is not validated by clearing them.
Evidence Integrity
# Evidence Integrity Manifest Case: `crwa-mobile-date-range-drawer` Generated at: `2026-04-26T05:32:10.047Z` Bundle fingerprint: `01ba72ba50a5de70577b7c70ab26db6330990aa21c985d59b175b5787a79060b` This is an unsigned SHA-256 integrity map. It helps compare copies of the package or case artifacts, but it is not independent signed provenance. ## Review Order 1. Compare `./artifacts/crwa-mobile-date-range-drawer/failure.png` and `./artifacts/crwa-mobile-date-range-drawer/success.png`. 2. Read `./artifacts/crwa-mobile-date-range-drawer/reasoner.md`, `./artifacts/crwa-mobile-date-range-drawer/PR.md`, and `./artifacts/crwa-mobile-date-range-drawer/scorecard.json`. 3. Use the hashes below to compare this artifact set against another copy. ## Hashed Files - `axTree` -> `./artifacts/crwa-mobile-date-range-drawer/ax-tree.json` sha256 `711c35d477cfb13f682b0844824673a34295560ccf6d05fe38edc46df0dd4644` size `201980` - `beforeVerify` -> `./artifacts/crwa-mobile-date-range-drawer/before-verify.json` sha256 `02c67998b3ec6c211520739689344e0005ca2e1d1acd554a63b2ddaeec946cc8` size `1612` - `candidates` -> `./artifacts/crwa-mobile-date-range-drawer/candidates.json` sha256 `1fd41a8c4eb96fda807f983512a950a76712131f3de7bf3df1c242abdaf9f99d` size `48111` - `console` -> `./artifacts/crwa-mobile-date-range-drawer/console.ndjson` sha256 `a5a653ca09f8f6abc8071577d4410816683b1afe0032d12a845f0f59b90a451f` size `6425` - `doctor` -> `./artifacts/crwa-mobile-date-range-drawer/doctor.json` sha256 `5cfe6ddf3f7c7a6b4f42e93b81f2a8560ca42c046b5d890ce313b70105bf97d6` size `2302` - `domSnapshot` -> `./artifacts/crwa-mobile-date-range-drawer/dom-snapshot.json` sha256 `561b2a1a89800c703c593c448915d280850bde6f4c1cfd2b606813362b01a580` size `715905` - `screenshot` -> `./artifacts/crwa-mobile-date-range-drawer/failure.png` sha256 `87606cabfdc494c5cb02533c53d1080ec4bbddc75f3d718134496fa2e768f8b0` size `27554` - `hypothesis` -> `./artifacts/crwa-mobile-date-range-drawer/hypothesis.md` sha256 `f9097637a4ed961fea78fac4a8dc69f6cb6e4ca6115cbf90964c15e80fa8558d` size `2666` - `input` -> `./artifacts/crwa-mobile-date-range-drawer/input.json` sha256 `ea7e59c03b0e6c36337627fe36a9aed83e2bfde8d1b5cfaac54153f71cb1fc0d` size `2451` - `network` -> `./artifacts/crwa-mobile-date-range-drawer/network.ndjson` sha256 `6ebf0e19ab0ca62414251188decb48bb4df3c59ec78c8fd876ebb3f8327e0135` size `15639` - `patch` -> `./artifacts/crwa-mobile-date-range-drawer/patch.diff` sha256 `603a03fc3c0ae9cbdd5e0f4d401276b3ab214f6ad31d972290b9fc6691e12a15` size `1472` - `report` -> `./artifacts/crwa-mobile-date-range-drawer/PR.md` sha256 `2f3de4ff2b79f0e40bdd6cbd1359f5b395af56993a3c4a3cd342ab139fe3ceaa` size `4382` - `reasoner` -> `./artifacts/crwa-mobile-date-range-drawer/reasoner.json` sha256 `1c6edf937ce004f896e9c02d4e30889f4809a3582b2997225e949c05fb36f6c2` size `3980` - `reasonerReport` -> `./artifacts/crwa-mobile-date-range-drawer/reasoner.md` sha256 `c4aa5e33164d684d029709b9bcea1d8aa5fbc71537fbce1dd1e5a9d9780a6c24` size `3669` - `redactionReport` -> `./artifacts/crwa-mobile-date-range-drawer/redaction-report.json` sha256 `d88e4a4f989a702f1809ced93b8858e02998e2d910915c3d9ad7dd561fe6488b` size `219` - `scorecard` -> `./artifacts/crwa-mobile-date-range-drawer/scorecard.json` sha256 `17195c806c800beebdf9a1c7a3fc7fc2fa720658d1903ea8810c296905811c25` size `4215` - `success` -> `./artifacts/crwa-mobile-date-range-drawer/success.png` sha256 `48975cdae0fda13c3476769a8bab742bfc3ae024f52d73f697e7881154ab0985` size `12059` - `trace` -> `./artifacts/crwa-mobile-date-range-drawer/trace.zip` sha256 `f5cf46449cb27af1f4ac9d77c621a8ef6116fda7492298bdbcc1fa1b5b4b0c1a` size `1198093` - `verify` -> `./artifacts/crwa-mobile-date-range-drawer/verify.json` sha256 `e392e6eecafeb00638d59f74edee7e2838493794650ab937d1981923441f8c24` size `1224`
Reasoner Evidence
./artifacts/crwa-mobile-date-range-drawer/failure.png./artifacts/crwa-mobile-date-range-drawer/trace.zip./artifacts/crwa-mobile-date-range-drawer/console.ndjson./artifacts/crwa-mobile-date-range-drawer/network.ndjson./artifacts/crwa-mobile-date-range-drawer/ax-tree.json./artifacts/crwa-mobile-date-range-drawer/dom-snapshot.json./artifacts/crwa-mobile-date-range-drawer/candidates.json./artifacts/crwa-mobile-date-range-drawer/patch.diff./artifacts/crwa-mobile-date-range-drawer/verify.json
Verification Plan
- Re-run the crwa-mobile-date-range-drawer capture and confirm console.ndjson no longer contains the `stop-color`/`stopColor` React warning.
- Confirm the three XState 'Empty string transition configs' warnings disappear after switching to `always`.
- Visually verify in failure.png follow-up that the Cypress logo and date range drawer still render correctly on 390x844.
- Diff ax-tree.json before/after to ensure no accessibility regressions in the drawer.
- Run existing unit/e2e tests covering TransactionDateRangeFilter and auth state machine.
Patch Diff
diff --git a/src/components/TransactionDateRangeFilter.tsx b/src/components/TransactionDateRangeFilter.tsx
index 9822724..32dd373 100644
--- a/src/components/TransactionDateRangeFilter.tsx
+++ b/src/components/TransactionDateRangeFilter.tsx
@@ -141,6 +141,13 @@ const TransactionListDateRangeFilter: React.FC<TransactionListDateRangeFilterPro
ModalProps={{ onClose: handleDateRangeClose }}
anchor="bottom"
data-test="date-range-filter-drawer"
+ PaperProps={{
+ sx: {
+ height: "100vh",
+ maxHeight: "100vh",
+ overflow: "hidden",
+ },
+ }}
>
<Button data-test="date-range-filter-drawer-close" onClick={() => handleDateRangeClose()}>
Close
@@ -173,8 +180,8 @@ export function RangeCalendar({
}) {
const [value, setValue] = useState<Value>(defaultValue);
- const width = xsBreakpoint ? window.innerWidth : 350;
- const height = xsBreakpoint ? window.innerHeight : 300;
+ const width = xsBreakpoint ? "100vw" : 350;
+ const height = xsBreakpoint ? "calc(100vh - 48px)" : 300;
const handleChange = (val: Value, _: any) => {
setValue(val);
@@ -187,6 +194,9 @@ export function RangeCalendar({
style={{
width,
maxWidth: "100%",
+ height,
+ overflowY: "auto",
+ boxSizing: "border-box",
background: color["400"],
padding: 8,
borderRadius: 8,