browser_review_gate 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf07fc0385a222895293b09a8000db74bf153a3b87731528b3e2d51c20cfd4e0
4
- data.tar.gz: 5866378bb1acbfa17f03d44d98413c6f6222903858b7ec7dd6f71a9b6ba95788
3
+ metadata.gz: ac053b24d64d38c70581bbfc8aef9b1a1419174634ce4a2bca58f1119bc639b2
4
+ data.tar.gz: 14819ac0b43719c11b0ad53f61ee588cdb27743071326d0e037e4fee1c076fea
5
5
  SHA512:
6
- metadata.gz: de467b5092e7d8d3e9871e789b2c844712808f6af4916173d3ec903fb84407eac61218c5e6ee54e4c20e91e10ccdd3cb4d06010a355e2ddae869118b496c4791
7
- data.tar.gz: 4ca8044e0cc223d3e269542ff1edb0ab635bdd710c549d017e48802c834eeef9b00fb2ff7ed71f9c9be37bd683185ea2d5450e95256574da7b12cf82723b7979
6
+ metadata.gz: d752841217a09af9f3514b1aabcc5abd23639ce43994ea13d59ca7b54267e66ae42855d6ba529584aeb0868394cee9d78e9a6f23f174ca51e439e0bea86e0747
7
+ data.tar.gz: 3c87aa88d8db31546e476f7e8fa11688272005875e266d5cbefc156c3ea5a4577861b975629eee8252bc5dad53442e3038855123ed85f7e8224f5d79efa745ef
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.1
4
+
5
+ - The `.network` log Playwright MCP writes with `browser_start_tracing`/`browser_stop_tracing` is
6
+ accepted as a case's trace, so Playwright MCP agents need no zip step. Its tracing tools need the
7
+ MCP server's `--caps devtools` option.
8
+
3
9
  ## 0.4.0
4
10
 
5
11
  - `provenance.trace` (off by default): the gem opens each case's Playwright trace and checks that a
data/README.md CHANGED
@@ -124,7 +124,7 @@ Off by default. A report is the agent's account; `provenance.trace` lets the gem
124
124
 
125
125
  It adds `X-App-Revision: <HEAD SHA>` to every response and follows new commits without a restart. Any other way of sending the header works too; name it in `provenance.revision_header`.
126
126
  2. Set `provenance.trace` to `warn` (results shown in the PR) or `require` (a passing case counts only with a verified trace). `doctor` checks that the app sends the header and that it matches the checkout.
127
- 3. The agent records a Playwright trace (`.zip`) or a HAR network log (`.har`) per case and lists it as `evidence.trace`. HAR is a standard format that Playwright, Chrome DevTools ("Save all as HAR") and many other tools write, so the check does not need Playwright itself. A browser tool that can save neither cannot satisfy `require`; `doctor` and `verify` warn about it before a run.
127
+ 3. The agent records a trace per case and lists it as `evidence.trace`: a Playwright `trace.zip`, the `.network` log Playwright MCP writes with `browser_start_tracing`/`browser_stop_tracing` (start the MCP server with `--caps devtools`), or a HAR network log (`.har`). HAR is a standard format that Playwright, Chrome DevTools ("Save all as HAR") and many other tools write, so the check does not need Playwright itself. A browser tool that can save neither cannot satisfy `require`; `doctor` and `verify` warn about it before a run.
128
128
 
129
129
  When the run is published, the gem opens each trace (a zip, or HAR JSON; read in memory with size, entry and compression-ratio caps, no extra dependency) and checks its network log: a response carried the revision header with the tested commit, the case's page was requested, and the request times fall within `started_at`..`finished_at` (± `clock_skew_seconds`). The PR shows "trace verified" or what was wrong.
130
130
 
@@ -134,7 +134,7 @@ What it catches: an agent that reports a run it did not do, ran against another
134
134
 
135
135
  A report is JSON in the shape the playbook describes (`schema_version: 2`): the tested commit (full SHA), the environment, the browser tool and its capabilities, start and finish times, and one case per scenario with `result` (`pass`, `fail`, `blocked`, `skipped`), the page, what was observed, and evidence.
