* origin/master:
fix(onboarding): preserve draft through company refetch (#12735)
feat(codex-local): give each Codex account its own home and path secret (#12709)
feat(claude-local): add Claude Fable 5.1 support (#12730)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Onboarding creates an organization in the browser.
> - The browser keeps onboarding drafts for the same origin.
> - A new data directory does not clear that browser data.
> - The organization create request refreshes the company list.
> - The old gate unmounted the live wizard during that refresh.
> - This pull request keeps the wizard mounted after its first draft
check.
> - The customer can continue to the agent step after the organization
is created.
## Linked Issues or Issue Description
No matching public issue was found. Related earlier fix: Refs #12667.
**What happened?**
A local canary install could create an organization through the API and
then return the browser to an empty organization-name screen.
**Expected behavior**
The wizard must continue to the agent step after it creates the
organization.
**Steps to reproduce**
1. Keep a Paperclip onboarding draft in the browser.
2. Run npx paperclipai@canary onboard with a new data directory.
3. Open /onboarding.
4. Enter an organization name and select Continue.
**Paperclip version or commit**
2026.902.0-canary.7. The fix is based on current master.
**Deployment mode**
Local trusted mode through the Paperclip CLI.
**Install method**
npx package install.
**Agent adapter(s) involved**
Not adapter-specific.
**Database mode**
Embedded PostgreSQL.
## What Changed
- Keep the onboarding wizard mounted after its first successful draft
ownership check.
- Keep a failed ownership check retryable, so a later verified fetch
restores the saved draft.
- Add component, source E2E, and published-canary coverage for the
retained-draft refetch case.
## Verification
- Confirmed that the new canary scenario fails against
2026.902.0-canary.7 before this fix.
- pnpm exec vitest run ui/src/components/OnboardingWizard.test.tsx
- PAPERCLIP_E2E_PORT=3245 pnpm exec playwright test --config
tests/e2e/playwright.config.ts tests/e2e/onboarding.spec.ts
--reporter=line
- pnpm --filter @paperclipai/ui typecheck
- pnpm check:token-gates
## Risks
Low risk. The initial ownership check still waits for a fresh company
list. A later successful retry can restore a retained draft. Later
background refetches preserve live wizard state.
## Model Used
OpenAI Codex, GPT-5. Reasoning, tool use, code editing, terminal
execution, and browser testing were used. The execution environment does
not expose a context-window size.
## 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 described the issue in-PR following the bug issue template
- [x] I have not referenced internal or instance-local Paperclip issues
or links
- [x] My branch name describes the change 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 is the control plane for companies that use AI agents for
work
> - Local adapters connect Paperclip agents to provider command line
tools
> - The Codex adapter stores login data in a shared company home
> - A shared home cannot keep credentials for more than one Codex
account
> - This pull request gives each account a safe home and a matching
company secret
> - The benefit is that one company can use multiple Codex accounts at
the same time
## Linked Issues or Issue Description
**Problem or motivation**
A company can hold only one Codex subscription credential because device
login uses one shared home. A second account cannot log in without
replacing or conflicting with the first credential.
**Proposed solution**
This change validates the vendor account identifier, stores each
credential in its own home, and creates a company secret that points to
that home. Repeat login calls return success when the matching secret
already exists.
**Roadmap alignment**
The change supports the roadmap goal for centrally managed secrets with
scoped access and audited resolution.
**Additional context**
The security review returned approve with no blocking finding. The
branch adds shared account-handle validation and tests for device login
and the Codex local adapter.
## What Changed
- Add strict allowlist validation for Codex account handles.
- Store each Codex account credential in a separate home under the Codex
cache root.
- Verify that the resolved account home stays inside the cache root.
- Create the `CODEX_HOME_<handle>` company secret for each account.
- Keep repeat and concurrent login calls safe and idempotent.
- Add shared helper and route, adapter, and validation tests.
## Verification
- `pnpm --filter @paperclipai/adapter-codex-local test` passes with 343
tests.
- `pnpm --filter @paperclipai/server test
src/__tests__/agent-device-login-routes.test.ts` passes with 25 tests.
- The adapter suite passes with 23 tests.
- The shared package and Codex adapter typechecks pass.
- Continuous integration must pass on every check before merge.
## Risks
The account handle becomes part of a directory path and secret name. The
strict allowlist and root containment check reduce path traversal risk.
Existing single-account homes remain unchanged unless a new device login
creates an account-specific home.
## Model Used
OpenAI GPT-5 (exact runtime model ID: gpt-5), with tool use and code
execution. The runtime context window is not exposed in this run.
## 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
- [ ] 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 is the open source app people use to manage AI agents for
work.
> - The Claude local adapter lets operators select a Claude model for an
agent.
> - Claude Fable 5.1 was absent from the adapter model lists.
> - The adapter runtime also used a Claude Code build that rejected
Fable 5.1.
> - This pull request adds the direct Anthropic ID and the AWS Bedrock
inference profile ID.
> - It also updates the Claude ACP runtime and keeps the Paperclip usage
and isolation patches.
> - The benefit is that operators can select and run Claude Fable 5.1
through the Claude adapter.
## Linked Issues or Issue Description
Refs #8810. That issue covers related model ID handling. This change
does not change provider-prefixed model IDs.
**Agent or provider**
Claude Code through the built-in `claude_local` adapter. The requested
model is Claude Fable 5.1.
**Why this adapter is useful**
Operators can use Fable 5.1 without entering an undocumented model ID.
The configured model also reaches both supported Claude execution lanes.
**How the agent is invoked**
The CLI lane sends `--model claude-fable-5-1`. The ACP lane sends
`ANTHROPIC_MODEL=claude-fable-5-1` to
`@agentclientprotocol/claude-agent-acp`.
**Are you willing to implement it?**
Yes. This pull request includes the implementation and tests.
**Additional context**
Claude Code 2.1.232 rejected Fable 5.1 and required version 2.1.251 or
newer. ACP package 0.73.0 includes Claude Code 2.1.257. The update keeps
Paperclip's usage metadata and isolated-context behavior.
## What Changed
- Added `claude-fable-5-1` to the direct Claude fallback list.
- Added `us.anthropic.claude-fable-5-1` to the AWS Bedrock list.
- Kept the existing default model at the first position in each list.
- Updated the Claude ACP dependency from 0.70 to 0.73.
- Carried the Paperclip usage and isolated-context changes into the 0.73
patch.
- Added a Claude Code 2.1.251 minimum-version preflight for Fable 5.1
when using the standard `claude` executable, surfaced in both adapter
Test and execution. Explicit custom wrappers retain their existing
compatibility contract.
- Kept local adapter Tests from executing caller-selected binaries: when
runtime `PATH` selects a different Claude executable than the trusted
probe, the Test warns and defers the authoritative version check to
execution instead of approving or rejecting the alternate installation.
- Added tests for model listing, discovery deduplication, Bedrock
filtering, model pass-through in both execution lanes, old-CLI rejection
before launch, custom-wrapper compatibility, and local runtime-PATH
mismatch handling.
## Verification
- `pnpm --filter @paperclipai/adapter-claude-local typecheck`
- `pnpm exec vitest run
packages/adapters/claude-local/src/server/execute.remote.test.ts
packages/adapters/claude-local/src/server/test.remote.test.ts
packages/adapters/claude-local/src/server/test.probe.test.ts
packages/adapters/claude-local/src/server/acp.test.ts
server/src/__tests__/adapter-models.test.ts` (72 tests passed)
- `node --test scripts/acpx-patch-packaging.test.mjs` (13 tests passed)
- `pnpm -r typecheck`
- `pnpm build`
- A local Paperclip agent run completed with `usageJson.model` set to
`claude-fable-5-1` through ACP 0.73.0 and its bundled Claude Code
2.1.257.
- `pnpm test:run` completed 5,638 passing tests and 24 skipped tests. It
also found 24 failures in unrelated workspace-runtime,
path-canonicalization, and runtime-exposure tests on macOS with Node 26.
These failures do not touch this diff. Clean pull request CI is the
final full-suite gate.
## Risks
- The ACP dependency update can change Claude runtime behavior outside
model selection. Focused ACP tests, the full typecheck, the production
build, and a real local Fable run reduce this risk.
- The 0.73 patch must stay aligned with the installed ACP version.
Dependency-resolution CI verifies the manifest and patch pair.
- Fable 5.1 adds a short `claude --version` preflight to standard
CLI-lane Tests and runs. The result is intentionally not cached so an
in-place Claude Code upgrade takes effect without restarting Paperclip.
Explicit custom wrappers are not version-probed because their output and
compatibility contract can differ from the standard executable.
- Local Tests preserve the existing deny-by-default probe boundary and
do not execute a binary selected by caller-controlled `PATH`. A
mismatched runtime binary produces an explicit warning without blocking
an otherwise valid setup; execution independently validates the actual
runtime-selected CLI before launch.
- The AWS Bedrock identifier differs from earlier IDs because Fable 5.1
has no `-v1` suffix. The model-list test locks this exact value.
- There is no schema change or migration.
> 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
Provider: OpenAI. Model: GPT-5 Codex. The host did not expose a more
specific model ID or context-window size. Capabilities used: agentic
reasoning, repository editing, shell execution, web research, and local
runtime verification.
## 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 is the control plane for agents that perform work.
> - Paperclip Runner connects durable provider sessions to individual
task runs through PRP.
> - Provider continuity and per-run authority are different lifetimes.
> - The existing implementation mixed those lifetimes and lost event
metadata between provider frames, runnerd, persistence, API
sanitization, and the task thread.
> - That caused failed continuation, missing progress and Plans,
duplicate replies, hidden failures, and unsafe recovery.
> - This repair gives every heartbeat fresh authority, preserves
qualified provider-session continuity, and restores one lossless
presentation path without changing direct adapters.
## Linked Issues or Issue Description
**What happened?**
A second native heartbeat could reuse tickets, leases, command receipts,
sequence state, and run identity from the first heartbeat. Provider
phase and item identity could be lost before the UI read them. Redaction
could corrupt protocol discriminators while still missing malformed
credential tails. The task thread could fold progress into the final
response, hide failures, or show more than one final answer. Native
Codex also exposed approval modes that do not yet have a durable
approval bridge.
**Expected behavior**
Each heartbeat uses a new PRP authority epoch. Codex and OpenCode
preserve exact qualified provider sessions; ACPX emits an explicit
continuity event when its qualified process-replacement policy is used.
Every accepted provider event is presented, classified as internal, or
surfaced as unsupported. The task page shows chronological progress,
reasoning summaries, activity, Plans, interactions, terminal failures,
and exactly one final reply. Direct adapters retain their existing path.
**Steps to reproduce**
1. Enable the unified experimental Paperclip Runner setting.
2. Create a local native Codex, OpenCode, ACPX Claude, or ACPX Codex
agent.
3. Run response, Plan, structured-question/resume, restart,
cancellation, and failure scenarios.
4. Reload the task while active, waiting, failed, and settled.
5. On the old implementation, observe stale run authority, missing
classifications, incomplete output, or duplicated/folded replies.
**Paperclip version or commit**
The repair is based directly on `master` at
`87d05e194b643810d16d20612115acd01d735d43`.
**Deployment mode**
Local development with the embedded database.
Related work: Refs #12616, #12646, #12666, #12685, and #12700.
## What Changed
- Rotates PRP control-plane, outbox, ticket, lease, command, receipt,
and sequence authority for each heartbeat while carrying forward only a
validated provider-session identity.
- Reads `control-plane-state.json`, validates both durable schemas and
lifecycle values, resumes coherent current runs, archives qualified
settled authority, and quarantines malformed or mismatched scoped state
without moving ambiguous live legacy state.
- Preserves Codex provider phase and stable item identities so
commentary remains progress and only `final_answer` becomes final.
- Adds raw OpenCode HTTP/SSE boundary coverage and canonical reasoning
lifecycle mapping.
- Makes ACPX normalization lossless for visible reasoning, tool
lifecycle metadata, stable bounded identities, Plan revisions,
structured requests, failures, and qualified process replacement. Only
the compatible terminal assistant message is promoted as final.
- Applies schema-aware redaction before generic JWT-shaped detection and
scans every diagnostic string leaf. Malformed raw/escaped quoted
credential tails are redacted in both server and durable Rust state.
- Restores snapshot-style chronological task presentation, expandable
tool activity, inline Plan cards, visible waiting/resume/cancel/failure
states, and exactly one final answer.
- Makes `never` the only qualified native Codex permission mode and
rejects unsupported persisted native modes with remediation. OpenCode
and ACPX policies remain intact.
- Keeps the unified experimental Runner setting as the only enablement
flag. Onboarding and direct Codex, Claude, and OpenCode stay on their
legacy execution/finalization paths.
- Adds cross-language goldens, authority/recovery/fault coverage, exact
response/count assertions, and native plus legacy acceptance scenarios.
## Verification
- Pull-request GitHub Actions run Rust formatting/tests, TypeScript
checks, server/UI tests, builds, protocol drift checks, browser E2E, and
security scans.
- A separate workflow-only validation ref is pinned directly on this PR
head and runs the 35-cell paid local matrix: three core scenarios plus
structured-question resume and restart/resume for native Codex, native
OpenCode, ACPX Claude, ACPX Codex, and direct Codex/Claude/OpenCode.
Run: https://github.com/paperclipai/paperclip/actions/runs/33682434315
- Acceptance requires exact single visible replies, monotonic sequences,
matching envelope discriminators, one semantic terminal, one run
terminal, no unresolved interaction, no duplicate mutation, no secret
leakage, provider continuity, and zero native rows for direct adapters.
- Per maintainer direction, tests are running in GitHub Actions rather
than on the slower local host. Only formatters and static diff checks
were run locally.
## Risks
- Recovery from old or partial filesystem state is sensitive. The repair
fails closed, preserves active or unverifiable authority, and
quarantines only state whose scoped ownership is safe to move.
- Provider event formats can change. Closed validators and boundary
goldens turn new or malformed events into visible diagnostics instead of
silent drops.
- Shared task presentation could affect direct adapters. Runtime-fact
gating plus the direct-adapter matrix protect the existing path.
- Managed and remote providers are not qualified here. Shared code
continues to compile and fail safely, but live qualification is
deferred.
> 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 Codex based on GPT-5. The exact deployed snapshot and
context-window size are not exposed to this task. It used agentic
reasoning, repository inspection, code editing, Git, parallel subagents,
and GitHub Actions.
## 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 and contains no internal
Paperclip ticket id
- [ ] I have run tests locally and they pass (intentionally deferred to
GitHub Actions)
- [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 risks above
- [ ] All Paperclip CI gates are green
- [ ] The paid local-provider matrix is green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge