workspace-mgr 0.4.0

Fixed-policy repository workspace manager for coding agents
workspace-mgr-0.4.0 is not a library.

workspace-mgr

workspace-mgr is the repository interface for coding agents. It turns repository policy into executable instructions, creates isolated task scaffolding, chooses whether retained content lives in Git or S3, and publishes both as one verified transaction.

The public model has two storage locations:

  • Git stores content directly in the repository history.
  • S3 stores content as versioned objects while Git records the small metadata needed to reproduce that exact state.

Content can also be explicitly kept local only with untrack: its bytes stay in the working tree, while a small placement record and managed .gitignore rule prevent future publication. New clones do not receive those bytes.

Users and agents choose between those concepts; the lower-level engines remain implementation details.

Start with the workspace model to understand how a user can treat a coding agent as a general-purpose collaborator, how a writable chat becomes one task/branch/PR, and how scope, placement, publication, and the shared checkout fit together. Continue with the user guide for the lifecycle. The command reference documents every public command, option, side effect, and example.

Core workflow

workspace-mgr setup
workspace-mgr init \
  --s3-url s3://example-bucket/workspace \
  --s3-endpoint-url https://s3.example.invalid
workspace-mgr doctor
workspace-mgr instructions
workspace-mgr task create example-task \
  --title "Example task" \
  --purpose "Produce one reviewable deliverable"
workspace-mgr plan
workspace-mgr publish -m "Create the task review"
workspace-mgr task create shared-policy --kind infrastructure \
  --title "Shared policy" --purpose "Update repository policy" \
  --scope AGENTS.md --scope-note "The user requested this shared change"

Inside a task:

workspace-mgr task rename more-accurate-topic
workspace-mgr storage status
workspace-mgr storage set path/to/data --to s3 --reason "Retained dataset"
workspace-mgr storage set path/to/report.pdf --to git --reason "Review in Git"
workspace-mgr remove path/to/obsolete-data
workspace-mgr untrack path/to/local-data
workspace-mgr plan
workspace-mgr publish -m "Publish the deliverable"

A task directory is where the work happens, not only where finished results are filed: the tools the agent writes, the materials they use, and the task's own record of decisions, process, and hard-to-reproduce results all live inside it, listed in its README directory map.

What leaves the task directory is curated. Every file under a task is either selected for publication or ignored by a rule this repository tracks, so the by-products of a run are not published by accident. Rules for one task belong in that task's own .gitignore; this repository's own rules belong in .workspace-mgr/repository.gitignore, from which init generates the root .gitignore together with the product's fixed rules. A path that only a machine-local rule hides is refused.

Immediately after creating a deliverable task, the agent publishes its initial scaffold and creates the one matching draft pull request. Before every later turn ends, it automatically records the turn's decisions, process, tools, and hard-to-reproduce results in the task's own files, publishes all safe retained in-scope changes, updates the draft pull request, and verifies that the local task, remote branch, and pull-request head agree. This synchronization does not require a separate user request.

When a conversation's topic changes, task rename <new-slug> moves the complete deliverable directory and updates task metadata while preserving the immutable task ID, target branch, and existing pull request. The next ordinary publish removes the previously published path and publishes the new one. storage set, storage reset, move, remove, and untrack change local desired state only. storage hydrate reads from S3. plan is read-only. publish is the only command that publishes repository content, and it verifies S3 before publishing a Git revision. It then permanently deletes every S3 version at object paths removed by delete, move, rename, untrack, or S3-to-Git placement; current remote branches and tags defer deletion until the last live reference disappears. If the user instead decides to retain none of the task, the agent closes its unmerged pull request and uses task discard --dry-run followed by task discard --confirm <task-id> to remove its branch and local workspace.

Each task's cloud usage across Git history and retained S3 versions is limited to 1 GiB (1073741824 bytes). plan reports the published and projected usage, and publish refuses to grow a task past its limit; while a task is over its limit, only publications that remove content, apart from at most 1 MiB (1048576 bytes) of new workspace-mgr control-file content per publication, where metadata that only drops entries is free, remain allowed. The agent then stops the task and asks the user, who either approves a higher limit, recorded in the task manifest with task approve-cloud-usage and published with the task for review, or chooses the cleanup to publish.

Placement policy

Git is the collaboration/control plane for clone-ready, directly reviewable repository state. S3 is the artifact/data plane for exact objects that change atomically or hydrate on demand. The agent records that semantic choice with storage set --to git|s3 --reason <reason> when intent is clear; the CLI does not infer intent from filename extensions.

Size is only the fallback for unclassified new files. Below 1 MiB, Git is the strong default. From 1 through 10 MiB, Git remains the fallback but the plan asks the agent to review the semantic choice. Above 10 MiB, S3 is the fallback. An explicit S3 boundary below 1 MiB is allowed but receives an efficiency warning. Existing published placement stays stable when size changes, and storage reset returns a path to published history or the fallback.

Directories may be placed in S3 as one logical boundary whose aggregate payload size is reported. Git and S3 placement both count toward the task's cloud-usage limit; placement never changes who approves growth. move preserves a path's placement, and remove explicitly deletes a file or boundary without confusing an unhydrated S3 output for an intentional deletion. storage hydrate materializes S3 content without publishing.

untrack keeps a materialized file or complete storage boundary locally and adds an exact ignore rule. After publication, its payload is absent from the task's Git tree and obsolete S3 versions are queued for permanent cleanup. refresh preserves the local copy after the change is merged. Use storage set <path> --to git|s3 --reason <reason> to track it again; storage reset does not undo a local-only choice. Git commit history remains available.

Agent instructions

workspace-mgr init installs a deliberately small AGENTS.md that tells the agent to run workspace-mgr instructions --repo .. The generated document begins with the same workspace model read by users, then renders the complete product-owned policy using the repository's Git and S3 facts and appends an optional repository-specific content module. Every initialized repository gets the same management strategy; policy evolves with the CLI rather than through per-repository switches. Re-running init after a CLI update deterministically replaces product-owned scaffold files with the current versions; their ownership comes from the initialized repository and reserved path, never from matching old file content.

The scaffold also contains a recovery path for a machine without the CLI. The agent asks the user before installing the latest stable release from crates.io with cargo install --locked workspace-mgr, runs workspace-mgr setup, and then retries the instructions command. It never falls back to raw repository or storage mutation commands.

Installation

Install the latest stable release from crates.io, then provision its private storage runtime:

cargo install --locked workspace-mgr
workspace-mgr setup
workspace-mgr --help

Building the crates.io package requires Rust 1.85 or newer. To install without a Rust toolchain, download a prebuilt native archive for Linux x86-64/arm64 or Apple Silicon macOS from the latest GitHub release, extract it, and run:

./install.sh

The native installer provisions the runtime and copies the CLI to ${HOME}/.local/bin by default. Set WORKSPACE_MGR_PREFIX to choose another executable prefix.

setup checks Git, creates a private Python environment, installs the pinned storage engine, and verifies both its executable and Python module. Users and agents never invoke that engine directly. The exact compatibility contract is in docs/platform-support.md.

Every CLI invocation consults a local update cache. At most once every six hours, it asks crates.io for newer non-yanked versions; a failed request is silently retried after one hour. When an applicable version is available, the CLI writes one agent-directed notice to stderr without changing command output or exit status. It never updates itself. The agent reports the versions and asks the user before updating, then runs workspace-mgr setup; managed repository scaffolding is reconciled with workspace-mgr init in an infrastructure task.

A repository can also declare the oldest compatible release as minimum_cli_version in .workspace-mgr.toml. workspace-mgr maintains that declaration itself: a publication raises it when it introduces task state that older releases cannot read, such as a task manifest that records a cloud-usage approval, and nothing lowers it once it is merged. From 0.4.0 on, a release older than the declaration refuses the repository with a message naming both versions, and the agent asks the user before updating. Releases up to 0.3.0 do not know the key and reject .workspace-mgr.toml with an unknown-field error for minimum_cli_version; update the CLI instead of removing or editing the key.

Configuration is documented in docs/configuration.md, transaction guarantees in docs/architecture.md, platform requirements in docs/platform-support.md, and releases in docs/releasing.md.

Development

cargo fmt --check
cargo deny check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
cargo package --allow-dirty

Integration tests use fresh temporary repositories and local storage. GitHub Actions also runs the full public lifecycle against a versioned local S3 service and a network Git server. Neither test path reads developer cloud credentials.

License

MIT