Skip to content

feat(analysis-view): page retained browser scenario steps and text - #4163

Open
kangyishuai wants to merge 29 commits into
morluto:mainfrom
kangyishuai:feat/4069-ui-state-transition-view
Open

kangyishuai wants to merge 29 commits into
morluto:mainfrom
kangyishuai:feat/4069-ui-state-transition-view

Conversation

@kangyishuai

@kangyishuai kangyishuai commented Oct 15, 2026 •

Copy link
Copy Markdown

Summary

Refs #4069 (RFC: evidence-backed UI state/transition observation primitives). Related: #39 (browser tracker) and draft #4107. #4107 derives one transition from two passive inspect_web_page records plus a caller-declared external action. This PR projects the steps of one REA-controlled capture_browser_scenario run. The two sources differ, and neither introduces a shared "UI state" owner. A shared vocabulary is left for the maintainer discussion in #4069.

capture_browser_scenario already records a post-action capture for every declared step. Agents still could not read a completed capture step by step:

  • inspect_analysis_view rejected it as an unsupported parent.
  • compare_web_captures compares two runs, not consecutive steps within one run.
  • A 20-action capture with screenshot, DOM, accessibility and URL after each step is about 2.2 MB, measured below.

Problem and expected behavior

An external agent reconstructing an application's behavior needs, for each declared step:

  • what was done, as the recorded declaration;
  • whether the step completed;
  • which recorded page artifacts differ from the previous step's capture;
  • which events and requests were received in that step's receipt window.

It needs this without re-reading the whole capture or re-running the browser.

  • Before: inspect_analysis_view returned Parent Evidence operation "capture_browser_scenario" does not support analysis views (source-derived from unsupportedParent in src/domain/analysisView/analysisView.ts on main). An oversized capture could only be exported.
  • After: three views of retained (MCP) or inline (CLI) capture Evidence:
    • {kind: "summary"}
    • {kind: "browser-scenario", collection: "steps", offset, limit}
    • {kind: "browser-scenario", collection: "text", step_index, artifact: "accessibility" | "dom", offset, limit}

Change and scope

  • A new capture_browser_scenario parent for inspect_analysis_view and inspect-analysis-view.

    • Summary: browser identity, step outcomes, per-artifact capture coverage and step changes, declared and enabled event families, events received outside every step window, and network transaction counts. Transactions dropped by the transaction limit are counted separately.
    • Steps: each row has the exact recorded action declaration and its family, outcome, recorded URLs, per-artifact coverage, comparison digest and change from the previous step's capture, the events received in the step's sequence window, and the request-attributed network transactions with their own coverage. When network was not observed, the count is null with not_requested coverage, never 0. Every page also carries enabled_event_families and received_outside_step_windows.
    • Text: UTF-16 pages of one step's retained accessibility or DOM text, with the producer's artifact SHA-256.
  • Single owners:

    • Step changes reuse the compare_web_captures comparison owner. browserScenarioDiffEvidence now exports per-step artifact observation, and browserScenarioDiff exports pair classification. Run comparison output is unchanged; see the evidence below.
    • The rule that selecting network content enables network events now lives in enabledScenarioEventFamilies. The Playwright producer and the view both call it, with no behavior change.
  • The view fails closed on inconsistent recorded data:

    • recorded actions must match steps by step_id and action;
    • step receipt windows must rise with step_index and stay disjoint;
    • every event must carry the step current at receipt: the last step that ran whose window had opened. This covers events between windows and after the final capture, not only those inside a window;
    • the capture must restate the scenario recorded in the parent parameters. This covers the browser mode; the scenario fields (start origin, action count, secret references, network content, event families, limits); and each step's artifacts, which follow after_each_step on every step and at_end on the final one. The producer and the views share one domain owner for the scenario projection and for the per-step artifact selection.
  • Capture schema invariants, added from review. browserScenarioCaptureSchema now rejects:

    • retained events whose family was not selected;
    • network transaction omissions when network was not selected;
    • a step 0 other than the completed scenario_start/goto_start step whose receipt window starts at event sequence 1, now a shared constant that the producer uses;
    • step completeness that does not list exactly the missing and truncated artifacts, plus action when the action did not complete. This is how the producer derives it. The comparison owner's completeness downgrade could no longer be reached, so it now depends only on the action outcome, and the text view reads recorded artifact states directly;
    • capture completeness that does not aggregate those step ledgers (each section once, adding only missing events), or that omits events despite connect mode, dropped events, a retained unfinished request, unavailable network content, or a popup while a gap family is selected;
    • a network_transaction_range that does not match the network events dropped for max-network-transactions (a reason only network kinds may carry), or per-transaction omissions that do not correlate with by_kind in both directions: each omitted kind and budget reason is dropped there, no kind is omitted by more transactions than its drops, and every budget drop of a network kind names its transaction;
    • launch or connect ownership and cleanup values that do not pair;
    • a cancelled step with captured artifacts, or a step after the first unfinished action that is not a never-ran cancellation;
    • a retained event sequence or step window end above the sequenced events: retained plus dropped, less the drops known to belong to refused transactions, which spend no sequence numbers;
    • a by_kind row counting fewer drops than its listed reasons and naming transaction records imply. Because by_kind keeps one count per kind across its reasons, refused-transaction drops are bounded rather than counted, and the omitted range may not exceed that bound. Exact per-reason counts would need a producer format change, which is left for a separate PR;
    • network content whose headers or body disagree with header_values and the phase's body selection, or content kept or dropped with no content facet selected;
    • a second request event for one transaction;
    • more retained events than max_events, or more admitted transactions than max_network_transactions.

    Step-completeness derivation, the popup gap families and the unavailable-content rule now each have one domain owner that the producer uses. Event rules live in browserScenarioCaptureEvents.ts and the capture fields in browserScenarioCaptureFields.ts. The comparison owner's per-step event sections could no longer be reached, so they now reduce to one capture-wide event coverage rule.

    Omission accounting keeps the producer's admission rule: a popup page refused by an event budget remains an omitted popup-opened record whenever any family is selected, because popup discovery runs for every selected family. The producer's final parse, compare_web_captures and these views share this schema, so all three reject such inline captures. Producer output already satisfied these rules; see Validation.

  • Inline capture validation boundary. Views and comparisons reject inline captures that:

    • are structurally invalid;
    • contradict the relations above, which the views compute from;
    • do not restate the scenario recorded in their parameters.

    They do not try to prove that any inline Evidence could have come from the recorder. These remaining recorder guarantees are left for a separate hardening PR:

    • strictly ascending event order;
    • consistent redirect fields, and the request coming first, within each transaction;
    • moving the receipt-window and step-provenance checks from the step projection into the capture schema, so that compare_web_captures gets them too;
    • per-reason drop counts in by_kind, which would replace the current bounds on refused-transaction drops but is a producer format change;
    • removing completeness sections that scenario captures can no longer use.

    Further findings that only hand-built captures can trigger will be answered with this boundary rather than with new rules here. Findings that affect producer output, view results for producer Evidence, or regressions will still be fixed.

  • Intentionally not included:

  • Alternatives rejected:

    • A new tool: same intent as the existing view tool, plus catalog growth.
    • A within-run mode of compare_web_captures: inline-only inputs, a reduced compact schema, and observed/external-service labelling of a derivation.
    • A producer change: it would put derived facts into observed Evidence.