136
136
 
137
- - Screenshots (`.png`, `.jpg`, `.webp`) and traces (`.zip` Playwright traces or `.har` network logs) are read from the report's directory. Paths that leave it, links, wrong file types (checked by content, not just name) and files over 20 MB are refused. Accepted files are hashed and kept in the git directory; the PR shows their names, sizes and SHA-256 digests, not the files.
137
+ - Screenshots (`.png`, `.jpg`, `.webp`) and traces (`.zip` Playwright traces, Playwright MCP `.network` logs or `.har` network logs) are read from the report's directory. Paths that leave it, links, wrong file types (checked by content, not just name) and files over 20 MB are refused. Accepted files are hashed and kept in the git directory; the PR shows their names, sizes and SHA-256 digests, not the files.
138
138
  - Console errors and failed requests are trimmed, query strings are dropped, and values that look like credentials are masked.
139
139
  - Evidence links are accepted only on hosts listed in `evidence.link_hosts`; use them to point reviewers at screenshots you uploaded to your own artifact store.
140
140
  - A case counts when it passes, breaks no enforced policy, and was tested on a commit of the PR.
@@ -24,9 +24,11 @@ module BrowserReviewGate
24
24
  ".webp" => [ "image/webp", [ "RIFF".b ] ],
25
25
  ".zip" => [ "application/zip", [ "PK\x03\x04".b ] ],
26
26
  # A HAR network log: JSON, so it starts with "{" after optional whitespace or a byte order mark.
27
- ".har" => [ "application/json", [ "{".b ] ]
27
+ ".har" => [ "application/json", [ "{".b ] ],
28
+ # The network log Playwright MCP writes next to a trace (traces/<name>.network): JSON lines.
29
+ ".network" => [ "application/x-ndjson", [ "{".b ] ]
28
30
  }.freeze
29
- TRACE_TYPES = %w[.zip .har].freeze
31
+ TRACE_TYPES = %w[.zip .har .network].freeze
30
32
  SECRET = /
31
33
  (?<key>authorization|proxy-authorization|cookie|set-cookie|x-api-key|api[_-]?key|access[_-]?token|refresh[_-]?token|
32
34
  id[_-]?token|token|secret|password|passwd|session(?:[_-]?id)?|csrf[_-]?token|auth)
@@ -25,7 +25,7 @@ This file is the playbook for the AI coding agent that does the run. The person
25
25
  4. Run every scenario end to end. For each case record:
26
26
  - `url`: the page it was exercised on; `details`: what you observed;
27
27
  - evidence, as `policy.agent` in the `verify` output asks: screenshots (`never`, `on_failure`, `always`), a trace, and the console errors and failed requests you saw (`[]` when there were none). Save files in a directory outside the repository, next to the report.
28
- - When `policy.enforced.trace_check` is `warn` or `require`, record a Playwright trace (`.zip`) or a HAR network log (`.har`, which Playwright and Chrome DevTools can save) for every case, one per case, and list it as `evidence.trace`. If your browser tool can save neither, stop and tell the person: with `require`, every passing case would be refused. The gem opens it and checks that the app answered with the tested commit, that the case's page was requested, and that the requests fall between `started_at` and `finished_at`. With `require`, a passing case without such a trace does not count. Record the trace while running the case; a trace from another run will not match.
28
+ - When `policy.enforced.trace_check` is `warn` or `require`, record a trace for every case and list it as `evidence.trace`: a Playwright `trace.zip`, the `.network` file Playwright MCP writes into its `traces` directory after `browser_stop_tracing` (its tracing tools need the `--caps devtools` option), or a HAR network log (`.har`). Start tracing before the case and stop it after, and copy the file next to the report. If your browser tool can save neither, stop and tell the person: with `require`, every passing case would be refused. The gem opens it and checks that the app answered with the tested commit, that the case's page was requested, and that the requests fall between `started_at` and `finished_at`. With `require`, a passing case without such a trace does not count. Record the trace while running the case; a trace from another run will not match.
29
29
  - A scenario you could not run is `blocked` (something prevented it) or `skipped` (deliberately not run), with a `reason`. Neither is a pass.
