Repository navigation
feat(analysis-view): page retained browser scenario steps and text - #4163
kangyishuai wants to merge 29 commits into
Conversation
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>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
[Medium impact] The PR appears safe to merge; no actionable blocking issues were found. SummaryAdds summary, step, and retained-text views for
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
Reviews (28) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." · Reviewed by Greptile |
There was a problem hiding this comment.
💡 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".
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>
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>
|
Could a maintainer approve the pending workflow runs for this PR? It is my first contribution from a fork, so Until they run, all validation is local. After merging 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>
There was a problem hiding this comment.
💡 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".
…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>
There was a problem hiding this comment.
💡 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".
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>
There was a problem hiding this comment.
💡 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".
… 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>
There was a problem hiding this comment.
💡 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".
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>
There was a problem hiding this comment.
💡 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".
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>
There was a problem hiding this comment.
💡 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".
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>
There was a problem hiding this comment.
💡 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".
…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>
There was a problem hiding this comment.
💡 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".
…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>
There was a problem hiding this comment.
💡 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".
…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>
There was a problem hiding this comment.
💡 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".
…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>
There was a problem hiding this comment.
💡 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".
…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>
There was a problem hiding this comment.
💡 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".
…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>
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
…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>
|
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>
There was a problem hiding this comment.
💡 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".
…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>
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
…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>
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
…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>
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
…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>
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
…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>
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
@earakely-scale @gensokyo-dev @kaoru0822-kitauji, I'd like to align on Where the two lines of work meet
Questions
|
…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>
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_pagerecords plus a caller-declared external action. This PR projects the steps of one REA-controlledcapture_browser_scenariorun. 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_scenarioalready records a post-action capture for every declared step. Agents still could not read a completed capture step by step:inspect_analysis_viewrejected it as an unsupported parent.compare_web_capturescompares two runs, not consecutive steps within one run.Problem and expected behavior
An external agent reconstructing an application's behavior needs, for each declared step:
It needs this without re-reading the whole capture or re-running the browser.
inspect_analysis_viewreturnedParent Evidence operation "capture_browser_scenario" does not support analysis views(source-derived fromunsupportedParentinsrc/domain/analysisView/analysisView.tson main). An oversized capture could only be exported.{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_scenarioparent forinspect_analysis_viewandinspect-analysis-view.changefrom 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 isnullwithnot_requestedcoverage, never0. Every page also carriesenabled_event_familiesandreceived_outside_step_windows.Single owners:
compare_web_capturescomparison owner.browserScenarioDiffEvidencenow exports per-step artifact observation, andbrowserScenarioDiffexports pair classification. Run comparison output is unchanged; see the evidence below.enabledScenarioEventFamilies. The Playwright producer and the view both call it, with no behavior change.The view fails closed on inconsistent recorded data:
step_idand action;step_indexand stay disjoint;scenariofields (start origin, action count, secret references, network content, event families, limits); and each step's artifacts, which followafter_each_stepon every step andat_endon 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.
browserScenarioCaptureSchemanow rejects:scenario_start/goto_startstep whose receipt window starts at event sequence 1, now a shared constant that the producer uses;actionwhen 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;events), or that omitseventsdespite connect mode, dropped events, a retained unfinished request, unavailable network content, or a popup while a gap family is selected;network_transaction_rangethat does not match the network events dropped formax-network-transactions(a reason only network kinds may carry), or per-transaction omissions that do not correlate withby_kindin 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;by_kindrow counting fewer drops than its listed reasons and naming transaction records imply. Becauseby_kindkeeps 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;header_valuesand the phase's body selection, or content kept or dropped with no content facet selected;requestevent for one transaction;max_events, or more admitted transactions thanmax_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.tsand the capture fields inbrowserScenarioCaptureFields.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-openedrecord whenever any family is selected, because popup discovery runs for every selected family. The producer's final parse,compare_web_capturesand 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:
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:
compare_web_capturesgets them too;by_kind, which would replace the current bounds on refused-transaction drops but is a producer format change;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:
detail: "summary"delivery forcapture_browser_scenario, planned as a separate PR because it changes a producer tool's input.Alternatives rejected:
compare_web_captures: inline-only inputs, a reduced compact schema, and observed/external-service labelling of a derivation.Contract and boundary impact
src/domain/browserScenarioSteps.ts;browserScenarioDiffEvidence.tsandbrowserScenarioDiff.ts;src/domain/analysisView/browserScenarioView*.ts.inspect_analysis_viewandinspect-analysis-view. The tool count stays at 207. Measured byte and token deltas are under Validation.PlaywrightScenarioEventsnow calls the shared family rule. Views accept the current capture schema only.compare_web_capturesnow also rejects inline captures that contradict these capture rules; the producer never wrote such captures. Thecompare_web_capturescontract example now records a consistent launch-mode capture with the producer'sgoto_startstart step.rea.analysis-viewwith confidencederived. It inherits the parent'scontrolled-replayauthority under the existing view rule and links the parent.controlled-replayauthority, so exported bundlescenariosmanifests will list view records with operationinspect_analysis_view. Maintainer input is welcome.Expected effects:
Evidence and regression coverage
src/domain/analysisView/browserScenarioView.test.ts, 13 cases:null, not0;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 intoverify:browser.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.browserScenarioDiff.test.ts,browserCli.test.ts,tests/fixtures/webScriptCapture.ts,ScriptCaptureAdapters.test.tsandwebScriptExport.test.tsnow record producer-shaped captures. Each test keeps its property; for example, differing comparison anchors now come from unrelated events instead of unaccounted sequence gaps.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.For evidence-bearing changes:
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
aac8f3136merges main1417bf943. 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 onparent_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:fastpassed (typecheck and lint).npm run test:localpassed on 49 source test files (692 tests).npm run test:focusedpassed on 164 boundary, acceptance, contract, catalog and environment files: 1,493 passed, 48 skipped.npm run docs:checkpassed.npm run verify:browserpassed with Google Chrome 155.0.8059.85 andverified: true, includingscenarioViews.The previous merge head
c1fcb5c5fmerged main2538214e2. 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 onparent_operation. This PR's summary now follows that pattern withbrowserScenarioSummaryViewResultSchema, 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:fastpassed (typecheck and lint).npm run test:localpassed on 49 source test files (692 tests).npm run test:focusedpassed 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:checkpassed.npm run verify:browserpassed with Google Chrome 155.0.8059.85 andverified: true, includingscenarioViews.The previous merge head
bddd1eaaemerged main0134732fc. Main's protobuf capture view (#5031) conflicted in two places:UnsignedAnalysisView: main now derives this type fromAnalysisViewResultinstead of listing each kind, so the browser-scenario result needs no separate entry.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:fastpassed (typecheck and lint).npm run test:localpassed on 48 source test files (687 tests).npm run test:focusedpassed on 161 boundary, acceptance, contract, catalog and environment files: 1,464 passed, 48 skipped.npm run docs:checkpassed.npm run verify:browserpassed with Google Chrome 155.0.8059.85 andverified: true, includingscenarioViews.The previous merge head
05a17923amerged main3fca2e0ca. Main's #5319 adds anenvironment-stateview that also readscapture_browser_scenarioparents. The merge keeps both sides:api-surface,environment-manifest,environment-state) still go to main's projectors first, and this PR's projector servessummaryandbrowser-scenario. This PR's refusal for any other view kind now names all four supported views.docs/mcp-contracts.mdplaces main's environment-state paragraph right after the environment-manifest paragraph it refers to, followed by this PR's paragraph.environmentScenario.test.tskeeps this PR's summary-succeeds check, with the four-view message.header_valuesselected. 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:fastpassed (typecheck and lint).npm run test:localpassed on 46 source test files (679 tests), including main'senvironmentStateView, environment andscenarioCaptureRecordstests.npm run test:focusedpassed on 160 boundary, acceptance, contract, catalog and environment files: 1,460 passed, 48 skipped.npm run docs:checkpassed.npm run verify:browserpassed with Google Chrome 155.0.8059.85 andverified: true, includingscenarioViews.The previous merge head
ae827b13fmerged mainf93a0335a. Main's #5293 adds anevidence-filesource toinspect_analysis_viewand new service tests. Two conflicts came from it:capture_browser_scenariotext;AnalysisViewService.test.ts, which now keeps both this PR's browser-scenario authority test and main'sinspectAnalysisViewWithFilestests.For the summary, steps and text views of the fixture capture, an
evidence-filesource gives the samenormalized_result,controlled-replayauthority 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:fastpassed (typecheck and lint).npm run test:localpassed on 43 source test files (632 tests), including main's new evidence-file andscenarioCaptureRecordstests.npm run test:focusedpassed on 158 boundary, acceptance, contract, catalog and environment files: 1,448 passed, 48 skipped.npm run docs:checkpassed.npm run verify:browserpassed with Google Chrome 155.0.8059.85 andverified: true, includingscenarioViews.The previous merge head
150d147ecmerged main5fa4defcb. The only conflict was theinspect_analysis_viewdescription, where main's Godot PCK change (#3634) rewrote the inventory text. The merge keeps main's text and adds only this PR'scapture_browser_scenarioparent and view sentences. #3634 does not touch the browser scenario producer, capture schema, views or fixtures. On that head:npm run check:fastpassed (typecheck and lint).npm run test:localpassed on 42 source test files (616 tests).npm run test:focusedpassed on 158 boundary, acceptance, contract, catalog and environment files: 1,447 passed, 48 skipped.npm run docs:checkpassed.npm run verify:browserpassed with Google Chrome 155.0.8059.80 andverified: true, includingscenarioViews.The previous merge head
d499af870merged main833136507. Main's newil2cpp-metadataview (#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:fastpassed (typecheck and lint).npm run test:localpassed on 41 source test files (605 tests), including main's environment,scenarioCaptureRecordsand IL2CPP view tests.npm run test:focusedpassed on 158 boundary, acceptance, contract, catalog and environment files: 1,447 passed, 48 skipped.npm run docs:checkpassed.npm run verify:browserpassed with Google Chrome 155.0.8059.80 andverified: true, includingscenarioViews.The previous merge head
2cae99f53merged mainbf1eeee94. Main's #5182 builds environment manifests fromcapture_browser_scenarioparents, so one parent kind now has two view paths:environment-manifestviews still go to main's projector first. This PR's projector servessummaryandbrowser-scenarioviews for the same parents, and its refusal for any other view kind now names all three supported views.tests/fixtures/browserScenarioCapture.tsbuilt 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:wait_for_timeoutand receives every event;environmentScenario.test.tsusedsummaryas its unsupported example. It now expectssummaryto succeed on the same Evidence, and checks that an unsupported view names the supported ones.On that head:
npm run check:fastpassed (typecheck and lint).npm run test:localpassed on 40 source test files (595 tests), including main's environment andscenarioCaptureRecordstests.npm run test:focusedran 327 boundary, acceptance, contract and environment files: 3,529 passed, 122 skipped, 2 failed. The failures arejavascriptRuntimeObservation("includes targets outside the old caller root filter") andfilesystemObservationRaceCli("keeps a stable symlink observation complete"). Both fail the same way on a clean mainbf1eeee94worktree on this macOS machine, and this PR does not touch those areas.npm run docs:checkpassed.npm run verify:browserpassed with Google Chrome 155.0.8059.80 andverified: true, includingscenarioViews.The previous head
757bbdfc3fixed 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:fastpassed (typecheck and lint).npm run test:localpassed on 29 capture, view, producer, network, scenario-service, observation and Evidence test files (477 tests).npm run test:focusedpassed on 64 boundary, acceptance and contract files: 526 passed, 5 skipped.npm run verify:browserpassed with Google Chrome 155.0.8059.80 andverified: true, includingscenarioViews; the steps view is 14,713 bytes, unchanged.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.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
aa689d960merged mainb4938aed5. Main's newdesktop-applicationview (#5207) conflicted with this PR's browser-scenario views in theinspect_analysis_viewtool description and theinspect-analysis-viewCLI 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:fastpassed (typecheck and lint).npm run test:localpassed on 29 capture, view, producer, network, scenario-service, observation and Evidence test files (476 tests).npm run test:focusedpassed on 64 boundary, acceptance and contract files: 526 passed, 5 skipped.npm run docs:checkpassed.npm run verify:browserpassed with Google Chrome 155.0.8059.80 andverified: true, includingscenarioViews.The previous merge head
2fa0ba9e8merged mainfdaffe21c. There, main'senvironment-manifestview (#4954) conflicted in the tool description,docs/mcp-contracts.mdandtests/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:checkandverify:browser.The previous merge head
6ae23996emerged mainbec88b9d7. Its only conflict was inscripts/verify-real-browser.mjs, where both sides added a verifier import, and the merge kept both.verify:browserpassed there too, including main'surlUserInfocheck.The previous head
bf85798c4added only a change to the views, which now merge the capture's own limitations with the envelope's. I validated it withnpm 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 maind9d085a15and includes the earlier review fixes:npm run checkpassed, with lint at 0 errors.npm run docs:check,npm run verify:test-discovery,npm run jscpd(3.28%) andnpm run scan:todospassed.npm run test:localpassed on 16 capture, view and producer test files (280 tests).npm run test:focusedpassed on 46 boundary, acceptance and contract files: 482 passed, and 2 tests inserverLifecycleMcp.test.tswere 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:browserpassed with Google Chrome 155.0.8059.80 andverified: true, includingscenarioViewsand popup coverage.PlaywrightScenarioEventsrecorder 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. Themax-listener-ownersreason was not exercised.consoleselected,max_events: 1and awindow.openpopup completes, with two omittedpopup-openedrecords. Before the popup adjustment, the stricter rule rejected this producer output.Earlier results on the first PR commit, rebased onto main
9d6651e5b:npm run checkpassed, with lint at 0 errors.npm run docs:checkpassed.npm run verify:test-discoverypassed.npm run jscpdpassed (3.18%).npm run scan:todospassed.npm run test:localpassed on 19 domain, service and producer test files (291 tests), includingsrc/domain/analysisView/*,src/application/analysisView/*,src/domain/browserScenario*.test.ts,src/domain/evidence.test.tsandsrc/browser/PlaywrightScenario*.test.ts.npm run test:focusedpassed on 17 files (194 tests): the analysis-view MCP and CLI boundaries plustoolSchemaValidity,contractPresentation,toolInputAdmission,compactInputSchemaMcp,outputSchemaProfile,serverIdentity,cliToolCoverage,jsonInputStatus,cliStartupImports,productCatalog,documentationFacts,targetContentProvenance,toolEffects,toolInputReferencesandtupleSchemaParity.npm run verify:browserpassed with Google Chrome 155.0.8059.40 andverified: true. That includes the newscenarioViewscheck: 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.
capture_browser_scenario(21 steps)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
tokenxestimates of the returned text, not billed model usage.Catalog effect, comparing main
9d6651e5bwith the first PR commit (not re-measured after the merge and the review fix):Compatibility, safety, and release
environment-manifestview (feat(environment): build environments from browser scenario captures #5182), which parses the same schema. Main's hand-built fixture intests/fixtures/browserScenarioCapture.tswas one of them, and this PR updates it to match what the recorder emits (details under Validation).src/domain/browser*andsrc/browser/**files.managedMemberViewprecedent. 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
Before merge
type(scope): outcome.🤖 Generated with Claude Code