Contract and boundary impact

  • Semantic owner and earliest changed stage:
    • domain step projection: src/domain/browserScenarioSteps.ts;
    • shared comparison owner: browserScenarioDiffEvidence.ts and browserScenarioDiff.ts;
    • view: src/domain/analysisView/browserScenarioView*.ts.
  • Contribution scope fit and linked maintainer decision: not applicable. This is a derived view over existing Evidence; it adds no tool, provider, execution, injection or mutation. Feedback on contract shape and ownership is requested on [RFC] Evidence-backed UI state/transition observation primitives for agent-driven behavioral reconstruction #4069.
  • CLI and MCP/tool-catalog contract: additive view kind and parent on inspect_analysis_view and inspect-analysis-view. The tool count stays at 207. Measured byte and token deltas are under Validation.
  • Provider, bridge, target-format, or platform compatibility: the producer emits the same data. PlaywrightScenarioEvents now calls the shared family rule. Views accept the current capture schema only. compare_web_captures now also rejects inline captures that contradict these capture rules; the producer never wrote such captures. The compare_web_captures contract example now records a consistent launch-mode capture with the producer's goto_start start step.
  • Evidence, artifact, provenance, or reconstruction contract: view Evidence is rea.analysis-view with confidence derived. It inherits the parent's controlled-replay authority under the existing view rule and links the parent.
    • This is the first view parent with controlled-replay authority, so exported bundle scenarios manifests will list view records with operation inspect_analysis_view. Maintainer input is welcome.
    • For subject-less parents, the analysis-view service now states the missing artifact identity once in view Evidence instead of repeating the parent's copy.
  • Target selection, authority, upstream behavior, and cleanup details: none; no target interaction.
  • Generated metadata, package, or installation impact: no tracked generated files changed.

Expected effects:

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:
    • src/domain/analysisView/browserScenarioView.test.ts, 13 cases:
      • consecutive comparison and revisit-equal digests;
      • failed and cancelled steps;
      • receipt windows, gaps and the after-final bucket;
      • capture-wide event coverage, including dropped events and connect mode;
      • truncated artifacts;
      • unobserved network reported as null, not 0;
      • pages past the end;
      • fail-closed declarations and windows;
      • view-owned limitations kept under the message budget.
    • src/domain/browserScenarioDiff.test.ts: a new characterization case pins every incomparable branch with full objects (states, captured-side digest, exact reason).
    • src/application/analysisView/AnalysisViewService.test.ts: authority, links, parameters, and a single subject limitation.
    • tests/boundary/mcp/analysisViewMcp.test.ts: retained parent, Ajv validation against the advertised input and output schemas, and the public error projection.
    • tests/boundary/cli/analysisViewCli.test.ts: portable parent through the compiled CLI.
    • scripts/lib/browser-scenario-view-e2e.mjs: wired into verify:browser.
    • Capture invariants:
      • src/domain/browserScenarioCapture.test.ts: every capture rule, including omission accounting, the popup-discovery case and each event-gap cause. Mutation checks removed each rule branch one at a time, and each removal failed a test.
      • src/browser/PlaywrightScenarioEvents.test.ts: the producer's budget-refused popup page and network metadata over its budget both parse under the schema.
      • src/domain/analysisView/browserScenarioView.test.ts: exact-issue rejection of unselected-family events, of a foreign or failed step 0, of a ledger that contradicts retained text, and of capture accounting that contradicts its steps or omissions.
      • Hand-built fixtures in browserScenarioDiff.test.ts, browserCli.test.ts, tests/fixtures/webScriptCapture.ts, ScriptCaptureAdapters.test.ts and webScriptExport.test.ts now record producer-shaped captures. Each test keeps its property; for example, differing comparison anchors now come from unrelated events instead of unaccounted sequence gaps.
  • Base reproduction or other evidence:
    • The new comparison characterization case was also run with the identical fixture against origin/main's comparison implementation in a temporary worktree. The serialized step results were identical, so the shared comparison refactor did not change these outputs.
    • The view also fails closed on malformed inline Evidence; see the domain tests.
  • User-visible CLI/MCP output: see the real step row below.
  • Remaining proof gaps:
    • No model-host discoverability evaluation was run.
    • Model token usage for agent tasks is unmeasured; tokenx estimates only.
    • Linux and Windows real-browser lanes were not run locally.
    • CPU time and memory cover the MCP server process only.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.
