ruby_llm-browser 0.1.0 → 0.3.0
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 +4 -4
- data/CHANGELOG.md +34 -0
- data/CONTRIBUTING.md +8 -1
- data/README.md +25 -96
- data/docs/API.md +5 -172
- data/docs/RAILS.md +5 -162
- data/docs/README.md +23 -12
- data/docs/RELEASE_ACTION_PLAN.md +28 -13
- data/docs/RELEASE_AUDIT.md +19 -0
- data/docs/RELEASING.md +24 -12
- data/docs/SECURITY_MODEL.md +1 -1
- data/docs/WORK.md +22 -0
- data/docs/_advanced/development-and-testing.md +107 -0
- data/docs/_advanced/live-backend-qualification.md +5 -0
- data/docs/_advanced/rails-integration.md +147 -29
- data/docs/_advanced/result-delivery.md +119 -0
- data/docs/_config.yml +8 -4
- data/docs/_core_features/diagnostics.md +68 -0
- data/docs/_core_features/inspect-extract.md +18 -2
- data/docs/_data/navigation.yml +2 -0
- data/docs/_getting_started/getting-started.md +11 -1
- data/docs/_getting_started/overview.md +3 -0
- data/docs/_getting_started/whats-new-in-0-3.md +48 -0
- data/docs/_plugins/versioned_docs.rb +3 -3
- data/docs/_reference/api-and-configuration.md +203 -0
- data/docs/_reference/api-reference.md +3 -2
- data/docs/_reference/release-history.md +3 -1
- data/docs/_reference/roadmap.md +171 -0
- data/docs/_reference/upgrading.md +48 -14
- data/docs/_reference/whats-new-in-0-2.md +46 -0
- data/docs/index.md +2 -3
- data/examples/plain_ruby.rb +7 -4
- data/examples/rails_results.rb +141 -0
- data/lib/ruby_llm/browser/doctor.rb +25 -10
- data/lib/ruby_llm/browser/rails/operation_job.rb +16 -4
- data/lib/ruby_llm/browser/rails/result_delivery_error.rb +22 -0
- data/lib/ruby_llm/browser/rails.rb +16 -0
- data/lib/ruby_llm/browser/result.rb +3 -3
- data/lib/ruby_llm/browser/version.rb +1 -1
- data/lib/ruby_llm/browser.rb +11 -0
- metadata +11 -2
data/docs/RELEASE_ACTION_PLAN.md
CHANGED
|
@@ -7,26 +7,41 @@ llms: false
|
|
|
7
7
|
|
|
8
8
|
# Release action plan
|
|
9
9
|
|
|
10
|
+
This is the historical 0.1.0 release record. Use the
|
|
11
|
+
[roadmap to 1.0]({% link _reference/roadmap.md %}) for upcoming development.
|
|
12
|
+
|
|
10
13
|
The owner selected the offline-only first release as `0.1.0`, authorized its publication,
|
|
11
|
-
and requested tag-based release automation.
|
|
12
|
-
and
|
|
14
|
+
and requested tag-based release automation. Version `0.1.0` is published. This plan records
|
|
15
|
+
the outcome and preserves the live-provider limits for future work.
|
|
13
16
|
|
|
14
17
|
## Current position
|
|
15
18
|
|
|
16
|
-
- Hardening baseline: `0ec34d4`.
|
|
17
|
-
- Expanded remote CI
|
|
19
|
+
- Hardening baseline: `0ec34d4`; release workflow fix: `8f0e8e7`.
|
|
20
|
+
- Expanded remote CI passed before release. Tagged verification and publication passed in
|
|
21
|
+
[release run 39110148539](https://github.com/yorzi/ruby_llm-browser/actions/runs/39110148539).
|
|
22
|
+
- RubyGems lists [ruby_llm-browser 0.1.0](https://rubygems.org/gems/ruby_llm-browser).
|
|
23
|
+
Publication used the registered trusted publisher for `yorzi/ruby_llm-browser`,
|
|
24
|
+
`.github/workflows/release.yml`, and environment `release`; MFA publication is recorded.
|
|
25
|
+
- The [GitHub Release](https://github.com/yorzi/ruby_llm-browser/releases/tag/v0.1.0)
|
|
26
|
+
includes the gem and `SHA256SUMS`. The gem SHA-256 is
|
|
27
|
+
`0159bf5b4d50fc1a5d129ce8e6d8235ff9a5181704d5e8168c2facb429808ed3`.
|
|
28
|
+
- The post-release Pages build passed in
|
|
29
|
+
[Docs run 39110265391](https://github.com/yorzi/ruby_llm-browser/actions/runs/39110265391).
|
|
30
|
+
The [custom-domain docs site]({% link index.md %}) shows `0.1.0 (stable)`.
|
|
31
|
+
- The first publish attempt failed before upload because the action's optional
|
|
32
|
+
experimental attestation patch activated Ruby's default zlib before Bundler. The
|
|
33
|
+
unpublished tag was moved to a fix that disables that patch; OIDC publication remains.
|
|
18
34
|
- Owner decision on 2026-10-18: first release is read-only; defer live Act and mark the
|
|
19
35
|
built-in Stagehand backend unsupported until egress and cleanup are qualified.
|
|
20
36
|
- No live provider calls are authorized or were run for this decision.
|
|
21
37
|
- Independent H1 and owner H2 are complete for exact candidate Q
|
|
22
38
|
`22d488987517b10dcd96d2713ed3d47e8818b36b`. H2 approves handoff, not RubyGems publication.
|
|
23
|
-
- The
|
|
24
|
-
|
|
25
|
-
matches installed gemspec metadata; Stagehand is covered by its pinned source
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
`release` environment.
|
|
39
|
+
- The pre-release exact-name check returned 404 on 2026-10-18; it did not reserve the
|
|
40
|
+
name. Version `0.1.0` is now registered on RubyGems. The resolved 26-gem runtime license
|
|
41
|
+
inventory matches installed gemspec metadata; Stagehand is covered by its pinned source
|
|
42
|
+
MIT text.
|
|
43
|
+
- The owner instructed publication separately from H2's handoff approval. The gem requires
|
|
44
|
+
MFA, and RubyGems records the successful publication as MFA-protected.
|
|
30
45
|
|
|
31
46
|
## Release scope
|
|
32
47
|
|
|
@@ -42,9 +57,9 @@ exact Q `22d488987517b10dcd96d2713ed3d47e8818b36b`; the approved Specs candidate
|
|
|
42
57
|
| --- | --- | --- |
|
|
43
58
|
| Release scope / Act | H2 approved the read-only scope and KPI proposal against exact Q. Live Act remains a later-version feature. | Keep the Stagehand adapter disabled and preserve the H2 decision in release docs. |
|
|
44
59
|
| Provider qualification | No live call is authorized for the first release. A later live release needs a named deployment and approval of data-processing/billing owners. | Record the unsupported egress and cleanup guarantees. Do not use a host assertion as qualification. |
|
|
45
|
-
| Name and account | The owner authorized publication as `ruby_llm-browser`;
|
|
60
|
+
| Name and account | The owner authorized publication as `ruby_llm-browser`; version `0.1.0` is registered and MFA-protected. | Use the existing trusted publisher for future tags; do not add a long-lived RubyGems API key to GitHub. |
|
|
46
61
|
| Formal approval | H1 and H2 are complete for exact Q; C/R registration and implementation baseline receipt remain pending. | Preserve the historical approval. Do not represent H2 as RubyGems authorization; the owner's later release instruction supplies that authorization. |
|
|
47
|
-
| Publication |
|
|
62
|
+
| Publication | Version `0.1.0` is published under tag `v0.1.0`; GitHub Release assets and stable Pages are live. | For each later version, align gem/docs/changelog metadata and push the matching tag. The release workflow verifies tests, advisories and package contents before OIDC publishing; Docs deploys after success. |
|
|
48
63
|
|
|
49
64
|
## Provider questions to resolve before live tests
|
|
50
65
|
|
data/docs/RELEASE_AUDIT.md
CHANGED
|
@@ -156,3 +156,22 @@ does not authorize provider calls, make Stagehand supported, or implement live A
|
|
|
156
156
|
approved Specs Q remains identified by its historical candidate label `0.3.0-draft`.
|
|
157
157
|
RubyGems publication and GitHub Pages deployment results are recorded separately from
|
|
158
158
|
this pre-release audit snapshot.
|
|
159
|
+
|
|
160
|
+
## Publication outcome (2026-10-18)
|
|
161
|
+
|
|
162
|
+
The owner authorized publishing the offline-only `0.1.0` package after the earlier audit
|
|
163
|
+
snapshot. The RubyGems trusted publisher is registered for repository `yorzi/ruby_llm-browser`,
|
|
164
|
+
workflow `release.yml`, and environment `release`. The corrected tagged workflow
|
|
165
|
+
[39110148539](https://github.com/yorzi/ruby_llm-browser/actions/runs/39110148539) passed
|
|
166
|
+
tagged-package verification and published the gem with GitHub OIDC. RubyGems lists
|
|
167
|
+
[version 0.1.0](https://rubygems.org/gems/ruby_llm-browser), published with MFA metadata;
|
|
168
|
+
the [GitHub Release](https://github.com/yorzi/ruby_llm-browser/releases/tag/v0.1.0)
|
|
169
|
+
contains the gem and checksum. The custom-domain [documentation site]({% link index.md %})
|
|
170
|
+
is deployed and shows `0.1.0 (stable)`.
|
|
171
|
+
|
|
172
|
+
The first tag run, [39109944660](https://github.com/yorzi/ruby_llm-browser/actions/runs/39109944660),
|
|
173
|
+
failed before upload because the action's optional experimental attestation patch loaded
|
|
174
|
+
RubyGems before Bundler and activated Ruby's default zlib. The unpublished tag was moved
|
|
175
|
+
to a workflow fix that disables that optional patch; OIDC publishing remains active.
|
|
176
|
+
This release does not close provider qualification: no live egress, TTL, billing, or
|
|
177
|
+
cleanup calls were made. Stagehand remains unsupported, and full live Act remains deferred.
|
data/docs/RELEASING.md
CHANGED
|
@@ -17,6 +17,10 @@ After reading this guide, you will know:
|
|
|
17
17
|
|
|
18
18
|
## Compatibility evidence
|
|
19
19
|
|
|
20
|
+
The source repository's `docs/evidence/V0_3_VALIDATION.md` records local 0.3.0 checks.
|
|
21
|
+
`docs/evidence/V0_3_RELEASE.md` records the exact remote CI, published artifact and
|
|
22
|
+
hosted documentation results. The earlier audit below is historical evidence.
|
|
23
|
+
|
|
20
24
|
The 2026-10-18 audit runs on Ruby **3.3.5**, arm64 macOS, with Stagehand **3.21.0**,
|
|
21
25
|
JSONSchemer **2.5.0**, and sqlite3 **2.10.0**. Full offline suites cover:
|
|
22
26
|
|
|
@@ -40,6 +44,7 @@ bundle exec rake
|
|
|
40
44
|
bundle exec bundle-audit check --update
|
|
41
45
|
bundle exec ruby examples/plain_ruby.rb
|
|
42
46
|
bundle exec ruby examples/rails_adapter.rb
|
|
47
|
+
bundle exec ruby examples/rails_results.rb
|
|
43
48
|
|
|
44
49
|
BUNDLE_GEMFILE=gemfiles/ruby_llm_2_0.gemfile bundle install
|
|
45
50
|
BUNDLE_GEMFILE=gemfiles/ruby_llm_2_0.gemfile bundle exec rspec
|
|
@@ -47,6 +52,7 @@ BUNDLE_GEMFILE=gemfiles/rails_8_0.gemfile bundle install
|
|
|
47
52
|
BUNDLE_GEMFILE=gemfiles/rails_8_0.gemfile bundle exec rspec
|
|
48
53
|
|
|
49
54
|
bundle exec rake build
|
|
55
|
+
bin/verify-release --candidate # for unreleased development candidates
|
|
50
56
|
bundle exec ruby bin/verify-package --rails --audit
|
|
51
57
|
```
|
|
52
58
|
|
|
@@ -76,10 +82,10 @@ Verify all of the following:
|
|
|
76
82
|
- Core require loads no Rails, Active Record, Active Job, or Stagehand client.
|
|
77
83
|
- The optional Rails require loads on demand.
|
|
78
84
|
- The generated migration and all README-linked guides are shipped.
|
|
79
|
-
-
|
|
85
|
+
- All shipped examples run using the installed artifact.
|
|
80
86
|
- The artifact contains no keys, cookies, dumps, databases, lockfiles, or test fixtures.
|
|
81
87
|
- Dependency/license inventory and known-advisory check match the resolved versions.
|
|
82
|
-
- Record the artifact SHA-256, exact versions, commands and date in the
|
|
88
|
+
- Record the artifact SHA-256, exact versions, commands and date in the candidate validation note.
|
|
83
89
|
|
|
84
90
|
## Release boundaries
|
|
85
91
|
|
|
@@ -101,18 +107,24 @@ made for `0.1.0`.
|
|
|
101
107
|
## Releasing a version
|
|
102
108
|
|
|
103
109
|
For a later version, update the gem version in `lib/ruby_llm/browser/version.rb` and the
|
|
104
|
-
documentation version in `docs/_config.yml` to the same value. Keep `released: false`
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
documentation version in `docs/_config.yml` to the same value. Keep `released: false`
|
|
111
|
+
while preparing a candidate. Set it to `true` and update `stable_version` when the
|
|
112
|
+
owner authorizes a release. The documentation builder uses release tags
|
|
113
|
+
for the stable site and builds the working tree under `/next/`. Add a matching release
|
|
114
|
+
entry to `CHANGELOG.md` and `docs/_reference/release-history.md`.
|
|
115
|
+
|
|
116
|
+
During candidate development, keep changes under `Unreleased` in the changelog and
|
|
117
|
+
run `bin/verify-release --candidate`. Before tagging, move them to a dated release
|
|
118
|
+
section and run `bin/verify-release` without that flag. The tag workflow requires
|
|
119
|
+
released metadata; local candidate verification cannot enable publication.
|
|
108
120
|
|
|
109
121
|
Run the checks above, review the package contents and push the completed commit to
|
|
110
|
-
`main`. Then create and push a matching tag, for example `
|
|
111
|
-
`
|
|
122
|
+
`main`. Then create and push a matching tag, for example `v{{ site.version }}` for gem version
|
|
123
|
+
`{{ site.version }}`:
|
|
112
124
|
|
|
113
125
|
```bash
|
|
114
|
-
git tag -a
|
|
115
|
-
git push origin
|
|
126
|
+
git tag -a v{{ site.version }} -m "Release {{ site.version }}"
|
|
127
|
+
git push origin v{{ site.version }}
|
|
116
128
|
```
|
|
117
129
|
|
|
118
130
|
The `Release Gem` workflow rejects a tag that does not match both the gem and docs
|
|
@@ -127,5 +139,5 @@ workflow `release.yml`, and environment `release` before the first tag.
|
|
|
127
139
|
## Next steps
|
|
128
140
|
|
|
129
141
|
- Review the requirement evidence in the source repository's `docs/WORK.md` and the [remaining audit findings]({% link RELEASE_AUDIT.md %}).
|
|
130
|
-
- Follow the
|
|
131
|
-
|
|
142
|
+
- Follow the [roadmap to 1.0]({% link _reference/roadmap.md %}) for proposed version scope.
|
|
143
|
+
The source repository's `docs/RELEASE_ACTION_PLAN.md` preserves the 0.1.0 release record.
|
data/docs/SECURITY_MODEL.md
CHANGED
|
@@ -113,5 +113,5 @@ qualification. Cleanup and TTL are best-effort, and cost values are advisory.
|
|
|
113
113
|
|
|
114
114
|
## Next steps
|
|
115
115
|
|
|
116
|
-
- Follow [Rails recovery]({% link
|
|
116
|
+
- Follow [Rails recovery]({% link _advanced/rails-integration.md %}) to schedule cleanup and protect status access.
|
|
117
117
|
- Review [the release audit]({% link RELEASE_AUDIT.md %}) for evidence and remaining blockers.
|
data/docs/WORK.md
CHANGED
|
@@ -242,6 +242,28 @@ the tag's stable documentation only after that release workflow succeeds. The fi
|
|
|
242
242
|
is pushed only after the trusted publisher is registered for this repository and the
|
|
243
243
|
`release.yml` workflow under the `release` GitHub environment.
|
|
244
244
|
|
|
245
|
+
### 0.1.0 publication receipt (2026-10-18)
|
|
246
|
+
|
|
247
|
+
The first tagged workflow run failed before the gem upload because the action's optional
|
|
248
|
+
experimental attestation patch loaded RubyGems before Bundler and activated Ruby 3.3's
|
|
249
|
+
default zlib instead of the locked patched zlib. No gem was published by that attempt.
|
|
250
|
+
The release action now has attestations disabled; trusted OIDC publishing remains enabled.
|
|
251
|
+
The unpublished `v0.1.0` tag was moved to the workflow-fix commit before retrying.
|
|
252
|
+
|
|
253
|
+
| Check | Result |
|
|
254
|
+
| --- | --- |
|
|
255
|
+
| Tagged release workflow | PASS: [run 39110148539](https://github.com/yorzi/ruby_llm-browser/actions/runs/39110148539); tagged package verification and RubyGems publish jobs succeeded |
|
|
256
|
+
| RubyGems | PASS: [ruby_llm-browser 0.1.0](https://rubygems.org/gems/ruby_llm-browser); published by `yorzi/ruby_llm-browser` via `.github/workflows/release.yml` and `release` environment; MFA publication is recorded |
|
|
257
|
+
| Gem SHA-256 | `0159bf5b4d50fc1a5d129ce8e6d8235ff9a5181704d5e8168c2facb429808ed3` |
|
|
258
|
+
| GitHub Release | PASS: [v0.1.0](https://github.com/yorzi/ruby_llm-browser/releases/tag/v0.1.0) contains the `.gem` file and `SHA256SUMS` |
|
|
259
|
+
| Documentation Pages | PASS: [run 39110265391](https://github.com/yorzi/ruby_llm-browser/actions/runs/39110265391); the [custom-domain docs site]({% link index.md %}) shows `0.1.0 (stable)` |
|
|
260
|
+
| Live provider egress, TTL, billing and cleanup | NOT RUN; Stagehand remains unsupported until provider qualification |
|
|
261
|
+
| Full live Act protocol | NOT IMPLEMENTED; offline simulation only, deferred to a later version |
|
|
262
|
+
|
|
263
|
+
The published gem metadata reports MFA publication. No long-lived RubyGems API key was
|
|
264
|
+
added to GitHub; the release workflow uses the registered trusted publisher and GitHub
|
|
265
|
+
OIDC. The first failed run was [39109944660](https://github.com/yorzi/ruby_llm-browser/actions/runs/39109944660).
|
|
266
|
+
|
|
245
267
|
## Commit log
|
|
246
268
|
|
|
247
269
|
Small, meaningful commits land one piece at a time. See `git log` for the authoritative
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Development and Testing
|
|
4
|
+
nav_order: 3
|
|
5
|
+
description: Verify changes with offline contracts, installed packages, and a local browser workbench.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# {{ page.title }}
|
|
9
|
+
|
|
10
|
+
{{ page.description }}
|
|
11
|
+
|
|
12
|
+
After reading this guide, you will know:
|
|
13
|
+
|
|
14
|
+
- How to run the local verification loop.
|
|
15
|
+
- How to review browser behavior and retain fixture screenshots.
|
|
16
|
+
- What offline, browser, and installed-package checks establish.
|
|
17
|
+
|
|
18
|
+
## Run the Offline Checks
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
bin/setup
|
|
22
|
+
bin/check
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Start a behavior change with a focused failing spec. Implement the smallest public
|
|
26
|
+
contract, update its guide, then run `bin/check`. The command runs specs and RuboCop,
|
|
27
|
+
the RubyLLM 2.0 and Rails 8.0 alternate bundles, and the plain-Ruby and Rails examples.
|
|
28
|
+
Install each alternate bundle first if needed. Database suites run sequentially.
|
|
29
|
+
RuboCop uses the writable `tmp/rubocop` cache. Default tests block unmocked HTTP.
|
|
30
|
+
|
|
31
|
+
The Rails result suite executes serialized jobs in separate processes against temporary
|
|
32
|
+
SQLite files. It verifies reads after worker exit, actor/run isolation, conflicting
|
|
33
|
+
delivery rejection, persistence failures before and after commit, and the crash gap
|
|
34
|
+
between browser execution and host storage. HTTP stays blocked in those subprocesses.
|
|
35
|
+
A frozen 0.2.0 migration verifies preservation of existing rows and indexes. These
|
|
36
|
+
checks exercise host result delivery without adding a second browser fixture.
|
|
37
|
+
|
|
38
|
+
Commit each completed change with its docs and checks. Keep the next work item in the
|
|
39
|
+
[roadmap]({% link _reference/roadmap.md %}); do not create a second task ledger.
|
|
40
|
+
|
|
41
|
+
## Review the Offline Workbench
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
BUNDLE_GEMFILE=gemfiles/browser.gemfile bundle install
|
|
45
|
+
bin/workbench
|
|
46
|
+
# Open http://127.0.0.1:4024, then Ctrl-C to stop.
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The single fixture in `dev/workbench.rb` runs the real Ruby tools with FakeBackend,
|
|
50
|
+
a deterministic resolver, and an in-memory operation store. Inspect and Extract show
|
|
51
|
+
their returned hashes and fake start/cleanup counts. Enter an unapproved host to
|
|
52
|
+
exercise a denial, run offline Doctor, or check that Stagehand remains blocked. The
|
|
53
|
+
Stagehand diagnostic uses synthetic fixture credentials and never calls the provider.
|
|
54
|
+
|
|
55
|
+
The host serves local HTML and CSS, escapes returned content, requires a form token,
|
|
56
|
+
and accepts loopback Host values only. It is a development fixture, not a production
|
|
57
|
+
controller or a new public gem API. It does not load the requested page or use provider
|
|
58
|
+
credentials. The fixture and browser libraries are excluded from the gem.
|
|
59
|
+
|
|
60
|
+
## Run Browser Tests
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
bin/check-browser
|
|
64
|
+
# Or include browser tests after the offline checks:
|
|
65
|
+
bin/check --browser
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Use installed Chrome. `CHROME_BIN` can select its binary; `CHROMEDRIVER` can select an
|
|
69
|
+
installed matching driver to avoid Selenium Manager's driver resolution. Screenshots
|
|
70
|
+
go into the printed, ignored `tmp/browser/` directory. The runner fails if tests fail
|
|
71
|
+
or no screenshot is produced. CI retains fixture screenshots for seven days.
|
|
72
|
+
|
|
73
|
+
Browser scenarios cover inspect/extract, denial before dispatch, keyboard recovery at
|
|
74
|
+
a 390px device viewport, and offline/blocked-Stagehand Doctor output. Capture screenshots before closing the
|
|
75
|
+
active session, including on assertion failures. Inspect failure artifacts before
|
|
76
|
+
retrying. Screenshots support visual review; assertions establish the expected behavior.
|
|
77
|
+
|
|
78
|
+
The Puma host and Selenium port probe bind loopback. Browser test HTTP clients allow
|
|
79
|
+
loopback only; this is not a Chrome network firewall. No live provider request is part
|
|
80
|
+
of this suite. Tests close their driver sessions, and Puma ends with the test process.
|
|
81
|
+
Stop manual previews and verify no task-owned service remains after your review.
|
|
82
|
+
|
|
83
|
+
## Verify a Candidate Package
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
bin/check --browser --package
|
|
87
|
+
bin/verify-release --candidate
|
|
88
|
+
docs/bin/build.sh
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The package option builds the gem and runs `bin/verify-package --rails --audit`. It
|
|
92
|
+
installs into an empty GEM_HOME outside the checkout, resolves dependencies from the
|
|
93
|
+
registry, runs shipped examples, tests the generated migration, and audits the activated
|
|
94
|
+
runtime. Refresh the advisory database first with `bundle exec bundle-audit check --update`.
|
|
95
|
+
Package verification needs registry access; offline test success cannot replace it.
|
|
96
|
+
|
|
97
|
+
`bin/verify-release --candidate` checks version alignment, the Unreleased changelog,
|
|
98
|
+
the unreleased docs flag, and package exclusions. Without `--candidate`, it requires
|
|
99
|
+
released docs and a dated changelog; the tag workflow never passes the candidate flag.
|
|
100
|
+
The install verifier copies the input artifact before testing and prints that snapshot's
|
|
101
|
+
SHA-256. A later build cannot replace the file under verification.
|
|
102
|
+
|
|
103
|
+
Record the exact artifact hash, dependency versions, checks, and not-run boundaries in
|
|
104
|
+
the candidate validation note. Local browser tests prove fixture application wiring.
|
|
105
|
+
They do not establish real provider egress, session TTL, cleanup, billing, external
|
|
106
|
+
adoption, remote CI success, or publication. Follow the
|
|
107
|
+
[release checklist]({% link RELEASING.md %}) before releasing.
|
|
@@ -34,6 +34,11 @@ built-in Stagehand backend as unsupported: `egress_isolation` remains `:unverifi
|
|
|
34
34
|
the Engine refuses to start a session. The host cannot override this status with a
|
|
35
35
|
constructor option. A custom backend must enforce its own browser-side network boundary.
|
|
36
36
|
|
|
37
|
+
The fake report has `mode: :offline` and skips provider credential and SDK checks.
|
|
38
|
+
Stagehand reports `mode: :live` even though it remains unsupported; mode describes
|
|
39
|
+
the backend, not its qualification. See [Checking Configuration]({% link _core_features/diagnostics.md %})
|
|
40
|
+
for the report fields and checks applied to each backend.
|
|
41
|
+
|
|
37
42
|
Browserbase's documented [Allowed Domains feature](https://docs.browserbase.com/platform/browser/security/allowed-domains)
|
|
38
43
|
applies to top-frame navigations. It does not block iframe or subresource requests such
|
|
39
44
|
as scripts, images, and XHR. That setting alone cannot qualify provider egress. Any future
|
|
@@ -1,56 +1,174 @@
|
|
|
1
1
|
---
|
|
2
2
|
layout: default
|
|
3
|
-
title:
|
|
3
|
+
title: Rails Jobs and Recovery
|
|
4
4
|
nav_order: 1
|
|
5
|
-
|
|
5
|
+
redirect_from:
|
|
6
|
+
- /RAILS/
|
|
7
|
+
description: Run bounded read-only operations with durable state and independently scheduled cleanup.
|
|
6
8
|
---
|
|
7
9
|
|
|
8
|
-
#
|
|
10
|
+
# Rails jobs and recovery
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
{: .fs-6 .fw-300 }
|
|
12
|
+
Run bounded read-only operations with durable state and independently scheduled cleanup.
|
|
12
13
|
|
|
13
14
|
After reading this guide, you will know:
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
- How to install the adapter's tables.
|
|
17
|
+
- How to build a freshly authorized job context with matching budgets.
|
|
18
|
+
- How to deliver results to host storage.
|
|
19
|
+
- How to inspect status, cancel work, and recover orphaned sessions.
|
|
18
20
|
|
|
19
|
-
##
|
|
21
|
+
## Installing the adapter
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
Your application supplies Rails 8, Active Record, Active Job, and a database adapter.
|
|
24
|
+
They are not runtime dependencies of the plain-Ruby gem.
|
|
23
25
|
|
|
24
26
|
```ruby
|
|
25
27
|
require "ruby_llm/browser/rails"
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
```
|
|
30
|
+
```bash
|
|
29
31
|
bin/rails generate ruby_llm:browser:install
|
|
30
32
|
bin/rails db:migrate
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
The generator creates
|
|
34
|
-
|
|
35
|
+
The generator creates operations, approvals, and per-actor reservation-lock tables.
|
|
36
|
+
SQLite and PostgreSQL are accepted by the store, but only SQLite concurrency is tested
|
|
37
|
+
locally. MySQL is not supported by this adapter's partial indexes/locking contract.
|
|
38
|
+
Use a database timeout appropriate to your workload. Database lock failures fail closed;
|
|
39
|
+
they must not be handled by retrying a browser call with a new operation ID.
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
`Schema.create!` is for disposable fixtures, not production migrations or schema upgrades.
|
|
42
|
+
The [offline Rails example](https://github.com/yorzi/ruby_llm-browser/blob/main/examples/rails_adapter.rb) requires no full Rails app.
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
run authorization, and use the same operation store and budget limits as the reservation.
|
|
40
|
-
Never put provider credentials or authorization decisions in model arguments or job
|
|
41
|
-
payloads. Protect queue storage because URLs, instructions, and schemas are persisted.
|
|
44
|
+
## Configuring the trusted context factory
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
```ruby
|
|
47
|
+
# config/initializers/ruby_llm_browser.rb
|
|
48
|
+
require "ruby_llm/browser/rails"
|
|
49
|
+
|
|
50
|
+
browser_budget = RubyLLM::Browser::Budget.new(max_seconds: 30, max_steps: 6)
|
|
51
|
+
RubyLLM::Browser::Rails.context_factory = lambda do |actor_id:, run_id:|
|
|
52
|
+
# Resolve authenticated host records and recheck authorization, consent and revocation.
|
|
53
|
+
# Build policy/backend from those records, never from job or model-supplied credentials.
|
|
54
|
+
RubyLLM::Browser::Context.new(
|
|
55
|
+
actor_id: actor_id, run_id: run_id,
|
|
56
|
+
backend: qualified_backend, source_policy: policy,
|
|
57
|
+
operation_store: RubyLLM::Browser::Rails.operation_store,
|
|
58
|
+
budget: browser_budget
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`qualified_backend` and `policy` above are host objects, not global APIs supplied by the
|
|
64
|
+
gem. The factory must use the **same operation-store instance and budget limits** as
|
|
65
|
+
the queued reservation. Construct different budgets per run only from trusted records
|
|
66
|
+
that the factory can retrieve again. An optional approval store does not enable Act in
|
|
67
|
+
jobs; `OperationJob` accepts only `inspect` and `extract`.
|
|
68
|
+
|
|
69
|
+
## Enqueuing a read-only operation
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
operation = RubyLLM::Browser::Rails::OperationJob.enqueue(
|
|
73
|
+
actor_id: current_user.id.to_s, run_id: research_run.id.to_s,
|
|
74
|
+
kind: :inspect, url: "https://docs.example.com/",
|
|
75
|
+
budget: browser_budget, idempotency_key: "research-#{research_run.id}"
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
For extraction, pass `kind: :extract` and a host-pinned JSON `schema:`. Optional
|
|
80
|
+
`instruction:` and `max_bytes:` have the same meaning as on the tools.
|
|
81
|
+
|
|
82
|
+
One actor/run/key identifies one exact payload and budget. A changed payload using the
|
|
83
|
+
same key is rejected. Repeated enqueue calls may add duplicate queue deliveries, but
|
|
84
|
+
they attach to the same durable operation. Starting is atomically claimed once. A job
|
|
85
|
+
that sees a started, unknown, pending-cleanup, or terminal operation cannot start it
|
|
86
|
+
again. No automatic browser retry is configured.
|
|
87
|
+
|
|
88
|
+
Reservation and queue insertion are separate transactions. If enqueueing fails, retain
|
|
89
|
+
the returned operation identity when available and use the same idempotency key after
|
|
90
|
+
investigation. Schedule the reaper to reclaim expired reservations that never started.
|
|
44
91
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
92
|
+
Configure `RubyLLM::Browser::Rails.job_queue = :browser` if you need a separate queue.
|
|
93
|
+
Jobs suppress argument logging, but queues still persist URLs, instructions and schemas.
|
|
94
|
+
Protect queue access, storage, retention and encryption in the host application.
|
|
95
|
+
|
|
96
|
+
## Reading status and progress
|
|
97
|
+
|
|
98
|
+
```ruby
|
|
99
|
+
store = RubyLLM::Browser::Rails.operation_store
|
|
100
|
+
operation = store.fetch!(operation_id)
|
|
101
|
+
# Authorize this read against the authenticated actor/run before returning anything.
|
|
102
|
+
summary = operation.summary
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`summary` omits provider session IDs and budget internals. It reports state, steps,
|
|
106
|
+
bytes, fence, timestamps, error code and cancellation flag. It is coarse progress,
|
|
107
|
+
not a percentage-complete promise. To persist a result body, opt in to
|
|
108
|
+
`RubyLLM::Browser::Rails.result_delivery`. The callback receives `operation:` and
|
|
109
|
+
`result:` after execution and cleanup. Your application owns storage and authorized
|
|
110
|
+
retrieval. Read [Rails result delivery]({% link _advanced/result-delivery.md %}) for
|
|
111
|
+
failure handling and recovery. Do not rely on an Active Job return value after
|
|
112
|
+
asynchronous execution.
|
|
113
|
+
|
|
114
|
+
The stores are trusted server APIs, not tenant-safe controllers. They expose unscoped
|
|
115
|
+
fetch/sweep methods for workers; never expose them directly to model arguments or HTTP.
|
|
116
|
+
Tool progress callbacks are feature-detected on RubyLLM 2.1+, and contain no raw URL.
|
|
117
|
+
|
|
118
|
+
## Cancelling and reaping
|
|
119
|
+
|
|
120
|
+
```ruby
|
|
121
|
+
store.cancel(operation_id, actor_id: current_user.id.to_s,
|
|
122
|
+
run_id: research_run.id.to_s, now: Time.now.utc)
|
|
123
|
+
RubyLLM::Browser::Rails::Reaper.new(backend: qualified_backend).sweep
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Cancellation of a never-started reservation is terminal immediately. Otherwise it sets
|
|
127
|
+
`cancel_requested`, fences stale workers, and remains `cleanup_pending` with quota held.
|
|
128
|
+
It cannot undo an in-flight provider request. A returned session ID is persisted even
|
|
129
|
+
if cancellation raced with session creation.
|
|
130
|
+
|
|
131
|
+
Run a reaper regularly in an independent scheduler, not only in the operation worker's
|
|
132
|
+
ensure block. A reaper fences workers **before** reconciliation/cleanup, tries to end
|
|
133
|
+
known sessions even when provider reconciliation is unavailable, and reports `failed`
|
|
134
|
+
rather than claiming a database write succeeded. `ttl_seconds:` is an optional positive
|
|
135
|
+
idle threshold, not proof that the provider's billable session has expired.
|
|
136
|
+
|
|
137
|
+
Stagehand exposes no correlation endpoint here. An unknown start without a session ID
|
|
138
|
+
remains unknown and holds quota until the host supplies provider-confirmed evidence.
|
|
139
|
+
Alert on unknown/pending/failed entries. Never free quota just because enough local time
|
|
140
|
+
passed. An unknown action outcome remains in the result/error code even if session
|
|
141
|
+
cleanup succeeds; do not replay it.
|
|
142
|
+
|
|
143
|
+
One reaper/backend instance must cover only operations belonging to that provider
|
|
144
|
+
configuration. The current table has no backend credential-configuration binding.
|
|
145
|
+
Multi-provider/multi-credential deployments need a host-scoped store or a future schema
|
|
146
|
+
extension before a global sweep is safe.
|
|
147
|
+
|
|
148
|
+
## Upgrading an earlier development snapshot
|
|
149
|
+
|
|
150
|
+
If you installed the generator from an earlier development snapshot, preserve your data
|
|
151
|
+
and add an explicit migration for these new fields instead of rerunning `create_table`
|
|
152
|
+
or dropping the database:
|
|
153
|
+
|
|
154
|
+
```ruby
|
|
155
|
+
class HardenBrowserBookkeeping < ActiveRecord::Migration[8.1]
|
|
156
|
+
def change
|
|
157
|
+
create_table :ruby_llm_browser_actors, id: :string do |t|
|
|
158
|
+
t.integer :sequence, null: false, default: 0
|
|
159
|
+
end
|
|
160
|
+
add_column :ruby_llm_browser_operations, :cancel_requested, :boolean, default: false, null: false
|
|
161
|
+
add_column :ruby_llm_browser_operations, :request_digest, :string
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
```
|
|
49
165
|
|
|
50
|
-
|
|
51
|
-
|
|
166
|
+
Adapt this migration if any additions already exist. Drain workers during the upgrade.
|
|
167
|
+
Legacy rows without request digests are not payload-bound, so do not reuse their
|
|
168
|
+
idempotency keys for new work. Inspect earlier terminal cancellations for sessions that
|
|
169
|
+
may not have been confirmed closed before reclaiming them.
|
|
52
170
|
|
|
53
|
-
## Next
|
|
171
|
+
## Next steps
|
|
54
172
|
|
|
55
|
-
|
|
56
|
-
|
|
173
|
+
- Review [the API]({% link _reference/api-and-configuration.md %}) for result interpretation and budget semantics.
|
|
174
|
+
- Review [release blockers]({% link RELEASE_AUDIT.md %}) before production deployment.
|