Skip to content

readWorkspace has no ignore rules or size cap, so it cannot carry a real project #19

Description

@amondnet

Both review passes on #13 noticed this and neither filed it, because the fix is a design decision rather than a patch.

The gap

readWorkspace walks the source with readdir(root, { recursive: true }) and reads every file into memory as a string. seedWorkspace then writes each one through writeTextFile, which in the harness layer is intoDirectoryFor (an mkdir) followed by writeFile — so on the Docker backend that is a docker round trip per directory plus one per file.

There is no ignore list, no size cap, and no batching.

Why it matters more than it looks

This is not a performance nit on an edge case. It blocks the use case the project states as its reason to exist. From packages/core/src/agent/workspace.ts own header:

a directory handed to defineAgent({ workspace }) is not a file drop — it is how an existing Claude Code project is carried into a sandbox unchanged.

Point workspace at an actual Claude Code project and it walks node_modules, .git, dist, and every build artifact into memory, then issues two container calls for each.

And since #13 it is a hard failure, not merely slow. decodeText now refuses a file that is not valid UTF-8, naming it — deliberately, so a PNG cannot be silently seeded as a string of U+FFFD. A real project directory contains at least one such file (a .git pack, an icon, a lockfile binary), so readWorkspace rejects the whole seed. The UTF-8 guard is right; combined with the missing ignore rules it means the documented use case currently cannot run at all.

What needs deciding

  • Which ignore rules. Honour the project .gitignore? A fixed built-in list (node_modules, .git, dist)? Caller-supplied globs? Some combination, and which wins.
  • What to do with a binary file once ignores exist — still refuse, or skip with a warning? The refusal is correct for a file the caller meant to seed and wrong for one that only got picked up by a broad walk.
  • A size cap, per file and in total, and whether exceeding it refuses or warns.
  • Whether seeding should batch rather than issuing per-file calls — this is a backend question (a tar stream into the container), so it may belong with the sandbox contract rather than here.

Scope note

The Worker path takes a WorkspaceFiles record inlined at build time and never calls readWorkspace, so whatever is decided here also has to be what the future build-time inliner applies — otherwise local runs and deployed ones carry different file sets.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions