# Fast-browser performance workflow record
## Status
- Status: active
- Current phase: final verified product ready for independent review.
- Next safe action: pin the clean committed diff, run independent standards/specification reviews, then integrate only through the approved safe source-checkout gate.
## Request and scope
Optimize fast-browser for local development testing and validation, borrowing proven round-trip reductions from jev-ultrafast. The parent orchestrates; subagents implement exclusive slices. Optimize browser/runtime overhead first, with measured correctness-preserving gains rather than a speculative autonomous-agent rewrite.
In scope: redundant browser calls; AX-preserving batched observation metadata; local origin-context calculation; a provider-free paired benchmark; focused regression tests and performance documentation.
Out of scope: new actions, autonomous planning, broader model context, changed model/provider, dependency changes, public API changes, uploads/downloads, personal browser profiles, production access, publishing, and speculative page-state/decision caches. No product UI change. Synthetic fixture HTML is validation material, not a new UI feature.
## Git identity
- Source branch: `main` at `773c628512fdfdf5a139ae1b27833bea97d74255`.
- Remote: `origin/main`, fetched and identical to local main.
- Feature branch: `feature/fast-browser-performance` (must be absent before creation).
- Worktree: `/home/jb/code/harness-tools/.worktrees/fast-browser-performance` (must be absent before creation).
- Omitted source changes: untracked `docs/local-decision-model-feasibility.md`, preserved untouched. No tracked source modifications observed.
- Add `/.worktrees/` to the repository-local Git exclude file before worktree creation. This is local Git housekeeping, not a product change.
- Record path after approval: `docs/plans/fast-browser-performance.md` in the new worktree.
- Reuse existing root node_modules and the pinned Python environment `/home/jb/code/harness-tools/.pi/fast-browser-demo/venv/bin/python`; no installation or lockfile modification. Any worktree-local links are ignored and explicitly owned.
## Acceptance criteria
1. Existing public tools, operation schemas, candidate ordering/limit, field-label privacy, fresh action revalidation, occlusion checks, outcome verification, budgets, session isolation, and no-blind-retry semantics remain intact.
2. Browser hot-path call counts fall deterministically: one target inventory per refresh; no redundant domain enables after the pinned harness attach; browser platform detection at most once per backend; batched observations remove per-candidate partial-AX queries and repeated evaluate/release cycles.
3. Chrome AX data remains authoritative for observation roles and click names. Fill labels retain the existing value-free DOM extraction and never fall back to AX value-bearing names. No field values, raw DOM, selectors, or arbitrary scripts enter observations, provider input, or benchmark reports.
4. Batch resources exist only for one bounded observation chunk and are released on success/failure. Fresh single-target metadata remains the pre-mutation authority. Missing/failed batch data uses the existing safe per-node path where compatible; no blind mutation retry.
5. Origin narrowing remains validated and session-lifetime/serialization aware but does not send a redundant JSONL operation. The effective context still travels with every subsequent browser operation; omitted context restores the session base, and restricted sessions cannot broaden.
6. Benchmark results cover unchanged baseline and optimized code with the same runner/fixture/browser, independent outcome assertions, all attempts retained, startup separate from warm operation timing, p50/p95 and protocol counts. Keep optimizations only when call counts improve and live results show no material regression; investigate noisy or mixed results before claiming gains.
7. Full repository tests/typecheck, focused regressions, real Chromium runtime validation, and two independent review axes pass for the final committed diff. Any environment blocker or unsupported claim remains explicit.
## Approved implementation plan and gates
Plan approval: user selected `approve` (Approve and implement) through ask_user on 2026-09-21. Approval covers the exact slices and source-file omission below, local benchmark browsers/fixtures, local commits, and eventual safe fast-forward integration. It does not authorize dependency changes, production access, API/security-posture changes, or publication.
### Slice A: provider-free measurement and regression fixture
Owner `performance-benchmark` (worker). Exclusive paths: `extensions/fast-browser/performance-benchmark.ts`, `extensions/fast-browser/performance-benchmark.test.ts`, `extensions/fast-browser/performance_probe.py`, `extensions/fast-browser/fixtures/performance.html`.
Build a bounded opt-in runner using existing browser-session/runtime/transport seams. Accept explicit worker/baseline paths and pinned Python/browser configuration rather than copying an old implementation into production. Count CDP/IPC methods and JSONL operations locally without recording arguments, URLs, values, text, or screenshots. A test-only Python probe may wrap the selected worker's helper methods for counting; no product instrumentation switch is required.
Use realistic local account/settings or search/filter form workflows with 0/10/60 eligible controls, fill replacement, immediate/delayed click outcomes, and popup discovery. Assert actual final state independently of action postconditions. Exercise warm repeated observations and complete verified flows; measure cold startup separately. Alternate baseline/optimized arms, aim for at least 20 paired warm samples, retain failures and cleanup results. Deterministic model stubs may exercise orchestration without provider cost; clearly exclude real provider latency and semantic accuracy from claims. Focused tests cover statistics/report accounting, input bounds, failure inclusion, and report privacy. No wall-clock thresholds in unit tests.
### Slice B: remove proven browser-call duplication
Owner `browser-hotpath` (worker). Exclusive paths: `extensions/fast-browser/browser_worker.py`, `extensions/fast-browser/test_browser_worker.py`.
Use a single `Target.getTargets` response for page inventory and opener metadata, preserving filtering and target identity. Remove duplicate Page/DOM/Runtime/Network enables only where pinned browser-harness 0.1.13 already guarantees attempts on attachment. Cache browser-version-derived select-all modifiers per backend lifetime. Reuse the already obtained tab result during fill URL verification. Add exact call-count and behavioral regressions. Do not lengthen polling intervals as a speculative throughput optimization or cache changing document/target state across operations.
### Slice C: AX-preserving observation batching
Owner `browser-hotpath`, serialized after B, same exclusive paths. Use an internal Python-owned script constant to avoid new runtime assets and packaging changes.
Introduce a private optional batch-metadata seam with the legacy backend/fake fallback. Keep full AX candidate discovery and ordering. Resolve eligible backend node IDs into a bounded temporary object group; evaluate existing value-free DOM metadata for a small chunk together, using full AX snapshot role/name rather than redundant partial AX reads; release the object group in finally. Never retain remote node handles or geometry across observations. Keep fresh existing single-node AX/DOM revalidation before act. Cover distinct AX/DOM labels, password/value privacy, disabled/hidden/disconnected nodes, duplicate candidates, limits, malformed/partial responses, navigation/detachment and cleanup. Measure against the baseline before retaining. If the compatible batch path cannot demonstrate safe benefit, retain B and document the blocked experiment instead of weakening contracts.
### Slice D: local origin-context calculation
Owner `runtime-hotpath` (worker). Exclusive paths: `extensions/fast-browser/runtime.ts`, `extensions/fast-browser/runtime.test.ts`.
Compute `narrowOriginPolicy` locally, retaining runtime closed/aborted behavior, serialized session semantics and current validation/error shaping. Subsequent transport/worker operations must still enforce the returned context. Preserve compatibility for direct legacy transport requests. Test no transport dispatch for narrowing, context propagation, rejected broadening, base restoration, closed/aborted sessions and concurrency behavior. Do not remove transport validation, serialized lanes, or change error/mutation semantics to save time.
### Orchestration and documentation
Parent owns `docs/plans/fast-browser-performance.md`, `docs/fast-browser-performance.md`, and the performance section of `extensions/fast-browser/README.md`. No code implementation is assigned to the parent. Record measured boundaries, exact commands, baseline identity, limitations and retained results. Add `docs/todos.md` evidence only for a newly encountered tool defect that cannot be resolved in scope.
Each mutating assignment has a 15-minute deadline. B and C are separate assignments to the same owner; A and D may run in parallel because paths are disjoint. Workers do not commit, delegate mutation, alter dependencies, modify other owners' files, or integrate branches. Parent records before/after Git evidence and inspects every returned diff. A worker hitting its deadline must stop and report its partial state; reassignment requires proven completion.
## Ownership
| Assignment | Owner identity | Deadline | Exclusive paths | Before/after Git evidence | Outcome |
| --- | --- | --- | --- | --- | --- |
| Research browser | browser-performance-research / scout | complete | none; read-only | source unchanged | delivered |
| Research runtime | runtime-performance-research / scout | complete | none; read-only | source unchanged | delivered |
| A benchmark | performance-benchmark / worker | first and correction deliveries within deadlines | four listed new files | initial owned patch `/tmp/pi-present/performance-slice-a-initial.patch`; parent inspected corrections and reran 6 tests/compile/check | committed e10a957; stable 20-pair measurement started |
| B browser duplication | browser-hotpath / worker | completed within deadline | worker Python + Python tests | delivered only owned paths; `/tmp/pi-present/performance-slice-b.patch`; parent reran 47 Python tests (pass) and diff check | committed a79418e |
| C observation batching | browser-hotpath / worker | delivered within deadline | same Python files | owned patch `/tmp/pi-present/performance-slice-c.patch`; parent reran 53 Python tests and diff check | committed 574e083; optimized real Chromium runtime validation passed |
| D origin context | runtime-hotpath / worker | completed within deadline | runtime.ts + runtime.test.ts | owned patch `/tmp/pi-present/performance-slice-d.patch`; parent reran 12 tests and typecheck | committed c0c18a5 |
| Docs/integration | parent | phase bounded | listed docs/README only | record checkpoints | pending |
## Verification matrix
| Surface | Command | Exit code | Outcome |
| --- | --- | --- | --- |
| Baseline typecheck | `bun run typecheck` | 0 | Passed; an accidental nonexistent chained test command then failed, unrelated to repository correctness. |
| Baseline full tests | `bun run test` | 0 | Passed. |
| Baseline fast-browser | `bun run test:fast-browser` | 0 | 220 TS passed, 2 skipped; 42 Python passed. |
| Focused Python | `.pi/fast-browser-demo/venv/bin/python -m unittest discover -s extensions/fast-browser -p 'test_*.py'` | 0 | 61 passed, including counting, batching, stale/privacy, delayed-close and readiness fake-clock regressions. |
| Focused runtime/benchmark | individual `node --test --experimental-strip-types` runs for runtime.test.ts and performance-benchmark.test.ts | 0 | Parent verified 12 runtime and 7 benchmark tests. |
| Integrated static/offline | `bun run typecheck && bun run test` | 0 | Full repository suite passed. Fast-browser: 230 TS passed, 2 opt-in skips; 61 Python passed. No dependency installation. |
| Scenario validation | scenario-cli `--check --format json` for existing local-form/login/popup examples | 0 | All three validated; no browser started by preflight. |
| Real runtime | `FAST_BROWSER_DEVELOPMENT_LIVE=1 node --test --experimental-strip-types extensions/fast-browser/development-live-validation.test.ts` | 0 | Passed with no skip on baseline, batched worker and final corrected worker. Includes private evidence and cleanup. |
| Paired benchmark | command in `docs/fast-browser-performance.md`, 20 pairs plus 3 cold samples per arm | 0 | Final all 46 attempts passed, counters complete, cleanup passed. Warm p50 702 to 279ms; p95 729.05 to 315.30ms; CDP 17,791 to 7,407. Earlier failures retained. |
| Hygiene/package | `git diff --check`; root package tests in full suite | 0 | Passed. Metadata script is an internal Python constant; no external runtime resource needed. |
## Review
Review fixed point: final verified product commits against the fetched source base. Specification is the approved committed record. Standards sources are repository/global AGENTS.md plus fast-browser contracts.
Two new read-only Git-capable `claim-verifier` sessions independently review standards and specification. All authors, parent, and worker identities are excluded. Parent pins base, product HEAD, clean status, tree, commit list and SHA-256 of `git diff --binary --full-index --find-renames ... --`. Reviewers reproduce the digest. Accepted fixes go back to an implementer, followed by verification and fresh independent review.
## Integration and rollback
Commit checked slices locally, fetch source again and rebase only if needed, reverify any changed tree, then review. Fast-forward integration only. Existing untracked source material stays untouched; if the source checkout is still dirty, pause integration rather than moving or deleting it. Approval of omission does not authorize removing the unrelated file.
After safe integration, make one record-only closure commit, prove reachability, and remove only the clean owned worktree/branch. No push or publish. Rollback is a normal revert of focused optimization commits; retain benchmark tooling if useful. If batching fails acceptance, drop only its uncommitted owned changes through a reviewed non-destructive patch, preserving other slices and benchmark evidence.
## Checkpoints and blockers
- Last committed valid checkpoint: approved plan/assignments at 05793fe; B product a79418e, D product c0c18a5, C product 574e083, A product e10a957. Worktree dependency links include workspace-local node_modules; local Git excludes now ignore these symlinks. No dependency installation occurred.
- Blockers: none for implementation. Source still has only the approved unrelated untracked file.
- Worktree creation verified at the specified base and path. `/.worktrees/` was already in local Git excludes; no exclude change was needed.
- Baseline real Chromium development validation passed (opt-in test exit 0, no skips).
- A corrections: alternate pair order, expose per-density timing/count evidence, independently check saved fixture data, make popup postcondition stable, fail/retain evidence on cleanup or missing counters, and sanitize errors to safe categories. This completes existing acceptance criteria without changing public scope.
- A correction smoke passed; historical pre-correction transient popup-close failure is preserved at `/tmp/performance-smoke-final.json`, not attributed to concurrent editing. Stable paired measurements must include all failures.
- First stable 20-pair result `/tmp/fast-browser-performance-20-pairs.json`: exit 1; baseline 19/20 and optimized 18/20 warm flows passed, all six cold attempts passed, counters/cleanup complete. Failures are popup-close verification (optimized samples 10/13, baseline sample 20). 60-control median observation 79 to 30ms; 10-control 16 to 7ms, but aggregate medians 445 to 551ms. These are diagnostic results, not acceptance.
- Additional bounded assignments: browser-hotpath read-only diagnosis (8 minutes), performance-benchmark safe per-operation timing in its existing four paths (15 minutes). Before state acd57ae, product paths clean; only parent performance doc untracked. No scope/API/security expansion: this is required existing benchmark verification.
- Browser diagnosis confirmed one-shot close verification races asynchronous Target.closeTarget completion; removing the duplicate inventory makes the pre-existing race more visible. Proposed correction repeats only inventory reads within the existing action-verification budget, never the close mutation. This restores intended verified-close behavior without API/security changes.
- Browser-hotpath test-first assignment: 8 minutes, only its existing Python test path, at f2e42f5 with benchmark-owned TS files dirty; product Python remains stable during diagnostic measurement. Add deterministic delayed-disappearance and permanent-presence close cases, prove the first fails before the fix, then return. Before patch `/tmp/pi-present/performance-before-close-tests.patch`.
- Timing probe committed 12a6bb6; parent reran 7 benchmark tests and full typecheck. Diagnostic `/tmp/fast-browser-performance-4-pairs-diagnostic-20260921.json` passed all attempts and confirms navigate ~335ms versus observe ~223 to ~88ms. Action times ~110ms remain similar. No provider latency is measured.
- Parent reproduced close tests RED: 4 focused tests, 1 expected failure and 1 expected error for delayed/permanent target presence, 2 passed for inventory/cancellation handling. Test patch `/tmp/pi-present/performance-close-red.patch`.
- Browser-hotpath correction assignment: 15 minutes, same Python worker/test paths; before HEAD 12a6bb6, only owned red tests dirty plus parent doc. Implement single-dispatch close followed by bounded inventory reads under existing ACTION_TIMEOUT_SECONDS. Replace pinned helper's 300ms readiness sleep with <=25ms bounded monotonic polling for the exact same document.readyState == complete predicate and existing timeout, retaining error propagation. Add readiness regression tests before the fix. This changes private polling cadence, not API, security posture, postconditions or budgets. Before patch `/tmp/pi-present/performance-close-red.patch`.
- Corrected close/readiness worker committed 2dc359c; parent inspected patch `/tmp/pi-present/performance-readiness-close-fix.patch` and reran 61 Python tests. Final report `/tmp/fast-browser-performance-20-pairs-final.json` passed all 46 attempts; hash and exact environment/commands are in performance documentation.
- Final verification background task bg_vjl_mubjba9s_12 exited 0 after typecheck, complete repository suite, pinned Python suite, real Chromium runtime test, scenario preflight and diff check. No failures; opt-in general-profile test remains skipped in the default suite, while the development live gate was explicitly run.
- Source fetched again: origin/main still 773c628512fdfdf5a139ae1b27833bea97d74255, no rebase needed. Source checkout still has only the unrelated untracked feasibility document; final integration requires a bounded decision or a clean checkout.
- Next safe action: commit final documentation, pin review bytes, launch independent read-only reviewers. Preserve every failed result.