Real step row (Chrome 155, self-owned fixture, trimmed)
{
 "context": {
  "source_completeness": "complete",
  "enabled_event_families": [
   "console",
   "network"
  ],
  "received_outside_step_windows": {
   "retained": 0,
   "kinds": []
  }
 },
 "row": {
  "step_index": 1,
  "step_id": "open-settings",
  "action_class": "input",
  "action": {
   "step_id": "open-settings",
   "action": "click",
   "locator": {
    "kind": "role",
    "role": "button",
    "name": "Open settings"
   },
   "button": "left",
   "click_count": 1
  },
  "status": "completed",
  "error": null,
  "elapsed_ms": 31,
  "before_url": {
   "url": "http://127.0.0.1:<port>/app",
   "origin": "http://127.0.0.1:<port>",
   "query_parameter_names": [],
   "redacted": false
  },
  "after_url": {
   "url": "http://127.0.0.1:<port>/app",
   "origin": "http://127.0.0.1:<port>",
   "query_parameter_names": [],
   "redacted": false
  },
  "artifacts": [
   {
    "artifact": "accessibility",
    "coverage": "captured",
    "reason": null,
    "comparison_sha256": "bfbf5cd355389a3ac0153e2ad7e8c0efd1390a65bb2f80e181e8ed78fd2c94d1",
    "change": "changed"
   },
   {
    "artifact": "url",
    "coverage": "captured",
    "reason": null,
    "comparison_sha256": "94611b2e44231cb6051645e0f41a503056bfeb4dba3b4c90005ff8867750d843",
    "change": "unchanged"
   }
  ],
  "events_received": {
   "retained": 1,
   "kinds": [
    {
     "kind": "request",
     "count": 1
    }
   ],
   "coverage": "captured",
   "sequence_start": 5,
   "sequence_end": 5
  },
  "network_transactions": {
   "coverage": "captured",
   "retained": 1
  }
 }
}

Validation performed

All results are on macOS arm64 with Node 24.14.0.

The current head aac8f3136 merges main 1417bf943. Main's native function matching view (#5390) added its summary result schema at the same place as this PR's. The merge keeps both in the summary union keyed on parent_operation. Main's other new commits do not touch the browser scenario producer, capture schema, views or scenario fixtures. On this head:

  • npm run check:fast passed (typecheck and lint).
  • npm run test:local passed on 49 source test files (692 tests).
  • npm run test:focused passed on 164 boundary, acceptance, contract, catalog and environment files: 1,493 passed, 48 skipped.
  • npm run docs:check passed.
  • npm run verify:browser passed with Google Chrome 155.0.8059.85 and verified: true, including scenarioViews.

The previous merge head c1fcb5c5f merged main 2538214e2. Main's native inventory view (#5378) changed how summaries are typed: each parent operation now has its own summary result schema, and the summaries form a union keyed on parent_operation. This PR's summary now follows that pattern with browserScenarioSummaryViewResultSchema, replacing the earlier single summary schema whose body could be any of several shapes. The tool description, the CLI description and the generic unsupported-parent message are main's text plus only this PR's browser scenario additions. On that head:

  • npm run check:fast passed (typecheck and lint).
  • npm run test:local passed on 49 source test files (692 tests).
  • npm run test:focused passed on 163 boundary, acceptance, contract, catalog and environment files: 1,492 passed, 48 skipped. This includes the analysis-view MCP output-schema validation.
  • npm run docs:check passed.
  • npm run verify:browser passed with Google Chrome 155.0.8059.85 and verified: true, including scenarioViews.

The previous merge head bddd1eaae merged main 0134732fc. Main's protobuf capture view (#5031) conflicted in two places:

  • UnsignedAnalysisView: main now derives this type from AnalysisViewResult instead of listing each kind, so the browser-scenario result needs no separate entry.
  • The tool description: main's text, including the protobuf sentence, plus only this PR's additions.

Main's other new commits (#5350, #5355, #5356) merged without conflicts and do not change the browser scenario producer, capture schema or scenario fixtures. Main also added a dependency, so I reran npm ci. On that head:

  • npm run check:fast passed (typecheck and lint).
  • npm run test:local passed on 48 source test files (687 tests).
  • npm run test:focused passed on 161 boundary, acceptance, contract, catalog and environment files: 1,464 passed, 48 skipped.
  • npm run docs:check passed.
  • npm run verify:browser passed with Google Chrome 155.0.8059.85 and verified: true, including scenarioViews.

The previous merge head 05a17923a merged main 3fca2e0ca. Main's #5319 adds an environment-state view that also reads capture_browser_scenario parents. The merge keeps both sides:

  • Routing: grouping views (api-surface, environment-manifest, environment-state) still go to main's projectors first, and this PR's projector serves summary and browser-scenario. This PR's refusal for any other view kind now names all four supported views.
  • Fallback error: main's "only environment-manifest and environment-state" branch can no longer be reached, so the generic unsupported-parent message stays.
  • Docs: docs/mcp-contracts.md places main's environment-state paragraph right after the environment-manifest paragraph it refers to, followed by this PR's paragraph.
  • Tool description: main's text plus only this PR's additions.
  • Main's test: environmentScenario.test.ts keeps this PR's summary-succeeds check, with the four-view message.
  • Shared fixture: main's new test builds the scenario fixture with header_values selected. The fixture now records content-event headers as captured when header values are selected (an empty list, since the fixture records no header names), as this PR's capture schema requires.

On that head:

  • npm run check:fast passed (typecheck and lint).
  • npm run test:local passed on 46 source test files (679 tests), including main's environmentStateView, environment and scenarioCaptureRecords tests.
  • npm run test:focused passed on 160 boundary, acceptance, contract, catalog and environment files: 1,460 passed, 48 skipped.
  • npm run docs:check passed.
  • npm run verify:browser passed with Google Chrome 155.0.8059.85 and verified: true, including scenarioViews.

The previous merge head ae827b13f merged main f93a0335a. Main's #5293 adds an evidence-file source to inspect_analysis_view and new service tests. Two conflicts came from it:

  • the tool description, which now keeps main's evidence-file sentence alongside this PR's capture_browser_scenario text;
  • AnalysisViewService.test.ts, which now keeps both this PR's browser-scenario authority test and main's inspectAnalysisViewWithFiles tests.

For the summary, steps and text views of the fixture capture, an evidence-file source gives the same normalized_result, controlled-replay authority and parent link as the same Evidence passed inline. I checked this with a local script, not a committed test. On that head:

  • npm run check:fast passed (typecheck and lint).
  • npm run test:local passed on 43 source test files (632 tests), including main's new evidence-file and scenarioCaptureRecords tests.
  • npm run test:focused passed on 158 boundary, acceptance, contract, catalog and environment files: 1,448 passed, 48 skipped.
  • npm run docs:check passed.
  • npm run verify:browser passed with Google Chrome 155.0.8059.85 and verified: true, including scenarioViews.