30
30
  5. Write the report as JSON next to the evidence (see the shape below). Set `coverage_complete` to true only when every scenario from step 2 ran.
31
31
  6. Publish, from the checkout that was tested, with everything committed and pushed: `browser-review-gate verify --report PATH` (add `--pr NUMBER` when the branch has several PRs). With a PR it is published; without one it is saved and published when the PR for this commit is opened.
@@ -86,7 +86,7 @@ Some scenarios cannot be exercised locally, for example a sign-in through an ext
86
86
 
87
87
  - `result`: `pass`, `fail`, `blocked` or `skipped`. `url` is an http(s) URL or a path starting with `/`; required for `pass` and `fail`. `reason` is required for `blocked` and `skipped`.
88
88
  - `tool.capabilities`: what your browser tool could record, from `screenshots`, `trace`, `console`, `network`. Claim only what it really can.
89
- - `evidence` paths are relative to the report file's directory. Accepted: `.png`, `.jpg`, `.jpeg`, `.webp` screenshots and a `.zip` Playwright trace or `.har` network log, at most 10 files of 20 MB each. `network_errors` entries may be strings or `{ "method", "url", "status" }`; query strings are dropped. `links` may point to evidence kept elsewhere, on hosts listed in `evidence.link_hosts`.
89
+ - `evidence` paths are relative to the report file's directory. Accepted: `.png`, `.jpg`, `.jpeg`, `.webp` screenshots and a `.zip` Playwright trace, a Playwright MCP `.network` log or a `.har` network log, at most 10 files of 20 MB each. `network_errors` entries may be strings or `{ "method", "url", "status" }`; query strings are dropped. `links` may point to evidence kept elsewhere, on hosts listed in `evidence.link_hosts`.
90
90
  - Everything you write is scrubbed of values that look like credentials, but do not rely on it: never put cookies, tokens, passwords or customer data into a report, a screenshot or a trace. Keep customer and real company names out of the report.
91
91
 
92
92
  ## Rules
@@ -3,8 +3,9 @@ require "time"
3
3
  require "uri"
4
4
 
5
5
  module BrowserReviewGate
6
- # Reads a Playwright trace (trace.zip) or a HAR network log (.har, which Playwright, Chrome DevTools
7
- # and other tools write) and checks that it shows the case really ran against the
6
+ # Reads a Playwright trace (trace.zip), the network log Playwright MCP saves beside its trace
7
+ # (.network), or a HAR network log (.har, which Playwright, Chrome DevTools and other tools write) and
8
+ # checks that it shows the case really ran against the
8
9
  # tested code: a response carried the app's revision header with the tested commit, the case's page
9
10
  # was requested, and the requests fall inside the run's time window.
10
11
  #
@@ -40,17 +41,15 @@ module BrowserReviewGate
40
41
 
41
42
  def read(path)
42
43
  return read_har(path) if File.extname(path).casecmp?(".har")
44
+ return read_lines(File.binread(path, ZipReader::MAX_ENTRY_BYTES + 1).to_s.force_encoding(Encoding::UTF_8)) if File.extname(path).casecmp?(".network")
43
45
 
44
46
  requests = []
45
- ZipReader.new(path).each(->(name) { NETWORK_ENTRY.match?(name) }) do |_name, content|
46
- content.each_line do |line|
47
- request = parse(line)
48
- requests << request if request
49
- end
50
- end
47
+ ZipReader.new(path).each(->(name) { NETWORK_ENTRY.match?(name) }) { |_name, content| requests.concat(read_lines(content)) }
51
48
  requests
52
49
  end
53
50
 
51
+ def read_lines(content) = content.each_line.filter_map { |line| parse(line) }
52
+
54
53
  def read_har(path)
55
54
  text = File.binread(path, ZipReader::MAX_ENTRY_BYTES + 1).to_s.force_encoding(Encoding::UTF_8).delete_prefix("\uFEFF")
56
55
  log = JSON.parse(text)
@@ -1,3 +1,3 @@
1
1
  module BrowserReviewGate
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browser_review_gate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Islam Gagiev