Commit Graph
4030 Commits
Author SHA1 Message Date
DottaandPaperclip 2aaffe0308 fix(runner): retain resumed call type across callbacks
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 20:10:12 +00:00
DottaandPaperclip c07c1f95d3 fix(runner): resume pending Codex calls exactly once
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 20:08:09 +00:00
Dotta a70b0f70b6 Merge remote-tracking branch 'origin/master' into PAP-16679-paperclip-runner
* origin/master: (57 commits)
  fix(adapter-utils): extend the duplex fail-closed run disposition to the CLI lane (#11966)
  fix(recovery): stop automatic stranded-task takeovers (#11961)
  feat(sandbox): add the duplex bridge broker, gated transport selection, and fixed observability (#11769)
  Drop the mission step from the wizard arc (#11935)
  fix(runtime): guard empty Bash 3.2 array expansion (#11891)
  chore(lockfile): refresh pnpm-lock.yaml (#11915)
  feat(commitperclip): surface the Co-Authored-By trailers a squash merge needs (#11498)
  Rebuild the onboarding agent arc on the prototype's step design (#11905)
  fix(workspaces): read process cwd on macOS so port-owner adoption works (#11763)
  fix(workspaces): attach PR preparation to existing branches (#11703)
  fix(grok-local): stop defaulting --permission-mode to dontAsk (#11898)
  Fix remote-only workspace base refs and pre-adapter retry loops (#11892)
  feat(environments): refer to the managed default environment by name, not the sandbox driver key (#11838)
  test(server): cover buffered duplex chunk drain after a late listener bind (#11865)
  fix(server,ui,claude-local): verify auth on the adapter Test lane and enforce managed-sandbox tenant binding (#11810)
  chore(lockfile): refresh pnpm-lock.yaml (#11867)
  fix(kimi): align package with Node 24 policy (#11890)
  feat(ui): rename "Agent mode" to "Auto mode" and show full work-mode labels (#11866)
  fix(build): enforce Node 24 across Paperclip (#11792)
  fix(server): end the duplex route on the pre-bind bounds when frames arrive before the bind (#11860)
  ...

# Conflicts:
#	Dockerfile
#	packages/db/src/migrations/meta/0226_snapshot.json
#	packages/db/src/migrations/meta/_journal.json
#	pnpm-lock.yaml
#	server/package.json
#	server/src/routes/agents.ts
#	server/src/services/heartbeat.ts
#	server/src/services/issues.ts
#	server/src/services/recovery/service.ts
#	ui/package.json
#	ui/src/adapters/transcript.test.ts
#	ui/src/components/TaskChatThread.test.tsx
#	ui/src/components/TaskChatThread.tsx
#	ui/src/components/task-chat/TaskChatTurn.tsx
#	ui/src/index.css
#	ui/src/pages/Agents.tsx
2026-08-22 15:46:15 -05:00
Dotta 24f5d5c603 refactor(task-chat): compact search and file activity 2026-08-22 15:24:17 -05:00
Dotta 0f2b643c78 feat(runner): add provider tracing and live activity 2026-08-22 14:53:30 -05:00
Nicky LeachandPaperclip cc42a67e7e fix(adapter-utils): extend the duplex fail-closed run disposition to the CLI lane (#11966)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip runs agents through adapter execution lanes
> - Duplex adapters can lose their control channel before a process
completes
> - The ACP lane already fails closed, but the CLI lane can report false
success
> - This pull request applies the same completion rule to the CLI lane
and shares the loss code
> - The benefit is consistent failure reporting when a duplex channel
closes during a run

## Linked Issues or Issue Description

**What happened?**

A CLI-lane duplex run can lose its control channel before clean process
completion. The run can then report `succeeded` with exit code 0 and no
error code.

**Expected behavior**

The execution target must fail closed when the channel dies before clean
completion. It must return exit code 1, the typed `duplex_channel_lost`
error code, and a short stderr note.

**Steps to reproduce**

1. Start a duplex adapter run through the CLI execution lane.
2. Close the duplex control channel before the process completes
cleanly.
3. Inspect the run result and error code.

**Paperclip version or commit**

Commit `5e01523d4eb6df4a20a0bddd05374c9c42225203`.

**Deployment mode**

Built from source.

**Installation method**

Built from source with pnpm.

**Agent adapter(s) involved**

Claude Code, Codex, Cursor, Gemini, Kimi, OpenCode, and Pi local
adapters.

**Database mode**

Not database-related.

## What Changed

- Add an optional `errorCode` field to `RunProcessResult`.
- Add a one-read completion seam to the execution target process
options.
- Fail closed when a duplex channel dies before clean process
completion.
- Add `settleRunDisposition()` to atomically read and mark orderly
completion.
- Share the typed duplex loss error code across the ACP and CLI lanes.
- Mark non-success terminal results as orderly completion before
teardown.
- Wire the seam through the seven duplex adapters.
- Add regression tests for channel loss, clean completion, and non-clean
terminal results.

## Verification

- `npx vitest run
packages/adapter-utils/src/execution-target-sandbox.test.ts` — 118
passed.
- `npx vitest run packages/adapter-utils/src/acpx-engine/execute.test.ts
-t "sandbox duplex run-disposition seam"` — 4 passed.
- The author confirmed a clean type-check for
`@paperclipai/adapter-utils` and the seven duplex adapter packages.
- Pre-existing environment failures remain outside this change. They
include `EACCES mkdir '/srv/paperclip'` and remote file-size setup
failures.

## Risks

The change alters terminal status for CLI duplex runs that lose control
before clean completion. The typed error code and stderr note keep the
failure visible. The broker marks failed, cancelled, and timed-out
results as orderly completion to prevent false loss events during
teardown.

## Model Used

OpenAI Codex, GPT-5, tool use and code execution, with the standard
GPT-5 context window. The model assisted with the implementation and
test work.

## 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>
canary/v2026.822.0-canary.3
2026-08-22 11:12:51 -07:00
Dotta 4fdcf5a141 feat(task-chat): add queued message steering 2026-08-22 13:11:17 -05:00
DottaandPaperclip f572e08678 fix(recovery): stop automatic stranded-task takeovers (#11961)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The recovery service restores execution when a task loses its live
path.
> - The service retries the original agent for a limited number of
attempts.
> - The old fallback could select a manager or an executive and wake
that agent.
> - That fallback changed the effective recovery owner without a board
decision.
> - This pull request keeps the source owner and gives the exhausted
recovery decision to the board.
> - The benefit is a clear ownership rule with no automatic task
takeover.

## Linked Issues or Issue Description

Refs: #11807

Refs: #11817

**What existing behavior does this improve?**

This improves stranded-task recovery in the server and the recovery
action card in the board UI.

**Subsystem affected**

Cross-cutting: server recovery orchestration, recovery observability,
board UI, and execution documentation.

**Current behavior**

Paperclip retries the original agent for a limited number of attempts.
After the retry limit, it can select a manager, task creator, CTO, or
CEO as a recovery owner. It can then wake that substitute agent. The
source task keeps its assignee, but the automatic substitute wake
creates an implicit takeover path.

**Proposed behavior**

Paperclip keeps the limited retry path for the original agent. If
recovery is exhausted or unsafe, Paperclip creates one board-owned
source recovery action. It keeps both source assignee fields. It does
not wake a substitute agent. The board can repair, retry the original
owner, explicitly reassign, or resolve the task.

**Reason and benefit**

Source task ownership must remain stable until a person or an approved
policy changes it. The new rule removes implicit manager and executive
takeover. It also gives operators clear evidence through the
`board_escalation_no_takeover_v1` routing marker.

**Breaking changes**

Automatic recovery no longer wakes a manager or executive after the
original-agent retry limit. Existing active agent-owned recovery actions
remain visible and can resolve. Paperclip does not schedule a new
takeover wake for those legacy actions.

## What Changed

- Route exhausted and unsafe stranded recovery to a board-owned source
action.
- Preserve agent and user assignee fields during automatic escalation.
- Keep limited same-agent continuity repair and provider quota
monitoring.
- Stop new manager, creator, CTO, and CEO recovery wakes.
- Keep legacy agent-owned recovery actions readable and resolvable.
- Add the routing marker to new board escalation evidence and
observability.
- Update recovery notices, the board UI card, tests, and execution
documentation.

## Verification

- Run `pnpm -r typecheck`.
- Run `pnpm build`.
- Run `pnpm check:token-gates`.
- Run `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-process-recovery.test.ts`.
- Run `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-workspace-branch-containment.test.ts`.
- Run the focused recovery and UI Vitest files changed by this pull
request.
- Confirm that a paused or over-budget source owner creates one board
action, keeps the source assignee, and creates no substitute wake.

## Risks

- Operators must now make the final recovery decision after the
original-agent limit.
- Legacy agent-owned actions use their stored contract. This avoids a
rollout-time ownership rewrite.
- No database migration or API response shape changes are included.
- The tests cover concurrent escalation, paused and over-budget owners,
legacy actions, provider quota monitoring, and UI presentation.

> 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 with GPT-5. The hosted exact model revision and context
window are not exposed. Reasoning, tool use, and code execution were
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>
canary/v2026.822.0-canary.2
2026-08-22 11:41:24 -05:00
Nicky LeachandPaperclip 10d2781a29 feat(sandbox): add the duplex bridge broker, gated transport selection, and fixed observability (#11769)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Sandbox adapters provide controlled execution for untrusted provider
environments.
> - The sandbox channel needs one persistent duplex transport with
strict host control.
> - The transport must remain off unless the instance setting and
provider capability both allow it.
> - The host must detect loss, bound resource use, and expose only safe
telemetry.
> - This pull request adds the broker, gated selection, kill-switch
wiring, fixed observability, and real-process proof.
> - The benefit is safer sandbox execution with bounded failure behavior
and inspectable transport results.

## Linked Issues or Issue Description

No public issue exists for this change. The related pull requests are
#11738 and #11750.

**Problem or motivation**

The sandbox duplex channel needs a host-controlled broker, strict
transport gates, bounded provider input, and safe loss telemetry.
Without these controls, a provider can cause replay, resource growth,
unsafe endpoint selection, or data exposure through telemetry.

**Proposed solution**

Add a host broker with nested time limits, request limits, one-shot
loss, and per-id deduplication. Select duplex transport only when the
instance setting and provider capability both equal true. Assign the
endpoint and nonce on the host. Reject invalid readiness data and use
the file bridge on failure. Add fixed redacted telemetry and a
real-process end-to-end test harness.

**Alternatives considered**

Keep the file bridge as the only transport. This avoids new channel
behavior but does not provide persistent duplex operation for supported
sandbox providers.

**Roadmap alignment**

This change supports the Cloud / Sandbox agents section in ROADMAP.md.

## What Changed

- Add the duplex bridge broker with bounded forward, response, and
gateway wait budgets.
- Bound concurrent requests, lifetime requests, and request-id bytes
before retention or forwarding.
- Select duplex transport only when both required gates are true.
- Assign the loopback port and nonce on the host and enforce a
liveness-only READY frame.
- Fall back to the file bridge after invalid readiness, contamination,
bind failure, or timeout.
- Carry the kill switch through the server, acpx engine, and six local
adapters.
- Add fixed, redacted duplex telemetry with a provider allowlist.
- Add a real-process end-to-end harness for readiness, round trips,
loss, and teardown.
- Add regression coverage for limits, loss, UTF-8 splits, concurrency,
and telemetry dimensions.

## Verification

- Adapter-utils, server, and Daytona typechecks pass locally.
- Adapter-utils tests pass, including the codec, broker,
execution-target sandbox, and real-process harness.
- Server kill-switch tests pass.
- Live Daytona tests pass with the required provider key and skip
without that key.
- The root pnpm-lock.yaml file has no diff.
- The branch contains ten commits after origin/master.

## Risks

- Duplex transport remains disabled unless both gates equal true.
- A provider remains an untrusted boundary and needs least-privilege
credentials and quotas.
- The server telemetry recorder stays deferred; the default recorder
does nothing.
- A provider that pre-binds the host port causes a fail-closed fallback
to the file bridge.
- The change adds no database migration and changes no root lockfile.

## Model Used

OpenAI GPT-5, exact model family GPT-5, large context window, reasoning,
and tool use. The model assisted with Git handoff validation and PR
preparation. The implementation commits came from the engineering
worktree.

## 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/... or 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
- [x] I searched the GitHub PR list for similar PRs and confirmed this
is not a duplicate

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
canary/v2026.822.0-canary.1
2026-08-22 09:01:31 -07:00
DottaandPaperclip edde864925 feat(runner): stabilize native planning and review
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-22 10:57:02 -05:00
TonioandClaude Opus 5 3ff636bc48 Drop the mission step from the wizard arc (#11935)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - New customers arrive through an onboarding arc that spans Paperclip
Cloud and the tenant app
> - Cloud's naming screen stopped asking for the company mission, but
the tenant wizard still decided its first step by asking whether the
company had one
> - Every Cloud-created company therefore looked mission-less on
arrival, so every walk detoured through a "Define your mission" screen
the design had already removed
> - This pull request removes that step from the arc, and makes step 1
create the company itself
> - The benefit is a shorter arc that matches the design, and a
three-step progress strip that now counts the steps that exist

## Linked Issues or Issue Description

No public issue exists. The problem was found by walking staging end to
end.

**What happened:**
A new customer signs in, names their organization, and waits for it to
build. The tenant wizard then asks "Define your mission" before it asks
for the first agent. Cloud no longer collects a mission, so this screen
appears for every new customer.

**Expected behavior:**
The wizard asks for the first agent, the model, and a review. The
progress strip counts three steps.

**Actual behavior:**
The wizard asks for the mission first. The progress strip counts five
segments, because the run does not enter on the agent arc.

**Additional context:**
Three merged pull requests built the mission-based step choice this
change removes: #11352, #11416 and #11429. The mission is now collected
later, inside the tenant app, so onboarding does not ask for it at all.

## What Changed

- `onboardingStepForCompany` always returns the agent step. The
`companyHasMission` parameter is removed, because it cannot change the
answer.
- `resolveRouteOnboardingOptions` no longer accepts `companyHasMission`.
- The dashboard no longer waits for the goal lookup before it opens the
wizard. That wait only chose a step, and the step is now fixed.
- Step 1 creates the company in a new `handleCreateCompany`. Company
creation used to sit at the end of `handleConfirmMission`.
- No company goal is written during onboarding.
- The three-step strip now shows on the agent, model and review steps,
because every Cloud-first run enters on the arc.
- The full-length bar drops its second segment. No run can fill it.
- The grow path keeps its step 2 questionnaire. Only the create path
skips ahead.
- Back from the agent step goes to the screen the run came from.
- Four end-to-end specs no longer drive the wizard through the mission
step.

## Verification

Run the tenant test suite:

```
cd ui && npx vitest run
```

- 4356 tests pass. 471 files pass.
- `npx tsc --noEmit` reports no errors.
- Fault injection: forcing `skipsMissionStep` to `true` fails the grow
questionnaire test. Removing the Back rule fails the Back test. Both
tests fail on the exact defect they guard.
- The three-step strip is asserted by an existing test. It checks `Step
1 of 3` and `aria-label="Create your first agent"`.

Manual check on staging after the paired Cloud change:

1. Open a new incognito window.
2. Sign in with a new account.
3. Name the organization.
4. Confirm the wizard shows "Create your first agent" and "Step 1 of 3".

## Risks

- **Behavioral change.** Onboarding no longer writes a company goal. An
agent hired during onboarding starts without a seeded mission. This is
intended. The mission moves to the tenant app.
- **Dead code.** `ONBOARDING_MISSION_STEP` and the mission screen stay
in the codebase, but nothing in the app opens them. They wait for the
surface that collects the mission later.
- **Grow path.** The grow path is unchanged, but it shares step 2 with
the removed screen. New tests cover it.
- **Superseded work.** #11352, #11416 and #11429 tuned the mission-based
step choice. This change removes the branch they tuned.

## Model Used

Claude Opus 5 (`claude-opus-5`), extended thinking, with tool use and
code execution through Claude Code.

## 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
- [x] My branch name describes the change and contains no internal
Paperclip ticket id
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] 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: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 02:28:45 -07:00
Dotta 7e9d93f1d2 feat(ui): complete task protocol interactions 2026-08-21 21:15:01 -05:00
Dotta 10765bad75 fix: update qualified ACPx profile digest 2026-08-21 20:48:58 -05:00
Dotta b50eaea4bb feat: add ACPx and AgentCore runner support 2026-08-21 20:48:43 -05:00
scotttongandPaperclip dc5b070709 fix(runtime): guard empty Bash 3.2 array expansion (#11891)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents can run in isolated worktrees with a separate Paperclip
runtime.
> - Runtime provisioning uses a Bash script on macOS hosts.
> - macOS ships Bash 3.2, where an empty array expansion fails under
`set -u`.
> - The source-config argument array is empty when the base workspace
already has a config.
> - This pull request guards that expansion and tests the normal
base-config path on Bash 3.2.
> - The benefit is that managed worktree provisioning no longer fails
before database seeding.

## Linked Issues or Issue Description

No public GitHub issue exists for this problem. PR #11752 added the
conditional source-config argument that exposed the failure.

**What happened?**

`scripts/provision-worktree-runtime.sh` expands an empty
`source_config_args` array while `set -u` is active. Bash 3.2 reports
`source_config_args[@]: unbound variable` and stops provisioning when
the registered base workspace already has `.paperclip/config.json`.

**Expected behavior**

Runtime provisioning must call `worktree ensure-seeded` without a source
override when the base workspace config exists. It must work with the
Bash 3.2 version that macOS supplies.

**Steps to reproduce**

1. Use macOS system Bash 3.2.
2. Create a base workspace with `.paperclip/config.json`.
3. Run `scripts/provision-worktree-runtime.sh` with `set -u` active in
the script.
4. Observe the unbound-variable error before `worktree ensure-seeded`
runs.

**Paperclip version or commit**

Reproduced on `origin/master` before this change.

**Deployment mode**

Local managed worktree runtime on macOS.

## What Changed

- Guard all three optional source-config array expansions with Bash
3.2-compatible parameter expansion.
- Add a regression test that uses the base-config path and verifies that
no `--from-config` argument is sent.
- Document the Bash 3.2 compatibility requirement in the runtime script.

## Verification

- `/bin/bash -n scripts/provision-worktree-runtime.sh`
- `node --test --test-name-pattern='runtime provisioning invokes
ensure-seeded once|runtime provisioning omits the source
override|runtime provisioning guards every optional source-config
expansion' scripts/__tests__/provision-worktree-self-heal.test.mjs`
- `git diff --check`

## Risks

Low risk. The change only affects expansion of an optional two-element
CLI argument array. The regression tests cover both the empty and
non-empty paths.

> 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 with model ID `gpt-5`. The runtime did not expose the
context-window size. Reasoning, tool use, and code execution were
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>
2026-08-21 17:26:51 -07:00
github-actions[bot]andlockfile-bot 35b5105f07 chore(lockfile): refresh pnpm-lock.yaml (#11915)
Auto-generated lockfile refresh after dependencies changed on master.
This PR only updates pnpm-lock.yaml.

Co-authored-by: lockfile-bot <lockfile-bot@users.noreply.github.com>
2026-08-21 17:06:16 -07:00
TonioandClaude Opus 5 24913064ff feat(commitperclip): surface the Co-Authored-By trailers a squash merge needs (#11498)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work, and it takes contributions from outside the core team
> - Those contributions arrive as PRs, and this repository squash-merges
every one of them
> - A squash collapses the whole branch into a single commit authored by
whoever pressed the button
> - So when a maintainer rebases and lands a contributor's stale PR, the
contributor's name survives only if the squash message carries a
`Co-Authored-By` trailer
> - Nothing prompts for that trailer, and the PR page keeps showing the
original author either way, so losing it is invisible at the moment it
happens
> - This pull request has commitperclip detect the situation and print
the exact trailers to paste
> - The benefit is that keeping an outside contributor's name is a
default rather than something a maintainer has to remember

## Linked Issues or Issue Description

No public issue exists. The problem follows, and it is not hypothetical.

**What happened?**

#11370, #11371 and #11379 landed @stubbi's work yesterday. Each of those
PRs carries a comment from me telling them their authorship would be
preserved. All three squash commits went in without a `Co-Authored-By`
trailer, so `git log` credits none of them:

| commit | landed from | credited |
| --- | --- | --- |
| `66515582e` | #9900 | Claude only |
| `bc0b5a164` | #9501 | Claude only |
| `35a9b9873` | #8982 | Claude only |
| `6542ad1f4` | #11259 | ✅ Jannes Stubbemann + Claude |

The last one has the trailer because that message was written by hand
with the contributor in mind. The only difference between the two
outcomes was memory. Master history cannot be rewritten, so those three
are now credited by comment on the original PRs — which is a worse
record than a commit trailer, and the reason to make this automatic.

**Expected behavior**

When a branch carries commits by someone other than the PR author, the
merger is told what trailers the squash needs.

**Paperclip version or commit**

`master` at `92047cac4`.

## What Changed

- `.github/scripts/check-pr-coauthors.mjs` — new gate.
- `.github/scripts/run-quality-gates.mjs` — fetches the PR's commits and
runs it.
- `.github/scripts/tests/check-pr-coauthors.test.mjs` — 12 cases.
- `.github/workflows/pr.yml` — runs `.github/scripts/tests/`.

### Informational, not a failure

The squash message does not exist while the PR is open. This can neither
be verified there nor fixed there, so failing a PR on it would block
work on something its author cannot satisfy. The gate notices that the
situation applies and prints the lines to paste.

Run against #11370's actual commits it produces exactly what was
missing:

```
This branch carries commits by stubbi. Squash-merging drops that authorship
unless the squash message carries their trailers, and nothing else will notice
if it does not. Add to the squash body when merging:

      Co-Authored-By: Jannes Stubbemann <stubbi@users.noreply.github.com>
```

### Edge cases it handles

Bots skipped; the PR author's own commits skipped; logins compared
case-insensitively (`PR_AUTHOR` does not always arrive in the same case
as the commit author login); each contributor listed once however many
commits they wrote; and a commit GitHub could not match to an account
falls back to its raw git author — that identity being the one most
likely to be lost, not least likely.

Paging stops at the API's own 250-commit ceiling rather than spinning on
full pages of nothing new.

### The test directory was not running

`.github/scripts/tests/` held ten test files covering the existing
gates, and no workflow ran any of them. Adding an eleventh would have
meant adding a test that never executes, so `pr.yml` now runs the
directory. All **149** pass, including the 137 that were already there
and previously unverified in CI.

## Verification

- 149 tests pass via `node --test '.github/scripts/tests/*.test.mjs'` —
the exact command CI now runs.
- The gate was run against the real commit shape from #11370 and
produces the missing trailer verbatim.

This PR is its own negative control: the branch carries only my commits,
so the new gate should stay silent on it. If commitperclip prints a
co-author note below, the gate is wrong.

## Risks

Low. Informational output only — it cannot fail a PR, and `allPassed` is
unchanged.

It adds one API call per gate run (`/pulls/{n}/commits`), fetched in the
same `Promise.all` as the existing PR and files calls.

Enabling the previously-unrun test directory could in principle surface
a pre-existing failure; all 149 pass locally, so it does not.

Revert the commit to restore.

## Model Used

Claude Opus 5 (`claude-opus-5`), through Claude Code. Extended thinking
enabled. Tool use enabled: file read and edit, shell for test runs.

## 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
- [x] My branch name describes the change and contains no internal
ticket id
- [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: Claude Opus 5 <noreply@anthropic.com>
canary/v2026.822.0-canary.0 nightly/v2026.822.0-nightly.0
2026-08-21 16:44:26 -07:00
TonioandClaude Opus 5 3d366ba15f Rebuild the onboarding agent arc on the prototype's step design (#11905)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The onboarding wizard in `ui/` hires that first agent. It runs three
steps: create the agent, connect a model, and review
> - A standalone prototype holds the agreed design for these steps.
#10786 ported that prototype, but #11067 reverted it in full because the
port deleted `OnboardingWizard.tsx` while four pull requests were
editing that file
> - Those four pull requests have since merged. The revert said the port
can "re-land incrementally", and this is that re-land
> - This pull request takes the presentational layer from the prototype
only. It keeps master's wizard as the source of behaviour, so the eight
onboarding fixes merged since the revert stay in place
> - The benefit is that the three agent steps match the agreed design,
and no merged fix is lost to get there

## Linked Issues or Issue Description

Refs #10786 — the first attempt to land this design.
Refs #11067 — the revert that asked for it to re-land in smaller steps.

No public issue exists for the re-land. The problem is described below.

**Subsystem affected**

The `ui` package. The change touches the onboarding wizard, the agent
capsule,
and one Storybook story. It adds four small presentational components
under
`ui/src/components/onboarding/`.

**Current behavior**

The wizard's agent steps do not match the prototype. Each step shows a
small
heading beside an icon, above a form. The agent capsule sits below that
heading and does not animate. The agent gets a name but no role, so
every
first agent is created as `ceo`.

The wizard also shows a five-segment progress bar on these steps. A
walker who
enters on the agent step cannot reach the first two segments, so two of
the
five can never be filled.

**Proposed behavior**

The three steps use the prototype's card, its centred display heading,
and its
footer. One capsule sits above the heading and stays mounted across all
three
steps, so it reads as one object being built rather than three screens
that
each show their own.

A three-segment strip counts these steps for a walker who enters on
them. The
full-length bar stays for a walker who starts at step one, so that count
never
restarts partway.

The agent step gains a role. The options come from the agent role enum,
not
from the prototype's mock list.

**Reason and benefit**

The design is agreed and already built once. Re-landing it
presentation-first
keeps the behaviour that master gained after the revert.

Sourcing roles from the enum matters. The prototype offers "Coder",
which is
not a valid role — the enum uses `engineer` — so a walker who picked it
would
fail validation at hire time.

**Breaking changes**

None. The wizard keeps its routes, its draft format, and its hire call.
The
draft gains one optional field, `agentRole`. A draft saved before this
change
loads without it and falls back to the default.

## What Changed

- Add `ui/src/components/onboarding/`: `Stepper`, `OnboardingCard`,
`OnboardingHeading`, `FooterNav`, `AgentPreview`, and shared motion
constants
- Rebuild wizard steps 3–5 on those parts: one card, the capsule above a
  centred heading, and one footer
- Hold one `AgentCapsule` across the three steps. It springs in once,
then
  morphs from dashed slot to traced outline to filled
- Add `strokeDraw` to `AgentCapsule`. It traces the outline instead of
  cross-fading it. The dashed layer holds until the trace ends
- Add a role select to the agent step. Choosing a role fills the name,
unless
  the walker typed one
- Show one progress indicator per run, not two
- Label strip segments by destination, not by number
- Add `motion` to the `ui` package
- Add a Storybook story for the strip and the capsule states

## Verification

Run the tests:

```
pnpm --filter @paperclipai/ui exec vitest run
pnpm --filter @paperclipai/ui exec tsc -p tsconfig.json --noEmit
```

4235 tests pass. The typecheck is clean.

To see the steps, start the app and open `/<PREFIX>/onboarding` for a
company
that has a company-level goal. The wizard opens on the agent step. Step
three
requires a hire.

Three absence assertions were checked by fault injection. Each one fails
when
the old behaviour returns:

- put the step counter back, and the "shows no step counter" test fails
- default `strokeDraw` to true, and the cross-fade test fails
- restore the timer gate on the strip, and the indicator test fails

## Risks

Low to medium.

`motion` is one new dependency in `ui`. #11067 gave dependency weight as
one
of three reasons to revert #10786, so this branch carries the smallest
set
that works. `motion` drives the step transitions and the capsule
choreography,
and three files import it.

An earlier revision of this branch also added `three` and
`@types/three`. Both
are removed. They existed for the 3D backdrop, which belongs to the auth
and
welcome screens rather than to these three steps, so nothing on this
branch
imported them.

The role select changes what the wizard sends. Before this change every
first
agent was hired as `ceo`. Now the walker chooses. The values come from
the
enum, so the server accepts all of them.

Steps 1 and 2 keep the older design. They do not run on the Cloud-first
path,
where the company already exists.

## Model Used

Claude Opus 5 (`claude-opus-5`), with extended thinking, tool use, and
code
execution. Used for the code, the tests, and this description.

## 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: Claude Opus 5 <noreply@anthropic.com>
canary/v2026.821.0-canary.12
2026-08-21 16:41:53 -07:00
Dotta 39c4fbe421 feat: add provider-neutral runner events 2026-08-21 18:36:12 -05:00
14027df09e fix(workspaces): read process cwd on macOS so port-owner adoption works (#11763)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - A workspace can run a shared local service, such as a dev server, on
an automatic port
> - Paperclip adopts a live service again after it loses the runtime
registry state
> - Paperclip must first prove that the port owner runs inside the
workspace
> - Linux reads the process working directory from `/proc/<pid>/cwd`
> - macOS has no `/proc`, so the check returned `null` and adoption
always failed
> - This pull request reads the process working directory with `lsof` on
macOS
> - The benefit is that macOS keeps a healthy live service after startup
reconciliation, instead of recording it as stopped

## Linked Issues or Issue Description

Closes #9911. That pull request reports the same defect and was opened
first, on 2026-07-20. Its checks have been red since that day, because
its inline issue description does not use the label format the gate
parses. It has had no author activity since. This pull request keeps
that author's test-fixture commit, with the author unchanged, and adds
NUL-delimited parsing, adoption-boundary tests, and fail-closed Darwin
registry handling. Maintainers may prefer to land #9911 instead. I will
close this one again if they do.

This pull request replaces #11600, which I closed earlier as a
duplicate. It carries the same work, rebased onto current `master`, with
the review feedback from that pull request applied.

No public issue exists. The problem follows.

**What happened?**

On macOS, `readLocalServiceProcessCwd` returned `null`. Startup
reconciliation found a live port owner, but it could not verify the
working directory. It rejected the candidate and recorded the live
service as stopped.

**Expected behavior**

Paperclip adopts a healthy port owner when the working directory is
inside the requested workspace. Paperclip rejects the process when the
working directory is outside the workspace, or when it cannot be read.

**Steps to reproduce**

1. Build Paperclip from source on macOS.
2. Start a shared workspace runtime service on an automatic port.
3. Remove the runtime registry state while the service stays alive.
4. Run startup reconciliation.
5. Read the result. Unpatched `master` reports `adopted: 0` and
`stopped: 1`.

**Paperclip version or commit**

This branch is based on `master` at
`7c8064da1b35527865c1d523c9f0016e304ae46d`.

**Deployment mode**

Local development from source.

**Installation method**

Built from source with pnpm.

**Operating system**

macOS 26.4, Darwin 25.4.0, arm64.

**Node.js version**

Node.js 22.22.2 on macOS. Node.js 24.19.0 on Linux. pnpm 9.15.4.

## Darwin Registry Adoption Now Fails Closed

This pull request changes one existing Darwin registry-adoption behavior
in addition to enabling port-owner adoption.

Before this change, `readLocalServiceProcessCwd` always returned `null`
on Darwin. `isLocalServiceRegistryCwdCompatible` treated a null cwd as
compatible on every non-Linux platform, so a service with an existing
registry record could still be adopted when its port owner, process
group, and command matched, even though Paperclip had not verified the
process's real working directory.

Darwin can now inspect the process cwd through `lsof`. If that
inspection returns `null` — including a missing `lsof`, a command
failure, or missing cwd output — registry-backed adoption now fails
closed and the stale registry record is removed.

This is a deliberate behavior change. It prevents a failed Darwin cwd
probe from silently falling back to trusting stored registry metadata.
The no-registry port-owner path already rejected a null cwd before this
pull request, so its failure behavior has not changed.

## What Changed

- Add a Darwin branch to `readLocalServiceProcessCwd`.
- Run `lsof -a -d cwd -p <pid> -F0n` to read the process working
directory.
- Parse the NUL-delimited field output.
- Do not trim the path. Do not split it on newlines. A directory name
can contain a trailing space or a newline, and a changed path would name
a different directory.
- Keep the Linux `/proc/<pid>/cwd` path unchanged.
- Return `null` for an invalid pid, a missing `lsof`, a command error,
or missing output.
- Reject a Darwin registry record when the working directory cannot be
read. Darwin can now read it, so a failed read means the check failed.
It no longer means the platform has no way to check.
- Keep the registry fallback only on platforms that cannot read a
process working directory.
- Run the existing foreign-workspace rejection test on macOS.
- Add a test: Paperclip adopts a port owner inside the workspace when no
registry record exists.
- Add a test: Paperclip rejects a listener in a sibling directory that
differs only by a trailing space.
- Add helper tests for newline and whitespace parsing, an invalid pid,
and a missing `lsof` binary.
- Resolve the branch-containment temporary repository root before the
path comparison. This test-only commit comes from #9911 and keeps its
author.

## Verification

Head of this branch: `2be1b74746d8a0db4b680062f0c57995a6ff3912`.

**Linux, on this head**

```sh
pnpm --filter @paperclipai/server exec vitest run \
  src/__tests__/workspace-runtime.test.ts \
  src/__tests__/heartbeat-workspace-branch-containment.test.ts
```

Result: 138/138 pass. `workspace-runtime.test.ts` is 132/132.
`heartbeat-workspace-branch-containment.test.ts` is 6/6.

**macOS, on this head**

macOS 26.4, Darwin 25.4.0, arm64, Node.js 22.22.2, pnpm 9.15.4.

- Controlled baseline: `workspace runtime startup reconciliation >
adopts a live auto-port shared service after runtime state is reset`
fails on the rebase base `7c8064da1b35527865c1d523c9f0016e304ae46d` and
reports `adopted: 0`, `stopped: 1`. The same test passes on this head.
That test uses the normal managed start path, which starts the service
detached.
- Focused working-directory, registry, adoption, and boundary tests: 8/8
pass.
- `heartbeat-workspace-branch-containment.test.ts`: 6/6 pass. Two
assertions failed before the fixture change, because `/var/...` and
`/private/var/...` name the same macOS directory.
- Server typecheck: pass.
- Full `workspace-runtime.test.ts`: 131/132 pass.

The one failure is `realizeExecutionWorkspace > records teardown and
cleanup operations when a recorder is provided`:

```text
expected: /var/folders/...
received: /private/var/folders/...
```

I ran that same test alone on the rebase base `7c8064da`, with no patch
applied, and got the identical failure. It is a pre-existing macOS
fixture that builds a path from `os.tmpdir()` and compares it against a
realpath. It does not run the changed adoption path. This description
does not claim the whole file is green on macOS.

**macOS listener evidence**

In the `adopts a port owner running inside the workspace when the
registry record is gone` scenario, the auto-port listener bound port
`54360`:

```text
COMMAND  PID   USER          FD   TYPE  DEVICE              SIZE/OFF NODE NAME
node    6808   <local-user>  12u  IPv4  0xee4e36b2c8c094cf  0t0      TCP 127.0.0.1:54360 (LISTEN)
```

To hold the listener open long enough to capture this, that one
diagnostic run added a temporary pause, which exceeded the Vitest
timeout. The pause was reverted, the unmodified test was run again on
this head, and it passed 1/1. The process and the port were then
released.

Note for maintainers: an existing test already covered this defect. That
test never runs on macOS, because CI runs on Linux. A macOS job would
have caught it in July.

## Risks

Low risk.

- Linux keeps the existing procfs implementation.
- Other platforms keep the existing registry fallback.
- macOS makes one extra `lsof` call, and only when it must read a
process working directory.
- A probe failure returns `null`.
- Darwin port-owner adoption and Darwin registry adoption both fail
closed.
- The parser keeps significant whitespace and embedded newlines.
- There is no database migration and no API change.

## Model Used

Claude Opus 5 (`claude-opus-5`), with extended thinking, tool use, and
code execution. It wrote the original implementation and the adoption
tests, reviewed the branch, ran the Linux test suite, rebased onto
current `master`, and prepared this text. OpenAI GPT-5.6-sol, through
Hermes Agent, added the failure-mode coverage and ran the macOS checks.
A human reviewed the change and controls publication.

## 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 (see Verification for the
one disclosed macOS baseline failure)
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes (this
change affects an internal helper and tests only)
- [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: tim <tf00185077@i-mps.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: scbailey-build <scott@bequall.com>
canary/v2026.821.0-canary.11
2026-08-21 16:03:43 -07:00
417336f8be fix(workspaces): attach PR preparation to existing branches (#11703)
<!-- Write all pull request text in Simplified Technical English
(ASD-STE100): short sentences, one instruction per sentence, simple
approved vocabulary, and the active voice. -->

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Execution workspaces isolate an agent task from the primary
checkout.
> - Pull request preparation can need a branch that already contains
completed work.
> - The workspace policy could not require an exact existing branch.
> - Workspace cleanup also treated worktree creation as branch
ownership.
> - This pull request adds an exact existing-branch policy and separate
branch ownership metadata.
> - The benefit is safe pull request preparation that preserves every
existing commit and operator-owned branch.

## Linked Issues or Issue Description

**What happened?**

A pull request preparation run could not pin its execution workspace to
an exact existing branch. Workspace reuse and cleanup could also confuse
worktree creation with branch ownership.

**Expected behavior**

The run must attach only to the requested branch in an isolated Git
worktree. It must fail if the branch is missing, busy, or inconsistent.
Cleanup must not delete a branch that Paperclip does not own.

**Steps to reproduce**

1. Create a branch that contains completed work.
2. Configure a pull request preparation task to use that branch.
3. Start the task and observe that the prior policy cannot require the
exact branch.

**Paperclip version or commit**

This behavior reproduces on the base revision before this pull request.

**Deployment mode**

Local development with isolated Git worktrees.

## What Changed

- Add `existingBranch` to the execution workspace policy and shared
validation contracts.
- Require `existingBranch` to use an isolated Git worktree and reject
conflicting branch templates.
- Attach to the exact branch without creating, renaming, resetting, or
deleting it.
- Track branch ownership separately from worktree creation and use that
ownership during cleanup.
- Return HTTP 422 for invalid existing-branch settings on every
issue-producing route.
- Add a bounded repair script for existing pull request preparation
tasks.
- Add focused policy, route, heartbeat, runtime, and ready-comment
tests.
- Document the exact-branch behavior and safety rules.

## Verification

- `pnpm exec vitest run
server/src/__tests__/execution-workspace-policy.test.ts
server/src/__tests__/heartbeat-workspace-session.test.ts
server/src/__tests__/issue-existing-branch-validation-status.test.ts
server/src/__tests__/workspace-runtime.test.ts
server/src/services/workspace-runtime-exposure.test.ts
server/src/services/workspace-runtime-ready-comment.test.ts` passed 335
tests.
- `pnpm -r typecheck` passed for all workspace projects.
- `pnpm test:run` passed 4,431 tests. Two unrelated embedded-Postgres
setup hooks timed out under aggregate load. Their isolated rerun passed
74 tests.
- `pnpm build` passed for all workspace projects.
- The two review regressions passed with 139 unrelated tests skipped.
- All latest-head CI gates passed after one unrelated timing-sensitive
test passed on rerun.
- Greptile scored the latest head 5/5 with no unresolved review threads.

## Risks

- Invalid workspace settings now return HTTP 422 instead of a generic
validation response.
- The exact branch must already exist and must not be checked out by
another worktree.
- The new policy fails closed when it cannot prove branch identity or
ownership.
- This change has no database 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

OpenAI Codex from the GPT-5 family assisted with this change. The
runtime did not expose its exact deployment ID or context window. The
agent used high-reasoning mode, repository tools, shell execution, and
code execution.

## 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>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
canary/v2026.821.0-canary.10
2026-08-21 17:23:18 -05:00
Devin FoleyandPaperclip fbd20b28d3 fix(grok-local): stop defaulting --permission-mode to dontAsk (#11898)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The `grok_local` adapter runs the native Grok Build CLI in headless
mode for unattended agent heartbeats
> - Grok CLI 1.0 started to enforce the `dontAsk` permission mode as
deny-by-default, and it takes precedence over `--always-approve`
> - The adapter passes both flags on every run, so each run dies on its
first tool call and is still recorded as a success
> - This pull request removes the `dontAsk` default so unattended runs
rely on `--always-approve` alone
> - The benefit is that `grok_local` agents can execute tools again on
current Grok CLI releases

## Linked Issues or Issue Description

No public issue exists. Description per the bug template:

**What happened?**

Every `grok_local` run on Grok CLI 1.0.x stops on its first tool call.
The stream shows the tool call move from `pending` to `failed` with
"User cancelled the execution for tool `run_terminal_command`", and the
session ends with `stopReason: "cancelled"` after one turn. The CLI
exits 0, so Paperclip records the run as succeeded with no work done,
and the issue lands in missing-disposition recovery.

**Expected behavior**

Unattended runs must auto-approve tool executions. The adapter already
passes `--always-approve` for this.

**Steps to reproduce**

In a clean Linux environment with Grok CLI 1.0.3 and `XAI_API_KEY` set,
run the adapter's exact invocation shape:

`grok --output-format streaming-json --permission-mode dontAsk
--always-approve --disable-web-search --single "Run the shell command:
echo ok"`

The tool call is denied. Drop `--permission-mode dontAsk` (or use
`--permission-mode bypassPermissions`) and the same command executes the
tool. On Grok 0.2.x the original combination worked because the CLI
accepted `dontAsk` without enforcing it; the 0.2.39 embedded docs state
the flag takes effect only for `bypassPermissions` / always-approve.

**Paperclip version or commit**

master (917d2350f)

## What Changed

- `packages/adapters/grok-local/src/server/execute.ts`: `permissionMode`
no longer defaults to `dontAsk`. The adapter passes no
`--permission-mode` flag unless one is explicitly configured.
`--always-approve` (default on) remains the unattended policy.
- `packages/adapters/grok-local/src/index.ts`: config doc updated to
explain the new default and the Grok 1.0 semantics.
- `packages/adapters/grok-local/src/server/execute.test.ts`:
default-args assertion now requires the absence of `--permission-mode`;
new test covers explicit `permissionMode` pass-through.

## Verification

- `npx vitest run packages/adapters/grok-local` — 7 files, 29 tests, all
pass.
- `pnpm --filter @paperclipai/adapter-grok-local typecheck` — clean.
- Live matrix against Grok CLI 1.0.3 in a clean sandbox: `dontAsk
--always-approve` denies the first tool call; `--always-approve` alone
executes it; `bypassPermissions --always-approve` executes it; `dontAsk`
alone denies it.

## Risks

- Low risk. Operators who explicitly set `permissionMode` keep their
value verbatim. Only the implicit default changes, and the old default
is what breaks every run on current Grok CLI releases.
- On Grok 0.2.x the flag was unenforced, so omitting it does not change
behavior there.

## Model Used

Claude Fable 5 (`claude-fable-5`), extended thinking, tool use, via
Claude Code CLI.

## 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
- [ ] 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>
canary/v2026.821.0-canary.9
2026-08-21 14:50:43 -07:00
Dotta 47b3429a7f fix(runner): defer activity caret until settled 2026-08-21 16:31:44 -05:00
Dotta cc19675b28 fix(runner): space live identity below header 2026-08-21 16:19:08 -05:00
Dotta c925b3fbb9 fix(runner): place agent identity above activity 2026-08-21 16:17:12 -05:00
Dotta d2c851523b fix(runner): keep live turn layout stable 2026-08-21 16:10:48 -05:00
Dotta c31a345a3d fix(runner): stabilize live response handoff 2026-08-21 15:56:15 -05:00
Dotta fab305db71 fix(runner): simplify expanded activity history 2026-08-21 15:26:40 -05:00
Dotta 4c3e30cdad feat(runner): add OpenCode and durable runner UX 2026-08-21 15:18:00 -05:00
Nicky LeachandPaperclip 69590890d4 Fix remote-only workspace base refs and pre-adapter retry loops (#11892)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Execution workspaces give each run an isolated directory and a
selected base ref
> - A remote-only base ref can fail before `git worktree add` when the
ref is not local
> - A setup failure before adapter dispatch must block the run without
an agent-only retry
> - This pull request resolves both remote-tracking ref forms and bounds
recovery for the same unresolved ref
> - The benefit is correct workspace setup and no repeated pre-adapter
recovery loop

## Linked Issues or Issue Description

This PR has no existing public issue. It addresses a workspace setup
bug.

**What happened?**

A remote-only base ref could fail before `git worktree add`. A setup
failure before adapter dispatch could also queue an agent-only
missing-comment retry.

**Expected behavior**

Paperclip must resolve `fix/foo` and `origin/fix/foo` before it creates
a worktree. An unresolved ref must create a human-owned configuration
blocker. Paperclip must not queue an agent-only retry when the adapter
never starts.

**Steps to reproduce**

1. Configure an execution workspace with a base ref that exists only on
the remote.
2. Start a run that creates a fresh worktree.
3. Repeat the run with the same unresolved ref.
4. Observe one configuration blocker and no repeated agent-only recovery
action.

**Paperclip version or commit**

`7664e323189bc219d8cbe00433b2e82b682b0504`

**Deployment mode**

Built from source with `pnpm dev`.

**Agent adapter(s) involved**

Not adapter-specific. The failure occurs before adapter dispatch.

**Database mode**

Not database-related.

**Access context**

Both board and agent execution paths can use execution workspaces.

Related public pull request: `Refs #11123`.

## What Changed

- Resolve remote-only base refs with the authenticated fetch helper
before `git worktree add`.
- Support both unqualified refs and remote-tracking refs.
- Raise a `configuration_incomplete` blocker when the requested ref
remains unresolved.
- Suppress missing-comment retries when setup fails before adapter
dispatch.
- Add the requested ref to the recovery fingerprint to bound identical
recovery actions.
- Add focused tests and update the execution semantics document.

## Verification

- `tsc --noEmit` passed for the changed server code.
- Focused Vitest suites passed, including four base-ref tests,
fingerprint deduplication, and pre-adapter retry suppression.
- GitHub Actions must run the full pull request gate.

## Risks

Low risk. The change affects workspace setup before adapter dispatch.
Existing worktree reuse remains unchanged. An unresolved ref now creates
a clear configuration blocker instead of starting an adapter run.

## Model Used

OpenAI GPT-5; exact model ID `gpt-5`; agentic tool use and repository
review.

## 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>
canary/v2026.821.0-canary.8
2026-08-21 13:09:44 -07:00
Devin Foley adfbe2d4b9 feat(environments): refer to the managed default environment by name, not the sandbox driver key (#11838)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Managed deployments provision a platform-managed default environment
for agent runs; the UI shows this environment in selectors, the agent
form, run details, and the environments page
> - Those surfaces append the raw driver key to the environment name, so
users see labels like "Paperclip Computer (sandbox)", "Paperclip
Computer · sandbox", and fallback copy such as "Managed sandbox" and
"The sandbox has no ready authentication"
> - "sandbox" is infrastructure vocabulary, not the product name of the
environment; showing it next to the managed environment's name is
confusing and off-brand
> - This pull request renders platform-managed environments by name
alone and rewords the sandbox-phrased copy, while user-created
environments keep the driver suffix so mixed lists stay distinguishable
> - The benefit is that the default environment reads as one clear
product name everywhere, and self-hosted users lose nothing: their own
environments still show the driver

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Display of the platform-managed default environment across the UI.

**Subsystem affected**

UI (environment selectors, agent config form, environments page, agents
page, run details) and the claude-local/codex-local adapter auth checks.

**Current behavior**

The agent form labels the inherited default environment as "Name
(sandbox)". Environment selectors and the environments list render "Name
· sandbox". The agents page describes the environment as "<provider>
sandbox provider". The agent form's fallback label is "Managed sandbox".
Adapter auth checks say "The sandbox has no ready authentication for
this adapter."

**Proposed behavior**

Platform-managed environment rows (`metadata.managedByPaperclip`) render
their name alone. The fallback label is "Paperclip Computer". The agents
page describes managed environments as "Managed by Paperclip". Run
details omit the driver suffix for sandbox-driver environments (the
adjacent Provider entry already identifies the mechanism). Adapter auth
checks say "This environment has no ready authentication for this
adapter."

**Reason and benefit**

The managed environment carries a product name. Appending the raw driver
key ("sandbox") to it is noise and contradicts the product naming.
User-created environments keep the driver suffix, so mixed lists stay
distinguishable.

**Breaking changes**

None. Message text of the auth check is not read programmatically; the
UI keys off `ADAPTER_AUTH_MISSING_CHECK_CODE`. Rows without the managed
marker render exactly as before.

## What Changed

- New `environmentDisplayLabel` helper in
`ui/src/lib/managed-sandbox-environment.ts`: managed rows → name alone;
other rows → "Name · driver".
- `AgentConfigForm`: inherited-default label uses the helper; fallback
copy "Managed sandbox" → "Paperclip Computer"; environment options use
the helper.
- `ProjectProperties`, `CompanyEnvironments`: environment selector
options use the helper; the environments-list row hides the driver
suffix on managed rows; the managed detail page's fallback description
no longer says "sandbox".
- `Agents` page: managed environments are described as "Managed by
Paperclip" instead of "<provider> sandbox provider".
- `CommentThread` run details: the driver suffix is omitted for
sandbox-driver environments.
- claude-local and codex-local adapters: auth-missing check message/hint
reworded from "sandbox" to "environment" (ACP and environment-test
paths); claude-local probe/effort/login hints reworded the same way.
- Run status lines: "Syncing workspace to sandbox", "Exporting git
changes from sandbox", "Starting adapter in sandbox", and friends now
say "environment"; "Finalizing sandbox workspace" → "Finalizing
workspace". Templated transfer-progress lines map the `sandbox`
transport key to "environment" for display (`runtime-progress.ts`).
- Agent form sign-in panel: "Sign in to the sandbox" → "Sign in to the
environment"; "Authenticated. The sandbox has credentials now." → "…The
environment has credentials now."
- Feature catalog + instance settings card: "Managed Sandbox Only" →
"Managed Environment Only" (setting key unchanged; the card keeps its
alphabetical slot).
- Server agents routes: execution-target failure and test-identity copy
no longer say "sandbox"; workspace-mode label "Cloud sandbox" → "Cloud
environment".
- Tests: new `environmentDisplayLabel` unit cases; new `AgentConfigForm`
render case asserting the managed default renders without "(sandbox)" or
"· sandbox"; status-line assertions updated across adapter-utils, server
heartbeat/live-run, and UI chat suites.

## Verification

- `pnpm --filter @paperclipai/ui typecheck` — clean.
- `pnpm --filter @paperclipai/adapter-claude-local typecheck` and
`--filter @paperclipai/adapter-codex-local typecheck` — clean.
- `vitest run` for `managed-sandbox-environment.test.ts`,
`AgentConfigForm.render.test.tsx`, `CompanyEnvironments.test.tsx`,
`Agents.test.tsx`, `CommentThread.test.tsx`, `NewAgent.test.tsx` — all
green (118 tests across the two runs).

## Risks

Low risk. Cosmetic label changes only; no data or API changes. Rows
without `metadata.managedByPaperclip` render exactly as before, so
self-hosted deployments with their own environments see no change. The
only self-hosted-visible wording changes are the adapter auth-check
message and the driver suffix omission on sandbox-driver rows in run
details.

## Model Used

- Claude (Anthropic) — claude-fable-5 (Claude Fable 5), Claude Code CLI,
extended thinking, tool use.

## 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 (no
docs reference these labels)
- [x] I have considered and documented any risks above
- [ ] 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
canary/v2026.821.0-canary.7
2026-08-21 12:51:22 -07:00
DottaandPaperclip f34591016e fix(runner): preserve workspace binding on recovery
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-21 14:10:45 -05:00
Nicky LeachandPaperclip 0148c2c6eb test(server): cover buffered duplex chunk drain after a late listener bind (#11865)
## Thinking Path

> - Paperclip uses duplex routes to carry data from plugin workers.
> - PR #11860 added the product fix for buffered data after an early
route end.
> - The fix needs a regression test for a listener that binds after the
byte cap ends the route.
> - This pull request adds that test and protects the fix from later
regressions.
> - The benefit is clear test coverage for late-listener delivery.

## Linked Issues or Issue Description

This pull request adds regression coverage for the fix in [PR
#11860](https://github.com/paperclipai/paperclip/pull/11860).

The product fix already exists on `master`. Before that fix, a late
listener could receive no data after the byte cap ended the route. The
test sends two three-byte `€` chunks to a route with a four-byte cap,
waits for route end, then binds the listener. It expects the first valid
chunk.

## What Changed

- Add one server regression test for late-listener delivery after
byte-cap route termination.
- Keep the product code unchanged in this pull request.

## Verification

- The test passes on the current branch.
- PR #11860 merged the product fix into `master` at commit
`33eb68b3ae4ce7ee27b31c59bd41db600ad47d19`.
- GitHub CI passes on the current head.
- Greptile reports 5/5 with no blocking finding.

## Risks

Low risk. This pull request changes one test file and no product code,
schema, public API, or authentication flow.

## Model Used

OpenAI GPT-5. Runtime model ID: GPT-5. Context window: not exposed in
this run. Capabilities used: repository review, GitHub operations, and
tool use. The implementation came from the engineer's authorized test
commit.

## 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 pull request does not
duplicate planned core work
- [x] I have searched GitHub for duplicate or related pull requests and
linked them above
- [x] I have either linked an existing issue or described the issue in
this pull request
- [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
- [x] I have run the relevant test and GitHub CI passes
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation, or documentation does not
apply
- [x] I have considered and documented the 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>
canary/v2026.821.0-canary.6
2026-08-21 11:48:21 -07:00
Nicky LeachandPaperclip 5bc6031f79 fix(server,ui,claude-local): verify auth on the adapter Test lane and enforce managed-sandbox tenant binding (#11810)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Adapter Test checks whether an agent adapter can run with its
configured environment, and every local-driver adapter (Claude, Codex,
Gemini, OpenCode, Pi, Cursor, etc.) shares this Test route and its UI
resolution logic
> - The Claude ACP Test lane could report pass without checking local or
remote authentication, and the shared Test route and UI had gaps in
environment binding, probe safety, and managed-sandbox resolution that
affect every adapter that uses the Test button, not only Claude
> - This pull request verifies authentication on every Claude ACP
target, and closes the shared Test-route/UI gaps: tenant-binding on the
route, a managed-sandbox-only redirect that matches the real run path,
and a three-tier environment resolution in the UI
> - The benefit is a truthful Test result with safer probe execution and
tenant isolation, for Claude specifically and for every other local
adapter that shares this Test surface

## Linked Issues or Issue Description

**What happened?**

The Claude ACP Test lane returned `status: "pass"` without checking
authentication for some local and non-sandbox targets. Separately, the
shared `/companies/:companyId/adapters/:type/test-environment` route —
used by every local-driver adapter, not only Claude — accepted a foreign
environment id, and its UI resolution did not mirror the server's
managed-sandbox-only redirect.

**Expected behavior**

The Test lane checks the resolved credential and hello probe for every
Claude ACP target. The shared adapter Test route rejects a foreign
environment before it reveals environment details or starts a lease, for
any adapter type. The Test's environment resolution (UI and server)
matches the real run's three-tier resolution, including the
managed-sandbox-only redirect.

**Steps to reproduce**

1. Run the Claude ACP Test lane against a local target without a valid
credential.
2. Run the adapter Test route with an environment id from another
company (any adapter type).
3. Observe the pass result on step 1, or the missing tenant-binding
rejection on step 2.

**Paperclip version or commit**

`933749e01f74e82ce5d315c071be534d04e01158`

**Deployment mode**

Local dev (`pnpm dev`) and server route tests.

**Agent adapter(s) involved**

Claude Code directly (the ACP auth-verification work). The
tenant-binding guard, managed-sandbox-only redirect, and UI three-tier
resolution apply to the shared adapter Test route and affect every
local-driver adapter (Codex, Gemini, OpenCode, Pi, Cursor, etc.), not
only Claude — see "What Changed" below for the split between Claude-only
and shared changes.

**Database mode**

Not database-related.

**Access context**

Both board and agent paths use the affected Test surface, for every
local-driver adapter.

**Additional context**

Two commits that were previously bundled into this PR — a
`plugin-worker-manager` duplex-channel frame-bound fix and a
`workspace-runtime` exit-persist crash fix — are unrelated to the
adapter Test lane and have been split out into their own PRs: #11860 and
#11861.

## What Changed

Claude-only (`packages/adapters/claude-local`):

- Verify `CLAUDE_CODE_OAUTH_TOKEN` and run the hello probe for every
Claude ACP target.
- Keep `adapter_auth_missing` sandbox-only and report missing
non-sandbox credentials as a warning.
- Add a deny-by-default probe environment builder for the ACP and CLI
local probes.
- Log only fixed probe context and allowlisted classifications.
- Seed the host OAuth token into the hello probe environment.

Shared, cross-adapter (`server/src/routes/agents.ts`,
`ui/src/lib/adapter-test-environment.ts`,
`ui/src/components/AgentConfigForm.tsx`,
`ui/src/components/OnboardingWizard.tsx`):

- Add a company-binding guard and a binding assertion for the generic
`/companies/:companyId/adapters/:type/test-environment` route, so a
foreign-company environment id is rejected before any secret resolution
or sandbox lease, for every adapter type.
- Resolve all three server environment tiers (agent default, instance
default, local default) in the UI, and add the managed-sandbox-only
redirect so the Test probes the same target a real run would use.
- Enforce onboarding Test results: block hire on a failed environment
test.

- Add regression tests for authentication, tenant binding, probe safety,
diagnostics, and UI resolution.

## Verification

- Adapter suites pass for the Claude local server probe, remote, ACP,
auth, probe environment, and config paths.
- Server route tests pass, including the five tenant-binding cases.
- UI adapter Test environment resolver tests pass for all three
resolution tiers.
- Adapter package `tsc --noEmit` exits 0.
- Full CI must pass on this pull request.

## Risks

The probe environment now denies caller variables by default. A required
variable that is not on the allowlist could stop a probe from starting.
The route now rejects foreign environment ids with a fixed 403 response.
The managed-sandbox-only redirect changes where the Test (and the login
affordance) probes for every local-driver adapter under that policy, not
only Claude — operators running other local adapters under
managed-sandbox-only will see their Test target move from local to the
managed sandbox, matching what real runs already do. The change limits
secret and diagnostic exposure.

## Model Used

Original implementation: OpenAI Codex, GPT-5; exact context window not
exposed in that run; tool use and code execution.

This revision (commit split and title/description correction): Claude,
Sonnet 5 (claude-sonnet-5). The original title and description described
this PR as Claude-only; review found it also changes the shared adapter
Test route and UI resolution used by every local-driver adapter, and
carried two unrelated server fixes. Claude split those two commits into
#11860 and #11861 via `git rebase --onto` (verified byte-identical to
the original tree minus those commits) and rewrote this description to
reflect the actual scope. No functional code in this PR was authored by
Claude.

## 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>
2026-08-21 11:30:49 -07:00
github-actions[bot]andlockfile-bot 917d2350f8 chore(lockfile): refresh pnpm-lock.yaml (#11867)
## Thinking Path

> - Paperclip uses a pnpm workspace for its packages.
> - Package manifests and the lockfile must stay synchronized.
> - A merged Node version policy fix changed package manifests on
master.
> - The frozen lockfile no longer matched those manifests.
> - This automated pull request refreshes the generated lockfile.
> - The benefit is that clean installs and required CI jobs can run
again.

## What Changed

- Regenerated `pnpm-lock.yaml` from the current package manifests.

## Verification

- `pnpm install --lockfile-only --ignore-scripts --no-frozen-lockfile`
- The repository PR workflow validates the generated lockfile with a
frozen install.

## Risks

Low risk. This is an automation-generated lockfile-only update after
manifest changes on master.

## Model Used

None — automation-generated.

Co-authored-by: lockfile-bot <lockfile-bot@users.noreply.github.com>
2026-08-21 11:02:35 -07:00
Nicky LeachandPaperclip 1746783d40 fix(kimi): align package with Node 24 policy (#11890)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip now requires Node.js 24.11.0 or later
> - Each workspace package must publish the same Node.js engine
requirement
> - The Kimi adapter entered `master` after the Node.js upgrade branch
started
> - Its package still used Node.js 22 types and had no engine
requirement
> - This pull request aligns the Kimi adapter with the repository
Node.js policy
> - The benefit is that the Node.js policy check passes again on
`master`

## Linked Issues or Issue Description

**What happened?**

The `pnpm check:node-version` command fails on `master`. The Kimi
adapter uses `@types/node` 22 and has no `engines.node` value.

**Expected behavior**

All workspace packages must use Node.js 24 types and declare Node.js
24.11.0 as the minimum version.

**Steps to reproduce**

1. Check out commit `a7e689b3c`.
2. Use Node.js 24.11.0.
3. Run `pnpm check:node-version`.

**Paperclip version or commit**

`a7e689b3c`

**Deployment mode**

Local dev (`pnpm dev`).

## What Changed

- Update the Kimi adapter to use `@types/node` 24.
- Add the repository minimum Node.js engine requirement to the Kimi
adapter package.
- Keep `pnpm-lock.yaml` out of this pull request.

## Verification

- `npx -y -p node@24.11.0 -c 'node --version && pnpm check:node-version
&& pnpm --filter @paperclipai/adapter-kimi-local typecheck'`
- The command reports Node.js `v24.11.0`.
- The Node.js policy check passes.
- The Kimi adapter typecheck passes.
- A broader local suite was started and stopped at the maintainer's
request after the focused checks passed.

## Risks

- Low risk. This change updates package metadata and development types
only.
- The lockfile refresh runs in separate repository automation.

> 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, GPT-5, with repository inspection, shell tools, and code
execution.

## 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>
2026-08-21 10:55:58 -07:00
DottaandPaperclip baf49f5e97 fix(dev): rebuild runner before server startup
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-21 12:49:04 -05:00
scotttongandClaude Fable 5 a7e689b3c3 feat(ui): rename "Agent mode" to "Auto mode" and show full work-mode labels (#11866)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The task composer and the New Task dialog show a work-mode chip (how
the agent will run a task)
> - The default mode was labeled "Agent mode", and the New Task dialog
chip abbreviated every mode to one word ("Auto", "Plan", "Ask")
> - "Agent mode" is confusing because every mode runs an agent, and the
abbreviated chip hid what the label means
> - This pull request renames the mode to "Auto mode" and makes every
mode chip show the full label
> - The benefit is a clearer, consistent mode name in every place the
user selects a work mode

## Linked Issues or Issue Description

No public GitHub issue exists for this change. Description follows the
enhancement template:

**What existing behavior does this improve?**

The work-mode selector chips in the task composer and in the New Task
dialog.

**Subsystem affected**

UI (`ui/src/lib/work-mode-meta.ts`,
`ui/src/components/NewIssueDialog.tsx`).

**Current behavior**

The default work mode is labeled "Agent mode". The New Task dialog chip
shows a shortened label ("Auto", "Plan", "Ask") from a separate
`shortLabel` field.

**Proposed behavior**

The default work mode is labeled "Auto mode". Every chip shows the full
label ("Auto mode", "Plan mode", "Ask mode"). The `shortLabel` field is
removed so no surface can fall back to the short form.

**Reason and benefit**

"Agent mode" does not describe the behavior — all modes use an agent.
"Auto mode" states what the mode does. One label field keeps every
surface consistent.

**Breaking changes**

None. This is a display-string change only. No API, storage, or mode-key
changes.

## What Changed

- Renamed the `standard` work-mode label from "Agent mode" to "Auto
mode" in `ui/src/lib/work-mode-meta.ts`, the single source for all mode
chips.
- Changed the New Task dialog mode chip to render the full `label`
instead of `shortLabel`.
- Deleted the `shortLabel` field from `WorkModeMeta` so nothing can
silently regress to the short form.
- Updated unit tests and fixtures to pin the full labels.

## Verification

- Run `pnpm --filter @paperclipai/ui test --
src/lib/work-mode-meta.test.ts src/components/NewIssueDialog.test.tsx
src/components/IssueChatThread.test.tsx
src/components/task-chat/TaskChatComposer.test.tsx`. All tests pass. The
tests assert the labels are exactly "Auto mode", "Plan mode", and "Ask
mode".
- Manual: start the dev server, open the board, press `c` to open the
New Task dialog, and press Cmd+Period to cycle modes. The chip reads
"Auto mode", "Plan mode", then "Ask mode". The composer chip on an open
task shows the same labels.

## Risks

- Low risk. Display strings only. The chip is a few pixels wider in the
New Task dialog; no layout overflow was observed in any of the three
modes.

## Model Used

- Claude Fable 5 (Anthropic, model ID `claude-fable-5`), extended
thinking with tool use, run inside a Claude Code agent session.

## 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
- [ ] 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: Claude Fable 5 <noreply@anthropic.com>
canary/v2026.821.0-canary.5
2026-08-21 10:28:55 -07:00
DottaandPaperclip 2fe9fdd5a2 fix(runner): stream native activity into task chat
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-21 12:27:35 -05:00
Nicky LeachandPaperclip 38d8f37172 fix(build): enforce Node 24 across Paperclip (#11792)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Paperclip runs across the CLI, server, adapters, plugins, CI, and
container images.
> - These surfaces declared different Node.js versions from 20 through
24.
> - A newer `@types/node` major can expose APIs that the supported
runtime does not provide.
> - Node.js 20 is no longer a suitable project baseline, and Node.js 24
is the current LTS line.
> - This pull request sets Node.js 24.11.0 as one repository-wide
baseline, adds a drift check, and gives users actionable startup
guidance when their runtime is too old.
> - The benefit is one clear runtime contract for development, release,
installation, and published packages.

## Linked Issues or Issue Description

Refs #2734

Refs #11727

Refs #739

## What Changed

- Require Node.js 24.11.0 or newer in all 42 package manifests and
runtime checks.
- Use Node.js 24 in GitHub Actions, Docker images, smoke images, sandbox
setup, portable installs, and esbuild targets.
- Align every direct `@types/node` declaration on `^24.0.0`.
- Prevent Dependabot from opening major `@types/node` upgrades without a
matching runtime decision.
- Add `.nvmrc` and a CI policy check for Node version drift.
- Update ACP version gates, tests, and user documentation for the new
minimum.
- Print a non-blocking warning on CLI and server startup when Node is
unsupported, with remediation through a version manager or the
documented downloaded `install.sh` workflow.
- Deduplicate that warning when `paperclipai run` boots the CLI and
server in the same process.

## Verification

- `node scripts/check-node-version-policy.mjs`
- `node --check scripts/check-node-version-policy.mjs`
- `node --check cli/esbuild.config.mjs`
- `node --check scripts/generate-npm-package-json.mjs`
- `bash -n scripts/install.sh scripts/test-install-sh-docker.sh
scripts/e2e-install-lifecycle.sh`
- Parsed all 42 package manifests and confirmed `engines.node` is
`>=24.11.0`.
- `git diff --check`
- `vitest run
packages/adapter-utils/src/sandbox-install-command.test.ts` passed with
3 tests.
- `vitest run cli/src/node-version.test.ts` passed with 4 tests.
- Directly exercised the shared warning helper for unsupported-version
messaging and same-process deduplication.
- The focused exe.dev suite could not resolve the locally unbuilt plugin
SDK from this isolated worktree. A full offline workspace install was
also blocked because the package-manager signature verifier requires
registry access. The full suite was not run locally; draft CI performs a
clean install and evaluates the wider impact.

## Risks

- This is a breaking runtime change for users, plugins, and deployments
that still use Node.js 20 or 22.
- Published workspace packages will now produce an engine warning or
failure in strict package managers on older Node.js releases.
- Node.js 24 can reveal dependency, native module, Playwright, or agent
CLI compatibility issues in CI.
- The bootstrap installer now installs Node.js 24 when the current
runtime is older than 24.11.0.
- The portable sandbox fallback is pinned to Node.js 24.11.0 and depends
on that upstream tarball remaining available.
- Unsupported runtimes continue booting after a warning, so a later
incompatibility can still fail at its point of use.
- The CLI and server share the warning policy through the published
`@paperclipai/shared` package; packaging checks must keep that subpath
export available.
- This PR does not commit `pnpm-lock.yaml` because repository policy
assigns lockfile generation to CI.

> 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 deployment ID and context
window are not exposed in this session. Reasoning, repository tools,
shell execution, and GitHub tools were 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>
2026-08-21 10:17:52 -07:00
Nicky LeachandPaperclip 33eb68b3ae fix(server): end the duplex route on the pre-bind bounds when frames arrive before the bind (#11860)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The host and a plugin worker talk over a duplex channel route with
bounds on buffered frames and total bytes
> - A worker can batch its data and exit frames with the open reply, so
those frames arrive before the route binds and before a listener
attaches
> - Two of the route bounds did not hold on that pre-bind path: a shared
limit let the pre-open hold swallow an over-limit frame before the
buffered-frame bound could end the route, and the route end discarded
chunks a later listener still needed
> - This pull request gives the pre-open hold its own ceiling above the
buffered bound, and keeps the buffered chunks across a route end
> - The benefit is a duplex route that enforces its bounds and preserves
valid data, even when a worker batches frames ahead of the bind

## Linked Issues or Issue Description

No existing GitHub issue covers this. Filing it directly here, following
the bug report template.

**What happened?**

Two duplex channel route bounds in
`server/src/services/plugin-worker-manager.ts` did not hold when the
data and exit frames arrived in the open-reply read batch, before the
route bound:

- The pre-open hold and the pre-bind buffered-frame bound shared one
limit. When a caller lowered the buffered bound, the hold dropped the
overflow frame as a protocol error before the buffered bound could end
the route, so the route never ended.
- The route end discarded the buffered chunks. A frame can end the route
during the replay, before a listener attaches, and the chunks the host
accepted before that frame are valid data.

**Expected behavior**

The pre-open hold uses its own ceiling, above the buffered bound, so the
replay after the bind lets the buffered bound end the route. A route end
keeps the buffered chunks so a listener that attaches after the end
still drains them.

**Steps to reproduce**

1. Open a duplex channel where the worker batches several data frames
with the open reply.
2. Lower `maxPreBindBufferedFrames` below the batch size.
3. Observe the route fails to end on the buffered-frame bound, or a
listener that attaches after an end-during-replay never receives the
chunks buffered before that end.

**Paperclip version or commit**

`933749e01f74e82ce5d315c071be534d04e01158`

**Deployment mode**

Local dev (`pnpm dev`) and server unit tests.

**Agent adapter(s) involved**

None — this is host/plugin-worker transport infrastructure, not
adapter-specific.

**Database mode**

Not database-related.

**Access context**

Any board or agent path that runs a plugin worker over a duplex channel
route.

## What Changed

- Give the pre-open frame hold its own ceiling
(`MAX_DUPLEX_CHANNEL_PRE_OPEN_HOLD_FRAMES`), separate from the pre-bind
buffered-frame bound, so lowering the buffered bound still ends the
route instead of being pre-empted by the hold.
- Keep the buffered chunks on a route end instead of discarding them, so
a listener that attaches after an end-during-replay still drains the
data the host already accepted.
- Add two regression tests that batch frames with the open reply, so
both bounds run through the pre-bind path deterministically.

## Verification

- `cd server && npx vitest run
src/__tests__/plugin-worker-manager-duplex.test.ts` — 24/24 tests pass,
including the two new regression cases.

## Risks

Low risk. This only changes bound bookkeeping on an internal transport
path (frame hold ceiling and end-time buffer retention); it does not
change the wire protocol or any public API. The new ceiling is a
constant above the existing buffered bound, so pre-open holds are still
capped.

## Model Used

Claude, Sonnet 5 (claude-sonnet-5); assisted with repository-grounded
diff review and drafted this PR description from the commit and code
history. No functional code in this PR was authored by Claude — the fix
itself is Priya Raman's, preserved with original authorship intact.

## 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>
canary/v2026.821.0-canary.4
2026-08-21 10:09:30 -07:00
Nicky LeachandPaperclip 9af1e75629 fix(server): handle the runtime service exit persist when a parent row is gone (#11861)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - A runtime service (e.g. a dev server an agent started) runs as a
child process tracked against a project row
> - When that child exits on its own, the host records its terminal
status in the database as a detached, best-effort persist
> - A caller can delete the project (or company) while the child still
runs, so the `project_id` foreign key rejects that persist, and the
detached write had no error handler, turning the rejection into an
unhandled crash
> - This pull request wraps the exit-time persist in a try/catch and
logs the failure instead of crashing the host
> - The benefit is a host that survives a project deleted out from under
a still-running runtime service, instead of taking down the whole
process on an unrelated cleanup

## Linked Issues or Issue Description

No existing GitHub issue covers this. Filing it directly here, following
the bug report template.

**What happened?**

`registerRuntimeService`'s child `exit` handler in
`server/src/services/workspace-runtime.ts` runs a detached, unawaited
persist of the terminal service status. If the parent project row was
deleted while the service was still running, the `project_id` foreign
key rejects the write. The detached persist had no error handler, so the
rejection surfaced as an unhandled promise rejection and could crash the
host.

**Expected behavior**

The exit-time persist is best effort: every error inside it is caught
and logged, so a foreign-key rejection (or any other persist failure)
never crashes the host.

**Steps to reproduce**

1. Start a runtime service tied to a project.
2. Delete the project (or company) while the service is still running.
3. Let the child process exit on its own.
4. Observe the detached persist throws an unhandled foreign-key error.

**Paperclip version or commit**

`933749e01f74e82ce5d315c071be534d04e01158`

**Deployment mode**

Local dev (`pnpm dev`) and server unit tests (embedded Postgres).

**Agent adapter(s) involved**

None — this is runtime-service lifecycle infrastructure, not
adapter-specific.

**Database mode**

Embedded/managed Postgres — the fix concerns the `project_id` foreign
key on the runtime-service table.

**Access context**

Any board or agent path that starts a runtime service (e.g. a dev
server) tied to a project that can later be deleted.

## What Changed

- Wrap the exit-handler's `cleanupRecordExposure` /
`removeLocalServiceRegistryRecord` / `persistRuntimeServiceRecord`
sequence in a try/catch; log a warning on failure instead of letting the
rejection escape.
- Terminate real child processes in the embedded-postgres test teardown
before the row deletes, so a left-over child does not exit later and
write a row that references an already-deleted project.

## Verification

- `cd server && npx vitest run src/__tests__/workspace-runtime.test.ts`
covers the new exit-persist-after-parent-delete regression case. This
suite spins up embedded Postgres and did not finish inside this review's
local time budget, so I did not confirm a local pass — deferring to CI,
which runs it as part of the normal server test job.

## Risks

Low risk. The change only adds error handling around an existing
best-effort, detached persist — it does not change the happy-path
behavior or the persisted schema. A persist failure is now logged
instead of crashing the host, which is strictly safer.

## Model Used

Claude, Sonnet 5 (claude-sonnet-5); assisted with repository-grounded
diff review and drafted this PR description from the commit and code
history. No functional code in this PR was authored by Claude — the fix
itself is Priya Raman's, preserved with original authorship intact.

## 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>
2026-08-21 09:02:36 -07:00
DottaandPaperclip d711fe390c fix(runner): stream progress and final replies
Publish runner-authored comments to live issue threads, keep progress distinct from completion, and make follow-up comments authoritative for native completion contracts.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-21 10:53:45 -05:00
Dotta ea10f3d2b9 docs: explain native status arbitration 2026-08-21 10:36:07 -05:00
Dotta 2fc9b49d39 docs: explain durable continuation scheduling 2026-08-21 10:31:57 -05:00
Dotta 391b429955 fix(runner): honor comment wakes and stop completion loops 2026-08-21 10:30:18 -05:00
Dotta 0f507a8622 fix(runner): await authoritative provider turn identity 2026-08-21 10:12:37 -05:00
Dotta f4a6ad61a4 fix(runner): preserve coalesced provider turns 2026-08-21 10:06:57 -05:00
Dotta da934b6d3d fix(runner): buffer pre-accept Codex items 2026-08-21 10:02:53 -05:00
Dotta 380e9f3aae fix(runner): bind implicit Codex item turns 2026-08-21 09:59:14 -05:00