The previous merge head 150d147ec merged main 5fa4defcb. The only conflict was the inspect_analysis_view description, where main's Godot PCK change (#3634) rewrote the inventory text. The merge keeps main's text and adds only this PR's capture_browser_scenario parent and view sentences. #3634 does not touch the browser scenario producer, capture schema, views or fixtures. On that head:

  • npm run check:fast passed (typecheck and lint).
  • npm run test:local passed on 42 source test files (616 tests).
  • npm run test:focused passed on 158 boundary, acceptance, contract, catalog and environment files: 1,447 passed, 48 skipped.
  • npm run docs:check passed.
  • npm run verify:browser passed with Google Chrome 155.0.8059.80 and verified: true, including scenarioViews.

The previous merge head d499af870 merged main 833136507. Main's new il2cpp-metadata view (#3807) conflicted with this PR's browser-scenario views in the analysis-view request and result unions, parent operations, summaries, unsigned view types and the tool description. The merge keeps both view kinds. The generic unsupported-parent message names both IL2CPP metadata and browser scenario captures. The tool description is main's text plus only this PR's additions. #3807 does not touch the browser scenario producer, capture schema or fixtures. On that head:

  • npm run check:fast passed (typecheck and lint).
  • npm run test:local passed on 41 source test files (605 tests), including main's environment, scenarioCaptureRecords and IL2CPP view tests.
  • npm run test:focused passed on 158 boundary, acceptance, contract, catalog and environment files: 1,447 passed, 48 skipped.
  • npm run docs:check passed.
  • npm run verify:browser passed with Google Chrome 155.0.8059.80 and verified: true, including scenarioViews.

The previous merge head 2cae99f53 merged main bf1eeee94. Main's #5182 builds environment manifests from capture_browser_scenario parents, so one parent kind now has two view paths:

  • Routing: environment-manifest views still go to main's projector first. This PR's projector serves summary and browser-scenario views for the same parents, and its refusal for any other view kind now names all three supported views.
  • Fallback error: main's "supports only the environment-manifest view" branch can no longer be reached, so the generic unsupported-parent message stays.
  • Tool description: keeps both sides' text.
  • Main's fixture: tests/fixtures/browserScenarioCapture.ts built captures the recorder cannot emit, which this PR's capture schema rejects. I made it match the recorder without changing its transactions or record content:
    • step 0 is the implicit start navigation;
    • step 1 is the declared wait_for_timeout and receives every event;
    • content events exist only for selected body facets;
    • the recorded scenario declares the capture's event, network and artifact selection.
  • Main's test: environmentScenario.test.ts used summary as its unsupported example. It now expects summary to succeed on the same Evidence, and checks that an unsupported view names the supported ones.

On that head:

  • npm run check:fast passed (typecheck and lint).
  • npm run test:local passed on 40 source test files (595 tests), including main's environment and scenarioCaptureRecords tests.
  • npm run test:focused ran 327 boundary, acceptance, contract and environment files: 3,529 passed, 122 skipped, 2 failed. The failures are javascriptRuntimeObservation ("includes targets outside the old caller root filter") and filesystemObservationRaceCli ("keeps a stable symlink observation complete"). Both fail the same way on a clean main bf1eeee94 worktree on this macOS machine, and this PR does not touch those areas.
  • npm run docs:check passed.
  • npm run verify:browser passed with Google Chrome 155.0.8059.80 and verified: true, including scenarioViews.

The previous head 757bbdfc3 fixed a paging cost found in review. Every page used to rerun the declaration checks and the page-shared limitations and unknowns over the whole capture; these results now join the sealed-parent cache. A new test pages one sealed result and checks that another Evidence ID over the same frozen result is checked on its own. With the Evidence ID binding removed, that test fails. On that head:

  • npm run check:fast passed (typecheck and lint).
  • npm run test:local passed on 29 capture, view, producer, network, scenario-service, observation and Evidence test files (477 tests).
  • npm run test:focused passed on 64 boundary, acceptance and contract files: 526 passed, 5 skipped.
  • npm run verify:browser passed with Google Chrome 155.0.8059.80 and verified: true, including scenarioViews; the steps view is 14,713 bytes, unchanged.
  • In-process paging measurement: a sealed parent with N click actions, all steps paged 20 at a time through projectAnalysisView, two runs each on macOS arm64. Output is unchanged, so view bytes and tokens are unchanged. MCP end-to-end time was not re-measured.
Actions Warm ms per page, before → after All warm pages, before → after Process user CPU, before → after Process RSS MiB, before → after
200 0.97–1.07 → 0.33–0.36 10 ms → 3–4 ms 0.29–0.39 s → 0.25–0.26 s 237–241 → 204–216
2,000 3.5–3.7 → 0.26 354–368 ms → 26 ms 0.96–0.99 s → 0.51–0.53 s 289–295 → 282–283
10,000 17.0–19.1 → 0.20 8.5–9.5 s → 0.1 s 10.8–11.8 s → 1.2 s 671–672 → 529–547

The cold first page, which parses and projects the capture, is unchanged (8–9 ms, 42–52 ms and 180–190 ms). A summary request still tallies every step once per request.

The previous merge head aa689d960 merged main b4938aed5. Main's new desktop-application view (#5207) conflicted with this PR's browser-scenario views in the inspect_analysis_view tool description and the inspect-analysis-view CLI command description. The merge keeps both view kinds, so each description is main's text plus this PR's additions. None of the main commits since the previous merge touched the browser scenario producer or capture schema. On that head:

  • npm run check:fast passed (typecheck and lint).
  • npm run test:local passed on 29 capture, view, producer, network, scenario-service, observation and Evidence test files (476 tests).
  • npm run test:focused passed on 64 boundary, acceptance and contract files: 526 passed, 5 skipped.
  • npm run docs:check passed.
  • npm run verify:browser passed with Google Chrome 155.0.8059.80 and verified: true, including scenarioViews.

The previous merge head 2fa0ba9e8 merged main fdaffe21c. There, main's environment-manifest view (#4954) conflicted in the tool description, docs/mcp-contracts.md and tests/boundary/cli/analysisViewCli.test.ts, and the merge kept both view kinds and all three CLI tests. The same checks passed on that head: 476 unit tests, 464 boundary tests (5 skipped), docs:check and verify:browser.

The previous merge head 6ae23996e merged main bec88b9d7. Its only conflict was in scripts/verify-real-browser.mjs, where both sides added a verifier import, and the merge kept both. verify:browser passed there too, including main's urlUserInfo check.

The previous head bf85798c4 added only a change to the views, which now merge the capture's own limitations with the envelope's. I validated it with npm run check:fast, the capture, view and producer unit tests (277), the analysis-view MCP/CLI boundary and output-schema tests (35), and the real-Chrome scenario-view e2e.

On 688f33b2a, which merges main d9d085a15 and includes the earlier review fixes:

  • npm run check passed, with lint at 0 errors.
  • npm run docs:check, npm run verify:test-discovery, npm run jscpd (3.28%) and npm run scan:todos passed.
  • npm run test:local passed on 16 capture, view and producer test files (280 tests).
  • npm run test:focused passed on 46 boundary, acceptance and contract files: 482 passed, and 2 tests in serverLifecycleMcp.test.ts were skipped as unrelated. On the previous head, 1dd14fe, one run hit 30-second timeouts in 5 unrelated files while the machine's load average was about 10. Those 5 files and then the full set passed when rerun, and the full set passed in one run on this head.
  • npm run verify:browser passed with Google Chrome 155.0.8059.80 and verified: true, including scenarioViews and popup coverage.
  • Producer conformance stress run: the real PlaywrightScenarioEvents recorder and network collector, driven by fake Playwright objects, across all 256 family subsets, with and without network content, 8 budget settings (including network metadata budgets), and launch and connect ownership. Capture completeness was computed with the provider's own rule. All 8192 captures were accepted by the schema. The max-listener-owners reason was not exercised.
  • A real Chrome capture with only console selected, max_events: 1 and a window.open popup completes, with two omitted popup-opened records. Before the popup adjustment, the stricter rule rejected this producer output.

