A single quote and an ANSI-C `$'` are what JSON serialization leaves alone,
so unlike a double quote they name no layer. The reading set gave them
depth 0 alone, so a serialized double-quoted segment adjacent to the closing
quote was read as an escaped quote followed by a word-ending space, and its
bytes stayed in the clear at every depth from 1 up. Bash joins them to the
header word. Seed the tail after such an argument at every layer the unquoted
reading set already carries and take the longest, which is what the union
policy asks for.
The body stays at depth 0 on purpose: these quotes delimit the same bytes at
every layer, and reading the body deeper would take an ANSI-C escape for a
plain backslash and close the value early.
A backslash-newline is a line continuation. The token reader already named
it, but the word scan returned at it as though it were a boundary, so the
bytes on the next physical line stayed in the clear after an unquoted value
and after a closed quoted argument. The shell removes the pair and joins the
lines into one word, so the scan follows it now. Inside a quoted part the
handling is unchanged.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
The growth loop settles because the placeholder carries no byte that stops a
scan: no quote, no backslash, no whitespace, no backtick, no metacharacter.
Every caller passes `***REDACTED***`, so the assumption holds today, but it
is an assumption about a parameter and it belongs next to the loop that
depends on it.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
Promote the round-eight review matrices into repository tables so the
scanner's contract is checked here rather than in a harness under /tmp.
Opener kind by value kind by suffix kind by serialization depth 0 to 3,
including the adjacent double-quoted segment whose first byte is a space
that leaked at depths 2 and 3. Truncated tails of each quote kind after each
root kind, including the escaped-quote tail whose remainder leaked. Even
backslash runs of 2, 4, 6 and 8 before a quote, a plain character, a space
and a line end.
Serialized rows assert the marker is gone, the output is stable, and the
output still parses as the JSON string it arrived as and decodes to the
redacted shell text. Truncated rows assert removal and stability only: a
serialized string cut inside the header argument loses its outer delimiter,
which is the contract's known over-redaction and never keeps a credential.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
The header-secret rule was one composite regular expression with six
branches. Command text arrives at an unknown serialization depth, and the
same bytes mean opposite things at depth 0 and inside a JSON string, so
every generalisation made for shell text broke serialized text or the
reverse. Replace the whole thing with a bounded forward scanner.
The scanner keeps the candidate detector as a regular expression: a header
name, its colon, and an optional auth scheme are all a pattern can decide on
its own. Everything after that is scanned in code, in one pass, linear in
the length of the line.
The contract is union over readings, never a guess. For each candidate the
scanner enumerates the plausible readings of the surrounding text, scans the
header's shell word once per reading, and redacts the longest span. A
reading that disagrees can only lengthen the redaction, so disagreement
over-redacts and never leaks. A reading is one number: the backslash run
that spells a quote at that layer, with depth 0 as the run of length zero,
which collapses the shell and serialized cases into one code path.
Two leaks close. A serialized adjacent double-quoted segment whose first
byte is a space is now consumed with the word it belongs to, at every depth.
A truncated double-quoted tail carrying an escaped quote after a closed
escaped value no longer leaves its remainder in the clear; bash reads those
bytes as part of the credential-bearing word.
One pass settles. The placeholder that replaces a value carries no quote, no
backslash and no separator, so a second pass reads the output in a state the
first pass never reached. The scanner consumes now whatever such a pass
would consume, which keeps the caller's chain stable.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
The even-run escape pair now requires a character that is neither a quote
nor a backslash after the run, so a run of any even length is consumed by
the odd alternative as pairs plus an escaped backslash and the following
quote opens a segment of the same word. The continuation may end with one
unterminated quoted segment that runs to the end of the line, so a log cut
inside the last segment of a header word still redacts it.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
An escape-pair segment is either an even backslash run followed by a
character other than a quote, the form a serialized escaped space takes,
or an odd run followed by any character, a true shell escape. An even run
before a quote is an escaped backslash and the quote opens a further
segment of the same word, which the value consumes. A truncated
escaped-quoted value runs to the end of its line again: a bare quote there
may be a further segment of the word, so it is redacted rather than kept
as an enclosing delimiter.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
A shell escape pair doubles its backslash with every serialization layer,
so the continuation and opening escape-pair segments now consume the whole
backslash run with the character it escapes. An escaped-space segment
adjacent to a header value inside a serialized command is therefore part
of the value at any depth.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
A suffix segment adjacent to a serialized quoted header argument belongs to
the same shell word, so the serialized branch now takes the shell
continuation after its closer. A truncated serialized argument has no
closer on its line; its value then stops before a bare quote, one preceded
by an even run of backslashes, which can only be the enclosing serializer's
delimiter, so that string stays parseable. The closer of an escaped-quoted
value must itself be unescaped, so backtracking cannot read an escaped
backslash as the closer.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
An escaped-quoted argument carries a backslash run before its quote that
doubles and grows by one with every serialization layer, so a rule that
requires exactly one backslash misses a command serialized twice. Both
escaped-quote branches now capture the odd backslash run of the opener and
close on the same run, with a tempered body that keeps deeper embedded
quotes and a dangling trailing backslash inside the value. A scheme word
may precede the escaped opener as well as follow it. Every capture group
is named and the replace callback reads the groups object.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
A value written with escaped quotes after the colon, the form an outer
shell uses to pass quote syntax to `sh -c`, had no owner: the unquoted
branch declines an escaped-quote opener so the server's own authorization
rule keeps its shape. A dedicated branch now redacts that value and keeps
the escaped quotes, so both rules agree on the same text. The unquoted
branch also keeps a value's own delimiters when the value is quoted after
the colon, which makes the rule idempotent across the log-writer and UI
passes. The replace callback selects prefix, opener, and closer from the
defined capture groups.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
The first segment of an unquoted header value may open on an escape pair,
so a value whose first byte is an escaped space is consumed, while an
escaped-quote opener still falls to the caller's own rules. That first
segment is bounded by whitespace only: a raw HTTP diagnostic carries an
opaque credential the same way, so a shell metacharacter inside it is a
credential byte. Only a continuation segment after a closing quote stops
at a metacharacter, which keeps a following separator or command intact.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
A header value is the rest of its shell word, which can concatenate
unquoted, double-quoted, single-quoted, ANSI-C-quoted, and backslash-escaped
segments. The rule now consumes every segment of that word before writing
one placeholder, stops at whitespace and shell metacharacters so the next
argument survives, and still redacts a run-log line truncated inside a
quoted value. The recognized scheme list gains the registered `Concealed`
scheme, and a quoted Digest parameter may carry HTTP quoted-pairs.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
A serialized command writes a double-quoted header argument with escaped
quotes. The escaped opener fell through to the unquoted branch, which
stops at the first backslash, so a multi-part credential such as a Digest
value kept its later fields. A fourth branch mirrors the double-quoted one
over `\"` delimiters and consumes the doubled escape sequences an embedded
quote or backslash becomes.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
A backslash-newline continuation inside a double-quoted header argument
ended the quoted match, so the unquoted fallback redacted only the part of
the credential before the continuation. The double-quoted branch now treats
the continuation as part of the value, with LF and CRLF line endings.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
A double-quoted header value stopped at the first backslash, so a
credential with an embedded escaped quote such as `"X-API-Key: abc\"def"`
kept its tail in the recorded text. The double-quoted branch now consumes
escape pairs and requires an unescaped opening quote, which keeps it off a
serialized diagnostic where `\"` is the JSON escape. The single-quoted
branch takes a backslash literally. Only the unquoted branch still stops at
a backslash.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
The header rule stopped at the first whitespace or quote, so a multi-part
credential such as a Digest or AWS SigV4 authorization value lost only its
first token. It also matched any bare word carrying a credential hint, so
prose and paths like `auth: failed` or `/v1/tokens:list` were redacted.
The value is now bounded by its context: to the closing quote inside a
quoted shell argument, and to the end of a comma-separated `key=value` list
or a single token when unquoted. A header name must be hyphenated or
underscored, or be the bare `authorization` or `apikey`; the
`www-authenticate` and `proxy-authenticate` challenge headers are excluded.
The recognized scheme list follows the IANA registry plus
`AWS4-HMAC-SHA256` and `Token`.
Claude-Session: https://claude.ai/code/session_01RYigf3eMFJjey9iKRApPGE
The command redaction covered `Authorization: Bearer <value>`, shell
`NAME=value` assignments, and common token shapes. It did not cover a
credential passed in any other header. A `curl -H "X-API-Key: <token>"`
command therefore kept the token in clear in a run log.
A new rule redacts the value of any header whose name contains an api-key,
token, secret, or auth hint. The rule keeps an optional auth scheme in the
output, so `Authorization: Bearer <value>` produces the same text as
before. `Authorization: Basic <value>` is now redacted too. The value ends
at the first quote, backslash, or whitespace, so the rule stops at the end
of one header argument.
Claude-Session: https://claude.ai/code/session_01U9PF3d9SASC9tomDRjyeVt
## Thinking Path
> - The trusted target-branch runner workflow checks out PR code before
paid tests.
> - PR policy intentionally forbids manual lockfile commits.
> - Some runner changes legitimately alter pnpm patch hashes.
> - Frozen installs therefore fail before test selection.
> - Resolve one script-disabled lockfile from the authorized immutable
target SHA and distribute it by exact artifact ID and digest.
> - Keep provider credentials and trusted reporting outside this
resolution job.
## Linked Issues or Issue Description
Target-branch paid runner campaigns currently fail frozen install when a
PR changes pnpm patch content, even though ordinary PR CI regenerates
the lockfile.
## What Changed
- 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.
- Changed the disabled-AWS fallback from unavailable ubuntu-latest-m to
ubuntu-latest.
## Risks
The workflow evaluates pnpm lockfile resolution from authorized target
code. That job receives no provider credentials, disables lifecycle
scripts, rejects unrelated workspace mutations, and exposes only a
digest-verified lockfile artifact. Paid-secret jobs consume only that
lockfile after exact artifact-ID and SHA-256 validation.
## Verification
- Runner workflow-security focused tests pass.
- actionlint passes.
- Prettier and git diff checks pass.
## Model Used
OpenAI Codex, GPT-5.
## Checklist
- [x] Change is narrowly scoped to paid runner orchestration.
- [x] Target lock resolution has no provider credentials and disables
lifecycle scripts.
- [x] Downloaded artifacts are selected by exact artifact ID and
verified by SHA-256.
- [x] Trusted reporting and history jobs remain on the workflow SHA.
Bumps
[paperclipai/paperclip/.github/workflows/pr-trusted.yml](https://github.com/paperclipai/paperclip)
from 39b8ee2960 to
f038633bf5.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/paperclipai/paperclip/blob/master/doc/RELEASE-AUTOMATION-SETUP.md">paperclipai/paperclip/.github/workflows/pr-trusted.yml's
changelog</a>.</em></p>
<blockquote>
<h1>Release Automation Setup</h1>
<p>This document covers the GitHub and npm setup required for the
current Paperclip release model:</p>
<ul>
<li>automatic canaries from <code>master</code></li>
<li>manual stable promotion from a chosen source ref</li>
<li>npm trusted publishing via GitHub OIDC</li>
<li>protected release infrastructure in a public repository</li>
</ul>
<p>Repo-side files that depend on this setup:</p>
<ul>
<li><code>.github/workflows/release.yml</code></li>
<li><code>.github/CODEOWNERS</code></li>
</ul>
<p>Note:</p>
<ul>
<li>the release workflows intentionally use <code>pnpm install
--no-frozen-lockfile</code></li>
<li>this matches the repo's current policy where
<code>pnpm-lock.yaml</code> is refreshed by GitHub automation after
manifest changes land on <code>master</code></li>
<li>the publish jobs then restore <code>pnpm-lock.yaml</code> before
running <code>scripts/release.sh</code>, so the release script still
sees a clean worktree</li>
</ul>
<h2>1. Merge the Repo Changes First</h2>
<p>Before touching GitHub or npm settings, merge the release automation
code so the referenced workflow filenames already exist on the default
branch.</p>
<p>Required files:</p>
<ul>
<li><code>.github/workflows/release.yml</code></li>
<li><code>.github/CODEOWNERS</code></li>
</ul>
<h2>2. Configure npm Trusted Publishing</h2>
<p>Do this for every public package that Paperclip publishes.</p>
<p>At minimum that includes:</p>
<ul>
<li><code>paperclipai</code></li>
<li><code>@paperclipai/server</code></li>
<li><code>@paperclipai/ui</code></li>
<li>public packages under <code>packages/</code></li>
</ul>
<h3>2.1. In npm, open each package settings page</h3>
<p>For each package:</p>
<ol>
<li>open npm as an owner of the package</li>
<li>go to the package settings / publishing access area</li>
<li>add a trusted publisher for the GitHub repository
<code>paperclipai/paperclip</code></li>
</ol>
<h3>2.2. Add one trusted publisher entry per package</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f038633bf5"><code>f038633</code></a>
feat(runner): reduce ACPX provider state (<a
href="https://redirect.github.com/paperclipai/paperclip/issues/12417">#12417</a>)</li>
<li><a
href="7bb6cebeae"><code>7bb6ceb</code></a>
feat(runner): normalize ACPX provider events (<a
href="https://redirect.github.com/paperclipai/paperclip/issues/12416">#12416</a>)</li>
<li><a
href="fe2ddfad2b"><code>fe2ddfa</code></a>
feat(runner): validate ACPX event payloads (<a
href="https://redirect.github.com/paperclipai/paperclip/issues/12415">#12415</a>)</li>
<li><a
href="3db24d9366"><code>3db24d9</code></a>
feat(runner): bind ACPX event scope (<a
href="https://redirect.github.com/paperclipai/paperclip/issues/12414">#12414</a>)</li>
<li><a
href="75708fec6d"><code>75708fe</code></a>
feat(runner): add ACPX sidecar transport (<a
href="https://redirect.github.com/paperclipai/paperclip/issues/12412">#12412</a>)</li>
<li><a
href="9ad8dbffa0"><code>9ad8dbf</code></a>
feat(runner): add Codex ACPX sidecar (<a
href="https://redirect.github.com/paperclipai/paperclip/issues/12410">#12410</a>)</li>
<li><a
href="b93ad538b6"><code>b93ad53</code></a>
test(runner): add question adapter conformance (<a
href="https://redirect.github.com/paperclipai/paperclip/issues/12409">#12409</a>)</li>
<li><a
href="4fe3189f02"><code>4fe3189</code></a>
feat(runner): bridge Codex ACPX questions (<a
href="https://redirect.github.com/paperclipai/paperclip/issues/12408">#12408</a>)</li>
<li><a
href="96421b0663"><code>96421b0</code></a>
feat(runner): recover settled Codex ACPX sessions (<a
href="https://redirect.github.com/paperclipai/paperclip/issues/12407">#12407</a>)</li>
<li><a
href="30ef14edd4"><code>30ef14e</code></a>
feat(runner): wire the Codex ACPX backend (<a
href="https://redirect.github.com/paperclipai/paperclip/issues/12406">#12406</a>)</li>
<li>Additional commits viewable in <a
href="39b8ee2960...f038633bf5">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - The server refuses to boot when its database is not migrated, or
when an authenticated public deployment has no `DATABASE_URL`. These
refusals are deliberate and correct.
> - In managed cloud, a supervisor creates each stack, migrates its
fresh database, applies configuration, and restarts the app. The app
container often boots before those steps finish.
> - Each early boot hits one of the two refusals, exits, and captures
the refusal to Sentry. One fleet build batch produces hundreds of
identical expected events. Real errors get buried.
> - This pull request classifies exactly those two refusals as expected
transients when `PAPERCLIP_CLOUD_API_ORIGIN` marks a supervised
deployment, and skips only the Sentry capture for them.
> - The benefit is a clean error signal: expected provisioning noise
stops, and every real failure still reports.
## Linked Issues or Issue Description
**What happened?**
A managed-cloud stack boots its app container before the supervisor
migrates the empty database or finishes applying configuration. The
container refuses to start, crash-loops briefly, and converges after the
supervisor restarts it. Every refused boot sends an error event to
Sentry. A batch of new stacks produces hundreds of these expected
events.
**Expected behavior**
The refusal logs and exits nonzero, so the supervisor can act. Sentry
receives no event for an expected provisioning transient. Sentry still
receives events for real failures: schema drift, malformed
configuration, and every refusal outside managed cloud.
**Steps to reproduce**
1. Set `PAPERCLIP_MIGRATION_AUTO_APPLY=false`,
`PAPERCLIP_MIGRATION_PROMPT=never`, `SENTRY_DSN`, and
`PAPERCLIP_CLOUD_API_ORIGIN`.
2. Point `DATABASE_URL` at an empty database and start the server.
3. The server refuses to start. Before this change it also captures the
refusal to Sentry on every boot.
**Deployment mode**
Authenticated public (managed cloud).
## What Changed
- 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.
## Verification
- `pnpm vitest run src/__tests__/startup-refusals.test.ts` — 7 passed.
- Review the decision matrix in the test file: refusals report when
`PAPERCLIP_CLOUD_API_ORIGIN` is absent or blank; non-refusal errors and
non-`Error` throwables always report; drift always reports.
## Risks
- Low risk. The change only skips a Sentry capture in one narrow,
marker-gated case. Boot behavior, logging, and the exit code do not
change.
- Self-hosted deployments do not set `PAPERCLIP_CLOUD_API_ORIGIN`, so
their reporting is unchanged, and the tests pin that.
- A supervised deployment with a genuinely stuck migration runner loses
per-boot Sentry events for that stack. The supervisor's own health
checks and monitoring own that signal, and the container logs still
carry the refusal.
## Model Used
Claude Fable 5 (claude-fable-5) via Claude Code, extended thinking with
tool use.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above (none found for startup Sentry suppression)
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
(module doc comment; no user-facing docs affected)
- [x] I have considered and documented any risks above
Accept and persist Cloud-signed canonical runtime identity before activation, then route absolute self-URLs through the durable runtime identity provider.
Co-Authored-By: Codex <codex@openai.com>
Bumps
[@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react)
from 4.7.0 to 6.1.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/releases">@vitejs/plugin-react's
releases</a>.</em></p>
<blockquote>
<h2>plugin-react@6.1.1</h2>
<h3>Add <code>compiler.logDiagnostics</code> option</h3>
<p>Recoverable React Compiler diagnostics are no longer logged by
default. Set <code>compiler.logDiagnostics</code> to <code>true</code>
to log them through Vite. Fatal diagnostics are always logged and fail
the transform.</p>
<h3>Respect environment sourcemap option for React Compiler transform
when <code>builder.sharedPlugins</code> is enabled (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1439">#1439</a>)</h3>
<p>The React Compiler transform was using the top-level sourcemap option
instead of the environment sourcemap option. This caused a problem when
the experimental <code>builder.sharedPlugins</code> was enabled.</p>
<h2>plugin-react@6.1.0</h2>
<h3>Add experimental native React Compiler support (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1419">#1419</a>)</h3>
<p>Add experimental native React Compiler support.</p>
<p>You can use it by installing <code>oxc-transform-react</code> and
enabling it via the <code>compiler</code> option:</p>
<pre lang="sh"><code>npm install -D oxc-transform-react
</code></pre>
<pre lang="js"><code>import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
<p>export default defineConfig({<br />
plugins: [<br />
react({ compiler: true })<br />
]<br />
})<br />
</code></pre></p>
<h2>plugin-react@6.0.5</h2>
<h3>Fixed the react compiler preset filter to be linear (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1353">#1353</a>)</h3>
<p>The improved filter in v6.0.3 was non-linear and caused a performance
regression (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/issues/1349">#1349</a>).
The filter was changed to be linear to avoid that.</p>
<h2>plugin-react@6.0.4</h2>
<h3>Fixed <code>$RefreshSig$ is not defined</code> error when running
<code>vite dev</code> with <code>NODE_ENV=production</code></h3>
<p>When running <code>vite dev</code> with
<code>NODE_ENV=production</code>, the app errored with
<code>$RefreshSig$ is not defined</code>.
This error is now fixed.</p>
<h2>plugin-react@6.0.3</h2>
<p>No release notes provided.</p>
<h2>plugin-react@6.0.2</h2>
<h3>Allow all options in reactCompilerPreset (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1189">#1189</a>)</h3>
<p>This is a type only change. Only <code>compilationMode</code> and
<code>target</code> options were available for
<code>reactCompilerPreset</code>.</p>
<h2>plugin-react@6.0.1</h2>
<h3>Expand <code>@rolldown/plugin-babel</code> peer dep range (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1146">#1146</a>)</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md">@vitejs/plugin-react's
changelog</a>.</em></p>
<blockquote>
<h2>6.1.1 (2026-08-28)</h2>
<h3>Add <code>compiler.logDiagnostics</code> option</h3>
<p>Recoverable React Compiler diagnostics are no longer logged by
default. Set <code>compiler.logDiagnostics</code> to <code>true</code>
to log them through Vite. Fatal diagnostics are always logged and fail
the transform.</p>
<h3>Respect environment sourcemap option for React Compiler transform
when <code>builder.sharedPlugins</code> is enabled (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1439">#1439</a>)</h3>
<p>The React Compiler transform was using the top-level sourcemap option
instead of the environment sourcemap option. This caused a problem when
the experimental <code>builder.sharedPlugins</code> was enabled.</p>
<h2>6.1.0 (2026-08-19)</h2>
<h3>Add experimental native React Compiler support (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1419">#1419</a>)</h3>
<p>Add experimental native React Compiler support.</p>
<p>You can use it by installing <code>oxc-transform-react</code> and
enabling it via the <code>compiler</code> option:</p>
<pre lang="sh"><code>npm install -D oxc-transform-react
</code></pre>
<pre lang="js"><code>import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
<p>export default defineConfig({<br />
plugins: [<br />
react({ compiler: true })<br />
]<br />
})<br />
</code></pre></p>
<h2>6.0.5 (2026-07-30)</h2>
<h3>Fixed the react compiler preset filter to be linear (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1353">#1353</a>)</h3>
<p>The improved filter in v6.0.3 was non-linear and caused a performance
regression (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/issues/1349">#1349</a>).
The filter was changed to be linear to avoid that.</p>
<h2>6.0.4 (2026-07-22)</h2>
<h3>Fixed <code>$RefreshSig$ is not defined</code> error when running
<code>vite dev</code> with <code>NODE_ENV=production</code></h3>
<p>When running <code>vite dev</code> with
<code>NODE_ENV=production</code>, the app errored with
<code>$RefreshSig$ is not defined</code>.
This error is now fixed.</p>
<h2>6.0.3 (2026-06-23)</h2>
<h3>Improve the react compiler preset filter to reduce false-positives
(<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1138">#1138</a>)</h3>
<p>Improved the filter in the react compiler babel preset to reduce the
false-positives so that less modules are processed by the react
compiler.</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="04cac5020e"><code>04cac50</code></a>
release: plugin-react@6.1.1 (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1440">#1440</a>)</li>
<li><a
href="82d35abe49"><code>82d35ab</code></a>
fix(react): respect environment sourcemap option when
<code>builder.sharedPlugins</code>...</li>
<li><a
href="397e8471a5"><code>397e847</code></a>
fix(react): make logging diagnostics an opt-in for React Compiler (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1431">#1431</a>)</li>
<li><a
href="61006e6f52"><code>61006e6</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1433">#1433</a>)</li>
<li><a
href="e2a649cbaa"><code>e2a649c</code></a>
chore: use <code>deps.neverBundle</code> instead of
<code>external</code> in tsdown config (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1430">#1430</a>)</li>
<li><a
href="fb2d6f3635"><code>fb2d6f3</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1427">#1427</a>)</li>
<li><a
href="39b31735bf"><code>39b3173</code></a>
release: plugin-react@6.1.0 (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1428">#1428</a>)</li>
<li><a
href="f1340b0c76"><code>f1340b0</code></a>
feat(react): add native React Compiler support (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1419">#1419</a>)</li>
<li><a
href="9ab698eafc"><code>9ab698e</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1375">#1375</a>)</li>
<li><a
href="68c0cb8796"><code>68c0cb8</code></a>
release: plugin-react@6.0.5 (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1362">#1362</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.1.1/packages/plugin-react">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for <code>@vitejs/plugin-react</code> since your current
version.</p>
</details>
<br />
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Use full dependency resolution in automated lockfile repair paths, add regression coverage, and refresh the stale Rollup snapshot.
Co-Authored-By: Dotta <cryppadotta@users.noreply.github.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: lockfile-bot <lockfile-bot@users.noreply.github.com>
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.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/aws/aws-sdk-js-v3/releases">@aws-sdk/client-s3's
releases</a>.</em></p>
<blockquote>
<h2>v3.1120.0</h2>
<h4>3.1120.0(2026-08-27)</h4>
<h5>Documentation Changes</h5>
<ul>
<li><strong>client-opensearch:</strong> Updating SDK and CLI
documentation for AttachDataSource API. (<a
href="d696fe7602">d696fe76</a>)</li>
</ul>
<h5>New Features</h5>
<ul>
<li><strong>client-lambda-microvms:</strong> Added
InsufficientCapacityException to RunMicrovm for capacity-related
failures. Added lifecycle status field (AVAILABLE, DEPRECATED) to
ListManagedMicrovmImageVersions. Added ConflictException to
CreateMicrovmAuthToken and CreateMicrovmShellAuthToken for unregistered
MicroVMs. (<a
href="72a8ff8092">72a8ff80</a>)</li>
<li><strong>client-codedeploy:</strong> Added a deploymentMode parameter
to CreateDeployment. Set it to RESTART to restart an EC2 and on-premises
fleet, using the last successful revision, honoring Deployment
Configuration. (<a
href="78d4f9640b">78d4f964</a>)</li>
<li><strong>client-cloudwatch-logs:</strong> Added resultCount to
QueryStatistics in GetQueryResults. This field returns the total number
of output rows in the final result set, helping customers
programmatically determine whether a query produced results after all
operations including post-aggregation filters. (<a
href="0e4d242b71">0e4d242b</a>)</li>
<li><strong>client-datazone:</strong> Add cascadeDelete to DeleteDomain.
When specified, DataZone recursively deletes all projects, environments,
subscriptions, and their underlying AWS resources before removing the
domain. Deletion progress is reported via deleteProgress and resource
failures via failureReasons on GetDomain. (<a
href="3a74dc4b94">3a74dc4b</a>)</li>
<li><strong>client-rds:</strong> Adding support for the full snapshot
size, in bytes, of DB instance snapshots. (<a
href="ab2f66f5f5">ab2f66f5</a>)</li>
<li><strong>client-ec2:</strong> EC2 allows AMI owners to define
compatible instance types on their AMIs, blocking RunInstances calls
automatically for launches on non-permitted instance types. (<a
href="311b3b26db">311b3b26</a>)</li>
<li><strong>client-cognito-identity-provider:</strong> Adds the
AdminDeleteSoftwareToken API operation, enabling administrators to
remove a user's registered TOTP (software token) MFA configuration from
a user pool. (<a
href="f661bebc4d">f661bebc</a>)</li>
</ul>
<hr />
<p>For list of updated packages, view
<strong>updated-packages.md</strong> in
<strong>assets-3.1120.0.zip</strong></p>
<h2>v3.1119.0</h2>
<h4>3.1119.0(2026-08-26)</h4>
<h5>Chores</h5>
<ul>
<li><strong>codegen:</strong> smithy-aws-typescript-codegen 0.53.0 (<a
href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8276">#8276</a>)
(<a
href="dffb383bdc">dffb383b</a>)</li>
</ul>
<h5>New Features</h5>
<ul>
<li><strong>client-sagemaker:</strong> Amazon SageMaker AI now supports
ml.g7 instances for model optimization. You can now run model
optimization jobs on ml.g7 instances, in supported AWS Regions. (<a
href="6d5e106634">6d5e1066</a>)</li>
<li><strong>client-devops-agent:</strong> AWS DevOps Agent now supports
trigger filter groups for Release Readiness Review, letting you control
when the capability auto-triggers based on webhook events and target
branches. (<a
href="bc3d53d550">bc3d53d5</a>)</li>
<li><strong>client-license-manager-user-subscriptions:</strong> Released
support for License Expiry field in ListProductSubscriptions API (<a
href="454d7f7ffb">454d7f7f</a>)</li>
<li><strong>client-ec2:</strong> Adds deleting state to possible VPC
States. (<a
href="43091d55b3">43091d55</a>)</li>
<li><strong>client-network-firewall:</strong> Adding new status enum for
Firewalls. (<a
href="4cb21cb3b8">4cb21cb3</a>)</li>
</ul>
<hr />
<p>For list of updated packages, view
<strong>updated-packages.md</strong> in
<strong>assets-3.1119.0.zip</strong></p>
<h2>v3.1118.0</h2>
<h4>3.1118.0(2026-08-25)</h4>
<h5>Documentation Changes</h5>
<ul>
<li><strong>client-marketplace-metering:</strong> Updated documentation
to clarify duplicate-billing prevention and BatchMeterUsage retry
guidance (<a
href="322310259e">32231025</a>)</li>
</ul>
<h5>New Features</h5>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md">@aws-sdk/client-s3's
changelog</a>.</em></p>
<blockquote>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1119.0...v3.1120.0">3.1120.0</a>
(2026-08-27)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1118.0...v3.1119.0">3.1119.0</a>
(2026-08-26)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1117.0...v3.1118.0">3.1118.0</a>
(2026-08-25)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1116.0...v3.1117.0">3.1117.0</a>
(2026-08-24)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1115.0...v3.1116.0">3.1116.0</a>
(2026-08-21)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@aws-sdk/client-s3</code></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d6be6f8dd3"><code>d6be6f8</code></a>
Publish v3.1120.0</li>
<li><a
href="ba4e4498a7"><code>ba4e449</code></a>
Publish v3.1119.0</li>
<li><a
href="c65dd6533d"><code>c65dd65</code></a>
Publish v3.1118.0</li>
<li><a
href="78b069ac77"><code>78b069a</code></a>
Publish v3.1117.0</li>
<li><a
href="d760a00859"><code>d760a00</code></a>
Publish v3.1116.0</li>
<li><a
href="8369ada75d"><code>8369ada</code></a>
chore(codegen): update to sync with the latest smithy-ts (<a
href="https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3/issues/8272">#8272</a>)</li>
<li>See full diff in <a
href="https://github.com/aws/aws-sdk-js-v3/commits/v3.1120.0/clients/client-s3">compare
view</a></li>
</ul>
</details>
<br />
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Thinking Path
> - Paperclip uses paid runner tests to qualify agent execution.
> - The runner workflow controls provider secrets and AWS runner access.
> - The trusted workflow must stay on the protected default branch.
> - The code under test often exists on a branch before merge.
> - CODEOWNERS need a safe way to select that branch.
> - This pull request separates workflow authority from the code under
test.
> - The benefit is pre-merge AWS testing without target-controlled
workflow code.
## Linked Issues or Issue Description
**What existing behavior does this improve?**
The manual Runner Full-Stack E2E workflow can test only the default
branch.
**Subsystem affected**
GitHub Actions and the paid runner E2E security boundary.
**Current behavior**
A CODEOWNER must merge runner changes before the trusted AWS workflow
can test them.
Selecting another branch as the workflow ref is rejected.
**Proposed behavior**
A CODEOWNER starts the workflow from `master` and supplies a
same-repository branch in `target_branch`.
The authorization job resolves the branch to one commit SHA.
Catalog, image, and paid test jobs check out that SHA after
authorization.
Report sanitization and AWS publication use the trusted workflow SHA.
**Reason and benefit**
This permits paid pre-merge qualification on AWS.
It keeps the workflow definition, report sanitizer, history publisher,
environment deployment, and runner-group permission on `master`.
**Breaking changes**
None.
The new input is optional.
An omitted input still tests the default branch.
## What Changed
- 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.
- Pin report sanitization and AWS history publication to the trusted
workflow SHA.
- Disable persisted checkout credentials in every job.
- Key cancellation by the selected target branch.
- Add policy regression coverage and operator documentation.
## Verification
- `pnpm test:e2e:runner:unit` passes with 65 tests.
- `actionlint -ignore SC2129
.github/workflows/runner-full-stack-e2e.yml` passes.
- Prettier checks pass for all changed files.
- `git diff --check` passes.
## Risks
A CODEOWNER can authorize selected branch code to receive a cell-scoped
provider credential.
This is the intended trust decision.
The workflow rejects fork refs and target-controlled workflow
definitions.
The trusted workflow SHA owns report sanitization and AWS history
publication.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
OpenAI Codex, GPT-5.
The exact serving snapshot and context-window size are not exposed.
The model used tool-enabled reasoning and code execution.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
Bumps [mermaid](https://github.com/mermaid-js/mermaid) from 11.16.1 to
11.17.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mermaid-js/mermaid/releases">mermaid's
releases</a>.</em></p>
<blockquote>
<h2>mermaid@11.17.2</h2>
<h3>Patch Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/8125">#8125</a>
<a
href="178d7c79fc"><code>178d7c7</code></a>
Thanks <a
href="https://github.com/knsv-bot"><code>@knsv-bot</code></a>! - fix:
restore the <code>edgePaths</code> class on the edge group in rendered
SVG, and point the flowchart, block and user journey stylesheets at
it</li>
</ul>
<h2>mermaid@11.17.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/8092">#8092</a>
<a
href="31ce60a596"><code>31ce60a</code></a>
Thanks <a
href="https://github.com/pbrolin47"><code>@pbrolin47</code></a>! -
fix(c4): wrap element labels to <code>c4.width</code> again</p>
<p>C4 element labels (<code>System</code>, <code>Container</code>,
<code>Component</code>, <code>Person</code> and their <code>_Ext</code>
variants) stopped wrapping in 11.17.0, so long descriptions rendered on
one unbroken line and the shape grew sideways well past the configured
<code>c4.width</code>. The unified-shapes label helper gated wrapping on
the root-level <code>wrap</code> option, which has no schema default and
is therefore <code>undefined</code>; it now gates on
<code>c4.wrap</code> (default <code>true</code>), which is what the
legacy renderer used.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/8088">#8088</a>
<a
href="c66200bc23"><code>c66200b</code></a>
Thanks <a
href="https://github.com/ashishjain0512"><code>@ashishjain0512</code></a>!
- fix: neo-look arrowheads and crow's-foot markers no longer fall back
to default theme colours/stroke widths on the first render with
<code>layout: elk</code>. State diagram arrowheads stayed dark on dark
themes, and ER / requirement markers were drawn at the default stroke
width, because markers were created from the layout package's own
bundled copy of mermaid, whose config had not been initialized yet.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/8079">#8079</a>
<a
href="281cd7b070"><code>281cd7b</code></a>
Thanks <a
href="https://github.com/ashishjain0512"><code>@ashishjain0512</code></a>!
- fix(class): class diagram relation markers (composition, aggregation,
extension, dependency, lollipop) no longer scale with the edge stroke
width, so they stay outside the class box boundary in themes that set
<code>strokeWidth: 2</code> (<code>redux</code>,
<code>redux-dark</code>, <code>redux-color</code>,
<code>redux-dark-color</code>, <code>neo</code>, <code>neo-dark</code>)
with the default <code>classic</code> look.</p>
</li>
</ul>
<h2>mermaid@11.17.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7842">#7842</a>
<a
href="3670b4e2d9"><code>3670b4e</code></a>
Thanks <a
href="https://github.com/filipsajdak"><code>@filipsajdak</code></a>! -
feat(c4): render C4 elements through the unified shape system, using the
new person shape</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7812">#7812</a>
<a
href="cdfc0ea65f"><code>cdfc0ea</code></a>
Thanks <a
href="https://github.com/knsv-bot"><code>@knsv-bot</code></a>! -
feat(class): route <code>classDiagram</code> to the unified (v2)
renderer by default</p>
<p>Set <code>class: { defaultRenderer: 'dagre-d3' }</code> in the config
to restore the legacy renderer.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7785">#7785</a>
<a
href="c45cde9582"><code>c45cde9</code></a>
Thanks <a
href="https://github.com/knsv-bot"><code>@knsv-bot</code></a>! -
feat(flowchart): add collapsible flowchart subgraphs via
<code>subgraphId@{ view: collapsed }</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7828">#7828</a>
<a
href="8eb3afc08c"><code>8eb3afc</code></a>
Thanks <a
href="https://github.com/knsv-bot"><code>@knsv-bot</code></a>! -
feat(elk): add <code>elk.keepEntryNodeOnTop</code> config option to keep
a recursive flow's entry node on top</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7803">#7803</a>
<a
href="74e44ebf86"><code>74e44eb</code></a>
Thanks <a
href="https://github.com/knsv-bot"><code>@knsv-bot</code></a>! -
feat(elk): add <code>elk.nodePlacementAlignment</code> config option</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7792">#7792</a>
<a
href="ea55b31bcf"><code>ea55b31</code></a>
Thanks <a
href="https://github.com/RodrigojndSantos"><code>@RodrigojndSantos</code></a>!
- feat(er): add subgraph support to ER diagrams.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7970">#7970</a>
<a
href="a2c0fb6cdf"><code>a2c0fb6</code></a>
Thanks <a
href="https://github.com/filipsajdak"><code>@filipsajdak</code></a>! -
feat(flowchart): add <code>folder</code>, <code>bucket</code>,
<code>console</code> (terminal window) and <code>browser</code>
shapes</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7842">#7842</a>
<a
href="ae3e1157c1"><code>ae3e115</code></a>
Thanks <a
href="https://github.com/filipsajdak"><code>@filipsajdak</code></a>! -
feat(flowchart): add <code>person</code> shape (circular head above a
rounded body), usable in flowcharts via <code>A@{ shape: person
}</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7724">#7724</a>
<a
href="0fd7a9fe0d"><code>0fd7a9f</code></a>
Thanks <a
href="https://github.com/xdumaine"><code>@xdumaine</code></a>! -
feat(xyChart): add legends for named line and bar series</p>
</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7847">#7847</a>
<a
href="215fe89d3e"><code>215fe89</code></a>
Thanks <a
href="https://github.com/filipsajdak"><code>@filipsajdak</code></a>! -
fix(c4): named attributes such as <code>$tags</code>, <code>$link</code>
and <code>$sprite</code> are no longer clobbered to undefined when they
arrive in an earlier positional slot of
Person/System/Container/Component/Boundary/Rel statements.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7871">#7871</a>
<a
href="8d874c49fa"><code>8d874c4</code></a>
Thanks <a
href="https://github.com/knsv-bot"><code>@knsv-bot</code></a>! -
fix(flowchart): stop dagre layout from spamming <code>warn</code>-level
logs on every node/edge/cluster</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/8071">#8071</a>
<a
href="b3d1f63167"><code>b3d1f63</code></a>
Thanks <a
href="https://github.com/pbrolin47"><code>@pbrolin47</code></a>! -
fix(block): sibling blocks overlapping in block diagrams when one has a
label wider than 200px</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7870">#7870</a>
<a
href="71b8843fb5"><code>71b8843</code></a>
Thanks <a
href="https://github.com/knsv-bot"><code>@knsv-bot</code></a>! - fix: a
<code>RangeError: Invalid array length</code> crash when rendering
certain edges.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/mermaid-js/mermaid/pull/7924">#7924</a>
<a
href="9cbef5d94f"><code>9cbef5d</code></a>
Thanks <a
href="https://github.com/nightt5879"><code>@nightt5879</code></a>! -
fix(treeView): icons disappearing after strict security
sanitization.</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="dcb694ddb5"><code>dcb694d</code></a>
Version Packages (<a
href="https://redirect.github.com/mermaid-js/mermaid/issues/8130">#8130</a>)</li>
<li><a
href="178d7c79fc"><code>178d7c7</code></a>
fix: restore edgePaths class on the edge group (<a
href="https://redirect.github.com/mermaid-js/mermaid/issues/8125">#8125</a>)</li>
<li><a
href="569f46e261"><code>569f46e</code></a>
Version Packages (<a
href="https://redirect.github.com/mermaid-js/mermaid/issues/8114">#8114</a>)</li>
<li><a
href="3054836688"><code>3054836</code></a>
Version Packages</li>
<li><a
href="5b17e0a38f"><code>5b17e0a</code></a>
Merge pull request <a
href="https://redirect.github.com/mermaid-js/mermaid/issues/8092">#8092</a>
from mermaid-js/hotfix/11.17.1</li>
<li><a
href="655211a065"><code>655211a</code></a>
Reverted change of wrap-options</li>
<li><a
href="8a23480200"><code>8a23480</code></a>
Updated doc from feedback</li>
<li><a
href="412c80abb7"><code>412c80a</code></a>
Update doc and consistent handlig in c4 as for seq diags</li>
<li><a
href="b433a9aad5"><code>b433a9a</code></a>
Updated changeset to describe specifik diagram affected</li>
<li><a
href="6bae15eb59"><code>6bae15e</code></a>
Updated tests to Playwright API</li>
<li>Additional commits viewable in <a
href="https://github.com/mermaid-js/mermaid/compare/mermaid@11.16.1...mermaid@11.17.2">compare
view</a></li>
</ul>
</details>
<br />
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Thinking Path
> - Paperclip manages AI agents that perform work.
> - The paid runner matrix verifies complete runner behavior with real
providers.
> - Each matrix job currently repeats work on GitHub-hosted runners.
> - Paperclip has an ephemeral AWS runner fleet for trusted workflows.
> - The paid workflow needs a reviewed and fail-closed route to that
fleet.
> - This pull request adds that route and keeps the existing hosted
runner as the disabled-state fallback.
> - The benefit is faster paid campaigns with the same actor,
environment, and secret boundaries.
## Linked Issues or Issue Description
**What happened?**
The Runner Full-Stack E2E workflow always uses `ubuntu-latest-m`. It
limits the matrix to 57 parallel jobs. The repository AWS fleet can run
100 ephemeral jobs, but the paid workflow cannot select it.
**Expected behavior**
An explicit repository flag must select the reviewed AWS fleet label. A
missing or invalid flag must keep the existing hosted runner. The
workflow must authorize the stable actor identity before it routes any
paid job.
**Steps to reproduce**
1. Dispatch the Runner Full-Stack E2E workflow from `master`.
2. Inspect a paid matrix job.
3. Observe that the job requests `ubuntu-latest-m` even when the AWS
fleet should be used.
**Paperclip version or commit**
`da0947d3582ac7779d6bf11851c9938eca6c5c8c`
**Deployment mode**
GitHub Actions paid runner campaign.
## What Changed
- 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.
- Keep the hosted-runner limit at 57.
- Reauthorize paid execution before checkout and provider access.
- Stop paid checkouts from storing GitHub credentials.
- Cancel superseded validation-ref campaigns while preserving `master`
audit runs.
- Add workflow policy checks and operator documentation.
## Verification
- `git diff --check`
- `actionlint -ignore SC2129
.github/workflows/runner-full-stack-e2e.yml`
- The organization runner group permits this workflow only from
`refs/heads/master`.
- The repository AWS switch remains disabled until this pull request is
merged and a one-cell probe succeeds.
## Risks
- A wrong fleet policy can leave jobs queued. The disabled state keeps
the existing hosted runner.
- The AWS fleet uses paid compute. The workflow validates a configured
maximum of 100 jobs.
- The runner group, actor allowlist, and paid environment remain
separate enforcement layers.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
OpenAI Codex based on GPT-5 with agentic reasoning, repository
inspection, code editing, Git, GitHub API coordination, and static
workflow analysis. The exact deployed model identifier and
context-window size are not exposed to this task.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip uses local adapters to connect agent sessions to the
control plane
> - The Codex adapter emits turn events from response and notification
channels
> - A terminal notification can arrive before the turn/start response
> - This pull request gates the terminal event on turn.accepted
> - The result keeps the event order stable for consumers and tests
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip uses local adapters to connect agent sessions to the
control plane
> - The Codex adapter emits turn events from response and notification
channels
> - A terminal notification can arrive before the turn/start response
> - This pull request gates the terminal event on turn.accepted
> - The result keeps the event order stable for consumers and tests
## Linked Issues or Issue Description
**What happened?**
The Codex harness session emitted `turn.accepted` only after the
`turn/start` response resolved. A terminal notification could arrive
before that response and reach consumers first.
**Expected behavior**
The Codex driver must emit `turn.accepted` before any terminal event for
the same turn.
**Steps to reproduce**
1. Start a Codex harness session.
2. Keep the `turn/start` response pending.
3. Send `turn/started` and `turn/completed` notifications.
4. Observe the event order.
**Paperclip version or commit**
`afbcd28dae9e51108738c4258929b95ca359186c`
**Deployment mode**
Built from source with the Codex driver test harness.
**Agent adapter(s) involved**
Codex.
## What Changed
- 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.
- Add a regression test that delivers a terminal notification while
`turn/start` remains pending.
## Verification
- The regression test failed 5 of 5 times before this change and passed
5 of 5 times after it.
- The Codex driver suite passed 189 of 189 tests.
- The affected live transport test file passed 46 of 46 tests on 10
consecutive runs.
- The TypeScript check exited with status 0.
- Continuous integration must pass before merge.
## Risks
The change affects only Codex turn event ordering. It adds no sleep,
retry, or timeout. The main risk is a provider path that does not settle
`turn/start`; existing provider response handling still controls
completion.
## Model Used
OpenAI GPT-5. The exact deployment identifier is not exposed in this
environment. Tool use and code execution assisted this change.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` /
`Closes: #` / `Refs #` OR (b) described the issue in-PR following the
relevant issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip runs agent heartbeats and stores their run state in a
database
> - The direct-adapter native-isolation tests start heartbeat runs and
then clear database state
> - A terminal run status does not prove that its background database
work has stopped
> - The teardown can then deadlock with a live run during PostgreSQL
`TRUNCATE`
> - This pull request drains active runs before teardown and adds a
guard for queued or running runs
> - The benefit is stable test teardown without a production code change
## Linked Issues or Issue Description
This change fixes an intermittent test deadlock in the direct-adapter
native-isolation suite.
**What happened?**
The test teardown could run PostgreSQL `TRUNCATE` while a heartbeat
execution still held a write transaction. PostgreSQL then returned error
`40P01` during some test runs.
**Expected behavior**
The test teardown must wait until all heartbeat executions finish before
it clears the test database.
**Steps to reproduce**
1. Run
`server/src/__tests__/heartbeat-direct-adapter-native-isolation.test.ts`
repeatedly.
2. Run the suite against PostgreSQL-backed native isolation.
3. Observe intermittent deadlock error `40P01` during teardown.
**Paperclip version or commit**
Commit `57515726d3ef45a07df9b5ee2dfaf7d108556478`.
**Deployment mode**
Built from source with the native-isolation test suite.
**Agent adapter(s) involved**
Not adapter-specific. The test covers the direct adapter path.
**Database mode**
External PostgreSQL used by the native-isolation test suite.
**Additional context**
Related prior attempt:
[#12715](https://github.com/paperclipai/paperclip/pull/12715). This pull
request starts from current `master` and does not depend on that pull
request.
## What Changed
- 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.
- Create one shared `heartbeatService` instance in `beforeAll` so the
drain tracks the test runs.
## Verification
- Run
`server/src/__tests__/heartbeat-direct-adapter-native-isolation.test.ts`
20 times. All 20 runs pass.
- Run the target suite with
`server/src/__tests__/native-run-finalizer.test.ts`. Both files pass
with 19 tests.
- Run `tsc --noEmit`. The branch adds no new error compared with
`master`.
- Run the pull request checks after GitHub starts them.
## Risks
Low risk. The change affects one test file and no production code. The
added drain can expose an incomplete test run before teardown, which is
the intended guard.
## Model Used
OpenAI GPT-5. Exact runtime model ID: GPT-5. The context window is not
exposed to this agent. The model used tool calls and code execution.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` /
`Closes: #` / `Refs: #` OR (b) described the issue in-PR following the
relevant issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip uses a frozen pnpm lockfile to create the same dependency
graph for each build.
> - The Claude local adapter now uses
`@agentclientprotocol/claude-agent-acp` version 0.73.0.
> - The root patch configuration contains a patch for version 0.73.0.
> - The committed lockfile did not contain the matching patch record.
> - A frozen install rejected this mismatch and stopped the master
deployment.
> - This pull request regenerates only `pnpm-lock.yaml` from the current
master manifests.
> - The change makes the frozen install valid again.
## Linked Issues or Issue Description
Refs #12730
**What happened?**
The master lockfile did not match the current patched dependency
configuration.
**Expected behavior**
The frozen install must accept the lockfile on master.
**Steps to reproduce**
1. Extract a clean archive of master.
2. Run `NODE_ENV=development CI=true pnpm install --frozen-lockfile
--force`.
3. Observe that pnpm rejects the stale lockfile.
**Paperclip version or commit**
`b1f4910ee57789c7045705a38c31ca34704f3575`
**Deployment mode**
Self-hosted server.
**Installation method**
Built from source with pnpm.
## What Changed
- 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.
## Verification
- `git diff --check` passes.
- A clean archive of commit `236767cdd1832575fe93ea50f50df2890fb2bf1f`
accepts the frozen lockfile.
- `NODE_ENV=development CI=true pnpm install --frozen-lockfile --force`
completes with exit code 0 in that archive.
- Latest-head GitHub checks are green (32/32 success, neutral, or
skipped).
- Greptile passed the same head at 5/5 with zero unresolved threads.
## Risks
- Risk is low because pnpm generated the only changed file.
- The lockfile now records the dependency version that the manifests
already require.
## Model Used
OpenAI Codex with a GPT-5 family model produced this change. The runtime
does not expose the exact deployment ID or context size. The model used
high reasoning and shell execution.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used with the available version and
capability details
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have linked the related public pull request with `Refs #`
- [x] I have not referenced internal or instance-local Paperclip issues
or links
- [x] My branch name describes the change and contains no internal
Paperclip ticket id
- [x] I have run the required local verification and it passes
- [x] Tests do not need source changes for this generated lockfile
correction
- [x] Documentation does not need changes because behavior and commands
are unchanged
- [x] I have considered and documented the risks above
- [x] All Paperclip CI gates are green
- [x] Greptile has no open P2 findings, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before merge
Co-authored-by: lockfile-bot <lockfile-bot@users.noreply.github.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip manages AI agents and their work.
> - The runner starts ACPX sessions and controls their resources.
> - An aborted admission can leave sandbox preparation active after the
opening promise rejects.
> - Test teardown can then remove the sandbox directory before that work
ends.
> - This pull request retains and observes each unfinished admission
stage.
> - The change gives runtime resources and temporary directories one
deterministic cleanup owner.
## Linked Issues or Issue Description
**What happened?**
Under full test load, an aborted admission test can end before sandbox
preparation settles. Test teardown then removes the temporary session
directory. The active preparation can report an unhandled `ENOENT`
error.
**Expected behavior**
An aborted admission must observe and retain all active preparation
work. Test teardown must wait until that work settles.
**Steps to reproduce**
1. Run the complete `@paperclipai/paperclip-runner` test suite under CI
load.
2. Abort runtime admission during credential or sandbox preparation.
3. Observe an intermittent test timeout or an unhandled
missing-directory error.
**Paperclip version or commit**
The failure occurred on a branch based on commit `b1f4910ee`. This fix
is based on current `master` commit `4d30efa8e`.
**Deployment mode**
The failure occurred in GitHub Actions on a source build.
## What Changed
- 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.
- Replace time-based stage detection with exact deferred stage signals.
- Add a deterministic regression test for an abort during sandbox
preparation.
## Verification
- Ran the focused runtime-host file in 20 separate processes. All 20
runs passed without an unhandled error.
- Ran `pnpm --filter @paperclipai/paperclip-runner exec vitest run
src/drivers/acpx/runtime-host.test.ts` after the rebase. All 27 tests
passed.
- Ran `pnpm --filter @paperclipai/paperclip-runner check:all` after the
rebase. The full command passed.
- The final TypeScript test stage passed 127 files and 1,490 tests. All
Rust checks, tests, and parity checks passed.
- Greptile reviewed two heads. The final review is 5/5 with no open
comments.
- All latest-head CI and security checks passed. One unrelated workspace
test passed on its permitted rerun.
## Risks
- Risk is low. An aborted stage now delays final runtime-host cleanup
until its active operation settles.
- A stage that never settles can delay embedding shutdown. The existing
stage operations have bounded or controlled owners.
- The regression test holds sandbox preparation and confirms the new
cleanup order.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
OpenAI Codex with GPT-5 assisted this change. The environment did not
provide the exact deployment ID or context size. The model used
reasoning, shell tools, code editing, and test execution.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Onboarding creates an organization in the browser.
> - The browser keeps onboarding drafts for the same origin.
> - A new data directory does not clear that browser data.
> - The organization create request refreshes the company list.
> - The old gate unmounted the live wizard during that refresh.
> - This pull request keeps the wizard mounted after its first draft
check.
> - The customer can continue to the agent step after the organization
is created.
## Linked Issues or Issue Description
No matching public issue was found. Related earlier fix: Refs #12667.
**What happened?**
A local canary install could create an organization through the API and
then return the browser to an empty organization-name screen.
**Expected behavior**
The wizard must continue to the agent step after it creates the
organization.
**Steps to reproduce**
1. Keep a Paperclip onboarding draft in the browser.
2. Run npx paperclipai@canary onboard with a new data directory.
3. Open /onboarding.
4. Enter an organization name and select Continue.
**Paperclip version or commit**
2026.902.0-canary.7. The fix is based on current master.
**Deployment mode**
Local trusted mode through the Paperclip CLI.
**Install method**
npx package install.
**Agent adapter(s) involved**
Not adapter-specific.
**Database mode**
Embedded PostgreSQL.
## What Changed
- Keep the onboarding wizard mounted after its first successful draft
ownership check.
- Keep a failed ownership check retryable, so a later verified fetch
restores the saved draft.
- Add component, source E2E, and published-canary coverage for the
retained-draft refetch case.
## Verification
- Confirmed that the new canary scenario fails against
2026.902.0-canary.7 before this fix.
- pnpm exec vitest run ui/src/components/OnboardingWizard.test.tsx
- PAPERCLIP_E2E_PORT=3245 pnpm exec playwright test --config
tests/e2e/playwright.config.ts tests/e2e/onboarding.spec.ts
--reporter=line
- pnpm --filter @paperclipai/ui typecheck
- pnpm check:token-gates
## Risks
Low risk. The initial ownership check still waits for a fresh company
list. A later successful retry can restore a retained draft. Later
background refetches preserve live wizard state.
## Model Used
OpenAI Codex, GPT-5. Reasoning, tool use, code editing, terminal
execution, and browser testing were used. The execution environment does
not expose a context-window size.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used with version and capability
details
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have described the issue in-PR following the bug issue template
- [x] I have not referenced internal or instance-local Paperclip issues
or links
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the control plane for companies that use AI agents for
work
> - Local adapters connect Paperclip agents to provider command line
tools
> - The Codex adapter stores login data in a shared company home
> - A shared home cannot keep credentials for more than one Codex
account
> - This pull request gives each account a safe home and a matching
company secret
> - The benefit is that one company can use multiple Codex accounts at
the same time
## Linked Issues or Issue Description
**Problem or motivation**
A company can hold only one Codex subscription credential because device
login uses one shared home. A second account cannot log in without
replacing or conflicting with the first credential.
**Proposed solution**
This change validates the vendor account identifier, stores each
credential in its own home, and creates a company secret that points to
that home. Repeat login calls return success when the matching secret
already exists.
**Roadmap alignment**
The change supports the roadmap goal for centrally managed secrets with
scoped access and audited resolution.
**Additional context**
The security review returned approve with no blocking finding. The
branch adds shared account-handle validation and tests for device login
and the Codex local adapter.
## What Changed
- Add strict allowlist validation for Codex account handles.
- Store each Codex account credential in a separate home under the Codex
cache root.
- Verify that the resolved account home stays inside the cache root.
- Create the `CODEX_HOME_<handle>` company secret for each account.
- Keep repeat and concurrent login calls safe and idempotent.
- Add shared helper and route, adapter, and validation tests.
## Verification
- `pnpm --filter @paperclipai/adapter-codex-local test` passes with 343
tests.
- `pnpm --filter @paperclipai/server test
src/__tests__/agent-device-login-routes.test.ts` passes with 25 tests.
- The adapter suite passes with 23 tests.
- The shared package and Codex adapter typechecks pass.
- Continuous integration must pass on every check before merge.
## Risks
The account handle becomes part of a directory path and secret name. The
strict allowlist and root containment check reduce path traversal risk.
Existing single-account homes remain unchanged unless a new device login
creates an account-specific home.
## Model Used
OpenAI GPT-5 (exact runtime model ID: gpt-5), with tool use and code
execution. The runtime context window is not exposed in this run.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Claude local adapter lets operators select a Claude model for an
agent.
> - Claude Fable 5.1 was absent from the adapter model lists.
> - The adapter runtime also used a Claude Code build that rejected
Fable 5.1.
> - This pull request adds the direct Anthropic ID and the AWS Bedrock
inference profile ID.
> - It also updates the Claude ACP runtime and keeps the Paperclip usage
and isolation patches.
> - The benefit is that operators can select and run Claude Fable 5.1
through the Claude adapter.
## Linked Issues or Issue Description
Refs #8810. That issue covers related model ID handling. This change
does not change provider-prefixed model IDs.
**Agent or provider**
Claude Code through the built-in `claude_local` adapter. The requested
model is Claude Fable 5.1.
**Why this adapter is useful**
Operators can use Fable 5.1 without entering an undocumented model ID.
The configured model also reaches both supported Claude execution lanes.
**How the agent is invoked**
The CLI lane sends `--model claude-fable-5-1`. The ACP lane sends
`ANTHROPIC_MODEL=claude-fable-5-1` to
`@agentclientprotocol/claude-agent-acp`.
**Are you willing to implement it?**
Yes. This pull request includes the implementation and tests.
**Additional context**
Claude Code 2.1.232 rejected Fable 5.1 and required version 2.1.251 or
newer. ACP package 0.73.0 includes Claude Code 2.1.257. The update keeps
Paperclip's usage metadata and isolated-context behavior.
## What Changed
- Added `claude-fable-5-1` to the direct Claude fallback list.
- Added `us.anthropic.claude-fable-5-1` to the AWS Bedrock list.
- Kept the existing default model at the first position in each list.
- Updated the Claude ACP dependency from 0.70 to 0.73.
- Carried the Paperclip usage and isolated-context changes into the 0.73
patch.
- Added a Claude Code 2.1.251 minimum-version preflight for Fable 5.1
when using the standard `claude` executable, surfaced in both adapter
Test and execution. Explicit custom wrappers retain their existing
compatibility contract.
- Kept local adapter Tests from executing caller-selected binaries: when
runtime `PATH` selects a different Claude executable than the trusted
probe, the Test warns and defers the authoritative version check to
execution instead of approving or rejecting the alternate installation.
- Added tests for model listing, discovery deduplication, Bedrock
filtering, model pass-through in both execution lanes, old-CLI rejection
before launch, custom-wrapper compatibility, and local runtime-PATH
mismatch handling.
## Verification
- `pnpm --filter @paperclipai/adapter-claude-local typecheck`
- `pnpm exec vitest run
packages/adapters/claude-local/src/server/execute.remote.test.ts
packages/adapters/claude-local/src/server/test.remote.test.ts
packages/adapters/claude-local/src/server/test.probe.test.ts
packages/adapters/claude-local/src/server/acp.test.ts
server/src/__tests__/adapter-models.test.ts` (72 tests passed)
- `node --test scripts/acpx-patch-packaging.test.mjs` (13 tests passed)
- `pnpm -r typecheck`
- `pnpm build`
- A local Paperclip agent run completed with `usageJson.model` set to
`claude-fable-5-1` through ACP 0.73.0 and its bundled Claude Code
2.1.257.
- `pnpm test:run` completed 5,638 passing tests and 24 skipped tests. It
also found 24 failures in unrelated workspace-runtime,
path-canonicalization, and runtime-exposure tests on macOS with Node 26.
These failures do not touch this diff. Clean pull request CI is the
final full-suite gate.
## Risks
- The ACP dependency update can change Claude runtime behavior outside
model selection. Focused ACP tests, the full typecheck, the production
build, and a real local Fable run reduce this risk.
- The 0.73 patch must stay aligned with the installed ACP version.
Dependency-resolution CI verifies the manifest and patch pair.
- Fable 5.1 adds a short `claude --version` preflight to standard
CLI-lane Tests and runs. The result is intentionally not cached so an
in-place Claude Code upgrade takes effect without restarting Paperclip.
Explicit custom wrappers are not version-probed because their output and
compatibility contract can differ from the standard executable.
- Local Tests preserve the existing deny-by-default probe boundary and
do not execute a binary selected by caller-controlled `PATH`. A
mismatched runtime binary produces an explicit warning without blocking
an otherwise valid setup; execution independently validates the actual
runtime-selected CLI before launch.
- The AWS Bedrock identifier differs from earlier IDs because Fable 5.1
has no `-v1` suffix. The model-list test locks this exact value.
- There is no schema change or migration.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
Provider: OpenAI. Model: GPT-5 Codex. The host did not expose a more
specific model ID or context-window size. Capabilities used: agentic
reasoning, repository editing, shell execution, web research, and local
runtime verification.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the control plane for agents that perform work.
> - Paperclip Runner connects durable provider sessions to individual
task runs through PRP.
> - Provider continuity and per-run authority are different lifetimes.
> - The existing implementation mixed those lifetimes and lost event
metadata between provider frames, runnerd, persistence, API
sanitization, and the task thread.
> - That caused failed continuation, missing progress and Plans,
duplicate replies, hidden failures, and unsafe recovery.
> - This repair gives every heartbeat fresh authority, preserves
qualified provider-session continuity, and restores one lossless
presentation path without changing direct adapters.
## Linked Issues or Issue Description
**What happened?**
A second native heartbeat could reuse tickets, leases, command receipts,
sequence state, and run identity from the first heartbeat. Provider
phase and item identity could be lost before the UI read them. Redaction
could corrupt protocol discriminators while still missing malformed
credential tails. The task thread could fold progress into the final
response, hide failures, or show more than one final answer. Native
Codex also exposed approval modes that do not yet have a durable
approval bridge.
**Expected behavior**
Each heartbeat uses a new PRP authority epoch. Codex and OpenCode
preserve exact qualified provider sessions; ACPX emits an explicit
continuity event when its qualified process-replacement policy is used.
Every accepted provider event is presented, classified as internal, or
surfaced as unsupported. The task page shows chronological progress,
reasoning summaries, activity, Plans, interactions, terminal failures,
and exactly one final reply. Direct adapters retain their existing path.
**Steps to reproduce**
1. Enable the unified experimental Paperclip Runner setting.
2. Create a local native Codex, OpenCode, ACPX Claude, or ACPX Codex
agent.
3. Run response, Plan, structured-question/resume, restart,
cancellation, and failure scenarios.
4. Reload the task while active, waiting, failed, and settled.
5. On the old implementation, observe stale run authority, missing
classifications, incomplete output, or duplicated/folded replies.
**Paperclip version or commit**
The repair is based directly on `master` at
`87d05e194b643810d16d20612115acd01d735d43`.
**Deployment mode**
Local development with the embedded database.
Related work: Refs #12616, #12646, #12666, #12685, and #12700.
## What Changed
- Rotates PRP control-plane, outbox, ticket, lease, command, receipt,
and sequence authority for each heartbeat while carrying forward only a
validated provider-session identity.
- Reads `control-plane-state.json`, validates both durable schemas and
lifecycle values, resumes coherent current runs, archives qualified
settled authority, and quarantines malformed or mismatched scoped state
without moving ambiguous live legacy state.
- Preserves Codex provider phase and stable item identities so
commentary remains progress and only `final_answer` becomes final.
- Adds raw OpenCode HTTP/SSE boundary coverage and canonical reasoning
lifecycle mapping.
- Makes ACPX normalization lossless for visible reasoning, tool
lifecycle metadata, stable bounded identities, Plan revisions,
structured requests, failures, and qualified process replacement. Only
the compatible terminal assistant message is promoted as final.
- Applies schema-aware redaction before generic JWT-shaped detection and
scans every diagnostic string leaf. Malformed raw/escaped quoted
credential tails are redacted in both server and durable Rust state.
- Restores snapshot-style chronological task presentation, expandable
tool activity, inline Plan cards, visible waiting/resume/cancel/failure
states, and exactly one final answer.
- Makes `never` the only qualified native Codex permission mode and
rejects unsupported persisted native modes with remediation. OpenCode
and ACPX policies remain intact.
- Keeps the unified experimental Runner setting as the only enablement
flag. Onboarding and direct Codex, Claude, and OpenCode stay on their
legacy execution/finalization paths.
- Adds cross-language goldens, authority/recovery/fault coverage, exact
response/count assertions, and native plus legacy acceptance scenarios.
## Verification
- Pull-request GitHub Actions run Rust formatting/tests, TypeScript
checks, server/UI tests, builds, protocol drift checks, browser E2E, and
security scans.
- A separate workflow-only validation ref is pinned directly on this PR
head and runs the 35-cell paid local matrix: three core scenarios plus
structured-question resume and restart/resume for native Codex, native
OpenCode, ACPX Claude, ACPX Codex, and direct Codex/Claude/OpenCode.
Run: https://github.com/paperclipai/paperclip/actions/runs/33682434315
- Acceptance requires exact single visible replies, monotonic sequences,
matching envelope discriminators, one semantic terminal, one run
terminal, no unresolved interaction, no duplicate mutation, no secret
leakage, provider continuity, and zero native rows for direct adapters.
- Per maintainer direction, tests are running in GitHub Actions rather
than on the slower local host. Only formatters and static diff checks
were run locally.
## Risks
- Recovery from old or partial filesystem state is sensitive. The repair
fails closed, preserves active or unverifiable authority, and
quarantines only state whose scoped ownership is safe to move.
- Provider event formats can change. Closed validators and boundary
goldens turn new or malformed events into visible diagnostics instead of
silent drops.
- Shared task presentation could affect direct adapters. Runtime-fact
gating plus the direct-adapter matrix protect the existing path.
- Managed and remote providers are not qualified here. Shared code
continues to compile and fail safely, but live qualification is
deferred.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
OpenAI Codex based on GPT-5. The exact deployed snapshot and
context-window size are not exposed to this task. It used agentic
reasoning, repository inspection, code editing, Git, parallel subagents,
and GitHub Actions.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no internal
Paperclip ticket id
- [ ] I have run tests locally and they pass (intentionally deferred to
GitHub Actions)
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented risks above
- [ ] All Paperclip CI gates are green
- [ ] The paid local-provider matrix is green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
## Thinking Path
> - Paperclip is the control plane for AI-agent companies.
> - Agent outputs must remain visible after a run and easy to inspect
from a task.
> - The thread and artifact inventory need one consistent rich-card
vocabulary.
> - Run uploads also need durable artifact registration and
producing-run context.
> - Reviewers need deterministic examples for each rich-card kind and
state.
> - This pull request adds the shared presentation, registration,
inventory, and Storybook review coverage.
> - The benefit is a complete output path that reviewers can inspect
without seeded data.
## Linked Issues or Issue Description
**What existing behavior does this improve?**
This change improves work-product presentation in task threads and the
task Artifacts tab.
**Subsystem affected**
The change affects shared work-product contracts, the runner diff path,
server attachment and work-product services, GitHub metadata refresh,
the React board UI, and Storybook.
**Current behavior**
The thread used generic cards. Some files uploaded by a run existed only
as message attachments. The Artifacts tab showed a flat list without run
context or filters. Storybook showed only one resting card per kind.
**Proposed behavior**
The thread uses rich cards for supported work-product types. Each
run-produced file registers one attachment-backed artifact work product.
The Artifacts tab groups outputs by run and supports filters. Storybook
shows every kind and requested state, PR lifecycle states, stats
variants, truncation, mobile layout, and message-tail media.
**Reason and benefit**
Users can identify outputs quickly. Reviewers can inspect all card
permutations without creating task data.
**Breaking changes**
None. The metadata fields and automatic artifact registration are
additive. Existing attachments and work products keep their current
behavior.
## What Changed
- 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.
- Registered each run-produced attachment as an artifact work product in
the same server transaction.
- Grouped task artifacts by run with agent and timestamp headings.
- Added type and run filters, image thumbnails, compact cards, and a
company Artifacts link.
- Added a Storybook kind-by-state matrix with stats variants for all
eight visual kinds.
- Added PR open, draft, merged, and closed examples, long-title
truncation, an exact 375-pixel viewport, and message-tail overflow
coverage.
- Closed reconciled runtime work products when the linked runtime stops
or disappears, so the card shows `Stopped` instead of `Unhealthy`.
### Screenshots
Before: one resting card per kind.

After: the kind and state matrix.

After: message-tail media at 375 pixels.

[Open the Storybook evidence
viewer](https://pages.paperclip.ing/rich-work-product-storybook-20260902/).
The earlier artifact inventory comparison remains available in the
[artifact inventory
viewer](https://pages.paperclip.ing/rich-artifacts-inventory-proof-20260902/).
## Verification
- `pnpm --filter @paperclipai/ui typecheck` passed.
- `pnpm check:token-gates` passed.
- `pnpm build-storybook` passed.
- `pnpm exec vitest run
server/src/__tests__/work-product-runtime-reconciliation.test.ts` passed
with 5 tests.
- Chromium visual checks passed at desktop and 375-pixel widths.
- All 30 latest-head GitHub checks passed. One unrelated annotation test
was flaky and passed on its single retry.
- Greptile passed at 5/5 with zero unresolved threads.
## Risks
- Low risk. The Storybook change adds review fixtures only. The runtime
fix changes read-time reconciliation without database writes.
- The matrix is intentionally large so every permutation stays visible
in one review surface.
> I checked `ROADMAP.md`. This work does not duplicate planned core
work.
## Model Used
- OpenAI Codex with GPT-5 and GPT-5.6-sol across this pull request.
Reasoning, tool use, and code execution were enabled. The context-window
size is not exposed.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My public branch name describes the change and contains no
internal task id
- [x] I have run tests locally and the changed-path tests pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
Takes the four tenant onboarding steps to the design, and makes the model
choice explicit.
**Nothing is preselected on the connect step.** It arrived with a source
already chosen, which made the row read as a confirmation rather than a
question and let a customer pass the step having touched none of it. The
step now opens unanswered and cannot advance until a source is selected in
the visible row.
Two defects fell out of that, both found by Greptile in review:
- A saved draft can name an adapter the row does not show — one the registry
dropped, or one in the advanced list. The gate asked `sourcePicked`, which
only means "a draft named something", so Next stayed live on a step that
had visibly asked nothing and would hire against the hidden name. It now
asks `sourceSelected`, read off the visible row, and the snap that replaces
an unofferable adapter clears the pick rather than presenting its
replacement as chosen.
- Cmd+Enter bypassed that gate entirely, because the condition was written
out twice and drifted. Both paths now ask one predicate.
Also: selection is a fill rather than a border; the input canvas opens only
for a chosen source; the close control is gone from every step (nothing
downstream of the connect step works until a model is connected); the arc
draws to the design's 424px column with a filled 44px name field; the CTA
reads "Next" through the arc and "Get started" at the end; the login spinner
reads "Preparing..."; the OAuth panels number their fields and show the URL
above the code.
Storybook: the arc stories waited for a button named "Connect" and had been
silently rendering the wrong step since the CTA was renamed. They now wait on
the destination heading. Three e2e specs had the same fault and now select a
source before advancing.
One test was removed rather than replaced — `hydrates again when the same
company comes back through onboarding` drove the close control, and three
substitutes each passed against a wizard with the behaviour deleted. The
reason is recorded where it stood.
Known and not fixed here: SidebarCompanyMenu opens the wizard at step 1 for
"create a new organization", and with no exit an existing user who changes
their mind is trapped.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Apps subsystem gives humans and agents governed access to
external tools.
> - The current connection flow hides Apps behind an experimental gate
and repeats setup text.
> - Google sharing choices and generic MCP permissions do not use one
consistent opening model.
> - Self-hosted installs also need a safe default origin for managed
OAuth without a manual config file.
> - This pull request makes Apps available, simplifies connection setup,
and applies one governed permissions model.
> - The benefit is a shorter connection flow that works on a clean
self-hosted install.
## Linked Issues or Issue Description
**What existing behavior does this improve?**
This improves the Apps connection setup flow, managed Google connection
flow, generic MCP connection flow, navigation, and runtime origin
discovery.
**Subsystem affected**
Cross-cutting. This changes `ui/`, `server/`, `packages/shared/`,
connector documentation, and browser tests.
**Current behavior**
Apps require an experimental switch. Setup pages repeat titles and
explanatory copy. Connection names require manual input. Google
credential sharing does not always offer both personal and organization
access. Generic MCP providers do not start with the same permission
choices. Managed OAuth needs a public URL setting even when the request
already has a safe HTTPS origin.
**Proposed behavior**
Apps are available by default. Setup asks only for required permissions
and sharing choices. Paperclip creates conflict-free connection names.
Google apps and generic MCP providers use the same human and agent
access model. Managed OAuth derives a validated same-origin HTTPS URL
when no explicit public URL is set.
**Reason and benefit**
A clean self-hosted install can connect a managed Google app without
hidden setup. Humans can share a service account with their
organization. The shorter flow reduces duplicated choices and setup
errors.
**Breaking changes**
The Apps experimental switch is removed. Existing connection APIs remain
compatible. New connections can receive a numeric suffix when a name
already exists.
No duplicate or related public issue was found.
## What Changed
- 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.
- Added organization sharing to Google Workspace credentials while
keeping personal access available.
- Generated connection names automatically and resolved name conflicts
with numeric suffixes.
- Derived a validated public HTTPS origin from the request for
config-free managed OAuth.
- Updated connector contracts, tests, browser coverage, and authoring
documentation.
## Verification
- `pnpm check:token-gates`
- `pnpm -r typecheck`
- `pnpm build`
- `pnpm exec vitest run server/src/__tests__/tool-access-service.test.ts
server/src/__tests__/generic-mcp-connection.test.ts` (273 passed)
- Targeted UI/service regression suite (308 passed)
- Six targeted Playwright connection journeys on a fresh onboarding
instance (6 passed)
- Fresh-install browser proof through Tailscale HTTPS: enrolled with
Paperclip Cloud, connected managed Google Drive, and completed a real
read operation.
- [Exact-head CI
run](https://github.com/paperclipai/paperclip/actions/runs/33669760711):
all 23 matrix jobs passed, including build, typecheck, server,
serialized, canary, and all browser shards.
- Greptile 5/5 on `0ae2a859f269984ee950d0af231a5b09a06f3dfd`, with no
unresolved review threads.
## Risks
Apps are now visible to all operators. The removed experimental flag no
longer hides unfinished app definitions. Managed Google availability
still depends on the Cloud profile rollout and active instance
enrollment. Automatic conflict handling changes only the display name of
a newly conflicting connection.
> I checked [`ROADMAP.md`](ROADMAP.md). MCP Tool Gateway and Apps are
shipped. Connected Apps is planned, and this change improves the
existing shipped connection flow.
## Model Used
OpenAI Codex, GPT-5, with reasoning, browser control, tool use, and code
execution.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - The runner subsystem executes agent work across local and managed
provider backends.
> - The lower pull requests restore the task runtime, provider backends,
and managed-provider control plane.
> - The restored system needs repeatable full-stack checks before it can
ship safely.
> - Paid live checks also need clear access, cost, and secret controls.
> - This pull request adds acceptance, live evaluation, chaos, and
release gates for the restored runner stack.
> - The benefit is measurable runner parity with safer release
decisions.
## Linked Issues or Issue Description
**Subsystem affected**
Cross-cutting. This change covers runner tests, release workflows,
server contracts, and evaluation tools.
**Problem or motivation**
The runner stack did not have one complete acceptance surface for native
Codex, ACPX, Claude Managed, and AWS AgentCore. Release checks could
miss provider drift, task-view regressions, cost-policy errors, and
destructive cleanup errors.
**Proposed solution**
Add a 57-cell full-stack catalog, a Daytona image, and opt-in paid
workflows. Add live evaluation, chaos, cost-limit, redaction, and
release contract checks. Add AWS AgentCore infrastructure and guarded
provisioning tools. Keep the native runner experimental flag off by
default.
**Alternatives considered**
We considered manual smoke tests only. They do not give repeatable
evidence and they do not protect release branches. We also considered
one large pull request. The stacked pull requests keep each review below
the Greptile file limit.
**Roadmap alignment**
This work supports the shipped Cloud / Sandbox agents milestone and the
shipped Agent evals & feedback milestone in `ROADMAP.md`.
Related stack:
- #12699 adds managed provider backends and lifecycle support.
- #12691 adds qualified OpenCode and ACPX provider backends.
- #12685 restores task runtime rendering and steering.
## What Changed
- 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 in-flight reported-usage cost stops, post-turn cost caps,
exact-threshold failure classification, secret redaction, retry
classification, and actor authorization.
- Reattach stream and hard-budget listeners before restart-recovery
continuations so restored paid sessions cannot bypass in-flight
interruption.
- Preserve OpenCode usage and cost across tool-loop messages and turns
while exposing an explicit current-run delta to durable accounting.
- Keep PNG/WebM evidence in access-controlled artifacts only, reject
SVG, and publish only pruned inert structured per-attempt evidence.
- Add AWS AgentCore infrastructure, provisioning checks, and smoke
tools; reject unsafe model identifiers, require exact stack ownership
markers, and make failed-stack replacement explicit.
- Add evaluation-session contracts and capability reports.
- Add release workflow checks for immutable action pins, frozen
dependency installs, exact weekly cron shape, paid-run guards,
provider-secret isolation, and chaos test paths.
- Reauthorize the original and triggering numeric actor IDs as the first
step of every provider-secret job, including partial reruns, before
checkout or provider access.
- Give each full-stack matrix cell only its matching provider
credential, expose Daytona only to Daytona cells, and disable shared
dependency caches anywhere paid credentials or OIDC write access are
present.
- Protect the legacy manual E2E workflow with the same default-branch,
allowlist, environment, and per-job authorization boundary.
- Rotate live-eval candidates by week and retain 120 days of compatible
history so the seven-week trend window remains viable.
- Restore the root runner-acceptance commands and reconcile reported
snapshots,
raw receipts, and terminal usage without double counting or losing late
usage.
- Mark ACPX token deltas exact only when every budget field is present,
keep
cumulative cost/request authority separate, reject non-USD cost
labeling,
and include thought tokens in output-token budgets.
- Keep `enableNativeRunner` off by default. The acceptance harness
enables it only in its isolated test instance.
## Verification
Passed locally:
- `pnpm --filter @paperclipai/paperclip-runner typecheck`
- `pnpm test:runner-acceptance:typecheck`
- `pnpm test:runner-acceptance` (19 tests)
- focused OpenCode proxy, driver, runnerd transport, live-session, and
turn-stream tests (106 tests)
- `pnpm --filter @paperclipai/paperclip-runner exec vitest run
src/live/clean-room-server.test.ts` (22 tests)
- `pnpm test:e2e:runner:typecheck`
- `pnpm test:e2e:runner:unit` (62 tests)
- `node --test scripts/__tests__/release-verify-workflow.test.mjs`
- `pnpm --filter @paperclipai/paperclip-runner
test:runner-workflow-evals` (22 tests)
- `pnpm -r typecheck`
- `pnpm build`
- `node --test
packages/paperclip-runner/scripts/aws-agentcore-provisioning.test.mjs`
(6 tests)
- `git diff --check`
- `cargo test --manifest-path
packages/paperclip-runner/runner/Cargo.toml -p paperclip-runner-core
--lib --locked` (161 tests)
- focused ACPX provider-event tests (10 tests)
- The rebased PR changes 92 files. `pnpm-lock.yaml` is unchanged.
I did not run paid live provider jobs or provision AWS resources. Those
checks need credentials and can create cost.
## Risks
The paid workflows can create provider cost. They require an allowlisted
original and triggering actor, the protected `runner-e2e-paid`
environment, explicit opt-in variables, and cost limits. The four
provider credentials exist only in that master-only environment, which
requires allowlisted reviewer approval and disables administrator
bypass; repository and organization Actions scopes contain no copies.
Provider usage arrives after a billable request, so the live guard
cannot prevent one request from crossing a threshold. It interrupts
immediately on the first reported threshold hit and permits no
continuation.
Visual evidence can contain secrets rendered as pixels. PNG/WebM remain
only in access-controlled workflow artifacts; SVG and per-attempt XML
are excluded, and S3/Pages receive a pruned structured dashboard.
The AWS scripts can create cloud resources. They use explicit commands,
least-privilege roles, KMS encryption, saved nonsecret metadata, and
explicit teardown.
This pull request does not enable the experimental native runner for
existing instances.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
OpenAI Codex with GPT-5. The model used extended reasoning, tool use,
code execution, and parallel subagents.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - The task properties pane lets an operator change the settings for
one task.
> - The pane did not let an operator select the execution workspace for
the next run.
> - The existing workspace card had selection rules that another control
could copy by mistake.
> - This pull request adds one shared selection module and one compact
property picker.
> - The picker keeps the current workspace active until the next run.
> - The benefit is a clear workspace choice in the task properties pane
without an API change.
## Linked Issues or Issue Description
**Subsystem affected**
ui/ — React + Vite board UI
**Problem or motivation**
An operator cannot set the execution workspace from the new task
properties pane. The existing task workspace card also owns selection
rules that a second control could copy and change over time.
**Proposed solution**
Add a compact workspace property picker. Put the shared selection and
update rules in one UI module. Show the picker only when isolated
workspaces and the project workspace policy are enabled.
**Alternatives considered**
The existing workspace card could remain the only control. This would
leave the new task interface incomplete. The picker could also copy the
card logic, but that would create two sources of truth.
**Roadmap alignment**
This is a small UI improvement for existing workspace controls. It does
not duplicate a planned item in `ROADMAP.md`.
Related workspace work: Refs #12682. That pull request changes runner
recovery and other workspace controls. It does not add this task
property picker.
## What Changed
- 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.
- Added unit and component tests for visibility, selection payloads,
search, and workspace reuse.
- Rebased onto the upstream native-run teardown fix so CI drains
background heartbeat writes before PostgreSQL cleanup.
## Verification
- `NODE_ENV=test pnpm --filter @paperclipai/ui exec vitest run
src/lib/issue-workspace-selection.test.ts
src/components/IssueProperties.test.tsx
src/components/RoutineRunVariablesDialog.test.tsx` — 74 tests passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm check:token-gates` — passed.
- `pnpm -r typecheck` — passed.
- `pnpm build` — passed.
- `NODE_ENV=test pnpm --filter @paperclipai/server exec vitest run
src/services/native-runtime/native-question-bridge.test.ts` — 8 tests
passed on the rebased head. The upstream teardown drain prevents the
prior PostgreSQL cleanup deadlock.
## Risks
- Low risk. This is a gated UI-only change.
- A wrong selection payload could change the next workspace mode. Exact
payload tests cover every mode.
- The old card must keep its existing project-default payload. A
shared-helper test covers that payload.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex with GPT-5. The exact serving revision and context window
are not exposed. The agent used reasoning, tool use, and code execution.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - The release pipeline keeps a canonical stable note at
`releases/vX.md` on master for every published stable.
> - Stable `2026.831.1` was a hotfix cut from a branch off
`v2026.831.0`, with its notes committed into the source tree.
> - In that path the workflow resolves notes in `source_tree` mode and
skips `canonicalize_stable_notes`, which is the job that normally copies
the note to master.
> - As a result `releases/v2026.831.1.md` exists on the tag but never
landed on master, so the stable-notes history has a gap.
> - This pull request adds the canonical copy of that note to master.
> - The benefit is a complete, consistent stable-notes history for
readers and for the release tooling.
## Linked Issues or Issue Description
No separate issue. Describing the gap in-PR with the docs template
fields:
**Issue type**
Documentation gap in the release-notes history on master.
**Where is the issue?**
`releases/` on the master branch — the file `releases/v2026.831.1.md` is
missing, although the stable `2026.831.1` release has already published.
**What's wrong?**
The `2026.831.1` patch was published from a hotfix branch whose notes
lived in the source tree (`source_tree` notes mode). That mode skips
`canonicalize_stable_notes`, the job that copies a stable's note onto
master. So every other stable has a `releases/vX.md` on master, but
`2026.831.1` does not.
**Suggested fix**
Add the canonical `releases/v2026.831.1.md` to master, identical to the
copy published with the tag.
## What Changed
- Add `releases/v2026.831.1.md` to master, copied verbatim from the
published `v2026.831.1` tag.
## Verification
- `diff` of the added file against `git show
v2026.831.1:releases/v2026.831.1.md` is empty (identical to the shipped
note).
- Docs-only change: no code, tests, or build outputs are affected.
## Risks
- Low risk. The change adds one Markdown file and touches no code,
schema, or configuration.
## Model Used
- Claude (Anthropic), model id `claude-fable-5` (Claude Fable 5), used
with tool use, shell commands, and file editing.