Commit Graph
164 Commits
Author SHA1 Message Date
DottaandPaperclip 0a5f1546ee feat(cases): add reusable prompt workflows (#17114)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Cases keep facts, documents, and one primary task across agent
handoffs.
> - Each case currently needs its own procedure text.
> - Agents need to reuse procedures and move cases between them without
replacing the task.
> - This change adds company workflow definitions with a name and
Markdown prompt.
> - Existing handoff and document transactions preserve authority,
revisions, and recovery.
> - Cases remain behind `experimental.enableCases`.

## Linked Issues or Issue Description

Refs #16959. Related proposal: #3951 uses task graphs and a visual
editor. This change extends existing Cases with prompt definitions and
keeps its current handoff model.

**Problem or motivation**

Agents cannot share a reusable procedure across cases or inspect a
case's movement between procedures.

**Proposed solution**

Add name-and-prompt workflow definitions. Adopt a prompt into the
primary task's revisioned workflow document through a handoff. Keep
phases as free text.

**Alternatives considered**

Defer graphs, workflow versions, run entities, role schemas, authoring
screens, and Spec Kit integration.

**Roadmap alignment**

This extends the existing Cases experiment and same-task review flow. It
adds no work queue or new execution engine. The maintainer approved this
scope in the implementation plan.

## What Changed

- Add company-scoped definition storage, shared request schemas, REST
routes, and four optional Cases tools.
- Accept a workflow ID at kickoff. Agent handoffs can adopt, refresh,
preserve, or detach a workflow.
- Capture prompt text and the document base revision at acceptance.
Apply workflow, phase, and document revision together after outgoing
execution settles.
- Hold conflicting document edits for recovery. Preserve cancellation,
replay, and restart behavior.
- Show current workflow names and captured transition names/phases in
Work, history, and Audit.
- Update instructions, API/tool contracts, capability maps, and the
isolated workflow journey.
- Pin bounded workflow prompt reads to a content fingerprint;
continuation conflicts on edits and can restart safely.
- Remove experimental Cases/workflow/Mermaid guidance from the always-on
native prompt. Extract runtime-context prompt strings into a
CODEOWNERS-protected constants file while preserving the public imports.
- Refresh Copilot’s pinned source identity to v57, including the
extracted prompt file and retaining historical identities.

## Verification

Local checks: repository `pnpm -r typecheck` and `pnpm build` pass on
the prompt-extraction tree (`88222d45d8`). Full repository coverage
previously completed through the supported isolated shard groups (1,082
general server suites, 161 serialized suites, and all three workspace
groups). The earlier default serial run was interrupted and remains
incomplete. The first sharded run retained the failures described below;
targeted corrections and separate limited-concurrency reruns pass. All
CI jobs, security checks, and the 5/5 Greptile review passed on
`fc1bd79c28`. Fresh CI and review are pending for the prompt extraction
in `88222d45d8`. Focused verification passes: real-database handoff
recovery and reuse; 2,002 native-tool/API contract checks; 144 Runner
catalog/discovery checks; 27 Runner context/coverage checks; 37
case/Audit UI checks; and Product E2E oracle calibration. Token gates,
migration safety/numbering, module boundaries, capability maps, and
generated tool/Storybook catalogs pass. The final route/context
corrections pass 49 API/native-tool tests, 90 real-database handoff
tests, and server typecheck; 142 Copilot installation/sidecar tests pass
with the refreshed identity.

Greptile’s first review found that successive prompt pages could mix
definitions after an edit. The fix returns a content fingerprint,
requires it for continuation, and rejects edits with 409. Strict
live/catalog schemas pass (171 Runner checks). The 2,005 API/OpenAPI
tests pass; the initial native regression caught compression’s weak ETag
prefix, and all 23 native integration tests pass after handling it. The
regression covers same-length edits and a four-byte restart window. No
stored version fields or entities were added.

The prompt extraction passes all 462 checks across six focused suites,
including persisted-context recovery and provider transport. The first
local transport attempt lacked the required debug Runner binaries (102
failures, retained); after building the normal prerequisites, all 283
tests in that suite pass without source or assertion changes. Existing
saved snapshots retain their recorded prompt text, and new executions
use core-only prompt v7. The extracted prompt source is now covered by
both CODEOWNERS and Copilot’s source fingerprint.

Live-provider evidence is separate from those simulated checks: the
isolated API-key campaign `reusable-workflows-api-final-2026-10-21`
passed with local code matching `a1d73b4652`. Four actual Codex API runs
read the adopted task documents, moved one case A → B → A on the same
task, completed normally, and passed all nine durable checks. Browser
assertions verified the current workflow/phase, historical names/phases,
five handoff records including terminal completion, and the completed
original task. Cleanup passed. The local report remains under
`tests/runner-e2e/results/reusable-workflows-api-final-2026-10-21/`; no
credentials or screenshots are committed.

CI initially caught an omitted route-inventory entry and a stale pinned
instruction-source hash; both are corrected and separately verified.
Local serialized coverage also recorded an unrelated environment-route
socket disconnect and activity-route timeout; their separate 11-test and
17-test suites passed without code or timeout changes. An unchanged
chunked-webhook check also passed its separate four-test rerun. The
initial adapter/database workspace groups hit time and resource limits
under default worker counts; complete reruns with `VITEST_MAX_WORKERS=2`
pass, including all 55 database files and 211 tests. The UI/CLI groups
passed 837 files and 9,442 tests in the original run. Original failures
remain retained and are not regraded.

Earlier failed live campaigns remain unchanged: subscription HTTP 429
before agent execution; an obsolete exact-four-row oracle that rejected
the valid terminal fifth row; and a chat-marker expectation that did not
account for the existing explicit-comment presentation policy. The final
fixture requires terminal completion and places the marker in its
authoritative comment. Positive/negative oracle tests and the fresh live
campaign pass.

## Risks

- The additive migration adds a table and nullable case/handoff fields.
Existing rows keep null workflow metadata; no assignments are inferred.
- Adoption can wait on an intervening task-document edit. Recovery must
cancel the old intent and accept a new one after readback.
- Shared definition edits affect future adoptions. Existing case copies
keep their revisions.
- The feature remains experimental. This PR does not merge or deploy the
change.
- Live acceptance covers native Codex before the prompt extraction; this
cleanup has contract/transport verification rather than a new
live-provider campaign. The refreshed Copilot identity has static
compatibility evidence, not new live-provider qualification.

## Model Used

OpenAI Codex, configured model ID `gpt-6-astra`, xhigh reasoning. Used
terminal execution, file editing, and tool calls. The active
context-window size is not exposed.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My 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-21 15:00:12 -05:00
DottaandPaperclip 30b753f614 perf(budgets): scope accounting and deliver enforcement asynchronously (#17046)
## Thinking Path

> - Paperclip manages AI agents and their paid work.
> - Budgets must prevent new work and stop reported overruns.
> - Cost settlement also ran serial lifecycle reconciliation for every
eligible company agent.
> - That made request latency grow with unrelated idle agents and
delayed results on stop delivery.
> - This change separates atomic admission and accounting from durable
asynchronous enforcement.
> - Scoped live usage detects overruns without writing provisional
ledger charges.
> - The result is constant query scope for ordinary settlement and
recoverable stop delivery.

## Linked Issues or Issue Description

**What happened?**

Settlement and budget checks entered company-wide lifecycle
reconciliation. A company with 1,000 unrelated idle agents performed
1,001 accounting transactions for one ordinary cost evaluation. User
requests could also wait for provider termination. Running usage
checkpoints did not enforce reported monetary exposure.

**Expected behavior**

Keep the final reservation gate authoritative. Commit charges, scope
blocks, and enforcement intent before returning. Deliver stop requests
after commit. Read only applicable policies and execution scopes for
ordinary charges. Stop long-running work when supported reported or
priced usage establishes an overrun.

**Steps to reproduce**

1. Create a disposable company with one company budget and idle agents.
2. Evaluate a charge below the budget with 0, 17, and 1,000 unrelated
idle agents.
3. Compare query counts, company accounting transactions, and duration.
4. Use the controlled partial-usage and delayed-stop fixtures to check
enforcement and request responsiveness.

**Paperclip version or commit**

The measured baseline is `6c9b87d0922f1ebfc43e8b0c36889ac5ba7b9837` from
`master`.

Related public work: Refs #16976, #2006, #3539, #13763, #14296, #16853,
#13075. These cover the affected service charge, cancellation, and
accounting paths. This change removes their shared reconciliation
overhead.

## What Changed

- Batch applicable policy exposure under the existing company accounting
lock. Preserve exact fractional money and zero-reservation dispatch
fences.
- Commit a durable final budget dispatch claim before provider I/O.
Retain a separate final issue/run ownership transaction through
synchronous handoff, without holding the company accounting lock or
awaiting provider work. Preserve native recovery lease checks and
duplicate handoff fencing. Browser handoff rechecks current policy; it
reuses a consumed rate slot only for the identical policy generation.
- Separate ledger spend, live observed spend, and effective held
capacity. Use the maximum of reservation and live observation for each
unfinished operation.
- Deliver budget cancellation through the existing coordinator.
Revalidate generations and persist queued/running stop fences before
external termination. Bound stop concurrency to four.
- Apply agent holds only to the affected agent. Project budgets leave
other projects running. Project real company transitions in bounded
lifecycle batches.
- Replace periodic broad reconciliation with durable pending work,
startup repair, receipt replay, and concrete retry/window deadlines.
Retain drain and idle-safety checks.
- Enforce accepted cumulative usage checkpoints without provisional
charges. Final accounting atomically replaces live exposure and settles
reservations.
- Add operator-gated budget spans, regression coverage, map updates, and
a real-PostgreSQL comparison harness. No schema or first-party telemetry
change.

## Verification

- Full workspace `pnpm -r typecheck` passes on the final ownership fix,
rebased onto `bbcf5dfe98`. Production `pnpm build` passes on final head
`4c5f4de8b1`. Map, module-boundary, token, and Storybook catalog checks
pass.
- Focused real-PostgreSQL coverage includes the 292-case rebased
accounting/dispatch run, 63 browser cases, 52 run-control/cancellation
cases, 42 policy-generation cases, 77 lifecycle/commentary cases, and
the exact Muse confirmation regression. Native executor unit coverage
passes all 768 cases. Final ownership coverage passes: 74
adapter/use-case cases, nine public regression cases, and the additional
deleted-project race. These exercise competing ownership, budget changes
and charges between phases, zero/nonzero duplicate claims, rollback,
recovery contention, read-only capacity rechecks, and controlled HTTP
startup after commit. Another 74 pure/startup/tracing cases pass. The
complete CI matrix and both 5/5 reviews passed on `1ac9b58`; its
external security scan identified a stale-owner handoff race. The final
fix restores synchronous issue/run ownership fencing after the
accounting transaction commits. Final head `8e84f55ce8` has fresh
Greptile 5/5 with zero new comments, Paperclip review 5/5, and a passing
security scan. The complete latest-head [CI
matrix](https://github.com/paperclipai/paperclip/actions/runs/39535189808)
passes, including budget, browser, Runner, build, and canary jobs. The
unchanged Runner close fixture passed on its sole same-head job retry.
- Broad local `pnpm test:run` invocations were stopped before required
source updates (rebase and review fixes). They are not claimed as full
passes. Final full-suite coverage comes from the complete latest-head CI
matrix; local focused coverage and the incomplete broad invocations are
reported separately.
- Reproduce performance with `pnpm --filter @paperclipai/server exec tsx
../scripts/benchmark-budget-enforcement.ts
--baseline-ref=6c9b87d0922f1ebfc43e8b0c36889ac5ba7b9837`; repeat with
`--reverse`. The harness uses disposable real PostgreSQL, 20 warm
samples per variant/count, and records raw timings, SQL/lock counts,
agent reads, unchanged agent state, and query plans. Final
production-source measurement revision:
`eff713a4f72c7f4b7a4002a701cb481d4bfccd95`; the extended harness is
committed in `4c5f4de8b1`.

| Unrelated idle agents | Baseline median / p95 | New median / p95 |
Baseline SQL / locks | New SQL / locks | New agent reads |
| --- | ---: | ---: | ---: | ---: | ---: |
| 0 | 1.80 / 2.33 ms | 2.99 / 3.88 ms | 5 / 1 | 7 / 1 | 0 |
| 17 | 15.53 / 19.55 ms | 2.24 / 2.60 ms | 90 / 18 | 7 / 1 | 0 |
| 1,000 | 978.35 / 1,790.43 ms | 2.16 / 2.52 ms | 5,005 / 1,001 | 7 / 1
| 0 |

- These measurements use local PostgreSQL 18.1 and Node 26.4.0 arm64.
They isolate the cost-evaluation core and complete admission path,
without hosted-region or provider latency. Prior-revision reversed-order
controls also preserved the constant query counts; the final
measurements above use the final production source.
- Complete reserve → final ownership gate → immediate offline provider
result is measured separately, with one responsible agent and one active
operation at each unrelated-agent count. Admission p95 baseline/new: 0
agents **11.54 / 29.77 ms**; 17 agents **9.31 / 27.62 ms**; 1,000 agents
**24.51 / 74.05 ms**. Baseline admission was already scoped; the
stronger final fence adds bounded overhead. New counts stay constant at
53 Drizzle statements, three transactions, two company-accounting locks,
and five agent-reading statements bound to the responsible agent. Zero
unrelated-agent reads, exactly one provider callback per sample, and no
leftover runs or holds. All admission scenarios stay below 250 ms. No
external provider calls are included.
- The partial-usage/delayed-termination fixture passed 20/20: receipt
persistence p95 13 ms, receipt return to observed durable Stop fence p95
28 ms, complete receipt-start-to-fence p95 50 ms, unrelated database
request p95 1 ms while termination was blocked. After releasing the
controlled termination fixture, acknowledgement p95 was 14 ms. These are
separately measured phases; fixture acknowledgement is not live-provider
termination latency.
- Models and provider deadlines are unchanged. No deployment, live
inference, or staging acceptance is claimed. A quiet 30-minute follow-up
waits for the merged revision on staging, then repeats classifier and
controlled budget-stop acceptance in staging, recording hosted
bookkeeping, queue delay, and actual provider acknowledgement
separately.
- Development failures retained: finalizer notification regressions
(fixed; 27/27 affected cases passed), invalid browser admission fixture
assumptions (fixed; browser coverage now passes 63/63), and first-head
lifecycle/dispatch CI regressions (reproduced and repaired). A
prior-head Cases E2E test hit its unchanged announcement-dismiss handler
race while opening a filter; the same journey passed on `1ac9b58`. The
external security review then found a stale-owner race between
accounting commit and provider entry; final verification covers a
competing run in that gap while retaining provider I/O outside the
accounting lock. Early PostgreSQL startup attempts hit local semaphore
pressure; serial reruns succeeded. The final-head Runner lane had one
failure among 1,823 tests: the unchanged `timeout-attachment` fixture
failed at its first process close after 6.28 seconds. The sole same-head
job retry passed all 1,819 active tests (four skipped), including that
fixture in 1.85 seconds. Three isolated local probes could not run
correctly because the Rust fake-provider fixture binary was absent;
cleanup masked the original startup failure. CI builds that fixture
through its normal lane. These probes are inconclusive and are not
counted as passes.

## Risks

- This changes accounting, lifecycle, and cancellation ordering. Durable
generations, source/sequence checks, ownership leases, and company
locking remain required for correctness.
- Provider stop acknowledgement can be slow or fail. Stop intent remains
pending until existing termination proof succeeds; cancelled row status
alone does not acknowledge delivery.
- Mid-run limits depend on provider usage reports or supported price
calculations. Providers that report only at completion cannot provide
exact mid-call detection.
- Signals are process-local wake hints for the supported
single-active-writer model. Durable state and startup recovery remain
authoritative.
- There are no migrations, new queue tables, or cached balances. Repeat
the classifier and controlled budget-stop acceptance after normal
rollout.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, tool use, code execution,
and parallel coding agents. The host does not expose the exact backend
model revision or context-window size, so those values are not asserted.

## 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-21 07:23:00 -05:00
Nicky LeachandPaperclip 79b2bf78dd Create agent records when onboarding names are submitted (#17005)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Core onboarding selects an agent and connects its provider account.
> - The current flow creates the agent record after authentication.
> - Setup needs a stable agent identity as soon as the user submits its
name.
> - This PR saves a paused setup record on name submission and finishes
the hire on that same record.
> - The existing sandbox authentication and approval paths continue to
apply.

## Linked Issues or Issue Description

**Subsystem affected**

Core agent lifecycle, shared validators, and onboarding UI.

**Current behavior**

Onboarding creates the database record at the final hire step. Earlier
authentication and saved setup have no agent record.

**Proposed behavior**

Create a paused agent with a setup hold when the user submits its name.
Do this before adapter selection or authentication. Update that same
record after adapter selection. Reuse its ID on retries and saved setup.
Finish that record through the existing hire path.

**Reason and benefit**

Give setup a stable identity without coupling this refactor to computer
provisioning or a new execution backend.

**Breaking changes**

Incomplete setup now leaves an inactive agent record. Existing clients
can still create and hire agents without the new optional fields. The
sandbox authentication flow and API key support remain in place.

**Additional context**

Requested Core-only refactor. Related work: #15422 changes runner
defaults. This PR preserves those choices. No duplicate early-record
refactor was found in the issue and PR search.

## What Changed

- Save the agent when the user submits its name in both onboarding entry
points. Use a provisional adapter until the user chooses one. Reopen
name-only drafts at adapter selection.
- Add retry-safe setup creation and same-record hire completion. Keep
approval checks at final hire.
- Save and restore setup configuration in both onboarding entry points.
Show Finish setup for paused setup agents.
- Restrict setup changes to authorized board users. Block generic resume
until setup finishes.
- Add lifecycle, authorization, connection, and UI coverage. Update the
specification and feature maps.

## Verification

- Latest focused server run: 126 lifecycle and AI-connection tests
passed after the Apex fixes. An earlier broader run passed 301
lifecycle, instruction, adapter-validation, and AI-connection tests.
Earlier authentication, retry, cross-company, and direct-create
regressions also passed.
- Name-save verification: 336 tests across the wizard, naming dialog,
New agent, action-button, and wizard-step suites passed. Coverage
includes retry identity, repeated submission, closing during a save,
saved-model restoration, and a disabled process adapter.
- Shared, server, and UI TypeScript checks passed. The latest UI package
check and direct server TypeScript check passed. The server package
preparation command could not finish locally because Cargo is
unavailable; full build preparation runs in CI. Map checks, token gates,
and `git diff --check` passed; each pushed diff was scanned for
credentials and PII.
- All six onboarding browser tests passed together with installed Chrome
against a fresh throwaway instance after the Apex fixes. They include
numbered duplicate names, first-time Copilot without a connected
account, and Grok’s saved model. They verify early persistence in both
entry points, closing and reopening a name-only draft, same-record
adapter selection, sandbox sign-in, login reload, and failed-connection
gating. Provider responses are simulated; Core persistence is real.
- Regression coverage includes incomplete Copilot creation versus final
validation, Kimi settings through redacted responses, stale local
drafts, company switches during creation, saved environments, and
provider changes with personal/shared old bindings.
- Apex found five name-only setup gaps: numbered names, early Copilot
account validation, the Grok model default, same-name draft ownership,
and provisional runner restoration. The fixes preserve server names,
defer implicit account binding until hire, set Grok’s model, avoid
name-based reuse of unfinished records, and restore Auto for pending
adapter choices. UI, database, and browser regressions cover these
cases.
- Standard Greptile found a Grok provider mismatch in the new adapter
save. The save now uses ACPX with the Grok profile. Both the 129-test
dialog/setup run and a real-API browser regression passed after the fix.
The first browser attempt stopped on an ambiguous empty-roster button
selector; it now scopes the click to the toolbar.
- Moving the save point exposed a saved-model reset and timing
assumptions in the same-name and portal fixtures. The source choice now
preserves the restored model, and tests cover same-name recovery without
a second hire.
- Initial CI exposed direct-create compatibility, concurrent setup
effects, fixture assumptions, and a missing-fields assumption in the
provider-validation guard. These were fixed and verified locally. Review
findings were addressed with authorization, recovery,
credential-persistence, and restored-configuration regressions.
- The final desktop capture passed after host resource cleanup. A repeat
first failed before Core started because macOS had exhausted
shared-memory IDs. Standalone PostgreSQL initialization reproduced the
same error. Releasing only unattached control segments from this task’s
stopped test databases allowed the unchanged revision to pass. No Core
or system setting changed.
- Local database tests required port access outside the sandbox. Missing
declared development dependencies were supplied outside the branch. No
live provider sign-in was tested locally.
- [Full monorepo
CI](https://github.com/paperclipai/paperclip/actions/runs/39522434236)
is green on `82b82fec189a172a885d4dd565ae2f4a18c73efc`. Standard
Greptile scored 5/5 with zero new comments (check `118969424903`). The
subsequent Apex review also scored 5/5 with zero new comments (check
`118972866331`) on that same commit. All review threads are resolved.
- The separate Superagent Security scan returned neutral/inconclusive
because its pinned merge-base checkout failed or timed out. GitHub
returned 404 for check and suite rerun requests. This is not a
successful security scan; the CI workflow and other security checks
passed.

## Risks

- Users can leave inactive setup records behind, including after name
submission alone. These records cannot run until hire completes.
- Setup completion touches hiring and approval boundaries. Tests cover
retries, company isolation, creator permissions, and approval snapshots.
- An uncertain credential-save result retains its new secret reference
for retry. A confirmed client rejection removes only credentials staged
by that attempt.
- No schema migration or VM provisioning change is required.
Agent-computer integration is out of scope.

## Model Used

OpenAI Codex, based on GPT-6, with repository search, code editing, and
tool execution. The exact deployment 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] Apex Greptile is also 5/5 on the same commit as standard review
and green CI
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-20 18:08:57 -07:00
Devin FoleyandPaperclip a2d26a83fe fix(inbox): keep automatic work out of Mine by default
Keep channel and routine attribution out of Mine unless the person participates directly, is assigned the task, or receives a current addressed request. Apply the same source rules to unread state, archives, and task notifications. Preserve direct comments and current human action requests.

Restore the two expressions damaged by redaction during the earlier master merge.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-20 13:46:10 -05:00
DottaandPaperclip 505e1a5582 feat(cases): add persistent workflows with same-task agent handoffs (#16959)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - An agent workflow needs persistent facts and a safe way to transfer
work.
> - Creating a task for each phase splits the objective, discussion,
workspace, and review policy.
> - A case can retain the facts while one primary task moves between
agents.
> - Transfers must survive process failure and preserve private access,
budgets, and completion gates.
> - This pull request adds durable case handoffs, native case tools, and
read-only case pages.
> - Prompts describe the workflow. Existing task controls decide when
work can run and finish.

## Linked Issues or Issue Description

**Problem or motivation**

Prompt-driven agent teams need a persistent record that can move through
triage, implementation, verification, and correction. Ordinary
reassignment does not provide a durable instruction, safe release
barrier, or recoverable delivery receipt for an agent handing off its
own running task.

**Proposed solution**

Extend standalone cases with one primary task, a descriptive phase,
retained access sources, and a handoff ledger. Apply assignments after
source execution and workspace settlement. Deliver each transfer through
the existing durable wake queue. Provide `create_case`, `read_case`,
`update_case`, and `handoff_case` in the native runner. Creation
requires kickoff and explicit workflow text. An explicit handoff to
`done` closes the case when normal task completion is accepted.

**Alternatives considered**

Do not add a workflow engine, filesystem queue, configured state graph,
or one task per phase. The workflow document combines transition prose
with an optional Mermaid `stateDiagram-v2` map. The server does not
execute the diagram. The Pipelines experiment removed on master stays
removed.

**Roadmap alignment**

This extends Agent Reviews and Approvals, Enforced Outcomes, Bounded Run
Recovery, and Activity Log attribution. Existing approval, review,
budget, privacy, workspace, and responsible-user rules remain
authoritative.

Related work: [ordinary handoff wake
recovery](https://github.com/paperclipai/paperclip/pull/15019). This
feature adds a separate persisted case-handoff receipt and release
barrier.

## What Changed

- Add case routing fields, retained access sources, durable handoff
history, delivery leases, and replay-safe migrations.
- Keep the same primary task across agent phases. Preserve each
returning agent's own session and the task's workspace.
- Fence outgoing mutations, wait for provider and workspace release, and
recover delivery without duplicate task comments or runs. Recheck
current assignment permissions as the original caller before applying a
delayed transfer. Scope a run Stop to that run’s own handoff intents, so
repeated old Stop requests preserve newer work. Cancelling terminal
intent without a source run also requires fenced current task ownership,
including native retries and preparation with an old checkout. For Cloud
callers, revalidate current stack membership with an uncached Cloud RPC
and derive owner elevation from the current managed setting.
- Keep case reads, documents, assets, Audit, and live events inside
retained task/project permissions.
- Add native case creation/read/update/handoff tools. Store required
workflow text and initial documents on the first task. Page oversized
case facts and referenced document bodies through the dedicated tool
with bounded UTF-8 JSON, current routing versions, snapshot conflicts,
and current source authorization on every page.
- Add read-only case lists and detail pages, task-style list controls,
compact dotted field tables, linked handoff tasks, and case filters in
Audit.
- Add native/legacy integration tests, migration/restart tests, browser
coverage, and bounded live receipt fixtures. Extend the trusted sandbox
condition to cover the new subscription fixture profile.
- Hide obsolete paused-agent warnings on completed or cancelled task
threads.
- Synchronize the company-switch settings test with React effects after
a CI failure. Preserve its security assertions and production remount
behavior.

## Verification

The branch directly includes master `9ef434fe79`. The required `ci /
verify` and `ci / e2e` gates pass on head `765fccd67c`. [Current-head
CI](https://github.com/paperclipai/paperclip/actions/runs/39464348614)
passes typecheck, build, tests, and all eight browser shards. Security
checks pass. [Greptile gives this exact head
5/5](https://github.com/paperclipai/paperclip/pull/16959#issuecomment-6291156549),
with no unresolved review threads. The optional Paperclip Review check
remains queued because its assigned agent is paused. It is not a
required branch check. No check result was overridden.

Local workspace typecheck and build pass after the master merge, along
with database migration checks, token gates, map checks, Storybook
catalog checks, and the Copilot profile identity check. Standard builds
refresh Runner vendor output. Focused checks pass 2,008
API/paging/context tests and 7 strict case protocol tests. The final
commit changes one test fixture only; its ten tests, UI typecheck, and
token gates pass. No production source changed in that commit.

On current head `765fccd67c`, all **194 critical workflow tests**
executed and passed with no skipped tests in those files:

- 38 Stop/ownership tests, including board completion intent, native
retries, stale Stop, and preparation with an old checkout.
- 2 actual legacy process/HTTP handoff tests, including scratch failure,
a closed-stdio child that continues writing, and recovery through a
fresh worker after the process group stops.
- 5 migration tests, including SQL column metadata, preserved null
authority context, and all six prior-numbering receipts.
- 3 process-settlement and 5 scratch tests.
- 88 handoff-service, 18 heartbeat handoff, and 21 native case-tool
integration tests.
- 7 bounded case/document-read projection tests and 7 strict
protocol-contract tests.

The current CI checkout was `fed65d49`, merging `765fccd67c` into master
`9ef434fe79`. Its new document regressions reconstruct exact
Unicode/escaped bodies and revisions through real native authority and
authenticated HTTP with generic API tools disabled. They cover
case-owned, primary-task, and linked-task documents; routing on every
page; stale document snapshots; access loss and unlinking;
unrelated/foreign/private sources; system documents; and quarantined
content. Active-task document tools retain their existing behavior.
These are current-head test results from the first CI attempt; the
browser-only retry did not rerun these suites.

The full `64fdd3403f` CI failed one separate settings test: after a
company switch, it observed an unsettled API-key draft. The production
component and test were unchanged from prior green source. Production
switches remount both keyed settings layers; the test directly reused an
unkeyed view and used a timer tick instead of waiting for React effects.
The final commit replaces that fixture synchronization with React `act`.
The exact secret-clearing assertions and all timeouts remain unchanged.
The original assertion failure remains recorded; no unchanged retry was
used. The narrow unchanged baseline and fixed fixture each pass 10
tests.

The upstream result-paging merge preserves case capture namespaces and
current asset privacy. Its API integration suite executed 39 of 41 tests
successfully, with two skipped; the optional assigned-result PRP
integration test was skipped. Neither skipped suite is counted in the
194 critical tests or as live provider proof.

All 361 upstream migration entries and SQL bodies remain unchanged. Six
case migrations follow master as 0363–0368 with identical SQL hashes.
Official Drizzle generators produced the combined metadata and five
retained snapshots. Generation reports no schema changes, and the
snapshot drift test passes. The earlier `ce361ae5d0` CI passed on
attempt 1, including its then-current 179 critical tests. Fresh review
later identified unusable document references with generic API tools
disabled; the bounded document reads and ten additional authenticated
HTTP tests address that finding.

The full local `pnpm test:run` attempt was cancelled after this Mac
exhausted PostgreSQL semaphore capacity; it is **not** counted as a
pass. Later database attempts also stopped before assertions or skipped,
including one sandbox socket denial. Two original stale-Stop regressions
did reproduce the bug against the old source. A REST serialization
assertion passed after two preserved database-startup failures. No test
timeout was increased. All 194 assertions listed above executed and
passed in current-head CI. The complete 385-file, 3,963-test UI shard
also passed after the fixture repair.

A configured-provider receipt workflow passed 13 backend checks across
triage → implementation → verification → correction → done, using one
task and four work runs. The saved receipt is revision 2 with total 6
USD; case and task both closed. The original canonical attempt remains
failed because its browser assertion confused the terminal destination
with completed-task tooltips. The corrected full browser verifier passed
on the same retained database and original runs, with no additional
provider calls. The last clean-build browser readback is on
`6a86c54a53`; later changes affect recovery, authorization, bounded
reads, and settlement. Accounted work cost is a $1.010574 rate-card
estimate; provider billing and setup-probe usage are unavailable.

Copilot profile 49 passed the unchanged seven-fixture private protocol
pack (46/46 checks, no retries) and the product file-edit canary after
master's completion-replay change. All 60 bound implementation hashes
remain unchanged on the current source. Historical profile-47/48
identities and results remain intact. See the [profile-49 compatibility
record](https://github.com/paperclipai/paperclip/blob/codex/persistent-case-handoffs/doc/plans/2026-10-20-copilot-completion-recovery-compatibility-v49.json).
This is bounded compatibility evidence, not a fresh full matrix,
installed-package product test, or Daytona rollout.

Preserved CI failures and retries:

- On `20662930ac`, Slack managed setup failed a five-second success
assertion after reload. Its test/application path was unchanged from a
prior green head. One unchanged-source retry passed all 25 tests in that
shard; no source or timeout changed.
- On `9402b4f17a`, two CI workers received shutdown signals at 15:24:19
UTC. Neither log had an assertion failure before interruption. One
unchanged-source retry of each passed all Runner static checks and all
32 tests in browser shard 6; both aggregates passed. The next head,
`7b4374edaf`, passed all CI without retries.
- On `295f289b5a`, serialized shard 9 timed out during its first
device-login test, then the next test found an active login lease.
Direct login/test paths were unchanged from a prior green head. Cold
import plus a timed-out async body using the next test's mutable
actor/store is the supported fixture-race explanation; no request trace
proves that sequence. The original failure remains recorded. One
unchanged-source retry passed all 294 tests in 19 files, including all
41 device-login tests. No login source or timeout changed. The
subsequent `ce361ae5d0` CI passed without retries.
- On `64fdd3403f`, one company-switch settings assertion observed an
unsettled draft. The final test-only commit uses React `act` without
changing assertions, timeouts, or production code. On `765fccd67c`, all
ten settings tests and the complete 385-file, 3,963-test UI shard
passed.
- On `765fccd67c`, browser shard 3 completed the split-handoff
assertions, then cleanup received HTTP 500 from run cancellation after a
one-second PostgreSQL row-lock timeout. The extra chat run was reporting
completed work while teardown began. Cleanup stopped before restoring a
global experiment flag, causing a later assertion to fail. Relevant
production and test paths are unchanged from an earlier green commit.
Stop's lock order is consistent, and no nested self-lock was found; the
exact PostgreSQL blocker was not recorded. One unchanged-shard retry
passed. The original failure, trace, and downstream flag failure remain
recorded. No Stop implementation, cleanup assertion, or timeout changed.
The retry supports intermittent cleanup contention; it does not identify
the original blocking transaction.


## Risks

- Local process transfers require host-owned PID/group absence. Missing
or uncertain termination evidence keeps delivery pending, independently
of scratch setup.
- Handoff admission and task cancellation share execution ownership. New
regression tests cover temporary holds, late source writes, and
uncertain provider termination.
- Retained private sources use an intersection of existing permissions.
This intentionally fails closed when a source is missing or an existing
task cannot preserve that boundary.
- Migrations add tables and indexes. They preserve master history and
can replay over prior feature installs. Migration 0368 adds nullable
internal authorization provenance with no default or authority backfill.
Historical transfers still awaiting release without this context fail
closed; an operator must cancel them and request a new handoff.
- Delayed Cloud handoffs depend on the current Cloud membership RPC. An
unavailable, ambiguous, expired, or mismatched response holds the
handoff for retry; it does not reuse cached authority or grant access.
- Bounded reads reload and reauthorize the selected projection per page.
Underlying work grows with the data size and number of pages. Changed
data or routing requires restarting from offset zero without the old
snapshot.
- Phase names and workflow diagrams remain advisory. They do not satisfy
review or approval gates.
- This is a large, cross-cutting PR. The maintainer requested one PR for
the whole feature; the commits separate data, runtime, UI, and
qualification work.

## Model Used

OpenAI Codex, GPT-6 family, with tool use, code execution, and delegated
code review. The exact deployment model ID and context-window size were
not exposed in the session. Live fixture agents used the explicitly
configured provider model recorded in their test evidence.

## 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-20 12:46:14 -05:00
DottaandPaperclip 2c96f76780 feat(connections): add model-backed prompt injection prevention
Add opt-in OpenRouter checks at existing tool-result boundaries with regex fallback, service accounting, and settings on Connections. Make migration 0362 safe to replay over existing or partially applied schema state.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-20 11:32:25 -05:00
DottaandPaperclip 813e808af4 Remove filesystem history authorization from workspace preparation (#16963)
Remove physical-root source/reader authorization and sticky directory classifications from workspace preparation. Preserve current task/run authority, app-record privacy, credential authorization, containment, and lifecycle/publication integrity.

Validate replacement selections against persisted new inputs and refresh verified checkout ownership so bounded reuse survives earlier workspace relocation. Add real PostgreSQL/Git regressions, a reproducible history-scaling benchmark, and documentation.

Full CI passed all 48 jobs and Greptile scored 5/5 at 3d5da6c259. Five preparation-guard medians improved from 20,512.99 ms to 52.22 ms on the 8,500-workspace fixture; these are not end-to-end startup timings.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-20 09:19:59 -05:00
DottaandPaperclip e5927e1db9 fix: give commentary its own default read permission (#16903)
## Thinking Path

> - Paperclip lets people manage AI agents and inspect their work.
> - Commentary collects agent suggestions and complaints for company
members.
> - Commentary used the permission for detailed agent-action audits.
> - Owners, admins and viewers could therefore receive a permission
error when they opened Commentary.
> - This pull request gives commentary its own permission and enables it
for all human company roles.
> - Members can read feedback while task privacy and detailed audit
access keep their own checks.

## Linked Issues or Issue Description

Refs #16884, which added the Commentary browser. A search found no open
PR for this permission fix.

**What happened?**

Commentary returned `Missing permission: audit:view_agent_actions` for
company members without the detailed audit grant. Default owners, admins
and viewers did not receive that grant.

**Expected behavior**

All human company roles can read commentary by default. A separate
`commentary:view` permission controls this access. Private source tasks
remain private. Commentary access does not grant detailed agent-action
audits or CSV exports.

**Steps to reproduce**

1. Sign in as an active company owner, admin or viewer without
`audit:view_agent_actions`.
2. Open Audit, then Commentary.
3. Observe the permission error before this change.

**Paperclip version or commit**

Base commit: `7c58ea07b2`.

**Deployment mode**

Authenticated server or Cloud tenant.

## What Changed

- Add `commentary:view` to the shared permission contract and all human
role defaults.
- Require that permission for commentary list and detail reads.
- Add an idempotent upgrade migration for existing active human members.
Preserve existing grants and scopes.
- Add the commentary default when approving saved human invitation
grants that omit it, including pre-upgrade invitations. Preserve
explicit commentary scopes.
- Add regression coverage for role defaults, permission removal, audit
separation, private tasks and migration replay.
- Update the API description, specifications, database notes and access
maps.

## Verification

- Passed 68 tests across commentary reads, role grants, old-invitation
HTTP acceptance, migration replay, agent audit routes, access services
and migration snapshot drift under the repository's locked dependencies.
- Confirmed the new role and read tests failed before the
implementation.
- `node scripts/check-maps.mjs` passed.
- Migration numbering and safety checks passed during the build.
- Full `pnpm -r typecheck` and `pnpm build` passed locally after the
invitation fix.
- The final-commit CI matrix passed, including all test shards,
typecheck, build, public-install checks and canary smoke. The redundant
local `pnpm test:run` was stopped after the full CI matrix completed;
the 68 focused local regressions passed separately.
- The first install bypassed the stale lockfile and selected a newer
diff-viewer API. The initial typecheck and build failed in that
unrelated plugin. Installing the locked versions cleared both failures;
the tracked lockfile is unchanged.
- The first locked-dependency regression run hit the 15-second limit
while importing the audit route graph in its first test. Moving that
import into suite setup fixed the timeout; all 58 regressions then
passed.
- Greptile found that pre-upgrade invitations retain old grant lists.
New helper and HTTP regressions reproduced this gap before the fix, then
passed after approval added the missing commentary default.
- Greptile reviewed the final commit at 5/5 with no remaining actionable
findings. Its earlier thread is resolved.
- No UI code changed. The permission tests use real disposable
PostgreSQL databases and HTTP routes.

## Risks

- The upgrade deliberately enables commentary for every existing active
human company member, including viewers. Existing commentary grants
retain their saved scopes.
- Source-task privacy still filters previews, counts, searches and full
messages. Agent-authenticated browsing remains denied.
- Agent-action audit grants, detailed filters and CSV export permissions
keep their current behavior.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, repository editing and
command execution. The exact runtime model ID and context window are not
exposed to 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-19 16:58:17 -05:00
DottaandPaperclip ac9459bae3 feat: configure company agent observability (#16874)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Companies use several agent harnesses and execution environments.
> - Operators need one place to select where native agent logs and
traces go.
> - An inference proxy would add a dependency to the agent request path.
> - This pull request supplies native OpenTelemetry settings to managed
Codex and Claude Code processes.
> - Company secrets protect destination credentials. Export failure does
not change the task result.

## Linked Issues or Issue Description

**Subsystem affected**

Company settings, shared contracts, database, server, adapters, and
runner.

**Problem or motivation**

An operator cannot configure a company destination for native agent logs
and traces. Manual harness configuration is hard to apply across local
and remote execution.

**Proposed solution**

Add one company destination: Braintrust or a custom OTLP HTTP/protobuf
endpoint. Apply a transient snapshot when execution preparation starts.
Keep credentials out of API reads, task environment manifests, recovery
files, and command arguments. Replace a warm process when its export
settings change and preserve its conversation.

**Alternatives considered**

Multiple destinations can use a user-operated collector for fan-out.
This change does not add a collector, an inference proxy, or transcript
scraping.

**Roadmap alignment**

This extends company settings, secret management, and support for
multiple harnesses. The maintainer requested this implementation.
Searches for observability and Braintrust found no duplicate company
destination feature. Related infrastructure tracing work in #16236 has a
separate content-free contract.

## What Changed

- Add strict schemas, revision checks, encrypted secret storage,
activity records, and board-only settings routes.
- Add explicit synthetic logs and traces tests with a bounded HTTP
request and sanitized results.
- Supply native Codex configuration and Claude Code environment values
through local and remote launch paths.
- Preserve Codex login refresh through the existing managed credential
link. Retain unsaved drafts across background reads. Require complete
custom header re-entry when the endpoint origin changes.
- Separate process export compatibility from conversation identity.
Isolate generated Codex configuration and preserve resumable sessions,
including remote home refresh after export changes.
- Advance the immutable Pi/Copilot source attestations for shared
environment and sidecar code changes. Keep their provider payloads
unchanged and retain prior identities for decoding.
- Redact destination credentials throughout launch diagnostics and HTTP
logs.
- Add the production settings form, Storybook states and journey,
documentation, and feature/access map entries.

## Verification

- Real managed local Codex 0.160.0 and Claude Code 2.1.286 tasks
exported to Braintrust. API readback and the Braintrust UI showed the
test records. A real remote Daytona Codex task exported through the
legacy `exec` path.
- Live tests exercised content capture off, export disabled, warm
conversation reuse, and a destination that accepted connections but
never replied. Agent work succeeded and export requests stopped at the
configured three-second timeout. The UI connection test returned “Test
payload accepted”; the saved API key stayed masked after reload.
- All current-head CI test lanes, typechecks, packaging/build checks,
and required aggregates passed on
`71e994b2be9c8fb6d6e938a4ad7cf4c95fdafe31` ([CI
run](https://github.com/paperclipai/paperclip/actions/runs/39319194318)).
Greptile completed on that exact commit at 5/5, with zero unresolved
review threads. The additional optional Paperclip Review check remains
queued waiting for its assigned agent.
- Local workspace typecheck and build passed. Focused verification
included 239 combined runner tests, 789 API/native-session tests, 107
Codex home/ACP/sandbox-site tests, 204 feature/privacy tests, and the
affected Rust suites. Migration, token, map, Storybook catalog, and
Storybook build checks passed during acceptance. These checks ran at the
relevant implementation or merge boundary; the current-head CI is the
complete final gate.
- Managed AI credential projections now receive enabled and disabled
company export settings; genuine caller-owned Codex homes remain
untouched. Two regressions reproduced the skip before the repair. All
276 engine/lifecycle tests and adapter-utils typecheck pass afterward.
The launched TOML retains provider/MCP settings, credential continuity,
and redaction.
- Settings saves, removal, and the real company-deletion owner acquire
secret mutation ownership before database locks. PostgreSQL NOWAIT
probes cover all three paths; concurrent save/rotation/removal/deletion
requests settle correctly. The affected suites passed 137 tests,
followed by all 32 service/connection cases after expanded deletion
coverage. Server and Codex adapter typechecks pass.
- Codex source profiles use the effective CLI argument list. A spawned
fixture CLI reproduced both ignored-argument failures; all three
precedence/fallback cases now pass.
- Real tar staging reproduced remote conversation loss in both API-key
and subscription modes before the repair. Both now pass: changing
managed settings preserves sessions, archives, native indexes, and
refreshed subscription credentials. A corrupt upload preserves the prior
config and conversation.
- Preserved failure evidence: initial CI caught stale Pi/Copilot source
attestations, a missing test-harness helper, and packaging fixture/probe
mismatches; those were corrected and covered by focused checks.
Superseded heads had intermittent attachment-composer timeouts despite
successful uploads; [the original trace and screenshot remain
available](https://github.com/paperclipai/paperclip/actions/runs/39309701089/artifacts/12215109203).
The same attachment case passed on the final head: [25/25 tests in shard
3](https://github.com/paperclipai/paperclip/actions/runs/39319194318/job/118288637051).
- A connection-fault fixture also exposed a stale pooled socket after
its hang case; closing fixture responses isolated scenarios and the full
affected suite passed.
- The broad local test run was not clean: database resource failures,
timeouts, an older cached module graph, and a stale optional-resource
manifest assumption were recorded. Focused checks passed after the
documented fixes. This does not establish a clean full local pass.
- Native remote Codex, remote Claude, and the full ACPX Codex bridge
remain unqualified. The direct Codex resume test does not establish full
bridge acceptance.

## Risks

- Native exporters perform network requests from each execution
environment. A server connection test does not prove remote
reachability.
- Prompts, assistant responses, and tool content are enabled by default
when supported. Native caps and harness-specific controls still apply.
- Caller-owned Codex homes are unsupported for automatic configuration
and remain untouched.
- Native harnesses and their tool processes can inspect export
credentials. The settings form and documentation advise using
ingestion-scoped credentials. Retained headers remain bound to their
saved scheme, host, and port; changing origin requires fresh values or
removal.
- Migration 0357 adds a company-scoped row and secret reference. It is
safe to reapply. Secret removal and company deletion use the existing
secret lifecycle.
- Slow or unavailable destinations must not block task settlement.
Export settings take effect at the next execution preparation boundary.

## Model Used

OpenAI Codex, GPT-6, with reasoning, tool use, code execution, and
browser verification. The exact serving model ID and context window size
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-19 15:36:04 -05:00
DottaandPaperclip e6dcd1e8e9 feat: add Commentary to Audit with filters and shareable messages (#16884)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents can submit suggestions and complaints while they work.
> - Operators currently need database access to read those messages.
> - That makes it hard to find feedback from one agent or share a
specific message.
> - This pull request adds a standard Commentary tab in Audit.
> - Operators can filter messages, browse 50 at a time, and share links
to full message dialogs.

## Linked Issues or Issue Description

Refs #15367, which added feedback storage and agent submission. The
duplicate search found no open PR for a commentary reader.

**Subsystem affected**

Server, shared API contracts, and the board UI.

**Problem or motivation**

Agent suggestions and complaints are stored but have no board reader.
Operators must query the database to inspect feedback.

**Proposed solution**

Add Commentary to Audit without an experimental toggle. Show previews,
agent and message-type filters, text search, and 50-message pages.
Opening a row updates the URL. A copied URL opens the full message with
its agent, task, and run context.

**Alternatives considered**

Direct database queries remain useful for operators, but do not provide
a normal product workflow. An experimental setting would add setup to a
read-only audit page.

**Roadmap alignment**

This completes the operator view for the existing feedback feature. It
supports human oversight and does not change agent execution or task
ownership.

## What Changed

- Add company-scoped, board-only list and detail endpoints with audit
permission and source-task privacy checks.
- Return bounded previews and counts. Fetch full bodies only when a
message opens.
- Add the Commentary tab, search, filters, 50-row pagination, and
URL-based selection. Audit tab destinations work in both layouts, with a
classic sidebar entry for Commentary.
- Add production Storybook examples for populated, filtered, linked,
long, paginated, empty, loading, failed, denied, mobile, and light
states.
- Update API documentation and the feature and agent access maps.

## Verification

- Final head `abc4a251c14cfbfec007542214beec528f2b18bf`: 55 checks pass;
two conditional Storybook checks are skipped. The PR workflow is
successful. Greptile is 5/5 with all findings resolved.
- Focused database, HTTP, submission, OpenAPI, and UI regression tests
cover company isolation, task privacy, filter bounds, 50-row pagination,
and copied message links.
- Browser Storybook journeys cover row opening, direct links, combined
filters, search, and pagination. Storybook uses synthetic API fixtures;
database authorization is tested separately.
- Token gates, feature maps, and Storybook catalog validation pass.
- `pnpm -r typecheck`, `pnpm build`, and `pnpm build-storybook` pass on
the rebased branch. All 80 focused tests and all 37 Audit tests pass,
including the real App route table in both layouts, task
grant/revocation through HTTP, deleted-task privacy, and URL UI
regressions. The full suite passes in the parallel PR CI matrix. The
local serial full-suite run was stopped before completion after checking
the recorded 94-minute serial duration. Local focused tests, workspace
typecheck, production build, and final server/UI checks pass.
- The linked-message Storybook test initially asserted against the
loading dialog. It now waits for the message body; both direct-link and
row-open journeys pass.
- Native and legacy deleted-task privacy regressions failed before the
fix and pass afterward. The reader checks the run task binding after the
task foreign key clears.
- A rapid search-then-agent-filter browser regression reproduced the
search overwriting the selected agent. The pending search now restarts
when URL filters change. The same browser test passes with both filters
applied.
- CI found two existing AuditHub assertions that still expected five
tabs. They now assert the six-tab model and selected-company Commentary
rendering. All 37 Audit tests pass. All other test and build jobs passed
before this test-only correction.

- The [agent-chat attachment browser
test](https://github.com/paperclipai/paperclip/actions/runs/39307881171/job/118250189664)
timed out waiting for an attachment preview. The [same shard passed on
the prior
head](https://github.com/paperclipai/paperclip/actions/runs/39306658703/job/118245498343)
with identical application code; the intervening change only updates
AuditHub unit tests. The single retry passed on the same head. The
precise cause of the earlier failure remains unconfirmed.

## Risks

- Commentary may contain sensitive task context. The reader requires
board access and audit permission, and filters source-task visibility
before returning previews, counts, or full bodies.
- Text search scans stored message bodies. Pages are bounded and full
bodies are fetched on demand.
- Offset pagination can shift if new messages arrive while paging.
Ordering uses timestamp and ID for stable ties.
- No database migration or agent submission behavior changes are
required.

## Model Used

- OpenAI Codex, GPT-6 family, with reasoning, tool use, browser
interaction, and code execution. The exact backend model ID and
context-window size 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-19 14:21:13 -05:00
DottaandPaperclip 3e5a9f5afe perf(ui): load recent tasks with bounded summaries (#16851)
Replace passive recent-task detail reads with bounded, authorized summaries. Keep account isolation, stored history, task actions, and live recovery behavior.

Overlap access checks with shell settings and avoid duplicate session and health reads on the first healthy socket opening. Retain domain reconciliation.

Add focused coverage and local performance evidence. Isolate the existing cache capacity test from entry expiry on slow CI runners.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-19 12:13:28 -05:00
DottaandPaperclip 9966f31bee fix(chat): keep permission failures scoped to the rejected operation (#16847)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - External channels deliver agent replies through a durable
publication queue.
> - A provider can reject one operation while other operations remain
allowed.
> - The shared error classifier treated generic 403 and permission
errors as failures of the whole connection.
> - Failure handlers then changed the user's enabled setting and removed
all assigned channel tools.
> - This pull request limits permission failures to the rejected
operation and preserves connection intent during authentication
failures.
> - Unrelated work can continue, while confirmed authentication failures
still stop endpoint traffic.

## Linked Issues or Issue Description

Refs #16137. Follows #16138, which distinguishes local authorization
errors from provider errors. This change also narrows provider
permission failures. Related #16806 handles a separate task-continuation
tool-binding defect.

A provider 403 or missing-scope response currently disables a connection
that may still support other operations. The expected behavior is a
visible operation failure with unrelated work preserved. Confirmed
authentication failures must stop sends without changing the user's
enabled setting.

## What Changed

- Classify generic 403, adapter permission errors, and Slack
missing-scope/no-permission responses as failed operations.
- Preserve rate-limit retries, known destination quarantine, and
confirmed authentication failures.
- Preserve connection status and enabled intent when publication,
provider-reply, or form-open authentication fails. The endpoint still
enters attention and its runtime stops.
- Add GitHub regressions for retained discovery and successful later
publication after 403, and no further sends after 401.
- Mark authentication health failed and fence persistent receiver
startup, background reconciliation, and receiver callbacks. Keep signed
GitHub lifecycle events available during an authentication stop. Verify
Discord reconciliation and Photon restart preserve the stop, while
transient Discord disconnects still recover.
- Update provider, publication, and modal regression expectations and
the execution contract and verification maps.

## Verification

- Red: five new classifier cases returned endpoint attention before the
repair. The signed-installation-removal regression also reproduced a
blocked lifecycle event after a 401 before narrowing the receiver guard.
- Green: all 35 classifier tests pass.
- Green: 19 PostgreSQL-backed cases pass through the production channel
services, including GitHub discovery/publication, Slack provider replies
and question modals, Telegram credential/destination failures, rate
limiting, and Discord/Photon authentication-stop persistence.
- Map structural checks and `git diff --check` pass.
- `pnpm -r typecheck` and `pnpm build` pass. All CI gates are green on
`7e379bcd98aa8363e42efe7f8a4b2589b7111ae6`; Greptile is 5/5 on that
exact commit with no unresolved findings.
- The monolithic local `pnpm test:run` was started, then stopped after
its revision passed the full CI matrix and was superseded by the
authentication-stop repair. Final full-suite verification passed in CI
shards; all 19 final local provider regressions pass.
- The tests run from this source checkout on macOS arm64 with isolated
PostgreSQL and controlled provider failures. They do not prove live
GitHub recovery or deployment. No live connection settings were changed.

## Risks

- Permission failures now leave unrelated work available. The rejected
operation remains failed and is not automatically replayed. Provider
authorization still applies to every request.
- Keeping a connection enabled must not bypass an authentication stop.
GitHub verifies blocked tool discovery and later sends; Discord and
Photon verify background reconciliation and restart cannot clear the
stop. Failed connection health is an execution gate while the endpoint
requires attention.
- Explicit disable, disconnect, signed installation revocation, and
existing destination-specific denial handling remain unchanged. No
migration or API schema change is required.
- Previously disabled connections are not automatically re-enabled
because an upgrade cannot safely infer the user's intent.

## Model Used

- OpenAI Codex, GPT-6 family. The runtime does not expose the exact
deployment model ID or context-window size. Used reasoning, shell tools,
repository edits, and test execution.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-19 09:54:22 -05:00
DottaandPaperclip 9077748894 Remove the Pipelines experiment and preserve its data (#16834)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Pipelines was an unused experiment with its own UI, API, CLI, and
automation.
> - Keeping it leaves unsupported product surfaces and extra task-detail
queries.
> - Removing the experiment must preserve data that users already saved.
> - This pull request removes the feature and keeps its database schema
and migration history.
> - Cases and Routines remain available as separate features.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Remove the unused Pipelines experiment across the application.

**Current behavior**

The experiment includes pipeline boards, stage settings, case
automation, review queues, learnings, permissions, and CLI commands.
Task detail also queries pipeline links.

**Proposed behavior**

Remove all these product surfaces and their implementation. Preserve
existing tables, records, and documents. Ignore the retired boolean in
older managed configurations so upgrades still start.

**Breaking changes**

Pipeline URLs, API endpoints, CLI commands, and `pipelines:write` are
removed. Task detail no longer includes the old `linkedCases` field. The
independent Cases API remains available. No database migration or
cleanup is included.

Related feature work: #7907, #9110, #10905, #11375, #13004, #14671,
#16133. Related issues: #9663, #10310, #10312. This removal supersedes
the feature; it does not implement those pending enhancements or delete
their saved data.

## What Changed

- Remove Pipeline UI pages, navigation, gates, clients, query keys,
helpers, and unused design tokens.
- Remove Pipeline REST routes, services, automation dispatch,
task-detail queries, and OpenAPI discovery.
- Remove the CLI commands, shared contracts, experimental flag, catalog
entry, and permission defaults.
- Remove feature-specific tests, tutorials, smoke scripts, maps, and
Storybook examples.
- Preserve database schema, migration history, and the reserved document
key used by old records.
- Keep Cases routes independent and cover obsolete stored and managed
settings.

## Verification

- Passed: `pnpm build` and `pnpm -r typecheck`.
- Passed: targeted settings, managed configuration, sidebar, settings
UI, routing, and feature-catalog tests. A first sidebar run caught a
shared Workspaces icon import; the import was restored and the sidebar
rerun passed.
- Passed: 40 tests covering Cases routes, OpenAPI discovery, retained
Pipeline table constraints, and schema snapshot drift.
- Passed: token gates, map validation, generated API metadata check,
Storybook catalog validation, and 28 map/catalog tests.
- Passed: isolated local browser verification of navigation and
Experimental settings with Pipelines absent; Cases and Routines still
open normally. Live GET/POST requests to retired Pipeline endpoints
return 404, and the retired setting is absent. CLI help has no Pipeline
commands.
- Passed: 22 access-service and agent-default-grant tests after
restoring unrelated permission assertions flagged in review.
- Local full run: `pnpm test:run` reported one failure in the unchanged
workspace-runtime port-allocation test. That test passed in an isolated
rerun. The long local run was stopped after full CI passed; it is not
reported as a complete local pass.
- Passed: all 56 checks on `def9181f3a4491d95fca1d38e9739f5b821aae3e` (2
conditional checks skipped), including build, typecheck, test shards,
and browser suites. Eleven interrupted CI jobs reported “The operation
was canceled”; their one-time retry passed. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/39255211006).
- Greptile: 5/5 on the final commit, with the only review finding fixed
and resolved.
- Sandbox socket restrictions affected the first build/API test
attempts. The same commands ran with local sockets available.

## Risks

- Existing Pipeline clients must stop using the removed endpoints and
commands.
- Existing data remains in the database and backups, but the removed UI
no longer displays it.
- Historical boolean `enablePipelines` values are ignored. They cannot
restore the feature.
- Cases and Routines must retain their separate behavior. Targeted route
tests cover this boundary.

## Model Used

OpenAI Codex, GPT-6, with repository inspection, editing, shell
execution, and browser verification. The exact deployed model ID and
context-window size 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-19 08:09:46 -05:00
DottaandPaperclip 896f3c7f3b Add personal Muse operator setup and composer controls (#16450)
Add Muse invitation, connection readiness and scoped operator controls.

Keep connection state tied to the current company, person, agent and binding. Surface failed reads and invalidate stale cleanup observations; require current authority and exact readback. Preserve Dot/Grok setup, source-trust limits and existing design tokens.

Carry actual merged backend e6dcc6b095 through a normal forward merge. Preserve its project-write authority fix, existing migration bytes and upstream idle-serving behavior; no new UI behavior is authored by this source carry. Current-head CI and substantive review remain merge gates; final canonical and deployed-provider qualification remain separate.

Refs #16450.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-17 23:01:42 -05:00
86c965ce7a fix(skills): expire unused version caches and restore saved contents (#16433)
Expire idle skill-version caches with durable runtime pins, bounded discovery, conservative retention, and database-backed restoration.

Co-Authored-By: Dotta <cryppadotta@users.noreply.github.com>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-15 12:20:57 -05:00
DottaandPaperclip 4460785534 fix(skills): preserve referenced files in large repository imports (#16308)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents use skills imported from project repositories.
> - Large repositories fall back to isolated skill folders.
> - That fallback drops shared files and turns advisory links into
import failures.
> - This pull request retains bounded referenced files and keeps missing
references advisory.
> - Users can import valid skills such as test-audit without editing the
source repository.

## Linked Issues or Issue Description

Refs #16066. Refs #16256. Refs #16288. Related draft #15730 adds
optional reference selection to individual skill packages. This fix
applies automatic repository fallback and does not add that selection
UI.

**What happened?**

A project source showed 86 warnings. It rejected 23 skills solely
because references were absent from the isolated package. It also
treated web routes and inline Markdown examples as files. For
test-audit, repository scripts were resolved inside the skill folder.

**Expected behavior**

Retain referenced files that fit the package limits. Missing references
must not block an otherwise valid selected skill. Preserve content
validation and installed shared files.

**Steps to reproduce**

Import paperclipai/paperclip at commit
09a2f0b7b0 as a repository source. Select
test-audit. Inspect its references and saved files. Repeat with a skill
whose optional reference is missing.

## What Changed

- Add a bounded fallback that keeps skill folders and transitive
Markdown references with their original repository paths.
- Resolve existing repository-root resource paths. Ignore site-relative
web links and inline Markdown examples.
- Keep missing references advisory, including explicit imports and
automatic project imports.
- Share fallback with file previews. Reinspect cached dependency
failures at an unchanged upstream commit.
- Retain existing versions when fallback cannot preserve installed
shared files. Keep file limits, content audits, authorization and work
budgets.
- Update product contracts and Skills maps. No schema or public API
changes.

## Verification

- Red/green: three original regression cases failed before the fix and
passed afterward. Two review controls also reproduced omitted directory
siblings and duplicate blob reads before their fixes.
- Focused scanner, repository package, persistence, project
synchronization and GitHub access tests: 126 cases passed across local
and isolated Linux runs.
- Full recursive typecheck and `pnpm build` passed locally on
`555bd3fc90314dbf23ed0ffe7034429946c1a471`. The [full Paperclip CI
workflow](https://github.com/paperclipai/paperclip/actions/runs/38596749890)
passed on that head, including all general, serialized, Runner and eight
browser test shards. The duplicate local `pnpm test:run` was stopped
after CI completed (exit 143); it is not claimed as a completed local
full-suite pass.
- Real GitHub scan at the pinned public commit: 77 skills, 454 retained
files, 9,117,635 bytes. test-audit has no missing references. The full
source reports 23 warnings, including remaining file validation and
genuine missing-reference notices.
- Local browser: scanned the public repository, selected test-audit and
create-issue-interaction-ui, and imported both. The second skill
retained an advisory missing-reference warning. Both remained installed
after reload. The saved package exposes `scripts/run-vitest-stable.mjs`
(25,813 bytes) and `scripts/general-server-shard.mjs` (2,813 bytes). No
GitHub responses were mocked. No model execution was needed for this
import fix.
- Map checks and Git whitespace checks passed. Greptile is 5/5 on the
current head with both review findings resolved. The external Superagent
security scan concluded neutral/inconclusive after its agent exceeded
the prompt deadline. A check-run retry request returned HTTP 404. All
Paperclip CI gates passed, but merge is held pending a conclusive
security scan; this is not an all-checks-green claim.

## Risks

- Dependency detection covers explicit Markdown links and resource
paths. It does not infer all script imports or runtime dependencies.
- Referenced content can exceed package limits. The existing bounds
still apply, and warnings disclose omissions.
- Content validation still rejects invalid entrypoints and omits
rejected support files. This change does not make every upstream skill
importable.
- No migration is required. Existing sources with the old dependency
error are inspected again on refresh.

## Model Used

OpenAI Codex, GPT-6 family. The runtime did not expose the exact serving
model ID or context window. Used reasoning, code editing, terminal
execution and browser tools. No subagents were used.

## 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:04 -05:00
Devin FoleyandPaperclip 5b29b9062e fix(server): compact finished task worktrees and shorten the reaper cooldown (#16304)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Each task can run in its own isolated Git worktree, and each
worktree installs its own dependencies
> - The terminal-workspace reaper removes a worktree only when the task
tree is finished, the delivery is merged, the files are clean, and a
7-day cooldown has passed
> - A recurring task that runs every hour keeps a week of worktrees, and
each worktree holds gigabytes of `node_modules`. A finished task with no
merged pull request, or with leftover agent files, keeps its worktree
forever
> - On a busy instance this fills the disk in days, and a larger volume
only delays the next failure
> - This pull request adds compaction: one hour after a task tree
finishes, the reaper removes regenerable directories from the worktree
and keeps the workspace, the branch, and all source changes
> - The benefit is that finished tasks stop holding gigabytes of disk,
and no work is lost because a resumed task regenerates the files when
its workspace is provisioned again

## Linked Issues or Issue Description

Refs #2022 (retention for workspace cleanup). Related: #11936 and #14608
add external reclaim scripts (a scheduled tool and a disk-guard step).
This pull request does the reclaim inside the server's
terminal-workspace reaper instead. That way it uses the reaper's
lifecycle lock, issue-tree checks, and live-run checks, and needs no
extra scheduler.

**What existing behavior does this improve?**
Disk retention of execution workspaces after their tasks finish.

**Current behavior**
A finished task keeps its full worktree, including installed
dependencies and build output, for at least 7 days. If the delivery is
not merged, or the worktree has uncommitted or untracked files, the
reaper never removes it. On one instance, an hourly recurring task
created about 22 worktrees per day at about 3 GB each (about 2.8 GB of
that was `node_modules`). Together with finished tasks that had no
merged pull request, they filled a 100 GB volume in about two days.

**Proposed behavior**
One hour after a task tree becomes terminal, the reaper removes
regenerable directories (installed dependencies, build output, tool
caches) from the worktree. It keeps the worktree, the branch, the
commits, and every tracked, untracked, or other ignored file. When the
task resumes, the existing reuse path runs the provision step, which
reinstalls the dependencies. Clean, merged worktrees are archived after
1 day instead of 7.

**Reason and benefit**
Most of a finished worktree's size is regenerable. Compaction removes
that part without the risk of deleting work, so it can apply to
workspaces that the reaper must keep (no merged pull request, leftover
files). The shorter cooldown limits the cost of the source checkouts
that stay.

**Breaking changes**
None. The default archive cooldown changes from 7 days to 1 day.
`PAPERCLIP_WORKSPACE_REAPER_COOLDOWN_DAYS` still overrides it.
`PAPERCLIP_WORKSPACE_COMPACTION_ENABLED=false` turns compaction off.

## What Changed

- New `server/src/services/workspace-compaction.ts`:
- Finds directories with a regenerable name (`node_modules`, `dist`,
`build`, `coverage`, `storybook-static`, `target`, `.cache`, `.next`,
`.nuxt`, `.parcel-cache`, `.svelte-kit`, `.turbo`, `.vite`).
- Keeps only the directories that the repository's own `.gitignore`
files ignore and that hold no tracked file. A negated pattern
(`!build/`), a global excludes file, and `.git/info/exclude` do not
count. Each candidate is checked per path, so dependencies below an
ignored parent (`vendor/tool/node_modules`) are found.
- Searches inside a regenerable-named directory that does not qualify
(for example a tracked `build/`), so its ignored dependencies still go.
- Never enters `.git` or `.paperclip` (the worktree instance data), and
never follows a symlink.
- Each Git read has a 60-second deadline and stops when the sweep is
aborted.
- Moves the directories into `.paperclip-compaction-trash` beside the
worktree with a same-filesystem rename, and can restore them.
- `sweepTerminalWorkspaces` compacts each terminal workspace once per
terminal cycle, after the compaction delay and before the archive
cooldown check:
- Only isolated linked Git worktrees qualify. A shared workspace, a
project's main checkout, or a row whose `.git` is a directory is never
compacted.
- The move runs inside a transaction that holds the workspace lifecycle
lock. The guard checks a fresh row and the same lifecycle generation. It
also checks that the issue tree is terminal, that no queued or running
run works on the tree or the workspace (by checkout or execution run, or
by run context), and that no runtime service runs from the workspace.
- The guard runs before the move and again after it. If the second check
fails (for example, the task reopened or a run started), the directories
move back. Otherwise the trash is deleted.
- The worker wakes at the compaction deadline, not only at the archive
deadline.
- Stale trash from an interrupted compaction or a failed delete is
purged by later sweeps. The sweep checks each worktree parent at most
every 30 minutes, whether or not anything is left to compact.
- New counters `compacted` and `compactionFailed` in the sweep result.
The activity log gets an `execution_workspace.regenerable_files_removed`
entry with the removed paths.
- Config: new `PAPERCLIP_WORKSPACE_COMPACTION_DELAY_HOURS` (default `1`)
and `PAPERCLIP_WORKSPACE_COMPACTION_ENABLED`. The default for
`PAPERCLIP_WORKSPACE_REAPER_COOLDOWN_DAYS` changes from `7` to `1`. Both
new keys are added to the run-failure diagnostics allowlists.
- Docs: `doc/DEVELOPING.md` documents the new variables and has a new
"Terminal workspace compaction" section. `doc/SPEC-implementation.md`
describes compaction.
- `execution-workspaces.ts` was already above 1,000 lines. The
file-system logic is in the new module. Only the guarded orchestration,
which uses the existing lifecycle lock and run predicates, is in the
service.

## Verification

- `pnpm exec vitest run src/__tests__/workspace-compaction.test.ts
src/__tests__/execution-workspace-compaction.test.ts` (in `server/`): 27
passed. `workspace-reaper-cooldown-config.test.ts`: passed.
- Unit tests: directory selection (ignored, untracked, regenerable name
only, `.env` and local data kept, tracked `coverage` kept, `.paperclip`
skipped, symlinks not followed), nested candidates under a source
`build/` and under an ignored `vendor/`, a negated `!build/` kept,
global and `info/exclude` rules ignored, glob characters in names,
abort, main checkout vs linked worktree, move and restore, restore that
keeps a recreated directory, and stale-trash purge.
  - Embedded Postgres tests:
- A no-PR, unmerged, dirty workspace is compacted. HEAD, the branch ref,
`git status --porcelain --untracked-files=all`, untracked notes, `.env`,
local data, and `.paperclip` data stay the same, and the row stays
active.
    - A delivered workspace inside the cooldown is compacted.
    - The delay is respected, and the worker wakes at the delay.
- An active checkout run, a queued run found through its context, an
unfinished child issue, and a running runtime service all block
compaction.
- The task reopens during the move: the files are restored and
unchanged.
    - A run starts during the move: the files are restored.
    - A shared workspace and a main checkout are never compacted.
- Compaction runs once per terminal cycle and again after a later cycle.
    - Disabled compaction does nothing.
- End to end: `realizeExecutionWorkspace` creates a worktree, the sweep
compacts it, and a second `realizeExecutionWorkspace` reuses the same
worktree. The provision command regenerates `node_modules`, and the
untracked notes and the unmerged commit are still present.
- Leftover trash is purged when the workspace has nothing left to
compact.
- Mutation checks: when the post-move guard is disabled, both race tests
fail. Without the negation fix or the repository-only source fix, their
tests fail.
- `pnpm exec vitest run` for `execution-workspaces-service.test.ts`,
`terminal-workspace-work.test.ts`, `execution-workspace-reopen.test.ts`,
`server-startup-feedback-export.test.ts`, and
`workspace-runtime.test.ts`: 335 passed. Two `workspace-runtime.test.ts`
cases fail locally with and without this change (`does not diagnose a
missing remote branch as a rejected credential`, `rejects explicit main
on a master-only remote ...`). They also fail on unmodified `master` on
the same machine, so the cause is the local Git environment.
- `pnpm typecheck` in `server/`: passed. `pnpm check:module-boundaries`:
passed.

## Risks

- A repository can keep something that is not regenerable in an ignored
`dist`, `build`, `target`, or `.cache` directory. Compaction removes it.
The fixed name list, the ignore check, and the tracked-file check limit
this. `PAPERCLIP_WORKSPACE_COMPACTION_ENABLED=false` turns compaction
off.
- A repository without a provision command does not get dependencies
back automatically. This is the same state as a new worktree for that
repository, where the agent already installs them.
- A resumed task pays for a dependency install again. This happens only
for tasks that finished more than an hour earlier.
- The shorter default cooldown removes clean, merged worktrees after 1
day instead of 7. An operator who wants the old hold can set
`PAPERCLIP_WORKSPACE_REAPER_COOLDOWN_DAYS=7`.
- Self-hosted instances get the same behavior. There is no schema
change.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`), 1M context, through Claude Code
with tool use (shell, file edits, test runs). A separate Claude agent
read the reaper code during the diagnosis.

## 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
- [ ] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-14 09:49:04 -07:00
ba4fac585d feat(agents): show who created an agent in shared companies (#16055)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - A company in Paperclip can have more than one human member, and each
member can create agents
> - The app does not record which person created an agent
> - When two or more people share a company, members cannot see who
added an agent or who to ask about it
> - This pull request records the creator of each agent and shows the
creator on the agent Overview tab
> - The benefit is clear ownership of agents in shared companies, with
no change for single-user companies

## Linked Issues or Issue Description

No public issue exists. This description follows `feature_request.yml`.

**Subsystem affected**

Agents: the agent data model, the agent create path on the server, and
the agent Overview tab in the board UI.

**Problem or motivation**

Paperclip does not record which human user created an agent. When more
than one human user works in a company, the agent page does not tell
members who created the agent.

**Proposed solution**

Record the user ID of the creator when a human creates an agent. Show
"Created by <name>" on the Identity card of the agent Overview tab. Show
this row only when the company has two or more human members. Do not
count the synthetic local Board principal as a human member. Do not show
the local Board as a creator.

**Alternatives considered**

Count human users across the full instance. We did not do this. An
instance-wide count tells a member of one company that other companies
have users. The creator is always a member of the agent's company, so
the company count is sufficient.

**Roadmap alignment**

`ROADMAP.md` has no item for agent ownership. This change is small and
additive.

## What Changed

- Add the nullable column `agents.created_by_user_id`
(`packages/db/src/schema/agents.ts`, migration `0343_new_mentor.sql`).
- Set the column in the single agent insert path
(`server/src/modules/agent-lifecycle/adapters/records.ts`). The value
comes from the authenticated user actor. The server ignores a creator
value in the request body. Agents that agents or the system create keep
`null`.
- Backfill existing agents in the migration. The backfill uses the
earliest `agent.created` or `agent.hire_created` activity row that a
user actor wrote in the same company.
- Add `createdByUserId` to the shared `Agent` type
(`packages/shared/src/types/agent.ts`).
- Add `ui/src/lib/agent-creator.ts`. It decides if the UI shows the
creator row and it resolves the creator name. If the creator left the
company, the row shows "Former member".
- Add the "Created by" row to the Identity card in
`ui/src/pages/AgentDetail.tsx`. If the company user directory request
fails, the row shows "Could not load creator". The row does not
disappear silently.
- Add the Storybook story `Pages/Agent Detail → Shared Company Shows
Creator`.
- Document the column in `doc/SPEC-implementation.md` §7.2.

## Verification

- `pnpm --filter @paperclipai/db typecheck` passes. This includes the
migration numbering and migration safety checks.
- `pnpm --filter @paperclipai/shared typecheck` passes.
- `ui`: `tsc --noEmit` passes.
- `server`: `vitest run
src/modules/agent-lifecycle/__tests__/lifecycle.test.ts` passes (49/49).
Two new tests:
- The server records the creator from the actor and ignores a creator
value in the request body.
- The backfill takes the earliest user activity row. It skips agent
actors and rows from other companies.
- `server`: `vitest run src/__tests__/built-in-agents.test.ts` passes
(40/40). A new test checks that a built-in agent enabled by a human
records that human, and that automatic provisioning stays unattributed.
The gated (pending-approval) provisioning test also asserts the creator.
`src/__tests__/built-in-agent-routes.test.ts` also passes.
- `ui`: `vitest run src/lib/agent-creator.test.ts
src/pages/AgentOverview.test.tsx` passes (10/10). The tests cover these
cases: the row shows with two or more humans, the row stays hidden with
one human plus the Board, the UI never shows the Board as the creator,
the row shows an error when the directory request fails, and the row
stays hidden (no error) for agents with no creator or the Board as
creator. The last case fails without the fix.
- The current Storybook catalog uses source annotations and generated
indexes. `node scripts/storybook-catalog.mjs --check` passes (264 story
files, 2,514 stories). The merge keeps the authored catalog deletion
from master.
- `pnpm check:token-gates` is clean.
- Screenshots from the Storybook story (fake data: two human members,
Alice Admin and Bob Builder, plus the local Board). The red "Could not
load public key" text is a Storybook artifact: the story has no fixture
for the public key request. The existing `Dashboard` story shows the
same text.

  **Two or more human members: the Identity card shows "Created by".**

![Identity card with the Created by
row](https://raw.githubusercontent.com/paperclipai/paperclip/9b62bd2ea6cf984ce6745f08cc45f44ddf00fb51/pr-16055/identity-created-by.png)

  **One human member plus the local Board: the row stays hidden.**

![Identity card without the Created by
row](https://raw.githubusercontent.com/paperclipai/paperclip/9b62bd2ea6cf984ce6745f08cc45f44ddf00fb51/pr-16055/identity-single-human.png)

Full Overview tab:
[overview-created-by.png](https://raw.githubusercontent.com/paperclipai/paperclip/9b62bd2ea6cf984ce6745f08cc45f44ddf00fb51/pr-16055/overview-created-by.png).
The images are on the separate branch `pr-assets/agent-created-by`. They
are not in this PR and do not go to `master`.
- Manual check: open Storybook at `Pages/Agent Detail → Shared Company
Shows Creator`. The Identity card shows "Created by Alice Admin". The
`Dashboard` story has one human, so it does not show the row.
- Final focused verification on
`5a02350cf16050a3cf3cb3f8dc061fe61758c60d`: all 99 tests pass across the
two UI suites, built-in-agent suite, and lifecycle suite. The backfill
test applies the complete migration twice. The migration uses `ADD
COLUMN IF NOT EXISTS` and preserves the company-scoped backfill.
Migration numbering and token checks pass.
- Full repository typecheck, build, and Storybook build pass. The
generated creator story ID is present. A Chromium check renders the
production agent page fixture and verifies the creator row and Alice
Admin name. Map checks and their 21 tests pass. A fresh Apex review is
5/5 on the current head with no unresolved findings. All 54 successful
CI checks pass on this head, with two intentional skips, including all
general and serialized test shards, E2E, typecheck, and build. The
workspaces-b job passed after rerunning a runner shutdown; no source
change was needed. The separate, unsharded local `pnpm test:run`
invocation has not completed; complete suite verification comes from CI.

## Risks

- Migration: the migration adds one nullable column and runs one
`UPDATE` on `agents` with a correlated subquery on `activity_log`. On an
instance with a very large activity log, the backfill can take some
time. The migration does not lock other tables and does not delete data.
- Backfill accuracy: agents with no user-authored create activity row
keep `null`. The UI then does not show a creator. This is the same as
the current behavior.
- Privacy: the row shows only names from the company user directory, and
only to users who can already see that directory.
- Low risk for single-user companies: the UI does not change for them.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Provider: Anthropic, Claude Opus 5.5 (model ID `claude-opus-5-5`), run
as a coding agent through Claude Code with tool use (shell, file edit,
and test execution), standard context window.

OpenAI GPT-6 (`gpt-6`) through Codex assisted conflict resolution,
regression tests, and repository verification. 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: Amy (Opus) <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: devinfoley <139239+devinfoley@users.noreply.github.com>
2026-10-13 14:57:41 -07:00
DottaandPaperclip 473c80d13f Automatically import and update project repository skills (#16066)
Automatically import skills from new GitHub project repositories and update enabled sources in the background. Preserve project-derived access, saved selections, immutable execution versions and explicit pins; add legacy adoption, refresh and connection repair in Sources.

Include durable scheduling and bounded work credits, production Storybook journeys, real GitHub-to-routine acceptance receipts and final-head CI/security/Greptile qualification.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-13 16:11:43 -05:00
DottaandPaperclip be380ba155 fix(ui): hide agent-created tasks by default (#16157)
Hide agent-created, system-created, and chat-channel tasks from independent collections by default. Preserve task hierarchy context and existing inbox participation. Add a saved opt-in checkbox without helper text.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-13 09:26:37 -05:00
DottaandPaperclip aded4197e5 fix: make multiplayer task toasts personal (#16153)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for work.
> - A company can have several human users and shared agents.
> - Live task events currently produce toasts for any user who can read the task.
> - This makes unrelated work interrupt other users.
> - This pull request checks each user's task participation before it permits a toast.
> - Users receive relevant task notifications while company views continue to refresh.

## Linked Issues or Issue Description

**What happened?**

Company task activity and agent failures produce noisy toasts for users who have no involvement in the task.

**Expected behavior**

A task qualifies when the viewer created it, commented on it, is its assigned user, deliberately acted on it under the Mine rules, or has an explicit user mention in its description or a non-deleted comment. Viewing, agent ownership, responsible-user attribution, and parent participation alone do not qualify.

**Steps to reproduce**

1. Sign in as two users in the same company.
2. Have the second user create and update a task that does not involve the first user.
3. Observe a task toast in the first user's company view before this fix.

The duplicate PR search found no existing change for personal task-toast eligibility.

## What Changed

- Extract the existing Mine participation predicate without changing Mine behavior.
- Compute task eligibility from stored tasks, comments, and run associations after WebSocket access checks. Use an exact indexed comment-mention lookup with `LIMIT 1`.
- Add optional `toastEligible` metadata to each viewer's event copy. Keep it off the shared event bus.
- Require eligibility for live task activity and task-linked run errors. Suppress generic agent errors.
- Continue cache updates for quiet events. Refetch visible comments when authenticated events omit hydration details. Ignore stale socket callbacks after account or company changes.
- Document toast semantics and add feature-map and agent-access-map coverage.
- Add persisted-data, socket, UI, and authenticated browser regression coverage.

## Verification

- Final commit: `1dc4f9402c5883744738cfe236ad00fa0bb5ca4c`.
- All 55 current-head checks passed. Two Storybook checks were skipped because this change does not affect that coverage.
- Greptile approved this exact commit with 5/5. The security scan passed. Both review threads are resolved.
- Local `pnpm build`, `pnpm -r typecheck`, `pnpm check:token-gates`, and `node scripts/check-maps.mjs` passed.
- The focused socket/UI suite passed 123 tests. The persisted eligibility suite passed 9 tests, including long history, exact viewer matching, and regex escaping. The existing Mine service suite previously passed 140 tests.
- The named browser case `task toasts follow personal involvement in multiplayer` passed against the final commit in an isolated authenticated instance. It used two real sessions, real WebSocket delivery, and persisted tasks, edits, comments, and mentions. It verified quiet unrelated activity, viewing alone, first and historical mentions, own-action suppression, visible-task suppression, and live cache refresh.
- A prior-head server shard passed its single rerun after a fixture-cleanup deadlock. The final-head CI run passed without a rerun.
- The broad local run remained in progress when CI completed the full test suite. Local focused checks and CI provide the completed test evidence.

## Risks

- This intentionally reduces live notifications. A new client stays quiet against an older server that omits eligibility.
- Eligibility queries add work to live event delivery. A lookup failure suppresses the toast and still delivers the authorized event.
- Deleted mentions cease to qualify unless another participation rule applies. Historical comment authorship retains the existing Mine behavior.
- No database migration or notification-settings change is required.

## Model Used

OpenAI Codex with GPT-6 assisted with implementation, tests, documentation, and PR preparation. It used repository tools, shell commands, and browser automation. The runtime did not expose an exact backend revision 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-13 08:09:19 -05:00
DottaandPaperclip 2ad36f4ff2 Fix skill source removal with a keep-or-delete choice (#16150)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - GitHub sources import skills and keep their updates together.
> - Disconnect only disabled a source and kept its read-only imports.
> - A disabled source could not be removed or imported again.
> - Removing a source needs an explicit decision about its imported
skills.
> - This pull request removes the source after the user keeps editable
copies or deletes the imports.
> - Existing disabled sources use the same removal flow.

## Linked Issues or Issue Description

Refs #15731, #14713.

**What happened?**

Disconnect left the repository on Sources. Its Disconnect action was
then disabled. The saved repository still blocked a new import.

**Expected behavior**

Remove the repository from Sources. Require a choice to keep editable
copies or delete its imports. Allow removal of sources that are already
disconnected.

**Steps to reproduce**

1. Import a repository in Skills → Sources.
2. Choose Disconnect source.
3. Observe the disconnected row and disabled removal action.
4. Try to import the repository again.

**Paperclip version or commit**

d67e3507b2.

## What Changed

- Add one confirmation with a required keep-or-delete choice.
- Remove the source and entries, including legacy disabled sources.
- Keep complete editable copies in My Skills, including shared
repository files and executable modes. Preserve skill IDs, keys,
versions, and agent assignments.
- Delete imported skills and source in one transaction with its activity
record. Check policy for every linked skill, including deselected
entries. Reject deletion of skills still used by agents.
- Fence removal with the source revision. Reload stale confirmations and
require a new choice. Prevent an in-flight refresh from restoring
removed imports.
- Reject incomplete legacy copies with a recovery message. Lock copied
skill rows against concurrent deletion and check publication succeeded.
- Add regression tests and production-page Storybook examples. Make an
initially unselected radio-card group keyboard accessible.

## Verification

- Workspace typecheck and build passed. Final affected server/UI
typechecks passed.
- Focused server, UI, and API suites passed: 114 tests initially. After
review fixes, all 21 source persistence and 58 route authorization tests
passed, including the complete repository copy regression; affected
server/UI typechecks and token gates passed again.
- Design token gates passed.
- Real isolated app: imported a public repository, assigned bro to the
CEO, verified that deletion reports the assignment, kept an editable
copy, observed the source disappear, opened the copy in My Skills, saved
an edit, and refreshed. The assignment remained. Re-imported the same
repository, deleted its new unused import, and verified the original
editable copy and assignment remained. No model tasks ran.
- Full local Vitest was attempted but terminated with exit 137 before
completion; it is not counted as a pass. Current-head sharded CI is
pending. Greptile reviewed the current head at 5/5 with no new
actionable comments. The final workspace build passed again.
- Storybook catalog aligned. The legacy removal example was inspected in
the browser; the Delete choice enables removal.
- Storybook: Skills / GitHub-synced skills / Sources · Disconnect source
and Sources · Remove disconnected source.

## Risks

- DELETE of a skill source now requires the saved revision and an
explicit copy/delete choice. Old callers must update their request body.
- Deletion removes imported skills and their records. Assigned skills
must be detached first.
- Incomplete legacy versions must be refreshed before keeping copies;
removal does not silently discard supporting files.
- Copies intentionally stop receiving upstream updates. Their IDs and
keys remain stable for assigned agents.
- No database migration. Copy writes use new managed directories and
clean up on failure. Delete restores quarantined files before releasing
publication locks on failure.

## Model Used

OpenAI GPT-6 through Codex, configured model `gpt-6-astra`. The runtime
does not expose the context-window size. Used shell tools, code editing,
tests, and browser interaction.

## 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 07:53:13 -05:00
DottaandPaperclip f329b24ee1 feat: give tasks durable project-optional workspaces (#15749)
Give tasks durable company-scoped workspace bindings independent of project assignment, channel defaults and authorized repository preparation. Reuse verified input seeds and sparse output recovery while preserving trust, privacy and controller provisioning boundaries.

Full CI and E2E, Superagent, legacy checks and Greptile Apex 5/5 passed on reviewed head 753680b61c. All review findings are resolved; the PR records focused verification and historical acceptance limits.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-12 20:45:18 -05:00
Dotta a9830414c7 Preserve repository dependencies when importing GitHub skills (#15731)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Its Skills library imports reusable instructions from GitHub.
> - Some skills depend on shared files and sibling skills outside their
folders.
> - Directory-only imports lose those dependencies.
> - This pull request keeps repository files together and lets users
select which skills appear in the library.
> - Agents receive the original files and paths through the existing
skill delivery system.

## Linked Issues or Issue Description

Refs #14713. Related: #13656.

**Current behavior**

GitHub imports copy independent skill directories. Shared scripts,
policies, helper skills, and credit files can be omitted. One
shared-file error can block every skill.

**Proposed behavior**

New imports keep repository files together at the scanned commit. Show
all skills with their folders and select every skill by default.
Collapse individual package files. Omit unsupported or oversized files
with a warning. Import available content without repair choices or an
extra confirmation. Keep warnings on the saved source.

**Reason and benefit**

Skills can read their shared repository files after Paperclip delivers
them to an agent. Original instructions stay unchanged. Users can
inspect included files and understand omissions before and after import.

## What Changed

- Store immutable company-scoped repository snapshots and associate them
with skill versions. Regenerate the migration after merging master.
- Preserve original bytes, binary encoding, and executable modes.
Shared-file changes version each usable selected skill. Pinned versions
retain their original files.
- Deliver a discovery wrapper with the original tree under
`.paperclip-repository/`. Preserve invocation policy when present. Fork
and create-from-existing retain repository files.
- Keep repository files together for new UI imports. Show every skill,
select all by default, and collapse package files. Remove the
packaging-mode menu. Keep the mobile import footer visible.
- Warn about symlinks, submodules, oversized files, missing references,
and invalid optional manifests. A malformed skill remains selected with
a Needs setup warning. Usable skills still publish, and its original
file remains repository support content. Source warnings persist through
refresh. Unsafe execution and secret-disclosure findings omit the
affected files before snapshot publication.
- Expose saved repository files in the installed skill viewer, including
binary encoding and executable flags. Reads use the immutable
company-scoped snapshot; relative instruction links resolve from their
original repository directory.
- Audit delivered inventories and derive trust from all repository
files. Accept evaluation prose while retaining dynamic-execution
findings. Read blobs in one bounded Git batch and check budgets before
reading support files. Imports never execute setup commands.
- Add scanner, database, delivery, UI, and browser regressions. Update
Storybooks, screenshots, and documentation.

## Verification

- 69 focused scanner, Git snapshot, delivery, and PostgreSQL lifecycle
tests passed. They cover partial imports, warning persistence, missing
references, binary files, executable modes, copies, pinned versions,
cancellation, company isolation, and batched Git reads.
- 110 import, skill-detail, selection-tree, saved-file link, and
Markdown renderer tests passed. A file-switch regression failed before
the resolver fix and passed afterward. Browser walkthroughs cover the
all-selected open tree, repository preview, non-blocking warnings,
missing references, setup problems, warning persistence, and mobile
layout.
- Full workspace typecheck and build passed. Runner E2E TypeScript
checks and design-token gates passed. The full serial local suite was
attempted and stopped after over an hour. The existing 40,000-file Git
streaming stress test failed after 303 seconds on macOS; the broad local
suite is not counted as passed. All 55 applicable PR checks passed on
the final commit, including the full sharded CI suite. Two optional
Storybook workflows were skipped; the five local Storybook walkthroughs
passed.
- On October 12, live campaigns imported the private Poteto repository
through the production GitHub Sources UI, selected architect and bro,
and invoked them with native Codex on local and Daytona. The source
connection was disabled before invocation. Independent filesystem
inspections matched every supported Git blob, size, and executable mode.
Both tasks completed and cleanup passed. Campaigns:
`local-2026-10-12T15-07-39-504Z` (both environments),
`local-2026-10-12T16-08-39-682Z` (local), and
`local-2026-10-12T16-03-33-938Z` (Daytona). Each of the two selected
skills received all 234 supported repository files. Later changes only
affect the installed-file viewer and documentation. This qualifies skill
delivery and instruction reads, not every Poteto workflow or adapter.
- A manual source-checkout test drive imported a synthetic private
GitHub repository with a symlink, an oversized file, a missing
reference, and malformed skill metadata. Available skills published with
their shared checklist. The walkthrough found duplicate warning text
after import; the final UI fix removes that duplicate. The file viewer
exposes saved repository dependencies and resolves authored relative
links without changing the instructions. A follow-up live refresh
omitted unsafe helper files with warnings, preserved every safe file
byte, and survived a server restart.

Screenshots below use the production UI with Storybook fixtures. They do
not replace the live GitHub and runtime checks.

<details>
<summary>All skills visible and selected by default</summary>

![Default repository
import](https://github.com/paperclipai/paperclip/blob/codex/skill-repository-packages/docs/pr-screenshots/pr-15731/repository-import.png?raw=true)

</details>

<details>
<summary>Import stays available with warnings</summary>

![Import
warnings](https://github.com/paperclipai/paperclip/blob/codex/skill-repository-packages/docs/pr-screenshots/pr-15731/repository-warning-details.png?raw=true)

</details>

<details>
<summary>Repository file inspector</summary>

![Repository
files](https://github.com/paperclipai/paperclip/blob/codex/skill-repository-packages/docs/pr-screenshots/pr-15731/repository-files.png?raw=true)

</details>

<details>
<summary>Mobile import</summary>

![Mobile
import](https://github.com/paperclipai/paperclip/blob/codex/skill-repository-packages/docs/pr-screenshots/pr-15731/repository-mobile.png?raw=true)

</details>

## Risks

- Each selected skill carries a repository copy in the runtime. The
database stores each snapshot once. Runtime transfer and storage
increase with the number of assigned skills.
- Runtime budgets remain: 9,990 repository entries, 1 MiB per file, and
61 MiB total. File omissions are recorded as warnings. Source-access or
download failures retain installed versions.
- Import success does not prove that every skill can run. Environment
dependencies, credentials, delegation tools, and schedules still need
configuration. Imported setup scripts are not executed.
- Live runtime coverage is native Codex on local and Daytona. Other
adapters use the shared delivery path but were not exercised in these
campaigns.

The roadmap marks Skills Manager as shipped. This extends the existing
importer. Related pull requests were checked.

## Model Used

OpenAI Codex, based on GPT-6, with repository inspection, code
execution, automated tests, and browser tools. The exact deployment
identifier and context-window size 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
- [ ] 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
2026-10-12 11:30:20 -05:00
1b4c803816 fix(costs): preserve usage attribution and explain unavailable run costs (#15948)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The cost ledger records usage and controls agent budgets.
> - Some runs lose the selected model or API billing category before
their usage reaches the ledger.
> - The dashboard reports missing costs but does not identify the
affected runs or the available actions.
> - This pull request preserves usage attribution and adds a compact
view of cost gaps grouped by agent.
> - Operators can inspect runs, open agent settings, and record saved
costs without starting new agent work.

## Linked Issues or Issue Description

Refs #15634, #11938, #15879.

This follows the merged subscription reporting in #15634. The older
proposal in #11938 addresses part of ACP model attribution. This change
also rejects conflicting models across a turn, fixes credential-backed
billing capture, and explains cost gaps in the existing dashboard. The
Pi receipt recovery work in #15879 covers a separate adapter recovery
path. This PR preserves unresolved receipts and does not recover
provider usage or reprice past entries.

**What happened?**

ACP results use the requested model even when the runtime selects a
model. Native and OpenCode API runs can report unknown billing despite a
matching API credential. The dashboard shows notices without links to
the affected runs. These gaps make API and subscription totals harder to
interpret.

**Expected behavior**

Record the model selected by the runtime. Identify API billing only from
a matching credential. Keep costs unresolved when reliable usage or
pricing is absent. Show the affected agents and runs. Offer an
accounting retry only when saved evidence is ready.

**Steps to reproduce**

1. Run an ACP agent with its model left unset, or use a matching API
credential with a native or OpenCode agent.
2. Inspect the recorded model and billing category for the run.
3. Open Costs Overview for a period with unpriced usage or terminal runs
awaiting receipts.
4. Inspect the notice and try to find the affected run or the relevant
agent settings.

**Paperclip version or commit**

Current master at `657e71584a0`. The patch is rebased on that commit.

**Deployment mode**

Self-hosted server and local development. The cost detail tests use a
disposable PostgreSQL database.

## What Changed

- Preserve the runtime-selected ACP model in checkpoints and final
results. Conflicting models across one turn remain unpriced.
- Share credential-backed API billing checks across native and OpenCode
results. Keep unknown billing when the provider and credential do not
match.
- Add company-scoped cost detail and accounting retry endpoints. Board
viewers can read details but cannot retry. Agents and foreign companies
are denied.
- Limit each detail category to 25 entries. Use one consistent database
snapshot and sparse indexes matching the filters and sort order. Add the
unknown-billing count to the existing summary query.
- Replace the notice with an expandable count line. Group entries
alphabetically by agent. Show the saved blob icon, link each name to
configuration, and put run and retry links beside the date.
- Preserve estimate and unavailable-price labels on Providers and
Billers; keep retry confirmation after the resolved notice disappears.
- Fetch details only while expanded. Retain the last loaded details
after a refresh error. Retry saved accounting only; do not rerun the
agent.
- Add capture, database, authorization, UI, and Storybook coverage.
Update the implementation contract and cost reporting guide.

## Verification

- `pnpm -r typecheck` passed after rebase.
- `pnpm build` and `pnpm build-storybook` passed after rebase.
- `pnpm check:token-gates` and `git diff --check` passed.
- 1,086 focused tests passed across 17 files. These cover ACP, native
and OpenCode capture, PostgreSQL reports, route authorization, OpenAPI,
Costs UI, and existing accounting regressions.
- Desktop and mobile browser checks passed during UI review. They cover
lazy expansion, alphabetical groups, loaded blob icons, configuration
and run links, keyboard retry, and layout overflow.
- `pnpm test:run` was attempted with command-scoped
`init.defaultBranch=master` for Git fixtures. It was stopped after a
native session recovery failure reproduced on unchanged base
`657e71584a0` (`archives a damaged prior epoch before completing guarded
same-task replacement with real runnerd`). An MCP upload case failed in
the broad run but passed in isolation on both the base and PR branch.
These local limitations do not affect the 1,086 passing focused tests.
- Current-head CI is green, including all unit test lanes, serialized
server suites, runner checks, typecheck, build, policy, and eight
browser shards. Apex re-review is 5/5 on `56de60effdb`; all four
original findings are addressed and every review thread is resolved.
- PostgreSQL applies migration `0333` in the integration fixtures.
EXPLAIN ANALYZE on the production detail statements uses the new sparse
indexes behind 5,000 healthy records in each table.
- Ten provider/biller card cases cover missing and estimated prices; the
retry test covers row removal and notice unmount. A live Storybook
browser check verifies the confirmation and updated count.
- Run `pnpm storybook`. Open **Costs / Subscriptions / Cost Data Quality
Details** to inspect the production page with representative fixtures.

## Risks

- Model and billing metadata change for future runs. Estimates still
require complete usage and a supported price. No past cost amount is
rewritten.
- A missing final receipt remains unresolved for budget checks. The
display changes after fifteen minutes; that time limit never authorizes
settlement.
- Accounting retry is a write action. It retains the existing company
checks, receipt fences, idempotency, and audit logging.
- Detail reads are bounded and run only after expansion. They poll every
30 seconds while open. No provider probe or new summary query is added.
- Migration `0333` adds two partial indexes; it changes no stored cost
amounts or table columns. Index creation scans the existing tables and
may briefly block writes during deployment. No lockfile or workflow
change is included.

## Model Used

OpenAI Codex, based on GPT-6, with repository inspection, code editing,
browser checks, and test execution. The exact serving model ID,
reasoning setting, and context window were not exposed to 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: Codex <noreply@openai.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-11 22:48:29 -07:00
DottaandPaperclip a7dd5284b5 feat: add company fast-response acknowledgements (#15748)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Human messages start agent work through task, chat, and
external-channel intake.
> - Agent startup can delay the first visible response.
> - A small direct model call can acknowledge the request while normal
work starts.
> - This response must remain separate from evidence that the agent
answered or completed work.
> - This pull request adds optional company-wide fast responses with
durable receipts, access checks, and cost accounting.
> - Users receive prompt acknowledgement without changing the agent
execution path.

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting: database, shared contracts, server orchestration,
connections, and UI.

**Problem or motivation**

Users can wait for an agent to start before they receive a contextual
response. Generic progress messages do not confirm what the user asked.
An acknowledgement must not falsely complete work or satisfy an
unanswered turn.

**Proposed solution**

Add a disabled-by-default experimental fast-response model using an
existing shared API connection. Generate one short acknowledgement for
each accepted human turn. Use the existing agent identity and external
publication outboxes. Retain platform provenance and account for the
inference independently.

**Alternatives considered**

Running the acknowledgement through the agent runtime adds startup
latency. Restricting implementation to OpenRouter leaves other existing
API connections unsupported. This change supports all existing API
connections and uses OpenRouter for live verification.

**Roadmap alignment**

This extends existing agent communication and connection settings.
ROADMAP.md and open pull requests were checked. No duplicate
fast-response implementation was found. The maintainer supplied the
feature plan directly.

## What Changed

- Add Experimental fast responses to instance settings. Keep the feature
off by default. Enforce the flag at intake, dispatch, and publication.
- Move Decision model and Fast response setup to company Settings →
Connections when the experiment is enabled. Place Connections below
Environments. Separate the model sections with clear headings and a
divider. Keep Decision model in General when the experiment is off.
Route Costs setup links to the available settings page.
- Make the acknowledgement prompt a multiline template string. Ask for a
brief, positive response in the user’s language.

- Add settings, connection/model selection, sponsorship, fixed-sample
testing, and Costs history.
- Add a Vercel AI SDK text service for existing native, routed, Bedrock,
and local API connections.
- Add durable per-turn requests, a bounded worker, a three-second
admission deadline, and one inference attempt.
- Integrate task creation, task and agent chat, steering, queued
follow-ups, experimental board chat, shared chat intake, and email.
- Preserve receipt provenance and exclude receipts from completion,
recovery, interaction resolution, and agent wakeups.
- Recheck authorization, source validity, real replies, budgets, and
destination binding before publication. Preserve accounting for
suppressed or uncertain outcomes.
- Add provider contracts, database race tests, channel outbox tests, UI
tests, Stories, and documentation. Keep decision-model execution
unchanged.

## Verification

- Local `pnpm -r typecheck`, `pnpm build`, and UI token gates pass after
rebase. The UI typecheck and build also pass after the final navigation
fixes. All 37 focused navigation tests pass. The first full local `pnpm
test:run` invocation reported seven chat failures. All seven passed in
isolated reruns after fixture updates and host cleanup. This invocation
was stopped after the full final-head CI suite passed.
- Initial local database tests hit macOS shared-memory exhaustion. A
diagnostic confirmed `shmget: No space left on device` with the system
limit of 32 IDs. Three abandoned, unattached PostgreSQL IPC headers were
reclaimed. The isolated rerun passed all 31 fast-response and channel
tests. The two additional Slack regression cases also passed in a
separate rerun. No active database was stopped.
- UI token gates pass. Provider contract tests cover all supported API
connection types. Fast-response tests cover uniqueness, authorization,
budgets, expiry, cancellation, restart, real-reply races, and the
experimental flag.
- The test drive verified that disabling the experiment hides
Connections and redirects its direct URL. Enabling it restores the saved
OpenRouter setup. After restart on the final commit, the OpenRouter
settings sample returned “Sure, I’ll take care of fixing the border
around the settings panel.” in 428 ms. It used 260 input and 31 output
tokens and recorded $0.0000576 in reported cost.
- Earlier live OpenRouter verification produced a receipt in 1.013
seconds for a new task. The real agent then supplied its substantive
answer. A separate settings test took 1.34 seconds, used 246 input and
23 output tokens, and recorded $0.0000361.
- Live Slack verification on final commit
`24016fa525961ebc7a4acffdc5019ce123970549` passed for a fresh initial
task and a follow-up in a disposable bot DM. The initial acknowledgement
appeared 2.405 seconds after the Slack message and 1.413 seconds after
durable acceptance; the follow-up appeared in 2.322 seconds and 1.160
seconds respectively. The recorded generation/settlement durations were
898 ms and 697 ms. The initial call used 291 input / 39 output tokens
and cost $0.00006705; the follow-up used 281 / 47 and cost $0.00007035.
- The Slack acknowledgements retained the assigned agent identity and
`origin: fast_response`, source-turn references, and no fabricated run
ID. A status snapshot after the initial receipt showed the task still
`in_progress` with its real execution run. The agent then read the CSV
fixture and correctly reported two ready items, two blockers, and their
owners. Both replies stayed in the originating DM, and no duplicate
generic working message followed the delivered contextual
acknowledgements. The `new` command started a fresh conversation session
without generating a fast response.
- An earlier eligible Slack turn generated a response but suppressed
publication. Its reported cost was retained, generic progress remained,
and the real agent completed the requested result. This is recorded
separately from the two delivered acknowledgements; the history did not
expose a precise suppression reason.
- Slack verification used real signed provider events, the existing
intake/publication paths, and a user-approved temporary webhook-only
HTTPS tunnel. Subscriptions were limited to direct-message events. The
test bot was paused and the tunnel stopped afterward. Live
channel/group-thread and GitHub journeys remain unverified; their mocked
tests cover intake, destination binding, publication, and continued
underlying work.
- Greptile reviewed final commit
`24016fa525961ebc7a4acffdc5019ce123970549` at 5/5. Both new review
findings are fixed and all threads are resolved. [Final-head CI
run](https://github.com/paperclipai/paperclip/actions/runs/38060015730)
passed. This includes grouped server/chat/workspace tests, serialized
suites, runner checks, browser journeys, typecheck, build, release
registry, policy, and the canary dry run.
- Manual check: enable Experimental fast responses. Open company
Settings → Connections. Select a shared API connection and model. Save
and use Test response. Submit a task message and confirm that its
receipt does not complete the task.

## Risks

- The migration adds receipt and configuration tables plus accounting
references. It uses idempotent statements and follows the current
migration sequence.
- A slow provider, authorization change, or real-agent reply can
suppress an acknowledgement. Existing progress feedback remains
available.
- Unknown provider billing retains a reservation until reconciliation.
External deliveries with uncertain outcomes must not be blindly
repeated.
- Live Slack initial-task and follow-up DM journeys pass. Live Slack
channel/group-thread and GitHub journeys remain unverified. The PR
remains a draft and records these gaps. Final-head repository CI and
automated review pass.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, repository tools, code
execution, and browser interaction. The runtime does not expose an exact
model snapshot ID or context-window size; these are not asserted.

## 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-10 13:09:17 -05:00
32745f4e84 feat(issues): keep follow-up parents and show the creation source (#15762)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents delegate work by creating follow-up tasks through the issue
API, the CLI, and the chat `create_task` tool
> - An agent can omit `parentId` when it creates a follow-up from an
ordinary execution task. The API accepts the task as a top-level task.
The task hierarchy does not show where the task came from, even though
the run provenance is recorded
> - The operator must read run history to learn why the task exists.
This is slow and it hides delegated work from the parent task
> - This pull request keeps the parent link for delegated follow-ups by
default, keeps intentional standalone tasks possible, and shows an
access-checked "Created from <task> by <agent>" note on the task page
from the recorded run provenance
> - The benefit is that each agent-created task shows its source without
log inspection, while structural parentage, provenance, and blockers
stay separate concepts

## Linked Issues or Issue Description

Refs #13241 (shows tasks created from a task on the source task page;
this PR shows the reverse direction on the created task)
Refs #9727 (open proposal for creation provenance tracking)

**What existing behavior does this improve?**

Issue creation by agent runs, and the task detail page.

**Subsystem affected**

Server (`POST /api/companies/:companyId/issues`, `GET /api/issues/:id`),
shared types, UI task detail page, CLI `issue create`, Paperclip skill
docs.

**Current behavior**

When an agent run bound to an execution task creates a task and omits
`parentId`, the task is created with no parent. The task page shows no
source. The operator must inspect the run log to find the task that the
agent was working on. The source run and the privacy parent are
recorded, but the UI does not use them.

**Proposed behavior**

- When an agent run bound to an ordinary execution task omits
`parentId`, the server sets `parentId` to that task. The `issue.created`
activity records `parentDefaultedFromRunIssue: true`.
- An explicit `parentId: null` keeps the task standalone. Conversation
runs (chat handoffs), board or user creates, watchdog follow-ups, a run
task the agent may not mutate, a default parent that would cause a
delegation cycle, and a default parent the agent may not create a child
under (for example a protected assignment policy without a grant) also
stay standalone. The server runs the same `tasks:assign` decision with
the defaulted parent in scope before it accepts the default. No request
that succeeded before now fails. An explicit `parentId` is still checked
as before.
- `GET /api/issues/:id` returns `createdFrom` with the source task, the
run, and the agent. The server resolves it from `origin_run_id`, or from
the recorded creation activity for historical rows. It returns `null`
when the viewer may not read the source task or the run, when the run is
from another company, or when provenance is missing.
- The task page shows "Created from <task> by <agent>" in the classic
breadcrumb area and in the streamlined Tasks tab. The note is not a
blocker and it is shown with or without a parent.
- The CLI `issue create` command gets `--standalone`, which sends
`parentId: null`.

**Reason and benefit**

Operators see why a task exists on the task itself. Delegated follow-ups
stay inside the parent task tree, so parent completion and child
wake-ups keep working. Private and cross-company sources stay hidden.

**Breaking changes**

None for the API schema. Agents that create tasks from a run and relied
on the omitted `parentId` to mean "top-level" must now send `parentId:
null` (CLI: `--standalone`). The skill and the spec document this.

## What Changed

- `server/src/services/issue-creation-source.ts` (new): resolves a
task's creation source from the origin run or the creation activity,
scoped to the company, and loads the run-bound task by UUID or
identifier.
- `server/src/routes/issues.ts`: `POST /companies/:companyId/issues`
defaults `parentId` to the run's task when the body omits it (with the
exclusions above) and records the default in the activity log. `GET
/issues/:id` adds the access-checked `createdFrom` field.
- `packages/shared/src/types/issue.ts` and index exports: new
`IssueCreationSource` type and the optional `createdFrom` field on
`Issue`.
- `ui/src/components/task-detail/IssueCreatedFromNote.tsx` (new),
`TaskDetailTasksPanel.tsx`, and `IssueDetail.tsx`: show the creation
source in both task page layouts and count it in the Tasks tab badge.
- `cli/src/commands/client/issue.ts`: `issue create --standalone`.
- Docs: `doc/SPEC-implementation.md`, `doc/CLI.md`,
`skills/paperclip/SKILL.md`.
- Tests: `server/src/__tests__/issue-creation-source-routes.test.ts`
(new), `TaskDetailTasksPanel.test.tsx`, `IssueDetail.test.tsx`.

## Verification

Run the new server route test (embedded Postgres):

```sh
cd server && pnpm exec vitest run src/__tests__/issue-creation-source-routes.test.ts
```

It covers: ordinary delegation gets the parent and `createdFrom`;
explicit `parentId: null` stays standalone but still shows the source;
conversation handoff and board create stay standalone; a would-be
delegation cycle falls back to standalone; a protected source task
without a grant falls back to standalone while an explicit parent still
returns 403; an explicit cycle still returns 409; historical provenance
from the creation activity; missing provenance, a private source for an
outsider, and a cross-company run all return `null`.

Related existing suites that passed locally (11 files, 313 tests):
`issue-created-from-routes`, `issue-create-deduplication-routes`,
`issue-agent-mutation-ownership-routes`, `chat-project-tools`,
`issue-assignee-invokability-routes`, `issue-watchdogs-routes`,
`issue-dependency-wakeups-routes`, `public-mcp`,
`native-runtime/task-creation-backlog`, `issue-access-grants-routes`,
`issue-list-assignee-filter-routes`.

UI:

```sh
cd ui && pnpm exec vitest run src/components/task-detail/TaskDetailTasksPanel.test.tsx src/pages/IssueDetail.test.tsx
pnpm check:token-gates
```

Manual check: as an agent run bound to a task, `POST
/api/companies/:companyId/issues` with only a title. The response has
`parentId` set to the run's task. Open the new task; the page shows
"Created from <task> by <agent>".

The related server suites pass locally (`issue-created-from`,
`issue-create-deduplication`, `issue-agent-mutation-ownership`,
`chat-project-tools`, `issue-watchdogs`, `public-mcp`,
`task-creation-backlog`, `issue-access-grants`,
`permissions-upgrade-boundary`). The full `pnpm -r typecheck`, `pnpm
test:run`, and `pnpm build` were not run locally because the sandbox has
a 4 GB memory limit and the TypeScript compiler is killed on the server
project; the CI gates on this PR cover them.

## Risks

- Behavior shift for agent clients: a run-created task without
`parentId` now becomes a child of the run's task. Clients that want a
top-level task must send `parentId: null`. The watchdog, conversation,
and board paths are excluded, and the default never adds a blocker.
- The default parent inherits the parent's execution workspace, which
run-created tasks already inherited from the run's task.
- `createdFrom` adds one run lookup, one issue lookup, one access
decision, and one agent lookup to the task detail request. It is skipped
when the task has no origin run and no creation activity with a run.
- Privacy: the field returns `null` unless the viewer can read the
source task and the run, so a private source is indistinguishable from
missing provenance.

## Model Used

Claude Fable 5.1 (`claude-fable-5-1`), Anthropic, run through Claude
Code in a Paperclip-managed execution workspace with tool use, shell
execution, and a local embedded Postgres for 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
- [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: devinfoley <139239+devinfoley@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-10 00:40:08 -07:00
DottaandPaperclip 3ec7309d91 feat(voice): add experimental Speko task connection runtime (#15727)
First PR: runtime. UI: #15728. Qualification: #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 an explicit voice transport to the existing connection
runtime.
> - The UI and qualification suites follow in linked PRs. 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 additive voice schema, shared contracts, session APIs, and
provider callbacks.
- Bind browser, inbound, and outbound sessions to an endpoint, task, and
selected agent.
- Add low-trust guest intake in an explicitly selected sandbox and keep
ordinary approval rules.
- Submit task work through session-scoped tools and push approved
replies through Speko POST /v1/calls/{id}/messages.
- Distinguish provider acceptance from confirmed spoken playback.
Reconcile reports without downloading recordings.
- Add protocol, migration, persistence, provider, and
delivery-diagnostic tests.

## Verification

- Master 3389bea708 is integrated. Database/shared builds, server
typecheck, migration upgrade/replay checks, and 46
communication-guidance/provider/protocol tests passed.
- The final persistence suite passed 85 real-database tests. Five
focused native continuation/authorization regressions passed. Five
callback ownership/rotation tests passed after the last runtime repair.
- Review repairs cover reconnect ownership, current caller authority,
duplicate delivery, multipart answers, task-page answers, guest question
handling, and saved sandbox recovery.
- A real OpenCode/OpenRouter DeepSeek task ran in Daytona and saved a
correct disk-space answer. This did not establish live-call playback.
- Full local typecheck/build passed before the final repairs; focused
typechecks passed after them. Latest-head CI runs the repository gates.
- The separate integrated browser qualification passed two journeys and
failed browser answer retrieval. The feature remains experimental. The
report in #15729 records this failure and outstanding real-provider
acceptance.
- No lockfiles are included. Speko migrations follow master as
0324–0330.

## 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-09 21:54:11 -05:00
Devin FoleyandPaperclip 1881894973 fix: prevent inbox archive deadlocks during completion (#15615)
Take a company-scoped parent lock before writing archive state and reuse the caller transaction. Preserve newer archive timestamps and attribution when a request waits, so completed tasks remain archived.

Verified with real PostgreSQL race, rollback, company isolation, concurrency, timestamp and visibility tests, independent review, full CI and Greptile 5/5.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 13:13:16 -07:00
DottaandPaperclip bf9dbd18a8 fix(runner): recover incompatible Codex models before launch (#15519)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Runner prepares and saves each task's provider configuration
before launch.
> - A sandbox image can have a supported Codex CLI that is too old for
the selected model.
> - The current version check stops that task even when the image can
run a similar model.
> - This pull request selects a compatible model before it saves a fresh
execution.
> - The task continues with a visible warning, and recovery uses the
saved effective model.

## Linked Issues or Issue Description

- Refs #15053. This fixes the same CLI and model mismatch for fresh
remote Runner tasks. It does not change subscription onboarding.
- Refs #14721. This adds a bounded startup choice for Codex CLI
compatibility. It does not add user-defined fallback chains or quota
failover.
- Related PR: #15399 added the model-specific CLI checks that this
change preserves at launch.

## What Changed

- Check the preinstalled remote Codex CLI before saving a fresh
execution that uses a model with a verified CLI minimum.
- Select the closest compatible older model in the same class, then the
stable Runner default. Consider each candidate once.
- Save the effective model before checkpoint selection. Keep the
requested agent and task settings unchanged.
- Add a task warning and a local `runner.model_fallback` run-log event
with both models and the CLI version.
- Share executable discovery with the launch verifier. Preserve explicit
artifact and install settings, saved executions, and existing artifact
checks.
- Add regression tests and document the selection and warning behavior.

## Verification

- Red: the three new provider-configuration regression cases failed
before the fix. They kept the incompatible requested model.
- Red: both rejected-probe cases failed before the review fix. They now
defer to launch verification.
- Green: targeted provider configuration, remote preflight, task
warning, and launch-verifier tests pass (680 tests).
- `pnpm -r typecheck` passes.
- [Full
CI](https://github.com/paperclipai/paperclip/actions/runs/37713759744)
passes on `eb273fc32661526d90a864b42c73a7da61dd62da`: 47 successful
jobs, including all general and serialized Vitest groups, browser
shards, Runner verification, typecheck, build, and the canary dry run.
- Local extended verification: three serialized shards pass (115
suites). HTTP route tests hit intermittent 15-second timeouts. The
authorization suite passes on rerun (130 tests). The document suite
passes on both master and the PR head in the same isolated setup (6
tests). The local general run was stopped after the equivalent full CI
matrix passed.
- `pnpm build` passes.
- Server typecheck and build pass again after the probe-error review
fix.
- `git diff --check` and `pnpm check:module-boundaries` pass.
- Example: request `gpt-6.1-sol` on Codex 0.158.0 to use `gpt-6-sol`; on
0.156.0, use `gpt-5.6-sol`. The warning names the requested model,
effective model, and CLI version.
- This PR has not been deployed to staging.

## Risks

- A fallback can have different capabilities. The task warning makes the
substitution visible. Later runs can use the requested model after the
image CLI is updated.
- Preparation adds two remote commands for models with a verified CLI
minimum. Failed or invalid version probes retain the existing launch
checks.
- This only handles known CLI and model mismatches before a fresh
provider launch. Authentication, capacity, and artifact failures keep
their existing behavior.
- No database migration is required.

## Model Used

OpenAI GPT-6 through Codex, with tool use and code execution. This
session does not expose the exact deployment model ID, context window
size, or reasoning setting.

## 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-08 04:57:26 -05:00
DottaandPaperclip fc6304dfe5 feat(runner): add experimental OpenAI Dot provider over MCP Events (#15402)
## Thinking Path

> - Paperclip manages AI agents, tasks, permissions, and execution
budgets.
> - Paperclip Runner gives each provider the same admitted task and tool
authority.
> - OpenAI Dot runs outside the local process tree and needs
asynchronous work delivery.
> - The merged MCP gateway supplies OAuth consent and signed event
delivery.
> - A personal assistant grant cannot safely stand in for an assigned
agent.
> - This pull request adds a separate Dot agent connection and a durable
Rust Runner bridge.
> - The operator can assign work to Dot and inspect its accepted work,
tool receipts, and result.

## Linked Issues or Issue Description

**Agent or provider**

OpenAI Dot, as an experimental provider of the existing Paperclip Runner
adapter.

**Why this adapter is useful**

An operator can assign normal Paperclip tasks to an existing Dot. Dot
can read its mailbox, request work on an assigned task, use admitted
task tools, and submit a result. Paperclip keeps company scope,
checkout, approvals, known budget limits, and activity attribution.

**How the agent is invoked**

A dedicated `/mcp/runner` OAuth resource pairs one Dot grant with one
agent. A signed MCP mailbox event wakes Dot. Dot explicitly accepts the
assignment. The Rust Runner owns the durable turn and operation
receipts. The first release supports self-hosted instances with a local
Runner controller.

**Additional context**

This extends the merged public MCP gateway from #14846 and the assistant
invitation and device-consent work from #14933. This also integrates the
merged assistant tool and configuration expansion in #15380. Dot retains
its dedicated agent resource and cannot receive personal configuration
permission. The public assistant connection remains a personal
connection.

## What Changed

- Add a durable Rust Dot provider and its TypeScript Runner driver.
- Add closed PRP v3 external-provider operations and native execution
input v6.
- Add company-scoped pairing, mailbox, assignment, and operation
records.
- Reuse merged browser/device consent, client metadata verification,
webhook admissions, refresh, secret rotation, and warm-standby gates.
- Keep Dot scopes, issuer, grants, event workers, and tool access
separate from personal assistant access.
- Add Dot configuration, pairing, readiness, and consent UI. Keep agent
grants out of the personal Connections entry.
- Regenerate the Dot-only migration after master. Preserve published
gateway migrations. Make the new migration safe to reapply.
- Document setup, recovery, accounting limits, evidence, and remaining
account qualification.
- Reverify reconnect callbacks and wake outstanding work with a fresh
mailbox reference; preserve the existing assignment and operation
receipts.
- Clean up Dot bindings and waiting runs on OAuth revoke and
refresh-token replay. Old grants cannot revoke replacement bindings.
- Restore the pairing reference when an unsaved agent form is reopened;
document board-only pairing routes in OpenAPI.
- Accept a clean Rust exit after the acknowledged shutdown receipt.
Unexpected exits still require recovery.
- Clear the cached binding after a successful revoke so a failed
connection refresh cannot restore it.
- Add production-component Storybook states and screenshots for pairing
and connection review. All preview account data is synthetic.
- Persist normalized completion, serialize Dot turns and durable work
admission, and poll subscription readiness.
- Serialize mailbox writes and cursor reads; retain paused fence
acknowledgement without task authority.
- Authorize admitted review runs without changing the worker assignee.
Include the fenced assignment ID in production stop notices.

## Verification

- This PR integrates master `4a8178e9c`. Dot migration
`0317_messy_famine.sql` follows the published history and is safe to
reapply. The merge preserves the reserved migration connection,
batch-commit handling, private task checks, task monitors, and native
accounting.
- Local workspace typecheck, full build, and UI token gates pass. The
server typecheck passes after the review fixes. Database and native
executor regressions pass.
- All twelve real Rust/PostgreSQL Dot integration tests and twelve Dot
driver tests pass. The tests cover native document writing and
finalization, durable replay, queue admission, mailbox ordering,
admitted reviews, stale authority, production stop references, and
paused acknowledgements.
- Current head `d0e7e0626` passes all 57 checks: 53 pass and four are
intentionally skipped. This includes full typecheck, build, tests, Rust
Runner verification, browser E2E, release verification, and Canary Dry
Run. Greptile rates this exact head 5/5. All review threads are
resolved.
- The full local root test run is slower than the sharded CI run and has
not completed. The full CI test gates pass on the current commit.
Focused local regressions pass.
- Real-account pairing and event delivery on this base commit remain
unqualified. Live account and setup proof are recorded in the follow-up
#15414.

The following screenshots use synthetic preview data. They show the
production pairing component and do not qualify a real account or the
full agent setup journey.

![Synthetic pairing
preview](https://github.com/paperclipai/paperclip/blob/codex/dot-events-prototype/doc/screenshots/openai-dot-runner/pairing.jpg?raw=true)

![Synthetic connected
preview](https://github.com/paperclipai/paperclip/blob/codex/dot-events-prototype/doc/screenshots/openai-dot-runner/connected.jpg?raw=true)

## Risks

- This base adapter uses `PAPERCLIP_ENABLE_OPENAI_DOT=1` plus Public MCP
and Paperclip Runner. The separate experimental-settings follow-up in
#15414 replaces this environment flag with saved operator settings.
- Dot does not expose provider token usage or cost. The operator must
acknowledge external billing. Known Paperclip budget gates still apply.
- Cancellation fences Paperclip authority. It does not confirm that Dot
stopped all external activity.
- Assigned skill files and third-party MCP bindings are unsupported and
reject admission. There is no mounted workspace, model selector, or
provider thread identifier.
- Hosted agent-broker and remote controller deployments are not
qualified.
- The new migration follows the merged master history. Existing
prototype databases still need the normal master migration history
before this Dot-only migration.

## Model Used

OpenAI Codex, based on GPT-6. The exact deployment ID and context window
size are not exposed in this session. Capabilities used: reasoning,
repository editing, code execution, and test inspection.

## 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 #123` 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 references)
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-07 19:11:50 -05:00
DottaandPaperclip a7a244ab33 feat: add company decision models with permission and cost controls (#15473)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Optional product features need small, typed model decisions.
> - Each company needs to choose which shared API connection pays for
those decisions.
> - Calls must retain user and task permissions, budget limits, and cost
attribution.
> - This pull request adds a managed decision service, setup UI, and
request history.
> - Features can check availability cheaply and keep their existing
behavior when decisions are unavailable.

## Linked Issues or Issue Description

**Subsystem affected**

Server services, shared contracts, database accounting, Company
Settings, and Costs.

**Problem or motivation**

Paperclip has no common decision-model service. Adding provider calls
within each feature would duplicate credential access, permission
checks, and billing rules.

**Proposed solution**

Let a connection manager configure one company decision model. Support
OpenAI Decisions and Jev through OpenRouter. Provide a fixed setup test
and metadata-only history. Default company-sponsored background
decisions to on during setup, and preserve a saved off setting.

**Alternatives considered**

Per-feature credentials would duplicate existing connection management.
Personal overrides and provider fallback chains add permission and
billing complexity; they remain deferred.

**Roadmap alignment**

Reviewed ROADMAP.md and searched open PRs. This extends existing
connection access and budget accounting. Product features that call the
service remain outside this change. No matching decision-model service
PR was found.

## What Changed

- Add company settings, an internal `decisionModelService`, local
availability checks, and trusted human, agent/run, and system contexts.
- Pin Vercel AI SDK provider dependencies and adapt boolean, choice, and
ordered-score decisions for both providers. Bound requests and time;
disable paid retries.
- Add durable invocation metadata and agentless decision ledger charges.
Preserve fractional cents, pricing evidence, dispatch identity, and
unresolved billing holds.
- Share the company accounting lock and apply company, agent, and
project budgets. Settle charges once, retain unknown holds, and recover
interrupted calls without resubmission.
- Reuse connection setup and management UI. Add a Decisions view under
Costs, production-component Storybook coverage, database migration, and
service documentation.

## Verification

- Passed 166 current-code tests covering the decision service/provider,
setup component, Costs, OpenAPI, and every failure from the earlier
broad run. Coverage includes native SDK wire formats, refusals, billed
malformed responses, permission and secret-rotation races, identity
changes, concurrent budget admission, unresolved holds, agent/task
deletion, and stale setup feedback.
- Passed 170 existing connection, cost, budget, heartbeat-accounting,
and profile regression tests.
- Passed repository typecheck, production build, and design token gates
after integrating master. Verified the generated migration on a fresh
test database and upgraded the populated preview database from the
branch's earlier migration without losing settings or usage.
- Ran the required full `pnpm test:run`: its general phase completed
with 16,354 passed and 10 failures across five files while this branch
was still being updated. Every reported failure passes in the
current-code rerun; the serialized phase did not run after that failure.
The full GitHub CI suite passed on `b1b856a88`: general and serialized
tests, browser shards, runner checks, typecheck, production build,
packaging/canary, and policy gates. [CI
evidence](https://github.com/paperclipai/paperclip/actions/runs/37673106360).
- Passed the full-shell Storybook setup-to-history interaction test
again after integrating master. Greptile rates the final revision 5/5
with zero unresolved threads.
- Walked through the running app: empty setup, add each provider, save,
reload, run all three sample questions, inspect fractional charges in
history, switch provider while sponsorship is off, disable, and
reconnect. Checked mobile settings. These tests used the actual UI,
vault, server, SDKs, and database with simulated upstream responses.
- Live paid setup tests remain unverified: this environment has no
authorized OpenAI/OpenRouter credentials available. No mocked test is
presented as live provider evidence.

Reviewer journey: Company Settings → General → Decision model.
Add/select a shared API connection, save, run the billed sample, open
View usage, then disable decisions and verify Run test is disabled after
reload.

## Risks

- The SDK decision interface is experimental. Pinned versions and
wire-format tests limit upgrade drift.
- The migration allows agentless service charges and reservations.
Existing agent cost-reporting APIs still require an agent, and decision
receipts stay separate from run reconciliation.
- Timeouts can have unknown provider charges. Holds remain until an
audited accounting correction resolves them.
- OpenAI prices use a versioned Decisions rate snapshot; OpenRouter
costs use provider receipts. Unknown pricing is retained as unknown.
- A configured company authorizes background spending by default. Setup
explains this, and managers can turn it off.
- Live provider account/model availability still needs the two
credentialed acceptance checks.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository inspection, code
execution, and browser tools. The exact serving revision and
context-window size 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-07 15:53:13 -05:00
DottaandPaperclip fd8c6b920a fix(native): resume connection tasks after approval decisions (#15471)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native tasks can pause while a human decides whether to allow a
connection action.
> - The next turn needs both the saved decision and complete accounting
for the previous turn.
> - Cancellation could discard final usage, and complete direct Claude
API receipts could remain unpriced.
> - A stale blocked or review report could also request approval again
after the original card was declined.
> - This pull request retains shutdown accounting and rejects approval
waits bound to an already resolved action.
> - The benefit is reliable continuation with the existing budget and
approval controls.

## Linked Issues or Issue Description

Refs #15420. Related: #15312 addresses requester ownership during
dispatch. This change addresses receipt capture and final-response
validation.

## What Changed

- Retain usage events after native cancellation. Continue to reject late
provider messages and work.
- Drain same-turn accounting and terminal events for at most fifteen
seconds after a durable governed wait. Keep incomplete accounting
blocked.
- Estimate complete, unpriced, direct Anthropic API receipts for the
exact `claude-sonnet-5` model. Record the rate version and assumptions.
Use the one-hour cache-write rate when the receipt lacks cache TTL.
- Bind stale approval reports to exact interaction, action-request, or
invocation IDs in the same company, task, agent, and run. Cover blocked,
review, and response-wake reports. Keep independent reviews valid.
- Fence checkpoint and result writes after a controller detaches for
restart, including operations waiting for a database lock. Reject stale
successful returns before certifying accounting.
- Allow bounded subscription teardown only after retaining an actual
provider terminal.
- Journal the exact governed-wait trigger and disposition before
provider interruption. Recover that wait independently of a later saved
answer, replay retained accounting, and reject mismatched or unproven
terminal evidence.
- Give settling governed turns a bounded window before shutdown detaches
their controller.
- Keep fuzzy external app matches alongside installed capability matches
instead of forcing an unrelated provider question for a generic query.
- Return up to twenty exact active catalog tool names after an invalid
request, after eligibility checks; still reject the request without
granting access or creating an approval.
- Require retained provider terminal proof before settling a governed
wait, including when complete usage arrives before stream
closure/error/timeout. Retain harmless numbered cancellation events so
restart replay stays contiguous.
- Isolate accounting-test OpenCode config from the host plugin
directory.
- Add regression coverage and document the accounting, restart and
connection-search behavior.

## Verification

Current PR source: `0cf08efd75f8fb23f7989beda6dbda92587088bf`. The live
matrix below measured frozen `09a776bcb1f77422156f8be11e13f8c29f43e7f7`;
later review fixes are verified separately and do not relabel those
runs.

- Repository typecheck and build pass.
- Current runner runtime and cancellation suites: 191 tests pass. Six
new regressions cover stream end/error/timeout without provider-stop
proof and contiguous cancellation acknowledgement/request replay; all
six failed before the fix. The existing bounded cleanup case now
explicitly supplies terminal proof. All 31 adapter accounting tests pass
with isolated fixture config.
- New checkpoint-rebinding and approval-criterion suites: 65 tests pass;
runner HTTP integration: 29 tests pass. Unchanged executor/control-plane
suites: 640 tests pass; database-backed connection suites: 68 tests
pass.
- Current retained evidence verification covers 222 file hashes across
all fifteen original result artifacts. The three-case [published
report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37651896525-1/index.html)
and all eight screenshot hashes verify. The [three-case recovery
report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37662587356-1/index.html)
and all six screenshots also verify; the nine-result campaign did not
publish.
- Evaluation support: 1,805 Vitest tests pass, one skipped; 128 Node
tests pass. Eval typecheck and catalog discovery pass.
- Full local repository unit run was interrupted before the follow-up
edits after three tool-access failures and one runner HTTP failure.
Those failures pass in isolation; the 09a full run was interrupted after
one rapid Slack callback-ordering failure and seven skill-service
failures. All eight pass both isolated and with full-runner environment
settings, and all 74 skill-service tests pass together; the subsequent
full run reported two 15-second OpenCode accounting timeouts and was
stopped with exit 130 to apply review fixes. The timeouts reproduce
while copying this host’s 61 MB OpenCode config. All 31 tests pass after
isolating config inside each fixture without increasing timeouts or
changing assertions. A complete local full-suite pass is not claimed.
Repository-wide CI also passes on the final review-fix head in [run
37669185952](https://github.com/paperclipai/paperclip/actions/runs/37669185952).
Earlier database-skipped diagnostics and the older ENFILE run are
retained and are not full-suite passing evidence.
- Three-case live campaign
[37651896525](https://github.com/paperclipai/paperclip/actions/runs/37651896525)
passes all three original grades on frozen source 09a: 55/55 checks,
eight succeeded run records, complete accounting receipts, matching
checkpoint identities and no pending approvals. Campaign
[37653533353](https://github.com/paperclipai/paperclip/actions/runs/37653533353)
adds nine original passes (173/173 checks, eighteen succeeded records)
on the identical source. Its other three jobs failed before runner
assignment or any step while GitHub could not load the paid environment;
those original infrastructure failures are retained. Campaign
[37662587356](https://github.com/paperclipai/paperclip/actions/runs/37662587356)
completes only those unstarted cells: all three original grades pass
(57/57 checks, six succeeded run records). All fifteen exact cases now
pass on source 09a: eight FAIL → PASS, seven PASS → PASS, zero new
overall failures and zero pending pairs. Total current evidence: 285/285
checks and thirty-two succeeded run records, complete accounting
receipts, matching checkpoint identities, no pending approvals or retry
records. Earlier campaigns retain forty-seven additional run records and
two known same-run recovery attempts; actual provider-call counts and
invoices remain unknown. The nine-result campaign skipped publication
and its public URL returns 403; original artifacts remain retained.
Previous ba9 campaign
[37645656840](https://github.com/paperclipai/paperclip/actions/runs/37645656840)
completed 2 PASS / 1 FAIL: Claude restart/approval and Codex decline
pass, while OpenCode resumes but times out searching for exact tool
names and never creates the access card. That failure and incomplete
cancelled-run accounting remain preserved; the new catalog error
guidance targets this observed dead end. Campaign
[37642957312](https://github.com/paperclipai/paperclip/actions/runs/37642957312)
remains 0 PASS / 3 FAIL and exposed the now-corrected cross-run marker
leak and unknown-criterion approval gap. The original baseline remains 7
PASS / 8 FAIL, first repair 2 PASS / 3 FAIL, and second repair 0 PASS /
3 FAIL. All fifteen selected cases are qualified by their original
grades in this bounded trial. These live grades belong to 09a. Its
twelve governed-wait checkpoints retain matching same-turn terminal
fingerprints, but passing artifacts omit detailed event journals; the
later six adversarial regressions qualify the new terminal-proof and
replay guards separately. Final-head repository CI passes. [Fresh
Greptile
review](https://github.com/paperclipai/paperclip/pull/15471#issuecomment-6044369780)
is 5/5, confirms both findings are fixed, and reports no new actionable
issues. All review threads are resolved and the PR has no merge
conflicts.

## Risks

- Governed cancellation drains accounting for up to fifteen seconds.
Restart detachment gives a settling batch up to twenty seconds to
finish. An incomplete receipt or unproven provider terminal still
prevents successful qualification.
- Claude prices are estimates, not invoices. The estimate assumes
standard global API pricing and uses a conservative cache-write rate.
Unsupported models, billers, and billing modes remain unpriced.
- Approval identity matching must remain scoped to the current run and
the requested approval. It does not authorize execution of a declined
call.
- Original baseline and final candidate have different merged master
context. Exact-case outcomes are before/after observations, not isolated
causal attribution to this repair.
- No schema migration, fixture, oracle or grader change. Search-result
guidance now treats fuzzy external matches as suggestions. Existing app
authorization and provider-consent checks remain required.

## Model Used

- OpenAI GPT-6 through Codex, with code editing, terminal tools, and
test execution. The exact deployment identifier 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
#` 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 (191 current runtime tests
and 31 accounting tests; interrupted full-suite history and CI coverage
are disclosed above)
- [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-07 14:43:07 -05:00
DottaandPaperclip ae6f95ed7a feat: add personal primary agents (#15470)
Add a personal primary agent per company and user. Initialize it from the first human-created agent, expose profile-only switching with confirmation, and use it after recent choices for task and Chat defaults.

Persist authenticated preferences, preserve lifecycle and membership rules, keep selections out of shared audit events, and document the API contract. Include the reviewed Storybook surfaces and regression coverage for concurrent choices, onboarding, cross-device updates, and browser journeys.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-07 13:53:46 -05:00
DottaandPaperclip 1640c5b6ab feat(ui): render HTML artifacts in a secure sandbox (#15447)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents deliver reports as task attachments and workspace files.
> - The board already renders Markdown, but it shows HTML reports as
source or rejects their preview.
> - Reports can need inline scripts to build charts and tables.
> - Artifact scripts must not read board cookies, storage, or the parent
page.
> - This pull request adds an opaque-origin HTML preview and view
controls beside Download.
> - Users can explore a report, inspect its source, and download the
original file.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The task attachment panel and workspace file viewers.

**Subsystem affected**

ui/ and the server workspace file preview service.

**Current behavior**

HTML attachments show source text. Workspace HTML files cannot be
previewed.

**Proposed behavior**

Render self-contained HTML reports in a sandboxed iframe. Place eye and
code controls beside Download. Preserve the original file for raw view
and download.

**Reason and benefit**

Users can read and filter agent reports in Paperclip without giving
artifact scripts access to the board session.

**Breaking changes**

HTML previews now open rendered. Scripts and styles must be embedded in
the report. Remote resources, API requests, forms, popups, and host
navigation are blocked. Workspace HTML content uses the existing bounded
UTF-8 JSON response.

**Additional context**

Related closed proposals: #3293 and #4857. This change uses the current
attachment and workspace viewers and adds no report-serving endpoint.
The Artifacts and Work Products roadmap item is complete; this improves
its existing preview behavior.

## What Changed

- Add a shared HTML iframe renderer with `sandbox="allow-scripts"` and
no `allow-same-origin`.
- Install a restrictive CSP before artifact markup. Keep inline report
scripts and styles.
- Add shared rendered/raw icon controls beside Download in the
attachment panel, workspace panel, and file sheet.
- Return workspace HTML as bounded text inside JSON. Keep download and
path-access protections.
- Add Storybooks for reports, security probes, workspace viewers, a task
journey, and mobile layouts.
- Document the security boundary and browser test command.

## Verification

- `pnpm -r typecheck` and `pnpm build` pass.
- Token gates and the static Storybook build pass.
- Four browser tests pass. They cover report filters, raw mode, task
entry, workspace viewers, cookies, storage, host DOM, resource requests,
forms, popups, and host navigation.
- The focused UI suite passes 26 tests. The file-resource server suite
passes 36 tests.
- Local full-stack acceptance passes with an actual 52 KB HTML report.
Its chart and filter render. Raw mode preserves the source. Download
bytes match the original file.
- The complete local UI suite passes: 698 files and 7,754 tests.
- `pnpm test:run` was attempted. Its server group recorded two unrelated
timeouts and eight connector failures. All failed cases pass in isolated
reruns, including the complete 388-test connector suite. The remaining
local run was stopped after the full CI test coverage passed, to release
test database resources. The full local command did not complete
cleanly.
- The separate local CLI group passes 511 tests. Three worktree database
cases fail to start embedded PostgreSQL because this Mac has exhausted
its shared-memory allocation. One isolated rerun fails at the same
database startup step. No CLI code was changed. The corresponding CI
test jobs pass.
- All 56 PR checks are clean on
`c771255f1a2e86bd8825f22eafb5d14a5e342cce`. Greptile gives 5/5 with no
actionable findings. The security scan passes. The branch has no merge
conflict.
- Review the **HTML artifacts** section in Storybook. Run `pnpm exec
playwright test --config tests/html-preview/playwright.config.ts` for
the browser checks.

## Risks

- Never add `allow-same-origin` to this iframe. Its opaque origin is the
cookie, storage, and host-DOM boundary.
- Reports that depend on CDN assets need to embed their dependencies.
- The frame can navigate itself. Sandbox restrictions remain after
navigation. This is not full network isolation.
- Inline scripts can consume browser resources. This change does not
isolate CPU or memory use.
- No database migrations or API shape changes are required.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, repository editing, code
execution, and browser tool use. The runtime does not expose a more
specific 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 — feature and UI checks
pass; the full local run has the infrastructure limits recorded above.
All CI test jobs 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-07 09:01:05 -05:00
DottaandPaperclip 3a726e676f feat: enforce private task permissions across execution and data (#10633)
Enforce private task and project access across direct reads, search, execution, files, plugins, live delivery, and sharing mutations. Preserve downward-only sharing, current responsible-user authorization, and audited emergency access. Bind historical draft assets with migration 0314.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-07 07:06:40 -05:00
DottaandPaperclip faa8e452c7 fix(tasks): stop repeated reminders for historical questions (#15392)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task questions remain saved so a person can answer them later.
> - The composer moves an old question into history after a newer human
message.
> - Native completion still treated every pending question as a required
response.
> - This caused agents to demand an old answer after the person moved
work forward.
> - This pull request shares the historical-question rule across context
and task execution.
> - Agents can finish verified work while the original question remains
answerable.

## Linked Issues or Issue Description

Refs #15229, Refs #14613, Refs #13130.

**What happened?**

An agent repeatedly asked a person to answer a question that had moved
into feed history. Completion feedback explicitly told the agent to
request a response. The saved pending row also blocked task completion.

**Expected behavior**

A question before newer human direction remains answerable in the feed.
Its pending state alone must not require another reminder or stop
completed work. A new input blocker, an approval, or a configured review
stage must keep its gate.

**Steps to reproduce**

1. Let a task agent create an ordinary question.
2. Dismiss the question and send a newer task message.
3. Let the agent finish the requested work and submit its completion
report.
4. Observe a demand to answer the old question and a retained completion
gate.

## What Changed

- Add one company-scoped predicate for historical questions. Only later
human comments count. Exclude agent attribution, run attribution, system
notices, and untrusted source data.
- Apply the predicate to completion feedback, native waits,
finalization, commit validation, retry validation, blocked routing, and
successful-run handoff.
- Include question classification and guidance in heartbeat context and
both native task-context tools. Add the guidance to fresh and resumed
task prompts.
- Replace automatic reminders for current ordinary questions with
instructions to assess the real blocker, continue independent work, and
withdraw obsolete questions through the existing API.
- Preserve historical question rows during completion while cancelling
their live native source runs through the existing post-commit and
recovery paths. Let an authorized human answer them after completion
without reopening work or creating a response wake. Preserve
cancellation, current-input, approval, permission, credential,
connection, and review gates. Add no dismissal storage or migration.
- Document the rule in the execution contract and agent skill. Refresh
generated capability source anchors. Add database-backed status,
context, attribution, and governance regression tests.

## Verification

- `pnpm build` passed. The server rebuild also passed after the
lifecycle fix. Generated capability contract and inventory checks passed
after the agent documentation update.
- `pnpm -r typecheck` passed. Final `pnpm --filter @paperclipai/server
exec tsc --noEmit` also passed after the last test additions.
- Lifecycle and interaction regressions passed: 224 tests in 3 suites.
Context and prompt tests also passed. Final historical-question cases
passed (33 tests), native cancellation/recovery cases passed (6 tests),
and the existing interaction/confirmation suites passed (72 tests). The
full local `pnpm test:run` was attempted and stopped after more than two
hours with unrelated fixture/hook timeout failures; it did not pass. All
52 successful GitHub checks are green on the latest commit, including
the complete test matrix; no checks are pending or failing. Greptile is
5/5 and both review threads are resolved.
- Regression cases cover the old-question/new-human-message sequence,
final task status, answering after completion with no wake, live-run
cancellation and crash recovery, current input blockers, both
task-context tools, API context, timestamp precision, attribution
boundaries, and protected gates.

## Risks

- A later human task message makes an earlier ordinary question
historical even if its input is still missing. The agent must identify
the current blocker and ask only for information that still prevents
work.
- Browser dismissal remains a local preference. Dismissal without a
later human message is not recorded by this change.
- No schema change or data migration. Completion retains ordinary
historical questions; cancellation still expires them. A completed task
accepts historical answers only from an authorized human and creates no
response-delivery outbox row. Governed requests retain their gates.

## Model Used

OpenAI Codex, GPT-6, with repository editing, code execution, and
browser diagnostics. The exact deployment model ID and context-window
size 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-06 20:33:13 -05:00
DottaandPaperclip b508a05c43 feat: add internal agent complaints and suggestions (#15367)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents use legacy skills or native runner tools to work on tasks.
> - Those agents can encounter friction that does not belong in the task
thread.
> - A complaint should preserve the raw reaction. A suggestion should
describe an improvement.
> - This pull request adds attributed local storage and both submission
paths.
> - Agents can submit feedback once and continue their primary work.

## Linked Issues or Issue Description

**Subsystem affected**

Server, database, shared contracts, runtime skills, and native runner
tools.

**Problem or motivation**

Agents have no default internal channel for incidental complaints and
suggestions. Sending this feedback through task comments adds noise and
can alter task workflows.

**Proposed solution**

Store free-form feedback in the current instance database. Derive agent,
run, company, and task attribution from active authority. Provide
default legacy skills and provider-neutral native actions. Keep the
instructions close to Warp's MIT-licensed originals.

**Alternatives considered**

Task comments and external Slack delivery add unwanted side effects.
Mandatory suggestion fields and short editorial limits would discard
useful feedback. This release has no listing API, UI, read tool,
automatic triage, or external forwarding.

**Roadmap alignment**

This is a maintainer-requested addition to the existing runtime skills
and runner tool paths. It does not duplicate a listed roadmap milestone.
Searches for complaint tooling, suggestion-box, and agent commentary
found no overlapping public PR or issue.

## What Changed

- Add the company-scoped `agent_commentary` table, shared validation,
and idempotent migration `0310`.
- Add one transactional service and the agent-only POST route. Validate
active authority before writes or replay. Redact known credentials.
Commit a content-free audit with each new record.
- Add `submit_complaint` and `submit_suggestion` to standard, ask, and
planning modes. Keep review, revocation, and completion restrictions.
Store replay identity on the commentary row.
- Mount `complain` and `suggestion-box` by default for legacy agents.
Bundle a dependency-free Node.js stdin helper in the operational skill
and allow its POST through the sandbox bridge.
- Preserve Warp's complaint voice and suggestion guidance, with
attribution and local transport adaptations. Keep source attribution and
MIT notices in each skill's LICENSE, outside runtime instructions.
- Document custom-runtime HTTP use and database inspection. Add
real-database tests and a repeatable live Codex smoke for local and
Daytona execution.
- Pin the lagging-source migration fixture before the identity-repair
migration so later migrations preserve its regression coverage.

## Verification

- Personally ran real Codex submissions in all four environments on
2026-10-06. Local runs passed at 20:35 UTC. Daytona native passed at
20:31 UTC; Daytona legacy passed at 20:33 UTC. Each stored exactly two
rows with company, agent, run, and task attribution, wrote the
continuation marker, exited zero, created no task comments, and left
task status unchanged. Each recorded two content-free activity entries.
- Daytona used production provider hooks, real remote execution and file
transfer, the legacy queue callback bridge, and native private WebSocket
ingress. The current Linux runner was built from `abf47b595`, staged,
and verified against controller contracts. Both sandboxes were confirmed
deleted. This is a focused feedback transport smoke; it does not claim
full Runner E2E catalog or browser qualification.
- The immutable base image and Linux binary digest are recorded in [the
verification
documentation](https://github.com/paperclipai/paperclip/blob/codex/agent-commentary/doc/agent-commentary.md#verification).
The smoke script can save content-free JSON evidence. No credentials or
feedback bodies are in these reports.

| Environment | Runner | Complaint row | Suggestion row |
| --- | --- | --- | --- |
| local | legacy Codex | `59413a00-1de2-4bb1-bcc6-9c4b54c64aa6` |
`3db2364d-3e15-4f47-846f-875d3902999d` |
| local | native Codex | `5da22b5f-41df-4de5-8ba0-d9345ab01267` |
`2d5abe17-dd41-403c-a5ee-4729f2d58921` |
| daytona | legacy Codex | `27c9d0aa-8477-409f-9da0-e8ffa48dee50` |
`209681c9-d1e9-4ce1-999e-48fa07692389` |
| daytona | native Codex | `6eb001bb-4bcf-43f7-8717-f662f53dc7c3` |
`77c383d8-a997-49e5-a33e-25c70e15c0b2` |

- Run the local check with `node cli/node_modules/tsx/dist/cli.mjs
server/scripts/verify-agent-commentary-live.ts`. The documentation gives
the Daytona invocation. Both use disposable instance databases and
normal Codex provider usage.
- Repository `pnpm -r typecheck` and `pnpm build` passed after the test
extension. The build includes runner generation, contracts, and replay
checks. The smoke scripts also passed a separate TypeScript check. The
lagging-source migration regression passed. All equivalent current-head
Vitest CI shards passed. The local monolithic `pnpm test:run` invocation
was stopped after CI supplied that coverage; it did not complete
locally.
- Focused tests cover company isolation, spoofing, revoked credentials,
stale ownership, post-finish rejection, concurrent replay, conflicting
keys, atomic rollback, and deletion through existing services. Boundary
tests cover empty text, Unicode, text beyond 8,000 characters, and the
524,288-character ceiling without truncation. Mounting tests cover
Codex, Claude, and sandbox staging. Helper tests cover standalone Node
execution, stdin, invalid UTF-8, redirects, HTTP failure, and its
deadline. Privacy and bridge tests cover successful and rejected
requests.
- Instructions were compared with Warp's originals. MIT notices and
source credits live only in LICENSE files. Native tools preserve
truthful disclosure when asked, without routine announcements.
- [Full
CI](https://github.com/paperclipai/paperclip/actions/runs/37508559190)
and Greptile 5/5 passed on the earlier feature commit `5209c3501`. The
later head found the migration-fixture assumption fixed in this update.
On `8a4965164`, all 55 check contexts passed after one browser shard
rerun. Its initial reviewer signoff failure also passed an isolated
local browser run (1 test). Greptile scored that head 5/5 and identified
one smoke cleanup gap. `6ecbafb0b` fixes failed-acquisition cleanup with
four passing tests and a passing smoke-script typecheck. Fresh CI is
pending for this final test-only fix. No commentary production code
changed during verification.

## Risks

- Feedback is internally attributed. It is not anonymous. Existing
redaction removes known credentials, but agents must still omit
sensitive content. Normal provider transcripts can include their
submitted arguments.
- Default skill availability changes for existing legacy agents. Runtime
policy filtering still applies. The helper uses the existing Node.js
runtime with no extra dependencies; custom runtimes can call the HTTP
endpoint.
- Feedback is removed with its run, agent, or company. Task deletion
clears only the issue pointer. Normal database backups include the
table.
- The migration is additive and has no backfill. Writes serialize on the
active run for replay consistency. No server suggestion quota is
imposed.

## Model Used

OpenAI `gpt-6-astra` through Codex, with `xhigh` reasoning effort and a
reported 258,400-token context window. Capabilities used: repository
inspection, code execution, and live runtime verification. No subagents
were used.

## 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-06 16:14:06 -05:00
DottaandPaperclip 582911ba74 fix(access): give Operators default company editing permissions (#15377)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Human company members receive permission grants from their role
preset.
> - Human invitations use the Operator role by default.
> - The old Operator preset only granted task assignment, so ordinary
members could not edit agents or manage connections.
> - This pull request gives Operators company editing and audit access
while keeping join approval and member-permission management separate.
> - Members can configure their agents and accounts without an Owner
role.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The default permission grants for human Operators and the invitation
role description.

**Subsystem affected**

server/ permission presets and invitation authorization, plus ui/
invitation and tool access gates.

**Current behavior**

Operators receive only `tasks:assign` as an explicit default grant.
Agent configuration and managed account setup fail their permission
checks.

**Proposed behavior**

Operators receive agent creation/configuration, skills, environments,
invitations, task assignment, pipelines, connections, tool
management/use, and audit grants. The preset excludes `joins:approve`
and `users:manage_permissions`. Operators can invite Operators and
Viewers. Inviting a role with either excluded power requires that power,
so invitations cannot bypass the restriction.

**Reason and benefit**

Ordinary company members can edit company work and connect accounts
through the existing routes.

**Breaking changes**

The Operator preset grants more permissions. The existing startup and
Cloud sign-in seeding paths can insert these missing grants for existing
Operators. They retain custom grant scopes. Explicit invitation grants
still take precedence. Inviting Admins now requires join approval;
inviting Owners also requires member-permission management. This PR adds
no migration or new backfill path.

Related: #5945 describes missing role grants in another membership entry
point. This PR changes the preset and does not change that endpoint.

## What Changed

- Expanded the Operator preset to 14 company editing, invitation, tool,
and audit grants.
- Kept join approval and member-permission management out of the preset.
- Required those powers when an invitation's selected human role
includes them, preventing Operators from delegating the excluded powers
through Owner/Admin invitations.
- Updated the invitation role copy and the product specifications.
- Allowed active Operators (including legacy Member roles) through the
invite shortcut and advanced tool/profile UI gates. Kept inactive
memberships, Viewers, and other companies excluded; API grants remain
authoritative.
- Added tests for the default Operator grants, both excluded actions,
agent editing, company boundaries, and invitation role authorization.
- Simplified adapter-route test imports so authorization errors and the
error handler use one module graph; retained the upstream
mock-initialization fix.
- Kept Owner/Admin/Viewer presets and explicit invitation grants
unchanged. Added no EE code or database migration.

## Verification

- Permission and invitation tests: 38 passed across access service,
invitation defaults, and invitation creation routes.
- UI access tests: 61 passed across invitation shortcuts, Operator
tool/profile access, and invitation UI.
- Adapter route tests: 15 passed after resolving the upstream test setup
conflict.
- `pnpm -r typecheck`, `pnpm build`, and `pnpm check:token-gates`:
passed on the final branch.
- The initial local `pnpm test:run` general-server batch reported three
tool-access failures and eight upload-helper timeouts. Both complete
affected suites passed in isolation on the final branch: 403 tests. The
initial full local run was not green.
- Both complete tool-access and adapter route suites also passed on an
untouched snapshot of base `88ff98b83`: 387 tests. The earlier tool
failures did not reproduce there.
- [All CI gates
passed](https://github.com/paperclipai/paperclip/actions/runs/37527422346)
for `068be153b9c2a064f2aaccc0627fdf458e73747e`, including the previously
failing serialized adapter lane, general tests, E2E, typecheck, build,
Runner checks, and canary dry run.
- Greptile scored that exact commit 5/5. Superagent passed. Both
invitation review threads are resolved.

## Risks

- Operators gain broad company editing and invitation access by design.
- Existing default seeding can add the new missing grants during startup
or Cloud sign-in. It does not replace existing scopes.
- Company boundaries and the two excluded permission checks still apply.
- An Admin without member-permission management can no longer invite an
Owner. Operators retain invitation access for Operator/Viewer roles and
agent-only invites.
- This PR changes company permissions. Cloud workspace invitation rules
remain separate.

## Model Used

OpenAI Codex, GPT-6. The exact deployment model ID and context window
were not exposed in this session. Used repository inspection, code
editing, shell execution, and test tools.

## 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 a merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-06 15:55:38 -05:00
DottaandPaperclip 2ca0d26a99 fix(connections): recover missing personal AI credentials in chat (#15376)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-06 15:36:01 -05:00
DottaandPaperclip a590ab769d Give managed agents persistent cryptographic identities (#15352)
Give agents persistent Ed25519 identities encrypted with the existing instance master key. Create keys transactionally for new agents and lazily before supported managed runs, expose public identities in the API and agent UI, and protect private material during runtime delivery and output persistence.

Preserve identities in recovery backups while giving imported and development-cloned agents fresh keys.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-06 13:57:03 -05:00
DottaandPaperclip e34abee670 feat(mcp): connect assistants to a team with user OAuth (#14846)
## Thinking Path

> - Paperclip gives teams durable tasks, agent execution, budgets, and
approvals.
> - People also use assistants in Codex, Claude, and other MCP clients.
> - Those assistants need a scoped connection that preserves the
person’s permissions and attribution.
> - Delegating a task must not turn the assistant into the assigned
agent.
> - This PR adds opt-in user OAuth, ten first-party tools, browser
consent, and workflow packages.
> - Paid product evals verify the resulting tasks, documents,
attribution, retries, and access boundaries.
> - The team keeps working after the assistant conversation ends.

## Linked Issues or Issue Description

**Problem or motivation**

A person cannot connect an external assistant to an existing team
through browser consent and safely delegate durable work as themselves.

**Proposed solution**

Expose an opt-in `/mcp/paperclip` endpoint with individually described
first-party operations. Bind every connection to a person, client,
company, resource, and scopes. Reuse domain authorization and
scheduling. Package shared team-review, delegation, and follow-up
workflows for OpenAI/Codex and Claude.

**Alternatives considered**

Related PRs #9393 and #12549 cover earlier remote MCP and board-operator
approaches. This change uses user OAuth and a bounded public catalog. It
does not expose a generic executor, operator administration, static
shared board credentials, or external agent execution. Registry listing
work in #9851 is a separate distribution step.

**Roadmap alignment**

This maintainer-requested implementation extends the governed MCP
gateway, activity attribution, durable work products, and hosted
deployment direction in `ROADMAP.md`. It implements the first release of
the saved design plan; external agent participation and granted
third-party tools remain later releases.

## What Changed

- Add MCP 2.0 discovery and task status/comment/document Events on the
same authenticated endpoint. Persist subscriptions and delivery
receipts, verify HTTPS callbacks, sign Standard Webhooks, encrypt
callback material, recheck permissions/Cloud membership, and bound
retries/expiry. Older MCP clients keep their existing tools.
- Add discovery, dynamic client registration, S256 PKCE, resource
validation, rotating refresh tokens, revocation, and company consent.
Store credentials as hashes and recheck membership at execution.
- Add tools for connection identity, agents/projects, task
search/read/create, human comments, documents/deliverables, and
pending-approval links. Preserve current domain permissions and
scheduling.
- Add durable mutation receipts across reconnects. Matching retries
replay results; uncertain outcomes keep the same request ID and require
inspection.
- Add consent and connection-management pages, OAuth log redaction,
shared plugin workflows, and separate OpenAI/Codex and Claude package
outputs.
- Add eight paid Product E2E cases across three models, independent
durable-state grading, usage evidence, cleanup, and report integration.
Add task-document guidance and regenerate the runner capability
inventories.
- Add migrations 0301 and 0302, the dated implementation plan, result
notes, and direct-client setup instructions in `doc/public-mcp.md`.

## Verification

- Merge integration `e180b1948`: resolved conflicts with current master,
preserved both eval registries, regenerated capability catalogs, and
regenerated migrations as 0301/0302 while keeping the original
replay-safe SQL byte-identical. Local migration safety/snapshot tests
(26), MCP/OAuth tests (38), redaction/OpenAPI tests (71), and eval
catalog/grading tests (198) pass. Token and capability gates pass. Full
recursive typecheck passed. Fresh Greptile review is 5/5 with no
unresolved findings. CI is green on this exact head (55 successes, two
intentional skips, one neutral result): one unchanged Cursor sandbox
test timed out at 10 seconds, then passed locally in 856 ms. A single
retry of that failed shard and the aggregate workflow passed. Merge
remains blocked on the repository code-owner approval rule.

Earlier checks passed at `6aa0962d4fb715f2190bb7bb22efacab2e58495d`: 55
successes, two intentional skips and one neutral result. [The earlier CI
run](https://github.com/paperclipai/paperclip/actions/runs/36901592350)
includes all test shards, browser tests, typecheck, build and canary dry
run. Greptile was 5/5 on that commit with no unresolved review threads.
GitHub still requires code-owner review under the repository merge
rules; passing checks do not bypass that approval. Paid source
fingerprints remain separate below and in the dated result note.

- Paid Events qualification passes **3/3**: GPT-5.4 Mini, Claude Haiku
4.5 and Claude Sonnet 4.6. Each uses a real public HTTPS callback,
signature verification and report retrieval in a fresh conversation. A
final Mini regression passes after the quota/status fixes. All evidence
validates. Bounded tunnel startup retries occur before provider calls
and remain visible; failed earlier attempts retain their original
grades.
- The earlier complete seven-case matrix passes **21/21**, with a
separate **3/3** delegation regression. Two preceding matrices also
passed 21/21 each. A complete 24-cell matrix including Events has not
been run. [The dated
results](doc/plans/2026-10-01-public-mcp-paid-eval-results.md) retain
exact source fingerprints, failures, model IDs and partial costs.
- Node 24: repository-wide `pnpm -r typecheck` and `pnpm build` pass
after merging master. Server typecheck passes after the final
quota/status changes. Eval typecheck and all 892 eval-support tests
pass.
- All 33 real MCP/OAuth tests pass. The preceding combined MCP,
redaction, private-address and DNS-rebinding run passed 129 tests; two
later MCP regressions cover quota reuse and unchanged-status
suppression. All 28 adjacent issue-tree/stale-lock route tests pass. CI
then found a null checkout result in the existing concurrent-workspace
path; logging now uses optional status access. All 12 closed-workspace
tests and all 33 MCP tests pass after that correction. The exact-start
event calibration exposed a timestamp gap; scanning now includes the
subscription start, with all 33 MCP tests and server typecheck passing.
These two narrow corrections follow the paid regression.
- A real Core → Cloud → Core authority round trip passes OAuth, MCP 2.0
subscription/delivery, current membership loss, unsubscribe, legacy SDK
tools, refresh and revocation. Its callback transport is a fixture with
independent HMAC verification. The paid Events campaigns separately
prove public HTTPS delivery.
- Earlier component qualification passed UI 7,117 tests, CLI 502, shared
832, skills catalog 20, database 160 and OpenAPI 10. Token gates, module
boundaries, migration order and plugin regeneration passed. CI covers
general/serialized suites, eight browser shards, runner checks,
typecheck, build and canary dry run.
- **Local full-suite limitation:** the earlier monolithic run was not
clean. It encountered overlapping schema rebuilding, Mac database
shared-memory limits and isolated CLI/fixture failures. Targeted reruns
passed. The existing >32 MiB Git filename stress test still hit its
300-second Mac timeout. The additional serialized sweep stopped after 62
passing suites once CI passed. Original failures and partial logs
remain; this PR does not claim a wholly green local monolithic run.
- Local Codex CLI and Claude Code OAuth login and MCP SDK
interoperability were verified. Public-store installation, actual
ChatGPT Work Cloud Events UI, staging HTTPS client behavior and hosted
newcomer provisioning remain release gates.

Enablement is moving to **Settings → Experimental → Assistant
connections (MCP)** in the stacked follow-up
[#14933](https://github.com/paperclipai/paperclip/pull/14933). Merge
both for the intended setup experience. This foundation branch alone
still uses `PAPERCLIP_PUBLIC_MCP_ENABLED=true`. After deployment, set
`PAPERCLIP_PUBLIC_URL` to the authenticated instance's HTTPS origin, and
connect to `/mcp/paperclip`. Select a team and allow writes in browser
consent. Configure an available agent and budget, then delegate and
retrieve results later. For Events, rescan the deployed plugin catalog
in ChatGPT Work Cloud; the host supplies its webhook credentials when
the user asks to watch a task. See [the setup
runbook](doc/public-mcp.md).

## Risks

- Events are at-least-once and may arrive out of order. No replay cursor
is advertised. Clients must refresh finite subscriptions, read current
state and avoid comment feedback loops. Callback material uses the
instance secrets master key; hosted subscriptions require the updated
Cloud broker and are bounded to five minutes/the access proof expiry.
- ChatGPT Work Cloud/dot event UI, plugin rescan and a hosted staging
subscription remain deployment gates. Local signed-webhook and paid
model evidence does not claim those surfaces have been exercised.
- Disabled by default. Merging adds schema and opt-in code; it does not
deploy a public endpoint, publish a store listing, create a team, or
start paid agents.
- Migrations 0301 and 0302 are additive and idempotent. Their SQL is
unchanged from the earlier preview numbers, so hash-aware upgrade
reconciliation preserves prior staging applications. Normal instance
upgrades must apply it before enabling MCP.
- Task creation and comments can schedule paid agent work. Consent and
tool descriptions disclose that effect. Revocation blocks future calls
but does not undo delegated work.
- Public deployments need edge rate limits and credential-safe logging.
Internal dispatch is restricted to the closed catalog and carries a
request-local verified actor.
- Hosted onboarding requires the companion Cloud broker, encryption-key
configuration, and tenant rollout. Self-hosted direct connections can
use this PR alone.
- Store acceptance and agent-mode participation are not claimed.
Checked-in plugin endpoints are development defaults; rebuild packages
for a real deployment before installation.

## Model Used

OpenAI GPT-6 in Codex, with reasoning, tool use, and code execution. A
more specific serving version and context-window size were not exposed
by the session. Paid eval models: `gpt-5.4-mini-2026-03-17`,
`claude-haiku-4-5-20251001`, and `claude-sonnet-4-6`.

## 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 (targeted/component checks;
full local-run limitations are recorded above)
- [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-06 11:48:53 -05:00
DottaandPaperclip f2715e02bb fix(native): surface model capacity errors and retry automatically (#15347)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native runs preserve provider events and results, then decide task
state.
> - Codex can fail a turn because the selected model is temporarily at
capacity.
> - Paperclip displayed a generic native-session failure and left the
task in recovery.
> - A known capacity failure needs a clear message and a durable delayed
retry.
> - This pull request uses committed terminal evidence, the
status-effect ledger, and existing dispatch gates.
> - The task can continue automatically without an unbounded retry loop
or a model switch.

## Linked Issues or Issue Description

Related: #13993 adds launcher capacity deferrals before provider
startup. This change handles a committed native Codex `serverOverloaded`
terminal after provider work has started.

**What happened?**
A native Codex turn ended with `codexErrorInfo: serverOverloaded` and
“Selected model is at capacity. Please try a different model.” Paperclip
saved the result, showed a generic failure, and required recovery
instead of waiting and retrying.

**Expected behavior**
Show the capacity error directly. Schedule bounded retries after a short
delay. Preserve saved work and honor current execution gates.

**Steps to reproduce**
1. Run a native Codex task.
2. Commit a `turn.failed` event with `serverOverloaded`, then accept a
failed result for the same turn.
3. Inspect the task error and its recovery state. The regression test
reproduces this without a paid provider call.

**Paperclip version or commit**
Reproduced against master `16b7db35ffa0f9a95913c8cbdeea3d595435691f`.

## What Changed

- Classify capacity failures from committed runner events and the pinned
execution identity. Preserve accepted results and display the specific
capacity error.
- Atomically persist one scheduled successor with the status decision.
Retry after one minute, then two minutes. Share the existing failure
budget and stop after two automatic retries.
- Reuse dispatch gates for ownership, task holds, dependencies, budget,
and locks. Wait for predecessor execution, finalization, and cleanup
before claiming a retry.
- Preserve pending reviewer authority and suppress retries after
reassignment or a successor claim.
- Consume the failed run's resume receipt and delivered wake input.
Rebuild ordinary continuation from the failed run so explicitly resumed
tasks can retry without borrowing one-run authorization.
- Label scheduled retries “Model at capacity.” Add a Storybook example
and avoid duplicate punctuation in the existing retry card.
- Add regression coverage and document the runtime contract.

## Verification

- Targeted recovery and UI suites: 125 tests passed. Additional final
cleanup and lock regressions passed.
- Latest-head continuation and authorization regressions: 57 tests
passed, including all four capacity integration tests against an
isolated PostgreSQL database.
- Rechecked all four capacity integration tests with the full runner's
isolated `PAPERCLIP_HOME`, config, temporary directory, and serial fork
settings: passed.
- `pnpm -r typecheck`: passed. Final server typecheck passed.
- `pnpm build`: passed.
- `pnpm check:token-gates`: passed.
- Browser: checked the real Storybook card. It shows the capacity
message, automatic retry time, and existing Retry now action.
- `pnpm test:run`: attempted and restarted after an interruption. The
resumed run started before the final review correction and was stopped
after recorded workspace/native test failures and the five-minute Git
streaming timeout already documented on master. Exit 130; no complete
local full-suite pass is claimed. Current-head isolated capacity tests
and the complete CI suite pass.
- A combined local recovery-suite attempt also hit PostgreSQL
initialization failures at this macOS host's global shared-memory limit
(32 slots). The focused recovery suites passed separately; final-head
capacity tests also pass with the full runner's isolated environment
settings.
- Latest-head GitHub checks: all 56 checks green, including general and
serialized test shards, browser E2E, typecheck, build, Runner
verification, and canary dry run. No merge conflicts.
- Greptile: 5/5 on `813a470b8c18c05aeb7e31e63e573c3a3a2f5cac`, with zero
unresolved findings after fixing the resumed-task continuation issue.

## Risks

- Capacity retries can repeat a task turn after partial work. They start
a fresh provider session with task history and wait for predecessor
cleanup. They do not resume the failed turn.
- Retries retain the configured model unless an operator changes
configuration. Persistent overload consumes the existing failure budget
and then needs an explicit retry or model change.
- Only run-bound native Codex `serverOverloaded` failures qualify.
Usage-limit exhaustion, model/account incompatibility, unbound text, and
unknown provider failures retain their current recovery behavior.
- No schema migration is required.

## Model Used

- OpenAI GPT-6 through Codex. The exact model ID and context-window size
are not exposed to this session. Used reasoning, repository tools, code
execution, and browser verification. No subagents.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [ ] 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-06 10:59:18 -05:00
DottaandPaperclip a1ab55a56d fix(agents): grant configuration access by default (#15283)
## Thinking Path

> - Paperclip manages agent work and permissions for a company.
> - Agent setup can require one agent to configure another agent.
> - New standard agents could create agents, but they had no direct
configuration grant.
> - Existing agents must keep their current permissions after an
upgrade.
> - The requested new-agent defaults include 13 more direct permissions
for suggestions, skills, tools, audit, inbox, and task assignment.
> - This pull request adds the 14-grant set at creation and approval
activation, retains it through invitations, and keeps existing agents
unchanged.
> - The change keeps low trust and built-in agents on their narrower
permissions.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The agent creation and approval flows, and the agent configuration
authorization path.

**Current behavior**

A new standard agent can create an agent. It cannot make protected
changes to a peer agent unless an operator adds an `agents:configure`
grant.

**Proposed behavior**

Add direct grants for `agents:configure`, `agents:suggest-changes`,
`skills:create`, `skills:suggest-changes`, `tools:manage_connections`,
`tools:manage_profiles`, `tools:view_audit`, `audit:view_agent_actions`,
`tools:use`, `tools:manage_runtime`, `inbox:manage`, `tasks:assign`,
`tasks:assign_scope`, and `tasks:manage_active_checkouts` to new
standard agents. Scope `tasks:assign_scope` to the agent’s reporting
subtree. Keep existing agents and their grants unchanged.

**Reason and benefit**

New standard agents can complete agent setup and the requested tool,
skill, inbox, and task workflows under existing route, scope, and
approval checks.

**Breaking changes**

Existing agents keep their current permissions. There is no permission
migration.

Related PR: #12212 adds scoped grant routes. This PR changes the default
grant.

## What Changed

- Add the 14 requested direct grants in agent creation and approval
activation. Keep them when invitation approval replaces grants,
preserving explicit scopes. Remove them when an agent is deleted.
- Apply defaults only to new agents. Remove the existing-agent
permission migration, its snapshot, and its journal entry. Preserve
existing scoped grants.
- Add permission, scope, invitation, and existing-agent regression
tests. Document all default and excluded permissions.
- Prevent agent keys from creating, changing, or restoring host-executed
process or local adapter command settings, and from restoring workspace
commands through rollback.

## Verification

- Run `node_modules/.bin/vitest run
server/src/__tests__/agent-default-configure-grants.test.ts
server/src/__tests__/invite-join-grants.test.ts
packages/db/src/migration-snapshot-drift.test.ts`. All 15 tests pass.
These cover new-agent defaults, unchanged existing grants, pending
approval, invitation grants, and migration history.
- Run `node_modules/.bin/tsc -p server/tsconfig.json --noEmit`. It
passes.
- Run `packages/db/node_modules/.bin/tsx
packages/db/src/check-migration-numbering.ts` and
`packages/db/node_modules/.bin/tsx
packages/db/src/check-migration-safety.ts`. Both pass.
- Confirm that this PR has no files under `packages/db/src/migrations/`
in its final diff.
- GitHub CI at `e8173b2c41` passes build, typecheck, server suites,
browser shards, and canary verification. One unchanged OpenCode
transport test reached its five-second timeout in the first Runner shard
run. That test passes locally in 2.55 seconds. The shard passed on one
retry. All 54 checks pass, with two expected skips.
- Greptile gives this exact head 5/5. Security review passes. The PR has
no unresolved review threads or merge conflicts.

## Risks

- The 14 default permissions apply only to new standard agents. Existing
permissions stay unchanged. Low trust and managed built-in agents are
excluded.
- New grants include connection, runtime, and active-checkout
management. Existing company, responsible-user, scope, and approval
checks remain in force. The default inbox grant carries a
responsible-user-only scope so it cannot override another user's inbox
settings.
- Protected changes still need the responsible user's authority when
that check applies. Company boundaries and approval gates still apply.
- Agent-authenticated requests cannot configure process adapters or host
command settings on local adapters. Known provider credential references
remain allowed, as do narrow plain authentication overrides on new peers
when the caller uses an AI connection pool. Arbitrary environment
settings remain blocked. Board operators retain the host configuration
paths.

> I checked `ROADMAP.md`. This is a narrow fix to existing agent
configuration behavior.

## Model Used

- OpenAI Codex, GPT-6 series. This runtime did not expose its exact
hosted model ID or context window. This revision uses OpenAI GPT-6
through Codex with tool use, code execution, and tests. The runtime does
not expose the exact hosted model ID or context window.

## 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-06 05:28:48 -05:00
DottaandPaperclip 0e0b63e5a5 feat(connections): add experimental task-pinned AI routing (#14967)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - AI Connections separate account access from models and harnesses.
> - A pool must act as one connection while retaining each task’s
account.
> - Core must enforce member access and preserve session and recovery
rules.
> - A plugin supplies rotation policy without receiving credentials.
> - This change adds durable routing and native connector setup and
management.

## Linked Issues or Issue Description

**Subsystem affected**

AI Connections, Connectors, plugins, run dispatch, and session
compatibility.

**Problem or motivation**

Operators need to rotate new tasks across saved accounts while each task
keeps its account and session. Pool setup must fit the existing
connector catalog and account workflow.

**Proposed solution**

Add an experimental router binding, a capability-gated plugin hook, and
transactional task pins. Plugins declare native pooled connectors
through `aiConnectionRouter`. Core hosts the existing-account picker,
ordering step, and account settings. Related usage contract: #14936.
Companion private plugin:
https://github.com/paperclipai/paperclip-cloud/pull/643.

**Roadmap alignment**

This extends Apps and AI Connections. Core supplies generic enforcement
and native connector UI; the private plugin owns rotation and quota
policy. The prior duplicate search found no matching router
implementation.

## What Changed

- Add a router binding without changing existing concrete bindings. Keep
the instance flag and new pools disabled by default. Require manual
operator configuration. Show no routing toggle in Experimental settings
on either open-source or Cloud installs, even after routing is enabled.
- Persist company-scoped pools, one shared cursor per pool, and pins
keyed by company, pool, agent, and task. Commit pins and cursor advances
together with revision checks and bounded retries. Persist run-ID
affinity before allocation.
- Pass only authorized metadata and normalized usage to plugins. Core
retains credential handling, member access checks, runtime
qualification, and recovery evidence. Probe outside locks with a shared
15-second budget and freshness cache.
- Resolve routing before credential preparation and backend selection.
Preserve pins through turns, session resets, removed members, and quota
waits. Retain admitted recovery after disable or uninstall.
- Separate credential session epochs from token generations. Verified
refresh preserves the epoch; reconnect and manual replacement change it.
Include the credential slot ID in session and usage-cache identity, so
reconnecting an indexed legacy account invalidates its old session even
when both epochs are zero.
- Validate pool member installations before accepting saved-agent
bindings and recheck compatibility when the harness changes. Install
only authorized members in the new-agent transaction and record their
IDs in local activity. Pool membership cannot install a restricted
shared connection.
- Preserve pool bindings when agents hire teammates through either
creation API or native caller runtime inheritance. Block stale manager
credential references; retain explicit child authentication precedence
and reject incompatible inherited pools.
- Add native connector registration through plugin metadata. Reuse the
Connectors catalog, setup header, account header, sidebar, dialogs, and
usage display. Setup selects and orders saved connections. Advanced
settings hold usage rules and member runtime defaults. New-account setup
opens in another tab.
- Use revision-checked pool archival from the Connectors catalog and
account page. Keep task pins, cursors, recovery evidence, and underlying
connections. Reject ordinary connection updates or removals that bypass
pool revisions.
- Add pool selectors, composer models, override notes, quota status, run
details, activity records, and local run-log records. Keep
session-adoption copy minimal.
- Show **Used by** below the pool connections. List current company
agents with shared avatars and profile links. Include paused agents;
exclude terminated agents and agents using another pool.
- Add Core stories for the generic connector workflow and runtime
surfaces. Cloud stories reuse these production routes and tokens through
a preview-only alias.

## Verification

- Final head `73cb953bca30ed83e4505dd820edd9b5edffd28b`: full workspace
`pnpm -r typecheck`, `pnpm build`, and `pnpm check:token-gates` pass
locally.
- All 422 focused connector/settings/shared-contract/migration tests and
all 156 database-backed AI connection, hiring, reconnect, and
durable-routing cases pass (69 hiring cases rerun after the final
auth-precedence fix). The merged shared contract retains connection
instructions and pool metadata. The pool migration is generated at
sequence 0299 after the latest upstream migrations; this PR makes no
lockfile changes.
- All four full-app Playwright tests pass on the final head after a cold
restart and migration, against the installed private plugin and isolated
database, with no route or pool-API mocks. They cover hidden routing
controls after manual opt-in, native pool creation, ordering, membership
edits, rename, paused defaults, enabling/save/refresh persistence, stale
edits, cancellation/removal, preserved underlying accounts, unavailable
routers, and Used by avatars and profile links. Exact command:
`PAPERCLIP_CONNECTION_POOL_E2E=1
AI_CONNECTIONS_TEST_COMPANY_ID=a37b9625-5ecf-4e29-8081-04df3d6e7d6f
AI_CONNECTIONS_TEST_URL=http://127.0.0.1:3108 pnpm exec playwright test
--config tests/ai-connections-app/playwright.config.ts
connection-pools.spec.ts`.
- [Native setup, ordering, and management
screenshots](https://github.com/paperclipai/paperclip/pull/14967#issuecomment-6006976278)
address the review follow-up. [Earlier selector, quota, and run-detail
screenshots](https://github.com/paperclipai/paperclip/pull/14967#issuecomment-5971537316)
show the runtime surfaces. Core previews: `pnpm --filter @paperclipai/ui
storybook`, then **Connectors / Pool host** or **AI Connections /
Connection pools**. Cloud owns its host-backed plugin stories; both
repositories’ Operator Setup Required story assertions pass.
- Live acceptance used OpenAI/Codex and Anthropic/Claude ACPX, resumed
both exact sessions after restart, preserved pinned accounts through
explicit reset and controlled quota deferral/recovery, and committed
only two allocations across fourteen runs. A later UI-created task test
again rotated OpenAI then Anthropic and resumed OpenAI through
follow-up/restart/quota recovery. That later Anthropic execution was
blocked by its saved OAuth token expiring (provider 401). No live usage
probes ran.
- The full local `pnpm test:run` was attempted earlier and did not
complete because of macOS embedded PostgreSQL bootstrap/shared-memory
failures and the 40,000-file Git fixture timeout. The focused database
suites above now pass; full-suite verification is provided by the split
CI lanes. The preceding CI run had one runtime readiness timeout; it
passes locally both alone and inside the larger runtime suite. That
larger local suite also encountered an embedded PostgreSQL setup failure
and two macOS temporary-path alias assertions; those two assertions pass
with canonical TMPDIR=/private/tmp. All final-head CI checks are
terminal green, including full general/serialized server suites, Runner
checks, browser E2E shards, canary verification, build, and typecheck.
Greptile is 5/5 on that exact head with no unresolved threads.

## Risks

- The migration adds routing tables and a credential epoch column.
Install the private plugin only with the compatible Core contract.
- Routing and each pool require opt-in. Production distribution and
fleet defaults remain unchanged.
- Unknown usage stays eligible. Known pinned exhaustion waits; revoked
access requires operator repair.
- Legacy adapters require compatible members. Runner model and effort
overrides remain limited by qualified backend support.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository editing, code
execution, and browser testing. The exact deployment 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
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (targeted suites;
full-suite limitations are reported above)
- [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-05 20:44:37 -05:00
DottaandPaperclip 4857799a88 feat(connections): deliver saved instructions to authorized agent turns (#15216)
Persist optional connection instructions and deliver authorized snapshots to agent execution prompts. Keep provider templates with each app definition, preserve edits and opt-outs, and replace sessions when guidance or access changes.

Use shared production settings across setup and Permissions, with source visibility in agent Instructions. Add the initial memory-provider defaults and managed Honcho workspace configuration. Include migration 0298 and regression coverage for generic providers, runtime delivery, authorization, and catalog regeneration.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-05 18:16:00 -05:00
DottaandPaperclip 59015846ae fix(chat): keep dismissed task questions in the feed (#15229)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents ask users questions in task chats and Agent Chat.
> - Agent Chat keeps unanswered questions as compact entries in the
feed.
> - Regular task chats still show a pending composer badge after
dismissal.
> - A page reload can also open a dismissed question form again.
> - This pull request applies the same feed behavior to both chat types
and saves dismissal per person and task.
> - Users can continue the chat and return to the original question
later.

## Linked Issues or Issue Description

**What happened?**

Dismissing a question in a regular task chat leaves a pending composer
badge. The question can return after a page reload. The earlier feed
behavior only applied to Agent Chat.

**Expected behavior**

A dismissed question stays in the feed. Its form and pending badge leave
the composer. Reload preserves dismissal. Opening the feed entry
restores the original question and draft answer.

**Steps to reproduce**

1. Open a regular task chat with a pending question.
2. Select an option, then dismiss the form.
3. Reload the page. Check that the composer stays clear.
4. Open the question in the feed. Check that the draft is restored.
5. Submit the answer. Check that the answered receipt appears.

**Paperclip version or commit**

Reproduced on master at `a386a599983519eb1d399f8b770bfccdb2a74762`.

**Deployment mode**

Browser UI in local and authenticated instances. This change does not
depend on the agent adapter.

Related work: Refs #14613, which added the Agent Chat feed behavior.
Refs #9141, which validates real answers on the server. Refs #11434,
which tracks comment-driven changes to interaction state. This PR
changes question presentation only.

## What Changed

- Show compact unanswered question entries in regular task chats.
- Exclude durable questions from composer pending counts and navigation.
- Save dismissal in local storage per person and task. Merge the latest
saved IDs so dismissals from another tab survive reload. A new question
can still open its form.
- Keep the original question pending and answerable. Keep approval and
permission controls.
- Run the question-history regressions in both chat modes. Add reload,
new-question, user/task scope, and stale-tab coverage.
- Share the real-component Storybook fixture. Add a regular task test
drive and an interactive dismissal/answer scenario.
- Update the planning-mode browser test to check a dismissed question in
the feed after reload and on mobile.
- Update the design rules, implementation spec, and preview
instructions.

## Verification

- 329 focused thread, composer, and interaction-card tests pass.
- `pnpm -r typecheck` passes. The UI typecheck also passes after the
review fix.
- `pnpm build` passes for the full repository.
- UI build, Storybook build, and token gates pass. The UI build and
token gates were rerun after the review fix.
- Greptile gives final commit `98f71f221` a 5/5 score. The current-head
check passes, and there are no unresolved review threads.
- All 56 current-head checks are terminal: 54 pass and two conditional
Storybook jobs skip. The CI run includes the full test shards, build,
typecheck, browser tests, aggregate verification gate, and package
canary.
- The stale-tab regression fails in both chat modes before the review
fix and passes after it.
- `pnpm exec playwright test --config tests/e2e/playwright.config.ts
tests/e2e/planning-mode-visual-verification.spec.ts` passes against a
throwaway local server. It checks dismissal, reload, task navigation,
and desktop/mobile planning controls.
- The duplicate local `pnpm test:run` attempt was stopped after the full
CI test suites passed. It did not complete locally.
- Manual browser test: select Green, dismiss, reload, reopen, submit the
saved answer, and inspect the answered receipt. Also send a new message
while the unanswered question remains in the feed. The test drive uses
real UI components with fixture response callbacks.
- To repeat the browser test, run `pnpm storybook`. Open **Chat &
Comments → Task Chat Unanswered Questions → Test Drive**.

## Risks

- Dismissal is a browser-local preference. It does not sync to another
browser or device. Clearing local storage removes it.
- When local storage is unavailable, dismissal lasts for the mounted
thread only.
- Unanswered questions can accumulate in the feed. They stay pending
until answered or resolved through the existing API.
- No database migration, API change, or change to approval permissions.

## Model Used

OpenAI Codex, `gpt-6.1-sol`, with xhigh reasoning, repository editing,
code execution, and browser control. The context-window size is 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-05 10:55:38 -05:00
DottaandPaperclip cc67d4e1d8 fix: preserve steering and recover stopped task conversations (#15015)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - A task conversation must let a user guide a running agent and resume
stopped work.
> - The active run owns its input protocol, even when the user changes
the next model or effort.
> - Queue delivery waits for a provider receipt, which must be able to
persist during the request.
> - A stopped startup also needs a clear user action that passes normal
task admission.
> - This pull request fixes steering delivery, makes queue actions
immediate, and restores explicit continuation.
> - The benefit is a responsive conversation that can recover without
losing saved input.

## Linked Issues or Issue Description

**What happened?**

A queued message could change from Steer to Interrupt while a native run
prepared. A steer request could wait on its own database lock and fail
to deliver. A stopped startup could then leave the conversation without
a working Retry or message continuation. Interrupt also waited for the
server and showed a toast.

**Expected behavior**

The active run keeps its input protocol. Steer delivers input to that
run. Steer and Interrupt clear the submitted queue rows and show the
input in the conversation immediately. Failed delivery restores the
latest queue with an inline error. An eligible stopped run offers Retry,
and authenticated user input can start a fresh turn through normal task
admission.

**Steps to reproduce**

1. Start a task with a native Paperclip Runner.
2. Change the selected model or effort while that run prepares.
3. Queue a message and press Steer.
4. Observe the provider receipt and queue state during the request.
5. Stop a startup before its provider process begins, then try Retry or
send a new message.
6. Repeat queued delivery with a legacy runner and press Interrupt.

**Paperclip version or commit**

Reproduced on the parent of this branch, `59c07ede7`.

**Deployment mode**

Authenticated private deployment. The fixes also cover local task
conversations.

Related work: Refs #12834, Refs #13354, Refs #13275. The open refactor
in #13160 moves the same queue route; it does not fix the receipt lock
or stopped-run continuation addressed here.

## What Changed

- Select queue behavior from the active run's immutable dispatch and
runtime resolution.
- Leave the run row unlocked during provider acknowledgement, then lock
and read it before merging the receipt.
- Retain queued input if the target run stops during that wait. Keep
inline delivery errors visible after empty queue updates.
- Permit exact Retry and authenticated continuation after verified
native startup cancellation. Preserve pause, approval, budget,
ownership, and process-stop gates.
- Carry undelivered native queue input into a fresh turn once the old
execution is confirmed stopped.
- Show Steer and Interrupt input in the conversation and clear submitted
composer rows immediately. Restore the latest queue inline on failure.
Remove delivery toasts.
- Keep optimistic delivery stable across stale polls, empty queues, and
paginated history. Preserve classic Interrupt error handling.
- Document recovery and optimistic delivery behavior. Add regression
tests across server, shared queue projection, and UI boundaries.

## Verification

- Red-green regression tests reproduced the queue protocol, receipt
lock, stopped-startup continuation, and optimistic delivery failures.
- The focused server route, continuation, queue, and runner boundary
suites passed during implementation.
- The queue-route suite passes with 78 tests. The three complete
conversation UI suites pass with 347 tests.
- UI typecheck, production build, and `pnpm check:token-gates` pass.
- Workspace `pnpm -r typecheck` and `pnpm build` pass. The local
monolithic `pnpm test:run` is still running; remote CI verifies the
complete suite on the latest commit.
- All CI gates pass on `bd9031ad56abfcde13d13a13488c1b9217c2fd3a`,
including the full test shards, runner verification, browser E2E,
typecheck, release registry, and canary dry run.
- Greptile reports 5/5 for that commit. Both review threads are
resolved.

## Risks

This changes queue display and explicit continuation admission. The UI
must restore rejected delivery without losing other-session edits. The
server must preserve concurrent provider result updates and must not
resume a process whose stop is uncertain. Focused tests cover these
boundaries. This change has no database migration.

## Model Used

OpenAI Codex, an agent based on GPT-6. The exact runtime model ID and
context window are not exposed in this session. Used reasoning,
repository tools, code execution, and browser inspection.

## 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-02 22:07:14 -05:00
Devin FoleyandPaperclip 22cea6b2e6 fix: bound sandbox bridge waits and flag silent runs sooner (#14979)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Sandbox agents exchange input and output through bridge control
commands.
> - A provider can stop responding to a command even when it receives a
timeout.
> - These small commands can inherit a four-hour agent lifetime and
block input or teardown.
> - The board also calls a silent run healthy for the first hour.
> - This pull request bounds bridge control waits and surfaces silence
sooner.

## Linked Issues or Issue Description

**What happened?**

A sandbox run can remain active when a bridge control command never
returns. The shared helper passes a timeout to the provider but does not
enforce it on the host. It also accepts the agent's hours-long timeout.
Output silence remains `ok` for an hour and becomes `critical` only
after four hours.

**Expected behavior**

Bound short bridge operations even if the provider never settles. Report
failed input delivery through the existing shutdown path. Warn after
five silent minutes and escalate after fifteen. Keep normal agent
command limits and require verified termination before releasing
execution ownership.

**Steps to reproduce**

1. Use a sandbox runner whose bridge read or input-upload promise never
settles.
2. Set its configured timeout to four hours.
3. Observe that the old queue client never returns or rejects.
4. Inspect a running task with 35 minutes of output silence. The old
summary still reports `ok`.

**Paperclip version or commit**

Base commit `d6d88b9de2`.

**Deployment mode**

Self-hosted server with sandbox execution.

**Agent adapter(s) involved**

Shared command-managed sandbox bridge, including Codex ACP sessions. The
informational silence thresholds apply to active runs across adapters.

Related: #14889 recovers stalled Daytona output streams; #14485 retries
explicit gateway failures during input delivery. This change bounds
short control operations whose provider promises never settle. It does
not add tool replay or automatic cancellation for output silence. #6297
proposes configurable per-agent silence thresholds; this patch only
changes the existing defaults.

## What Changed

- Enforce at most 30 seconds per bridge control shell command on the
host and provider, including callback startup and shutdown,
process-session launch, and payload setup. Preserve shorter configured
deadlines and launch environments.
- Keep the long-lived agent command outside this deadline. Use a fixed
timeout diagnostic without command payloads.
- Surface suspicious output silence after five minutes and critical
silence after fifteen minutes.
- Decouple the shared-workspace holder cutoff from warning thresholds
and preserve its existing one-hour value.
- Add regressions for hung reads, a late upload response, failed input
delivery, exact warning boundaries, and fresh output clearing warnings.
- Update the adapter guide and execution contract.

## Verification

- The three new queue-client regressions fail on the unchanged base and
pass with this patch.
- Final callback bridge and sandbox session suites: 214 passed. These
cover hung reads, writes, startup, shutdown, process-session launch,
payload setup, and the separate long-running agent limit.
- Stdin ordering and shutdown suite: 56 passed after the lifecycle
change.
- Daytona and watchdog coverage passed in the earlier focused runs.
Across the focused suites, 602 distinct tests pass.
- `pnpm -r typecheck` and `pnpm build`: passed. Server and adapter
typecheck/build also passed after their respective follow-up changes.
- `pnpm test:run`: attempted and stopped after known local failures.
Four chat/email cases used an external ancestor skill path, three
skill-cache cases failed on macOS, and one wakeup case timed out. The
wakeup case passes alone (1 passed, 27 skipped). This run spanned the
workspace-cutoff follow-up and also failed its new holder case; a fresh
final-head workspace suite passes all 19 tests. The interrupted run is
not a full local-suite pass or final-head verification.
- A filesystem queue-drain test failed once during the lifecycle rerun
and passed on the complete two-suite rerun. It uses the filesystem
client, outside the changed command-runner path.
- Complete CI on `ff2212c235`: 53 successful checks and two expected
skips, including the full test suite and canary packaging dry run. No
failed or pending checks.
- Greptile reviewed `ff2212c235` at 5/5. All review findings are
addressed, no threads remain unresolved, and the branch has no merge
conflicts with `master`.
- `git diff --check` and a scan of added text for secrets and private
identifiers passed.

## Risks

- A bridge control operation that needs more than 30 seconds now fails,
even if the caller selected a longer run lifetime. Agent commands retain
their own limits.
- Timing out a provider promise does not cancel the remote operation or
prove it stopped. Existing execution settlement still owns termination
verification. No uncertain tool action is replayed.
- Quiet healthy runs display warnings sooner. Existing snooze, continue,
and false-positive dismissal controls still apply. Silence alone does
not cancel a run, create review work, or change assignments.
- No schema or API shape change.

## Model Used

OpenAI GPT-6 through Codex, 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
- [x] I have run change-specific 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-02 15:29:41 -07:00
DottaandPaperclip 9786f6df56 fix(runner): preserve credential content in document saves (#14937)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Runner sends authorized tool calls to the control plane.
> - Agents use these calls to save plans and instruction files.
> - The Runner used diagnostic secret detection to reject execution
arguments.
> - Ordinary credential-related prose could reject a document save
before persistence.
> - This pull request forwards the original arguments and leaves
credential policy to the provider harness.
> - The benefit is reliable saves with useful diagnostic records.

## Linked Issues or Issue Description

Related foundation: Refs #12415 and #14430. No duplicate save-policy fix
was found.

**What happened?**

A `write_document` call failed before the server saved its plan. The
Runner reported `semantic tool input contains credential material;
refusing to execute altered arguments`. The detector also masked
ordinary phrases such as `secret manager` and `credential handling` in
diagnostics. Both TypeScript dispatchers had equivalent execution gates.
One dispatcher also rewrote structured approval and question payloads
before execution.

**Expected behavior**

Paperclip forwards authorized arguments unchanged. The provider harness
decides credential-content policy. Log and audit redaction does not
reject or rewrite save input.

**Steps to reproduce**

1. Send an authorized `write_document` call with a plan that discusses
credential handling.
2. Include an intentional credential value in the body to exercise
harness-owned policy.
3. The old Runner rejects the call. With this change, the document
service stores the exact body.
4. Diagnostic records still mask explicit credential values. Qualified
credential fields, short bearer values, opaque diagnostic pairs, and
valid encoded JSON token headers have regression coverage.

**Paperclip version or commit**

Reproduced at `c46e41e81c03cd3c8b64cf993615b604d7fe8c62`. The branch is
based on current `master`.

**Deployment mode**

Server deployment with the native Paperclip Runner. Local regression
tests use the real document service and an embedded test database.

## What Changed

- Remove credential-content vetoes from Rust admission and both
TypeScript semantic dispatchers.
- Preserve original structured approval and question arguments during
execution.
- Keep transport bounds, schema checks, authorization, idempotency, and
audit masking.
- Require explicit credential syntax or recognized formats for
diagnostic masking. Preserve ordinary prose, metadata, and dotted
identifiers.
- Test exact document persistence, replay, nested argument identities,
and masked audit copies.
- Remove obsolete retry guidance and document harness-owned credential
policy.

## Verification

- `cargo test --manifest-path
packages/paperclip-runner/runner/Cargo.toml --locked -p
paperclip-runner-core --lib --test acpx_event_payload --test
acpx_provider_state --test acpx_provider_turns`: 355 tests passed.
- Focused server and adapter tests: 189 tests passed after rebase. These
include the real document save and the complete tool-gateway suite.
- Semantic dispatcher and conformance tests: 34 tests passed.
- Diagnostic redaction and MCP tests: 46 tests passed, including all six
review examples.
- `pnpm -r typecheck` and `pnpm build` passed on the repaired branch.
- The broad local root suite was interrupted after database fixture
setup failures. The focused database suites passed. CI runs the complete
configured test lanes.

## Risks

- Authorized tool arguments can intentionally contain credentials. The
harness must enforce its content policy.
- Diagnostic detection is narrower. Explicit assignments, credential
fields, and recognized credential formats remain masked.
- The change does not add a database migration or change company
authorization.

## Model Used

- OpenAI GPT-6 through Codex. The session exposes the GPT-6 model
family; its exact runtime model identifier and context window size are
not exposed. Used reasoning, tool use, and code execution.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-02 14:19:41 -05:00