Skip to content

Sandbox the page, fix the hook and the Codex install, and release 0.3.1 - #6

Merged
awss1i merged 8 commits into
mainfrom
fixes-before-launch
Oct 17, 2026
Merged

awss1i merged 8 commits into
mainfrom
fixes-before-launch

Conversation

@awss1i

@awss1i awss1i commented Oct 17, 2026

Copy link
Copy Markdown
Owner

This branch fixes security gaps, hook bugs and install steps found in a review of assay, and sets the version to 0.3.1.

Security

  • The page under test runs in Chromium's sandbox. assay used to turn it off. Where the sandbox can't start, assay runs the page without it, prints a warning on stderr and sets "sandboxed": false in --json.
  • The local server no longer serves hidden files such as .env or .git/config, or a file a symlink points to outside the folder. Before this change, a test page could read both and send them anywhere.

Hook

  • A crash or a missing Chromium now prints a line naming the page, so an unchecked page no longer looks like a clean turn.
  • hooks.json sets a 600-second timeout, and the hook spends at most 540 seconds on checks. Factory Droid and GitHub Copilot CLI cut a hook off after 60 and 30 seconds by default, which lost the report.
  • The last-run file goes in the repository's git directory from any subfolder or worktree, instead of into the project.
  • --one-line keeps page text on one line, so a page can't add lines to the report an agent repeats.

Plugins and docs

  • The Codex marketplace file used policy values Codex rejects, so codex plugin marketplace add awss1i/assay failed. It now loads.
  • Cursor gets the skill without the Claude Code format hook.
  • The docs have install steps for Codex, Grok Build CLI and Cursor, correct the DeepSeek Harness, opencode, Devin CLI, Factory Droid and GitHub Copilot CLI sections, and drop the claims that assay makes no network calls or writes nothing to disk. All four translations are updated.

Checks

  • CI tests on Python 3.11 too, and the workflow has read-only permissions.
  • 26 new tests cover the server, the sandbox fallback, the hook's reports and time budget, the report writer, the Chromium download and the manifests.
  • Locally the full suite passes, including the 106 end-to-end tests in Chromium with the sandbox on, and both benchmark scorers run.

Playwright turns Chromium's sandbox off unless asked, and assay also
passed --no-sandbox, so every page ran outside the sandbox. assay now asks
for it. Where the sandbox can't start, such as when running as root or in
some containers, assay runs the page without it, prints a warning on stderr
and sets "sandboxed": false in --json.

The local server was Python's stock file server, which serves hidden files
and follows symlinks. A page under test could read .env or .git/config, or
a file a symlink points to outside the folder, and send it anywhere. The
server now answers 404 for all of those.

SECURITY.md and the plugin's SECURITY.md describe both boundaries.
The hook printed nothing when assay crashed or Chromium couldn't be
installed, so a page that was never checked looked the same as a turn that
changed none. Both cases now print a line naming the page.

hooks.json set no timeout, so each harness used its own default. Factory
Droid's is 60 seconds and GitHub Copilot CLI's is 30, which cuts off most
checks and loses the report. hooks.json now sets 600 seconds, and the hook
spends at most 540 on checks, so its report always gets out. A page left
without time is reported as not checked.

The hook kept its last-run time in .git only when the working directory was
the top of the repository. In a subfolder or a worktree it wrote
.assay-last-run into the project. It now finds the repository's git
directory from any folder in it.
--one-line quotes labels and error messages from the page, and agents
repeat it verbatim. A newline in one let the page add a line of its own,
such as a false "nothing flagged". Page text is now collapsed to one line
of printable characters.
…f Cursor

Codex rejected .agents/plugins/marketplace.json because its policy values
aren't ones Codex accepts, so `codex plugin marketplace add awss1i/assay`
failed. The file now uses AVAILABLE and ON_INSTALL, drops fields Codex
doesn't read, and files assay under Developer Tools.

Cursor reads hooks/hooks.json from a plugin unless the manifest names
another file, and that file is in Claude Code's format, which Cursor
doesn't document for plugins. The Cursor manifest now points at an empty
hooks file, so Cursor gets the skill alone, and it names the plugin's logo.

.codexignore is removed because Codex doesn't read it, and the Codex
description no longer says assay needs no network. A test pins these
manifests so a bad value can't stop a marketplace loading again.
The docs said Codex, Grok Build CLI and Cursor had no plugin, but the
repository ships one for each and all three install it, so each now has
its own section. The DeepSeek Harness reads the skill from .agents/skills/
as well as running the hook, and opencode's section now uses the same
folder. The hook is listed for the harnesses that run it, which are Claude
Code, Codex, Grok Build CLI, Devin CLI, Factory Droid, GitHub Copilot CLI
and the DeepSeek Harness.

The README no longer says assay makes no network calls or writes nothing
to disk, and it says the planted-bug score is in-sample. Every change is
in all four translations.
pyproject.toml lists 3.11 as supported, but the test matrix skipped it.
The report writer and the Chromium download had no tests. links_of and
Surface.unavailable were never read. The end-to-end test that shadows eval
now writes it directly.
Sets the version to 0.3.1 in pyproject.toml, uv.lock and the three plugin
manifests.
@github-actions github-actions Bot added documentation Improvements or additions to documentation plugin The skill, the hook, or a harness labels Oct 17, 2026
@awss1i
awss1i merged commit 8428e6b into main Oct 17, 2026
8 checks passed
@awss1i
awss1i deleted the fixes-before-launch branch October 17, 2026 01:29
Repository owner deleted a comment from github-actions Bot Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation plugin The skill, the hook, or a harness

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant