diff --git a/releases/beta/v2026.825.0-beta.1.md b/releases/beta/v2026.825.0-beta.1.md new file mode 100644 index 00000000000..92dd6254d8b --- /dev/null +++ b/releases/beta/v2026.825.0-beta.1.md @@ -0,0 +1,569 @@ +# Paperclip stable draft — from beta 2026.825.0-beta.1 + +> Auto-generated at beta publish from `git log v2026.824.0..bef928866` (baseline: v2026.824.0). +> 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(duplex): run the Daytona sandbox callback bridge over Node HTTP/2 (#12120) + > - Carry raw Uint8Array chunks through the adapter, plugin, worker, runtime, and Daytona layers. + > - Encode bytes as base64 only across the JSON-RPC hop, because JSON has no binary type. + > - Add the bounded host HTTP/2 server and the in-sandbox HTTP/2 client gateway. +- feat(runner): define package API and verification boundary (#12129) + > - Export only `@paperclipai/paperclip-runner` and `@paperclipai/paperclip-runner/testing`. + > - Keep Node-only fixture loading and semantic conformance helpers out of the runtime root. + > - Add a provider-neutral semantic conformance kit with stable JSON comparison and fail-closed input checks. +- feat(release): thorough notes skeletons — nest each PR's summary at creation (#12124) + > - `scripts/draft-stable-notes.sh`: `enrich_pr` nests PR summaries under subjects; best-effort (`gh` failure or `DRAFT_NOTES_SKIP_PR_ENRICHMENT=1` degrades to today's output); pipefail-safe when a "What Changed" section has no bullets. + > - `.github/workflows/release.yml`: the `draft_stable_notes` step gets `GH_TOKEN` so `gh` can read PR bodies. + > - `.agents/skills/release-changelog/SKILL.md`: "write at full stable depth from the first pass" guideline. +- feat(runner): authorize semantic tool dispatch (#12126) + > - Add run-scoped tool projection and optional tool discovery. + > - Require an explicit application binding before an action is visible. + > - Intersect actor claims with claims delegated to the run. +- feat(runner): add PRP v1 schemas and fixtures (#12087) + > - Added 20 PRP v1 JSON Schemas with stable identifiers and resolved references, including explicit cross-language conformance input and output schemas. + > - Added canonical replay, cross-language, and Codex question fixtures. + > - Added accepted cases for additive optional fields and a rejected case for an unsupported required protocol version. +- feat: environment delete with agent reassignment and consented sandbox destroy (#12053) + > - `ui/src/pages/CompanyEnvironments.tsx`: delete button on the edit page header, confirmation modal with agent reassignment select, lease-holder list, impact notes, and a consent-labeled destroy-and-delete action + > - `ui/src/api/environments.ts`: `deleteBlastRadius` and `remove` client methods; `remove` takes an optional `destroyReusableSandboxLeases` flag + > - `server/src/routes/environments.ts`: `DELETE /environments/:id` accepts `?destroyReusableSandboxLeases=true`; it destroys the environment's reusable sandbox leases first, but only when those leases are the sole delete blocker, then re-checks the blast radius before it deletes +- feat(login): use the login pseudo-terminal for Codex device login and de-Claude the shared channel (#12020) + > - Route Codex device login through the shared login PTY transport. + > - Select the login command from a closed internal command key. + > - Carry a server-controlled session home through the launch contract. +- feat(adapter-utils): stream duplex bridge bodies as sequenced chunks with receive-side spill (#12006) + > - Add version 2 body_chunk frames with 256 KiB raw slices encoded as canonical base64 text. + > - Add receive-side memory and spill reassembly with per-channel disk and file limits. + > - Reject malformed, reordered, oversized, truncated, and non-canonical body chunks. +- feat(duplex): bound aggregate duplex route resource consumption with a process-owned byte ledger (#12003) + > - Add a process-owned aggregate byte ledger for duplex route resource use. + > - Charge and release route data, broker forward and response bytes, decoder buffers, and readiness replay bytes. + > - Bound host-to-worker pending writes and standard input transport bytes. +- feat(sandbox): add the duplex bridge broker, gated transport selection, and fixed observability (#11769) + > - Add the duplex bridge broker with bounded forward, response, and gateway wait budgets. + > - Bound concurrent requests, lifetime requests, and request-id bytes before retention or forwarding. + > - Select duplex transport only when both required gates are true. +- feat(commitperclip): surface the Co-Authored-By trailers a squash merge needs (#11498) + > - `.github/scripts/check-pr-coauthors.mjs` — new gate. + > - `.github/scripts/run-quality-gates.mjs` — fetches the PR's commits and runs it. + > - `.github/scripts/tests/check-pr-coauthors.test.mjs` — 12 cases. +- feat(environments): refer to the managed default environment by name, not the sandbox driver key (#11838) + > - New `environmentDisplayLabel` helper in `ui/src/lib/managed-sandbox-environment.ts`: managed rows → name alone; other rows → "Name · driver". + > - `AgentConfigForm`: inherited-default label uses the helper; fallback copy "Managed sandbox" → "Paperclip Computer"; environment options use the helper. + > - `ProjectProperties`, `CompanyEnvironments`: environment selector options use the helper; the environments-list row hides the driver suffix on managed rows; the managed detail page's fallback description no longer says "sandbox". +- feat(ui): rename "Agent mode" to "Auto mode" and show full work-mode labels (#11866) + > - Renamed the `standard` work-mode label from "Agent mode" to "Auto mode" in `ui/src/lib/work-mode-meta.ts`, the single source for all mode chips. + > - Changed the New Task dialog mode chip to render the full `label` instead of `shortLabel`. + > - Deleted the `shortLabel` field from `WorkModeMeta` so nothing can silently regress to the short form. +- feat: operator-configurable settings visibility via PAPERCLIP_HIDDEN_SETTINGS (#11823) + > - New `packages/shared/src/settings-visibility.ts`: registry of hideable surfaces (every instance settings page — profile, environments, access, heartbeats, experimental, plugins, adapters; every Instance → General section; every experimental flag as `instance.experimental.`), the `PAPERCLIP_HIDDEN_SETTINGS` parser, and the `settings_operator_managed` error code. The General page stays visible as the settings root and redirect target. + > - New `server/src/services/settings-visibility.ts`: parse-once accessor; unknown keys log one warning and are ignored. + > - `/api/health` reports `hiddenSettings` on every response shape; the field is omitted when nothing is hidden. +- feat(artifacts): bridge Markdown work products into the document review surface (#11822) + > - `packages/shared`: added a Markdown work-product eligibility classifier, review-document key helpers, and a shared size limit used by both server and UI + > - `server`: added an idempotent ensure service (`artifact-review-documents`) and `POST /issues/:id/work-products/:workProductId/review-document`, with typed 404/409/413/415/422 errors + > - `server`: wired the ensure step into work-product create and patch as fail-open, with promoted attribution, synchronization of title and revision provenance, and annotation remap +- feat: add kimi-local adapter for Kimi Code CLI (CLI + ACP engines) (#9967) + > - **New adapter package** `packages/adapters/kimi-local` (`@paperclipai/adapter-kimi-local`), modeled on `gemini-local`/`grok-local`: + > - **ACP engine lane (default)** (`src/server/acp.ts` + shared `adapter-utils/acpx-engine`): Kimi Code ships an ACP server (`kimi acp`), so `kimi_local` now runs on Paperclip's shared acpx engine by default, matching `claude_local`/`codex_local`/`gemini_local`. The issue-thread transcript streams live (assistant text deltas, tool calls with a `pending`->`completed` status lifecycle) instead of the CLI lane's bursty complete-message output. Registered `kimi_local -> "kimi"` in `ACPX_ADAPTER_AGENT_IDS` and resolved the built-in agent command to `kimi acp`; `execute.ts` dispatches to the ACP executor first with an automatic CLI fallback when ACP prerequisites fail (`engine=acp` requires ACP, `engine=cli` pins the headless lane); `index.ts` falls back to the shared acpx session codec; the UI/CLI delegate `acpx.*` events to the shared acpx transcript parser and event formatter. The headless CLI lane (above) remains as the fallback + > - **Registration** (one entry each, mirroring existing adapters): server adapter registry + `BUILTIN_ADAPTER_TYPES`, `AGENT_ADAPTER_TYPES` (shared), UI adapter registry + display registry (`Kimi Code`, Moon icon) + capabilities defaults, CLI adapter registry, `Dockerfile` (package copy + `npm install --global @moonshot-ai/kimi-code@latest`), `vitest.config.ts` workspace, `scripts/release-package-manifest.json` +- feat(acpx/ui): adapter-declared capabilities for verbose streaming backends (no behavior change by default) (#11761) + > - `packages/adapter-utils/src/acpx-engine/execute.ts`: the run preparation parses `summaryStrategy` and `coalescePlaceholderToolUpdates` from the invocation config (validated, defaulted); summary accumulation and `emitRuntimeEvent` branch on the prepared values. The default path is the pre-existing code (`textParts.join("")`, no event filtering). `buildAcpxRunSummary` is the exported last-segment strategy. + > - `packages/adapter-utils/src/acpx-engine/execute.test.ts`: a pin test asserting the default path's exact summary (thought stream included) and full tool-event stream (placeholder-titled in-progress updates present, names restored); opt-in tests for each knob; a `buildAcpxRunSummary` unit test. + > - `ui/src/adapters/types.ts`: `UIAdapterModule` gains an optional `transcriptPresentation` capability — `maxVisibleEntries` (issue-chat transcript window, default 30) and `liveReasoningView` (`"ticker"` default; `"scrollLog"` renders live reasoning in a scrollable auto-following box with one entry per tool call). +- feat(release): bootstrap new npm packages with a placeholder publish (#11757) + > - `scripts/bootstrap-npm-package.mjs`: replaced the build-and-publish flow with a placeholder publish — stages `package.json` + `README.md` + throwing `index.js` at version `0.0.0` in a temp directory, previews with `npm publish --dry-run`, and publishes only with `--publish`. One-time passwords are prompted interactively (never passed as arguments, since they are single-use and would land in shell history), with re-prompt on a rejected or expired code. After publishing, the helper polls the registry until the package is visible (a first publish can lag by minutes; verified live at ~5 minutes), requiring two consecutive sightings before prompting for a second code and deprecating the placeholder so accidental installs warn loudly; on timeout or failure it prints the exact manual `npm deprecate` command. Added an `@paperclipai/`-scope guard and a fail-fast error when `--publish` runs without an interactive terminal. Removed the workspace-plan dependency so it runs from any checkout. + > - `scripts/bootstrap-npm-package.test.mjs`: rewrote for the new interface — argument parsing, scope validation, the generated placeholder files (manifest shape, throwing entry point, README), the OTP re-prompt loop, and the registry poll (consecutive-sighting requirement, timeout, transient-error tolerance) via injected fakes. + > - `doc/PUBLISHING.md`: rewrote the "One-time bootstrap sequence for a new package" section for the placeholder flow, including the `latest` dist-tag window and the trusted-publishing setup ordering (placeholder publish → trusted publisher rule → `"publishFromCi": true`). +- feat(sandbox): add a duplex transport for Daytona behind a default-off kill switch (#11750) + > - Add the Daytona `duplexCommandStream` capability over a raw pseudo-terminal. + > - Add a launch wrapper that disables echo and newline translation for NDJSON frames. + > - Close channels on lease release, destroy, resume of a stopped worker, and worker shutdown. +- feat(environments): expose boot-relevant drift attribution in the custom-image overview (#11751) + > - Add `activeTemplateDrift` to the custom-image overview response. + > - Classify drift as `boot_source_drift`, `knob_only`, or `unclassified`. + > - Return drifted paths with safe `from` and `to` values. +- feat(sandbox): add opt-in duplex command-stream foundation (capability, protocol, bounded host route, frame codec) (#11738) + > - Add the opt-in `duplexCommandStream` provider capability with fail-closed narrowing. + > - Add duplex open, write, stop, and close requests and data and exit notifications to the plugin worker protocol. + > - Add a host-owned route with bounds for chunk size, cumulative bytes, lifetime, protocol errors, pending requests, and pre-bind buffering. +- feat: parallelize sandbox file-sync behind a provider opt-in capability (#11736) + > - Add the concurrentSyncOperations sandbox capability and fail-closed parsing. + > - Add a bounded settle-all scheduler with stable input-order errors. + > - Parallelize inbound workspace, asset, and referenced-project sync operations when the provider opts in. +- feat(auth): normalize agent login in the sandbox onto one session table and a capability contract (#11730) + > - Unify Codex device login and Claude setup-token login on `adapter_auth_sessions`. + > - Return and look up sessions with company-scoped public session identifiers. + > - Enforce one active session for each company, owner, and adapter. +- feat(workspaces): sign the workspace login handoff and gate readiness (#11671) + > - Adds a short-lived, signed, single-use login ticket. It binds the user, workspace, instance, and runtime origin. + > - Exchanges the ticket through Better Auth. It creates the session and cookie through the supported adapter path. + > - Adds protected workspace readiness fields for the database, clone data, login handoff, seed phase, and runtime identity. +- feat(server): add a one-click relink action for detached custom-image templates (#11641) + > - Add `relinkActiveTemplate` with drift classification and conditional fingerprint update. + > - Persist a server-owned boot-relevant configuration snapshot during capture. + > - Add the guarded relink route with strict request validation and activity logging. +- feat(server): add a configurable cooldown to the terminal workspace reaper (#11642) + > - Add `PAPERCLIP_WORKSPACE_REAPER_COOLDOWN_DAYS` with a seven-day default. + > - Treat `0` as no cooldown and use the default for negative or non-numeric values. + > - Use the latest `completedAt` or `cancelledAt` value in the source issue tree. + +## Fixes + +- fix(docker): make tini PID 1 in the server image so adopted orphans are reaped (#12137) + > - `Dockerfile`: install `tini` in the `base` stage and set `ENTRYPOINT ["/usr/bin/tini", "--", "docker-entrypoint.sh"]`. The entrypoint stays in the exec chain, so UID/GID remapping, `gosu`, and graceful shutdown are unchanged. + > - `scripts/assert-orphan-reaping.sh` (new): a behavioural probe. It spawns a leader that forks a grandchild, exits the leader, and asserts that the orphaned grandchild leaves `Z` state instead of persisting. It fails closed if the grandchild is not re-parented onto PID 1, so a pass cannot mean the check ran too early. + > - `.github/workflows/docker.yml`: run that probe against the pushed image after the publish step. The publish step is multi-arch with `push: true`, so nothing is loaded into the runner daemon and the pushed tag is the only thing to test. The cloud variant is `FROM production` and inherits the same `ENTRYPOINT`. +- fix(cli): open dashboard after onboarding service starts (#12164) + > - Record each running CLI server's PID, selected port, and dashboard URL in atomic per-instance runtime metadata. + > - Accept runtime metadata only when its PID matches the active managed service. + > - Wait for the selected runtime endpoint to report healthy before printing its URL. +- fix(cli): skip the foreground-start prompt after the service starts (#12153) + > - New `shouldOfferForegroundStart` predicate in `cli/src/onboard-service.ts`: the foreground-start prompt is offered only when the start was not already decided by flags, the service was not just installed, onboarding was not invoked by `run`, and the terminal is interactive. + > - Both onboarding call sites in `cli/src/commands/onboard.ts` use the predicate instead of the inline condition that ignored `serviceInstalled`. + > - Unit tests cover the predicate matrix in `cli/src/__tests__/onboard-service.test.ts`. +- fix(cli): materialize the managed install before the onboarding service install (#12148) + > - `cli/src/onboard-service.ts`: after the user opts in, an `ensureServiceShim` step checks the service shim path. Missing + managed-store location → run `installCommand` pinned to the onboarding version (payload, shim, PATH block), then proceed. Missing + custom `PAPERCLIP_SHIM_PATH`, or install failure → decline with `paperclipai install` / `paperclipai service install` guidance and install nothing. + > - `cli/src/checks/service-health-check.ts`: the runtime check diagnoses a missing service binary with the install repair hint (instead of the port-conflict hint); an inactive service with a healthy responder gets a `warn` attributing the foreign process instead of a plain "Healthy" pass. + > - Tests: new cases for shim materialization ordering, decline-on-failure, missing-binary diagnosis, and foreign-responder attribution; existing fixtures updated to inject the new dependencies. +- fix(grok_local): do not warn when the default model sentinel is unavailable (#12062) + > - `packages/adapters/grok-local/src/server/test.ts`: the model check now treats the default sentinel as valid and reports it as info (`Using the Grok CLI's default model ()`). It still warns when an explicitly configured, non-sentinel model is absent from the discovered list. This matches `execute.ts`, which never sends the sentinel to grok. + > - `packages/adapters/grok-local/src/server/test.test.ts`: adds a test that the default sentinel does not warn when it is absent from the real model list, and a test that a real, unavailable model still warns. +- fix: harden the sandbox bridge gateway against crashes and queue wedge (#12060) + > - The generated gateway source installs global `uncaughtException` / `unhandledRejection` handlers that log to stderr (already redirected to `logs/bridge.log`) and keep serving. The relay holds no state a fault can corrupt beyond the one request it interrupted. + > - Survival is gated on readiness: before the gateway has written its readiness file (file mode) or sent its READY frame (duplex mode), the same handlers exit(1) instead. A startup fault (failed bind, failed readiness write) means the process can never serve, and surviving there would only leave an un-ready zombie while the host waits out its readiness poll. + > - The file gateway attaches an explicit `error` listener to its server and pins the event loop with a keepalive until the bind settles. Newer Node runtimes do not reliably surface a failed bind through `uncaughtException` in this shape: the process can drain and exit 0 before the error event is delivered (reproduced on Node 24/25; Node 22 delivered it). The duplex gateway already had an explicit listener. +- fix: stop teaching agents to curl literal {id} route templates (#12061) + > - gemini-local's API note curl example now uses `$PAPERCLIP_TASK_ID` and tells the agent to substitute a real issue id when that variable is absent — the same convention as the acpx engine's API note. + > - The shared agent prompt template (`server-utils.ts`) uses `$PAPERCLIP_TASK_ID` in its interaction-creation and resume-endpoint mentions, and the harness checkout notice names `POST /api/issues/$PAPERCLIP_TASK_ID/checkout`. + > - openclaw-gateway's endpoint workflow keeps its `{issueId}` placeholders — they are defined by its "determine issueId" step — but now states explicitly that the literal text must never be sent in a URL. +- fix: verify issue-update writes instead of inferring success (#12051) + > - `scripts/paperclip-issue-update.sh` now captures `%{http_code}`, retries a retryable failure (connection-level, 429, 5xx) once — two attempts total, which matches the shared bounded-write-retry rule — rejects an empty 2xx body, and confirms the response echoes the requested status before it exits 0. + > - Failure output states plainly that the write was NOT saved, so the calling agent reports it accurately. + > - `skills/paperclip/SKILL.md` Step 8 adds a required "Verify writes — never infer them" rule: a successful PATCH always returns the updated issue JSON, disposition writes must never run through `head`/`tail` pipelines, and an unconfirmed write must be reported as FAILED. +- fix: survive transient sandbox exec failures in the callback bridge worker (#12052) + > - `startSandboxCallbackBridgeWorker`'s poll loop now separates three failure domains: + > - The watchdog, the claim/finalize fences, and the stop/drain semantics are unchanged. +- fix(plugins): retry errored plugins at boot instead of leaving them dead (#12054) + > - `server/src/services/plugin-loader.ts`: `loadAll` also fetches plugins in `error` status, flips each to `ready`, and activates it with the normal batch. The flip runs before activation because the `error` status only legally transitions to `ready` or `uninstalled`; a retry that failed while still in `error` could not re-mark itself. A failed flip logs a warning and never aborts the boot load. The stale comment at the `markError` site now describes the retry. + > - `server/src/__tests__/plugin-loader-error-retry.test.ts`: covers the flip-then-retry flow, the failed-flip isolation, and the empty case. +- fix(server): authorize agent resume through direct grants (#12047) + > - The resume route now uses the protected `agent_config:update` decision with `requiresChangeGrant: true` for agent actors. + > - The route keeps board access, tenant non-disclosure, and invalid organization-chain protection. + > - Resume activity now records the real user or agent actor, run, and API key. +- fix(issues): cycle-aware issue_blockers_resolved after terminal reset (#11979) + > - Extend `buildIssueBlockersResolvedWakeStateKey` so the digest includes the dependent's `blockedTransitionAt` as UTC ISO-8601, or `none` + > - Thread `blockedTransitionAt` through `listWakeableBlockedDependents`, both route emit sites, and both backstop candidate selects + > - Keep compatibility: new cycle-aware keys suppress in idempotent statuses; old no-cycle state keys suppress when in-flight, or when completed and `requestedAt >= blockedTransitionAt` (or the cycle is null); legacy per-edge keys stay in-flight-only +- fix(daytona-duplex): chunk host-to-sandbox writes and make a transport close legible (#11986) + > - Add a shared UTF-8 byte chunker with a 32768-byte cap. + > - Route both Daytona pseudo-terminal write paths through the chunker. + > - Preserve multi-byte UTF-8 sequences across read-side chunks. +- fix(adapter-utils): enforce the duplex frame size bound on encode in both codec copies (#11983) + > - Add `encodeDuplexFrameChecked` to the host and embedded gateway codecs. + > - Measure encoded JSON bytes without the trailing newline. + > - Return a typed `frame_too_large` result without throwing. +- fix(adapter-utils): extend the duplex fail-closed run disposition to the CLI lane (#11966) + > - Add an optional `errorCode` field to `RunProcessResult`. + > - Add a one-read completion seam to the execution target process options. + > - Fail closed when a duplex channel dies before clean process completion. +- fix(recovery): stop automatic stranded-task takeovers (#11961) + > - Route exhausted and unsafe stranded recovery to a board-owned source action. + > - Preserve agent and user assignee fields during automatic escalation. + > - Keep limited same-agent continuity repair and provider quota monitoring. +- fix(runtime): guard empty Bash 3.2 array expansion (#11891) + > - Guard all three optional source-config array expansions with Bash 3.2-compatible parameter expansion. + > - Add a regression test that uses the base-config path and verifies that no `--from-config` argument is sent. + > - Document the Bash 3.2 compatibility requirement in the runtime script. +- fix(workspaces): read process cwd on macOS so port-owner adoption works (#11763) + > - Add a Darwin branch to `readLocalServiceProcessCwd`. + > - Run `lsof -a -d cwd -p -F0n` to read the process working directory. + > - Parse the NUL-delimited field output. +- fix(workspaces): attach PR preparation to existing branches (#11703) + > - Add `existingBranch` to the execution workspace policy and shared validation contracts. + > - Require `existingBranch` to use an isolated Git worktree and reject conflicting branch templates. + > - Attach to the exact branch without creating, renaming, resetting, or deleting it. +- fix(grok-local): stop defaulting --permission-mode to dontAsk (#11898) + > - `packages/adapters/grok-local/src/server/execute.ts`: `permissionMode` no longer defaults to `dontAsk`. The adapter passes no `--permission-mode` flag unless one is explicitly configured. `--always-approve` (default on) remains the unattended policy. + > - `packages/adapters/grok-local/src/index.ts`: config doc updated to explain the new default and the Grok 1.0 semantics. + > - `packages/adapters/grok-local/src/server/execute.test.ts`: default-args assertion now requires the absence of `--permission-mode`; new test covers explicit `permissionMode` pass-through. +- fix(server,ui,claude-local): verify auth on the adapter Test lane and enforce managed-sandbox tenant binding (#11810) + > - Verify `CLAUDE_CODE_OAUTH_TOKEN` and run the hello probe for every Claude ACP target. + > - Keep `adapter_auth_missing` sandbox-only and report missing non-sandbox credentials as a warning. + > - Add a deny-by-default probe environment builder for the ACP and CLI local probes. +- fix(kimi): align package with Node 24 policy (#11890) + > - Update the Kimi adapter to use `@types/node` 24. + > - Add the repository minimum Node.js engine requirement to the Kimi adapter package. + > - Keep `pnpm-lock.yaml` out of this pull request. +- fix(build): enforce Node 24 across Paperclip (#11792) + > - Require Node.js 24.11.0 or newer in all 42 package manifests and runtime checks. + > - Use Node.js 24 in GitHub Actions, Docker images, smoke images, sandbox setup, portable installs, and esbuild targets. + > - Align every direct `@types/node` declaration on `^24.0.0`. +- fix(server): end the duplex route on the pre-bind bounds when frames arrive before the bind (#11860) + > - Give the pre-open frame hold its own ceiling (`MAX_DUPLEX_CHANNEL_PRE_OPEN_HOLD_FRAMES`), separate from the pre-bind buffered-frame bound, so lowering the buffered bound still ends the route instead of being pre-empted by the hold. + > - Keep the buffered chunks on a route end instead of discarding them, so a listener that attaches after an end-during-replay still drains the data the host already accepted. + > - Add two regression tests that batch frames with the open reply, so both bounds run through the pre-bind path deterministically. +- fix(server): handle the runtime service exit persist when a parent row is gone (#11861) + > - Wrap the exit-handler's `cleanupRecordExposure` / `removeLocalServiceRegistryRecord` / `persistRuntimeServiceRecord` sequence in a try/catch; log a warning on failure instead of letting the rejection escape. + > - Terminate real child processes in the embedded-postgres test teardown before the row deletes, so a left-over child does not exit later and write a row that references an already-deleted project. +- fix: preserve plugin detail-tab deep links and bridge the real JSX runtime (#11826) + > - `ui/src/pages/ProjectDetail.tsx`: the plugin-tab fallback now waits until the company is resolved and the plugin-slots query has finished before it decides. While the decision is pending it renders the detail `PageSkeleton` instead of navigating away. Loading a project that fails to load still shows the error state. + > - `ui/src/plugins/bridge-init.ts`: the plugin bridge registry now exposes the host's real `react/jsx-runtime` module as `reactJsxRuntime`. + > - `ui/src/plugins/slots.tsx`: the `react/jsx-runtime` shim served to plugin bundles prefers the bridged runtime's `jsx`/`jsxs`/`Fragment` and keeps the previous `createElement`-based implementation as a fallback. +- fix: exclude thought text from automatic issue comments (#11801) + > - Limit ACPX run summaries to the final non-empty output segment. + > - Ignore the legacy full-summary setting so configuration cannot bypass containment. + > - Update regression tests for the safe default and an attempted unsafe override. +- fix: preserve recovery retries across restarts (#11817) + > - Persist bounded source-owner and manager repair lineages with stable fingerprints and retry limits. + > - Resume incomplete disposition repairs after a server restart. + > - Keep recovery ownership separate from source issue ownership and enforce source mutation authority. +- fix(ui): surface live runtime status in the task-chat tail before the first transcript token (#11802) + > - `ui/src/components/TaskChatThread.tsx`: the live tail's `emptyMessage` prefers `liveRun.currentStatusMessage` (guarded to the run the tail is actually streaming) over the static "Waiting for transcript..." fallback. Queued runs keep "Waiting to start...". + > - `ui/src/components/TaskChatThread.test.tsx`: a test covering both branches — a live run with a runtime status shows it (and not the wait text), and a run without one keeps the generic message. +- fix(runtime): stop the readiness probe from stealing the guest exposure port (#11788) + > - Read listener presence from `/proc` on Linux instead of binding the guest port. + > - Keep the bind probe as the fallback on non-Linux hosts. + > - Capture the current port owner when an exposed guest exits with `EADDRINUSE`. +- fix(workspaces): seed managed worktrees when the base checkout has no config (#11752) + > - `resolveRegisteredWorktreeSeedSource` sets the registered config path only when `/.paperclip/config.json` exists. This makes the existing `registeredConfigPath ?? explicitSource` branch reachable for a plain checkout. + > - A base workspace that does hold its own config stays authoritative. A mismatched explicit source is still rejected. + > - The resolver throws a named error when the base workspace has no config and no source is named. +- fix(ui): task chat composer clears on send; align carets and composer with thread (#11772) + > - `TaskChatComposer.tsx`: clear the draft synchronously when a send starts instead of after the request resolves; restore the draft if the send fails. + > - `TaskChatTurn.tsx` and `TaskChatStatusPill.tsx`: use one shared caret alignment (size, x-offset) for turn disclosure and status pill carets, with supporting utility styles in `ui/src/index.css`. + > - `TaskChatThread.tsx`: align the composer container with the thread column padding. +- fix(server): stamp built commit into service.version (#11748) + > - Add a build script that writes the short Git commit to `dist/build-info.json`. + > - Resolve `service.version` from the build stamp, runtime Git, the environment, or `unknown`. + > - Log the resolved service version once during server startup. +- fix(runtime): route sandbox git-bundle export through native syncOut (#11749) + > - Route bundle export through `nativeSyncOut` when the provider supports it. + > - Keep the existing `readFile` fallback for providers without native sync support. + > - Confine the native bundle mapping with `assertSyncOperationsConfined`. +- fix(runtime): adopt surviving shell-command services (#11744) + > - Detect shell control syntax outside quoted strings. + > - Skip the weak command-line comparison for these shell expressions. + > - Require the live port owner to remain in the recorded process group. +- fix(routines): clear transient execution failures (#9689) + > - Load the linked routine run while synchronizing execution issue status. + > - Restore transiently failed runs to `issue_created` when their execution issue resumes active work. + > - Clear stale failure state when an execution issue completes and retain the earlier failure under `triggerPayload.transientFailure`. +- fix(workspaces): make managed runtimes reliable across restarts (#11740) + > - Added a shared port registry with lease heartbeats, process identity checks, and live listener probes. + > - Reserved worktree ports across custom parent paths and repaired duplicate legacy assignments. + > - Preserved and adopted healthy managed services across control-plane restarts. +- fix(server): make blockers-resolved wake dedup level-triggered (#11732) + > - Add a SHA-256 level-triggered idempotency key from the sorted blocker issue ids. + > - Share one deduplication helper across route-time, finalize-time, and periodic wake paths. + > - Treat state-key rows with idempotent statuses as duplicates. +- fix(workspaces): keep deferred seed databases reliable (#11706) + > - Add a first-class `workspace_seed` operation for deferred database seeds. + > - Require terminal, verified seed evidence before the seed operation succeeds. + > - Surface the seed phase and failure metadata in workspace status and UI state. +- fix(cli): accept renumbered migration journal order (#11684) + > - Compare resolved applied migration names with the expected checkout prefix as an order-independent set. + > - Derive the reported source revision from the checkout prefix instead of database application order. + > - Add unit and embedded-PostgreSQL regressions for shuffled application order, stale unresolved rows, lagging sources, and true divergence. +- fix(worktrees): quarantine cloned runtime services (#11653) + > - Stop cloned project and execution workspace runtime desired state during a full or minimal seed. + > - Change copied service states from `running` to `stopped`. + > - Clear copied process, provider, port, URL, owner, and starter claims. +- fix(workspaces): recover degraded runtime databases (#11651) + > - Require `{ "status": "ok" }` from the assigned loopback health endpoint before runtime reuse or adoption. + > - Refresh persisted runtime health and replace degraded managed processes. + > - Add bounded embedded PostgreSQL restart supervision with coordinated shutdown and hot-restart support. +- fix(release): draft-notes baseline survives candidate-cut stables (#11647) + > - `scripts/draft-stable-notes.sh`: the range start comes from walking stable tags newest-first and taking the first whose merge-base with the beta source is a proper ancestor of the source. Candidate-cut stables resolve to the promoted commit, master-lineage stables to the tag itself, and tags containing the source are skipped (an older-source promotion cannot produce an empty range). The skeleton header prints a runnable short-sha range with the stable tag as a labeled baseline. + > - `scripts/draft-stable-notes.test.mjs`: new regression fixture with the stable tag on an unmerged candidate branch; the existing older-source and fallback fixtures still pass unchanged. +- fix(ui): keep Archive available on every inbox item (#11636) + > - Reused the task-row Archive action for failed runs, approvals, and join requests. + > - Kept the unread marker visible in its own leading slot. + > - Kept retry, approve, and reject actions beside the new trailing Archive action. +- fix(hermes): surface real reasoning text from reasoning.available events (#9237) + > - `packages/adapters/hermes/src/gateway/ui/parse-stdout.ts`: the `reasoning.available` handler now extracts the reasoning text from the event `data` via a small helper (`extractReasoningText`), checking the plausible field names (`reasoning`, `reasoning_text`, `thinking`, `text`, `summary`, `content`) and recursing one level into nested `data` / `payload` records, with ANSI stripped. The prior `"Hermes reasoning available"` string is kept only as a fallback when no text field is present. + > - `packages/adapters/hermes/gateway-ui-parser.cjs`: applied the identical logical change to the committed CommonJS mirror (exported as `./gateway/ui-parser`), keeping the two files in sync. + > - `packages/adapters/hermes/src/gateway/ui/parse-stdout.test.ts` (new): unit tests for the gateway parser (there were none) covering direct-field, `summary`, nested `data`/`payload` extraction, the no-text fallback, and regression guards for `message.delta` and plain stdout. +- fix(adapter-utils): graft unrelated imported histories instead of failing the run (#11638) + > - `git-workspace-sync.ts`: new exported `createUnrelatedHistoryGraftCommit` helper. It reads the imported head's tree and message, and creates one commit on top of the current head with the deterministic sync identity and a trailer that records the graft and both shas. + > - `integrateImportedGitHead` (both the remote-git-sync version and the SSH copy in `ssh.ts`): when `merge-base` reports no common ancestor, graft instead of throwing. The ref update keeps the same compare-and-swap and concurrent-retry semantics as the merge path. + > - The graft is gated on `git merge-base` exiting with status 1 — the no-ancestor signal. Operational failures (timeout, missing object, repository error) keep the loud merge failure instead of rewriting the tip. +- fix(adapter-utils): give sync-created merge commits a deterministic git identity (#11637) + > - `git-workspace-sync.ts`: new exported `GIT_SYNC_COMMIT_IDENTITY_ARGS` (`-c user.name=Paperclip -c user.email=noreply@paperclip.ing`), applied to the `commit-tree` call in `integrateImportedGitHead`. + > - `ssh.ts`: the SSH-sync copy of `integrateImportedGitHead` applies the same identity args to its `commit-tree` call. + > - New regression test: builds divergent histories in a repo with no configured identity and asserts the sync merge commit is created with the deterministic identity, correct parents, and merged tree. +- fix(server): skip host provisionCommand for sandbox-driver environments (#11626) + > - Skip the orchestrator provision step when `environment.driver` is `sandbox`. + > - Keep the existing skip for `local` and the provision step for `ssh`. + > - Log one info message when a sandbox skip drops a present command. +- fix(markdown): make rendered code blocks follow the active theme (#11591) + > - Bind `.paperclip-markdown pre` to `--muted`, `--foreground`, `--border` and `--radius-lg` in `ui/src/index.css`. Remove the `#1e1e2e` and `#cdd6f4` literals. + > - Set the four `--tw-prose-*-pre-*` variables to the same tokens, so `prose` and `prose-invert` both follow the theme. + > - Apply the same four tokens to `.paperclip-mdxeditor-content pre`. +- fix(server): reject invalid agent credentials instead of downgrading to the local user actor (#11589) + > - `server/src/middleware/auth.ts`: a bearer token that fails verification now produces a 401 `unauthorized` error instead of a silent fall-through to the anonymous/local-user actor. + > - The 401 message states the cause: expired token, unverifiable token, empty bearer token, missing agent record, agent record in another company, terminated agent, or agent pending approval. + > - The API-key path now also rejects an agent record whose company does not match the key. + +## Other changes + +- build(deps): bump @agentclientprotocol/claude-agent-acp from 0.69.0 to 0.70.0 (#11873) + > Bumps [@agentclientprotocol/claude-agent-acp](https://github.com/agentclientprotocol/claude-agent-acp) from 0.69.0 to 0.70.0. + >
+- build(deps-dev): bump @storybook/react-vite from 10.5.8 to 10.5.10 (#11868) + > Bumps [@storybook/react-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite) from 10.5.8 to 10.5.10. + >
+- build(deps-dev): bump @types/supertest from 6.0.3 to 7.2.1 (#11878) + > Bumps [@types/supertest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/supertest) from 6.0.3 to 7.2.1. + >
+- build(deps): bump @mdxeditor/editor from 3.55.0 to 4.2.1 (#11870) + > Bumps [@mdxeditor/editor](https://github.com/mdx-editor/editor) from 3.55.0 to 4.2.1. + >
+- build(deps-dev): bump esbuild from 0.28.1 to 0.28.2 (#11882) + > Bumps [esbuild](https://github.com/evanw/esbuild) from 0.28.1 to 0.28.2. + >
+- build(deps): bump @aws-sdk/client-s3 from 3.1111.0 to 3.1115.0 (#11876) + > Bumps [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) from 3.1111.0 to 3.1115.0. + >
+- build(deps-dev): bump @storybook/addon-a11y from 10.5.8 to 10.5.10 (#11874) + > Bumps [@storybook/addon-a11y](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/a11y) from 10.5.8 to 10.5.10. + >
+- build(deps): bump react-resizable-panels from 4.12.2 to 4.12.3 (#11872) + > Bumps [react-resizable-panels](https://github.com/bvaughn/react-resizable-panels) from 4.12.2 to 4.12.3. + >
+- build(deps): bump @assistant-ui/react from 0.15.14 to 0.15.16 (#11888) + > Bumps [@assistant-ui/react](https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react) from 0.15.14 to 0.15.16. + >
+- build(deps): bump googleapis from 174.0.1 to 176.0.0 (#11889) + > Bumps [googleapis](https://github.com/googleapis/google-api-nodejs-client) from 174.0.1 to 176.0.0. + >
+- build(deps): bump @agentclientprotocol/codex-acp from 1.2.0 to 1.6.2 (#11883) + > Bumps [@agentclientprotocol/codex-acp](https://github.com/agentclientprotocol/codex-acp) from 1.2.0 to 1.6.2. + >
+- build(deps): bump @codemirror/view from 6.43.8 to 6.43.9 (#11879) + > Bumps [@codemirror/view](https://github.com/codemirror/view) from 6.43.8 to 6.43.9. + >
+- build(deps-dev): bump storybook from 10.5.5 to 10.5.10 (#11884) + > Bumps [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/core) from 10.5.5 to 10.5.10. + >
+- refactor(adapter-utils): remove the retired duplex_v1 sandbox bridge transport (#12171) + > - Delete the host `duplex_v1` broker and its transport-only tests. + > - Delete the in-sandbox duplex gateway and retired mode constants. + > - Move shared `http2_v1` symbols into `bridge-transport-contract.ts`. +- refactor(adapter-utils): clean up the HTTP/2 bridge request-body bounds (#12166) + > - Remove the renewable request-body lifetime bound and its public names. + > - Keep the total-lifetime ceiling as a one-shot timer that starts when the body read starts. + > - Replace repeated bound parameters with one `Http2BridgeBodyBounds` object. +- refactor(adapter-utils): rename EffectiveSandboxCapabilities to EffectiveExecutionCapabilities (#12119) + > - Rename the exported interface to `EffectiveExecutionCapabilities`. + > - Keep `EffectiveSandboxCapabilities` as a deprecated type alias. + > - Rename the private parser and update its call site and references. +- test(release-smoke): cover the background-service leg of onboarding (#12151) + > - New `scripts/service-onboard-smoke.sh`: onboards the published artifact with `--yes --install-service` on a systemd host, then fails unless the managed shim exists and is executable, `paperclipai.service` is active, and `/api/health` answers. A health response while the unit is not active also fails, because that is the signature of something other than the service serving. The script refuses to run over an existing managed install unless `SMOKE_FORCE=true`, and cleans up after itself by default so it is safe to run locally. + > - New `smoke_service` job in `.github/workflows/release-smoke.yml`: starts a user systemd session on the hosted runner (`loginctl enable-linger` + exported `XDG_RUNTIME_DIR`/`DBUS_SESSION_BUS_ADDRESS`), runs the script against `inputs.paperclip_version`, and uploads `systemctl status` + journal output as diagnostics. + > - No `release.yml` changes needed: `smoke_nightly` and `smoke_beta` call this reusable workflow, and a `workflow_call` result aggregates all jobs, so the new job gates nightly promotion automatically. +- docs(release): canonicalize stable notes for v2026.824.0 (#12139) + > - `git mv`-equivalent rename of the beta-keyed notes to `releases/v2026.824.0.md`, exactly as the release published them. +- test(release-smoke): follow the mission-less onboarding reorder (#12135) + > - Remove the mission-step interaction; step 1's "Next" now creates the company and the spec goes straight to the agent step. + > - Replace the mission-goal API assertion with the truthful one: onboarding deliberately writes no goal, so a fresh company's goal list is empty. + > - Update step comments to match the shipped flow. +- docs(release): re-date the 2026.818.0-beta.1 stable notes to v2026.824.0 (#12113) + > - Three header/intro lines re-dated. Nothing else. +- refactor: disambiguate the Telemetry and Observability data paths (#12128) + > - Rename the duplex instrumentation modules and identifiers from `Telemetry` to `Observability`. + > - Move the Observability and run-log contracts out of the Telemetry README. + > - Add `doc/observability.md` and `doc/run-log-events.md` as the canonical documents. +- Add canonical semantic action catalog to Paperclip Runner (#12121) + > - Added 27 versioned, provider-neutral semantic action declarations for the Codex spine. + > - Added bounded JSON Schema input contracts and normalized operation receipt output contracts. + > - Added placement, effect, claim, mode, and role metadata. +- Add Codex provider bridge to Paperclip Runner (#12111) + > - Added a Codex-only app-server process transport with bounded JSONL frames and buffered notifications. + > - Added strict provider descriptor validation for the Codex driver, working directory, launch arguments, model, instructions, and non-interactive approval policy. + > - Started new Codex threads with an empty dynamic tool inventory and the named workspace-only permission profile. +- chore(lockfile): refresh pnpm-lock.yaml (#12094) + > - `pnpm-lock.yaml` regenerated by the refresh automation (pnpm 9.15.4, `--lockfile-only`); the diff covers only the `packages/paperclip-runner` importer's new devDependencies. A human empty commit triggered the required checks (the automation's `GITHUB_TOKEN` push cannot — fix proposed in #12115). +- Add durable PRP transport and recovery (#12100) + > - Added a loopback-only WebSocket connection policy with one-time DNS resolution and pinned reconnect addresses. + > - Added an HMAC mutual-authentication handshake that never sends the bootstrap ticket over the socket. + > - Added AES-256-GCM secure frames with per-direction keys, monotonic counters, and session-bound authenticated data. +- Add local fake runner supervision (#12095) + > - Added a minimal locked Rust workspace with only `serde` and `serde_json` dependencies. + > - Added a package-local `paperclip-runnerd` local mode and a scripted fake harness. + > - Added bounded controller input, harness input, subprocess output queues, line sizes, log retention, script sizes, script steps, and command history. +- ci: refresh general-server shard duration manifest (#12075) + > - Regenerated `scripts/general-server-shard-durations.json` from actions run 32708351172 (2026-08-24): 405 suites, 1274s total serial time (was 279 suites, 946s from 2026-08-04) + > - Updated the `$comment` field to name the new sample run and date + > - No code changes; the partition logic in `scripts/general-server-shard.mjs` is untouched +- Add TypeScript PRP replay contracts (#12091) + > - Added JSON-Schema-derived PRP v1 types and AJV runtime validation. + > - Added fail-closed required-version checks and cross-envelope binding checks. + > - Added provider-neutral completion-result and structured-question contracts. +- chore(lockfile): refresh pnpm-lock.yaml (#12090) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- docs(runner): define architecture and compatibility (#12084) + > - Added an architecture decision for the runner process, PRP v1 transport, semantic tools, durable recovery, and additive server integration. + > - Added a compatibility and rollout contract for the default-off adapter, existing direct adapters, persisted native runs, and the task page. + > - Defined the initial package and provider limits. The first production provider is Codex only. +- Brand lockup, no idle env-check card, no Mission row (#12074) + > - `PaperclipLockup` renders the brand asset (mark + wordmark, one geometry, `fill="currentColor"`); the auth page uses it in place of the sparkles icon. + > - The adapter environment check's idle card (explainer + "Test now") no longer renders. The probe still runs on Connect and still blocks a failing hire. + > - The check's failure content still renders when a probe has found something — the blocking error points the customer at "the reported checks", so they stay visible. +- refactor(environment): classify environment capabilities from static driver definitions (#12045) + > - Add classifyEnvironmentCapabilities and static support definitions for all four driver families. + > - Add resolveCapabilities to every environment runtime driver. + > - Move driver traits into environment-driver-traits.ts and migrate runtime consumers. +- Drop the mission step from the wizard arc (#11935) + > - `onboardingStepForCompany` always returns the agent step. The `companyHasMission` parameter is removed, because it cannot change the answer. + > - `resolveRouteOnboardingOptions` no longer accepts `companyHasMission`. + > - The dashboard no longer waits for the goal lookup before it opens the wizard. That wait only chose a step, and the step is now fixed. +- chore(lockfile): refresh pnpm-lock.yaml (#11915) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- Rebuild the onboarding agent arc on the prototype's step design (#11905) + > - Add `ui/src/components/onboarding/`: `Stepper`, `OnboardingCard`, + > - Rebuild wizard steps 3–5 on those parts: one card, the capsule above a + > - Hold one `AgentCapsule` across the three steps. It springs in once, then +- Fix remote-only workspace base refs and pre-adapter retry loops (#11892) + > - Resolve remote-only base refs with the authenticated fetch helper before `git worktree add`. + > - Support both unqualified refs and remote-tracking refs. + > - Raise a `configuration_incomplete` blocker when the requested ref remains unresolved. +- test(server): cover buffered duplex chunk drain after a late listener bind (#11865) + > - Add one server regression test for late-listener delivery after byte-cap route termination. + > - Keep the product code unchanged in this pull request. +- chore(lockfile): refresh pnpm-lock.yaml (#11867) + > - Regenerated `pnpm-lock.yaml` from the current package manifests. +- ci(release): raise npm publish visibility budget to 10 minutes per package (#11835) + > - `NPM_PUBLISH_VERIFY_ATTEMPTS` 30 → 60 (with `NPM_PUBLISH_VERIFY_DELAY_SECONDS: "10"`, a 10-minute per-package budget), plus the comment documenting the observed near-miss. +- build(deps): bump zod from 3.25.76 to 4.4.3 (#11719) + > Bumps [zod](https://github.com/colinhacks/zod) from 3.25.76 to 4.4.3. + >
+- ci(release): give npm publish visibility polling a 10-minute budget (#11834) + > - Set `NPM_PUBLISH_VERIFY_ATTEMPTS: "30"` and `NPM_PUBLISH_VERIFY_DELAY_SECONDS: "10"` in the `Release` workflow's top-level `env`, raising `release.sh`'s post-publish visibility poll from 60 seconds to 5 minutes per package for every channel. Both variables are existing overrides read by the script (`scripts/release.sh` lines 311-312); no script change. + > - Raised the four publish jobs' `timeout-minutes` from 45 to 90 so several laggard packages fit inside the job without exhausting it before the tag push / Docker / release steps. +- ci(commitperclip): remove the security gate that filed a draft advisory per PR (#11828) + > - Deleted `.github/scripts/check-pr-security.mjs` and `.github/scripts/tests/check-pr-security.test.mjs`. + > - Removed the `Run security gates` step from `.github/workflows/commitperclip-review.yml`, and the `security-events: write` permission that only it used. + > - No other script imports from the removed module (`resolveBaseRef` lives in `check-pr-dependencies.mjs` and stays). +- build(deps-dev): bump @vitejs/plugin-react from 4.7.0 to 6.0.5 (#11710) + > Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 4.7.0 to 6.0.5. + >
+- build(deps): bump @clack/prompts from 0.11.0 to 1.7.0 (#11724) + > Bumps [@clack/prompts](https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts) from 0.11.0 to 1.7.0. + >
+- build(deps): bump googleapis from 164.1.0 to 174.0.1 (#11723) + > Bumps [googleapis](https://github.com/googleapis/google-api-nodejs-client) from 164.1.0 to 174.0.1. + >
+- build(deps): bump chokidar from 4.0.3 to 5.0.0 (#11720) + > Bumps [chokidar](https://github.com/paulmillr/chokidar) from 4.0.3 to 5.0.0. + >
+- chore(lockfile): refresh pnpm-lock.yaml (#11786) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- test(server): deflake postgres teardown and pinned exposure port (#11667) + > - `interaction-resolution-cross-issue-cap-postgres.test.ts`: `afterAll` now ends the drizzle/postgres.js pool (`db.$client.end()`) before it stops the embedded Postgres server. `end()` waits for in-flight queries, including a fire-and-forget wake that lands just after a response, and closes the sockets from the client side first. Sibling suites (for example `heartbeat-plugin-environment.test.ts`) already use this order; this suite had skipped the pool shutdown. + > - `workspace-runtime-exposure.test.ts`: the pinned-port test no longer hard-codes 42500. It scans the dedicated range with the suite's real loopback probe, finds the lowest free app/HMR pair, then pins the next free pair strictly above it. If the keep-preferred-port path broke, the ascending fallback scan would return the lower pair, so the assertion keeps its discriminating power while no longer betting on one fixed host port staying free. + > - *(Dropped on rebase: the `workspace-git-operation-scheduler.test.ts` coalescing fix, superseded by the equivalent barrier merged in [#11671](https://github.com/paperclipai/paperclip/pull/11671).)* +- build(deps): bump pino-http from 10.5.0 to 11.0.0 (#11716) + > Bumps [pino-http](https://github.com/pinojs/pino-http) from 10.5.0 to 11.0.0. + >
+- refactor(settings): unify settings and speed up exports (#11789) + > - Unified company and instance settings navigation and removed duplicate instance settings pages. + > - Embedded general instance controls in the company General page and kept access-sensitive navigation behavior. + > - Preserved instance Access and Heartbeats controls in the unified navigation and normalized old bookmarks to those destinations. +- build(deps): bump jsdom and @types/jsdom (#11717) + > Bumps [jsdom](https://github.com/jsdom/jsdom) and [@types/jsdom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jsdom). These dependencies needed to be updated together. + > Updates `jsdom` from 28.1.0 to 30.0.1 +- build(deps): bump @assistant-ui/react from 0.14.14 to 0.15.14 (#11725) + > Bumps [@assistant-ui/react](https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react) from 0.14.14 to 0.15.14. + >
+- build(deps): bump @agentclientprotocol/claude-agent-acp from 0.66.0 to 0.69.0 (#11728) + > Bumps [@agentclientprotocol/claude-agent-acp](https://github.com/agentclientprotocol/claude-agent-acp) from 0.66.0 to 0.69.0. + >
+- build(deps): bump react-dom and @types/react-dom (#11712) + > Bumps [react-dom](https://github.com/react/react/tree/HEAD/packages/react-dom) and [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom). These dependencies needed to be updated together. + > Updates `react-dom` from 19.2.7 to 19.2.8 +- build(deps): bump react and @types/react (#11721) + > Bumps [react](https://github.com/react/react/tree/HEAD/packages/react) and [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react). These dependencies needed to be updated together. + > Updates `react` from 19.2.7 to 19.2.8 +- test(runtime): assert order-independent port invariants for concurrent siblings (#11754) + > - Replace lane-order assertions with order-independent port invariants. + > - Assert distinct ports, the base lower port, and the bounded upper port. + > - Keep concurrent startup, service URL checks, and persisted-row checks. +- build(deps): bump radix-ui from 1.6.4 to 1.6.7 (#11726) + > Bumps [radix-ui](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/radix-ui) from 1.6.4 to 1.6.7. + >
+- build(deps): bump @aws-sdk/client-s3 from 3.1106.0 to 3.1111.0 (#11714) + > Bumps [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) from 3.1106.0 to 3.1111.0. + >
+- chore(lockfile): refresh pnpm-lock.yaml (#11737) + > Auto-generated lockfile refresh after dependencies changed on master. This PR only updates pnpm-lock.yaml. +- build(deps-dev): bump @storybook/addon-a11y from 10.5.4 to 10.5.8 (#11713) + > Bumps [@storybook/addon-a11y](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/a11y) from 10.5.4 to 10.5.8. + >
+- build(deps): bump react-i18next from 17.0.10 to 17.0.11 (#11711) + > [//]: # (dependabot-start) + > ⚠️ **Dependabot is rebasing this PR** ⚠️ +- build(deps): bump react-router-dom from 7.18.1 to 7.18.2 (#11715) + > Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 7.18.1 to 7.18.2. + >
+- build(deps-dev): bump tailwindcss from 4.3.2 to 4.3.3 (#11718) + > Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) from 4.3.2 to 4.3.3. + >
+- build(deps-dev): bump tsx from 4.23.1 to 4.23.12 (#11722) + > Bumps [tsx](https://github.com/privatenumber/tsx) from 4.23.1 to 4.23.12. + >
+- build(deps): bump ws from 8.21.1 to 8.21.3 (#11729) + > Bumps [ws](https://github.com/websockets/ws) from 8.21.1 to 8.21.3. + >
+- chore(deps): open one dependabot PR per major update (#11709) + > - Remove the `major-updates` group from the npm Dependabot entry. + > - Raise the npm `open-pull-requests-limit` from 10 to 20. + > - Keep the GitHub Actions Dependabot entry unchanged. +- test(workspaces): fix runtime provision metadata assertion (#11707) + > - Move the `provisionKind` assertion from `result.metadata` to the operation's top-level `metadata`. + > - Keep the `result.status` assertion unchanged. +- build(deps): bump @cursor/sdk from 1.0.24 to 1.0.28 (#11520) + > Bumps [@cursor/sdk](https://github.com/cursor/cursor) from 1.0.24 to 1.0.28. + >
+- build(deps): bump @base-ui/react from 1.6.0 to 1.7.0 (#11518) + > Bumps [@base-ui/react](https://github.com/mui/base-ui/tree/HEAD/packages/react) from 1.6.0 to 1.7.0. + >
+- build(deps): bump open from 11.0.0 to 11.0.1 (#11517) + > Bumps [open](https://github.com/sindresorhus/open) from 11.0.0 to 11.0.1. + >
+- build(deps): bump better-auth from 1.6.25 to 1.6.28 (#11516) + > Bumps [better-auth](https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth) from 1.6.25 to 1.6.28. + >
+- build(deps): bump @agentclientprotocol/codex-acp from 1.1.7 to 1.2.0 (#11515) + > Bumps [@agentclientprotocol/codex-acp](https://github.com/agentclientprotocol/codex-acp) from 1.1.7 to 1.2.0. + >
+- build(deps-dev): bump @storybook/react-vite from 10.5.0 to 10.5.8 (#11514) + > Bumps [@storybook/react-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite) from 10.5.0 to 10.5.8. + >
+- docs(skills): changelog entries describe deltas, not repeats (#11663) + > - `.agents/skills/release-changelog/SKILL.md`: a "describe deltas, not repeats" guideline in Step 4, with the read-the-previous-notes instruction and the headline-demotion rule. + > - `.agents/skills/release-changelog-discord-message/SKILL.md`: one mirrored bullet in the template notes. +- docs(release): stable notes for the 2026.818.0-beta.1 soak (v2026.821.0) (#11661) + > - Rewrite `releases/beta/v2026.818.0-beta.1.md` from skeleton to finished notes. Headline themes: chat-style tasks as the default experience, Tailscale HTTPS managed runtime exposure, sandbox capability contract with live output streaming, in-product Claude/Codex sign-in, chunked resumable company imports, and the completed release-channel automation. + > - Five verified breaking/behavior changes, including the `enableTaskChatRedesign` → `enableClassicTaskInterface` toggle inversion and migration `0218`'s conservative resolver-policy remap. + > - Contributors: 172 commits from 32 non-bot authors; 22 verified community handles listed (founders/core excluded per the canonical list; 4 authors omitted as unverifiable rather than guessed). +- build(deps-dev): bump @storybook/addon-docs from 10.5.0 to 10.5.8 (#11513) + > Bumps [@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs) from 10.5.0 to 10.5.8. + >
+- build(deps-dev): bump @playwright/test from 1.61.1 to 1.62.1 (#10734) + > Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.61.1 to 1.62.1. + >
+- Add governed secret alias confirmation cards (#11486) + > - Added safe source-config-path binding proposals and preserved user-secret ownership checks. + > - Added a proposal-to-interaction link and an idempotent database migration. + > - Minted human-only `request_confirmation` cards with server-owned `secretProposal` metadata. +- refactor(acpx-engine): coordinator-owned ACP run lifecycle with a typed resource ledger (#11576) + > - Add a run coordinator for startup, turn execution, settlement, and result reproduction. + > - Add a typed resource ledger with open, sealed, and consumed states. + > - Add host and sandbox run sites for lane-specific resource acquisition. +