Skip to content

Layer 3: agent-driven onboarding run on a box, with a separate judge - #24

Draft
lihautan wants to merge 9 commits into
mainfrom
layer3-design
Draft

lihautan wants to merge 9 commits into
mainfrom
layer3-design

Conversation

@lihautan

@lihautan lihautan commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Design and a first runnable cell for layer 3 of the onboarding tests (#11).

What this adds

An agent plays a new user on a box and tries to set up box from the landing line, then use it for one task. A separate judge reads the recording afterwards and decides pass, fail or blocked.

  • cli/e2e/layer3/DESIGN.md covers the roles, the run folder, the judge, filing, the test account and open questions.
  • run.mjs resets the box over its shell tool, runs a headless claude -p driver, extracts the recording, and runs the judge.
  • The driver can use only box's screenshot, computer_act and computer_state. This is enforced by --tools "", --strict-mcp-config, --allowedTools and --disallowedTools, not only by the prompt.
  • extract.mjs turns the driver's stream-json transcript into steps.jsonl and numbered screenshots.
  • judge.md and judge.schema.json define the verdict and the cited improvements.
  • cells.json holds the first cell, Claude Code CLI from the landing line with OAuth.
  • mcp-client.mjs is the MCP client from mcp-tools.mjs, moved out so layer 3 can call tools.
  • publish-cli.yml links the design from its TODO(layer 3).

Recordings show the test account's screen, so runs are written to ~/.box-layer3/runs/, outside this public repo.

Not in this PR

  • Filing issues to box-portal from the judge's improvements.
  • funnel.json from box api, and revoking the run's grant.
  • CI scheduling.

Testing

  • node --test passes, including a new test for the extractor. Lint is clean.
  • The cell's reset and precheck ran on a real box.
  • The first live run is pending: it needs a signed-in claude CLI and a box key on the machine that runs it.

🤖 Generated with Claude Code

lihautan and others added 9 commits November 5, 2026 12:33
Design for #11. An agent plays the new user on a box
through box's MCP tools, every step is recorded to a run folder, and a
separate judge gives the verdict and files issues in box-portal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
run.mjs resets a box over its shell tool, drives the onboarding with a
headless claude -p limited to screenshot, computer_act and computer_state,
extracts steps and screenshots from the stream-json transcript, then runs
a fresh judge session that writes judge.json. The first cell is Claude
Code CLI from the landing line. mcp-tools.mjs now uses a shared
mcp-client.mjs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ctor cell

The first live run found Claude Code on the box loading the signed-in
claude.ai account's box connector, so the clean cell never installed
anything. The clean cell now sets ENABLE_CLAUDEAI_MCP_SERVERS=false and
its precheck matches box's URL, not the name box. The connector path is
its own cell. The driver no longer types ahead into a starting program.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
grants.mjs calls cocoonbox Grants over gRPC-web with the box key. A run's
grants are the ones its client created inside the run window: they become
funnel.json (approval and first token use) and are revoked after the run.
A run is blocked when the client already holds a live grant, since consent
would renew it. file.mjs files the judge's improvements with gh: product
targets to box-portal with screenshots on a layer3-evidence branch, harness
targets to this public repo as text only, emails masked everywhere, a model
dedupe against open issues, at most three new issues per run, and filed.json
so a run files once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A cell's name is now its three values joined with /, so it can't disagree
with its fields. cells.mjs holds the allowed values with plain meanings
and rejects unknown ones; the app entry also holds the name the app shows
on box's sign-in page, which the funnel uses. DESIGN.md gains a Cells
section (dimensions, every setup value, what a cell holds) and a funnel
section that matches funnel.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant