Commit Graph
475 Commits
Author SHA1 Message Date
Dotta 70d9af5991 Merge current master and retain its snapshot forwarding test fix
Co-Authored-By: Paperclip <noreply@paperclip.ing>

* origin/master:
  fix(grok): avoid routine wakes for proactive admission (#16422)
  feat(ci): profile full CODEOWNER PR suites in Honeycomb (#16378)
  test: bound command snapshot forwarding checks (#16421)
  fix(agents): report actionable lifecycle failure steps (#16418)

# Conflicts:
#	packages/adapter-utils/src/sandbox-managed-runtime.test.ts
2026-10-15 07:23:05 -05:00
DottaandPaperclip 6acec4266e feat(ci): profile full CODEOWNER PR suites in Honeycomb (#16378)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Its PR workflow runs dozens of parallel build and test jobs.
> - Individual job durations do not show the elapsed cost of the whole
suite.
> - Maintainers need one shared timeline to find slow work and repeated
setup.
> - This pull request adds full-suite profiles for selected CI CODEOWNER
PRs.
> - Honeycomb shows each job, step, test file, and supported test on
that timeline.
> - The benefit is evidence for changes that reduce total CI time.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The main PR workflow has about 48 jobs. Maintainers need to compare
their overlapping work and find which jobs delay completion.

**Current behavior**

GitHub shows job and step durations separately. Test files and tests are
not joined to a full workflow trace.

**Proposed behavior**

A CI CODEOWNER adds `profile-ci` to a PR. The tested code stays on that
PR branch. All main PR lanes run, including lanes normally skipped for
stack position or release notes. A trusted post-run exporter sends one
wall-clock trace to Honeycomb.

**Reason and benefit**

The trace supports decisions about which CI work to speed up or remove.
Ordinary PRs do not export traces. The roadmap and related-PR search
found no duplicate CI profiling work.

## What Changed

- Add label selection and a full-suite override. Verify the PR author,
original actor, and rerun actors against the trusted `.github/**`
CODEOWNERS rule.
- Record Vitest, Playwright, and Node test file/test timings in local
artifacts. Keep ordinary reporter behavior and failing exit codes.
- Add a trusted `workflow_run` exporter. Use actual GitHub timestamps
for all jobs, setup, steps, waiting, and teardown. Mark missing test
data and partial reruns.
- Keep the ingest key out of PR jobs. Store it only in the
`ci-profiling` environment, restricted to `master`. The exporter reads
bounded JSON and never executes artifact code.
- Record expected test invocations outside reporters so a missing
invocation cannot appear complete. Preserve `node --test` on older PR
checkouts. Flush large shard inventories before exit.
- Add security, timing, routing, and real-reporter checks. Document
operation and activation. Protect the exporter with CODEOWNERS.

## Verification

- 509 focused workflow/reporter/shard checks passed. They include
outside authors, outside rerun actors, bots, stale revisions, malicious
ZIP paths, incomplete reports, and partial ingestion failures.
- Final revision `3bf5d9017d` adds multi-file qualification and fixes
short-file step parenting and duplicate Node file-wrapper events.
Greptile reviewed this exact revision at 5/5 with no unresolved threads.
[Main PR CI
run](https://github.com/paperclipai/paperclip/actions/runs/38728040302):
the initial attempt had 54 successful checks, 3 intentional skips, and
one serialized-shard failure from an unchanged workspace-authorization
test exceeding its 15-second timeout. The single failed-shard retry
passed: the final result is 55 successful checks and 3 intentional
skips. The same timeout reproduces locally with profiling disabled; both
assertions pass with a diagnostic 60-second timeout override (about 23
seconds total). No source or CI timeout was changed.
- A dry run against real GitHub attempt 2 of run `38677445871` produced
exactly 3 executed jobs, 40 spans, and 510 seconds, excluding 45
carried-over jobs. The partial trace remains explicitly incomplete; this
validation did not upload data.
- `actionlint` passed for all four changed workflows. `git diff --check`
passed.
- Full Node 24 `pnpm -r typecheck` and `pnpm build` passed. The local
full `pnpm test:run` was stopped after it reported a setup-token timeout
and a distribution-plugin-catalog fixture failure. The 30 setup-token
tests passed on focused rerun. The plugin fixture fails at `rmSync` of a
directory symlink on this macOS/Node 24.11.0 host; the same failure
reproduces with the unchanged base Vitest configuration and unchanged
test/service files (10 other tests pass). The local full test suite is
therefore not claimed green.
- A real root-config Vitest probe passed 13 tests with profiling both
off and on. Multi-file Vitest, Playwright, and Node probes each verify
two distinct filename rows and four correctly parented tests, including
repeated test names across files. Separate passing probes exercise the
full exporter hierarchy `workflow → job → step → filename → tests`.
Intentional failing probes preserve failing exit status.
- Verified all 48 measured jobs in latest-head run `38728040302` used
AWS: one `paperclip-ci-routing-x64` gate and 47
`paperclip-public-pr-x64` jobs. Profiling preserves AWS authorization
and its GitHub-hosted fallback. The separate privileged exporter runs on
`ubuntu-latest` outside the measured suite.
- [Live Honeycomb
baseline](https://ui.honeycomb.io/paperclip/environments/test/datasets/paperclip-ci/trace/oaPMzw8zGwG):
48 jobs, 731 spans, 479 seconds. It matches [GitHub run
38671274294](https://github.com/paperclipai/paperclip/actions/runs/38671274294).
This historical trace has job/step data only; it is not proof of the
future label-triggered test-reporting journey.
- Verified the dedicated Honeycomb key is ingest-only with dataset
creation disabled. Verified the GitHub environment allows only the
`master` branch. No repository-level secret of that name exists. Both
credential values were scanned absent from source and branch history.

After merge, add `profile-ci` to a CI CODEOWNER PR, wait for the entire
PR run and exporter, then follow the run-summary link. Collapse job
children to compare parallel lanes; expand a job to inspect its steps
and tests.

## Risks

- Activation requires merging the trusted workflow definitions to
`master`. This PR continues using the current trusted reusable workflows
until then.
- Selected runs produce many spans and artifacts. Oversized artifacts
fail export instead of truncating data. Missing or cancelled reporters
are marked incomplete.
- GitHub timings have second precision. Node test times use reporter
receipt time. Rust retains job/step timing but lacks per-test wall
timestamps.
- CI CODEOWNERS are individual users in the explicit `.github/**` rule.
Unsupported team rules and identity lookup failures disable profiling.
- An interrupted upload can leave partial data. Retrying uses the same
span IDs, but the Events API does not promise deduplication.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, code execution, repository
tools, and browser verification. The runtime does not expose the exact
serving model ID or 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 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
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-15 06:59:50 -05:00
DottaandPaperclip 70de574463 Merge current master into Claude protocol prerequisite
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-15 06:51:01 -05:00
DottaandPaperclip 1897080a6d test(scripts): retire duplicate provisioning fallback launch (#16110)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-15 00:02:38 -05:00
DottaandPaperclip 5c65525219 test(scripts): consolidate stable shard selection cases (#16109)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-15 00:02:23 -05:00
DottaandPaperclip 445feaa7aa fix(server): index retained workspace task authorization (#16334)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Before an agent starts, repository admission checks access to
retained workspace files.
> - Admission holds a company provenance lock while it checks each
source and reader.
> - The retained-task query cast the indexed task ID to text. PostgreSQL
could evaluate privacy across company history before it matched one
source ID.
> - Repeated slow checks kept the lock for hours and blocked other agent
launches.
> - This change looks up the canonical source UUID through the existing
primary key before it checks privacy.
> - The query does less work and keeps the same access decisions.

## Linked Issues or Issue Description

**What happened?**

Nine runs appeared active but had no provider process or log file.
Read-only database inspection found a transaction holding the company
repository-provenance lock for more than ten hours. Eight other
transactions waited for that lock. The owner repeatedly ran workspace
authorization queries. The company had about 13,400 tasks and 8,500
workspaces.

**Expected behavior**

A retained-source check should find the referenced task before it
evaluates that task's privacy. Unrelated task history should not
multiply the privacy work for every source and reader.

**Steps to reproduce**

1. Run the new `workspace-authorization-query.test.ts` against
authorization code from `5c7a025032`.
2. The real PostgreSQL fixture has 1,200 unrelated tasks and one
retained source. The regression fails with 2,402 recursive privacy
traversals, above the bound of 100. The other five access tests pass.
3. Apply this change and run the same test. All six tests pass.

Related: Refs #16330 adds workspace timing evidence. This PR fixes a
measured SQL plan. It does not change those tracing boundaries.

## What Changed

- Compare the UUID task column with a guarded canonical UUID from the
retained-source JSON key.
- Reuse `canonicalExecutionUuid`. Invalid and noncanonical keys still
match nothing and cannot cause a UUID parse error.
- Add real PostgreSQL coverage for query work, missing and foreign
sources, malformed and uppercase IDs, both agent and sponsor grants, and
grant revocation.
- Add a reproducible baseline comparison and document its scope in
`doc/DATABASE.md`.

## Verification

- Red: the unchanged query fails the new work-bound regression. Five
access cases pass.
- Green: 101 tests pass across the new query suite, workspace binding,
and the production privacy review suite.
- Full `pnpm -r typecheck` and `pnpm build`: pass. Dependencies use the
repository's pinned pnpm 9.15.4.
- All current-head CI checks pass, including the full server, chat,
workspace, serialized, Runner, and eight E2E test lanes. Build,
typecheck, canary, and security checks pass. Head:
`ad907f6e14c2d773fa8c20692e5ccc10215c9297`.
- Greptile: 5/5 on that head, with no actionable findings or unresolved
review threads. The branch is mergeable.
- The local full `pnpm test:run` was started, then stopped after a
concurrent disposable-database check hit the macOS shared-memory limit.
This is not counted as a local full-suite pass. The benchmark passed
when rerun alone; the complete suite passed in CI.
- `git diff --check`: pass. The branch has no lockfile or workflow
changes.

Synthetic SQL comparison on PostgreSQL 18.1, with 13,429 tasks and one
retained source:

| Query | Median | Five measured samples | Recursive privacy traversals
|
| --- | --- | --- | --- |
| Baseline `5c7a025032` | 42.57 ms | 42.57, 47.71, 44.51, 41.29, 41.44
ms | 26,860 |
| Fixed | 2.37 ms | 2.76, 2.35, 2.37, 2.11, 3.33 ms | 4 |

Both versions return identical complete rows. The benchmark alternates
variants after two warmup rounds. It loads the baseline authorization
module with current dependencies; the UUID helper is unchanged. The
measured gain is about 18x for this SQL fixture.

The final committed benchmark also passed a second isolated run: 55.44
ms baseline and 3.26 ms fixed, with identical complete rows (about 17x).

Two read-only queries on the affected database also returned identical
complete rows. One changed from 129 ms to 7 ms; a workspace with 49
retained sources changed from 576 ms to 11 ms. These are single paired
measurements, not endpoint or startup benchmarks.

Reproduce:

```sh
pnpm exec vitest run server/src/__tests__/workspace-authorization-query.test.ts server/src/__tests__/task-workspace-binding.test.ts server/src/__tests__/privacy-production-review.test.ts
pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-workspace-authorization.ts --baseline-ref=5c7a025032
pnpm -r typecheck
pnpm test:run
pnpm build
```

## Risks

- A direct UUID cast could broaden or break access for malformed keys.
The existing canonical guard and regression cases preserve the former
text-match behavior.
- Planner choices can differ across PostgreSQL versions and data sets.
The regression bounds real privacy work rather than elapsed time or one
exact plan shape.
- Admission still checks every retained source and reader under its
existing lock. This removes a measured query cost; it does not claim a
bound for the full admission process.
- No schema migration, permission change, lock removal, or live
deployment is included. Recovery of the affected runs remains unverified
until rollout.

## Model Used

OpenAI GPT-6 through Codex, with tool use and code execution. The exact
served model variant 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
#` OR (b) described the issue in-PR following the relevant issue
template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-14 16:55:34 -05:00
b226336762 ci: skip full CI for release-notes-only pull requests (#16207)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Each beta release ends with a pull request that adds one release
notes file under `releases/`
> - PR CI runs the full build, test, and e2e matrix for that pull
request
> - No build, test, or e2e lane reads `releases/v*.md` or
`releases/beta/v*.md`
> - The full matrix takes about 30 minutes, and lost runners or flaky
e2e specs can make it run again
> - This pull request lets the existing CI scope gate skip the heavy
lanes when a pull request changes only release notes
> - The benefit is that release notes pull requests get a green result
in minutes, and code pull requests keep full CI

## Linked Issues or Issue Description

**Issue type**

CI efficiency enhancement.

**Where is the issue?**

The `Select stacked PR CI scope` step in
`.github/workflows/ci-routing.yml`. This step sets the `full_ci` output
for PR CI.

**What's wrong?**

The step sets `full_ci=false` only for middle pull requests in a stack.
A pull request that changes only one release notes markdown file runs
the full matrix. For example, #16053 changed one file in
`releases/beta/`. Its CI ran two times: on the first run, 8 shards lost
their runners, and on the second run, one Playwright spec flaked and
needed a rerun.

**Suggested fix**

Read the pull request diff from the GitHub compare API in the scope
step. When every changed path is release notes, set `full_ci=false`. The
callers already support this value. I found no open pull request or
issue for this change.

## What Changed

- `ci-routing.yml`: the scope step (renamed to `Select PR CI scope`)
also sets `full_ci=false` when every path in the diff matches
`releases/v*.md` or `releases/beta/v*.md`.
- The step reads the diff from `compare/<event base SHA>...<event head
SHA>`. The SHAs come from the event, so a later push cannot change the
decision for this run.
- For a renamed file, the step checks the old path and the new path.
- The step keeps full CI when the event is not `pull_request`, a SHA is
malformed, the API call fails, the diff is empty, or the file list has
300 entries. The compare API can truncate a list at 300 entries.
- The step does not change the stacked pull request rules. It checks the
paths only when the stack rules select full CI.
- `ci-routing.test.mjs`: the GitHub stub now returns `files` for compare
calls. 17 new cases cover release notes paths, mixed diffs, renames,
non-markdown files, nested folders, empty and truncated lists, API
failure, non-PR events, malformed SHAs, and stack interaction.
- `e2e-shard.test.mjs`: the test now uses the new step name.
- `doc/DEVELOPING.md`: added a short description of the CI scope rules.

## Verification

- `node --test .github/scripts/tests/ci-routing.test.mjs
scripts/__tests__/e2e-shard.test.mjs`: 73 pass, 0 fail.
- `node --test '.github/scripts/tests/*.test.mjs'`: all pass.
- I ran the jq filter on real compare API responses. #16053 (one file in
`releases/beta/`) returns `true`. #16082 (10 files) returns `false`.
- After merge: open a pull request that changes only a
`releases/beta/v*.md` file. The `Select trusted runner` job shows the
notice `release notes only; full_ci=false`. The heavy lanes show as
skipped. The `policy`, `verify`, and `e2e` checks pass.

Note: `pr.yml` calls `pr-trusted.yml@master`, and that workflow calls
`ci-routing.yml@master`. This pull request does not change its own CI
run. The change applies after merge.

## Risks

- Low risk. The skip uses the existing `full_ci=false` path. The
`verify` and `e2e` aggregate checks already accept that value, and the
`policy` job always runs.
- A future job that reads release notes files would not run for
notes-only pull requests. Today, only the release workflows read these
files, and those workflows do not run on pull requests.
- The step now uses `GH_TOKEN` to call one more read-only API endpoint.
The workflow still does not check out or run pull request code, and its
permissions do not change.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`), Anthropic. Agentic coding with
tool use (shell, file edits, GitHub CLI).

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: devinfoley <139239+devinfoley@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 13:16:34 -07:00
DottaandPaperclip ad0bd26bb7 perf(heartbeat): avoid Git inspection for stored workspace reads (#16306)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Heartbeat selects and restores a saved execution workspace before
dispatch.
> - These reads used the workspace detail reader, which also scans Git
and resolves delivery state.
> - Configuration reads do not use those live display fields. Each extra
process can delay other controller work.
> - This pull request adds a stored-record reader and uses it in
configuration, environment selection, and finalization.
> - It also derives ancestry from the existing ahead/behind result and
skips delivery HEAD reads for unfinished tasks.
> - The benefit is fewer Git processes while live execution and cleanup
guards remain in place.

## Linked Issues or Issue Description

Related: #16282, #16302, #13619. Those changes reduce background or
display scan demand. This change removes live display inspection from
execution configuration reads.

**What existing behavior does this improve?**

Heartbeat workspace configuration reads and workspace close-readiness
checks.

**Current behavior**

Reading saved workspace configuration also loads runtime health, Git
status, ancestry, and delivery state. Close readiness walks history
twice to determine ancestry.

**Proposed behavior**

Execution reads stored configuration through a company-checked method.
Live branch validation and destructive cleanup still inspect current Git
state. Close readiness uses its ahead/behind result to determine
ancestry.

**Reason and benefit**

A synthetic benchmark of the actual service returned identical stored
fields for 20 workspaces. Detail reads launched 60 Git commands and took
689 ms. Stored reads launched zero Git commands and took 8 ms. This was
a local macOS measurement, not an end-to-end cloud latency claim.

**Breaking changes**

None to public APIs or saved data. Workspace detail responses keep their
live fields.

## What Changed

- Add `getStoredById(companyId, id)` and use it in three heartbeat
reads.
- Preserve the access-denied error for a foreign-company workspace.
- Remove the extra `merge-base` process and the unused HEAD read for
unfinished tasks.
- Add recovery, company-boundary, ancestry, and cleanup regressions.
- Add a repeatable database/Git benchmark and document the read
boundary.

## Verification

- The new environment-selection regression failed before the fix with
`Live Git inspection is unavailable` and passes after it. All eight
environment-selection tests pass.
- On the final rebased commit, workspace service, environment selection,
and branch finalization: 89 tests passed. Branch-containment,
runtime-execution, and display-cache suites also passed during
development.
- `pnpm -r typecheck`: passed.
- `pnpm build`: passed.
- `pnpm test:run`: started locally, then stopped after all full-suite CI
test shards passed on the final commit. The complete local run was not
finished; CI provides the full-suite result.
- Final commit `9a13ef0481b7bf6a60b2b7ac13f35f78a14e232c`: 55 successful
checks and 2 expected skips. Greptile: 5/5, no actionable findings.
- `pnpm --filter @paperclipai/server exec tsx
../scripts/benchmark-workspace-record-reads.ts`: identical stored
fields, 60 to zero Git commands, 689 ms to 8 ms for 20 reads.

## Risks

- Execution callers must use saved fields only. Detail readers and live
branch and cleanup guards remain separate.
- A failed ancestry comparison stays unknown. Automatic cleanup still
rejects unknown delivery state and rechecks Git before deletion.
- This patch has not been deployed. It does not prove the full slow-run
latency is resolved.

## Model Used

OpenAI Codex, GPT-6. The exact model identifier and context window are
not exposed in this session. Used reasoning, repository inspection, code
editing, and local command execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-14 12:53:41 -05:00
DottaandPaperclip 519e8369a1 fix(runner): align clean install probe with Pi profile digest
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-14 12:27:23 -05:00
Dotta 9ac6e674fa Reconcile Claude protocol with merged Codex defaults
Co-Authored-By: Paperclip <noreply@paperclip.ing>

* commit 'adb69e8f09852c772d9901ae270e5b2d66e39c77': (84 commits)
  feat: default new Codex agents to Paperclip Runner on Linux and macOS (#15683)
  docs(skills): add slow-query diagnosis and fix skill (#16303)
  feat(sentry): add opt-in run failure reporting with saved run references (#16300)
  refactor(server): isolate provider message admission and runtime policies (#16289)
  refactor(server): isolate provider webhook lifecycle decisions (#16283)
  fix(workspaces): keep cleanup Git scans fresh and dedupe page reads (#16302)
  fix(sentry): keep provider-rejected Grok wakes out of run failure reports (#16297)
  fix(runner): report Runner disconnect age when a Dot bridge exits (#16296)
  refactor(server): isolate chat conversation and control policies (#16276)
  perf(recovery): use indexed execution identity lookups (#16291)
  perf(runs): bound history and reduce repeated context reads (#16286)
  fix(native-runtime): report which close barrier failed (#16298)
  feat(skills): select and validate tracked GitHub branches (#16288)
  fix(observability): sample native runs independently of triggers (#16285)
  fix(github): retry and recover review publication (#16284)
  perf(workspaces): wake terminal cleanup from committed changes (#16282)
  fix(mcp): deduplicate discovered tool descriptors (#16281)
  perf: remove history scans from task and chat queries (#16278)
  docs(skills): add maintenance bot setup workflow (#16279)
  fix(observability): time execution configuration steps (#16236)
  ...

# Conflicts:
#	.dockerignore
#	doc/plans/2026-10-06-default-agent-runner.md
#	maps/agent-access-map/agents.md
#	maps/agent-access-map/onboarding.md
#	maps/agent-access-map/runs-adapters.md
#	maps/feature-map/onboarding.md
#	maps/feature-map/runs-adapters.md
#	packages/adapter-utils/src/types.ts
#	packages/adapters/codex-local/src/index.ts
#	packages/paperclip-runner/acpx-profiles.json
#	packages/paperclip-runner/protocol/manifest.json
#	packages/paperclip-runner/runner/crates/runner-core/src/generated_acpx_profiles.rs
#	packages/paperclip-runner/scripts/generate-acpx-profiles.mjs
#	packages/paperclip-runner/src/contracts/native-execution.test.ts
#	packages/paperclip-runner/src/contracts/native-execution.ts
#	packages/paperclip-runner/src/drivers/acpx/copilot-installation.test.ts
#	packages/paperclip-runner/src/drivers/acpx/generated-profiles.ts
#	packages/paperclip-runner/test/fixtures/copilot-profile-v18-identity.json
#	packages/shared/src/agent-runner.ts
#	packages/shared/src/index.ts
#	server/src/__tests__/adapter-auth-signal-routes.test.ts
#	server/src/__tests__/agent-adapter-validation-routes.test.ts
#	server/src/__tests__/agent-skills-routes.test.ts
#	server/src/__tests__/agents-pending-approval-config.test.ts
#	server/src/__tests__/built-in-agents.test.ts
#	server/src/__tests__/company-portability.test.ts
#	server/src/__tests__/native-status-arbiter-corpus.test.ts
#	server/src/__tests__/onboarding-seed-route.test.ts
#	server/src/__tests__/plugin-managed-agents.test.ts
#	server/src/dev-native-runner-status.ts
#	server/src/lib/agent-records.ts
#	server/src/lib/agent-runner-platform.ts
#	server/src/routes/adapters.ts
#	server/src/routes/agents.ts
#	server/src/services/agent-hiring.ts
#	server/src/services/agent-runner-selection.test.ts
#	server/src/services/agent-runner-selection.ts
#	server/src/services/built-in-agents.ts
#	server/src/services/company-portability.ts
#	server/src/services/native-runtime/runtime-mode.test.ts
#	server/src/services/native-runtime/runtime-mode.ts
#	server/src/services/native-runtime/setup-readiness.test.ts
#	server/src/services/native-runtime/setup-readiness.ts
#	server/src/services/plugin-managed-agents.ts
#	tests/e2e/chat-adapters-ui-messaging.spec.ts
#	tests/runner-e2e/catalog.ts
#	tests/runner-e2e/first-task-fixtures.ts
#	tests/runner-e2e/first-task-flow.ts
#	tests/runner-e2e/first-task.test.ts
#	tests/runner-e2e/runner.spec.ts
#	tests/storybook-visual/storybook-visual.spec.ts
#	ui/src/adapters/adapter-display-registry.test.ts
#	ui/src/adapters/adapter-display-registry.ts
#	ui/src/adapters/codex-local/config-fields.test.tsx
#	ui/src/adapters/codex-local/config-fields.tsx
#	ui/src/adapters/types.ts
#	ui/src/components/AgentConfigForm.render.test.tsx
#	ui/src/components/CodexRunnerSelect.tsx
#	ui/src/components/ConfigureBuiltInAgentModal.tsx
#	ui/src/components/OnboardingWizard.tsx
#	ui/src/components/ui/select.tsx
#	ui/src/lib/test-agent-setup.ts
#	ui/src/pages/AgentDetail.tsx
#	ui/src/pages/CompanyImport.tsx
2026-10-14 11:48:55 -05:00
DottaandPaperclip bd64eb27b0 perf(recovery): use indexed execution identity lookups (#16291)
## Thinking Path

> - Paperclip manages AI agents and their execution.
> - Recovery must keep old execution ownership visible before new work
starts.
> - Ownership reads filter large run contexts through a combined text
expression.
> - Recovery and status delivery also cast indexed UUID columns to text.
> - These reads can scan history before finding the requested execution.
> - This pull request preserves identity and ownership rules while using
existing indexes.
> - The benefit is less database work during recovery and task polling.

## Linked Issues or Issue Description

Refs #14406. Related community report: #15275. This is an independent
implementation. It does not use that pull request's code or commits. It
covers the reported execution joins and the additional ownership query
hotspot.

**What happened?**

Accumulated staging query statistics showed 11,782 ownership reads at 51
ms each. A paired recovery-action read averaged 22 ms. Both queried
large run JSON. Text casts also prevented indexed UUID lookups in
recovery and status delivery.

**What did you expect to happen?**

Recovery must find the same execution evidence through existing indexes.
Malformed identifiers must match nothing without a cast error. Native
issue bindings must retain precedence. Missing termination evidence must
continue to block new work.

**Steps to reproduce**

Run the disposable benchmark below. It loads the original service
modules from the baseline revision. It compares their exact ownership,
blocker action and status-delivery SQL with the current modules on 1,400
synthetic runs, 350 historical recovery actions and 192 KiB contexts.

## What Changed

- Convert saved text to UUID only after checking its canonical lowercase
form.
- Keep indexed run and task UUID columns unchanged in execution joins.
- Split native and legacy issue predicates so existing indexes can
filter ownership candidates.
- Preserve company scope, native precedence, process and lease holds,
recovery eligibility and delivery receipts.
- Add real PostgreSQL identity and ownership regressions, a reproducible
benchmark and database documentation.

## Verification

- Local service SQL benchmark: ownership 78.30 ms to 1.14 ms, with the
same two complete rows. Blocker action read 76.94 ms to 22.55 ms, with
the same complete row. These are synthetic SQL timings, excluding
process probes, provider calls and HTTP.
- Status delivery returned the same 100 rows. Timing was neutral on the
small-task fixture: 7.85 ms before and 8.30 ms after. No speedup is
claimed for that case.
- 231 local tests passed across six server suites. They cover malformed
identifiers, canonical spelling, company scope, native precedence,
retained processes, workspace restore, native replacement, conversations
and delivery.
- `pnpm -r typecheck` and `pnpm build` passed.
- `git diff --check` passed.
- All current-head CI and security checks passed, including the full
general and serialized suites, browser shards, Runner verification and
build. Greptile reviewed the exact commit at 5/5 with no actionable
findings.
- The older full local sweep in the companion worktree was stopped after
final-commit complete CI passed. It is not claimed as a completed local
pass. The 231 focused tests above passed locally on this branch.

```sh
pnpm --filter @paperclipai/server exec vitest run src/services/conversation-continuation.test.ts src/services/legacy-execution-recovery.test.ts src/__tests__/legacy-workspace-restore-recovery.test.ts src/__tests__/chat-completion-delivery.test.ts src/__tests__/agent-conversations.test.ts src/services/native-runtime/native-safe-replacement.test.ts
pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-recovery-queries.ts --baseline-ref=1e731520bb
```

## Risks

- PostgreSQL accepts more UUID spellings than the old text joins. The
explicit guard preserves the old lowercase spelling requirement.
- Query plans depend on the data distribution. Small task sets can show
neutral status-delivery timing. The benchmark is not a production
latency claim.
- Recovery ownership checks remain conservative. Process, lease,
workspace and no-replay rules are unchanged.
- No migration, new index, cache, cleanup change or lock removal is
included.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository inspection, shell
tools and local code execution. The runtime does not expose a more
specific backend model ID or 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 either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-14 10:14:58 -05:00
DottaandPaperclip ebeac833a6 perf(runs): bound history and reduce repeated context reads (#16286)
## Thinking Path

> - Paperclip helps operators manage AI agents and inspect their work.
> - Run history supplies recent execution records to the board and API
clients.
> - The list repeats eight reads of a large stored JSON context.
> - A caller can also omit the limit and read the complete history.
> - This pull request expands context fields once and bounds every list
read.
> - The benefit is lower database cost and bounded redaction work.

## Linked Issues or Issue Description

Refs #958. Related community reports: #13962 and #10631. This is an
independent implementation. It does not use their commits or code. It
covers the history bounds reported in both. Process memory monitoring
from #10631 is outside this change.

**What happened?**

The run-history query repeatedly extracts fields from large context
JSON. Requests without a limit also load every historical run before
authorization and redaction. Accumulated staging query statistics showed
271 ms for summary history and another 58 ms for its redaction lookup.

**What did you expect to happen?**

Normal reads must use a bounded recent history. Context projection must
preserve the existing values and privacy behavior with less repeated
database work.

**Steps to reproduce**

Run the disposable benchmark below against the baseline revision. It
creates 1,400 synthetic runs with 192 KiB contexts. It compares the
exact service SQL and every returned column for both summary and full
history.

## What Changed

- Expand context fields with one lateral record projection. Preserve
non-object legacy contexts and the first-class issue binding.
- Enforce a 200-row default and a 1,000-row maximum in the route and
service.
- Apply the default in the shared UI client, including both agent detail
implementations.
- Preserve response arrays, authorization, result projection and secret
redaction.
- Fetch older linked runs by ID in both agent pages. Check company and
agent scope, navigation races and visible retry errors.
- Update OpenAPI, data-path documentation and capability maps.
- Add real PostgreSQL and HTTP regressions plus a reproducible
benchmark.

## Verification

- Local benchmark: summary history 37.72 ms to 19.34 ms; full history
37.84 ms to 19.01 ms. All 200 complete positional rows match in each
comparison. These are synthetic local SQL timings, excluding HTTP and
redaction.
- History, route, privacy and redaction suites: 160 server tests passed
across six files. Twenty-two UI API, selection, run-panel and
log-visibility tests passed. Both agent-page variants render an older
linked run with an empty history page on desktop and mobile.
- `pnpm -r typecheck` and `pnpm build` passed.
- Map validation and `git diff --check` passed.
- All current-head CI and security checks passed, including the full
general and serialized suites, browser shards, Runner verification and
build. Greptile reviewed the exact commit at 5/5 with no remaining
findings.
- The full local sweep began before the final compatibility fixes. It
was stopped after the final commits passed complete CI. The focused
local suites listed above passed on the final code. Before interruption,
the broader local sweep passed 31,743 tests across the general server,
UI and several package groups, with no reported failures. The full local
command is not claimed as a completed pass.

```sh
pnpm --filter @paperclipai/server exec vitest run src/services/heartbeat/run-state.test.ts src/__tests__/heartbeat-list.test.ts src/__tests__/agent-live-run-routes.test.ts src/__tests__/run-secret-redaction.test.ts src/__tests__/heartbeat-run-privacy-routes.test.ts
pnpm --filter @paperclipai/ui exec vitest run src/api/heartbeats.test.ts
pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-run-history.ts --baseline-ref=1e731520bb
```

## Risks

- Clients that relied on an unbounded array now receive 200 rows by
default. Explicit limits allow up to 1,000. This change does not add
pagination.
- Legacy context conversion must stay identical. Real database
regressions cover null, array, scalar, nested values and native issue
precedence.
- No schema migration or persistent cache is introduced. Redaction and
access checks remain active.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository inspection, shell
tools and local code execution. The runtime does not expose a more
specific backend model ID or 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 either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-14 10:14:41 -05:00
DottaandPaperclip e9b6c4d44c perf: remove history scans from task and chat queries (#16278)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task reads and external chat notices must remain responsive as run
history grows.
> - The chat notice sweep casts indexed UUID columns to text.
> - Run redaction and task provenance filter large JSON contexts with
expressions that lack matching indexes.
> - These queries scan history and read large stored contexts on common
requests.
> - This pull request adapts two existing fixes to current master and
adds the missing provenance index.
> - The benefit is less database work with the same query results and
access rules.

## Linked Issues or Issue Description

Refs #15927. This change adapts that chat sweep fix to the extracted
inbound notice module and retains the contributor credit.

Refs #12499. This change adds that missing nested-context index through
a current, concurrent migration. It retains the contributor credit.

This combined change replaces those older layouts for the measured query
paths. It also covers task creation provenance, which those pull
requests do not address.

**What happened?**

The chat notice sweep scans wakeup history. Issue redaction scans run
contexts because only one branch of its JSON condition has an index. The
task creation-source filter also scans contexts because its native and
legacy ID expression lacks an index.

**Expected behavior**

The queries use indexed lookups and return the same rows. Company
access, task origin precedence, secret redaction, and chat notice
ordering remain the same.

**Steps to reproduce**

Run `pnpm --filter @paperclipai/server exec tsx
../scripts/benchmark-slow-queries.ts --baseline-ref=f8af817f8d`. The
benchmark creates disposable PostgreSQL data and compares the old query
with the current query on the same fixture.

## What Changed

- Compare chat UUID columns directly with safely parsed payload IDs.
Reject malformed and noncanonical IDs without a cast failure.
- Add the nested `paperclipIssue.id` run-context index and the exact
native/legacy task-provenance expression index.
- Build both indexes concurrently. Register the migration for top-level
execution and invalid-index retry repair.
- Extend chat payload and migration regression coverage.
- Add a repeatable synthetic SQL benchmark and document its scope and
command.
- Keep the five newest schema snapshots.

## Verification

- Focused local checks: 76 selected tests passed in five files. These
cover FIFO notices, malformed IDs, conversation state, redaction,
provenance, and company boundaries.
- Disposable PostgreSQL 18.1 fixture: 335 tasks, 1,400 runs, 13,000
wakeups, 377 actions, and 192 KiB synthetic contexts.
- Five warm samples per query, after two warmups. Every returned SQL
column matched before and after, compared as positional tuples so
duplicate unnamed projections are retained.

| Query | Before, median | After, median | Improvement |
| --- | ---: | ---: | ---: |
| Chat notice candidates | 26.21 ms | 6.43 ms | 4.1× |
| Task creation-source list | 159.69 ms | 6.51 ms | 24.5× |
| Issue redaction contexts | 131.88 ms | 0.34 ms | 389.1× |

The run-history context projection returned the same 200 rows and kept
the same index plan and buffer counts. Its timings were noisy (37.30 ms
before and 56.78 ms after in the last run; 34.25 ms and 34.14 ms in the
previous run). No improvement is claimed for this control. Its repeated
JSON projection remains a separate optimization opportunity.

The populated plans use the wakeup primary key, the provenance
expression index, and a BitmapOr over both redaction indexes. These are
local SQL measurements. They do not prove an equivalent change in hosted
API latency.

- `pnpm -r typecheck` and `pnpm build` passed locally.
- The full local `pnpm test:run` was started and then interrupted (exit
130) when the Mac reached its PostgreSQL shared-memory limit. It did not
complete and is not reported as passed. The final SQL benchmark passed
after its disposable database resources were released. The full general
and serialized test suites passed in CI.
- All CI checks for final head
`193acca6abaa992acad12f4b631bd31dd3234641` passed, including full Vitest
coverage, E2E checks, typecheck, build, migration order, and lifecycle
boundaries.
- Greptile reviewed that exact head at 5/5 with no actionable comments.


## Risks

- Both indexes add storage and write cost. Initial builds read stored
run contexts and can take time on large histories.
- Concurrent index builds avoid holding a write-blocking table lock for
the whole build. The existing migration retry path removes invalid
partial indexes before retrying.
- The chat parser accepts only canonical lowercase UUID text. This
preserves the prior text comparison, including rejection of uppercase
and malformed values.
- Staging has not been migrated or deployed. Local PostgreSQL and
synthetic data do not reproduce hosted load or network latency.

## Model Used

- OpenAI Codex, based on GPT-6. The exact serving model ID and context
window were not exposed in this session. Used reasoning, repository
tools, browser inspection, and local code execution. The adapted fixes
retain their original contributor credits.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-14 07:37:51 -05:00
Devin FoleyandPaperclip b7f41ee51d perf(ci): warm the public-install npm cache during pnpm build (#16204)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Each pull request runs the Trusted PR CI. The `ci / Build` lane is
the longest check, or close to the longest, in each green run.
> - On 2026-10-13, `ci / Build` took 415-446s in runs 38426120144,
38432086560 and 38423713537. Of that, the public-install verifier took
226-241s.
> - In the verifier, the consumer `npm install` took 119-129s. It
downloads the full public registry graph into an empty npm cache.
> - Source manifests set that graph. Thus CI can download it before
`pnpm build` makes any tarball.
> - This pull request fills the npm cache in the background while the
Rust restore, Evalbook and `pnpm build` run. Then the verifier reads
that cache.
> - The benefit is a shorter `ci / Build` lane. The verifier keeps all
its checks.

## Linked Issues or Issue Description

Refs #15213, #15849, #15868, #15888 (earlier changes that made this
verifier faster).

**Enhancement description**
The `ci / Build` lane runs the public-install verifier after `pnpm
build`. The verifier starts with an empty npm cache. Its consumer
install then downloads the full public registry graph: 119-129s of a
226-241s step.

**Proposed change**
Download the same registry graph into an npm cache in the background,
during the earlier part of the lane. Give that cache to the verifier.

**Why it helps**
The download moves off the critical path of the lane. A local test of
the same 628-package install took 51s with a cold cache and 21s with a
warm cache.

## What Changed

- Add `scripts/public-install-closure.mjs`. It holds the one definition
of the public package closure: `@paperclipai/server`, `paperclipai`, and
each public workspace package that they reach through `workspace:`
specs. It also gives the registry dependencies of that closure.
- Add `scripts/warm-public-install-npm-cache.mjs`. It installs those
registry dependencies into a temporary consumer, with scripts disabled,
to fill `PAPERCLIP_PUBLIC_INSTALL_NPM_CACHE`. Then it removes the
temporary consumer.
- `scripts/verify-grok-npm-install.mjs` now gets its closure from the
shared module. When `PAPERCLIP_PUBLIC_INSTALL_NPM_CACHE` is set, it uses
that directory as the consumer npm cache. When the variable is not set,
it uses a new empty cache, as before. `docker-runner-check.yml` and
`release-smoke.yml` do not change.
- `pr-trusted.yml` (Build job): a new step starts the warm-up in the
background after `Install dependencies`. The verify step waits for the
warm-up for a maximum of 180s and then gives the cache to the verifier.
If the warm-up fails, the step writes a notice and the verifier
continues as before.
- Add `scripts/__tests__/public-install-closure.test.mjs` and add it to
`test:release-registry`. Update the closure assertions in
`grok-public-install-sandbox.test.mjs`.

## Verification

- `node --test scripts/__tests__/public-install-closure.test.mjs`: 4/4
pass.
- `node --test scripts/__tests__/grok-public-install-sandbox.test.mjs`:
24/24 pass.
- `node --test scripts/__tests__/run-vitest-stable-shard.test.mjs
scripts/__tests__/e2e-shard.test.mjs
scripts/__tests__/runner-release-crate-cache.test.mjs`: all pass.
- `release-verify-workflow.test.mjs`: the two "publisher lockfile" tests
fail in my sandbox on clean master too, because they need pnpm. Two
canary git-fixture tests timed out once under load. They pass when they
run alone.
- I ran the warm-up against current master: 62 direct dependencies, 628
packages, 51s cold. The same install with the warm cache took 21s.
- Important: `pr.yml` calls `pr-trusted.yml@master`. Thus the CI of this
pull request runs the refactored verifier on its default path (empty
cache), but not the new warm-up steps. The warm-up steps start after
merge. To measure them, compare the `consumer_install_ms` value in the
`paperclip.public-npm-install.timing.v1` line of a Build job before and
after merge.

- Final review: all latest-head CI checks pass (54 successes, one
neutral result, two intentional skips). Fresh Apex is 5/5 on
`64d091b8b0c5359fa3dc0edb1fd7ef9d24294477` with no unresolved findings.
The two relevant local script suites pass all 28 tests. Current master
combines cleanly.

## Risks

- Low risk. The verifier result does not change. npm checks each cached
tarball against the integrity of its own resolution, and the consumer
directory and lock start empty.
- npm can use a cached registry packument that is a maximum of about 5
minutes old (registry `max-age`). This has the same effect as starting
the verifier a few minutes earlier.
- The warm-up runs at the same time as `pnpm build`. It uses network,
disk and some CPU. In the measured runs, `pnpm build` took 76-96s.
- If the warm-up is slow or fails, the verify step waits a maximum of
180s and then continues with what is in the cache.
- The verifier receipt still reports `cleanNpmInstall: true`. The
consumer install is clean. Only the download cache is shared.

## Expected time savings

- `ci / Build`: an estimated 65-85s less, from 415-446s to about
340-370s. The consumer install goes from 119-129s to about 40-55s, from
the local cold/warm ratio.
- Full PR time: after this change, `ci / Build` is no longer the longest
lane. The longest lanes become `General tests (server N/12)` and `Verify
Paperclip Runner (vitest 1/2)` at about 405-496s. Thus the full PR time
decreases only when Build is the critical path. That is approximately
0-30s in the runs above.

## Model Used

- Anthropic Claude Opus 5.5 (`claude-opus-5-5`), with tool use and code
execution in a Paperclip agent run.

OpenAI GPT-6 (`gpt-6`) through Codex assisted the final repository
review and targeted script validation. This session does not expose an
exact 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 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

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-13 17:18:44 -07:00
DottaandPaperclip 22d05644f4 feat(ui): add Speko voice setup, task calls, and Storybook coverage (#15728)
Runtime #15727 is merged. This PR adds the UI. Qualification follows in
#15729.

## Thinking Path

> - Paperclip manages agent work through tasks and governed connections.
> - Chat connections already bind external conversations to those tasks.
> - Speko handles voice and telephony, while the selected Paperclip
agent does the work.
> - A call needs durable session authority, ordered follow-ups, and safe
result delivery.
> - This PR adds the Speko setup and call controls to the existing Apps
and task UI.
> - This PR depends on #15727. The qualification suite follows
separately. Speko stays experimental.

## Linked Issues or Issue Description

**Problem or motivation**

Phone and browser voice conversations cannot use the chat connection
task lifecycle. A separate voice runtime is needed to preserve task
authority, retries, and reply history.

**Proposed solution**

Add company-scoped voice sessions, signed callbacks, durable replies,
inbound intake, and an agent-facing outbound-call tool. Reuse existing
tasks, queues, secrets, and publications.

**Roadmap alignment**

This extends the experimental chat connector entry points under Agent
Chat and Connected Apps. The project owner requested this feature.

Refs #11418 for the original provider catalog proposal. This
implementation uses the newer chat connection infrastructure rather than
an MCP catalog-only integration. Refs #15721 for remote OpenCode
startup.

## What Changed

- Add the Speko Apps catalog entry, provider artwork, and browser SDK.
- Reuse existing agents in setup. Keep the optional Company Phone Agent
in the catalog, with connection instructions available to any assigned
agent.
- Add task voice controls, transcripts, phone callbacks, inbound-line
settings, and call Activity entries.
- Surface retryable connection and incoming-task inventory failures,
preserve active call controls and cached tasks, restore keyboard focus
after recovery, and bound notification polling so a stuck request cannot
hide later results.
- Put Save & exit and Connect Speko in the credential step’s shared
footer.
- Add deterministic production-component Storybook fixtures for setup,
lifecycle, failures, permissions, and phone surfaces.
- Include voice components in the design guide. Stories never request a
real microphone or place calls.

## Verification

- All 27 focused UI/controller regressions, UI typecheck, token gates,
and 28 map/catalog structural tests pass. The shared connection cache
test covers pause/resume invalidation during the 30-second fresh period.
- Storybook builds 157 Speko production-component stories. The complete
prior 156-story set passed all 624 checks on UI source 249cbc616a. After
the final cache repair, all 152 affected page/launcher checks passed
across both themes, 390/1200 widths and reduced motion. Real microphone
access and external provider requests are blocked.
- Source annotations follow the current generated-catalog contract. No
generated catalog or lockfile is included. Three inherited
GitHub-heading tests passed after master reconciliation.
- Latest-head CI and Greptile review must pass before merge. Local
fixture success does not establish provider or spoken-playback
acceptance.
- The separate integrated browser run passed two journeys and failed
browser answer retrieval. Real browser/telephone playback and timing
acceptance remain outstanding. See the dated qualification report and
E01–E16 runbook. Speko stays experimental.

## Risks

- Voice sessions add migrations and provider-dependent lifecycle
behavior. Migrations preserve existing chat and AI transports.
- Callback origins must be reachable HTTPS. Provider keys and signing
secrets remain vaulted.
- Unverified callers receive task-scoped low-trust authority. Caller ID
does not grant private task access.
- Outbound telephony incurs provider charges. Provider acceptance is not
proof that the caller heard an answer.
- Keep the feature behind the existing experimental chat setting until
the real browser, inbound, outbound, and delayed-result acceptance
matrix passes.

## Model Used

OpenAI Codex, GPT-6, with tool use and code execution. The exact serving
model ID and context window are not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-13 16:26:38 -05:00
DottaandPaperclip 433d94ee0b refactor(maps): generate indexes from local story and feature metadata (#16214)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Feature recipes and Storybook help contributors find behavior,
examples, and verification steps.
> - Independent feature changes currently update shared catalogs,
indexes, and review hashes.
> - Those shared files cause merge conflicts and repeated bookkeeping
during parallel work.
> - This pull request stores metadata in each feature recipe and story,
then generates the combined views.
> - Contributors can merge independent work without editing a common
index. Git and PR evidence retain change and review history.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Maintaining the product, agent-access, and Storybook maps while multiple
agents change different features.

**Current behavior**

A story or recipe change can update `catalog.json`, `INDEX.md`, review
hashes, verification tables, and tracked generated navigation. Two
unrelated changes then conflict in the same files.

**Proposed behavior**

Each story declares capability links and classification in
`parameters.paperclip`. Each feature recipe declares its navigation and
optional verification guidance. Startup, build, and UI typechecking
discover these sources and generate ignored indexes and Storybook pages.

**Reason and benefit**

A routine change edits its own source files. Aggregate metadata is
rebuilt from the merged checkout. There is no sidecar registry, shared
review journal, or hash acknowledgment to maintain.

**Breaking changes**

The tracked Storybook catalog and index paths are retired. Consumers use
`ui/storybook/generated/` or `maps/generated/` after generation.
Contributor instructions and the existing feature-gap browser suite use
the new paths. Story and overview IDs remain stable.

## What Changed

- Move the existing annotations into 262 story files. Preserve
classifications, capability associations, exports, and explicit IDs.
- Discover all 35 feature recipes. Store section/order beside each
recipe and move durable verification routes out of the shared table.
- Remove tracked catalogs, inventories, overview pages, and inline
preview ordering. Keep authored preview behavior in `preview-base.tsx`.
- Generate the Storybook guide, feature/access Markdown indexes, gap
report, page-reference inventory, and preview wrapper automatically.
- Update the map contracts and maintenance skills to use Git history and
revision-specific PR/CI evidence.
- Add schema, identity, regeneration, and actual Git merge tests. Run
these through the existing UI Vitest suite. Add focused browser
navigation checks.

This is one coordinated migration. Most of the 367 changed files contain
only moved metadata or deleted generated content. Review the generator
scripts, map contracts, Storybook configuration, and tests first. No
product API or authorization behavior changes.

## Verification

Passed:

- `node scripts/check-maps.mjs`: 35 paired areas and 175 capabilities.
- `node scripts/storybook-catalog.mjs --check`: 262 suites and 2,485
authored stories after incorporating current master.
- `node --test scripts/check-maps.test.mjs
scripts/storybook-catalog.test.mjs
scripts/storybook-feature-index.test.mjs`: 28 tests, including
independent branches merged in both orders with identical generated
output and no tracked changes.
- `pnpm --filter @paperclipai/ui exec vitest run
storybook/map-tooling.test.ts`: the CI entrypoint runs those map tests.
- `pnpm check:token-gates`.
- `pnpm -r typecheck` and `pnpm build` before the final master rebase.
- `pnpm build-storybook`: all 2,517 original story/docs URLs retained.
Current master contributes exactly four additional recovery stories.
- Focused Playwright navigation checks: search and open a feature
without examples; expand verification guidance and check source links;
retain capability order and follow a related Foundations suite.

The final clean Storybook build passed after deleting every ignored map
output. Post-rebase UI typechecking and both browser tests passed. The
working tree stays clean after generation. The concurrent-cleanup
regression fails with `ENOENT` without the fix and passes with it.

All GitHub CI gates passed on `00fc7ec18e`, which also received Greptile
5/5 with no unresolved findings. The final merge commit `1c3c5143a6`
incorporates master and resolves only the two modify/delete conflicts by
retaining removal of the aggregate index and catalog. Master’s new
workspace feature and access guidance is preserved. Map validation,
catalog generation, overview generation, all 28 map tests, and diff
checks pass after conflict resolution. The maintainer explicitly
requested merging without another Greptile review. CI has not been rerun
to completion on this merge commit. The local repository-wide `pnpm
test:run` was stopped before completion after the earlier CI matrix
passed; it is not reported as a local pass. No screenshot baselines or
production acceptance are claimed.

To repeat the browser check against an owned Storybook server:

```sh
PAPERCLIP_GAP_STORYBOOK_URL=http://127.0.0.1:6136 pnpm exec playwright test --config tests/storybook-visual/feature-gap-stories.config.ts map-navigation.spec.ts
```

## Risks

- Existing branches need a one-time rebase to move their catalog changes
into local annotations. The PR incorporates the recovery changes from
current master.
- Changing the same story or capability can still produce a meaningful
conflict. This removes the shared aggregate bottleneck.
- The generator uses Storybook's existing CSF parser. Literal-only
annotations and parser regression tests protect the current contract.
- Generated Markdown is available after running the generator; the
published Storybook provides a browsable guide.
- Shared source changes still require review. Removing hashes removes
mechanical acknowledgments; it does not establish runtime parity.

## Model Used

OpenAI Codex, based on GPT-6, with repository inspection, code
execution, and browser-test tools. The exact deployment model ID and
context window were not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green on the previously reviewed head
`00fc7ec18e`; final conflict-resolution checks are documented above
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
on `00fc7ec18e`; another review was waived by the maintainer
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-13 15:27:23 -05:00
DottaandPaperclip 5e8e992df2 fix(storybook): reconcile capability associations and map omissions (#16154)
## Thinking Path

> - Paperclip helps people manage AI agents and their work.
> - The feature map describes user capabilities and verification
recipes.
> - Storybook holds isolated examples of those capabilities.
> - Missing catalog links can hide existing examples.
> - Some stories also expose shipped capabilities absent from the map.
> - This pull request adds verified source associations and three paired
map entries.
> - Readers can find existing examples without changing their homes or
URLs.

## Linked Issues or Issue Description

Refs #16052, #16049 and #16046.

**What existing behavior does this improve?**

Storybook capability lookup and the feature/agent access maps.

**Current behavior**

Seventy capabilities have no example link. Some matching stories already
exist. Primary-agent preferences and company decision/fast-response
services appear only under broad neighboring capabilities.

**Proposed behavior**

Add source-supported links across 34 suites. Keep shared foundations in
place while cross-listing them. Add primary-agent, decision-model and
fast-response capabilities to both upstream maps. Retain explicit
simulation and partial-example limits.

**Reason and benefit**

The catalog distinguishes missing associations from missing examples.
The upstream map describes three existing product capabilities more
precisely.

**Breaking changes**

None to product behavior, story exports, folders, sidebar titles or
URLs. A shared foundation can declare a reasoned `home: "foundations"`
override while referencing related capabilities.

## What Changed

- Add 55 references across 34 suites. Replace primary-agent suites'
reporting-line association with their own capability.
- Add three source-reviewed capabilities and their API/actor boundaries
to paired maps.
- Preserve the shared Foundations home when cross-listing developer
design examples. Add a validation regression test.
- Record which exports demonstrate each association and what remains
simulated or unverified.
- Regenerate the catalog and capability data. Preserve all original 223
authored suites and 2,210 story IDs. Retain the two skill-removal
stories added by current master, for 2,212 authored stories in total.
- Reduce empty example lookups from 70 of 171 capabilities to 59 of 174.
Links do not establish complete capability coverage.

## Verification

- Passed: 27 catalog/generator/map tests, catalog validation, map
structural checks, token gates and skill validation.
- Passed: source inventory comparison preserves all authored files,
titles, meta IDs and story IDs.
- Passed: repository typecheck/build and Storybook build. Final built
index has 2,248 entries and preserves all previous entries, including
the two skills stories added by current master.
- The broad local repository test run was interrupted before completion
to resolve a new master conflict. A complete local suite pass is not
claimed; fresh CI passed on the reconciled branch.
- Browser: Design links to preserved Foundations stories;
company-service sections link settings/history/journey suites; decision
SetupToHistory passed 12 interaction steps; primary-agent ReplacePrimary
passed four steps. No console errors in selected checks.
- Greptile: 5/5 on final commit
`805a8af62abe589907e7cc6ca1b415ce1e0cc3c0`, with no findings or
unresolved threads.
- Final-revision CI passed all 57 checks/statuses, including all eight
browser shards, server and Runner tests, typecheck and build. The
unchanged Cloud-auth mocked-response race seen on a superseded revision
did not recur on the final commit. No test expectations were changed.
- New agent-access evidence is source-only. Live provider and
agent-credential verification is not established.

## Risks

- Suite-level associations can represent only selected states. Notes
retain those limits and existing review classifications.
- In-memory connection drafts do not prove reload persistence.
Resume-failure UI does not prove successful continuation. No-op budget
controls do not prove relief or resumption.
- Three map capabilities document existing behavior. No permission, API,
provider or production component changes.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, code execution and source
inspection. The exact runtime model ID and context window are not
exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-13 08:11:15 -05:00
DottaandPaperclip 60bc0d5fee fix(release): run native builds and canary smoke after skipped channels (#16149)
## Thinking Path

> - Paperclip lets people manage AI agents for work.
> - Published packages need the native runner artifacts from their exact
source.
> - The release workflow selects one channel and deliberately skips the
other channels.
> - The native producer used an implicit success condition across those
skipped dependencies.
> - The merged-source release selected native artifacts but skipped
their build and canary publication.
> - This pull request makes the existing producer and canary smoke
conditions explicit.
> - Successful source selection, artifact verification and cancellation
checks still apply.

## Linked Issues or Issue Description

Refs #16028.

**What happened?**

[Release
38389963483](https://github.com/paperclipai/paperclip/actions/runs/38389963483)
passed source selection, then skipped native production, canary
publication and onboarding smoke. The exact source script requires
native artifacts; the API does not expose the source job outputs. The
registry canary still points to an older source.

**Expected behavior**

The selected release channel builds its required native artifacts,
publishes its verified package, then runs the exact-version onboarding
smoke. Skipped inactive channels must not suppress these jobs.

**Steps to reproduce**

Inspect the linked master-push run at
`d67e3507b23041212fa26302ce6de078c5ebcc05`. Compare the successful
source job and exact source script with the three skipped jobs. The two
existing workflow contract cases also fail against the original
conditions.

**Paperclip version or commit**

`d67e3507b23041212fa26302ce6de078c5ebcc05`.

**Deployment mode**

GitHub Actions release workflow.

## What Changed

- Require `!cancelled()`, successful source selection and
`required=true` for native production.
- Require `!cancelled()` and successful publication for canary
onboarding smoke.
- Extend the existing workflow tests for selected channels, skipped
ancestors, missing outputs, failed jobs and cancellation.

## Verification

- The two affected contract cases fail before treatment and pass after
treatment.
- Focused source controls cover 28 producer and five smoke condition
combinations.
- Independent source review found no changes to source, trust, artifact,
channel, permission or publication gates.
- These tests check source predicates. Actual hosted routing and
publication must still pass after merge.
- Full existing release suite: 70/70 pass. Existing source-verification
neighbors: 20/20 pass.
- Workflow structure passes actionlint. Full shell lint reports five
hints in unchanged commands.
- Full hosted checks and fresh Greptile review are pending.

## Risks

The producer serves all release channels. The explicit source-result and
required-output checks retain each channel's admission gates.
Cancellation still prevents new work. This does not change runtime code,
packages, agent selection, or stored configurations. [GitHub documents
the implicit status
check](https://docs.github.com/en/actions/reference/workflows-and-actions/expressions#status-check-functions)
and [skipped dependency
behavior](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-jobs).

## Model Used

OpenAI Codex, based on GPT-6, with reasoning and code tools. This
session does not expose a verifiable exact model ID or 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 either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-13 07:12:11 -05:00
9bd820e687 feat(storybook): mirror the complete feature-map index (#16052)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The feature map describes its user-facing capabilities and
verification recipes.
> - Storybook provides isolated UI examples for those capabilities.
> - The previous organization showed only features with primary story
suites.
> - This pull request derives the complete Storybook index from the
upstream map.
> - Readers can find the same features in both places and see related
examples or explicit gaps.

## Linked Issues or Issue Description

Refs #16046 and #16049.

**What existing behavior does this improve?**

Storybook navigation and the downstream feature catalog.

**Current behavior**

The sidebar has 28 primary feature homes. The feature map lists 35. The
main guide groups suites alphabetically by area slug. Related examples
can live under a different feature.

**Proposed behavior**

Use the feature map's eight sections and 35 features in the same order.
Give each feature an Overview page with all its capabilities, related
example links, and missing-example messages. Keep shared foundations
outside the product index. Preserve all existing stories and URLs.

**Reason and benefit**

Readers can move between the feature map and Storybook without learning
a second index. A feature without cataloged examples remains visible.

**Breaking changes**

None to existing story IDs or product behavior. Storybook start and
build now reject stale generated feature pages and ordering. Run the
catalog generator after upstream changes, inspect the output, and review
affected source fingerprints.

## What Changed

- Generate 35 feature Overview stories and capability data from the
upstream map. Generate the inline sidebar order required by Storybook.
- Replace the main guide with the full ordered feature index and search.
Link all related suites from feature pages, even across primary homes.
- Preserve all 223 authored files, 2,210 story IDs, and the existing
docs ID. Keep status, implementation, and fixture classifications
visible.
- Put the generated Markdown catalog in feature-map order. Keep
generated guides outside example counts.
- Update maintenance and review skills, documentation, and generator
tests. Keep the feature map independent of Storybook.

## Verification

- Passed: 16 catalog and generator tests; map checks; token gates; both
skill validators.
- Passed: `pnpm -r typecheck`, `pnpm build`, and the Storybook build.
- Built-index comparison preserved all 2,211 previous entries and added
only 35 feature overviews. Feature order matches the map.
- Browser: inspected the complete index and sidebar, searched for Goals,
opened its overview, and followed a related suite under Projects. The
original suite renders.
- Passed: all 8,170 UI tests in 728 files. Browser checks also covered
empty search, capability-ID search, missing-example pages, the original
editable-text bookmark, the CLI sidebar label, and searching/opening
shared foundations.
- The broad local `pnpm test:run` was stopped after a failure in the
unchanged GitHub chat test `authorizes description edits as the editor,
never inheriting the original author's access`. That exact test passed
alone without code or expectation changes. A complete local repository
suite pass is not established.
- Original revision CI passed after one runner retry. The merged
revision `5ca01c70716f23974680a8019ddc613035d11bc4` passed fresh CI.
Local UI typecheck, catalog checks, 16 generator tests, map checks and
token gates pass.
- Greptile: 5/5 on final commit
`5ca01c70716f23974680a8019ddc613035d11bc4`, with all findings resolved.
- Master merge: inspected source drift in 61 catalog entries and
regenerated INDEX, preserving upstream notes. Marked the sidebar suite
that mounts IssueDetail unreviewed for the new activity query; recorded
limits for composer and channel-default changes. No stories removed.
- Final Storybook build passed. Browser filename searches for
`new-task-composer` and `forms-editors` return the expected feature and
shared example.
- No visual-baseline or full production acceptance claim. The deeper
authored scenario groups remain intact.

## Risks

- The parser depends on the feature-map Markdown contract. It rejects
unknown index rows, omitted feature recipes, and unexpected generated
files.
- A suite can reference several capabilities. A link proves catalog
association, not complete behavior coverage or production parity.
- Storybook treats `/` as a folder separator. Sidebar labels use a comma
for that character; the guide and page headings retain the upstream
name.
- No database, API, authorization, or production component changes.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, code execution, and browser
inspection. The exact runtime model ID and context window are not
exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-10-13 07:01:29 -05:00
DottaandPaperclip d67e3507b2 feat(runner): qualify Codex platform packages and cache hosted builds (#16028)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native execution needs a compatible installed daemon and provider
dependency.
> - The Codex-default work found missing platform packages and
clean-install startup failures.
> - Release builds also repeat dependency compilation and run
preparation serially.
> - This prerequisite packages four daemon targets and verifies
installed native startup.
> - It also caches hosted Cargo dependencies and overlaps JavaScript
preparation with compilation.
> - Agent creation defaults and experimental gates stay at the current
master behavior.

## Linked Issues or Issue Description

Refs #15683. Refs #15555. Refs #15422. Refs #15926. Refs #15932.

Extract runtime and installation support from #15683. This prerequisite
has 65 changed files. Creation, onboarding, imports, UI runner selection
and graduation remain in the dependent PR. Feature/access maps and the
Storybook source catalog stay synchronized. Existing agents keep their
execution choices.

## What Changed

- Correct the existing runner test fixtures. Reserve owned credential
quorum listeners through the existing bounded fixture helper. Keep
foreign listeners intact, run actual credential staging once, and
preserve its rejection and unchanged-auth assertions. Reuse the
durable-resume outer-limit correction. Wait for actual warm-completion
and held-authorization callback entry under the existing recovery
deadline and surface early request errors. Preserve every semantic
assertion.
- Retain bounded installation failure diagnostics through the existing
qualification receipt upload. Keep the original error, 10-minute
deadline and all success checks.
- Keep startup ownership until credential preparation and registration
drain. Reject duplicate and post-close startup/resume work. Observe
shutdown during normal and adopted authentication readiness. Preserve
the primary failure and retain private state when cleanup is
unconfirmed.
- Package Linux x64/ARM64 and macOS Apple Silicon/Intel daemons. Verify
target headers, source identities, manifests, and hashes before assembly
and installation.
- Reuse the existing release producer/consumer workflows. Cache Cargo
dependencies by target, OS, compiler, lockfile, and contract inputs.
Rebuild workspace binaries. Permit trusted cache writes only for
canonical exact-source master pushes.
- Overlap JavaScript preparation with native compilation. Join both
commands and failure/cancellation cleanup before artifact verification.
- Preserve shell positional arguments in the shared SSH runner and apply
environment assignments correctly. Reject environment option keys. Six
before/after controls and two real SSH subprocess paths pass with zero
provider calls; this fix lands before both Codex and Claude defaults.
- Admit verified suspended SSH backups during cold controller
continuation, using the same full-scope, integrity and lifecycle checks
as sandbox targets. Two positive SSH cases fail before; all 14
positive/negative matrix cases pass afterward. Active ownership and
corrupt/malformed/nonempty state remain rejected.
- Record measured sandbox platform facts through the existing explicit
environment probe. Bind facts to the company, effective provider
configuration, immutable OCI image and actual captured image binding.
Check the returned cleanup receipt. Reject client-authored proof and
stale or named boot identities. Creation and discovery allocate nothing.
Preserve connection-only behavior.
- Resolve the actual remote Codex target and preserve same-host
development overrides. Preserve runtime artifact verification. Use
actual protocol/model compatibility rather than a numerical CLI version
fence.
- Resolve the installed Codex login dependency on 64-bit Linux and Mac
independently of the daemon libc baseline. Preserve account homes and
safe errors.
- Fix actual clean-install TOML table comparison. Preserve strict
semantic checks, comments, private writes, and malformed-input
rejection. Preserve primary startup failures and bounded cleanup.
- Document GNU libc 2.39+ and stock Ubuntu sandbox prerequisites.
Qualify ARM startup with a scoped distribution profile and unchanged
global restrictions. Preserve Windows and Alpine deferral.
- Preserve selected and saved native Codex reasoning effort in the
existing UI builder, while excluding it from other providers. This small
shared correction prevents import edits higher in the stack from
dropping effort.
- Reuse existing installed-package checks and assertions. Paperclip
tarballs contain no Codex native payloads. Official npm dependencies
supply the consumer's Codex binaries. All Docker and native builds stay
remote.

## Verification

Candidate: `271d434c170e74bdedde65d0b13059a55419c943`. It includes
current master `e168512f7bdbb6af6ea01954c6d7ed80b91e903e` and preserves
prior candidates through ordinary commits.

Current [full
CI](https://github.com/paperclipai/paperclip/actions/runs/38346601686)
is successful on attempt 2. GitHub reports 54 successful checks and four
conditional skips, including required verify and browser aggregates,
workspace typecheck/tests/build, Linux DB controls, both runner shards
and [isolated native
compilation](https://github.com/paperclipai/paperclip/actions/runs/38346601609).
Fresh current-head Greptile is 5/5 with all four threads resolved. The
passing build's clean Grok/Codex report records CI merge source
`7a82a37438e6e448abc7cc5caa60dc2519a97be0`, 18 installed packages,
omitted Codex payloads, official host-only npm dependencies and zero
provider calls. Pi setup and its no-prompt lease verification also pass.
The first attempt's single 60-second Node archive download timeout
remains retained; its DNS/TLS/download cause remains unknown. One
unchanged-source retry was requested through the normal Build-job dialog
with debug logging disabled. GitHub's attempt 2 graph reports the other
CI jobs as well; no second retry or source/deadline relaxation was made.

The [final exact-source package
campaign](https://github.com/paperclipai/paperclip/actions/runs/38347027535)
is successful on literal `271d434c170e74bdedde65d0b13059a55419c943`. It
passes all four native producers, public Linux package assembly and
clean installed consumers on Apple Silicon, Intel Mac and Linux ARM64.
The nine qualification-mode skips are intentional; full CI above covers
their ordinary gates. Native builds and Docker assembly ran remotely.
The predecessor [`dae808` package
campaign](https://github.com/paperclipai/paperclip/actions/runs/38342104102)
remains literal historical evidence. Only tests and the dated record
differ from that source; runtime, package and workflow code is
unchanged. The reused credential fixture correction passes all 42
canonical Node 24 controls with synthetic data and independent
matching-source review, and the current hosted runner shard passes.
Production credential behavior is unchanged.

**Merge hold:** current-source CI, fresh 5/5 review and exact-source
package qualification pass. Actual code-owner approval and normal
protected merge remain pending. No slice has merged or deployed. GitHub
CLI authentication needs refresh; the normal signed-in embedded GitHub
UI provided this status without credential workarounds.

- The master merge preserves both Storybook source-review appendices and
the guarded test-home cleanup. All six existing cleanup controls pass
without skips. Master's isolated-home helper/test/setup are
byte-identical. The two existing whitespace lines in master's unrelated
privacy test remain outside this PR's diff.
- Canonical Node 24 passes all 24 existing public-install helper tests.
Three narrow added cases prove bounded/redacted failure metadata,
symlink exclusions, original exception identity, failed diagnostic
writes and no false failure on success. The Mac installer now uses
`--timing`; at most two 16 KiB tails and 32 structured entries per tail
enter the existing receipt upload. Raw argv, URLs, environment, error
text and stacks are omitted. A failed receipt explicitly remains
FAILED/unqualified/runtime-not-attempted. The 600,000 ms install
deadline and every real package/hash/payload/lock/lifecycle/runtime
oracle are unchanged.
- Canonical Node 24 reproduces the durable-resume outer timeout under
controlled fake latency. Only its outer test limit changes to 15
seconds; internal 500 ms/5 second deadlines and usage/effect assertions
remain. Controlled warm-recovery and before-bootstrap authorization
scheduling delays reproduce their callback polling failures, while the
explicit entry signals pass. Early recovery errors surface unchanged.
Independent review is clear. Historical mock binaries support the
fixture controls; fresh full hosted CI remains decisive. The original
hosted callback failure cause is inconclusive.
- The composed runner/surfaces/server/E2E TypeScript checks pass. Map
checks pass 35 areas/171 capability IDs. Token gates pass. The existing
Storybook catalog passes 223 files/2,210 stories; story IDs and
classifications remain intact. The current master had 25 inherited stale
fingerprints from three changed map recipes. Only those guarded
fingerprints and a source-only review note change; all 92 non-map
story/component/fixture inputs remain unchanged. Existing
classifications are retained. This proves source structure, not visual
or live acceptance.
- The 65-file contribution audit has no code file crossing from below
1,000 lines to above the limit. Earlier comment cleanup preserves
executable emissions, parsed workflows and action pins. Independent
cleanup/catalog and three-file reporting reviews are clear. No new
workflow, suite, grader or local native/Docker build was added.

**Prior `dae808` gate evidence:** fresh Greptile is 5/5 with four
resolved threads, isolated native compilation and the browser aggregate
pass. Its first runner shard passes the previous two corrections but
fails a different held-authorization cell at the implicit one-second
polling deadline. It records 1,672 passes/one failure/three skips. This
candidate applies the verified entry-signal correction without changing
production deadlines or any semantic assertions. Its original hosted
cause remains inconclusive until fresh CI.

**Previous-source evidence, kept literal:** the [exact `16a532` package
campaign](https://github.com/paperclipai/paperclip/actions/runs/38338806076)
passes all four native producers, public Linux package assembly, Apple
Silicon, Intel Mac and Linux ARM64 installed consumers. Its fresh review
is 5/5 with all four threads resolved. Full CI records 52 successful
checks, four conditional skips and the two fixture failures corrected
here. This is not a green full-CI candidate or proof for the new source.

`64c074fb8da1b31f8d6042c4fef48dc4164e759b` passed [full
CI](https://github.com/paperclipai/paperclip/actions/runs/38332726938),
54 checks/four conditional skips, [isolated native
compilation](https://github.com/paperclipai/paperclip/actions/runs/38332726787/job/115085895328),
and fresh Greptile 5/5/all four resolved threads. The hosted transport
suite passed 246 tests and startup trust passed 22, closing that
source's local fake-binary limitation. These are historical after
reconciliation.

The [previous exact-source package
campaign](https://github.com/paperclipai/paperclip/actions/runs/38332921463)
built all four platform daemons and passed public Linux package assembly
plus Apple Silicon and Linux ARM64 installed consumers. **Intel Mac
failed:** its initial scripts-disabled npm install timed out before
lifecycle/runtime assertions. The underlying download/resolution/host
cause is unknown because the old helper deleted the npm logs. This is
the concrete baseline for the diagnostic change. The failed campaign
remains failed; no all-platform signoff or automatic retry is claimed.

The earlier `a200495` [four-target
campaign](https://github.com/paperclipai/paperclip/actions/runs/38283695248)
and [scoped ARM
qualification](https://github.com/paperclipai/paperclip/actions/runs/38291535914)
remain component evidence. Cargo restores were cold misses; no
warm-cache speedup is claimed. Paperclip tarballs contain no Codex
payloads. Official npm dependencies supply Codex on the user's platform.

Current-source full workspace typecheck/tests/build, Linux DB controls,
static/Rust/native tests, all browser shards and exact-source package
consumers must pass. New-agent defaults and final managed onboarding
belong to #15683. Actual private Cloud composition, warm/cold signup,
task/follow-up and rollback compatibility remain later release gates.
Source audits found that ordinary managed onboarding does not run the
saved platform probe and Cloud distributes named snapshots without a
verified final boot-image binding. These dependent release blockers
remain open; prequalified E2E fixtures do not close them. Master adds
task-workspace migrations; the final image/migrator and previous-image
checks must include them. ARM paid task/follow-up and ordinary OS APT
installation are not proven.

## Risks

- Multi-target packages require source and header agreement. Missing or
mismatched artifacts fail explicitly. Existing execution choices remain
unchanged.
- Linux requires GNU libc 2.39+ and compatible sandbox prerequisites.
The scoped hosted ARM preparation does not qualify arbitrary containers
or kernels. Windows, 32-bit ARM, and Alpine remain deferred.
- Only dependency crates are cached. Preview jobs cannot write trusted
caches. Concurrent command cleanup must preserve the primary failure.
- Native-free Paperclip packaging retains official Codex npm
dependencies. No Codex payload bundling, schema migration, automatic
agent migration, or production deployment is included.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, repository tools, code
execution, and parallel agents. The exact serving model snapshot and
context-window size are 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 branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-13 06:24:07 -05:00
DottaandPaperclip 35b811e09c fix(qualification): check the current immutable Pi profile
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 23:26:52 -05:00
DottaandPaperclip 12113e431e merge: reconcile task-workspace canonical prerequisite
Preserve Claude v7 effort, lease ownership, historical readers, and Pi25 source binding while composing canonical16a and task-workspace masterf329. Protocol/surfaces noemit and all generation checks pass.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 21:52:28 -05:00
DottaandPaperclip 16a53254c4 merge master and retain bounded install failure evidence
Preserve guarded test-home cleanup and both Storybook source reviews. Keep the installer deadline and all artifact/lifecycle/runtime assertions intact while retaining its failed npm progress.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 21:44:39 -05:00
DottaandPaperclip 48ffca9438 merge: reconcile published native prerequisite and current master
Preserve canonical startup ownership, scoped evidence, current Storybook IDs, and the Codex form controls while carrying Claude effort and immutable source bindings.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 20:40:11 -05:00
DottaandPaperclip c1b9933a24 chore: follow source comment contribution rules
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 20:33:39 -05:00
DottaandPaperclip 9f59ff36cf merge: reconcile runtime qualification with current master
Co-Authored-By: Paperclip <noreply@paperclip.ing>

* origin/master:
  fix(server): keep classified provider quota runs out of Sentry (#16029)
  refactor(chat): extract delivery, reaction, and setup boundaries (#16024)
  fix(heartbeat): answer an unsettled adapter Stop with a 409 instead of a 500 (#16032)
  refactor(storybook): organize folders and navigation by feature map (#16049)
  test: remove repeated setup and strengthen regression proof (#16022)
  feat: maintain Storybook through a downstream feature catalog (#16046)
  ci: route PR admission through reserved AWS capacity (#16042)
  docs(release): canonicalize v2026.1012.0 release notes (#16045)
  ci: add protected routing workflow for reserved AWS capacity (#16039)
  docs: add PR rules for file size and code comments (#16036)
  Add managed Slack setup with an independent own-app path (#15679)
2026-10-12 20:02:47 -05:00
DottaandPaperclip 0ff31b2b76 fix(runner): version Pi attestation for owned settings initialization
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 18:29:22 -05:00
DottaandPaperclip 88bf4c6c1d refactor(storybook): organize folders and navigation by feature map (#16049)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The feature map describes product areas and verification entry
points.
> - Storybook has 223 story suites that show production components,
proposals, and retained history.
> - The parent PR maps those suites to features, but their folders and
sidebar still use unrelated groups.
> - This pull request puts the existing suites under feature folders and
uses the feature map's names and order in the sidebar.
> - Explicit meta IDs preserve existing story links while the titles
change.
> - Contributors can find stories through the same product structure
without losing examples.

## Linked Issues or Issue Description

Refs #16046. This is the requested follow-up. Parent #16046 is merged.
This PR now targets master, with its single follow-up commit rebased
onto the parent squash merge. The Storybook implementation is unchanged
by that rebase. Related open Storybook PRs were checked; this change
organizes existing suites and adds no product capability.

## What Changed

- Move all 223 story files into folders named for their primary feature
area. Keep useful scenario groups below the feature's sidebar label.
- Order the sidebar by the eight feature-map sections. Put Overview
first and shared Foundations last. Leave areas with no stories out of
the sidebar.
- Move 19 support files into `ui/storybook/support/` and update relative
imports and active documentation.
- Preserve all 2,210 story IDs and the single docs ID through explicit
CSF meta IDs. Keep all entry names and story exports.
- Record stable IDs and sidebar titles in the downstream catalog.
Validate feature folders, title prefixes, and IDs. Update the
maintenance skill and review evidence.

## Verification

- Storybook build passed. Built index comparison against parent
`75bd3c977cd828d5222823850339e8204f40eb47` found the same 2,211 entries,
IDs, and names.
- UI typecheck passed (`ui/node_modules/.bin/tsc -b` from `ui`, invoked
as `./node_modules/.bin/tsc -b`).
- UI Vitest project: 728 files and 8,176 tests passed.
- Catalog checker and its nine tests passed. Feature-map checks, token
gates, and the maintenance-skill validator passed.
- Chromium: nine existing play cases and one render case reached
`storyFinished: success` with no page exceptions. The guide rendered,
sidebar sections followed map order, and a search for `steering/queue`
opened its preserved story link.
- Source comparison found only meta title/ID changes, rebased relative
references, and updated fixture path text in story files.
- To inspect: build Storybook, start `node
scripts/serve-storybook-static.mjs --port 6136`, and open the Overview
guide. Expand feature folders and use existing story links.
- The complete repository suite was not repeated for this organization
change. The parent records a backend timeout that passed in isolation,
without a complete broad-suite pass. Visual comparisons remain blocked
by the unpublished empty baseline. The separate fixture-server story was
not run.

## Risks

- Open branches that add stories under old paths will need to choose a
feature folder and update the catalog. Cross-feature suites have one
primary home and retain related capability references.
- Sidebar paths change; story and docs IDs remain stable. Automated
references to source paths may need the new location.
- This is one requested follow-up with 258 changed files, mostly moves.
It exceeds the usual review-size guideline because splitting it would
leave the sidebar and folder convention partly migrated.
- Browser verification samples ten stories, not all 2,210. Existing
production/prototype classifications and review gaps remain unchanged.
- Required CI gates and a 5/5 review passed on the original head. Fresh
checks and review are running for the rebased head. Catalog validation
and all nine checker tests passed after rebase; UI, map, skill, and
checker contents are identical to the original reviewed head.

## Model Used

- OpenAI Codex, GPT-6. The exact runtime model ID and context-window
size are not exposed in this session. Used reasoning, repository
inspection, code execution, and local browser automation.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-12 22:29:22 +00:00
DottaandPaperclip 9e721264e9 feat: maintain Storybook through a downstream feature catalog (#16046)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Storybook supports review of its production UI and proposed designs.
> - Its 223 story files have no consistent link to product capabilities
or record of component and mock provenance.
> - Old compositions can drift while they still look like current
product examples.
> - This pull request adds two maintenance skills and a catalog that
consumes the existing feature map.
> - The first audit preserves all stories and fixes proven fixture
drift.
> - Contributors can now find examples by feature and see what still
needs review.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Storybook maintenance, feature discovery, and the accuracy of isolated
UI examples.

**Current behavior**

Stories are already centralized under `ui/storybook/`, but their sidebar
has 51 top-level groups. Production components, local prototypes, and
historical designs are not consistently distinguished. The old guide
uses manual coverage claims. GitHub searches found no duplicate
feature-map catalog change.

**Proposed behavior**

Keep existing story locations and IDs. Add a downstream catalog keyed to
stable feature capabilities. Record product status, rendered subject,
data boundary, and declared review dependencies separately. Use
dedicated maintenance and review skills to reconcile drift and report
evidence.

**Reason and benefit**

The catalog makes existing examples reusable without treating mock
behavior or old designs as production acceptance. The feature map
remains independent of Storybook.

## What Changed

- Add `maintain-storybook` and `review-storybook` skills with
contributor guidance.
- Inventory all 223 story files. Generate a feature index and provide
searchable navigation in the existing Overview story. Track direct
subjects through relative imports and local wrappers, including the
primitives demonstrated by foundation suites.
- Add a checker for inventory, capability references, duplicate IDs, and
declared-source drift, with eight regression tests. The parser test
covers real nested CSF files, export filters, explicit IDs, and play
counts.
- Preserve historical designs and classify mixed wrappers. Record the
initial audit and remaining parity work.
- Align the question-dismiss/send fixture with production behavior. Add
dismissal and confirmation-reopen regressions and repair the editor
selector.
- Exclude three exported fast-response fixtures from story discovery and
add the missing render-time callback spy.

## Verification

- Passed: `node scripts/storybook-catalog.mjs`, `node --test
scripts/storybook-catalog.test.mjs` (8 tests), and `node
scripts/check-maps.mjs`.
- Passed: validators for both new skills, `pnpm check:token-gates`,
`pnpm -r typecheck`, and `pnpm build`.
- Passed: final Storybook build; nine selected browser `play` cases;
three fast-response render cases; feature-guide search/link navigation;
question-fixture reset on reload.
- Built-index comparison preserved all 2,208 original story IDs and
added only two new regression cases.
- Passed: `pnpm exec vitest run --project @paperclipai/ui` (728 files,
8,176 tests).
- The full `pnpm test:run` has reported a 15-second timeout in the
untouched backend case `connects advertised Workspace gmail.read without
mutating definitions in authenticated`. The exact test passed standalone
without changing code, expectations, or timeouts. The remaining broad
run was stopped after this failure. The full suite is not verified.
- Visual comparison is blocked by the existing empty baseline manifest.
The managed-accounts API/DB fixture was not started. See
`maps/storybook-map/REVIEW.md` for exact scope.

## Risks

- This is an initial inventory and targeted audit. 188 suites still
require deeper state and fixture parity review.
- Review hashes cover declared dependencies. They do not follow all
transitive production imports or prove semantic correctness.
- The catalog requires upkeep when stories, mapped recipes, or declared
subjects change. Shared mocks still need feature-by-feature contract
review.
- No production application source, database schema, or upstream
feature-map contract changes.

## Model Used

OpenAI GPT-6 via Codex. Used reasoning, shell tools, file editing, and
Chromium browser verification. The exact runtime model ID and context
window are not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-12 17:20:00 -05:00
DottaandPaperclip 66f20c4682 fix(runner): report the validated Pi profile in install evidence
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 17:04:17 -05:00
Dotta e23dd02651 Merge remote-tracking branch 'origin/codex/codex-runner-default' into codex/claude-runner-protocol
* origin/codex/codex-runner-default:
  docs: record final environment metadata review closure
  fix(environments): preserve measured proof atomically on metadata saves
  test(agents): distinguish measured and unknown sandbox defaults
  test(e2e): qualify managed Codex images in existing fixtures
  fix(agents): preserve legacy policy and require measured sandbox defaults
  fix(environments): bind platform facts to the effective immutable image
  fix(runner): close review gaps in setup and platform qualification
2026-10-12 16:48:56 -05:00
DottaandPaperclip f5346c05b9 ci: route PR admission through reserved AWS capacity (#16042)
## Thinking Path

> - Paperclip uses CI to verify changes before release.
> - Trusted PR tests can run on isolated AWS workers.
> - Their runner-selection job currently waits for GitHub-hosted
capacity.
> - A large hosted test queue therefore blocks admission to AWS.
> - A dedicated routing workflow lets us reserve capacity for metadata
validation.
> - This PR moves the routing job to reserved AWS capacity after the
bootstrap workflow and pool are available.

## Linked Issues or Issue Description

**Issue type**

CI reliability enhancement.

**Where is the issue?**

The Select trusted runner job in PR CI.

**What's wrong?**

The routing job competes with a large hosted test queue. Its sampled
median wait was about 20 minutes. AWS tests cannot begin before this job
finishes.

**Suggested fix**

Add a protected reusable routing workflow. Deploy its dedicated AWS
pool, then switch the PR caller in a follow-up PR. No overlapping open
PR or issue was found.

## What Changed

- Call ci-routing.yml on protected master from pr-trusted.yml.
- Check the canonical repository and approved PR author/sender before
allocating reserved AWS metadata capacity. Unapproved PRs continue to
use hosted routing.
- Permit approved manual routing canaries on protected master.
- Use a validated roster snapshot for placement. Invalid JSON, missing
settings, stale snapshots, and unapproved identities select hosted
routing without a placement-time JSON parse.
- Preserve the full in-job identity, rerun actor, repository, head,
merge, and stack checks.
- Update stack-scope and placement regression tests and document the
pool and rollback.

## Verification

- The routing scripts and placement expression tests passed (44 tests),
routing-plus-shard tests passed (56 tests), and the existing
.github/scripts suite passed (381 tests).
- Existing routing allow/deny scenarios passed with the extracted script
(16 cases).
- actionlint passed with the dedicated custom runner label declared in
its local configuration.
- git diff --check passed.
- Full pnpm typecheck/test/build cannot run in this worktree because
dependencies are not installed. The change is limited to workflow YAML
and Node tests.
- The dedicated pool is deployed with two warm On-Demand workers and a
four-worker ceiling. The routing qualification passed: it started about
five seconds after workflow creation, selected AWS, and finished while
the hosted gate in the same PR remained queued.
- Bootstrap https://github.com/paperclipai/paperclip/pull/16039 is
merged. The deployed group now authorizes only ci-routing.yml on
protected master, and its master canary passed.

## Risks

- The maintainer explicitly approved a queued-CI admin bypass after
current-head Greptile 5/5 and focused verification.

- Activation requires the deployed routing Fleet and its group to
authorize the routing workflow on protected master. Keep the bootstrap
dependency explicit.
- The group must authorize only ci-routing.yml on protected master and
canonical repository ID 1170821064.
- The routing workflow runs no checkout or PR code and has read-only
permissions. The test admission checks are unchanged.

## Model Used

- OpenAI GPT-6 via Codex, with reasoning, shell tools, and file editing.
The exact runtime model ID and context window are not exposed in this
session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (focused routing and
workflow tests; full pnpm commands are blocked by missing worktree
dependencies)
- [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] Required CI status checked; the maintainer explicitly approved
admin bypass for queued CI after clean current-head review and focused
verification
- [x] Greptile is 5/5 on 993fbe695a with
no open findings or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-12 16:47:57 -05:00
DottaandPaperclip 2a19f3721d fix(runner): close review gaps in setup and platform qualification
Read inert exact-source target data before selecting hosted native jobs. Bound registration teardown and retain unconfirmed recovery state. Record company-scoped sandbox platform facts only for immutable OCI images after confirmed cleanup; preserve existing connection and runner behavior.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 16:14:34 -05:00
Dotta 7eb4f8bdba Merge remote-tracking branch 'origin/codex/codex-runner-default' into codex/claude-runner-protocol
* origin/codex/codex-runner-default:
  feat(runner): qualify native Codex platforms and cache hosted builds
  docs: establish paired feature and agent access maps (#16025)
  fix: retain matching-host runner development overrides
  fix(acpx): record turn activity at the moment a stop fires (#15962)
  refactor(chat): extract channel status, receipts, drafts and authority workflows (#15995)
  fix: preserve saved setup and match sandbox runner targets
  feat: add portable verification skills and refresh the feature map (#15983)
2026-10-12 15:20:10 -05:00
DottaandPaperclip ddcd746eb6 feat(runner): qualify native Codex platforms and cache hosted builds
Extract the tested runtime and installed-package prerequisite without changing agent creation defaults or experimental gates.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 15:15:01 -05:00
DottaandPaperclip 7d9b93aee2 docs: establish paired feature and agent access maps (#16025)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Contributors use the feature map to understand and verify product
capabilities.
> - Agents need APIs and usable entry points within their permission
boundaries.
> - Product recipes and agent access need separate records with shared
capability IDs.
> - This pull request establishes that contract and gives maintenance
ownership of both maps.
> - The benefit is repeatable access review without changing product
behavior or permissions.

## Linked Issues or Issue Description

Refs: #15983, which added the portable verification skills and updated
the feature map. This is its contract-only follow-up. Related: #15288
added the original feature map.

**Issue type**

Missing documentation and maintenance contract.

**Where is the issue?**

The product map, its missing agent access companions, and the
verification skills.

**What's wrong?**

There is no shared convention for API presence, agent entry points,
permission boundaries, access gaps, or evidence. An API declaration does
not prove that a permitted native or remote agent can use it.

**Suggested fix**

Keep the product and agent access maps as siblings under `maps/`. Reuse
capability IDs. Record representative source inventory separately from
operation review and live proof. Keep both maps aligned through the
maintenance skill.

## What Changed

- Move the existing product map to `maps/feature-map/`. Preserve its
recipes and Poteto format. Update relative links and add companion
links.
- Add `maps/agent-access-map/` with 35 area files and 171 matching
capability IDs. Seed representative API operations, agent paths,
policies and known gaps from the reviewed source inventory. Mark entries
as `baseline`, `source-only`, and live verification `not-run`.
- Define the shared contract in `maps/README.md`. Track API presence,
agent availability, policy, evidence and review depth separately.
Require operation enumeration before marking a broad capability
operation-reviewed.
- Extend `maintain-verification-skill` to reconcile both maps and
inspect actual route policy and production tool admission. Update
creation, verification, notices and contributor references to use the
shared contract.
- Add `scripts/check-maps.mjs` and ten regression tests. Check matching
areas/IDs, indexes, references, contract fields, API method/path
examples, justified exceptions and evidence-state consistency.
- Keep the coverage inventory unchanged. Preserve skill invocation
policies and both MIT license blocks. No product API, permission, UI,
runtime helper, migration, dependency or workflow changes.

## Verification

- Passed: `node scripts/check-maps.mjs` reports 35 paired areas and 171
matching capability IDs. All local map references resolve.
- Passed: `node --test scripts/check-maps.test.mjs` runs ten tests.
Fixtures cover missing companions, renamed/orphan/duplicate IDs, broken
references, missing operation fields, empty exceptions, missing API
examples, empty policy fields, and verified evidence without passed
verification.
- Passed: metadata validation for all three verification skills. Skill
and contributor links resolve. Invocation policies and both license
blocks are unchanged.
- Compared relocated recipes with current master. Contents differ only
in relative links and companion links. `coverage.json` is byte-for-byte
unchanged. Master's updated read-only interaction test reference is
retained.
- Passed: `git diff --check`. The branch starts from current master and
contains only this contract change.
- Repository-wide typecheck, tests and build were not run locally for
this documentation and Node structural-check scope. Live agent access
was not exercised. Those gaps are explicit in the baseline entries; the
structural check does not certify behavior. CI and automated review are
pending.

## Risks

- The companions are representative source baselines. They are not
complete operation inventories or passed agent journeys.
- The checker cannot establish actual permissions, native tool
admission, operation completeness or truthful live evidence. Maintenance
must inspect source and verify with the actual permitted agent context.
- External links to the old product-map directory may need updates.
Repository references have been updated.
- Existing access gaps and board/user restrictions remain recorded. This
contract does not change authority or implement missing paths.

## Model Used

OpenAI GPT-6 through Codex assisted with this change. The session does
not expose the exact serving model ID, configured context-window size,
or reasoning setting. Capabilities used: source analysis, file edits,
shell commands, and structural regression tests.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-12 14:52:28 -05:00
Dotta 12f7b62115 Merge latest Codex qualification prerequisites and master fixes
Co-Authored-By: Paperclip <noreply@paperclip.ing>

* origin/codex/codex-runner-default: (25 commits)
  fix: pin ARM qualification helper to workflow source
  perf(ci): cache the Runner's release crate artifacts keyed by their inputs (#15932)
  perf(build): reuse a current Runner build in the server's prepare:runner-vendor step (#15926)
  fix(test): make the vitest home teardown remove read-only runtime-context bundles (#15931)
  fix(test): stop the Sentry timeout assertion matching a random event id (#15929)
  test: qualify Linux ARM with stock sandbox prerequisites
  docs(release): align 2026.1006.0-beta.0 stable notes header with v2026.1012.0 (#16000)
  fix: use Hermes adapter API URL env in prompt (#9425)
  fix(docker): skip the full-tree ownership walk on routine boots (#15992)
  refactor(chat): isolate Telegram, Slack, GitHub and Discord workflows (#15976)
  Preserve repository dependencies when importing GitHub skills (#15731)
  refactor(heartbeat): extract instruction working-copy lifecycle (#15984)
  test: retire redundant suites and consolidate owner coverage (#15978)
  refactor(heartbeat): extract runtime service coordination (#15980)
  refactor(heartbeat): extract execution configuration (#15973)
  refactor(heartbeat): extract run output recording (#15969)
  refactor(chat): extract failed-run retry coordination (#15845)
  refactor(chat): extract publication replacement decisions (#15844)
  refactor(chat): extract identity linking (#15836)
  refactor(heartbeat): extract session preparation (#15966)
  ...

# Conflicts:
#	tests/runner-e2e/pi-controls-evidence.test.ts
2026-10-12 13:43:39 -05:00
DottaandPaperclip 665c155472 Merge master and preserve qualified runner paths
Retain both hosted cache scopes. Use shared test-home teardown and restore owned directory permissions for the observed Mac ENOTEMPTY failure while keeping unrelated errors visible.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 13:42:01 -05:00
DottaandPaperclip a5b16834c8 fix: pin ARM qualification helper to workflow source
Keep frozen product and reusable workflow tooling identities separate. Preserve clean-consumer and package integrity checks.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 13:26:56 -05:00
8227485372 perf(ci): cache the Runner's release crate artifacts keyed by their inputs (#15932)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Its trusted PR workflow builds the Runner's Rust binary in five
jobs: Typecheck + Release Registry, Build, Canary Dry Run, and the
`rust` and `vitest 2/2` lanes of Verify Paperclip Runner. The `Build`
job is the slowest check in almost every green run (461s, 489s and 515s
in runs 38180574768, 38182717052 and 38183149920 on 2026-10-11).
> - Each of those jobs restores master's `release-runner-v2` dependency
cache. That cache holds only third-party crates. `rust-cache` removes
workspace crates when it saves, and a fresh checkout invalidates cargo's
mtime fingerprints for workspace crates in any case. So cargo compiles
`paperclip-runner-core` in release mode from scratch on every run. The
job logs show one `Compiling` line and 28s to 49s for it.
> - 18 of the 239 commits on `master` in the seven days before this
change touched the crate's inputs. The other 221 compiled the same
sources to the same binary again.
> - This pull request adds a second cache that holds only that crate's
release artifacts (about 70 MB). The key is made from the compiler, the
checkout root and a hash of every input the build reads. The master Rust
lane writes it. A pull request whose merge tree has byte-identical
inputs restores it and marks the artifacts newer than the checkout, so
cargo keeps them. Every other pull request misses and compiles as
before.
> - The benefit is about 28s to 49s less on `Build`, which is the run's
critical path, and the same on Typecheck, Canary Dry Run and two Runner
lanes, for about nine of ten pull requests.

## Linked Issues or Issue Description

No GitHub issue exists for this. The description below follows the
enhancement template.

**What existing behavior does this improve?**

The time the trusted PR workflow spends to compile the Runner's own
crate on every run.

**Subsystem affected**

CI / build

**Current behavior**

Every PR job that builds the Runner binary compiles
`paperclip-runner-core` in release mode from scratch. The compile takes
28s to 49s on the `runs-on` fleet (one `Compiling paperclip-runner-core`
line, then `Finished release profile` in runs 38169436532 to 38183149920
on 2026-10-11). The shared Rust cache cannot help: it holds only
third-party crates, and a fresh checkout gives every source a new mtime,
which makes cargo discard the crate's fingerprints.

**Proposed behavior**

The master Rust lane in `release-verify.yml` saves the crate's release
artifacts under a key made from the compiler, the checkout root and a
hash of every input the release build reads. The PR jobs that build the
binary restore that entry read-only. On a hit, a script sets the mtime
of every restored artifact to now, so cargo sees every source as older
than the build and keeps the artifacts. `pnpm build` then prints
`Finished release profile` in under a second for that crate. On a miss,
cargo compiles the crate exactly as before.

**Reason and benefit**

About 28s to 49s off `Build`, the slowest check in almost every green
run, and the same off the Typecheck, Canary Dry Run and two Verify
Paperclip Runner lanes. The saving applies to every pull request whose
merge tree does not change the crate's inputs, which was 221 of 239
`master` commits in the week before this change.

**Breaking changes**

None. The checks are unchanged. A miss or an eviction costs the compile
time it costs today and nothing else.

**Additional context**

This is a workflow change. `pr.yml` calls `pr-trusted.yml@master`, so
this pull request's own run uses the current reader steps, and the
writer runs only on a master push. The saving becomes visible on the
first PR runs after the merge and after the next master push has written
the entry.

## What Changed

- `scripts/runner-release-crate-cache.mjs` (new): the one place that
defines the cached path list (`CACHED_PATHS`), the hashed inputs
(`HASHED_INPUTS`) and the files a restore must contain (`REQUIRED`). The
`scope` subcommand prints the platform, the `rustc --version --verbose`
release, commit and host, and a hash of the checkout root. The
`mark-current` subcommand sets the mtime of every restored artifact to
now and prints a `paperclip.runner-release-crate.v1` JSON line with the
file count and bytes. If the restored set lacks any of the seven files
cargo's freshness check reads or checks for (the fingerprint hash and
dep-info of each unit, the lib's rlib and rmeta, the binary under
`deps`), it removes the restored files, prints `action: discarded`
naming the missing file, and exits 0, so cargo compiles as on a miss.
- `.github/workflows/pr-trusted.yml`: after the `release-runner-v2`
restore in `typecheck_release_registry`, `build` and `canary_dry_run`,
and in the `rust` and `vitest 2/2` lanes of `verify_paperclip_runner`
(new matrix key `release_crate: true`), three steps: compute the key
scope, `actions/cache/restore` the crate under
`runner-release-crate-v1-<scope>-<hashFiles(...)>` with no
`restore-keys`, and run `mark-current` when `cache-hit == 'true'`. The
`hashFiles` list covers the toolchain pin, the manifests and lockfile,
the crate sources, the protocol tree and the three fixture trees the
test modules include (two under the Runner package and
`tests/runner-e2e/fixtures` at the repository root).
- `.github/workflows/release-verify.yml`: in the Rust lane of an
own-repository master push, after the debug warm-up: compute the key
scope, look the key up (`lookup-only: true`), and on a miss run `cargo
clean --release -p paperclip-runner-core` and `pnpm build:binary` (the
exact command the readers run, so the entry carries no test-profile
variants), then `actions/cache/save` the same path list under the same
key.
- `scripts/__tests__/runner-release-crate-cache.test.mjs` (new, 10
tests, in `test:release-registry`): the path list and hashed inputs are
the expected ones and exist; every `include_str!` and `include_bytes!`
in the crate sources resolves under a hashed input, whether its argument
is a literal or a `concat!` of literals, `env!("CARGO_MANIFEST_DIR")`
and macro metavariables, and any other form fails the test by name (this
guard found the `test/fixtures` tree during development and the
`tests/runner-e2e/fixtures` tree in review); the parser itself is tested
on a synthetic crate for each supported form and six rejected ones;
every PR reader restores after the dependency cache and marks before its
build command with the script's exact path list and key and no
`restore-keys`; the Verify lanes are gated by `release_crate`; the
writer runs after the checks with the lookup, the clean and build, and
the save under the readers' exact path list and key; the scope changes
with the compiler and the checkout root and survives a missing `rustc`;
`mark-current` makes every artifact newer than the checkout, leaves a
dependency's artifacts alone, discards a restore missing any one of the
seven required files (one case each, checking the named reason), and
still marks a restore missing any one of the seven files cargo does not
need.

## Review fixes

Greptile's two findings on the first commit were both valid and are
fixed in the second commit:

- **Incomplete caches looked usable.** `REQUIRED` checked four files,
but cargo's freshness check needs seven. Measured with cargo 1.97.1 on
the real crate (restore, touch the artifacts, delete one file, build):
without the lib's fingerprint hash, dep-info, rlib or rmeta it
recompiles the crate (24s to 27s); without the bin's fingerprint hash,
dep-info or the binary under `deps` it relinks (1.5s); without either
`.json` fingerprint record, either rustc `.d` file, the uplifted binary
or its `.d` it reports the crate fresh in 0.15s and recreates the
uplifted binary from `deps`, and the staging step then copies it.
`REQUIRED` now lists exactly the seven files, the glob for the binary
under `deps` excludes the `.d` beside it, and the test removes each of
the seven in turn (discarded, naming it) and each of the other seven in
turn (still marked).
- **Composed include paths escaped the guard.** The regex matched only
`include_str!("literal")` and skipped `include_str!(concat!(...))`,
which the crate uses four times (30 of 34 includes were checked). The
guard now parses every include argument and resolves the `concat!`
forms; one of them, in `provider_events.rs`, reads
`tests/runner-e2e/fixtures/native-completion/terminal-tool-carrier.json`
at the repository root, outside every hashed input. It is test-only, so
today's release binary does not read it, but the key is meant to cover
every include whatever its build, so `tests/runner-e2e/fixtures/**` (9
files, 80 KB) joins `HASHED_INPUTS` and the six key embeddings in the
two workflows. With the first commit's input list, the new guard fails
on exactly that include.
- `doc/RELEASE-AUTOMATION-SETUP.md`: a "Runner release crate cache"
section under the Runner verification dependency cache, with the key,
the writer, the readers and the trust boundary.
- `package.json`: the new test file in `test:release-registry`.

## Verification

- `node --test scripts/__tests__/runner-release-crate-cache.test.mjs`:
10 tests pass, three consecutive runs.
- The second commit, with the real toolchain on the real crate (`rustc
1.97.1`, cold build 2m20s, the crate's artifacts 74 MB): every source
touched to a fresh-checkout mtime and the archived artifacts restored,
cargo compiles (`Compiling paperclip-runner-core`, 24.8s and 25.1s, the
two controls); restored and marked by `mark-current`, `Finished release
profile in 0.16s` with no `Compiling`, and the same on a second build.
Then, for each of the fourteen files cargo wrote for the two units, one
at a time: restored, marked and that file deleted, cargo recompiles
without any of the seven `REQUIRED` files and reports fresh without any
of the other seven; restored with that file deleted and run through
`mark-current`, the seven required ones print `action: discarded` naming
the file and the others print `marked`. A restore holding only the seven
required files builds fresh in 0.15s, cargo recreates the uplifted
binary, and `stage-runner-binary.mjs` copies it into `dist/bin`.
- `node --test '.github/scripts/tests/*.test.mjs'`: 378 of 381 pass. The
3 failures are in `docker-canary-promotion.test.mjs` and fail the same
way on an unmodified `master` checkout in this sandbox (the stand-in
docker writes no `calls.jsonl`).
- `node --test scripts/__tests__/release-verify-workflow.test.mjs
scripts/__tests__/e2e-shard.test.mjs
scripts/__tests__/run-vitest-stable-shard.test.mjs`: 99 of 101 pass; the
2 failures spawn `pnpm`, which is not on this sandbox's PATH, and fail
the same way on `master`.
- Both workflows parse as YAML. No job has a duplicate step name or step
id.
- The mechanism, with the real toolchain (`rustc 1.97.1`, the package's
pin) on a copy of the crate: a cold `cargo build --release -p
paperclip-runner-core --bin paperclip-runnerd` (2m23s here). Then the
artifact set was archived with `tar`, removed, every source re-copied so
each had a new mtime, and the set restored:
- restored, not marked: `Compiling paperclip-runner-core`, 24.6s (the
control; this is what CI does today);
- restored and marked by `mark-current`: `Finished release profile in
0.15s`, no `Compiling`; a second build is the same;
  - one Rust source edited after a marked restore: `Compiling`, 24.0s;
- one protocol schema edited after a marked restore: `Compiling`, 23.9s
(the protocol files enter cargo's dep-info as absolute paths and are
hashed into the key);
- the rlib removed from a restored set: `mark-current` prints `action:
discarded, reason: incomplete: the lib rlib is missing` and removes the
rest, and cargo compiles.
- Not run here: the workflow steps themselves. `pr.yml` pins
`pr-trusted.yml@master`, so this pull request's own `Build` job runs the
current reader steps, and the writer runs only on a master push. The
first PR runs after the merge and after the next master push show the
`Restore the Runner release crate` step's result and the
`paperclip.runner-release-crate.v1` line in their `Build` logs.

## Risks

- Correctness: a reader can only restore artifacts that master built
from inputs byte-identical to its own merge tree, because every input
the build reads is in the key, and the key has no prefix match. A pull
request cannot write. The trust boundary is unchanged: master writes, a
pull request restores master's entry.
- An input the build reads that is outside the hashed patterns would let
a stale artifact pass. The release dep-info lists the crate sources and
the protocol schemas and fixtures; all are hashed. The guard test
resolves every `include_str!` and `include_bytes!` in the crate, literal
or `concat!`, and fails if one lands outside the hashed inputs or uses a
form it cannot resolve, so a new include form cannot slip past it by not
matching a regex.
- GitHub-hosted runners check out under `/home/runner/work`, the
`runs-on` fleets under `/home/runner/_work`. Cargo records the included
protocol files as absolute paths, so an entry from one root is useless
under the other. The checkout root is in the key, so the other root
misses instead of restoring something cargo then discards.
- A cache that does not keep mtimes on restore changes nothing: the
artifacts are then already newer than the checkout, and `mark-current`
sets them to now in any case.
- Cost: one new entry of about 70 MB per distinct input set, written
only by the master Rust lane on a miss, plus one `cargo clean` and
`build:binary` (about 40s to 50s) on that lane when the inputs changed.
The readers pay one restore of about 70 MB (two to three seconds at the
fleet's observed restore speed) and a sub-second `mark-current`.
- An incomplete entry (a writer that saved a partial set) is discarded
by `mark-current` and costs one compile, the same as a miss.

## Model Used

- Claude (Anthropic), model id `claude-fable-5-1` (Claude Fable 5.1),
extended thinking, with tool use (shell, file editing, GitHub CLI, a
local Rust toolchain for the experiment) in a Paperclip agent session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: devinfoley <139239+devinfoley@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-12 11:25:31 -07:00
DottaandPaperclip 0690801f13 test: qualify Linux ARM with stock sandbox prerequisites
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 13:13:19 -05:00
DottaandPaperclip 33c9216614 fix(runner): pin the Pi v23 digest in its install probe
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 12:55:28 -05:00
DottaandPaperclip ca52d2998c fix(runner): verify the current Pi profile in clean installs
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 12:54:57 -05:00
Devin Foley 4f399cec9f fix(docker): skip the full-tree ownership walk on routine boots (#15992)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Docker image keeps all instance state under `PAPERCLIP_HOME`,
and deployments mount a volume there
> - Before it drops privileges, the entrypoint makes sure that the
`node` user owns the home (#10530)
> - The ownership probe is a first-mismatch `find` over the whole tree.
When ownership is correct, `-quit` never fires, so every boot stats
every file on the volume
> - On homes with many agent worktrees and `node_modules` trees, this
walk takes minutes before Node starts. That is close to common 300s
healthcheck windows
> - This pull request keeps a cheap shallow probe on every boot. It runs
the full-tree probe only once per volume and node UID/GID, and records
the result in a marker file
> - The benefit is that routine boots no longer scale with the file
count, and the original root-owned-volume fix stays in place

## Linked Issues or Issue Description

Refs #10431 (the open follow-up about the remaining cost of the
ownership walk). Related: #10530 (the change that added the full-tree
probe).

**What happened?**
On a hosted multi-instance deployment, we measured the time from
container start to the first app log line. Instances with many files on
the volume (agent worktrees with `node_modules`) took about 190-235s.
Small instances took 5-22s. One 30 GB volume with few files took 24s, so
the cost follows the file count, not the volume size. Almost all of this
time is the `find "$home_dir" \( ! -user node -o ! -group node \) -print
-quit` walk in `scripts/docker-entrypoint.sh`. When ownership is already
correct, `-quit` never fires, so the walk stats every inode on every
boot.

**Expected behavior**
When ownership is already correct, the entrypoint pre-start phase is
short and does not depend on the number of files in `PAPERCLIP_HOME`. A
fresh root-owned volume, a UID/GID remap, and an upgrade from an older
image are still repaired before the privilege drop.

**Steps to reproduce**
1. Run the image with a volume on `/paperclip` that holds a few hundred
thousand files, all owned by `node:node`.
2. Restart the container.
3. Compare the container start time with the first server log line. The
gap grows with the file count, even though no `chown` runs.

**Paperclip version or commit**
`master` at a9830414c7

**Deployment mode**
Docker production image (any platform that mounts a volume on
`PAPERCLIP_HOME`)

## What Changed

- `scripts/docker-entrypoint.sh`: the ownership probe is now tiered.
- Every boot runs a shallow probe (`find -maxdepth 3`) over the home and
its first three levels. A fresh root-owned mount and a UID/GID remap
both change the owner of the home directory, so this probe catches them.
- The full-tree probe runs only when
`PAPERCLIP_HOME/.paperclip-ownership-verified` is missing or records a
different node UID/GID (format `v1 <uid>:<gid>`). This catches deep
mismatches, including the first boot after an upgrade from an older
image.
- Any mismatch repairs the whole tree with `chown -R node:node`, as
before. After a clean probe or a repair, the entrypoint writes the
marker as the `node` user (through `gosu`), so the marker never trips
the shallow probe. A failed marker write is ignored: the only cost is a
full probe on the next boot. If `find` exits non-zero without a mismatch
(for example, an I/O error), the walk is incomplete, so the entrypoint
does not write the marker and the next boot probes again.
- `scripts/docker-entrypoint.sh`: timestamped log lines at entrypoint
start, around the full probe and the repair (with durations), and right
before the `exec` of the server. You can now measure the pre-start phase
from the container log.
- `server/src/__tests__/docker-entrypoint.test.ts`: the `find` stub now
tells the shallow probe from the full probe. New tests cover each path
(see Verification).
- `doc/DOCKER.md`: documents the marker, how to force a full check, and
the new log lines.

## Verification

- `cd server && npx vitest run src/__tests__/docker-entrypoint.test.ts
src/__tests__/container-init-reaping.test.ts
src/__tests__/docker-build-stamp.test.ts`: 40 passed. New cases:
- correct ownership + current marker → shallow probe only, no full walk,
no `chown`
- current marker + deep-only mismatch → full walk skipped (this is the
documented trade-off)
- no marker (upgrade) → one full walk, no `chown`, marker written as `v1
1000:1000`
- no marker + deep mismatch → full walk finds it, `chown -R`, marker
written
- root-owned top level with a current marker → `chown -R` without a full
walk
- full walk fails without a mismatch → no `chown`, no marker, retry
logged
- marker for another UID/GID → full walk runs again, marker rewritten as
`v1 1001:1001`
- timestamped `starting`, `ownership repair finished in Ns`, and
`starting app as node` lines, in order, before the command runs
- The new tests fail against the old script. The 11 existing tests pass
unchanged.
- `cd server && npx tsc --noEmit`: passes.
- `shellcheck -s sh scripts/docker-entrypoint.sh`: clean. `dash -n`:
syntax OK.
- Manual run with the real `find` (BSD find, script run under `dash`)
against a 200k-file tree. Only `id`/`usermod`/`groupmod`/`chown`/`gosu`
were stubbed, and `node` was mapped to the local user and group:
- boot 1, no marker, one deep group mismatch → full probe, `chown -R`,
marker written
  - boot 2, marker present → no full probe, no `chown`
- boot 3, no marker, clean tree → full probe, no `chown`, marker written
  - boot 4, marker present, clean → no full probe, no `chown`
  - boot 5, top-level group mismatch with marker → `chown -R`
- I did not build the image or measure boot time in a container. Docker
was not available on the machine I used. On a warm local disk the full
walk is sub-second, so the local timings say nothing about cold network
block storage.

## Risks

- Once the marker is current, a mismatch deeper than three levels is not
detected automatically. Examples: files written as root by `docker exec`
or a restore run as root, after the first verified boot. Before this
change, those files were repaired on the next boot. The workaround is in
`doc/DOCKER.md`: delete the marker and restart. A remap, a fresh volume,
and a root-owned top level are still detected on every boot.
- On the first boot after an upgrade, each existing volume pays one full
walk (the same cost as today). Later boots skip it.
- The marker is a new dotfile in `PAPERCLIP_HOME`. Backups and copies
that include the home carry it along. This is safe, because the marker
records the UID/GID that it verified, and a different UID/GID forces a
new full probe.
- The non-root path (restricted PodSecurity, OpenShift) does not change,
apart from two new stdout log lines.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`, 1M context) via Claude Code, with
tool use (shell, file editing). Default reasoning mode.

## 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
2026-10-12 10:22:43 -07:00
DottaandPaperclip 598e190cb3 test: bind installed native payloads and await saved state
Isolate actual Codex resolver fixtures from global bridge lookup and preserve host qualification blockers with literal evidence.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 11:45:22 -05:00
DottaandPaperclip 123a188374 fix: separate Codex login and ARM host qualification
Keep daemon ABI admission separate from CLI login and preserve restricted Docker installation checks before native host startup.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 11:20:36 -05:00
DottaandPaperclip 695506ad39 perf: cache native builds and verify Linux runtime targets
Preserve actual target selection, record the GNU libc baseline, and retain primary installed-startup failures for ARM qualification.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 10:53:24 -05:00
DottaandPaperclip dcdf09a0f3 feat: include Linux ARM64 in native Codex runner targets
Ship a source-bound ARM64 daemon alongside Linux x64 and both Mac targets.
Use native hosted builds and the existing clean npm/native startup verifier.
Read target requirements from the immutable source to preserve historical
three-target promotions. Keep Codex payloads as official npm dependencies.

Resolve ARM64 creation and login through the shared platform contract. Share
the existing legacy CLI permission calculation with import previews without
changing execution behavior. Record targeted checks and live Mac evidence.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 10:13:34 -05:00
DottaandPaperclip 058af8f1b6 fix: preserve release artifacts during dev builds and display imported policy
Keep source-built daemons separate from source-bound release targets and select
fresh compatible source output only inside the development supervisor. Preserve
release manifests, running executable inodes, and explicit operator overrides.

Show the existing translated Codex permission policy in import controls while
preserving runner-only override payloads. Record real Apple Silicon task and
paused import proof alongside exact qualification sources.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 09:32:28 -05:00
DottaandPaperclip d522822a5d fix: preserve imported runner choices and qualify Mac install fixtures
Forward explicit import runner overrides, preserve native harness identity without experimental Codex gating, refresh existing host daemon outputs atomically, and retain strict public install probes with target paths and the executing Node SDK.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 08:55:54 -05:00