diff --git a/releases/beta/v2026.910.0-beta.0.md b/releases/beta/v2026.910.0-beta.0.md new file mode 100644 index 0000000000..c1be0025ec --- /dev/null +++ b/releases/beta/v2026.910.0-beta.0.md @@ -0,0 +1,1333 @@ +# Paperclip stable draft — from beta 2026.910.0-beta.0 + +> Auto-generated at beta publish from `git log dbf052577..86c2e0ac4` (baseline: v2026.831.1 (merge-base dbf052577)). +> Edit freely during the soak: rewrite for release-notes voice, +> fold noise, and call out anything a self-hoster must act on. +> The stable promotion reads this file from master and publishes +> it as the GitHub Release body under the stable version. + +## Features + +- feat(server): log an activity row for each queued-comment queue mutation (#13159) + > - Add activity rows for queued-comment edit, reorder, and discard mutations. + > - Include queue identifiers, revisions, ordered comment identifiers, and cancelled run identifiers as applicable. + > - Add activity-feed labels for the three new actions. +- feat: add experimental native chat connectors (#13038) + > - Add native Slack, GitHub, Microsoft Teams, Telegram, and Discord chat connections. Keep chat disabled unless the operator enables experimental chat connectors. Preserve the production GitHub tool connection and its normal setup path. + > - Bind each provider bot identity to one immutable Paperclip agent. Bind each admitted external conversation to one task. Paperclip owns tasks, runs, permissions, and audit records. + > - Add durable admission, per-conversation queues, questions, task controls, progress, final replies, images, files, and delivery receipts. Board comments remain internal unless explicitly sent to the channel. +- feat: bind an agent to a Codex login whose account differs from the company default (#13067) + > - `packages/adapters/codex-local` — the prerequisite shield: `isCodexAuthCachePath` recognizes per-identity credential-store entries, and `seedManagedCodexHome` refuses to symlink, heal, or API-key-overwrite an entry's `auth.json`. The seeding pass runs before every probe and execute; without the shield, an agent bound to an entry would have its stored login silently swapped for the host credential. Static shared config files still copy in. Rotation already survives binding: the sandbox copy-back writes rotated credentials into the identity-keyed store slot. + > - `server` — the promotion records whether the company default home ended on a different account than the login (any read failure degrades to `false`, so the client can never be told to bind wrongly). After the terminal commit, the routes layer remembers a non-secret claim — the opaque account-home secret id plus that verdict — in a bounded in-memory map, and merges it into the owner read of an `authenticated` `codex_local` session. A restart drops the claim; the panel then shows plain success. + > - `packages/shared` — `CodexAccountBindingClaim` on the owner session response. It carries no account identifier and no credential byte. +- feat: add opt-in chat provider and data foundation (#13100) + > - Add closed channel types, additive tables, and migration upgrade tests. + > - Pin and patch Slack, Discord, Telegram, Teams, and GitHub adapters. + > - Add provider parser, native-form, private-response, file, receipt, and rendering helpers with synthetic transport tests. +- feat(ui): add composer Stop and simplify task controls (#13104) + > - Add Stop, pending feedback, duplicate-click protection, and inline errors to the composer. + > - Share the pause mutation across the composer, active-run controls, and menu. + > - Poll affected runs after a pause request. Require native cancellation acknowledgment. +- feat(ui): add task status badges and inline blocker removal (#13097) + > - Add a property variant to the shared task reference pill. + > - Show status icons in parent, blocker, blocking, and subtask badges. + > - Reserve space for an accessible blocker remove button. +- feat(onboarding): first task opens as a chat with a chief of staff (#13068) + > - Wizard: four steps (Name your organization, Create your first agent, Connect a model, Review). The front door and both mission steps are removed with their state and saved-progress keys. The UI no longer composes the first agent's instructions or the first task description. + > - Server-owned texts: the greeting, the brief with two proposal variants, the chief-of-staff persona, the opening question, and a README live in `server/src/onboarding-assets/first-task/` and load at runtime. The create route stores the assembled brief and ignores any client description. + > - Persona seed: an `onboardingFirstAgent` marker on the hire lets the server seed the chief-of-staff persona over the first agent's entry file. Board-authored hires only. The persona tells the agent the hire response shape and to list agents before it acts on an unclear result. +- feat: review connection actions from tasks (#13063) + > - Add compact pending and resolved task records. Preserve dismissal, reopening, multiple reviews, and cross-tab updates. Share the card with Connections. + > - Centralize human decisions. Preserve context binding, signed arguments, expiry, formal approval, and provider execution claims. + > - Add action-wide remembered permission for the same agent, connection, action, and current project. Keep exact-argument defaults for existing trust APIs. +- feat(adapter-utils): carry binary bodies and attachment routes over the HTTP/2 sandbox bridge (#12923) + > - Carry request and response bodies as raw bytes through the HTTP/2 bridge. + > - Permit attachment upload and attachment content routes on the HTTP/2 bridge only. + > - Raise the resolved per-body limit to 10 MiB and share it between the gateway and host. +- feat(connections): connect services from native task feeds (#13058) + > - Expose `connections_search` and `connection_request` with server-bound company, task, agent, and responsible user. Preserve the legacy entry points. + > - Discover catalog services and authorized custom connections. Check installation, identity, health, and executable permissions before reporting ready. + > - Keep pending cards through ordinary messages. Reuse requests and retire stale ownership. Put Connect at the right of Not now. +- feat: simplify agent onboarding and configuration (#13011) + > - Added a new-agent wizard with numbered steps, adapter branding, provider connections, editable model choices, runtime tests, and confirmation. + > - Added Codex app-server, Claude ACPX, and OpenCode runner choices. + > - Stored API credentials through existing secret APIs and persisted references in agent configuration. New setup keys are isolated from credentials used by existing agents. +- feat(projects): select multiple GitHub source repositories (#13010) + > - Add company-scoped repository discovery from usable personal and shared GitHub grants, with provider-ID deduplication, PAT pagination, and partial failure handling. + > - Document the repository endpoints and board access requirements in OpenAPI. + > - Validate new selections and save projects with multiple repository workspaces in one transaction. Preserve legacy URLs and existing selections whose access was lost. +- feat: use the responsible person's GitHub for shared agent operations (#13005) + > - Add durable, ordered identity contexts and active run references. Preserve message authors through consolidation, steering, retries, delegation, approvals, routines, and restart. + > - Add an authenticated operation-time GitHub credential broker and local/remote managed git and gh launchers. Keep personal tokens out of the long-lived provider process. + > - Resolve GitHub gateway and server-side Git operations through the same responsible-person or dedicated-grant selection rules. +- feat(runner): add guarded API search and call fallback (#13003) + > - Register two compact fallback tools in canonical contracts and provider projections. + > - Build deterministic API discovery from OpenAPI, mounted experimental routes and the old skill reference. + > - Execute bounded JSON, text, file and download requests through authenticated HTTP routes. +- feat: browse GitHub repository access across organizations (#12998) + > - Add an All accounts view, account filter, search, and empty states. + > - Link both configuration controls to GitHub's app account chooser. + > - Place an accessible refresh icon beside the configuration button. +- feat(runner): restore direct live eval campaigns and reports (#12909) + > - Added a trusted two-shard direct live workflow for up to 393 roster-plus-case cells. + > - Reused the numeric actor allowlist, protected paid environment, and RunsOn fleet controls from Runner full-stack E2E. + > - Added immutable Runner and eval revision resolution, exact credential boundaries, bounded retries, and cost ceilings. +- feat(agent-login): resume an active login session and permit concurrent login terminals (#12861) + > - Replace the single worker login route with maps keyed by host route and worker session identifiers. + > - Add a process-wide login route ceiling and release each reserved slot on every exit path. + > - Add owner-scoped active-session reads with consistent negative responses and private cache control. +- feat(runner-e2e): publish declared screenshots (#12895) + > - Mark screenshots from the exact server-created live fixture issue route with `public-runner-fixture`. + > - Keep marked PNG files in both the S3 history bundle and the GitHub Pages bundle. + > - Keep captures from other issue routes, sensitive routes, and external origins private. +- feat(cli): add isolated test-drive command (#12894) + > - Add `paperclipai test-drive` with isolated data, foreground startup, delayed browser opening, and no service installation or first task. + > - Add Claude, Codex, and OpenCode harness mappings with canonical secret references and model validation. + > - Accept provider credentials only through environment variables, keeping raw secrets out of CLI arguments. +- feat(runner-e2e): improve matrix report browsing (#12889) + > - Keep matrix and matcher table widths stable when details expand. + > - Show retained screenshot thumbnails in each test card. + > - Add a full-screen evidence gallery with mouse, keyboard, and swipe navigation. +- feat(onboarding): the connect step's sign-in as one continuous sequence (#12863) +- feat(ui): refine core navigation and task detail (#12854) + > - Rebuilt the profile and organization popovers with compact token-based layouts. + > - Matched organization popover width and alignment to the profile popover. + > - Unified sidebar hover and selected states in light and dark modes. +- feat(connections): add durable GitHub identities and webhooks (#12843) + > - Added agent-owned connection grants and a per-agent credential policy with company and subject constraints. + > - Added a managed GitHub App method while keeping the personal access token method as an advanced fallback. + > - Added durable access-token and refresh-token handling with proactive rotation and one automatic recovery after a provider `401`. +- feat(codex): add GPT-6 Astra support (#12851) + > - Added `gpt-6-astra` to the Codex local adapter model registry and fast-mode support list. + > - Added the official Astra reasoning efforts: `low`, `medium`, `high`, `xhigh`, `max`, and `ultra`. + > - Used the adapter metadata in agent and task model selectors. +- feat(telemetry): add the agent.task_run event and emit it at every terminal run transition (#12809) + > - Add the agent.task_run telemetry contract and client helper. + > - Reuse the existing pseudonym helper for the task identifier. The helper hashes the identifier with a per-installation salt and returns 16 hexadecimal characters. The raw identifier never leaves the installation. Existing identifiers do not move. + > - Emit one event from each legacy, native, recovery, and issue terminal transition. +- feat(onboarding): the API key field is the same card as the sign-in (#12820) + > - **`instruction` widens from `string` to `ReactNode`.** A variable name wants mono and a string cannot carry that. + > - **The row input's classes move to an exported `onboardingCardInputClass`**, shared by the browser-code field and this one. Matching by restating measurements is what let these drift in the first place; sharing the declaration is what stops it happening again. +- feat(ui): viewer=full document deep link opens the maximized side pane (#12812) + > - `ui/src/lib/document-annotation-hash.ts`: parse and build an optional `viewer=full` parameter in document hashes. + > - `ui/src/lib/issue-document-deep-link.ts`: thread a `maximize` flag on properties-pane routes; the continuation-summary route is unchanged. + > - `ui/src/context/PanelContext.tsx`: add a one-shot panel maximize request (`requestPanelMaximize` / `clearPanelMaximizeRequest`). +- feat(agents): grant new agents hire permission by default (#12814) + > - `normalizeAgentPermissions` now takes a `create`/`stored` context. Creation writes get the new default: enabled unless `permissionsImplyLowTrust()` detects the low-trust review preset or a trust boundary. Stored rows without an explicit value normalize to disabled (fail-closed). The role parameter is gone. + > - `agentPermissionsSchema` no longer injects `canCreateAgents: false` when the field is omitted. The server-side default applies instead. + > - `authorization.ts` normalizes raw agent rows for `agents:create`, so enforcement matches what the API reports for legacy rows. +- feat(onboarding): the connect step signs in from its own button (#12801) +- feat(onboarding): round-4 corrections to the connect and agent steps (#12796) + > - **Sources are named for the provider you sign in with** — "Claude" and "OpenAI", not "Claude Code" and "Codex". + > - **OpenAI's mark is inlined**, not served from `/brands`. + > - **Autofill is monochrome.** +- feat(apps): unify permissions and action testing (#12802) + > - Combined action testing with Permissions. + > - Added searchable Read and Write action groups. + > - Added Off, Ask first, and Allowed controls with tooltips. +- feat(ui): refine streamlined task experience (#12748) + > - Unify task and inbox collection controls, grouping, filtering, and row presentation. + > - Align the task breadcrumb with the task-list root header. + > - Refine task chat bubbles, notices, composer modes, scrolling, and interaction cards. +- feat(ui): refine streamlined workspace surfaces (#12747) + > - Apply streamlined layouts to agents, routines, skills, audits, costs, timeline, and organization pages. + > - Add reusable collection toolbar and issue-row presentation. + > - Keep routine and agent detail navigation in a secondary contextual sidebar. +- feat(ui): add streamlined navigation foundation (#12746) + > - Add the streamlined UI instance setting and shared contract validation. + > - Add shared navigation, breadcrumb, and contextual-sidebar primitives. + > - Keep recent tasks and organization navigation available in the global sidebar. +- feat(codex-local): give each Codex account its own home and path secret (#12709) + > - Add strict allowlist validation for Codex account handles. + > - Store each Codex account credential in a separate home under the Codex cache root. + > - Verify that the resolved account home stays inside the cache root. +- feat(claude-local): add Claude Fable 5.1 support (#12730) + > - Added `claude-fable-5-1` to the direct Claude fallback list. + > - Added `us.anthropic.claude-fable-5-1` to the AWS Bedrock list. + > - Kept the existing default model at the first position in each list. +- feat(work-products): add rich cards and run artifact inventory (#12717) + > - Added a shared rich work-product card with kind-specific content and a compact inventory variant. + > - Added pull-request and commit diff metadata plus bounded GitHub state refresh. + > - Added media strips and typed file chips to message-tail attachments. +- feat(onboarding): Figma pass over the tenant arc (#12726) + > - The connect step opens with no source selected. `sourcePicked` starts false unless a saved draft carries one. + > - The step cannot advance until a source is selected in the visible row. The gate reads `sourceSelected`, not `sourcePicked`. + > - The snap effect, which replaces an adapter the registry no longer carries, now clears the selection. The snap removes a choice; it does not make one. +- feat(runner): add managed provider backends (#12699) + > - Add Claude Managed Agents and AWS AgentCore provider executors to runnerd. + > - Add qualified managed and remote profile storage, routes, OpenAPI contracts, CLI commands, and migration 0237. + > - Validate profile ownership, enabled state, exact qualified revision, model, agent version, and secret binding before persistence and recovery. +- feat(runner): activate qualified OpenCode and ACPX providers (#12691) + > - Add one server profile resolver for Codex, OpenCode, and qualified ACPX descriptors. + > - Keep `adapterConfig` as the provider and permission authority for fresh runs. + > - Add Paperclip Runner provider, ACPX agent, and provider-specific permission controls to the UI. +- feat(grok-local): copy a refreshed sandbox credential back to the host (#12696) + > - `grok-auth-merge-decision.cjs` adds a host predicate in its own process. It compares the whole `::` identity key of the two files. It reads `expires_at` as an ISO-8601 string, an epoch-seconds number, or an epoch-milliseconds number. It exits 10 to use the source, 20 to keep the destination, 21 when the expiry shape is unreadable, and 22 when the source expiry sits more than 400 days after the host clock. It fails closed in every unclear case: an unusable side, a different identity, an absent expiry, a tie, an unreadable expiry, and an implausible expiry all keep the destination. + > - `grok-auth-merge-decision.ts` adds a wrapper that runs the predicate and maps the exit code to a typed result. + > - `grok-auth-copyback.ts` adds `copyBackGrokAuth({ hostHomeDir, readSandboxAuth, log, env })`. It locks on `hostHomeDir` with `withDirectoryMergeLock`, stages the sandbox bytes into a private `0600` temporary file, runs the predicate, and installs the file with an atomic rename in the same directory. It keeps no backup of the displaced credential. It leaves no temporary file on the success path, the keep path, or an error path. On an error it logs the `errno` code only, then re-throws. +- feat(apps): consolidate connector management (#12684) + > - Consolidated app browsing, connection setup, and connection management. + > - Added a red Remove connection action with a trash icon and confirmation. + > - Restored the ask-first review path for connector test calls. +- feat(server): split the Sentry DSN into front-end and backend variables (#12678) + > - Add `resolveSentryDsns(env)` and use it in the server and browser configuration paths. + > - Add precedence, empty-string, fallback, and route tests. + > - Update the README, observability guide, and stale code comments. +- feat(grok-local): stage a curated Grok home into remote subscription runs (#12618) + > - Stage a private temporary Grok home for remote subscription runs. + > - Copy only the allowed `auth.json` file and set its mode to `0600`. + > - Pass the staged directory as the remote `home` asset. +- feat(runner): add offline evaluation tooling (#12653) + > - Add a workspace-private, provider-neutral evaluation matrix kernel. + > - Add the public `@paperclipai/paperclip-runner/evals` compatibility and native execution contracts. + > - Add fail-closed runnerd artifact and protocol compatibility checks. +- feat(runner): add administration and observability (#12641) + > - Added Codex-only Paperclip Runner permission and lifecycle controls. + > - Added bounded warm idle configuration. + > - Kept the provider field fixed to Codex. +- feat(ui): complete the task workspace (#12640) + > - Added a reusable task workspace side panel for files and documents. + > - Added provider-neutral cards for tools, plans, questions, protocol activity, and progress. + > - Added queued guidance and richer composer state. +- feat(runner): add secure remote transport (#12639) + > - Added WSS dialing with rustls and native certificate roots. + > - Added an optional bounded private CA bundle that augments native roots. + > - Kept plaintext WebSocket dialing restricted to loopback addresses. +- feat(runner): add remote execution substrate (#12638) + > - Added execution-target traits for local, SSH, and sandbox environments. + > - Added plugin RPC contracts for runner ingress endpoints. + > - Added authenticated Daytona preview ingress. +- feat(ui): project native runner turns into task chat (#12617) + > - Project supported native PRP v1 assistant, reasoning, tool, activity, usage, interaction, and result events. + > - Render a native runner turn only when both runtime mode and adapter type match. + > - Recognize the canonical `assistant_message` item kind and preserve final-reply precedence. +- feat(runner): integrate Codex native execution (#12616) + > - Add the Codex-only native session executor and persisted resumption path. + > - Add run-scoped semantic tool projection, authorization, receipts, and idempotency. + > - Add audited native cancellation with durable issue and coordinator binding. +- feat(runner): add SDK and developer tooling (#12608) + > - Add browser, React, standalone, live-session, and issue-thread SDK surfaces. + > - Add deterministic mock control-plane, scenario, conformance, replay, and evaluation tools. + > - Add bounded Codex, OpenCode, and ACPX development transports and fixtures. +- feat(runner): add Codex-native application integration (#12591) + > - Added native run/result/finalization/provider-trace persistence, shared validators, and idempotent migration/replay coverage. + > - Added guarded Codex-only runtime selection, authenticated PRP coordination, recovery, finalization, and interaction services. + > - Added run/company-bound tool-gateway authorization, credential redaction, SSRF protections, and replay-safe behavior. +- feat(apps): add Paperclip Cloud managed OAuth connector (#12600) + > - Add a `paperclip_cloud_connector` client with signed requests, exact profile and scope bindings, and X25519-sealed credential handling. + > - Add explicit self-hosted enrollment with owner-only instance key storage and exact HTTPS origins. + > - Route managed Google Workspace setup through Paperclip Cloud and preserve customer-created OAuth clients. +- feat(runner): activate qualified Claude ACPX runtime (#12590) + > - Generalized the ACPX backend, driver, runtime adapter, host, and sidecar for the qualified Claude profile. + > - Added Claude ACPX activation through its exact pinned package/model pair and isolated-settings patch. + > - Added provider-lifetime fencing for non-Codex qualified ACPX sessions. +- feat(runner): add qualified OpenCode runtime (#12588) + > - Added the qualified OpenCode app-server proxy and input queue. + > - Added collaboration-mode and provider-event normalization. + > - Added the OpenCode MCP bridge and native session backend. +- feat(runner): persist ACPX suspension checkpoints (#12425) + > - Add a versioned ACPX safe-suspension checkpoint contract with unknown fields rejected at every persisted level. + > - Bind each checkpoint to the run, normalized session, catalog revision, catalog digest, and exact provider identity. + > - Persist a checkpoint-specific strict identity that requires the pinned permission mode without narrowing the additive live sidecar identity wire shape. +- feat(runner): project durable ACPX events (#12424) + > - Add a validated durable ACPX event projection context bound to one run, normalized session, turn, and item. + > - Pass already normalized activity events through without reintroducing provider-native envelopes. + > - Project authorized tool calls into canonical semantic input receipts with exact correlation and content digests. +- feat(runner): suspend safe ACPX sessions (#12422) + > - Add a provider-state query for active pending tool, input, or permission requests. + > - Permit session suspension only when no turn or provider request is active. + > - Send a bounded `session.suspend` command with an operator-safe reason. +- feat(runner): resolve ACPX provider requests (#12421) + > - Resolve authorized semantic tool calls only for the active turn and exact pending operation. + > - Validate semantic results against the authorized response schema before transport. + > - Send a bounded generic provider error when a semantic operation fails without exposing internal error text or payloads. +- feat(runner): validate structured question responses (#12420) + > - Validate `paperclip.question_response.v1` against its versioned JSON Schema. + > - Bound serialized responses to 768 KiB before validation. + > - Require answer identifiers to match the exact persisted question set. +- feat(runner): drive ACPX provider turns (#12419) + > - Start one ACPX turn only after validating a bounded turn identifier, bounded message, and the session's immutable working directory. + > - Require `turn.start` to acknowledge the exact requested turn before mutating provider state. + > - Request interruption only for the active turn and require an affirmative cancellation acknowledgement. +- feat(runner): bootstrap ACPX provider sessions (#12418) + > - Add a package-local ACPX provider session configuration and lifecycle owner. + > - Reject non-UTF-8 runtime and working directories before spawning so JSON path serialization cannot panic. + > - Validate the sidecar launch contract, Codex-only agent, model, run and session identifiers, absolute directories, positive JSON-safe catalog revision, pinned permission mode, bounded instructions, and canonical authorized tool catalog before spawning. +- feat(runner): reduce ACPX provider state (#12417) + > - Add a package-local ACPX provider state reducer with one run binding and one active turn. + > - Decode every sidecar event through the existing scope-first payload boundary before state mutation. + > - Bound retained assistant text, pending semantic tool inputs, and pending runtime request values. +- feat(runner): normalize ACPX provider events (#12416) + > - Normalize validated ACPX text, reasoning, plan, status, tool, notice, and error updates into existing PRP activity families. + > - Keep reasoning contents private while preserving a reasoning activity boundary. + > - Map plan entries, usage, review-mode status, and tool lifecycle into bounded canonical payloads. +- feat(runner): validate ACPX event payloads (#12415) + > - Decode sidecar payloads only after run and turn scope validation passes. + > - Limit each decoded payload to 256 KiB. + > - Add typed payload variants for runtime events, permission requests, input requests, semantic tool calls, terminal events, process events, and diagnostics. +- feat(runner): bind ACPX event scope (#12414) + > - Add an `AcpxEventScope` for one run and at most one active turn. + > - Validate run and turn identifiers before they enter scope state. + > - Make repeated binding of the same turn safe. +- feat(runner): add ACPX sidecar transport (#12412) + > - Add a Rust client for the generated ACPX sidecar v2 contract. + > - Validate the executable path, launch arguments, request timeout, and shutdown grace before process start. + > - Require exact request identities and contiguous event sequence numbers. +- feat(runner): add Codex ACPX sidecar (#12410) + > - Publish the `paperclip-runner-acpx-sidecar` package binary and document its current boundary. + > - Add a versioned stdin/stdout sidecar that admits only the qualified Codex ACPX profile and exact initialized model. + > - Support atomic session open, run attachment, turn start and cancellation, tool and input resolution, session read and snapshot, safe suspension, close, and recovery identity checks. +- feat(runner): bridge Codex ACPX questions (#12408) + > - Enable ACPX form elicitation for the Codex runtime and pass its handler through the runtime host boundary. + > - Normalize ACPX forms to `paperclip.question_set.v1` and emit `paperclip.runtime_request.v2` events. + > - Validate `paperclip.question_response.v1` resolutions before conversion to ACP form responses. +- feat(runner): recover settled Codex ACPX sessions (#12407) + > - Add settled-session recovery to the Codex ACPX harness driver and advertise resume support for that bounded path. + > - Keep provider recovery on the same persisted ACPX session. Do not permit a replacement provider session. + > - Require persisted run, normalized session, provider, profile, workspace, permission, result, terminal, and recovery-policy identities to agree. +- feat(runner): wire the Codex ACPX backend (#12406) + > - Add an internal Codex ACPX native backend constructor. + > - Require provider kind `acpx` and agent `codex` at the provider-specific boundary. + > - Resolve the qualified Codex ACPX profile for the requested model. +- feat(runner): add Codex ACPX harness driver (#12405) + > - Add a Codex-only ACPX `HarnessDriver` and session implementation. + > - Advertise only implemented capabilities. Keep resume, steering, runtime request resolution, runtime request handoff, goals, and thread lineage unavailable. + > - Emit canonical PRP turn, transcript, tool execution, final reply, result, failure, interruption, and usage facts. +- feat(runner): bind semantic tools to ACPX sessions (#12404) + > - Start and own one authenticated semantic MCP bridge when a host receives semantic tool options. + > - Pass one ephemeral loopback MCP binding to the Codex ACPX adapter. + > - Keep the bridge token out of the persisted environment and ACPX session options. +- feat(runner): add bounded ACPX turn lifecycle (#12403) + > - Add a narrow ACPX turn input and result and event lifecycle to the admitted runtime port. + > - Map prompt turns to the exact persistent ACPX session handle. + > - Support abort signals without adding steering or attachments. +- feat(runner): add authenticated semantic MCP bridge (#12402) + > - Add a provider-neutral runner semantic MCP bridge bound only to IPv4 loopback. + > - Require constant-time bearer authentication before MCP operations. + > - Expose only the supplied public catalog plus fixed completion and blocked-result tools. +- feat(runner): adapt the pinned Codex ACPX runtime (#12401) + > - Add a Codex-only adapter from the pinned ACPX library to the admitted runtime port. + > - Create the ACPX store inside the private runtime state directory. + > - Open one persistent session with the qualified model and bounded system instructions. +- feat(runner): pin the Codex ACPX runtime (#12400) + > - Pin `acpx` to `0.13.1` and the Codex ACP server to `1.6.2` in the runner package. + > - Register both patches in the pnpm 9 root configuration and newer-pnpm workspace configuration. + > - Preserve the existing embedded-Postgres and ACPX 0.12 patch entries used by other packages. +- feat(runner): compose ACPX runtime admission (#12399) + > - Add a minimal ACP runtime port for identity, status, model selection, and bounded shutdown. + > - Derive the qualified profile and canonical recovery binding before any provider startup. + > - Reject expected-identity drift and irrelevant managed-Codex inputs before opening the provider. +- feat(runner): stage managed Codex credentials (#12398) + > - Add one-use managed Codex credential leases for API-key, inline-JSON, and explicit managed-file modes. + > - Reject missing and ambiguous source combinations. + > - Require absolute external managed-file paths, private ownership and permissions on POSIX, bounded documents, no-follow opens, and stable file identity during reads. +- feat(runner): isolate ACPX runtime state (#12397) + > - Create a normalized session root beneath the private `acpx` runtime namespace. + > - Create isolated home, configuration, data, cache, state, and agent-specific directories with mode `0700`. + > - Reject symbolic links, non-directory paths, namespace escapes, and non-normalized roots. +- feat(runner): bind ACPX recovery identity (#12395) + > - Resolve real workspace and runtime-directory paths and reject filesystem roots or non-directories. + > - Derive collision-resistant runtime roots and provider session keys. + > - Bind the session key to workspace, complete qualified profile, model, protocol, agent, and permission mode. +- feat(runner): verify ACPX installations (#12393) + > - Verify exact server and optional runtime package versions from bounded metadata. + > - Require one supported relative Node executable and reject ambiguous or package-escaping paths. + > - Canonicalize the command directory and open final components without following symbolic links. +- feat(runner): verify ACPX effective models (#12392) + > - Require ACP model status before accepting a qualified runtime. + > - Select the exact canonical model when the session reports a stale default. + > - Reapply canonical selection when a qualified profile uses a distinct ACP selector. +- feat(runner): bind ACPX permission policy (#12391) + > - Map each ACPX permission mode to a closed runtime policy. + > - Decide local allow, reject, or coordinator delegation outcomes. + > - Auto-approve only runner-owned semantic MCP calls identified by structural metadata. +- feat(runner): declare ACPX driver profile (#12390) + > - Add the ACPX driver descriptor and native runtime-context capability declaration. + > - Add an agent-specific typed event capability matrix. + > - Add strict config validation for agent, exact qualified model, and permission mode. +- feat(runner): sequence ACPX sidecar input (#12389) + > - Add a serial asynchronous input queue that remains usable after operation and diagnostic failures. + > - Add ACPX-specific input sequencing around the shared queue. + > - Preserve the first `initialize` or `session.open` failure as the bootstrap cause. +- feat(runner): normalize ACP form questions (#12388) + > - Convert bounded ACP string, enum, multi-select, Boolean, number, and integer fields to `paperclip.question_set.v1`. + > - Validate every answer with the existing provider-neutral response parser before conversion. + > - Convert validated answers back to typed ACP form content. +- feat(runner): bind ACPX profile boundary (#12387) + > - Add a closed profile table for the qualified Pi, Claude, and Codex ACP servers. + > - Require the exact qualified model and return an isolated profile value to callers. + > - Add an agent-specific environment allowlist with entry and aggregate size limits. +- feat(runner): define ACPX sidecar contract (#12386) + > - Add the internal ACPX sidecar v2 JSON Schema outside the public PRP v1 schema catalog. + > - Generate one TypeScript inventory and one Rust inventory from that schema. + > - Add generate and check hooks to the existing runner protocol-type workflow. +- feat(runner): authorize server Codex tools (#12385) + > - Add a deterministic semantic-definition to runner-authorization projection. + > - Match the Rust canonical digest with a shared test vector. + > - Include the server coordinator projection in the native Codex `run.prepare` command. +- feat(runner): durably reconcile Codex tools (#12384) + > - Persist the authorized tool catalog with the Codex provider state. + > - Emit correlated and redacted semantic input, reconciliation, and result events. + > - Reconcile exact pending and completed calls after a provider restart. +- feat(runner): bridge Codex dynamic tools (#12382) + > - Add a Codex dynamic-tool projection for explicit authorized tool sets. + > - Advertise the same tool set on new and resumed provider threads. + > - Correlate bounded Codex tool calls and Paperclip semantic results. +- feat(runner): add durable semantic tool bridge (#12378) + > - Added the versioned authorized-tool, pending-call, and result contracts. + > - Added canonical SHA-256 catalog binding and drift rejection. + > - Added JSON Schema compilation and input and response validation. +- feat(runner): isolate Codex runtime context (#12376) + > - Added the native MCP binding contract and strict validation. + > - Added isolated Codex home materialization with shell snapshots disabled. + > - Added assigned-skill staging with lexical containment and two-pass symlink checks. +- feat(runner): add Codex native backend (#12374) + > - Added the Codex native backend constructor. + > - Added the Codex-first native backend factory. + > - Preserved the execution contract, runtime instructions, plan constraints, dynamic tools, transport injection, and durable identity requirements. +- feat(runner): add Codex session driver (#12371) + > - Added the Codex app-server harness driver and session lifecycle. + > - Added controller-bound semantic completion and terminal handling. + > - Added runtime requests, structured questions, goals, lineage, usage, steering, interruption, and recovery. +- feat(runner): verify workspace file references (#12368) + > - Added stable workspace file-reference records. + > - Added local Markdown link extraction and path normalization. + > - Added canonical-path and symlink-escape checks. +- feat(runner): normalize Codex thread state (#12367) + > - Added normalized Codex thread goals and lineage. + > - Added run- and thread-bound notification filtering. + > - Added safe workspace-relative path and stat projection. +- feat(runner): bound Codex workspace values (#12366) + > - Added assigned-workspace validation. + > - Added host home and Codex home overlap checks. + > - Added retained payload bounds. +- feat(runner): normalize Codex structured questions (#12365) + > - Added request-kind detection for approval, input, and elicitation requests. + > - Added requestUserInput normalization. + > - Added JSON Schema elicitation normalization. +- feat(runner): isolate Codex security configuration (#12364) + > - Added deny-by-default filesystem rules. + > - Added separate execution and planning permission profiles. + > - Added network denial. +- feat(runner): parse bounded Codex turn diffs (#12363) + > - Added create, modify, delete, rename, mode-change, and binary parsing. + > - Added workspace-relative path validation. + > - Added file-count and per-file text bounds. +- feat(runner): add bounded Codex app-server transport (#12362) + > - Added bounded JSON-RPC request and notification queues. + > - Added malformed-message and oversized-line fail-closed behavior. + > - Added sanitized Codex environment construction. +- feat(runner): add authorized scenario tool runtime (#12361) + > - Added run-scoped scenario tool discovery. + > - Added claim, role, task-mode, and policy authorization. + > - Added input validation, redaction, and authorization records. +- feat(runner): complete the canonical action catalog (#12360) + > - Added 14 domain and administration action contracts. + > - Added the complete immutable 41-action catalog. + > - Added validation for live inputs and outputs. +- feat(runner): normalize provider event contracts (#12350) + > - Expand the PRP provider descriptor and canonical activity event families. + > - Add bounded Codex, OpenCode, and ACP event normalizers for plans, tools, research, delegation, artifacts, review, safety, waits, and notices. + > - Preserve strict schema validation and regenerate the checked-in schema bundle and manifest. +- feat(runner): project native runs into task threads (#12321) + > - Add the canonical structured-question validator and shared contract exports. + > - Materialize native input requests as existing task interactions. + > - Validate native answers and deliver them through the durable question-response receipt. +- feat(apps): refine Postman and Shopify setup (#12357) + > - Update Postman hosted MCP methods, capability choices, default selection, and bearer-token placement. + > - Add Shopify UCP commerce and Storefront compatibility methods with public-store prerequisites. + > - Inject the reviewed Shopify UCP agent profile at runtime and remove that managed field from user input schemas. +- feat(apps): add connection intent setup experience (#12347) + > - Add connection intent cards and setup flow integration. + > - Add browse, connection, app detail, and sidebar experience updates. + > - Preserve exact draft identity and access choices across resume and OAuth recovery. +- feat(connections): add managed external MCP connectors (#12346) + > - Add managed Google Workspace and external connector backends. + > - Add Vercel Connect support without storing provider bearer tokens. + > - Add replay-safe migration 0232 and its generated snapshot. +- feat(connections): add self-serve intent runtime (#12345) + > - Add connection intent types, validation, service logic, and routes. + > - Add agent runtime tools and CLI support for connection requests. + > - Add issue-thread interaction support for connection intents. +- feat(apps): expand the self-serve connection catalog (#12344) + > - Add and update provider definitions for the self-serve catalog. + > - Add Google Workspace connection methods and capability profiles. + > - Add catalog generation, ingestion, URL matching, and contract tests. +- feat(apps): add local connection brand assets (#12343) + > - Add local provider logos for the connection catalog. + > - Add light and dark asset selection where providers need it. + > - Add deterministic fallback behavior and UI tests. +- feat(apps): add Composio and Gmail connectors (#12342) + > - Add Composio parent and child connection support. + > - Add Gmail connection setup and governance. + > - Preserve credential paths and remove duplicate binding declarations. +- feat(apps): add connection grants and delegated identities (#12341) + > - Add company and user connection grants. + > - Add delegated identity and membership rules. + > - Synchronize database, shared, server, and UI contracts. +- feat(apps): improve gateway and workspace connection UX (#12340) + > - Improve remote tool gateway connection behavior. + > - Add clearer app setup, test, and recovery states. + > - Add focused server and UI tests for the new paths. +- feat(apps): add secure remote MCP and PostHog setup (#12339) + > - Add guarded remote MCP setup and credential handling. + > - Add PostHog OAuth and API key connection methods. + > - Add focused server, shared contract, and UI coverage. +- feat(server): add a task-drain admission hold to the instance API (#12485) + > - Add process-local task-drain state with lazy TTL expiry. + > - Add task-drain admission suppression to the shared heartbeat resolver. + > - Add instance routes to read, start, and stop a task drain. +- feat: add Grok device login to the sandbox login panel (#12469) + > - Rename the shared device-login modules to adapter-neutral names. + > - Scope the shared login lifecycle to a closed adapter set. + > - Return the device-login URL that the provider prints. +- feat(onboarding): sign in to an agent provider during onboarding (#12440) + > - Add `GET /api/companies/:companyId/adapters/:type/auth-signal` with company and permission checks. + > - Add shared auth-signal types and the UI query path. + > - Apply a stored Claude login by reference without reading its token. + +## Fixes + +- fix(runner): close two timing windows in the capability-live suspend path (#13143) + > - Attach the turn-timeout rejection handler inside `armTurnWaiter()` at promise creation. + > - Remove the redundant per-call-site guard in `sendMessage()`. + > - Use a uniform five-second provider-drain proof budget, capped by the outer preparation deadline. +- fix(build): give two orphaned test setup files a governing tsconfig (#13141) + > - Add `server/src/__tests__/tsconfig.json` for the server test setup directory. + > - Add `vitest.setup.ts` to the `include` array in `ui/tsconfig.json`. + > - Keep `server/tsconfig.json` unchanged, so the build graph does not change. +- fix: verify ACP Stop and preserve safe continuation (#13119) + > - Propagate Stop into embedded ACP and wait for bounded adapter cleanup and provider exit. Retain the actual ChildProcess object for forced termination on all platforms; never signal a recycled numeric PID. + > - Preserve interrupted checkpoints only for acknowledged, local, persistent sessions with settled reads or no tools. Keep writes, incomplete actions, and forced termination blocked. + > - Restore the same compatible provider session with the current run's environment. Reject fresh-session fallback for an interrupted checkpoint. +- fix(server): bundle the vendored paperclip-runner instead of hand-mirroring its deps (#13121) + > - **Revision note:** the first version of this PR replaced the `cp -R` vendor step with an esbuild bundle of the runner's entry points. Greptile's review correctly caught that this broke packaged ACPX/OpenCode provider startup: several runner modules resolve sibling build artifacts via `import.meta.url`-relative filesystem paths (not JS imports) at whatever depth their source file sits at, and bundling collapses/rearranges that layout. The current version keeps the file layout untouched and only adds verification. See the second commit's message for the full explanation. + > - `server/scripts/verify-runner-vendor-dependencies.mjs`: a new build step that runs esbuild with `write: false` (a pure module-graph scan -- nothing is written to disk) against the runner's two entry points server actually imports (`index.js`, `testing.js`), with `packages: "external"` so its metafile reports exactly which npm packages the code needs at runtime. It fails with a precise, actionable error if any of them isn't declared in `server/package.json`'s `dependencies`. This is deliberately more precise than "mirror every dependency the runner declares": running it against this repo's real manifests shows `packages/paperclip-runner/package.json` declares dependencies (`react-markdown`, the codex/opencode CLI packages, ...) that only its unrelated `./react` and `./browser` export subpaths use -- server never imports those, so a blanket mirror rule would demand dependencies server doesn't actually need. + > - `server/package.json`: added the new check into the `build` script (right after the runner is built, before the expensive `tsc`/copy steps, so it fails fast), and added `smol-toml` (`^1.4.2`, matching `packages/paperclip-runner/package.json`) to `dependencies` -- the actual missing piece from #13110. The vendor step (`cp -R ../packages/paperclip-runner/dist/. dist/vendor/paperclip-runner/`) is unchanged from before this PR. +- fix(ui): refine mobile task surfaces (#13122) + > - Made mobile task and inbox toolbars use the viewport width with square icon controls. + > - Widened task and inbox lists, reduced left padding, aligned compact timestamps with title baselines, and restored task hierarchy connectors. + > - Simplified the mobile task header so it shows the status, a truncated title, and the task ID at the right. +- fix(adapters): probe Git context in the remote workspace (#13116) + > - Use `remote.remoteCwd` for the remote Git-context probe. + > - Cover a missing controller directory in both credential modes. + > - Verify that SSH reads Git metadata from the remote workspace even when the caller directory exists. +- fix(codex): correct startup trust, history reads, and resume usage (#13110) + > - Classify the exact historical resume usage event before the generic stale-turn warning. + > - Persist cumulative usage baselines across recovery of the same run. + > - Use excludeTurns on resume and lightweight thread reads. +- fix(runner): keep streaming after task completion tools (#13108) + > - Remove the completion-tool interrupt timer. + > - Drain pending event persistence before selecting the visible response. + > - Keep task completion validation, provider errors, cancellation, waits, and goals. +- fix(ui): simplify provider notices and hide completion calls (#13109) + > - Hide paperclip_finish calls and results in task-feed adapters. + > - Preserve the raw events for run-log inspection. + > - Carry provider-notice text into the transcript. +- fix(adapters): prevent engine fallback and preserve usable runtime defaults (#13105) + > - Remove automatic engine fallback for Codex, Claude, Gemini, and Kimi. Check prerequisites for default and explicit ACP selections. + > - Return a configuration error with proof that provider work did not start. Stop automatic continuation retries for this error. + > - Enable Codex ACP workspace networking at the actual turn boundary. Upstream mode presets otherwise force it off even when config.toml enables it. Preserve explicit network denial and read-only mode. +- fix(ui): remove action buttons from agent list (#13101) + > - Removed AgentActionButtons from both agent list implementations, including filtered lists. + > - Removed the unused board-access query and trace permission calculation. + > - Kept built-in setup controls, status, and membership actions. +- fix(runner): preserve durable native session authority across recovery (#13092) + > - Preserve pending provider cleanup and semantic-result evidence across session close and restart. + > - Add an authenticated warm handoff with exact old and new identities, durable receipts, and completion acknowledgement. + > - Drain retained provider events under the cumulative acknowledgement fence. +- fix(connections): keep task context through Cloud enrollment and OAuth (#13098) + > - Open task enrollment in a reserved window, with a new-tab fallback. + > - Refresh server enrollment status and the provider catalog while keeping the task dialog and access choices. + > - Return the enrollment callback to the verified task when available. +- fix(runner): restore legacy Git access and independent networking (#13094) + > - Prefer healthy eligible grants and retry credential acquisition once for the same principal and account before starting an operation. + > - Preserve host Git configuration only when managed access is unconfigured on a standard-trust local or SSH target. + > - Project authentication mode and validated Git metadata into native runner boundaries; refresh resumed provider settings when modes change. +- fix(workspaces): preserve dependency provisioning failures (#13093) + > - Capture the failed install status inside the `else` branch. + > - Use the existing single retry for both frozen-lockfile mismatch errors. + > - Include patch contents in the dependency fingerprint. +- fix(ui): stabilize task loading and live feeds (#13095) + > - Keep the composer mounted while the initial conversation waits for comments, interactions, stored artifacts, and relevant run history. Show an inline retry state on failure. Retain visible content during later refreshes. + > - Report initial transcript readiness and errors per run. Bound native/log reads to 15 seconds, abort stalled requests, and let Retry start fresh. Commit native event pages independently and reuse unchanged transcript projections. + > - Keep logical message identity through optimistic acknowledgement and live response persistence. Preserve open and closed activity details. Remove repeated entry animations from historical content. +- fix: make task recovery durable and preserve current requests (#13075) + > - Keep ownership locked through dispatch handoff, then commit without awaiting adapter bootstrap or finalization. + > - Persist terminal decisions, ownership-safe lock release, and retryable delivery. + > - Share three total attempts across bootstrap, resume, and safe replacement. Use 30-second retry delays, 60-second control deadlines, and 15-second reconciliation. +- fix(runner): preserve provider identity and terminal failures (#13074) + > - Classify root, provider-confirmed descendant, stale, unrelated, and invalid provider events. + > - Keep tool requests bound to their original execution authority. + > - Preserve typed failures through transport, session, and durable control-plane cleanup. +- fix: make Codex sign-in and the environment test agree on the credential a run uses (#13064) + > - `packages/adapters/codex-local/src/server/adapter-auth-promotion.ts`: the promotion writes the company default home unconditionally. The shared `last_refresh` merge predicate scopes the write. It seeds an absent or unusable slot, refreshes a same-identity slot only with a strictly newer credential, and keeps a slot a different account or an API-key file holds. The atomic rename replaces a symlinked `auth.json` at the link itself. It never writes through into the host home. + > - `packages/adapters/codex-local/src/server/codex-home.ts`: the same-identity heal in `seedManagedCodexHome` is freshness-aware. A regular-file credential is swapped for the shared symlink only when the shared source is strictly fresher by `last_refresh`. Ties and unparseable timestamps keep the file, which matches the predicate's fail-closed direction. A genuine stale copy still heals as soon as the host credential rotates past it. + > - `packages/adapters/codex-local/src/server/test.ts`: the sandbox hello probe prepares and stages the same home a real run resolves. The identity-anchored cache vend runs first. A configured managed `CODEX_HOME` is seeded in place and staged. A genuine external override is staged as-is and never seeded or mutated. +- fix: repair runner configuration, macOS execution, and artifact galleries (#13062) + > - Remove the Codex-only conversion restriction. Preserve agent identity, instructions, directories, credentials, and compatible model settings. Reset incompatible sessions while retaining history. + > - Show ACPX Claude and native Codex as distinct provider choices. Remove ACPX Codex from advertised configuration. Normalize legacy configurations before fresh runs without rewriting historical run descriptors. + > - Select model catalogs and cache entries by provider. Support refresh and typed model IDs. Pass exact Claude IDs through session creation, model changes, and recovery. +- fix(claude): default unset models to Opus 5 (#13055) + > - Add one Claude model resolver with an Opus 5 fallback. + > - Use it for CLI execution, ACP startup, and CLI environment checks. + > - Align ACP startup environment with explicit model precedence. +- fix(adapter-utils): preserve legacy sandbox PATH with managed GitHub (#13051) + > - Read the remote target's effective PATH when no remote override is set. Do not copy an inherited controller PATH. + > - Prepend the managed launcher directory and retain the combined path in shell startup files. + > - Stop startup if path discovery fails. Frame the response so login banners cannot contaminate PATH. +- fix(ui): simplify GitHub repository access controls (#13047) + > - Remove the account dropdown, search input, filtering state, and unused imports. + > - Rename the GitHub configuration button to “Add More Repos on GitHub”. + > - Render every returned repository and simplify the empty-list message. +- fix(ui): restrict company navigation to accessible memberships (#13039) + > - Added `scope=accessible` to `GET /api/companies`, using the existing `hasCompanyAccess` predicate. + > - Changed the board navigation list to request that scope. Instance Access uses a separate unscoped, account-keyed directory so administrators can manage all companies. Membership edits refresh navigation. + > - Reject empty, unknown, and repeated scope values with 400. Directory loading errors offer a retry before access controls are shown. +- fix(heartbeat): block runs on a stuck sandbox plugin and re-enable errored bundled plugins at boot (#12957) + > - `server/src/services/heartbeat.ts` + > - `server/src/services/recovery/stranded-notice.ts`: `buildConfigurationIncompleteRecoveryNoticeSeed` takes the optional payload. For `sandbox_provider_plugin_not_ready` the body names the plugin and its status and gives status-specific guidance (`sandboxProviderPluginRemedy`): review and approve the upgraded capabilities before enabling for `upgrade_pending`, enable again for an operator `disabled`, enable or restart for `error`. Other reasons keep the secret/env-binding wording. Exports `SANDBOX_PROVIDER_PLUGIN_NOT_READY_REASON`. + > - `server/src/services/recovery/service.ts`: the recovery action's `nextAction` for this reason uses the same status-specific guidance instead of "bind the missing secret(s)". Small refactor: `readConfigurationIncompletePayload` backs the existing fingerprint reader. +- fix(db): reap idle pool connections, name the pool, and end it on shutdown (#12956) + > - `packages/db/src/client.ts` + > - `server/src/shutdown.ts` + > - `server/src/app.ts`: the app shutdown hook (`shutdownAppServices`) now stops the plugin job scheduler, whose tick queries the database, so a programmatic `shutdown()` leaves no timer running against the ended pool. +- fix(skills): reuse validated runtime revisions during preparation (#13042) + > - Split public file reading from reading an already loaded skill. Runtime listing refreshes inventory once. + > - Add a company-scoped revision cache with file manifests outside the delivered skill directory. Fingerprints omit cosmetic metadata. + > - Validate exact file inventory, sizes, and hashes before warm reuse. Reject traversal and symlinks. Stage complete builds and serialize atomic publication across processes. +- fix: resolve duplicate connections to the same GitHub account (#13022) + > - Compare stable GitHub account IDs when more than one eligible grant exists. Never deduplicate by login alone. + > - Prefer an available grant, then the newest authorization with a stable ID tie-breaker. Refresh and webhook timestamps do not change the selection. + > - Keep the selected credential and connection policy together. Do not combine permissions or fall back from a dedicated account to a personal account. +- fix(runner): initialize Rustls crypto provider (#13023) + > - Install the Rustls `ring` provider before runner setup reaches TLS initialization. + > - Accept an existing process-level provider as an initialized state. + > - Add a focused regression test for TLS builder creation and repeated initialization. +- fix(ui): debounce recent task ordering (#13007) + > - Keep stored activity timestamps at their newest observed value in both recording paths. + > - Debounce activity-driven row moves for one second. Keep additions and removals immediate. + > - Keep detail query observers in a fixed order and resolve task text by task ID. +- fix: share current CLI runtimes across sandbox adapters (#12994) + > - Prefer `/opt/paperclip-runner/bin`, then the user's local bin directory, then PATH. Existing metadata and version validation remains in force. + > - Qualify Codex 0.153.4, OpenCode 1.18.29, and Claude SDK 0.3.263 / CLI 2.1.263. Update binary digests, TypeScript/Rust checks, registry defaults, and the displayed OpenCode version together. + > - Share Codex and Claude's native executable with the ACP bridges through exact dependency overrides. Preserve the separately qualified ACP bridge implementations and their security patches. +- fix: preserve GitHub sign-in and show connected repository access (#12993) + > - Preserve managed sign-in intent when the gallery omits its profile. + > - Refresh the selected gallery entry on retry without resetting the audience. + > - Fetch all pages of GitHub installations and repositories. +- fix(evals): make the chat viewer the default published Evalbook (#12952) + > - Add a closed public chat projection. Require mock isolation evidence before publishing recorded text. Scrub private references and withhold tool payloads, reasoning and provider state. + > - Validate public HTML against the exact trusted viewer shell and asset bytes. Validate the public DTO and local links. Keep CSP restrictions on outbound requests and forms. + > - Make the workflow render both data projections with the canonical viewer. Pass a viewer-only artifact to the trusted publisher. Reject an old renderer pin before paid execution. +- fix(onboarding): drop the sign-in card's Cancel, and resume after Back (#12958) + > - The Cancel button and the `onCancel` prop are gone from `OnboardingLoginCard`, and the instruction row is no longer a `justify-between` pair. + > - Both onboarding chromes stop passing it. + > - The chain that stranded behind it is removed too: `handleCancel` in both panels, the `onCancel` prop on `AdapterLoginPanel`, and the wizard's `onCancel={unwindConnectStep}` wiring. Left in place, that prop would go on accepting a handler it never ran — a worse trap than the button. +- fix(connections): distinguish local setup from provider handoff (#12947) + > - Use "Continue" when Access opens another local OAuth setup step. + > - Keep "Continue to " and the external arrow when Access starts OAuth directly. + > - Test GitHub defaults, pre-enrollment setup, direct Notion OAuth, and dialog behavior. +- fix(runner): align direct eval provider setup with qualified runtimes (#12945) + > - Resolve native Codex from the pinned Codex ACP dependency, as the full-stack launcher does. + > - Select explicit unattended ACPX permissions only in the isolated direct eval harness. + > - Add a configurable bounded turn-admission wait. AgentCore direct evals use up to 125 seconds, capped by their turn budget. Other callers retain the current default waits. +- fix(connections): refresh expired pending enrollment links (#12943) + > - Always call the existing enrollment-start endpoint from Continue. + > - Retain the server's expiry, pending-enrollment reuse, and concurrency rules. + > - Test both expired and future-dated cached enrollment responses. +- fix(runner): repair direct live provider bootstrap (#12932) + > - Build the reusable direct-eval runtime with `pnpm deploy --prod`. + > - Resolve ACPX dependencies from the actual scoped-package layout of a self-contained pnpm deployment. + > - Align AgentCore configuration and qualification checks on `aws-agentcore-harness-context-v2`. +- fix(ui): show continuation actions in confirmation receipts (#12939) + > - Show `Selected “Continue work”` when a rejected confirmation has that custom action label. + > - Use the same action-aware text in the success toast. + > - Keep `Declined request` as the fallback for confirmations without a custom rejection label. +- fix(onboarding): keep the pasted code on screen, and make the auto-copy real (#12921) +- fix(runner): restore Vite 6 viewer compatibility (#12929) + > - Restore `@vitejs/plugin-react` 4.7.0 in the Vite 6 runner package. + > - Follow the repository policy: trusted PR CI regenerates and verifies the lockfile artifact, and the master refresh workflow commits the lock-only update after merge. + > - Build the Runner Evalbook viewer in pull request CI. +- fix(runner): scope live eval tokens to eval repo (#12911) + > - Scoped all four private-eval installation tokens to `paperclipai/paperclip-evals`. + > - Added a regression requiring that exact scope in every token block. +- fix(runner): persist warm Daytona workspaces across turns (#12904) + > - Persist versioned, atomic native workspace-sync descriptors and durable seeds in `PAPERCLIP_HOME`, without credentials or a database migration. + > - Classify fresh, warm, replacement, and same-run-recovery workspace preparation explicitly; ambiguous lease/root/digest evidence fails closed. + > - Finalize native workspace export/merge after semantic result proposal and before run completion, with idempotent replay that never submits a second provider turn. +- fix(connections): project GitHub identity into sandbox runners (#12907) + > - Wait for connector enrollment hydration, retain a hidden managed method only while enrollment is needed, and otherwise select an advertised customer fallback. + > - Add a single bounded GitHub credential-environment projection for `GH_TOKEN`, `GITHUB_TOKEN`, the process-only Git helper token, GitHub commit identity, and at most 32 controller-generated Git config entries. + > - Forward that projection through the durable controller, Codex app-server transport, and Rust provider child without placing token values in arguments or config. +- fix(runner): persist warm Daytona workspaces (#12901) + > - Added explicit `host_current`, `durable_seed`, and `adopt_remote` workspace preparation modes. + > - Added atomic, versioned native workspace descriptors and seed archives under `PAPERCLIP_HOME`. + > - Added real native sandbox export and three-way host merge before terminal result completion. +- fix(onboarding): hide the probe's diagnostics while the hire is in flight (#12902) +- fix(connections): honor identity after reconnect (#12897) + > - Apply an explicit Access identity when a fresh gallery setup revives an archived connection row. + > - Preserve the identity for interrupted drafts and explicit reconnects. + > - Do not carry credential material across an identity change. +- fix(cli): restore test-drive credential inputs (#12898) + > - Add the `--api-key ` test-drive option. + > - Keep `--api-key` and `--api-key-env` mutually exclusive. + > - Capture provider variables before in-process server startup changes the process environment. +- fix(server): stop mock leakage between interaction-route tests (#12807) + > - Replace the partial mock reset with `vi.resetAllMocks()`. + > - Reset `mockRunAttribution.value` before each test. + > - Keep the change within the interaction-route test file. +- fix(server): hoist the comment-cancel route test suite's module graph (#12877) + > - Register mocks once and load the route module graph once through `hoistModuleGraph`. + > - Remove the per-test module reset and re-import. + > - Add a `res.on("finish")` diagnostic listener for server error context. +- fix(connections): simplify GitHub access details (#12893) + > - Replaced the GitHub status card with repository and refresh rows. + > - Kept the token-backed all-repositories warning inside the repository row. + > - Added explicit labels for selected, all, mixed, and empty repository access. +- fix(connections): reuse one-time cloud enrollment (#12891) + > - Made `stage=setup` authoritative during initial route hydration and enrollment return. + > - Added a contained one-time enrollment screen with provider-specific copy. + > - Accepted a provider `authorizationUrl` from Paperclip Cloud only when it matches the exact GitHub or Google OAuth endpoint. +- fix(runner-e2e): bound completed cell teardown (#12890) + > - Reduce the Plan attempt limit from 20 to 8 minutes for local execution. + > - Reduce the Plan attempt limit from 35 to 12 minutes for Daytona execution. + > - Stop Playwright after it stays alive for 120 seconds after every result exists. +- fix(runner): restore multi-turn remote sessions (#12840) + > - Wait for the internally bounded remote runner close and checkpoint before the host returns. + > - Preserve the existing short cleanup bound for other providers. + > - Validate remote continuation lifecycle from a complete digest-verified backup when local runner state is absent. +- fix(runner): complete live hot restart adoption (#12852) + > - Store lazy runnerd process ownership after provider session creation, read, and resume. + > - Detach native PRP controller authority during coordinated hot shutdown. Keep the live provider turn running. + > - Restore the exact checkpointed provider session when bounded PRP identity events have been compacted. +- fix(runner): recover native sessions across restarts (#12845) + > - Added correlated hot-restart requests and version-compatible native handoff fields. + > - Added controller boot identity, process-start identity, controller generation, recovery state, request id, and bounded history to the native finalization ledger. + > - Added transactional recovery claims for live-runner reattach, dead-runner resume, and incomplete bootstrap. +- fix(ui): stabilize active-run steering queue (#12834) + > - Project queued comments into the steering well for native and legacy live runners. + > - Send native steering to the active run and use interrupt-and-follow-up for legacy runners. + > - Keep optimistic queue order stable across refreshes and roll back failed actions. +- fix(runner): stabilize local paid E2E recovery (#12836) + > - Prove a new post-restart browser document with an in-memory sentinel. + > - Tolerate only Playwright's navigation timeout before the exact UI and API checks run. + > - Honor `PAPERCLIP_VITE_CACHE_DIR` in the embedded Vite server. +- fix(server): honor proxy trust for forwarded host (#12832) + > - Read the configured Express `trust proxy` function before using forwarded host data. + > - Trust forwarded host data only when the immediate socket peer is trusted at hop zero. + > - Preserve ordinary same-origin behavior through the request `Host` fallback. +- fix(runner): repair paid provider startup paths (#12769) + > - Bundle the ACPX sidecar and OpenCode proxy as self-contained Node ESM entrypoints before hashing and verified descriptor launch. + > - Anchor ACPX dynamic provider package resolution at a controller-derived provider-pack root and keep that root out of the provider child environment. + > - Persist executor-returned startup errors as redacted durable failed command results while retaining indeterminate recovery for true process death. +- fix(ui): recover expired Cloud tenant sessions (#12826) + > - Added one tenant-session recovery coordinator for exact top-level Cloud error codes. + > - Reloaded the top-level document once and shared one pending promise across concurrent failures. + > - Applied recovery before normal error handling in the shared API client, auth API, and health API. +- fix(ui): remove the Account badge and version line from the account menu (#12818) + > - `ui/src/components/SidebarAccountMenu.tsx` and `SidebarAccountMenu.production.tsx`: remove the "Account"/"Local" badge and the full version block (source-build branch/commit links and the release-version fallback); drop the now-unused `serverGit`/`version` props, the sha-parsing helper, and the `Badge` import + > - `ui/src/components/Layout.tsx` and `Layout.production.tsx`: stop passing the removed props at all four call sites + > - `ui/src/components/SidebarAccountMenu.test.tsx`: delete the source-build sha test; the sign-out test now pins that the popover contains neither "Account" nor "Paperclip v" +- fix(recovery): exclude hidden issues from stranded recovery and continuation wakes (#5648) + > - `server/src/services/recovery/service.ts`: `isNull(issues.hiddenAt)` added to the `reconcileStrandedAssignedIssues` candidate query, so hidden issues never enter the stranded set. + > - `server/src/services/heartbeat.ts`: `!issue.hiddenAt` added to `issueNeedsImmediateRecovery`, so terminal-run cleanup releases a hidden issue instead of queuing a continuation. + > - `server/src/__tests__/heartbeat-process-recovery.test.ts`: one test per guard. A failed run on a hidden issue queues no recovery run, and a hidden stranded issue is left out of reconciliation. +- fix: guard listComments against non-UUID afterCommentId to prevent 500 errors (#8695) + > - `server/src/services/issues.ts` — added `if (!isUuidLike(afterCommentId)) return [];` guard in `listComments` before the DB anchor lookup, using the already-imported `isUuidLike` helper +- fix(ui): honor PAPERCLIP_HIDDEN_SETTINGS in the production switcher menu (#12788) + > - `SidebarCompanyMenu.production.tsx` imports `useHiddenSettings` + `hidesCompanyPage`, computes `showInvitePeople` exactly as the streamlined menu does, and renders the invite row only when it is true. + > - Tests: the production shell shows the shortcut by default and hides it when `company.invites` is hidden. + > - The streamlined menu is unchanged (it already honored the keys). +- fix(ui): polish core navigation and task layout (#12793) + > - Balanced the task-chat content gutter and moved its scrollbar to the properties-panel boundary. + > - Reworked Settings navigation to replace the main sidebar and use the shared primary-sidebar style. + > - Added a Back to app navigation item to Settings. +- fix(ui): drop the "Open invite" action from the invites section (#12787) + > - Removed the "Open invite" anchor button from `InvitesSection`. + > - Removed the now-unused `ExternalLink` icon import. + > - The component test now asserts the action is absent. +- fix(runner-e2e): prepare frozen Daytona plugin dependencies (#12791) + > - Install standalone Daytona dependencies with lifecycle scripts disabled. + > - Run the audited repo-local plugin SDK linker before provider secrets are exposed. + > - Build the bundled Daytona plugin and verify its runtime dependency plus both entrypoints. +- fix(ui): stamp the service worker with a per-build id so deploys reach parked tabs (#12725) + > - `ui/public/sw.js`: derive `CACHE_NAME` from a `__PAPERCLIP_BUILD_ID__` placeholder so the worker source varies per build. + > - `ui/src/lib/vite-sw-build-id.ts`: new Vite build plugin that rewrites the placeholder in the emitted `sw.js` with the entry chunk's content hash (stable when the app is unchanged, new when it changes). Throws if the placeholder is missing, so the worker can never silently stop rotating. + > - `ui/vite.config.ts`: register the plugin. +- fix(server): validate project goal ids exist and belong to the company (#12779) + > - `assertGoalsBelongToCompany` in the project service: one query for the resolved ids scoped to the company; unknown ids produce `unprocessable` (422) with the ids in the message and details + > - called on create (before the project row insert, so no partial writes) and on update (scoped to the existing project's company); both `goalIds` and the legacy `goalId` field flow through the same resolution + > - new embedded-Postgres test file: valid link, nonexistent id on create with no partial insert, legacy field, another company's goal on create, and a foreign-goal update that leaves existing links unchanged +- fix(server): retry cloud-tenant auth sync once on a dropped DB connection (#12773) + > - `resolveCloudTenantActor` now delegates to the (unchanged) resolution body through `retryOnTransientDbConnectionError`, which retries exactly once on a transient closed-connection failure + > - `isTransientDbConnectionError` walks the error `cause` chain (drizzle wraps the driver error) for the postgres.js codes `CONNECTION_CLOSED`, `CONNECTION_ENDED`, `CONNECTION_DESTROYED`; both helpers are exported for tests + > - New unit test file `cloud-tenant-transient-db-retry.test.ts`: detection matrix (including a `23505` staying non-transient), retry-once-then-succeed, no-retry on non-transient, propagate-on-second-failure +- fix(security): harden privileged server boundaries (#12776) + > - Redact generic secret `value` and `token` fields recursively in structured logs. + > - Classify exact and separator-suffixed `KEY` environment names as secrets in company exports. + > - Limit restricted self-identity responses and protect company run, log, and secret catalog APIs. +- fix(agents): redact plaintext env values in agent read and mutation responses (#9860) + > - `server/src/redaction.ts`: adds `redactAgentAdapterConfig`, which rewrites every bare-string or `{ type: "plain", value }` env binding to `{ type: "plain", value: "***REDACTED***" }` and passes `secret_ref` / `user_secret_ref` bindings through unchanged. Reuses the existing `REDACTED_EVENT_VALUE` and `isSecretRefBinding` / `isUserSecretRefBinding` / `isPlainBinding` helpers — no new dependencies. + > - `server/src/redaction.ts`: `env` is destructured out and sanitized only by `redactAgentEnvBinding`, while the remaining adapter keys go through `redactEventPayload`. Previously the already-redacted `env` was passed back through `sanitizeRecord`, so each binding was processed twice — safe only because the sentinel is a fixed point of that second pass. The two paths are now disjoint, making the invariant structural rather than coincidental. + > - `server/src/routes/agents.ts`: `buildAgentDetail` applies `redactAgentAdapterConfig` before serialization, so `GET /api/agents/{id}` and `GET /api/agents/me` both redact at the response layer. Restricted views inherit the same protection. +- fix(runner): materialize pinned OpenCode binary (#12782) + > - Materialize only `opencode-linux-x64-baseline@1.18.17` into the matching `opencode-ai@1.18.17` package. + > - Verify package identity, version, regular-file type, SHA-256 equality, executable permissions, and runtime `--version`. + > - Invoke the helper for local OpenCode and breadth cells and for remote provider-pack assembly. +- fix(server): stop paging Sentry for supervised boot races in managed cloud (#12772) + > - New `server/src/startup-refusals.ts`: a `StartupRefusalError` class for refusals whose remedy belongs to the deployment supervisor, `migrationRefusalError()` to classify a pending-migrations refusal (zero applied migrations = never migrated = supervised transient; any applied history = drift = plain always-reported `Error`), and `shouldReportStartupFailure()` for the capture decision. + > - `server/src/index.ts`: the pending-migrations refusal uses the classifier; the missing-`DATABASE_URL` refusal under the authenticated-public contract becomes a `StartupRefusalError` (the malformed-URL refusal stays a plain `Error`); the startup crash handler consults `shouldReportStartupFailure()` before `captureException`. Logging and the nonzero exit are unchanged. + > - New `server/src/__tests__/startup-refusals.test.ts` covering the classification and decision matrix, including the unchanged self-hosted paths. +- fix(paperclip-runner): emit turn.accepted before any terminal turn event (#12752) + > - Add session state that tracks a pending `turn/start` operation. + > - Resolve the state when `turn/start` succeeds or fails. + > - Wait for that state before the terminal notification handler emits its event. +- fix(runner): retain aborted admission cleanup (#12755) + > - Retain each unfinished abortable admission stage in the global runtime-host cleanup set. + > - Notify the embedding lifecycle when an aborted stage needs deferred cleanup. + > - Make test teardown abort and await all active opening and cleanup promises before directory removal. +- fix(onboarding): preserve draft through company refetch (#12735) + > - Keep the onboarding wizard mounted after its first successful draft ownership check. + > - Keep a failed ownership check retryable, so a later verified fetch restores the saved draft. + > - Add component, source E2E, and published-canary coverage for the retained-draft refetch case. +- fix(runner): restore local session and task integrity (#12721) + > - Rotates PRP control-plane, outbox, ticket, lease, command, receipt, and sequence authority for each heartbeat while carrying forward only a validated provider-session identity. + > - Reads `control-plane-state.json`, validates both durable schemas and lifecycle values, resumes coherent current runs, archives qualified settled authority, and quarantines malformed or mismatched scoped state without moving ambiguous live legacy state. + > - Preserves Codex provider phase and stable item identities so commentary remains progress and only `final_answer` becomes final. +- fix(runner): restore task runtime parity (#12685) + > - Restored the queued-comment steering route for active native sessions. + > - Added durable and queue-bound steering acknowledgements for safe retries. + > - Restored runner instruction bundle support. +- fix: limit plan-to-auto transition to plan confirmation (#12695) + > - Require a full `request_confirmation` interaction before plan acceptance starts automatic work. + > - Add service tests for acceptance, rejection, stale interaction kinds, and unchanged standard-mode behavior. + > - Check the route activity log for the planning-to-standard mode change. +- fix(runner): stop capability live-session tests from failing on unhandled turn-timeout rejections (#12676) + > - Add a helper that captures a turn rejection before any await step. + > - Update three live-session test sites to assert the captured rejection value. + > - Add a helper test that waits past the turn timeout before it asserts. +- fix(runner): accept the indeterminate command result after a runner restart (#12646) + > - `DurablePrpControlPlane.#commandResult` accepts `indeterminate` as a + > - The persisted-state validation accepts `indeterminate`, so a control plane + > - `DurableRecoveryCoreCommand.status` includes `indeterminate` in both +- fix(runner): keep agents running when app connections expire (#12670) + > - Filter unavailable assigned app connections from the immutable native runtime MCP snapshot. + > - Keep healthy assigned connections and their tools in the snapshot. + > - Replace the fatal native MCP availability check with an optional stream warning callback. +- fix(onboarding): restore browser launch and gate canaries (#12667) + > - Open the browser once for interactive foreground onboarding. + > - Preserve explicit browser opt-outs and restore the prior environment value after startup. + > - Accept a same-company context update after organization creation and reject a different-company takeover with an explicit error. +- fix(workspaces): enable UI hot reload by default (#12612) + > - Set `PAPERCLIP_UI_DEV_MIDDLEWARE=true` for managed `paperclip-dev` services when the service does not set a value. + > - Keep explicit service values, including `false`. + > - Add a regression test and document the default and the opt-out. +- fix(runner): harden dormant provider boundaries (#12654) + > - Change dormant OpenCode and ACPX permission defaults to interactive modes. + > - Reject prototype property names as provider identifiers. + > - Default dormant ACPX input to the qualified Codex agent profile. +- fix(apps): complete managed Google Workspace rollout (#12619) + > - Added one table-driven invariant for all 16 Google Workspace profiles. + > - Verified each profile against its app slug, MCP URL, exact scopes, capability, ownership, grant kind, risk tier, and write-tool allowlist. + > - Kept the Google Chat write profile least-privilege because its only enabled write tool is `send_message`. +- fix(connector): isolate broker enrollment targets (#12609) + > - Resolve the connector broker and environment as one target. + > - Rotate a non-active identity when an administrator explicitly starts enrollment for a different target. + > - Reject active target changes and broker/environment mismatches. +- fix(release): skip lifecycle scripts for bundle staging (#12585) + > - Add `--ignore-scripts` to npm pack for prepared bundled packages. + > - Add `--ignore-scripts` to both normal and no-provenance npm publish attempts for prepared bundled packages. + > - Update release helper tests to require this behavior. +- fix(release): omit dev dependencies from bundle staging (#12584) + > - Remove `devDependencies` from the temporary manifest used for bundled package installation. + > - Keep the final publish manifest unchanged. + > - Add unit and staging regression checks for the unpublished development dependency case. +- fix(release): bundle vendored runner ACPX runtime (#12582) + > - Added `acpx@0.13.1` as a bundled server runtime dependency. + > - Added a version-specific patch check for the ACPX versions used by the server and adapter utilities. + > - Added release-package coverage for the server ACPX bundle. +- fix(ui): prevent false agent instruction saves (#12502) + > - Ignore rich Markdown editor normalization events until keyboard, pointer, paste, input, drop, or before-input interaction occurs. + > - Reset the interaction guard when the selected file, agent, or persisted content changes. + > - Clear the parent dirty, saving, save, and cancel state when the Instructions tab unmounts. +- fix(server): load the mocked module graph once in the closed-workspace issue route suite (#12470) + > - Load the mocked service graph once per file with `hoistModuleGraph`. + > - Remove the per-test module reset and unmock cycle. + > - Assert exact success statuses for the three affected responses. +- fix(cli): make embedded-Postgres tests survive runner contention (#12466) + > - Export `EMBEDDED_POSTGRES_TEST_TIMEOUT_MS` from the embedded-Postgres test helper. + > - Apply the shared timeout to every test defined by `itEmbeddedPostgres`. + > - Replace the five hand-written timeout values in `worktree.test.ts`. +- fix(ci): regenerate stale stacked lockfiles (#12461) + > - Regenerate the lockfile from every checked-out merge tree. + > - Compare the generated lockfile with the checked-in copy before upload. + > - Download the artifact only when the policy job reports that it uploaded one. +- fix(adapter-utils): bound the ACP startup handshake and fence the abandoned session promise (#12454) + > - Bound `runtime.ensureSession()` with a startup deadline and a duplex transport loss check. + > - Added terminal error codes for handshake timeout and transport loss. + > - Fenced late session resolution and rejection so the settled run has one owner. +- fix(ci): validate stacked PR merge refs (#12457) + > - Fetch and validate the current base branch ref. + > - Require the event base snapshot to remain an ancestor of that ref. + > - Validate direct and synthetic base merge parent shapes. +- fix(ci): route trusted stacked PRs to AWS (#12455) + > - Replace the master-only route check with a nonempty base-ref check. Keep the existing base-repository and live-state checks. +- fix(ci): make runner image tests deterministic (#12452) + > - Verify stale service ownership through the existing process-group ownership helper. + > - Allow normal issue reads in the watchdog reassignment fixture. + > - Assert that the watchdog reassignment reaches and denies the `tasks:assign` guard. +- fix(adapter-utils): allow process sessions without birthtime (#12451) + > - Allow a zero reported creation time for process-session directories. + > - Keep the probe that rejects a creation time copied from change time. + > - Add a regression test that launches and stops a session with zero birth time. +- fix(ci): validate the PR base snapshot (#12449) + > - validate the event base ref/SHA against the live PR state instead of requiring the moving `master` branch tip to remain unchanged while a hosted gate queues + > - retain exact event/live merge parent and tree validation, plus author/sender/rerun checks +- fix(ci): validate the workflow merge ref (#12447) + > - use `${{ github.sha }}` as the event merge commit validated by the trusted gate + > - retain exact base/head parent and identical-tree comparison against the current live merge ref +- fix(ci): emit one runner route (#12444) + > - emit exactly one `runner` job output from the trusted gate + > - write `ubuntu-latest` only inside fail-closed paths +- fix(ci): validate equivalent PR merge refs (#12441) + > - validate the live master ref and event base SHA before AWS routing + > - accept GitHub synthetic merge commits only when the event and live commits have the exact expected base/head parents and identical tree + +## Other changes + +- refactor(server): move the queued-comment queue mutations into the wake-queue module (#13145) + > - Move queued-comment edit, reorder, and discard operations into the wake-queue module. + > - Add company predicates to seven queue writes. + > - Use the shared queue contract type for mutation responses. +- ci: split runner verification from build (#13142) + > - Added a dedicated `Verify Paperclip Runner` job to the trusted PR workflow. + > - Added a dedicated `Verify Paperclip Runner` job to the release verification workflow. + > - Kept the Build jobs independent and retained their existing build commands. +- refactor(server): move the admission half of the deferred wake state machine into the wake-queue module (#13136) + > - Move deferred wake admission policy into `server/src/modules/wake-queue`. + > - Add module ports and a PostgreSQL adapter for the admission reads and writes. + > - Keep the existing wake outcomes and stored reason strings. +- refactor(server): simplify the wake-queue module (#13139) + > - Remove the unused database port method and carry the blocked release notice kind as a typed field. + > - Move four pre-drain decisions into pure policy functions with table-driven tests. + > - Resolve the responsible user once in the application layer. +- refactor(server): move the release half of the deferred wake state machine into a wake-queue module (#13132) + > - Move the release half of deferred issue execution from `heartbeat.ts` into `server/src/modules/wake-queue/`. + > - Add pure policy decisions with table-driven tests. + > - Claim a wake before the reopen write and advance to the next wake when the claim fails. +- chore(lockfile): refresh pnpm-lock.yaml (#13128) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- ci(docker): build each architecture on a native runner instead of QEMU (#12821) + > - **Per-arch BuildKit cache refs** (`:buildcache-amd64` / `:buildcache-arm64`). Separate runners sharing one ref would overwrite each other on every build. + > - **The PID-1 orphan-reaping check moves to the merge job**, since that is where a tagged, pullable image first exists. It still runs against the pushed image rather than a local build, for the same reason as before. +- ci: raise the multi-arch Docker publish timeout to 120 minutes (#13114) + > - Raise `timeout-minutes` on the `build-and-push` job from 60 to 120, with a comment that explains why. The amd64-only `build-and-push-cloud` job keeps its 60 minute cap. +- chore(lockfile): refresh pnpm-lock.yaml (#13106) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- test(heartbeat): pin 8 uncovered branches of the deferred issue-execution wake state machine (#13103) + > - Add tests for missing and cross-company deferred agents. + > - Add tests for pause-hold promotion and cancellation. + > - Add a test for atomic rollback when the responsible user cannot resolve. +- chore(lockfile): refresh pnpm-lock.yaml (#13061) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- ci: dispatch a Docker build for every canary tag (#12950) + > - `.github/workflows/release.yml`, `publish_canary` job: + > - No `docker.yml` changes: it already accepts `workflow_dispatch` for exactly this pattern. + > - No dry-run guard needed: `publish_canary` runs only on `push` events, so the `dry_run` dispatch input cannot reach it. +- Add end-to-end session goals to Paperclip Runner +- refactor(server): move scheduled-retry and queued-run dispatch into a run-dispatch module (#12920) + > - Move scheduled-retry promotion and queued-run staleness rules into pure functions. + > - Add table-driven unit tests for each policy branch. + > - Move promotion and cancellation writes into semantic transactions. +- Build isolated preview artifacts for exact-source deployments (#13041) + > - Add the preview channel, request correlation, artifact checks, and result artifact. + > - Compile source packages in a separate job from the npm publisher. The publisher + > - Publish only SHA cloud image tags. Preserve release aliases. Use full-SHA tags and no shared build cache. +- chore(lockfile): refresh pnpm-lock.yaml (#12999) + > - Update only `pnpm-lock.yaml` through the existing Refresh Lockfile workflow. + > - Record the provider versions, overrides, patch hashes, and dependency integrity hashes from #12994. +- chore(lockfile): refresh pnpm-lock.yaml (#12931) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- test(e2e): link runner campaign summaries (#12927) + > - Add a safe URL builder for public campaign, workflow, and artifact links. + > - Add a `View results` section to the GitHub Actions campaign summary. + > - Link each summary table cell to its exact section in the immutable campaign report. +- refactor(server): extract the active-run output watchdog into a feature module (#12853) + > - Add the `server/src/modules/active-run-watchdog/` feature module with domain, application, and adapter layers. + > - Move watchdog policy, use cases, Postgres access, and local process control into the module. + > - Keep the recovery service public methods and delegate them to the module. +- test(server): remove a concurrent-import race in the approval routes suite (#12876) + > - Reused the existing `hoistModuleGraph` helper for the approval route modules. + > - Loaded the route modules once in sequence instead of in one concurrent import. + > - Kept per-test mock behavior, Express app setup, database doubles, test names, and assertions unchanged. +- test(ui): flush passive effects with React act in CompanySkills tests (#12878) + > - Delegate the local test helper to React act. + > - Remove four setTimeout(0) hops that no longer provide synchronization. + > - Keep all 29 tests and all product code unchanged. +- ci: reuse trusted cache for Daytona images (#12862) + > - Read a registry-backed BuildKit cache for Daytona image content misses. + > - Export the cache only when the resolved target ref is the default branch. + > - Keep provider credentials outside the image build and cache. +- refactor(onboarding): reconcile the arc column's width comment with its width (#12875) + > - Replaced both comments with one. It states the current decision — 40px sides, a 480px column inside the 560px frame, the measure the connect sequence is drawn to, shared by the arc so no step sits narrower than the one after it. + > - Kept the earlier objection rather than deleting it, and marked it **not retested** since the width moved back. It is the one piece of history a future reader needs, because it is an argument against the current value. + > - Added where the fix belongs if it does resurface: step 1 and step 3 inherited this width without changing, and narrowing the shell again would put the connect step out of step with its design — so that would be a content change in those steps, not a shell change here. +- ci: activate the Docker context integrity gate for PRs (#12860) + > - `.github/workflows/pr.yml`: the `pr-trusted.yml` pin moves to the #12858 merge commit. One line. +- ci: keep traceability regression tests in the Docker build context (#12858) + > - `.dockerignore`: re-include `packages/paperclip-runner/src/**/*.test.ts` and `.tsx` — the traceability spec references only files under `src`, so the remaining test exclusions stay. + > - `.github/docker-context-checks.Dockerfile`: new spec-driven existence walk that replicates the traceability check's own access() loop against the exact build context. The path list comes from the spec at probe time, so a future spec change is covered automatically; the check itself still runs only inside the real image build, where `dist/` exists. +- ci: keep the Docker build context complete and guard it on every PR (#12855) + > - `.dockerignore`: narrow exceptions (last match wins) re-include the committed drift-check outputs (`!packages/paperclip-runner/generated/**`) and the inventory check's documentation input (`!packages/paperclip-runner/docs/capability-contract.md`). Every other exclusion from #12769 stays: no crate declares an explicit `[[test]]` target, so cargo builds without the `tests` directories, and the image build chain never runs the excluded smoke scripts. + > - `.github/docker-context-checks.Dockerfile` (new): a small probe that COPYs the real build context — identical `.dockerignore` semantics — and runs the dependency-independent drift checks inside it (`generate-capability-contract.mjs --check`, `check-capability-inventory.mjs`). ajv installs in an isolated directory for schema validation only; codegen checks such as `generate-protocol-schema-module` stay out because their emitted bytes vary with the ajv release and would raise false drift alarms outside the locked dependency tree. + > - `.github/workflows/pr-trusted.yml`: new `docker_context_integrity` job builds the probe on every full-CI pull request, and the existing `verify` aggregate now requires its result, so the guard gates merges through the same required check as the other lanes. +- perf(e2e): narrow Daytona image cache inputs (#12850) + > - Replace broad runner and eval package copies with explicit build inputs. + > - Advance the Daytona image content schema to version 5. + > - Hash the matching explicit TypeScript, protocol, script, manifest, lockfile, and Rust closure. +- chore(lockfile): refresh pnpm-lock.yaml (#12828) + > - Update the Codex ACP patch hash in `patchedDependencies`. + > - Update the two importer references to the same patch hash. + > - Update the matching dependency snapshot key. +- test(runner): harden native OpenCode paid fixtures (#12833) + > - Require `paperclip_finish` to be the only tool call in the native ask fixture. + > - Forbid `report_progress` and other tool calls in that fixture. + > - Wait for navigation commit after a server restart. +- ci: harden paid runner browser and lock repair (#12829) + > - install Playwright FFmpeg only on the AWS/system-Chrome path + > - retry the small helper installation up to three times before provider secrets are exposed + > - keep the GitHub-hosted Chromium fallback unchanged +- chore(docker): pass PAPERCLIP_ALLOWED_HOSTNAMES through to quickstart (#6846) + > - `docker/docker-compose.quickstart.yml`: forward `PAPERCLIP_ALLOWED_HOSTNAMES` from the host environment with an empty default, matching the existing pattern used for `PAPERCLIP_PUBLIC_URL`, `OPENAI_API_KEY`, etc. +- ci: activate Node-first pnpm setup for PRs (#12810) + > - Pin ordinary PR CI to trusted workflow revision `a0a78ee60946a5f79f85b2bd0584fc766fae43bb`. + > - Assert that the reusable workflow call is canonical, unique, and SHA-pinned to that audited revision. +- ci: bootstrap Node before pnpm setup (#12808) + > - install Node 24 before every trusted `pnpm/action-setup` invocation + > - preserve the existing pnpm-store cache setup, pinned actions, telemetry suppression, conditions, and secret boundaries + > - enforce ordering, modern Node, condition parity, and cache counts in the workflow security contract +- ci(runner): stamp paid target provenance (#12805) + > - emit the canonical authorized target ref alongside the immutable target SHA + > - pass those coordinates to paid cells and the trusted report + > - name shared build/provider artifacts with the target SHA rather than workflow SHA +- test(plugin-worker): remove the wall-clock race from the duplex buffered-replay tests (#12799) + > - Replace the fixed sleep in both buffered-replay tests with an exit-frame barrier. + > - Write the three data frames and the exit frame in one worker output write. + > - Wait for the session to settle before the tests attach listeners. +- ci(runner): skip bootstrap registry telemetry (#12797) + > - disable npm audit, funding, and update-notifier telemetry narrowly on all seven pinned setup steps in each of the trusted PR and full-stack workflows + > - add a workflow security contract proving every setup invocation remains covered and the overrides do not leak elsewhere +- chore(deps): bump motion from 12.43.0 to 13.1.1 (#12255) + > Bumps [motion](https://github.com/motiondivision/motion) from 12.43.0 to 13.1.1. + >
+- chore(deps): bump dompurify from 3.4.13 to 3.4.14 (#12266) + > Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.13 to 3.4.14. + >
+- chore(deps-dev): bump @types/react-dom from 19.2.4 to 19.2.5 (#12253) + > Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 19.2.4 to 19.2.5. + >
+- ci(runner): inspect Daytona image metadata remotely (#12795) + > - inspect the signed immutable Daytona image config through Buildx after GHCR logout + > - preserve digest, source revision, content ID, platform, user, and provider-pack assertions + > - extend the workflow contract test for the metadata-only path +- chore(deps): bump yjs from 13.6.29 to 13.6.32 (#12256) + > Bumps [yjs](https://github.com/yjs/yjs) from 13.6.29 to 13.6.32. + >
+- chore(deps): bump @aws-sdk/client-s3 from 3.1120.0 to 3.1122.0 (#12261) + > Bumps [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) from 3.1120.0 to 3.1122.0. + >
+- chore(deps-dev): bump vitest from 4.1.10 to 4.1.11 (#12262) + > Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.1.10 to 4.1.11. + >
+- chore(deps): bump react-i18next from 17.0.11 to 17.0.12 (#12263) + > Bumps [react-i18next](https://github.com/i18next/react-i18next) from 17.0.11 to 17.0.12. + >
+- chore(deps): bump i18next from 26.3.6 to 26.4.0 (#12267) + > Bumps [i18next](https://github.com/i18next/i18next) from 26.3.6 to 26.4.0. + >
+- Make managed Cloud OAuth handoffs invisible (#12790) + > - Add a backward-compatible opaque Cloud handoff to the shared OAuth start contract. + > - Validate the Cloud descriptor on the server and expose no browser-selected endpoint. + > - Exchange managed handoffs through one fixed same-origin route in every Apps OAuth launcher. +- chore(deps): bump @radix-ui/react-slot from 1.3.0 to 1.3.3 (#12268) + > Bumps [@radix-ui/react-slot](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/slot) from 1.3.0 to 1.3.3. + >
+- chore(deps): bump @pierre/diffs from 1.3.5 to 1.3.6 (#12311) + > Bumps @pierre/diffs from 1.3.5 to 1.3.6. + >
+- test(server): make the instance settings route suite deterministic under CPU contention (#12789) + > - Load the mocked instance settings module graph once for the suite. + > - Restore each mock implementation before every test. + > - Wait for two real transaction events instead of a fixed 30 millisecond delay. +- test(server): select exposure reservation host ports at run time (#12783) + > - Select two free app and HMR port pairs in `beforeEach`. + > - Start the scan 500 ports above the runtime exposure range minimum. + > - Keep the synthetic host stub limited to the selected pairs. +- test(server): make secret write-serialization tests deterministic (#12781) + > - Wait for a deferred signal when the first operation reaches its provider write. + > - Measure an uncontended provider-write duration and use a safety multiple for the queued-write check. + > - Release the test gate in a `finally` block so failed assertions do not leave a write active. +- test(acpx): bind ACPX credential waits to the real retry envelope (#12780) + > - Add a test-local wait helper with an explicit 10-second deadline. + > - Apply the helper to every credential and sandbox poll in `runtime-host.test.ts`. + > - Report the last observed error when a poll reaches its deadline. +- ci(runner): build paid artifacts once per campaign (#12777) + > - Build runner TypeScript and native binaries once per campaign in a credential-free job. + > - Build the remote provider pack once only when selected Daytona cells require it. + > - Upload run-scoped bundles with SHA-256 manifests and verify before extraction in each paid cell. +- chore(deps): bump lucide-react from 1.32.0 to 1.38.0 (#12313) + > Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.32.0 to 1.38.0. + >
+- ci(runner): prepare target lockfile once for paid validation (#12774) + > - Added one credential-free target-lock job that resolves the authorized immutable target SHA with lifecycle scripts disabled. + > - Uploaded the resolved lockfile with its SHA-256 and restored it by exact artifact ID before every target-code frozen install. + > - Left trusted reporting and history jobs on the workflow SHA. +- chore(deps): bump paperclipai/paperclip/.github/workflows/pr-trusted.yml from 39b8ee2960541d14b380f95365deecba6723d9bd to f038633bf5b04163ff985ef0542876bd9f455379 (#12562) + > Bumps [paperclipai/paperclip/.github/workflows/pr-trusted.yml](https://github.com/paperclipai/paperclip) from 39b8ee2960541d14b380f95365deecba6723d9bd to f038633bf5b04163ff985ef0542876bd9f455379. + >
+- chore(deps): bump sharp from 0.35.3 to 0.35.4 (#12563) + > Bumps [sharp](https://github.com/lovell/sharp) from 0.35.3 to 0.35.4. + >
+- chore(deps): bump @mdxeditor/editor from 4.2.1 to 4.2.3 (#12564) + > Bumps [@mdxeditor/editor](https://github.com/mdx-editor/editor) from 4.2.1 to 4.2.3. + >
+- Secure Cloud canonical runtime identity (#12766) + > - Store the accepted claim in a dedicated private singleton record in the existing instance settings table. + > - Verify compact EdDSA assertions against the configured public JWKS. + > - Require the expected stack, audience, issuer, claim, time window, pool origin, slug, and HTTPS destination. +- chore(deps): bump better-auth from 1.7.0 to 1.7.2 (#12565) + > Bumps [better-auth](https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth) from 1.7.0 to 1.7.2. + >
+- chore(deps-dev): bump @vitejs/plugin-react from 4.7.0 to 6.1.1 (#12566) + > Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 4.7.0 to 6.1.1. + >
+- chore(lockfile): refresh pnpm-lock.yaml (#12771) + > - Use full dependency resolution in the scheduled lockfile refresh. + > - Use the same repair mode in pull request policy checks and Docker build preparation. + > - Keep lifecycle scripts disabled during every repair. +- chore(deps): bump @aws-sdk/client-s3 from 3.1115.0 to 3.1120.0 (#12567) + > Bumps [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) from 3.1115.0 to 3.1120.0. + >
+- ci(runner): allow trusted branch targets (#12768) + > - Add the optional `target_branch` workflow input. + > - Resolve only a branch in `paperclipai/paperclip` to an immutable SHA. + > - Pin catalog, image, paid test, and Daytona provenance to the target SHA. +- chore(deps): bump @tanstack/react-query from 5.101.4 to 5.102.8 (#12568) + > Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.101.4 to 5.102.8. + >
+- chore(deps): bump mermaid from 11.16.1 to 11.17.2 (#12569) + > Bumps [mermaid](https://github.com/mermaid-js/mermaid) from 11.16.1 to 11.17.2. + >
+- chore(deps-dev): bump rollup from 4.62.4 to 4.63.1 (#12570) + > Bumps [rollup](https://github.com/rollup/rollup) from 4.62.4 to 4.63.1. + >
+- ci(runner): route paid matrix to AWS fleet (#12765) + > - Add a fail-closed `RUNNER_E2E_AWS_ENABLED` switch. + > - Select only the reviewed AWS fleet label or the existing hosted label. + > - Permit up to 100 parallel jobs in AWS mode. +- test(heartbeat): drain in-flight runs before native-isolation TRUNCATE (#12751) + > - Drain active heartbeat run executions before `afterEach` runs `TRUNCATE`. + > - Assert that no heartbeat run remains `queued` or `running` before teardown. + > - Drain active executions before `afterAll` removes the temporary database. +- chore(lockfile): refresh pnpm-lock.yaml (#12737) + > - Added the patch record for `@agentclientprotocol/claude-agent-acp@0.73.0`. + > - Updated the Claude local adapter lock entry to version 0.73.0. + > - Added the matching transitive Claude agent SDK lock entries. +- Simplify app connections and enable managed Google access (#12728) + > - Removed the Apps experimental gate and the breadcrumb that leaves the Apps section. + > - Simplified all connection setup pages and moved optional provider requirements into one small link. + > - Added consistent human and agent access choices for Google apps, Zapier, and generic MCP connections. +- test(runner): add full-stack acceptance and eval gates (#12700) + > - Add the runner full-stack harness with 57 catalog cells and 60 unit tests. + > - Add a Daytona runner image with digest-pinned base images and base-aware image-content checks. + > - Add guarded live evaluation and chaos workflows with a fixed 40-execution matrix; live and full-stack paid schedules now run only on Sundays or by manual dispatch. +- Add task workspace picker to properties pane (#12693) + > - Added shared helpers for the current workspace selection and its issue update payload. + > - Updated the existing workspace card to use the shared helpers without changing its project-default behavior. + > - Added a gated workspace property picker with mode and workspace search steps. +- docs(release): add v2026.831.1 stable notes to master (#12710) + > - Add `releases/v2026.831.1.md` to master, copied verbatim from the published `v2026.831.1` tag. +- docs(release): canonicalize stable notes for v2026.831.0 (#12708) + > - Renamed `releases/beta/v2026.828.0-beta.0.md` to `releases/v2026.831.0.md` (pure rename, no content changes) +- Onboarding: count the whole walk on a cloud tenant (#12706) + > - Adds `enteredFromCloud`, read from `enableManagedSandboxOnly` — the cloud-tenant shape the connect step already resolves its login environment through. + > - Excludes that case from `showsAgentArcStepper`, so it falls to the existing four-step strip. `ONBOARDING_STEP_LABELS` and `onboardingStepPositionFor` already produce 2, 3 and 4; neither needed changing. + > - Widens the experimental-settings query from step 4 to steps 3–5, so the strip can read it on every step of the arc. +- Remove cheap model profiles (#12683) + > - Removed model-profile types, adapter capabilities, API fields, and model selection logic. + > - Removed cheap-model controls from agent and task UI surfaces. + > - Kept status-only recovery limited to coordination context while normal continuations use the configured agent model. +- Clean up experimental settings features (#12681) + > - Removed the old task watchdog and issue graph recovery feature flags. + > - Removed the old issue graph recovery preview, run controls, API contracts, and unused recovery implementation. + > - Kept resolved dependency wakes as the scheduler backstop. +- refactor(docker): declare the build stage's C toolchain explicitly (#12673) + > - The build stage installs `gcc`, `libc6-dev`, and `pkg-config` explicitly, with a comment recording why: the old apt cargo brought gcc in as a dependency and the pinned rustup install does not. +- test(runner): bound codex provider exit polls by wall clock (#12596) + > - `tests/codex_provider.rs`: bound the exit wait at line 1256 by a 5 second deadline instead + > - `tests/codex_provider.rs`: bound the exit wait at line 1397 by a 5 second deadline instead + > - Both loops now sleep 1 ms when `poll()` returns no event. This copies the pattern that the +- Onboarding: model source tiles, one input canvas, and Storybook coverage for the agent arc (#12613) + > - Replaces the adapter dropdown and "Advanced settings" disclosure with `ModelSourceTiles` — brand tiles for Claude Code and Codex. + > - Adds `CredentialModeLink`, a text toggle between subscription sign-in and API keys, replacing the disclosure. + > - Adds `ConnectInputCanvas`: one surface that holds the sign-in panel or the API-key field and resizes between them, so the Connect button below does not move. +- Unify Paperclip Runner experimental controls (#12666) + > - Removed the separate Runner Preview Ingress card from Experimental Settings. + > - Made resolved native runtime selection authorize required provider ingress. + > - Preserved ingress recovery for persisted native runs after the rollout flag is disabled. +- chore(lockfile): refresh pnpm-lock.yaml (#12626) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- Gate Paperclip Runner setup behind an experimental flag (#12656) + > - Added the Paperclip Runner opt-in to Experimental Settings. + > - Refreshed adapter availability after the setting changes. + > - Kept UI and server-seeded onboarding on legacy adapters. +- test(runner): add credential-free acceptance foundation (#12652) + > - Add a catalog for built-in direct adapters and qualified native provider profiles. + > - Add compatibility cases for runtime selection, task threads, questions, and flag-change recovery. + > - Add pure redaction and transient-failure classification helpers. +- docs(release): stable notes for the 2026.828.0-beta.0 soak (v2026.831.0) (#12610) + > - Rewrote `releases/beta/v2026.828.0-beta.0.md` from the generated skeleton into finished notes titled `# Paperclip v2026.831.0` + > - Six breaking changes, led by the Node.js 24.11.0 minimum; each has an upgrade path + > - Five highlights: runtime skill delivery to agents, the Kimi Code adapter, operator settings-visibility controls, the HTTP/2 sandbox callback bridge, and the shortened onboarding arc +- Fix managed OAuth catalog activation (#12623) + > - Kept fresh and revived managed connections in the draft state until catalog finalization succeeds. + > - Added a managed-draft refresh option that quarantines discovery results without changing generic draft behavior. + > - Activated reviewed profile tools, created bindings, and installed ask-first policies in the existing finalization transaction. +- chore(lockfile): refresh pnpm-lock.yaml (#12593) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- refactor(docker): install rust via a verified rustup, pinned by rust-toolchain.toml (#12605) + > - The docker build stage downloads a pinned `rustup-init` (1.29.0) for the build architecture, verifies it against an embedded sha256, and installs with `--default-toolchain none`. + > - The compiler version comes from `packages/paperclip-runner/rust-toolchain.toml` (1.97.1) — one pin, no drift between the Docker layer and the runner package. + > - A comment records why apt rust is not used: Debian's archive lags the ecosystem. +- Detect the qualifier-less Claude usage-limit message in quota classification (#12475) + > - `CLAUDE_PROVIDER_QUOTA_RE` and `CLAUDE_EXTRA_USAGE_RESET_RE` (claude-local adapter) accept "you've hit your limit" with no qualifier, alongside the existing "session"/"usage" wordings, so the run classifies as `provider_quota` and the reset clock lands in `retryNotBefore`. + > - `PROVIDER_QUOTA_ERROR_RE` and `isProviderQuotaRecovery` (recovery service) accept the same wording, so runs recorded before the adapter fix (errorCode `adapter_failed` with the limit text in the error) also route to the quota wait. + > - `parseProviderQuotaClockReset` parses the "resets 2:30am (UTC)" clock shape alongside the existing "try again at" shape. +- test(e2e): shorten and split Smoke Lab coverage (#12506) + > - Reused one Smoke Lab service start within each spec while retaining isolated fixture installation for every scenario. + > - Removed the duplicate catalog evidence navigation. + > - Reduced success screenshots from 56 to 7 while retaining screenshots for every failed step. +- chore(lockfile): refresh pnpm-lock.yaml (#12583) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- chore(lockfile): refresh pnpm-lock.yaml (#12546) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- test(runner): add question adapter conformance (#12409) + > - Add a canonical ACPX form fixture and native response. Mark the equivalent Codex fixture field as required. + > - Add shared validation for question IDs, option IDs, answer modes, required answers, text bounds, numeric bounds, and response shapes. + > - Evaluate fixture-only regular expressions in a bounded child process. Reject patterns that cannot finish safely. +- test(runner): add Codex trace conformance (#12370) + > - Added exact task-envelope result validation. + > - Added bounded persisted-event validation and deterministic replay. + > - Added a controller-owned Codex trace harness and parity assertions. +- Add collaboration action contracts (#12359) + > - Add 13 collaboration and governance action definitions. + > - Add immutable policy, schema, documentation, and example data. + > - Add a collaboration-only aggregate. +- Add core runner action contracts (#12358) + > - Add 14 core protocol action definitions. + > - Add immutable policy, schema, documentation, and example data for each action. + > - Add a deep-freeze helper and a core-only aggregate. +- Add deterministic capability control plane (#12355) + > - Add deterministic capability fixture types and seed state. + > - Add an in-memory capability control-plane adapter. + > - Enforce run, company, actor, claim, role, and idempotency boundaries. +- Add deterministic runner conformance core (#12354) + > - Add a deterministic harness-driver implementation. + > - Add an in-memory control-plane adapter with replay and checkpoint support. + > - Add a canonical provider-neutral conformance fixture. +- Add durable semantic tool receipts (#12353) + > - Add semantic input and result receipt builders. + > - Add optional reconciliation receipts for pending calls. + > - Reject unsupported semantic receipt versions. +- Add the native runner session runtime (#12352) + > - Add a provider-neutral native session execution loop. + > - Add recovery cursor reconciliation and checkpoint hooks. + > - Add bounded timeout and governed-wait behavior. +- Define native runner execution contracts (#12351) + > - Add versioned native execution input contracts and strict parsers. + > - Add provider-neutral runtime context and completion contracts. + > - Add durable recovery and local runner types. +- chore(lockfile): refresh pnpm-lock.yaml (#12514) + > - Added `agentmail@^0.5.14` to the root lockfile importer. + > - Added the dependency resolutions required by the current workspace manifests. + > - Kept the change limited to `pnpm-lock.yaml`. +- refactor(server): remove unreachable task-drain compensation paths (#12511) + > - Remove the service-layer TTL clamp because the shared validator rejects values above the limit. + > - Write task-drain audit rows before drain mutation and remove the rollback helpers. + > - Remove the rollback generation counter and its unused state. +- Keep browser startup explicitly opt-in (#12435) + > - Stop onboarding from setting `PAPERCLIP_OPEN_ON_LISTEN=true` for foreground startup. + > - Set `PAPERCLIP_OPEN_ON_LISTEN=false` in E2E and issue-detail performance test servers as defense in depth. + > - Preserve the existing explicit environment opt-in in the server. +- ci: activate stacked pull request optimization (#12509) + > - Pin `.github/workflows/pr.yml` to merged master commit `39b8ee2960541d14b380f95365deecba6723d9bd`. + > - Activate the stack-aware trusted workflow that merged in pull request #12507. +- ci: optimize checks for stacked pull requests (#12507) + > - Add a fail-safe stack scope decision to the trusted PR runner gate. + > - Run typecheck, general tests, build, serialized tests, canary, and E2E shards only for ordinary, top, and lowest-unmerged pull requests. + > - Preserve the required `ci / verify` and `ci / e2e` names on every layer. +- chore: add @forgottendev to CODEOWNERS (#12501) + > - Added `@forgottendev` to all 13 existing entries in `.github/CODEOWNERS`. + > - Kept all existing owners and path patterns unchanged. +- chore(lockfile): refresh pnpm-lock.yaml (#12484) + > - Added the `@paperclipai/shared` workspace link to the Grok local adapter importer in `pnpm-lock.yaml`. +- test(server): load the agent-permissions route module graph once per file (#12471) + > - Load the route module graph one time for the describe block with the existing `hoistModuleGraph` helper. + > - Make `createApp` synchronous and read the hoisted graph. + > - Remove per-test `vi.resetModules()` and the 26 `vi.doUnmock(...)` calls. +- ci: activate stacked lockfile regeneration (#12464) + > - Pin the trusted pull request workflow to merged commit `1da6b37fc56dacf5e7ffbd31da35756a1cba41f8`. + > - Activate stale lockfile regeneration for native stacked pull requests. +- refactor(adapter-utils): replace the process-wide byte ledger with route-local byte bounds (#12465) + > - Bound each host retention site with a fixed local byte limit. + > - Limited concurrent live HTTP/2 streams with one built-in stream limit. + > - Bound each host forward and response-body read to its own HTTP/2 stream lifetime. +- ci: activate stale base handling (#12463) + > - Pin the thin pull request caller to f9c32513b2fe62586c60fa0b8863ebd21e5c7603. +- ci: ignore stale PR API base snapshots (#12462) + > - Stop treating pull request base.sha as a current-state signal. + > - Keep the signed event base SHA and live ref descendant check. + > - Keep the live base or synthetic base merge-parent proof. +- ci: activate live stacked base validation (#12460) + > - Pin the thin pull request caller to f929355fb9f4781ca46e542397fcaf2a110e6ca9. +- ci: allow validated stacked base advances (#12459) + > - Allow the live pull request base SHA to advance from the signed event base snapshot. + > - Require the pull request API base SHA to match the live Git ref during validation. + > - Keep the numeric author, sender, and triggering actor checks. +- ci: activate stacked merge validation (#12458) + > - Pin the thin caller to the authorized stacked-merge validator SHA. +- ci: activate trusted stacked PR routing (#12456) + > - Remove the caller base-branch filter so stacked pull requests trigger CI. + > - Pin the thin caller to the authorized stack-aware reusable workflow SHA. +- ci: pin PR base snapshot validation (#12450) + > - rotate the thin caller from `5ac66b3fdd5dc22c0c4e5fdb234ac063cf1d9ff8` to `c119c4bee6ebb9c81791d7a6994f1be06d7cc22b` + > - keep both exact SHAs authorized during rotation +- ci: pin workflow merge ref validation (#12448) + > - rotate the thin caller from `b88fadb0390d2113933d5d155f16b07cbd5dafee` to `5ac66b3fdd5dc22c0c4e5fdb234ac063cf1d9ff8` + > - keep both exact SHAs authorized during rotation +- ci: pin single runner route output (#12445) + > - rotate the thin PR caller from `3b295b05dc8c8dd82c12e4a9c6f721446c5cb2e8` to `b88fadb0390d2113933d5d155f16b07cbd5dafee` + > - keep both exact SHAs authorized during the rotation +- docs: point section 11 at the renamed implementation plan (#11677) + > - `doc/DEPLOYMENT-MODES.md` line 176 now names `doc/plans/2026-02-23-deployment-auth-mode-consolidation.md` +- ci: pin equivalent merge validation (#12442) + > - rotate the thin PR caller from `d9fc93d8383ece6fba721881a7aba638867f4996` to `3b295b05dc8c8dd82c12e4a9c6f721446c5cb2e8` + > - keep both exact workflow SHAs authorized in the runner group during the rotation +- ci: call trusted PR workflow (#12439) + > - Replaced the duplicated heavy CI job list with one reusable-workflow call. + > - Pinned the call to the reviewed default-branch commit. + > - Limited the caller token to actions, contents, and pull request read access. +- ci: synchronize trusted PR policy (#12438) + > - Added the current migration-order validation to the trusted workflow. + > - Added the existing shellcheck intent annotation to the active workflow. + > - Verified normalized heavy-job parity between both definitions. +- ci: add trusted reusable PR workflow (#12436) + > - Added an inactive `workflow_call` copy of the current PR checks. + > - Added a GitHub-hosted routing gate that checks the repository ID, pull request author ID, event sender ID, rerun actor ID, base branch, head SHA, merge SHA, and current pull request state. + > - Made every validation failure select `ubuntu-latest`. +- test(server): load the company-skills route module graph once per file (#12426) + > - Load the mocked route module graph once for each describe block. + > - Use the existing `hoistModuleGraph` helper, as the cost service test does. + > - Remove twelve per-test `vi.doUnmock` calls and the redundant module rebuild. +