## Thinking Path
> - Paperclip coordinates work for autonomous companies.
> - A run needs a workspace view before execution starts.
> - That view now needs to cover one anchor project and more referenced
projects.
> - Those extra workspaces must stay separate and must not change the
anchor path when the feature stays off.
> - This PR threads plural workspace data through run prep behind a
default-off kill switch.
> - It also keeps extra project workspaces isolated and makes the
realization contract round-trip the new shape.
> - The benefit is safer run prep for referenced projects without
changing the current default path.
## Linked Issues or Issue Description
This PR does not link a public GitHub issue.
It follows the internal run-prep task for plural referenced-project
workspaces.
Problem:
- Run prep resolves the anchor project today, but it does not yet carry
each referenced project into the run workspace view.
- That gap blocks runs that need a second repo or sibling project during
preparation.
Proposed solution:
- Thread a plural workspace result through run prep.
- Keep the anchor path unchanged when the kill switch is off.
- Resolve each referenced project into its own managed checkout
directory when the flag is on.
Alternatives considered:
- Keep one shared workspace and layer the extra repos into it. Rejected
because it would blur isolation and make failures harder to bound.
- Upload the extra workspaces immediately. Rejected because this PR only
prepares the data path.
Roadmap alignment:
- This change sits in the workspace and sandbox path.
- It matches the roadmap work on workspace strategy and cloud or sandbox
agents.
## What Changed
- Added `additionalWorkspaces[]` to the run workspace result.
- Split workspace resolution into an anchor path and an optional
referenced-project path behind `PAPERCLIP_MULTI_PROJECT_WORKSPACE_SYNC`.
- Kept per-project failure isolation so one bad clone does not stop the
run.
- Keyed managed workspace directories by `projectId` so sibling
workspaces stay separate.
- Added `additionalSources[]` to the workspace realization request and
kept read and write paths backward compatible.
- Added tests for the anchor-only path, the new workspace shape, and the
per-project directory rule.
## Verification
- `pnpm --filter @paperclipai/server run typecheck`
- `pnpm --filter @paperclipai/shared run typecheck`
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-project-env.test.ts` 21/21
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/workspace-runtime.test.ts` 98/98
## Risks
Low risk. The new path stays behind a default-off kill switch, so the
anchor flow does not change when the flag is off.
The main risk is a bad referenced project clone. That case now drops
only the affected project and keeps the run alive.
The shared type change also needs every consumer to use the new array
field where extra workspaces matter.
## Model Used
OpenAI Codex (GPT-5; exact internal model ID not exposed in this
environment; tool use enabled)
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies.
> - The plugin system needs host contracts and runtime support before
large plugins can integrate cleanly.
> - The source branch mixed the LLM Wiki package with supporting
host/runtime work, managed plugin skills, root-level storage spaces, and
a bookmarks reference plugin.
> - [PAP-9173](/PAP/issues/PAP-9173) asked for the current branch to be
split by file boundary: plugin package separately from everything else.
> - [PAP-9188](/PAP/issues/PAP-9188) clarified that LLM Wiki may have
plugin-local spaces, but Paperclip core should not reorganize top-level
local storage into spaces.
> - Follow-up review clarified that the bookmarks example should not
ship in this PR either.
> - This pull request contains the
non-`packages/plugins/plugin-llm-wiki/` host/runtime work, keeps runtime
state under the selected Paperclip instance root, and no longer includes
the bookmarks example.
## What Changed
- Added/updated plugin host contracts, SDK types, worker RPC plumbing,
managed plugin skill support, and related server tests.
- Removed the bookmarks example plugin package and its
bundled-example/workspace references.
- Removed the root-level local spaces CLI/migration surface and restored
instance-root runtime defaults for config, db, logs, storage, secrets,
workspaces, projects, and adapter homes.
- Replaced shared root `space-paths` helpers with `home-paths` helpers
for core runtime storage.
- Tightened stranded recovery unique-conflict detection so concurrent
recovery scans reuse the raced recovery issue when Postgres errors are
wrapped.
- Kept `packages/plugins/plugin-llm-wiki/` out of this PR diff;
plugin-local spaces remain in the stacked plugin-only PR.
## Verification
- `pnpm exec vitest run cli/src/__tests__/data-dir.test.ts
cli/src/__tests__/home-paths.test.ts cli/src/__tests__/onboard.test.ts
packages/shared/src/home-paths.test.ts
packages/db/src/runtime-config.test.ts
server/src/__tests__/agent-instructions-service.test.ts
server/src/__tests__/claude-local-execute.test.ts
server/src/__tests__/codex-local-execute.test.ts`
- `pnpm exec vitest run packages/db/src/runtime-config.test.ts`
- `pnpm exec vitest run
server/src/__tests__/plugin-routes-authz.test.ts`
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm exec vitest run
server/src/__tests__/heartbeat-process-recovery.test.ts -t "reuses the
raced stranded recovery issue"` skipped locally because embedded
Postgres did not initialize on this macOS temp host; the code path was
typechecked and is covered by Linux CI.
- Boundary check: no core references remain for `PAPERCLIP_SPACE_ID`,
`spaces migrate-default`, `@paperclipai/shared/space-paths`,
`registerSpacesCommands`, or the removed bookmarks example.
- Previous PR head `4f23e034` had green GitHub checks: `verify`, all
four serialized server shards, `e2e`, `Canary Dry Run`, `policy`, Snyk,
and `Greptile Review`. Current head `582f466d` is re-running checks
after the bookmarks deletion.
## Risks
- Plugin host changes touch shared runtime paths, so regressions would
most likely appear in adapter startup, plugin loading, or local dev path
defaults.
- Removing the bookmarks example also removes one demonstration of
plugin database namespaces plus local-folder persistence; remaining
plugin examples still cover bundled example discovery and plugin host
flows.
- The plugin package itself is intentionally deferred to the stacked
plugin-only PR, where LLM Wiki plugin-local spaces live.
- Existing installs that tested the transient root-level spaces CLI
should stop using it; this PR intentionally removes that unsupported
migration surface before merge.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI GPT-5 Codex via Codex CLI, tool use and local code execution
enabled; context window not exposed.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass, except where noted above
for host-specific embedded Postgres initialization
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
Stacked follow-up: PR #5592 contains only
`packages/plugins/plugin-llm-wiki/` and targets this branch.
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
Heartbeat service resolves cwd from task session, project primary
workspace, or agent home directory (~/.paperclip/instances/.../workspaces/).
Adapters receive workspace context and forward it as env vars and
session params. cwd is now optional in adapter config.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces a provider-agnostic storage subsystem for file attachments.
Includes local disk and S3 backends, asset/attachment DB schemas, issue
attachment CRUD routes with multer upload, CLI configure/doctor/env
integration, and enriched issue ancestors with project/goal resolution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>