Repository navigation
Prepare 3.1.0 for a paid web pilot - #93
Merged
Merged
Conversation
gabe4coding
marked this pull request as ready for review
October 18, 2026 19:34
This was referenced Oct 19, 2026
Pin TypeSafe to jev-1.14.0 on SDK 0.7, send an advisory failure screenshot, retry a truncated page with long context, and stop on Node older than 22. Co-authored-by: Gabe <gpavanello@thefork.com>
A version 1 lock still replays locators. A claim hash that does not match is judged again, and plain prints a one-line re-record notice. The long-context retry caps the uncut tree at 400k characters and does not run again on the settle re-check. plain-computer and plain-mobile name themselves in the Node check. A within claim does not get a whole-viewport screenshot line, and the split-text hint is only for text and count claims. Co-authored-by: Gabe <gpavanello@thefork.com>
gabe4coding
force-pushed
the
cursor/web-pilot-3-1-0-7357
branch
from
October 19, 2026 12:30
0468b4c to
913432c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prepares
@gabe4coding/plain3.1.0 for a paid browser pilot. Do not merge until you want this published: the Publish workflow onmainpublishes the version inpackage.jsonand tagsv3.1.0. This PR does not publish, tag, or create a GitHub release.Follow-up on
0468b4c(after live review ofcab4bb2): version 1 lock files are read again, and four smaller fixes landed. Not merged, not published, no tag.Follow-up: version 1 locks and the review notes
parseLockaccepts version 1 and version 2. Locators did not change, so--mode no-judgereplays them. A version 1 claim hash that does not match is judged again (a re-verify) instead of an inconclusive "page differs". The first read prints one line:plain: re-record to upgrade lock file: <path>. A passingjudgeorauto-healingrun writes version 2. Version 0 is still ignored. Tests:src/core/lock.test.ts(read + the one-line notice) andsrc/browser/lock.test.ts(a version 1 file replays in no-judge with no Jev call; a hash of zeros is judged again, the locator still replays, and no-judge does not rewrite the file). Desktop and mobile use the same store and the same re-verify.LONG_CONTEXT_MAX_CHARS, about 100k tokens, inside the 262k window). A settle re-check in the same check does not send long context again. Tests: the cap insrc/core/automation.test.ts, andsrc/browser/expect-advice.test.ts(a ticking cut page sends long context once).plain-computerandplain-mobilepass their own command name intorefuseOldNode. A Node 20 process saysplain-computer requiresorplain-mobile requires, notplain requires. Covered byscripts/node-check.test.mjs.expectwithwithindoes not send the viewport screenshot. The shot is the whole viewport, so it must not say a region claim holds. The split-text hint can still appear. Test:src/browser/expect-advice.test.ts.splitTextHintreturns false for a spatial claim (sureSpatial).2 items leftstays a count claim, because thatleftis not a relation. Test:src/browser/split-text.test.ts.1. TypeSafe SDK 0.7 and
jev-1.14.0@typesafe-ai/sdkis^0.7.0(lockfile 0.7.0). The TypeSafe model isjev-1.14.0inMODEL_BY_PROVIDER. The gateway model staystypesafe-ai/jev.usage.input_tokensandusage.output_tokensasnumber | null.tokenCountinsrc/jev/ask.tstreats null as zero. Covered bysrc/jev/ask.test.ts.jev-1.14.0.2. Failure screenshots, on by default
A browser
expectthat does not pass, and that has nowithin, sends the viewport PNG plain already captures. The call usesimage()with headerTypeSafe-Danger-Zone-Images: true. Sides must be 280–1568 px and the file must be at most 16 MiB; anything outside that range is not sent (TypeSafe rejects it, and plain does not resize).The step detail gets a
screenshot:line (holds,contradicted, ornot visible, with the probability). That line never changes pass or fail. A thrown image call, unreadable bytes, or no configured provider omits the line and leaves the status. The gateway path does not support images:ask()throws before sending, and the detail saysscreenshot: not sent (the Vercel AI Gateway path has no image support).Evidence:
src/jev/explain.test.tsandsrc/browser/expect-advice.test.ts(a pass does not call explain; a fail stays fail; a throw keeps the fail; a scopedwithincheck does not call explain; a zero-token gateway line is printed and not counted).3. Long context only after the 60k cut
When the capture set
truncatedand the uncut tree is longer than the text actually sent,judgeStateasks once more withTypeSafe-Danger-Zone-Long-Context: trueand uses that answer. The tree is cut at 400,000 characters. A failed retry keeps the first verdict. If the page changes while that check settles, the later look uses the cut tree and does not send long context again. The gateway path throws before sending, and that error is caught so the cut verdict stays.The uncut tree is
fullAriaon the capture, not on the public snapshot. New lock hashes include it, so new files are version 2. Version 1 files are still read (see the follow-up above). There are no committed lock files in this repo.Evidence:
src/core/automation.test.tsand the long-page cases insrc/browser/expect-advice.test.ts.Live e2e on
cab4bb2(run 39158122212): the long/consentpage judged with(long context)and the expected passes stayed passes (p=0.97). The expected failure on that page stayed a failure (p=0.01) with the screenshot line. No spec passed only on a retry. This follow-up has not been re-run live yet (see Validation).4. Split text
docs/phrasing.mdxsays to name the element (the counter shows 2 items left) when the tree puts2anditems lefton different lines. A failed text or count check whose neighboring content words appear on different lines, and not as one phrase, addshint:fromSPLIT_TEXT_HINT. A spatial claim does not get the hint. The hint does not change the status.Evidence:
src/browser/split-text.test.tsand the failed-check case insrc/browser/expect-advice.test.ts.5. Security and data
@modelcontextprotocol/sdkis^1.32.0(lockfile 1.32.1).webdriveriois10.0.2. 9.32.0 did not clear the audit (extract-ziphas no patched release). 10.0.2 drops that chain.npm audit --omit=devon this branch: info 0, low 0, moderate 0, high 0, critical 0.docs/security.mdxcovers page data sent to TypeSafe or Vercel, screenshots sent by default on a failed browser check, the 400,000-character long-context cap,$TMPDIR/plaineven without--artifacts, and$VAR/${env.*}for secrets.enginesstays>=22so a browser run on 22.0–22.18 is not blocked by the package.6. Node 22 at startup
bin/node-check.mjsexits before Playwright or webdriverio load. Browser and desktop require 22. Mobile also requires 22.19. The message names the CLI that was invoked (plain,plain-computer, orplain-mobile), the minimum, and the running version.Evidence:
scripts/node-check.test.mjs, including a spawned process on a faked Node 20.19.0 that exits 1 and does not continue.7. Nightly live runs
.github/workflows/live.ymlhascron: '0 6 * * *'(06:00 UTC). GitHub runs a schedule on the default branch only. A non-pull-request event already setsruntime=true, so the nightly run executes the checks.The workflow already uses
secrets.TYPESAFE_API_KEY. No secret was added from this environment.8. Beta engines and the pilot runbook
The README marks desktop and mobile as beta and drops React Native from the platforms cell. The same claim is gone from
docs/mobile-use.mdxand the mobile skill.docs/pilot.mdxcovers about five critical browser specs in CI, a nightly schedule, and what to measure (false passes stay 0, inconclusive, retries, tokens).9. Release 3.1.0, not published
package.jsonis3.1.0.CHANGELOG.mdcovers the pilot items, the version 1 lock read, and the user-visible work already on main since 3.0.0. Not published. No tag. No GitHub release.Validation
Local, on Node v22.23.3, after
0468b4c:npm run verifypassed in one run (/tmp/plain-verify2.log,EXIT:0). Tests 574, pass 574, fail 0. Docs ok (18). Agent notes ok (8). Source rules ok (3); the cast baseline is 62 after three!were removed. dependency-cruiser: no violations (163 modules). Examples validate. Plugin smoke: packed npx install and MCP protocol passed forplain,plain-computer, andplain-mobile.Not run in this environment, and why:
TYPESAFE_API_KEYis unset here (also unset in a fresh login shell, and there is no~/.config/plain/.env).node scripts/e2e.mjsandnode scripts/benchmark-claims.mjs --gatewere not run. The previous live run oncab4bb2is 39158122212 (E2E passed, specs 36,no-judge: 21/21, claimsFALSE PASS 0). Pushing this commit starts a new Live workflow with the repository secret. That result is not in yet.claudeandcodexare not installed (command -vfinds neither), so the agent evals and routing evals thatscripts/validate.mjsruns for the skill-file change were not run. CI does not run those evals.Out of scope, and not in this diff: the
boxprimitive, comment pruning, and unrelated refactors.