Earlier results on the first PR commit, rebased onto main 9d6651e5b:

  • npm run check passed, with lint at 0 errors.
  • npm run docs:check passed.
  • npm run verify:test-discovery passed.
  • npm run jscpd passed (3.18%).
  • npm run scan:todos passed.
  • npm run test:local passed on 19 domain, service and producer test files (291 tests), including src/domain/analysisView/*, src/application/analysisView/*, src/domain/browserScenario*.test.ts, src/domain/evidence.test.ts and src/browser/PlaywrightScenario*.test.ts.
  • npm run test:focused passed on 17 files (194 tests): the analysis-view MCP and CLI boundaries plus toolSchemaValidity, contractPresentation, toolInputAdmission, compactInputSchemaMcp, outputSchemaProfile, serverIdentity, cliToolCoverage, jsonInputStatus, cliStartupImports, productCatalog, documentationFacts, targetContentProvenance, toolEffects, toolInputReferences and tupleSchemaParity.
  • npm run verify:browser passed with Google Chrome 155.0.8059.40 and verified: true. That includes the new scenarioViews check: a self-owned fixture with known transitions, run through stdio MCP and the compiled CLI on the same Evidence with identical view output. It also confirms paged accessibility and DOM text reassemble to the producer SHA-256, and that per-window plus outside-window event counts equal the retained total.

Representative task measurement: one stdio MCP server process, 3 runs, 20 click actions with screenshot, DOM, accessibility and URL captured after each step.

Call Wall ms Server CPU s Server peak RSS MiB Response bytes tokenx estimate
capture_browser_scenario (21 steps) 2505–2678 0.37–0.52 457–461 2,189,439 461,055
summary, cold (first view of the parent) 17–19 0.02–0.03 458–461 6,908 1,869
summary, warm (cached projection) 2 ≤0.01 450–453 6,908 1,869
steps page, 21 rows, warm 4–6 ≤0.01 450–453 34,746 10,151
text page, 4,096 code units, warm 2 ≤0.01 450–453 7,536 1,975

The capture call is unchanged by this PR. Capture time and RSS cover the MCP server process only; Chromium processes are not included. Token counts are tokenx estimates of the returned text, not billed model usage.

Catalog effect, comparing main 9d6651e5b with the first PR commit (not re-measured after the merge and the review fix):

  • tools: 207 → 207 (+0)
  • tools/list full bytes (name+description+input): 824,508 → 826,128 (+1,620)
  • tools/list compact bytes: 189,737 → 190,263 (+526)
  • inspect_analysis_view description chars: 6,249 → 6,761 (+512)
  • inspect_analysis_view description tokenx: 1,586 → 1,726 (+140)
  • inspect_analysis_view full input bytes: 23,095 → 24,189 (+1,094)
  • inspect_analysis_view full input tokenx: 6,593 → 6,895 (+302)
  • inspect_analysis_view compact input bytes: 333 → 333 (+0)
  • inspect_analysis_view output schema bytes: 128,229 → 142,453 (+14,224)

Compatibility, safety, and release

  • Breaking changes or migration steps: no producer output changes. Hand-built inline captures that contradict these capture rules are now rejected as malformed input. This includes inline captures passed to main's environment-manifest view (feat(environment): build environments from browser scenario captures #5182), which parses the same schema. Main's hand-built fixture in tests/fixtures/browserScenarioCapture.ts was one of them, and this PR updates it to match what the recorder emits (details under Validation).
  • Real Hopper/Ghidra, browser, or OS coverage: real Chrome on macOS arm64 only. The CI real-browser lane is selected by the touched src/domain/browser* and src/browser/** files.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review:
    • Views return producer-redacted text and recorded declarations: caller literals and secret references, never resolved secret values.
    • No new data collection, process, network, or filesystem effect.
    • Inline captures are fully schema-validated on each call. Sealed retained parents cache, by object identity through a WeakMap/WeakRef, their validated capture, step projection, checked declarations and page-shared limitations and unknowns, following the managedMemberView precedent. An entry is reused only for the same Evidence ID, which authenticates the parameters and limitations those checks read. Failed checks are not cached. Later pages therefore do only page-sized work.

Author readiness

Human owner: @kangyishuai

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🤖 Generated with Claude Code

inspect_analysis_view now reads completed capture_browser_scenario
Evidence without reopening a browser:

- {kind: "summary"} reports browser identity, step outcomes, per-artifact
  capture coverage and step changes, enabled event families, events
  received outside every step window, and network transaction counts.
- {kind: "browser-scenario", collection: "steps"} pages each step's
  recorded action declaration, outcome, recorded URLs, artifact coverage,
  comparison digest and change from the previous step's capture, events
  received in the step's sequence window, and request-attributed network
  transactions with their own coverage.
- {kind: "browser-scenario", collection: "text"} pages one step's
  retained accessibility or DOM text in UTF-16 code units.

Step changes reuse the compare_web_captures comparison owner, which now
exports per-step artifact observation and pair classification; run
comparison output is unchanged. The rule that selecting network content
enables network events has one owner used by the producer and the view.
View Evidence stays derived, inherits the capture's authority and links
the capture. No tool, provider or execution authority is added.

Refs morluto#4069

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T10:14:38.311376Z aac8f31 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable blocking issues were found.

Summary

Adds summary, step, and retained-text views for capture_browser_scenario Evidence without reopening the browser.

  • Browser scenario captures now have pageable summaries, steps, and text views.
  • Browser scenario captures now check that their recorded steps and events agree.
  • Browser run comparisons now share the per-step comparison rules.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Retained or portable Evidence] --> B[Check Evidence identity]
  B --> C[Validate capture and declarations]
  C --> D[Project steps with shared comparison rules]
  D --> E[Summary]
  D --> F[Step page]
  D --> G[Retained text page]
  E --> H[Derived Evidence linked to parent]
  F --> H
  G --> H
Loading

Reviews (28) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." · Reviewed by Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8ead9e633f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/browserScenarioSteps.ts Outdated
An empty receipt window (end = start - 1) was skipped before the order
check, so a step whose empty window moved backward was accepted and the
step view reported contradictory receipt boundaries. Every window, empty
or not, must now start after the previous step's window ends; only
non-empty windows still take part in event matching.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kangyishuai and others added 2 commits October 16, 2026 07:33
Resolve conflicts with main's analysis-view changes:
- AnalysisViewService keeps both the single subject limitation for
  subject-less parents and main's relationship coverage for native views.
- analysisViewMcp.test.ts keeps both the browser scenario fixture imports
  and main's RelationshipCoverage type import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The merge commit's pre-commit autofix reformatted an unrelated file from
main; restore main's content so this PR changes only its own files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kangyishuai

Copy link
Copy Markdown
Author

Could a maintainer approve the pending workflow runs for this PR? It is my first contribution from a fork, so CI and PR title on the current head 32dc60fc7 are waiting with action_required and have not run.

Until they run, all validation is local. After merging main, I reran check:fast, docs:check, the focused unit and boundary/contract tests, and the real-Chrome scenario-view e2e. The full verify:browser run passed on Chrome 155 before that merge. The branch merges cleanly with main.

Thanks!

Resolve the inspect_analysis_view description conflict by keeping main's
javascript-facts guidance and re-adding the capture_browser_scenario parent
and its summary, steps and text views.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 92fe95e87a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/browserScenarioSteps.ts Outdated
Comment thread src/domain/analysisView/browserScenarioView.ts
…n or start step

The capture schema owns capture well-formedness but did not tie events to the
selected event families or fix step 0, so views and comparisons could project
contradictory inline captures.

Retained events must now belong to selected families (network content selects
network). Omission accounting follows the producer's admission rule: popup
discovery serves every selected family, so an unadmitted popup page stays an
omitted popup-opened record whenever any family is selected, and only the
network collector accounts network transaction omissions. Step 0 must be the
producer's completed scenario_start/goto_start step, now a shared constant.
A comparison example and test fixtures that recorded another start action are
corrected, and the contract doc drops a stale claim about captures without
event_families.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d24c2fe42a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/analysisView/browserScenarioView.ts Outdated
Step completeness restates the step's artifact states and outcome; the
producer derives it that way, but the step schema accepted any ledger. A
captured artifact listed as missing or truncated made the comparison owner
downgrade it and the text view drop the retained text without a reason.

The step schema now requires completeness to list exactly the missing and
truncated artifacts, plus the action section when the action did not
complete. The comparison owner's completeness downgrade, now unreachable,
reduces to the action outcome, and the text view reads recorded artifact
states directly. A characterization fixture that relied on the contradictory
ledger now records the missing URL it described.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b4463fd9e0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/browserScenarioCapture.ts Outdated
Comment thread src/domain/analysisView/browserScenarioView.ts
… events

Capture completeness, the omitted transaction range, browser ownership and
the steps after a failure restate facts the producer derives from the steps
and events, but the capture schema accepted any values. Views and
comparisons then published complete coverage beside failed steps or lossy
network accounting.

The capture schema now requires:
- completeness to aggregate the ledgers the steps' own facts determine, each
  section once, with missing events whenever connect mode, dropped events or a
  retained gap shows incomplete event coverage;
- the omitted transaction range exactly when events were dropped for
  max-network-transactions, with at least one such drop per omitted
  transaction, and dropped events behind per-transaction omissions;
- launch and connect ownership and cleanup pairs;
- cancelled steps that capture nothing, and never-ran cancellations after the
  first action that did not complete.

Step completeness derivation, the popup gap families and the unavailable
network content rule now have one domain owner shared with the producer. The
comparison owner's per-step event sections, unreachable under these rules,
collapse into one capture-wide event coverage rule. Test fixtures, the
comparison contract example and the CLI fixture now record consistent,
launch-mode captures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0cde8970c3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/browserScenarioCapture.ts Outdated
The network collector names an omitted kind and budget reason for an
admitted transaction only after dropping that event for that reason, but the
capture schema only required some dropped event behind any per-transaction
omission. A dropped console event could therefore vouch for an omitted
response.

The capture schema now correlates both directions when network is selected:
each per-transaction kind and budget reason must be dropped in by_kind, no
kind may be omitted by more transactions than its drops, and every budget
drop of a network kind must name its transaction. Refused transactions stay
in the omitted range rather than per-transaction records.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/domain/browserScenarioCapture.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0d50bfe896

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/browserScenarioCapture.ts Outdated
Comment thread src/domain/browserScenarioSteps.ts
kangyishuai and others added 2 commits October 16, 2026 16:59
The per-transaction omission check listed the budget reasons it accepted
and left out max-network-metadata-allocation-bytes, which the recorder
writes to by_kind and network_transactions when request or response
metadata exceeds its budget. A capture with a small metadata budget failed
the producer's final parse.

The check now excludes only the reason that belongs to the omitted
transaction range, so the admission rules stay with the recorder. A
producer-to-schema regression drives the real recorder and network collector
with a one-byte metadata budget.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The producer records step 0's receipt window from event sequence 1, so every
retained event lies in a window or after one. The capture schema did not
check where step 0's window starts, and an inline capture could leave
start-navigation receipts before the first window, where the step view
reported them as received outside every window.

The start-step constant now carries the window start the producer uses, and
the capture schema rejects a step 0 window that starts elsewhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 33c7d50233

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/browserScenarioCapture.ts Outdated
Comment thread src/domain/browserScenarioSteps.ts Outdated
Two producer facts were only partly checked. The recorder indexes each event
by the step current at receipt, the last step that ran whose window had
opened, but the step projection checked only events inside a window, so an
event between windows or after the final capture could name an unrelated
step and move its transaction to that row. And only the network collector
drops events for max-network-transactions, but the omitted range could be
backed by a dropped console row.

The step projection now derives the current step for every event from the
recorded windows and the steps that ran, which also covers the in-window
check it replaces. The capture schema counts only network drops toward the
omitted range and rejects max-network-transactions on other kinds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c8ff9e51aa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/browserScenarioSteps.ts
Comment thread src/domain/browserScenarioCapture.ts
…e recorder

Every sequence number the recorder spends belongs to a retained or dropped
event, and network content records exactly the facets the scenario selected
for its phase. The capture schema checked neither, so inline Evidence could
place a retained event or receipt window past the accounted events, or record
a selected body as never requested, and the views reported captured coverage
over them.

The capture schema now bounds retained sequences and window ends by
retained plus dropped events, requires network content headers and bodies to
match header_values and the phase's body selection, and rejects network
content kept or dropped when no content facet was selected. The event rules
move to browserScenarioCaptureEvents.ts and the fields to
browserScenarioCaptureFields.ts to keep each module within the size limit.

Hand-built fixtures in the comparison, script capture and view tests now
record producer-shaped captures while keeping each test's property: different
anchors come from unrelated events, filtered captures renumber through a
helper that refuses to strand content anchors, and the anchor-mutation test
asserts the anchor issue itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 103a4c3b5b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/analysisView/browserScenarioView.ts Outdated
Comment thread src/domain/browserScenarioSteps.ts
…sts to transactions

The capture result records no artifact selection, so a view of inline
Evidence could report a requested artifact as not requested, or omit one the
caller asked for, without contradiction. And the capture schema accepted two
request events with one transaction_id, which the transaction projection
collapses into one transaction counted on the later request's step.

The per-step artifact selection now has one domain owner shared by the
producer, and the views bind each step's artifacts to the selection recorded
in the parent parameters: after_each_step on every step and at_end on the
final one. The recorded-declaration checks move to their own module. The
capture schema accepts one request per transaction, and the script capture
projection drops its now unreachable request-count ambiguity; its duplicate
identity test now exercises a duplicate response and asserts that a
duplicate request is rejected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a1058560fa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/browserScenarioCaptureEvents.ts Outdated
Comment thread src/domain/browserScenarioCaptureEvents.ts Outdated
…d reasons

by_kind keeps one drop count per event kind across all its reasons, so the
capture cannot say how many drops of a kind belong to max-network-transactions.
The schema counted every drop of a kind listing that reason toward the
omitted range, and counted refused drops, which spend no sequence numbers,
toward the receipt ceiling.

Refused drops are now bounded from the recorded accounting: each listed
reason stands for at least one drop, and each per-transaction record naming
the kind for at least one drop of another reason. The omitted range may not
exceed the upper bound, the receipt ceiling subtracts the lower bound, and
each by_kind row must count at least the drops its reasons and records
imply. Exact per-reason counts would need a producer format change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1dd14fe0b6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/analysisView/browserScenarioViewDeclarations.ts Outdated
Comment thread src/domain/browserScenarioCaptureEvents.ts
…eclaration

The capture's scenario fields restate the declared scenario, but the views
checked only the recorded actions and artifact selection, so inline Evidence
whose parameters selected network content or event families could restate
them as unselected and report caller requests as not requested. The capture
schema also let retained events exceed max_events and admitted transactions
exceed max_network_transactions, which the recorder never does.

The projection from a declared scenario to the capture's scenario fields now
has one domain owner used by the producer. Views bind the browser mode, the
scenario fields and each step's artifacts to the declaration recorded in the
parent parameters, and the capture schema enforces the event and transaction
limits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 688f33b2a1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/analysisView/browserScenarioView.ts Outdated
Comment thread src/domain/browserScenarioCaptureEvents.ts
Comment thread src/domain/browserScenarioCaptureEvents.ts
…iews

The browser scenario views fed only the Evidence envelope's limitations into
their bounded messages, while the other analysis-view projectors merge the
envelope with the result's own limitations. Producer Evidence already copies
capture.limitations into the envelope, so its output is unchanged, but a
portable parent that keeps a caveat only in the result lost it.

The views now merge capture.limitations with the envelope's, deduplicated by
the existing bounded message owner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bf85798c4f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/browserScenarioCaptureEvents.ts
Comment thread src/domain/browserScenarioCaptureEvents.ts
Comment thread src/domain/browserScenarioCaptureEvents.ts
…ansition-view

Resolve the verify-real-browser.mjs import conflict by keeping both the
scenario-view verifier from this branch and the URL user-info verifier
from main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

…ansition-view

Resolve conflicts with main's environment-manifest view (morluto#4954) by keeping
both view kinds: the inspect_analysis_view description, the MCP contract
docs and the analysis-view CLI boundary tests now cover the
environment-manifest view and the capture_browser_scenario views.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Want your agent to iterate on Greptile's feedback? Try greploops.

…ansition-view

Resolve conflicts with main's desktop-application view (morluto#5207) by keeping
both view kinds in the inspect_analysis_view tool description and the
inspect-analysis-view CLI command description.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aa689d960c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/domain/analysisView/browserScenarioView.ts Outdated
kangyishuai and others added 2 commits October 20, 2026 04:42
…led parent

Every browser-scenario page reran the recorded-action binding, the
declaration and artifact-selection check, and the shared limitations and
unknowns over the whole capture. Paging all steps therefore cost
O(steps^2 / limit). These results now join the sealed parent's cached
capture and step projection, so later pages do only page-sized work.

The Evidence ID authenticates the parameters and limitations these checks
read, so a cache entry is reused only for the same Evidence ID. Failed
checks are not cached.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ansition-view

Main's morluto#5182 builds environment manifests from capture_browser_scenario
parents. Keep both view paths: environment-manifest views still route to
main's projector first, and this branch's projector serves summary and
browser-scenario views for the same parents. The tool description keeps
both sides' text, and the projector's refusal now names all three
supported views. Main's "supports only the environment-manifest view"
fallback can no longer be reached, so the generic message stays.

Make main's hand-built scenario fixture match what the recorder emits,
so it passes this branch's capture invariants. Step 0 is the implicit
start navigation. Step 1 is the declared wait_for_timeout and receives
every event. Content events exist only for selected body facets. The
recorded scenario declares the capture's event, network and artifact
selection. Main's refusal test now expects the summary view to succeed
and checks that an unsupported view names the supported ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

…ansition-view

Resolve conflicts with main's il2cpp-metadata view (morluto#3807) by keeping both
view kinds: the analysis-view request and result unions, parent
operations, summaries, unsigned view types and the tool description now
cover the il2cpp-metadata and browser-scenario views. The generic
unsupported-parent message names both, and the unreachable
browser-scenario fallback stays removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

…ansition-view

Resolve the inspect_analysis_view description conflict with main's Godot
PCK inventory change (morluto#3634). Keep main's rewritten inventory text and add
this branch's capture_browser_scenario parent and view sentences.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

…ansition-view

Resolve conflicts with main's evidence-file analysis-view source (morluto#5293).
Keep main's evidence-file sentence in the inspect_analysis_view
description together with this branch's capture_browser_scenario text.
Keep both the browser-scenario authority test and main's
inspectAnalysisViewWithFiles tests in AnalysisViewService.test.ts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

…ansition-view

Main's environment-state view (morluto#5319) also reads capture_browser_scenario
parents. Grouping views still route first, and this branch's projector
serves summary and browser-scenario views. Its refusal now names all four
supported views. Main's two-view fallback stays unreachable, so the
generic unsupported-parent message is kept.

Resolve the remaining conflicts by keeping both sides. The MCP contract
docs place the environment-state paragraph right after the
environment-manifest paragraph it refers to, followed by this branch's
paragraph. The tool description is main's text plus this branch's
additions. environmentScenario.test.ts keeps this branch's
summary-succeeds check with the four-view message.

The shared scenario fixture now records content-event headers as captured
when header_values is selected. It records no header names, so the list is
empty. This satisfies the capture invariant that main's new header-values
fixture variant exercises.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

@kangyishuai

Copy link
Copy Markdown
Author

@earakely-scale @gensokyo-dev @kaoru0822-kitauji, I'd like to align on capture_browser_scenario views now that #5182 and #5319 read the same parents as this PR.

Where the two lines of work meet

  • This PR adds summary, browser-scenario step and step text views. It also adds producer-derived invariants to browserScenarioCaptureSchema, which I checked against the real recorder and Chrome.
  • scenarioCaptureRecords.ts from feat(environment): build environments from browser scenario captures #5182 parses that same schema for environment-manifest and environment-state.
  • Keeping this branch merged with main has therefore needed three kinds of change outside this PR's own files:
    • tests/fixtures/browserScenarioCapture.ts (in merges 2cae99f and 05a1792) now emits what the recorder emits:

      • step 0 is the implicit scenario_start/goto_start navigation;
      • step 1 is the declared action, and its receipt window covers the events;
      • content events appear only for selected body facets;
      • headers are captured when header_values is selected;
      • the recorded scenario declares the capture's selection.

      Transactions and record content are unchanged, and all environment tests pass.

    • The environmentScenario.test.ts refusal test used summary as its unsupported view. With this PR, summary succeeds, so the test now refuses a capture view.

    • Main's capture_browser_scenario branch in unsupportedParent can no longer be reached once this PR's projector is registered.

Questions

  1. @earakely-scale: do these fixture and test changes keep the intent of your tests?
  2. Could the views a scenario parent supports have one owner? One option is a list that the dispatcher and the refusal message both read. Then each new view does not edit the same message and test. Similarly, src/domain/browserScenarioCapture.fixture.ts and tests/fixtures/browserScenarioCapture.ts now both build scenario captures. I'm happy to fold them into one recorder-shaped builder, here or in a follow-up, whichever you prefer.
  3. Maintainers: is this PR's scope still wanted alongside the environment views? If so, could someone approve its workflow runs? CI and PR title have been action_required since 2026-10-16. PR readiness stays pending on [Bug] PR readiness can never succeed for PRs from forks: the head-association lookup queries the base repository #3432, which affects every fork PR.

kangyishuai and others added 3 commits October 20, 2026 15:28
…ansition-view

Resolve conflicts with main's protobuf capture view (morluto#5031). Main now
derives UnsignedAnalysisView from AnalysisViewResult instead of listing
each kind, so the browser-scenario result needs no separate entry. The
inspect_analysis_view description is main's text, including the protobuf
sentence, plus this branch's capture_browser_scenario additions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ansition-view

Resolve conflicts with main's native inventory view (morluto#5378). Main now
gives each parent operation its own summary result schema, joined by a
union on parent_operation. Add browserScenarioSummaryViewResultSchema in
that style for this branch's summary instead of keeping the old shared
summary-body union. The inspect_analysis_view and CLI descriptions and
the generic unsupported-parent message are main's text plus this
branch's browser scenario additions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ansition-view

Resolve the summary-result conflict with main's native function matching
view (morluto#5390) by keeping both browserScenarioSummaryViewResultSchema and
nativeFunctionMatchingSummaryViewResultSchema in the parent_operation
summary union.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant