Commit Graph
1131 Commits
Author SHA1 Message Date
DottaandPaperclip 390627b46e [codex] Suppress worktree heartbeat scheduling (#9163)
Suppress heartbeat scheduling in worktree and restore runtimes while keeping routine ticks and setup cleanup active.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-07 09:27:46 -05:00
DottaandPaperclip 57a7da81ee [codex] Isolate run JWTs by control-plane instance (#9162)
Bind local agent run JWT signing and validation to the issuing Paperclip instance while preserving rollout compatibility for legacy tokens.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-07 09:27:19 -05:00
DottaandPaperclip 09f503f216 [codex] Surface AWS secret provider create errors (#9161)
Preserve sanitized AWS Secrets Manager create errors and make rollback/cleanup failures explicit.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-07 09:26:41 -05:00
Dotta 88ce6d3575 Speed up issue detail payloads (#9125)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Operators spend a lot of time in issue detail pages and agent
activity views while supervising work
> - Those views were receiving large embedded project, workspace,
runtime-service, and heartbeat context payloads
> - Large payloads make issue comments and page loads slower, especially
on active issues with workspaces and runtime metadata
> - This pull request trims the issue detail and activity ledger
response shapes to the fields those views need
> - The benefit is faster issue detail loading without changing the
underlying project, workspace, or run persistence model

## Linked Issues or Issue Description

No public GitHub issue was found for this exact problem, so this PR
describes the bug inline using the bug report template fields.

### Pre-submission checklist

- [x] I have searched existing open and closed issues and this is not a
duplicate.
- [x] I am on the latest released version of Paperclip (or can reproduce
on `master`).
- [x] I have confirmed the error originates in Paperclip itself — not in
my agent adapter, API provider, or local configuration.

### What happened?

Issue detail and related activity responses could include bulky embedded
metadata such as project environment values, workspace metadata, stopped
runtime services, and heartbeat context snapshots. On active issues with
workspaces and long activity history, that makes issue comments and page
loads slower than needed.

### Expected behavior

Issue detail endpoints should return bounded, UI-oriented embeds that
avoid shipping large or sensitive internal blobs when the full object
graph is not needed.

### Steps to reproduce

1. Create or open an issue with a project workspace and execution
workspace.
2. Ensure the workspace has runtime services and heartbeat runs with
context snapshots.
3. Inspect `GET /api/issues/:id` and the issue activity ledger payloads.
4. Observe that the response includes large embedded
project/workspace/runtime/run fields unrelated to rendering the issue
detail page.

### Paperclip version or commit

Reproduced against current `master` lineage before this change.

### Deployment mode

Local dev / server API behavior.

### Installation method

Built from source (`pnpm dev` / `pnpm build`).

### Agent adapter(s) involved

Not adapter-specific (core API payload shape).

### Database mode

Not database-related; no migration.

### Access context

Board and agent-facing issue detail consumers can both benefit from
smaller payloads.

### Node.js version

Not version-specific.

### Operating system

Not OS-specific.

### Relevant logs or output

Not applicable.

### Relevant config (if applicable)

Not applicable.

### Additional context

Related search:
- Searched public GitHub issues for `currentExecutionWorkspace metadata
runtimeServices issue detail`; no matching issue found.
- Searched public GitHub PRs for `compact currentExecutionWorkspace
metadata runtimeServices`; no matching PR found.

### Privacy checklist

- [x] I have reviewed all pasted output for PII (usernames, file paths,
API keys, tokens, company names) and redacted where necessary.

## What Changed

- Added compact response shaping for issue detail project, project
workspace, execution workspace, and runtime-service embeds.
- Dropped large project `env`, workspace `metadata` / embedded runtime
service lists, execution workspace `metadata`, and non-active runtime
services from `GET /api/issues/:id` responses.
- Removed heartbeat `contextSnapshot` from the activity ledger query
result.
- Added focused route and activity-service tests covering the compact
response shape.

## Verification

- `pnpm exec vitest run
server/src/__tests__/issues-goal-context-routes.test.ts
server/src/__tests__/activity-service.test.ts --no-file-parallelism
--maxWorkers=1`
- `pnpm --filter @paperclipai/server typecheck`
- `git diff --check public/master..HEAD`
- Confirmed the branch is based on current
`paperclipai/paperclip:master` and contains no `pnpm-lock.yaml` or
`.github/workflows` changes.

## Risks

Low to medium risk. The persisted data model is unchanged, but consumers
relying on the full embedded project/workspace/runtime metadata from
`GET /api/issues/:id` will now need to fetch the dedicated resource
endpoint instead of depending on the issue detail payload.

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

## Model Used

OpenAI GPT-5 Codex coding agent with repository file access, shell
command execution, GitHub connector usage, and local test execution.
Context window and exact hosted model variant are not exposed in this
runtime.

## 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
2026-07-07 06:28:54 -05:00
DottaandPaperclip 19454ce385 Deduplicate open watchdog review wakes (#9148)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Watchdogs keep issue execution moving by waking agents or creating
recovery paths when work stalls.
> - Open review states should generate useful follow-up, not repeated
duplicate wake requests for the same unresolved review condition.
> - Duplicate wakes create noise and can make the control plane look
busier without increasing progress.
> - This pull request deduplicates open watchdog review wake scheduling
and covers the behavior with scheduler tests.
> - The benefit is cleaner review wake behavior and fewer redundant
agent runs.

## Linked Issues or Issue Description

No public GitHub issue exists. Inline bug report:

**Pre-submission checklist**

- [x] I have searched existing open and closed issues and this is not a
duplicate.
- [x] I am on the latest released version of Paperclip (or can reproduce
on `master`).
- [x] I have confirmed the error originates in Paperclip itself — not in
my agent adapter, API provider, or local configuration.

**What happened?**

Watchdog scheduling could enqueue duplicate open review wake requests
while the same unresolved review condition was already pending.

**Expected behavior**

A watchdog should avoid scheduling redundant review wakes for the same
unresolved condition while preserving legitimate wake paths.

**Steps to reproduce**

1. Create an issue state that requires an open watchdog review wake.
2. Run the watchdog scheduler once and observe a wake request.
3. Run the scheduler again before resolving the original review
condition.
4. Observe whether a duplicate wake is created.

**Paperclip version or commit**

`master` at the PR base.

**Deployment mode**

Local dev (`pnpm dev`) and server deployments running watchdog
scheduling.

**Installation method**

Built from source (`pnpm dev` / `pnpm build`).

**Agent adapter(s) involved**

- [x] Not adapter-specific (core bug)

**Database mode**

Not database-related beyond scheduler persistence.

**Access context**

Agent wake scheduling and board-visible review state.

**Relevant logs or output**

Covered by the added scheduler regression test.

**Relevant config (if applicable)**

Not applicable.

**Additional context**

This suppresses duplicate wake scheduling only while the open review
state is still unresolved.

**Privacy checklist**

- [x] I have reviewed all pasted output for PII (usernames, file paths,
API keys, tokens, company names) and redacted where necessary.

## What Changed

- Added deduplication logic for open watchdog review wake scheduling.
- Added scheduler regression coverage for duplicate open review wake
suppression.

## Verification

- `/srv/paperclip/home/paperclipai/paperclip/node_modules/.bin/vitest
run server/src/__tests__/task-watchdogs-scheduler.test.ts`

## Risks

Low-to-medium risk. The change intentionally suppresses duplicate wake
scheduling, so reviewers should confirm no legitimate repeated wake path
depends on creating multiple open requests for the same unresolved
review state.

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

## Model Used

OpenAI Codex, GPT-5.5 coding agent with repository tool use and local
shell execution. Context window was not surfaced by the runtime.

## 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-07-07 05:54:23 -05:00
DottaandPaperclip be821a4f7e Fix DB backup health alerts (#9147)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Operators depend on `/api/health` and OpenAPI status surfaces to
know whether the local control plane is healthy.
> - Database backups are a safety-critical background process, but
backup failures were not represented in health responses.
> - That gap means an instance can look healthy while backup state is
stale, failing, or unavailable.
> - This pull request adds backup-health evaluation and exposes it
through the health route, server startup wiring, and OpenAPI contract.
> - The benefit is earlier operator visibility when automatic backups
stop protecting instance data.

## Linked Issues or Issue Description

No public GitHub issue exists. Inline bug report:

**Pre-submission checklist**

- [x] I have searched existing open and closed issues and this is not a
duplicate.
- [x] I am on the latest released version of Paperclip (or can reproduce
on `master`).
- [x] I have confirmed the error originates in Paperclip itself — not in
my agent adapter, API provider, or local configuration.

**What happened?**

Automatic database backup health was not included in the app health
response, so backup failures or stale backups could be missed while
`/api/health` still looked otherwise usable.

**Expected behavior**

The health endpoint should include backup-health details that let
operators identify disabled, stale, failing, or healthy backup states.

**Steps to reproduce**

1. Configure a Paperclip instance with automatic database backups.
2. Force backup status into a stale or failing state.
3. Call `/api/health` and inspect whether backup state is represented.

**Paperclip version or commit**

`master` at the PR base.

**Deployment mode**

Local dev (`pnpm dev`) and self-hosted server deployments.

**Installation method**

Built from source (`pnpm dev` / `pnpm build`).

**Agent adapter(s) involved**

- [x] Not adapter-specific (core bug)

**Database mode**

Embedded development Postgres and external Postgres backup paths.

**Access context**

Board/operator health checks.

**Relevant logs or output**

Covered by the added `server/src/__tests__/health.test.ts` cases.

**Relevant config (if applicable)**

Not applicable.

**Additional context**

This surfaces backup status only; it does not change backup execution
scheduling.

**Privacy checklist**

- [x] I have reviewed all pasted output for PII (usernames, file paths,
API keys, tokens, company names) and redacted where necessary.

## What Changed

- Added a database backup health service that classifies backup recency,
status, and failure conditions.
- Wired backup health into app/server startup and the health route
response.
- Documented the backup-health behavior in development docs and OpenAPI
output.
- Added focused health route tests for healthy, stale, disabled, and
failing backup states.

## Verification

- `/srv/paperclip/home/paperclipai/paperclip/node_modules/.bin/vitest
run server/src/__tests__/health.test.ts`

## Risks

Low-to-medium risk. This changes health response content and may affect
external health consumers that parse fields strictly. It should not
alter backup execution itself.

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

## Model Used

OpenAI Codex, GPT-5.5 coding agent with repository tool use and local
shell execution. Context window was not surfaced by the runtime.

## 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-07-07 05:54:20 -05:00
Nicky LeachandPaperclip 9d5b0e3c57 Add read-only issue subtree diagnostics endpoint (#9135)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The issue/task orchestration subsystem tracks parent–child and
blocker–dependent relationships, forming a directed acyclic (in
intention) subtree below each root issue
> - Agents and operators have no lightweight way to inspect the
dependency and wake state across an entire issue subtree — they must
walk the tree issue-by-issue, making multiple round-trips with full
object fetches
> - A bounded, read-only subtree diagnostic endpoint lets callers
understand the health of an entire work tree (which nodes are blocked,
which are cycling, which have pending wakes) from a single authenticated
request
> - This pull request adds `GET /api/issues/:id/diagnostics/subtree`, a
depth/node/per-node capped traversal that reuses the blocker and wake
projection helpers from the companion blocker and wake diagnostics
endpoints (see Refs #9114, #9133)
> - The benefit is that platform operators, monitoring, and coaching
tooling can surface \"why is this subtree stalled?\" across all nodes
without database access or unbounded graph walks, using only data the
caller already has read permission for

## Linked Issues or Issue Description

Refs #9114 (companion blocker diagnostics endpoint — blocker projection
helpers reused here)
Refs #9133 (companion wake diagnostics endpoint — wake projection
helpers reused here)

## What Changed

- **New route** `GET /api/issues/:id/diagnostics/subtree` in
`server/src/routes/issues.ts`: returns a bounded subtree traversal
rooted at `:id`, with depth/node/per-node caps and explicit truncation
flags
- **Cycle-safe traversal**: visited-node set prevents infinite loops on
any accidental cycle in the ancestry graph
- **Per-node authorization**: each subtree node is individually filtered
through `assertIssueReadAllowed`; unauthorized nodes are omitted from
the response and do not influence aggregate counts
- **Blocker and wake reuse**: per-node blocker rows and wake events are
projected through the same helpers as #9114 and #9133 — raw wake
payloads, raw errors, activity details, and trigger detail fields are
stripped
- **Low-trust filtering**: the `mention-scoped` low-trust path redacts
node/blocker identifiers for unauthorized actors, consistent with #9133
- **Truncation reporting**: response includes `depthTruncated`,
`nodeTruncated`, and per-node `blockersTruncated`/`wakesTruncated` flags
when caps are hit
- **Shared types** in `@paperclipai/shared`:
`IssueSubtreeDiagnosticsResponse` and supporting node/blocker/wake types
exported from the shared package
- **OpenAPI tag registration** for the new route
- **API reference docs** in
`skills/paperclip/references/api-reference.md`
- **Test coverage**
(`server/src/__tests__/issue-subtree-diagnostics-routes.test.ts`,
embedded Postgres): happy path, quiet singleton (no children/blockers),
node cap truncation, mention-scoped low-trust filtering, cross-company
denial

## Verification

```bash
# Subtree diagnostics tests only
pnpm exec vitest run server/src/__tests__/issue-subtree-diagnostics-routes.test.ts

# Full diagnostics suite (blocker + wake + subtree)
pnpm exec vitest run server/src/__tests__/issue-blocker-diagnostics-routes.test.ts server/src/__tests__/issue-wake-diagnostics-routes.test.ts server/src/__tests__/issue-subtree-diagnostics-routes.test.ts

# Type-check shared and server packages
pnpm --filter @paperclipai/shared typecheck
pnpm --filter @paperclipai/server typecheck

# Whitespace / diff check
git diff --check
```

All commands passed locally (5 subtree tests, 17 total across the three
diagnostics test files).

## Risks

- **No schema or migration changes** — read-only projection over
existing relations; no DDL risk
- **Bounded traversal** — depth, node count, and per-node blocker/wake
caps prevent unbounded graph walks; truncation is reported explicitly in
the response
- **Auth boundary** — root issue read is company-scoped and checked
before the subtree is built; each subtree node is individually
authorized; cross-company access is denied at `assertCompanyAccess`
- **No raw payloads** — raw wake payload, raw error, activity details,
and trigger detail fields are stripped from all nodes, consistent with
the companion endpoints
- Low overall risk; the endpoint is additive and read-only

## Model Used

- **Provider:** Anthropic
- **Model:** Claude Sonnet 4.6 (`claude-sonnet-4-6`)
- **Tool use:** yes (file reads, edits, bash execution, Paperclip API
calls)
- **Reasoning mode:** standard (no extended thinking)

## 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-07-06 22:39:34 -07:00
Nicky LeachandPaperclip 47aef634e5 Add branch incoherence containment (#9131)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run inside git worktrees; the heartbeat system establishes a
workspace branch and tracks it through checkout, realization, restore,
and finalization
> - When the live git branch diverges from the recorded workspace branch
mid-change (branch incoherence), the heartbeat must fail closed with
`workspace_validation_failed` and block the source issue with a recovery
action
> - There were no embedded-Postgres tests covering this fail-closed
behavior across the three interlock call sites: fresh git-worktree
realization, persisted workspace restore, and heartbeat finalization
> - This PR adds a single test file covering all three call sites with
an embedded-Postgres heartbeat test harness and asserts the exact
fail-closed outcome and evidence fields
> - The benefit is confidence that branch-incoherence containment is
correct and regressions in the interlock chain are caught before they
silently corrupt workspace state

## Linked Issues or Issue Description

Refs: #6425 (related: enforce issue branch matches workspace on
wake/checkout)

No pre-existing public GitHub issue for this specific reproduction test
gap. The underlying problem:

**Bug / gap:** The heartbeat's branch-incoherence containment was
untested by any embedded-Postgres integration test. All three call sites
— fresh git-worktree realization, persisted workspace restore, and
finalization — could regress without detection. The fail-closed path
(`workspace_validation_failed` + source-issue block + deduped recovery
action) and the evidence fields surfaced to operators were unverified.

## What Changed

- Added
`server/src/__tests__/heartbeat-workspace-branch-containment.test.ts`
with embedded-Postgres integration tests covering:
- **Fresh git-worktree realization** — heartbeat detects branch
divergence at workspace setup and fails closed
- **Persisted workspace restore** — re-entering a previously-established
workspace with a diverged branch fails closed instead of being silently
coerced into a generic reuse-failure path
- **Heartbeat finalization** — any late-stage branch incoherence
detected at finalization fails closed
- Asserts fail-closed behavior in all three cases: run status =
`workspace_validation_failed`, source issue status = `blocked`, exactly
one deduped workspace-validation recovery action on the blocked issue,
sibling issues on same/other workspaces retain their status
- Asserts evidence completeness: `expectedBranch`, `liveBranch`,
`expectedHead`, `liveHead`, `cleanliness`, `ancestryVerdict`,
`plainLanguageReason`, and `recoveryGuidance` fields are present and
correct on the run
- Ensures release/promotion errors after setup failures are logged (not
silently swallowed), making cleanup failures observable

## Verification

```bash
pnpm exec vitest run server/src/__tests__/heartbeat-workspace-branch-containment.test.ts
pnpm --filter @paperclipai/server typecheck
```

All 3 tests pass, typecheck clean.

## Risks

Low. Test-only change — no production code paths are modified. The tests
use an embedded-Postgres harness and do not touch any shared or live
database.

## Model Used

Claude Sonnet 4.6 (`claude-sonnet-4-6`) via Claude Code — tool use mode,
standard 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
- [ ] 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-07-06 22:02:52 -07:00
Nicky LeachandPaperclip 31a0080e61 Fix wake diagnostics low-trust identifier redaction (#9133)
## Thinking Path

> - Paperclip is the open-source app people use to manage AI agents for
work
> - The task/issue lifecycle subsystem tracks when agents wake up, are
suppressed, or are deferred, recording each wake request in
`agent_wakeup_requests` and each defer/suppression event in
`activity_log`
> - When an agent appears stuck or doesn't resume after a dependency
resolves, there is currently no read-only API surface to inspect its
wake history — operators must query the database directly
> - Making wake history queryable via a first-class endpoint lets
operators, support, and monitoring tools diagnose "why didn't this agent
wake up?" without database access
> - This pull request adds `GET /api/issues/:id/diagnostics/wakes`,
returning a bounded 14-day/50-row projection of wake requests and
defer/suppression activity events, with a deterministic `diagnosis`
field and a `likelyReason` inference — including a Case-B inference ("no
wake enqueued because a visible blocker is not done") that reuses the
blocker readiness data from the companion blocker diagnostics endpoint
(see Refs #9114)
> - The benefit is that platform operators can answer "why is this agent
not waking up?" from a safe, read-only HTTP endpoint rather than needing
direct database access, and CI/monitoring can assert expected wake
behavior

## Linked Issues or Issue Description

Refs #9114 (companion blocker diagnostics endpoint, already merged —
this PR extends the same diagnostic surface to wake/activity history)

## What Changed

- **New route** `GET /api/issues/:id/diagnostics/wakes` in
`server/src/routes/issues.ts`: returns a bounded (14-day window, 50-row
cap) projection of `agent_wakeup_requests` rows and wake-relevant
`activity_log` rows (defer/suppression events)
- **Sanitized projection**: raw `payload`, `details`, `error`, and
`triggerDetail` fields are stripped; unknown free-form `source`,
`reason`, and `status` values are projected to `"other"` to prevent
schema bleed
- **Deterministic `diagnosis` and `likelyReason` fields**: includes
Case-B inference ("no wake enqueued — visible blocker not done") that
calls the existing blocker-readiness helper from Slice 1 (#9114) so the
wake surface can explain missing wakes caused by outstanding blockers
- **Auth**: `assertCompanyAccess` + `assertIssueReadAllowed`;
cross-company requests are denied; Case-B blocker inference filters by
caller trust level so hidden (low-trust) blockers are mentioned but not
identified
- **Types in `@paperclipai/shared`**: `IssueWakeDiagnosticsResponse`,
`WakeEvent`, `ActivityEvent` exported from the shared package
- **OpenAPI tag registration** for the new route
- **Skill reference docs** in
`skills/paperclip/references/api-reference.md` documenting the endpoint
contract
- **Test coverage**
(`server/src/__tests__/issue-wake-diagnostics-routes.test.ts`, embedded
Postgres): happy path, empty/null diagnosis, Case-B inference, low-trust
hidden blocker, cross-company denial, raw blob minimization, cap
behaviour, combined blocker+wake test run

## Verification

```bash
# Wake diagnostics tests only
pnpm exec vitest run server/src/__tests__/issue-wake-diagnostics-routes.test.ts

# Wake + blocker diagnostics together (integration)
pnpm exec vitest run server/src/__tests__/issue-blocker-diagnostics-routes.test.ts server/src/__tests__/issue-wake-diagnostics-routes.test.ts

# Type-check shared and server packages
pnpm --filter @paperclipai/shared typecheck
pnpm --filter @paperclipai/server typecheck

# Whitespace / diff check
git diff --check
```

All commands passed locally.

## Risks

- **No schema or migration changes** — this is a read-only projection
over existing tables; no DDL risk.
- **Bounded queries** — 14-day window + 50-row cap limit per call; no
unbounded scans.
- **Auth boundary** — cross-company access is denied at
`assertCompanyAccess`; Case-B inference uses the same per-node trust
filtering as the blocker endpoint so low-trust blockers are acknowledged
but not identified.
- Low overall risk; the endpoint is additive and read-only.

## Model Used

- **Provider:** Anthropic
- **Model:** Claude Sonnet 4.6 (`claude-sonnet-4-6`)
- **Tool use:** yes (file reads, edits, bash execution, Paperclip API
calls)
- **Reasoning mode:** standard (no extended thinking)

## 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-07-07 04:45:23 +00:00
Nicky LeachandPaperclip 295294d7ce Add read-only issue blocker diagnostics endpoint (#9114)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents block each other with `blockedByIssueIds` relationships to
express dependencies
> - Users and tooling have no lightweight way to inspect *why* an issue
is blocked or whether its blockers are themselves ready to resolve
> - A read-only diagnostic endpoint over the existing blocker graph lets
callers understand dependency chains without requiring a full issue-tree
traversal
> - This pull request adds `GET /api/issues/:id/diagnostics/blockers` —
a bounded, read-only projection over each blocker's readiness state
> - The benefit is that callers can surface blocking-chain diagnosis
(e.g. "waiting on N blockers, M of which are themselves blocked") from a
single authenticated request, using only data they already have read
permission for

## Linked Issues or Issue Description

No public GitHub issue exists for this change. Feature description:

**Subsystem affected:** `server/` — REST API & orchestration services;
`packages/shared` — types, constants, validators, API paths

**Problem or motivation**

There is no API endpoint to inspect *why* an issue is blocked or to get
a per-blocker readiness summary. Clients must walk the issue graph
manually or fetch full issue objects, which requires multiple
round-trips and is expensive.

**Proposed solution**

A single `GET /api/issues/:id/diagnostics/blockers` endpoint returns a
bounded projection: root issue summary, an ordered blocker list with
per-blocker `readiness` state, and a top-level `diagnosis` field
summarizing overall blocking status. Authorization mediation omits
blockers the caller cannot read, so `diagnosis` only reflects visible
data.

**Alternatives considered**

A general graph-walk query (too broad/expensive for a targeted
diagnostic call); enriching the existing `GET /api/issues/:id` response
(too coupled to the main response shape and adds weight for callers that
do not need blocker detail).

**Roadmap alignment**

Read-only observability surface over existing data; no database schema
changes. This aligns with tooling that helps users understand dependency
state without mutating anything.

## What Changed

- Added `GET /api/issues/:id/diagnostics/blockers` route to the server
- Returns per-blocker `readiness` state and a top-level `diagnosis`
field summarizing overall blocking status
- Enforces `issue:read` authorization per-blocker: unauthorized blockers
are omitted and do not influence `diagnosis` or `readiness` values
- Added shared TypeScript response types in `@paperclipai/shared`
- Added route-level tests using embedded Postgres
- Added API documentation in the `paperclip` skill

## Verification

```sh
./node_modules/.bin/vitest run server/src/__tests__/issue-blocker-diagnostics-routes.test.ts
pnpm --filter @paperclipai/shared typecheck
pnpm --filter @paperclipai/server typecheck
```

All three commands pass locally.

## Risks

- Read-only endpoint over existing relations — no writes, no schema or
migration changes — low risk
- Authorization mediation intentionally omits unauthorized blockers from
both the list and from `diagnosis`/`readiness`; callers with partial
access will see a narrower picture than the full blocker graph

## Model Used

- Provider: Anthropic
- Model: Claude Sonnet 4.6 (`claude-sonnet-4-6`)
- Context window: 200k tokens
- Mode: Tool use, code generation, extended reasoning

## 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-07-06 20:42:40 -07:00
Nicky LeachandPaperclip a371ceec60 Fail projectless git-worktree workspaces during heartbeat setup (#9118)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agent work can run in shared, isolated, or operator-branch execution
workspaces
> - Isolated/operator git-worktree modes require a real git checkout as
their base
> - A projectless issue can otherwise resolve to the agent fallback
workspace directory
> - That fallback is not a valid project checkout for git worktree setup
> - This pull request adds a setup-time guard before workspace
realization starts
> - The benefit is that misconfigured work fails with a typed
remediation instead of raw git errors or accidental execution from the
agent home directory

## Linked Issues or Issue Description

No public GitHub issue was found for this specific failure mode. Inline
description follows the bug report template:

**What happened?**
When a Paperclip issue has no associated project (`projectId: null`) and
is configured for `isolated_workspace` or operator-branch execution with
`strategy: git_worktree`, the heartbeat setup silently fell back to the
`agent_home` directory as the base workspace. Because `agent_home` is
not a git repository checkout, the subsequent git worktree operations
either failed with raw git errors or — in the degraded path — ran in the
wrong directory entirely.

**Expected behavior**
A projectless issue requesting `git_worktree` execution should fail
immediately at setup with a typed `workspace_validation_failed` result
and a human-readable remediation message explaining that a project
workspace or a reusable execution workspace with a valid git base is
required.

**Steps to reproduce**
1. Create a Paperclip issue with `projectId: null` (no project
attached).
2. Assign it to an agent configured for `isolated_workspace` execution
with `strategy: git_worktree`.
3. Trigger a heartbeat run.
4. Observe: the heartbeat resolves the base workspace to `agent_home`
and either emits raw git errors during worktree setup or silently
executes from an incorrect directory.

**Paperclip version or commit**
`5cdf5103c` (current `master` HEAD at time of fix)

**Deployment mode**
Local dev (`pnpm dev`) / built from source — reproduces in any mode
because the fallback is in core workspace resolution logic.

**Agent adapter(s) involved**
Not adapter-specific (core bug — affects all adapters that issue
heartbeats for projectless tasks)

**Database mode**
Not database-related

**Access context**
Agent (bearer API key via `agent_api_keys`)

## What Changed

- Added a heartbeat setup guard that validates isolated/operator
`git_worktree` base workspaces before realization.
- The guard fails projectless `agent_home` fallback cases with a typed
`workspace_validation_failed` result and remediation text.
- The guard also fails non-git project base directories before raw git
worktree operations run.
- Added regression coverage for projectless isolated mode,
operator-branch mode, non-git bases, valid git bases, and
shared-workspace no-op behavior.

## Verification

- `pnpm exec vitest run
server/src/__tests__/heartbeat-workspace-session.test.ts`
- `pnpm exec vitest run server/src/__tests__/workspace-runtime.test.ts`
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm -r typecheck`
- `pnpm test:run`
- `pnpm build`

## Risks

- Low risk. The new guard only applies to issue-backed isolated/operator
execution modes using `git_worktree`; shared workspaces and
non-git-worktree strategies are left unchanged.
- The intentional behavior shift is that invalid git-worktree bases now
fail earlier with a structured remediation instead of reaching
lower-level git setup.

## Model Used

- OpenAI GPT-5 Codex, coding-agent tool-use mode with local command
execution; context window size not exposed by this runtime.

## 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-07-06 16:48:05 -07:00
5163208c3c Add workspace branch ancestry diagnostics (#9117)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run in git worktrees tied to a workspace branch; when the
actual branch diverges from the expected one (e.g. a parent feature
branch was renamed), Paperclip currently has no structured field to
report *why* the branch is incoherent or whether it can be
auto-reconciled
> - The workspace-incoherence fingerprint already captures SHA
mismatches, but there is no evidence field distinguishing "actual branch
is a descendant of expected" (safe to fast-forward) from "branches have
diverged" (needs human review) or "SHAs are unavailable" (unknown)
> - Operators and future recovery flows need a typed verdict to make
decisions without re-running git commands themselves
> - This pull request adds `ancestryVerdict` and `plainLanguageReason`
evidence fields computed via `git merge-base --is-ancestor`, and
scaffolds the off-by-default `enableWorkspaceBranchReconcileForward`
instance setting with no runtime behavior yet
> - The benefit is that future recovery logic can branch on a typed
verdict rather than parsing prose, while the fingerprint v1 payload
stays stable

## Linked Issues or Issue Description

No public GitHub issue pre-exists for this diagnostic addition.

**Problem or motivation**

When Paperclip detects that an agent's actual workspace branch differs
from the recorded expected branch, the current fingerprint carries only
raw SHAs. There is no typed field indicating whether the actual branch
is a descendant of the expected one (safe reconcile path) vs. a true
divergence (requires human intervention) vs. an indeterminate state
(missing SHAs or git errors). Downstream recovery logic cannot branch
safely without re-running git.

**Proposed solution**

Add `ancestryVerdict` and `plainLanguageReason` to the workspace
incoherence evidence type; compute via `git merge-base --is-ancestor`;
scaffold a feature-flag for future forward-reconcile behavior
(`enableWorkspaceBranchReconcileForward`, off by default, not yet read
by any runtime path).

**Alternatives considered**

Encoding the verdict in the existing fingerprint string was rejected
because the fingerprint is a stable identity hash, not a mutable
evidence bag. Changing it would break monitors keyed on the string.

**Roadmap alignment**

Supports future workspace auto-reconcile work; ROADMAP.md has no
conflicting entry for this diagnostic layer.

## What Changed

- `packages/shared/src/types/heartbeat.ts` adds `ancestryVerdict` and
`plainLanguageReason` fields to `WorkspaceIncoherenceEvidence`
- `packages/shared/src/types/instance.ts` adds
`enableWorkspaceBranchReconcileForward` boolean (off by default)
- `packages/shared/src/validators/instance.ts` exports the new flag from
the settings validator
- `server/src/services/workspace-runtime.ts` computes `ancestryVerdict`
via `git merge-base --is-ancestor`; falls back to `unknown` on missing
SHAs or command errors; excludes verdict fields from fingerprint v1
computation
- `server/src/services/instance-settings.ts` wires the new setting
through to the settings service
- Tests updated in `workspace-runtime.test.ts`,
`instance-settings-service.test.ts`, `instance-settings-routes.test.ts`,
and `instance.test.ts` (104 tests total)

## Verification

```bash
pnpm exec vitest run \
  server/src/__tests__/workspace-runtime.test.ts \
  server/src/__tests__/instance-settings-service.test.ts \
  server/src/__tests__/instance-settings-routes.test.ts \
  packages/shared/src/validators/instance.test.ts
# 104 tests pass

pnpm --filter @paperclipai/shared typecheck
pnpm --filter @paperclipai/server typecheck
# both exit 0
```

Manual: trigger a workspace incoherence event and confirm the evidence
object carries `ancestryVerdict` and `plainLanguageReason`; confirm the
fingerprint string stays `workspace_incoherence:v1:sha256:...`.

## Risks

**Low risk.** Purely additive. Fingerprint v1 payload is unchanged. The
new flag has no runtime effect in this PR. `git merge-base
--is-ancestor` exits non-zero for both "not an ancestor" and "command
error"; both are handled and collapsed to typed values with a prose
reason.

## Model Used

Provider: Anthropic, model: Claude Sonnet 4.6 (`claude-sonnet-4-6`),
200k context, tool use enabled.

## 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
- [ ] 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>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-06 16:29:01 -07:00
DottaandPaperclip ef617bee5c [codex] Enforce backend execution release gates (#9089)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents for work.
> - Backend execution safety is part of the control plane contract:
agents must stop at budget hard limits, stale execution paths must not
create duplicate live work, and checkout ownership must remain
authoritative.
> - The recovery branch bundled these release-gate checks with broader
unrelated work.
> - Reviewers need a narrow PR that isolates only the backend safety
behavior and regression coverage.
> - This pull request keeps budget incident creation idempotent so
repeated evaluation does not duplicate release-gate telemetry or
approvals.
> - It also adds focused coverage for idle timer skips, stale queued-run
behavior, and live checkout conflict preservation.
> - The benefit is a smaller, reviewable release-gate slice for budget
hard stops, stale execution recovery, and ownership-safe issue mutation.

## Linked Issues or Issue Description

Refs #8866

This PR extracts a focused backend safety slice from the closed broad
recovery PR. The underlying problem is that release-gate behavior needs
direct regression coverage before review: budget hard stops should not
duplicate incidents/logging on repeated evaluation, timer wakes should
respect the no-actionable-work skip policy, stale queued runs should
remain invalidated, and active checkout ownership must survive
conflicting checkout attempts without side effects.

## What Changed

- Made budget incident creation report whether an incident was newly
created, so soft/hard threshold activity logs are emitted once per
incident window.
- Added embedded Postgres budget release-gate tests covering soft
incident idempotency, hard-stop pause/cancel behavior, budget override
resume behavior, and telemetry redaction.
- Added heartbeat coverage for skipping generic timer wakes when the
agent opts into `skipTimerWhenNoActionableWork`, while preserving
legacy/proactive timer behavior.
- Added stale execution lock route coverage proving a conflicting
checkout returns `409` without overwriting live checkout or execution
ownership and without writing checkout activity.

## Verification

- `./node_modules/.bin/vitest run
server/src/__tests__/budgets-service.test.ts
server/src/__tests__/heartbeat-process-recovery.test.ts
server/src/__tests__/heartbeat-stale-queue-invalidation.test.ts
server/src/__tests__/issue-stale-execution-lock-routes.test.ts
--no-file-parallelism --maxWorkers=1`
- First run: 3 files passed, 98 tests passed;
`issue-stale-execution-lock-routes.test.ts` failed during import because
the isolated worktree initially lacked dev dependency links for
`supertest`.
- `CI=true NODE_ENV=development pnpm install --frozen-lockfile
--ignore-scripts`
- Recreated worktree dev dependency links; emitted unrelated plugin SDK
bin warnings because plugin SDK dist files were not built under
`--ignore-scripts`.
- `./node_modules/.bin/vitest run
server/src/__tests__/issue-stale-execution-lock-routes.test.ts
--no-file-parallelism --maxWorkers=1`
  - Passed: 1 file, 7 tests.
- `git diff --check`
  - Passed.

## Risks

Low to medium risk. The production code change is intentionally small
and only suppresses duplicate threshold activity logging for
already-open budget incidents, but it affects budget release-gate
observability. The new tests use embedded Postgres and should catch
regressions in budget hard stops, timer wake gating, stale queue
invalidation, and checkout conflict preservation.

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

## Model Used

OpenAI Codex, GPT-5 coding agent, tool-use enabled.

## 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-07-06 16:33:36 -05:00
DottaandPaperclip dfc256a543 [codex] Add heartbeat policy eval coverage (#9087)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents for work.
> - The relevant subsystem is the agent heartbeat policy surface: the
Paperclip skill, default onboarding AGENTS.md, new-agent runtime
defaults, and promptfoo eval coverage for agent behavior.
> - A broad recovery PR collected several unrelated local-mainline
changes, which made review too large and mixed policy/eval updates with
server execution and UI work.
> - This PR extracts only the heartbeat policy and prompt-eval slice so
reviewers can assess the behavior contract independently.
> - The eval additions cover scoped wake handling, idle no-op behavior,
dependency-blocked comment triage, final disposition, budget hard stops,
and Phase 5 memory/control-surface policy expectations.
> - The benefit is a narrower review surface plus deterministic
follow-up guidance for server/shared tests that should back these
prompt-level checks.

## Linked Issues or Issue Description

Refs #8866

No public issue was filed for this split. This is a focused extraction
from the closed broad recovery PR so heartbeat policy and eval coverage
can be reviewed separately from execution behavior, work-product feature
work, plugin hardening, pipeline health, and unrelated UI polish.

## What Changed

- Added promptfoo release-gate cases for scoped wake payload handling,
idle exits, dependency-blocked comment triage, final disposition, and
budget hard-stop behavior.
- Added Phase 5 memory/control-surface prompt eval cases for provider
binding precedence, provenance/audit fields, hook cost/trust handling,
and auditable board command surfaces.
- Documented how these prompt evals map to deterministic server/shared
follow-up coverage.
- Updated agent policy guidance so operator-facing engineering outputs
such as PRs, branches, commits, previews, and runtime services get
matching work products.
- Defaulted new agent runtime config to skip timer heartbeats when there
is no actionable work, with focused test coverage.

## Verification

- `cd evals/promptfoo && npx promptfoo@latest validate -c
promptfooconfig.yaml` passes.
- `/srv/paperclip/home/paperclipai/paperclip/node_modules/.bin/vitest
run ui/src/lib/new-agent-runtime-config.test.ts` passes in an isolated
worktree after `pnpm install --ignore-scripts --frozen-lockfile` created
workspace links.
- A live promptfoo eval was not run because `OPENROUTER_API_KEY`,
`OPENAI_API_KEY`, and `ANTHROPIC_API_KEY` were unset in the workspace.

## Risks

Low-to-medium risk. The runtime default reduces timer-driven empty
heartbeats for newly created agents, so the main behavioral risk is
missing an edge case where timer wakes were expected despite no
actionable work. The promptfoo additions are deterministic assertion
coverage and documentation-only until a live eval is run with provider
credentials.

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

## Model Used

OpenAI GPT-5-based Codex coding agent in the Paperclip local Codex
adapter environment; exact hosted model ID and context window were not
exposed to the agent runtime. Tool use included shell, git, promptfoo
validation, Vitest, and the GitHub connector/CLI.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [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-07-06 16:31:14 -05:00
DottaandPaperclip 903886bc79 [codex] Add starred resource sidebar controls (#9085)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board UI is the main daily navigation surface for agents,
projects, and their related resources.
> - Operators need a lightweight way to keep frequently used agents and
projects close without changing company-wide ordering or ownership.
> - Resource memberships already model per-user relationships to
projects and agents, so they are the right place to store user-specific
starred state.
> - This pull request extends that membership contract with a starred
timestamp and exposes star controls in list/detail views.
> - The sidebar then uses those starred memberships to show compact,
user-specific shortcuts.
> - The benefit is faster navigation without introducing a separate
favorites system or leaking preferences across users.

## Linked Issues or Issue Description

No public GitHub issue exists.

Feature request:

## Problem or motivation

Users cannot pin frequently used agents or projects into the main
sidebar. Returning to important resources requires scanning full
project/agent lists or navigating through detail pages, which adds
friction to repeated daily workflows.

## Proposed solution

Store a per-user `starred_at` timestamp on agent and project
memberships, expose API actions to set or clear that state, add star
toggle controls to list/detail pages, and render starred projects and
agents as compact sidebar shortcuts.

## Alternatives considered

A separate favorites table would work, but it would duplicate membership
scoping and require another resource relationship model. Keeping starred
state on memberships preserves existing company/user boundaries and
avoids a second source of truth.

## Roadmap alignment

Checked `ROADMAP.md`; no overlapping planned core work for starred
resource/sidebar navigation was found.

## Additional context

The affected subsystems are `packages/db`, `packages/shared`, `server/`,
and `ui/`. The migration is idempotent with `IF NOT EXISTS` guards so
environments that saw an earlier local migration name can still apply
the final ordered migration safely.

## What Changed

- Added idempotent migration `0133_resource_membership_stars` for
`starred_at` columns and lookup indexes on agent/project memberships.
- Extended shared resource membership types and validators with starred
metadata and actions.
- Updated server resource membership services/routes to read and mutate
starred resource state.
- Added reusable star toggle UI and resource membership hook support for
starred state.
- Added starred projects and agents sidebar rendering, plus star
controls on list and detail pages.
- Added focused shared, server, and UI coverage for starred membership
behavior and sidebar rendering.

## Verification

- Rebased and force-with-lease pushed current PR head
`a086fc965391c9e50a51b5b83b5b44a797b2a6f4` onto current
`paperclipai/paperclip:master`; `gh pr view` reports `MERGEABLE` with no
merge conflicts. GitHub checks are green for this fresh head.
- `pnpm exec vitest run packages/shared/src/resource-memberships.test.ts
server/src/__tests__/resource-memberships-routes.test.ts
server/src/__tests__/workspace-runtime.test.ts
ui/src/components/Sidebar.test.tsx
ui/src/components/SidebarAgents.test.tsx
ui/src/components/SidebarStarredProjects.test.tsx
ui/src/components/StarToggle.test.tsx
ui/src/pages/InstanceExperimentalSettings.test.tsx` passed after the
rebase: 8 files, 143 tests.
- Greptile re-review is 5/5; the remaining screenshot thread was
resolved as non-blocking because this task explicitly requested no
screenshots/images in the PR.
- `pnpm exec vitest run
ui/src/components/SidebarStarredProjects.test.tsx` passed after the
mobile pending-spinner fix.
- `pnpm exec vitest run packages/shared/src/resource-memberships.test.ts
server/src/__tests__/resource-memberships-routes.test.ts
ui/src/components/Sidebar.test.tsx
ui/src/components/SidebarAgents.test.tsx
ui/src/components/SidebarStarredProjects.test.tsx
ui/src/components/StarToggle.test.tsx
ui/src/pages/InstanceExperimentalSettings.test.tsx` passed: 7 files, 68
tests.
- `pnpm --filter @paperclipai/db typecheck && pnpm --filter
@paperclipai/shared typecheck && pnpm --filter @paperclipai/server
typecheck && pnpm --filter @paperclipai/ui typecheck` passed
db/shared/server, then failed in pre-existing UI code outside this PR:
`src/pages/CompanyEnvironments.tsx` missing `@xterm/*` type declarations
and `previous` possibly null.
- Checked that the PR diff does not include `pnpm-lock.yaml` or
`.github/workflows` changes.
- Checked `ROADMAP.md` and found no overlapping planned core work for
starred resource/sidebar navigation.
- Searched existing GitHub PRs for duplicate starred-resource/sidebar
work and found none.

## Risks

- Migration touches membership tables. The SQL uses `IF NOT EXISTS` for
columns and indexes so environments that saw an earlier local migration
name can still apply this safely.
- Sidebar ordering and visibility changes could affect users who rely on
the previous flat sidebar layout.
- Starred state is per-user membership metadata; code paths must
continue preserving company/user scoping around memberships.

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

## Model Used

OpenAI GPT-5 Codex, tool-enabled coding agent with shell/GitHub access.
Context window not disclosed by the runtime.

## 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-07-06 14:09:11 -05:00
Nicky LeachandPaperclip 8516700217 fix(server): report source-install version from git metadata (#9103)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The server reports its own version through `server/src/version.ts`,
which is read by the `/health` endpoint and the telemetry client
> - When running from a cloned source tree, `server/package.json` is
frozen at the last published release version (e.g. `0.3.1`), so the
reported `serverVersion` never reflects how far the local checkout has
drifted from that release
> - Operators and support staff cannot tell from telemetry or health
output whether they are running a tagged release or a development build
with local commits on top
> - A `git describe --tags --match v* --long --dirty` call at startup
gives the exact nearest tag, number of commits since it, the current
SHA, and whether the tree is dirty — all the information needed to
compute a semantically meaningful version
> - This pull request replaces the static `pkg.version` export with a
`resolveServerVersion()` call that parses `git describe` output into
`YYYY.MDD.P+N.git.<sha>` (drift), `YYYY.MDD.P` (clean on-tag), or
appends `.dirty` for a modified tree, with a non-throwing fallback to
`package.json` when git is unavailable
> - The benefit is that from-source installs now report a version string
that lets operators and support quickly identify their exact checkout
state without running additional git commands

## Linked Issues or Issue Description

No pre-existing public issue. Inline description:

**What happened?**

When Paperclip is installed from source (git clone + pnpm), `GET
/health` and the telemetry envelope report the version frozen at the
last published `package.json` value (e.g. `0.3.1`) regardless of how
many commits ahead of that tag the local checkout is.

**Expected behavior**

The reported version should reflect the actual local state — nearest
release tag, number of commits since that tag, abbreviated commit SHA,
and a dirty marker when the working tree has uncommitted changes.

**Steps to reproduce**

Clone the repo, run `pnpm install && pnpm --filter @paperclipai/server
start`, then call `GET /health` or inspect telemetry envelopes. The
`serverVersion` field shows the `package.json` version even when the
checkout is dozens of commits ahead of that tag.

**Paperclip version or commit**

Affects all source-tree installs where `package.json` has not been
updated to match the current HEAD.

**Deployment mode**

Source install (git clone).

## What Changed

- `server/src/version.ts`: extracted `resolveServerVersion()` (replaces
the module-level `const serverVersion`) and `parseGitDescribeVersion()`
(exported for unit testing); the default implementation shells out to
`git describe --tags --match v* --long --dirty` with a 1 500 ms timeout;
falls back to `pkg.version ?? "0.0.0"` without throwing when git is
unavailable or the output cannot be parsed; replaced `logger` import
with a `console.debug`-based default to avoid pulling pino transport
side effects into a zero-dependency utility module
- `server/src/__tests__/version.test.ts`: 7-test unit suite covering
drift, clean on-tag collapse, dirty on-tag edge case, unparseable
fallback, `resolveServerVersion` happy path, and git-unavailable
fallback — all exercised via injected stubs without spawning a real git
process

## Verification

```sh
# Unit tests (7 tests)
pnpm exec vitest run server/src/__tests__/version.test.ts

# Type check
pnpm --filter @paperclipai/server typecheck

# Health and telemetry regression
pnpm exec vitest run server/src/__tests__/health.test.ts server/src/__tests__/telemetry-client-flush.test.ts

# Runtime smoke (from-source checkout)
# git describe --tags --match 'v*' --long  =>  v2026.626.0-58-g518fc71ce
# server startup => serverVersion = 2026.626.0+59.git.3367571cc
```

All commands passed at the committed HEAD.

## Risks

Low. The change is additive and self-contained to
`server/src/version.ts`:

- `git describe` is called once at module load with a 1 500 ms timeout;
failure (non-git environment, git not on PATH, timeout) is silently
caught and falls back to `pkg.version`, preserving existing behavior for
published-package installs
- No API surface, database schema, or migration is touched
- The telemetry envelope already carried `serverVersion`; only the value
changes for source-tree installs

## Model Used

Claude Sonnet 4.6 (`claude-sonnet-4-6`) with tool use and code
execution. Context window: 200 k tokens.

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-06 09:15:44 -07:00
Nicky LeachandPaperclip 8a058f9d79 fix: deduplicate adapter-agnostic config keys (#9058)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - When you swap an agent's adapter (e.g. from one LLM provider to
another), the server merges the incoming PATCH body with stored config —
keys listed in \`ADAPTER_AGNOSTIC_KEYS\` are preserved regardless of
which adapter is active
> - That constant was defined independently in two places:
\`server/src/agents.ts\` (used by the adapter-swap route) and
\`ui/src/lib/agent-config-patch.ts\` (used by the UI patch builder)
> - PR #8975 fixed the bug where \`paperclipSkillSync.desiredSkills\`
was dropped on adapter swap by adding it to the server-side constant,
but the UI-side copy was not updated in the same PR — creating ongoing
drift risk
> - This pull request hoists \`ADAPTER_AGNOSTIC_KEYS\` into
\`packages/shared\` so both consumers import the same constant
> - The benefit is a single source of truth: any future key addition is
made in one place and both the server route and the UI patch builder
pick it up automatically, with a drift guard to catch any accidental
re-duplication

## Linked Issues or Issue Description

Refs #8975 — follow-up deduplication: #8975 fixed the runtime bug but
left the constant duplicated across server and UI. This PR closes that
gap.

## What Changed

- Added \`ADAPTER_AGNOSTIC_KEYS\` constant and \`AdapterAgnosticKey\`
type to \`packages/shared/src/adapter-agnostic-keys.ts\`
- Updated \`server/src/agents.ts\` to import the shared constant,
removing the local copy
- Updated \`ui/src/lib/agent-config-patch.ts\` to import the shared
constant, removing the local copy
- Added \`packages/shared/src/adapter-agnostic-keys.test.ts\`: drift
guard asserting the expected key set and both consumer import sites

## Verification

\`\`\`bash
pnpm exec vitest run packages/shared/src/adapter-agnostic-keys.test.ts
ui/src/lib/agent-config-patch.test.ts
server/src/__tests__/agent-instructions-routes.test.ts
pnpm --filter @paperclipai/shared typecheck
pnpm --filter @paperclipai/server typecheck
pnpm --filter @paperclipai/ui typecheck
\`\`\`

All 15 tests pass across the three files; all three packages typecheck
clean.

## Risks

Low risk — behavior-preserving refactor. The key set is unchanged; only
the import source changes. The drift guard will fail loudly if someone
accidentally re-introduces a local copy or modifies one without updating
the other.

> 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
- Model: Claude Sonnet 4.6 (\`claude-sonnet-4-6\`)
- Context: standard context window, tool use enabled
- Reasoning: standard mode (no extended thinking)

## 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)
- [ ] 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
- [ ] 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-07-05 21:47:38 -07:00
ad961227f5 feat(secrets): add user-specific runtime secrets (#8825)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent runs often need provider credentials, API tokens, and other
environment-bound secrets.
> - Company-level secrets work for shared credentials, but they do not
model values that should differ by human operator.
> - Without a user-scoped model, a run can dispatch without knowing
whether the responsible human has supplied the needed value.
> - Paperclip also needs run attribution to make those user-scoped
runtime checks deterministic and auditable.
> - This pull request adds user-specific secret definitions, per-user
values, environment bindings, responsible-user attribution, and runtime
resolution gates.
> - The benefit is that teams can define the secret once, let each user
provide their own value, and block runs before dispatch when required
user secrets or active definitions are unavailable.

## Linked Issues or Issue Description

Refs #224
Refs #6057

This PR implements user-specific secret support as a core
secret-management capability rather than a one-off adapter setting. It
is related to existing public work on company secrets UI and runtime
secret refs, but is distinct because the value is owned by the
responsible user and resolved at run dispatch time.

Related PR search before opening found existing secrets work such as
#1550, #8256, #8614, #8634, and #8647; none of those add the full
user-secret definition/value/runtime gate covered here.

## What Changed

- Added user-secret definitions and per-user "My secrets" values,
keeping stored values out of access metadata.
- Added `user_secret_ref` environment bindings and UI affordances to
pick them alongside existing secret refs.
- Added responsible-user runtime resolution so user-secret refs resolve
against the human responsible for the run.
- Added pre-dispatch missing-secret gates so runs fail before adapter
dispatch when required user values are absent or definitions are
inactive.
- Added low-trust allowlist hardening for user-secret runtime access.
- Added issue, routine, run, and agent API key responsible-user
attribution and fail-closed dispatch behavior when attribution cannot be
resolved.
- Added denial-copy mapping so responsible-user authorization failures
surface as actionable run outcomes instead of opaque setup failures.
- Added OpenAPI documentation for the user-secret routes.
- Rebases cleanly on current `master`; migrations were renumbered
incrementally as `0128_user_specific_secrets`,
`0129_agent_api_key_responsible_user`, and
`0130_run_responsible_user_invariant` after upstream `0126`/`0127`
migrations.
- Removed previously committed local design screenshots so the PR
contains code/docs/tests only.

## Verification

- PASS: PR head `2527febd106bcf3ca264ca0da7fca491084192d6` is based on
`paperclipai/paperclip:master`.
- PASS: `git diff --check`
- PASS: `git diff --name-only public/master...HEAD | rg
'^(pnpm-lock\\.yaml|\\.github/workflows/|screenshots/)' || true`
produced no files.
- PASS: migration journal audit confirmed unique indexes through `130`
with tail entries `0126_issue_comment_derived_attribution`,
`0127_environment_custom_images_instance_scoped`,
`0128_user_specific_secrets`, `0129_agent_api_key_responsible_user`, and
`0130_run_responsible_user_invariant`.
- PASS: `pnpm --filter @paperclipai/ui typecheck`
- PASS: `pnpm --filter @paperclipai/server typecheck`
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-responsible-user-invariant.test.ts`
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-active-run-output-watchdog.test.ts
src/__tests__/heartbeat-stale-queue-invalidation.test.ts
src/__tests__/heartbeat-workspace-finalize-branch.test.ts
src/__tests__/issue-monitor-scheduler.test.ts`
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-comment-wake-batching.test.ts
src/__tests__/heartbeat-retry-scheduling.test.ts
src/__tests__/heartbeat-accepted-plan-workspace-refresh.test.ts
src/__tests__/heartbeat-plugin-environment.test.ts`
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/low-trust-red-team-routes.test.ts`
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/secrets-service.test.ts` (55 tests)
- PASS: `pnpm vitest run server/src/__tests__/secrets-routes.test.ts
server/src/__tests__/secrets-service.test.ts` (89 tests after final
Greptile cleanup fixes)
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-issue-liveness-escalation.test.ts` (17 tests
after the final rebase CI fix)
- PASS: focused server Vitest batches covering heartbeat recovery,
project env, plugin env, routines, low-trust, pipelines, monitors,
watchdog, and stale queue paths.
- PASS: GitHub checks are green on
`2527febd106bcf3ca264ca0da7fca491084192d6`, including Typecheck +
Release Registry, Build, General tests, serialized server suites, e2e,
Canary Dry Run, verify, security checks, and Greptile Review.
- PASS: Greptile Review completed successfully on
`2527febd106bcf3ca264ca0da7fca491084192d6` with Confidence Score 5/5,
and GraphQL review-thread audit returned zero unresolved non-outdated
threads.

## Risks

- Runtime behavior now depends on a run having a correct responsible
user; missing or incorrect responsibility assignment can block runs
before adapter dispatch.
- `user_secret_ref` bindings intentionally expose metadata without
values, but UI/API callers may need to handle the new binding kind
explicitly.
- External secret providers and IAM policies are not automatically
provisioned by this PR; operators still need to configure provider-side
access for non-local vaults.
- The PR is broad across db/shared/server/UI/runtime paths, so release
validation should include both API and UI secret workflows before merge.
- The migration renumbering is intentionally incremental after upstream
migrations; the branch migrations use guarded
column/table/index/constraint creation so users who tested the older
draft numbering should not hit duplicate DDL for the existing objects.

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

## Model Used

OpenAI Codex, GPT-5-based coding agent (`gpt-5`), Codex local adapter
with shell/tool use and code execution. Context window and internal
reasoning mode are not exposed by the runtime.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 05:58:20 -05:00
fengqing eb2cb916be fix(agents): preserve skill selection when switching adapter type (#8975)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Each agent runs on an adapter (`claude_local`, `codex_local`, …) and
can be assigned company skills that are synced into its runtime
> - An agent's desired-skill selection is persisted inside its single
`adapterConfig` JSON blob under `paperclipSkillSync`, even though the
selection is a company-level, adapter-agnostic choice
> - When a user changes an agent's adapter type, both the server PATCH
handler and the UI patch builder rebuild `adapterConfig` and carry over
only a hardcoded allow-list of adapter-agnostic keys (`env`, `cwd`,
instructions bundle, …)
> - `paperclipSkillSync` was missing from both allow-lists, so switching
adapters (e.g. claude_local → codex_local) silently wiped every assigned
skill
> - This pull request adds `paperclipSkillSync` to the adapter-agnostic
preservation list on both layers and covers it with regression tests
> - The benefit is that switching an agent's adapter no longer destroys
its skill configuration — skills are preserved exactly like
env/cwd/instructions already are

## Linked Issues or Issue Description

Fixes #8974

## What Changed

- **Server (authoritative fix)** — `server/src/routes/agents.ts`: added
`"paperclipSkillSync"` to the `ADAPTER_AGNOSTIC_KEYS` list in the
`changingAdapterType` branch of `PATCH /agents/:id`. On an adapter-type
change the handler now restores the skill-sync selection from the
existing persisted config when the incoming config omits it — the same
mechanism already used for `env`, `cwd`, and the instructions bundle.
This protects every API/CLI client, not just the UI.
- **UI (defense in depth)** — `ui/src/lib/agent-config-patch.ts`: added
`"paperclipSkillSync"` to the client-side `ADAPTER_AGNOSTIC_KEYS` in
`buildAgentUpdatePatch`, so the optimistic patch the client builds on an
adapter switch stops stripping the key before it reaches the server.
- **Tests** — added regression tests on both layers:
- `server/src/__tests__/agent-instructions-routes.test.ts`: `PATCH`ing
`adapterType` (claude_local → codex_local) with `replaceAdapterConfig:
true` keeps `adapterConfig.paperclipSkillSync`.
- `ui/src/lib/agent-config-patch.test.ts`: `buildAgentUpdatePatch`
preserves `paperclipSkillSync` when the overlay changes the adapter
type.

## Verification

```
# server (run from repo root)
cd server && ../node_modules/.bin/vitest run \
  src/__tests__/agent-instructions-routes.test.ts \
  src/__tests__/agent-skills-routes.test.ts \
  src/__tests__/agent-adapter-validation-routes.test.ts \
  src/__tests__/agent-permissions-routes.test.ts
# 83 passed
../node_modules/.bin/tsc --noEmit -p tsconfig.json   # clean

# ui
cd ui && ./node_modules/.bin/vitest run src/lib/agent-config-patch.test.ts   # 7 passed
pnpm --filter @paperclipai/ui typecheck   # clean
```

Both new tests fail without the corresponding source change (verified
red → green).

Manual: create an agent on `claude_local`, assign skills, switch it to
`codex_local`, and confirm `GET /api/agents/:id/skills` still returns
the desired skills.

## Risks

Low risk.

- The change only *adds* one key to an existing preservation allow-list;
it does not alter how any other key is handled. Behavior for agents
without a `paperclipSkillSync` block is unchanged (the key is simply
absent and nothing is copied).
- `paperclipSkillSync` is adapter-agnostic (company skill keys, not
adapter-specific), so carrying it across an adapter switch is always
safe — a target adapter that does not support skill sync just ignores
it, and switching back restores the selection.
- Same-adapter config edits already merged and preserved the key; this
only closes the adapter-type-change gap, matching the existing
env/cwd/instructions behavior.
- Follow-up (not in this PR to keep it minimal): the server and client
`ADAPTER_AGNOSTIC_KEYS` lists are maintained separately and already
diverge (`instructionsFilePath` is client-only); a shared constant could
prevent future drift.

## Model Used

Claude Opus 4.8 (`claude-opus-4-8`, 1M-token context), extended thinking
enabled, with tool use (file edit, shell, GitHub CLI) via Claude Code. A
read-only sub-agent was used to trace the root cause across the server
and UI layers.

## 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 (bug fix, not a feature)
- [x] I have searched GitHub for duplicate or related PRs and linked
them above (none found)
- [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
(`fix/preserve-skills-on-adapter-type-switch`) 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 (N/A —
internal config-preservation fix, no user-facing docs or API contract
change)
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green (pending CI on this PR)
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
(pending review)
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-07-04 15:25:01 -07:00
Devin FoleyandPaperclip a328ec953a Fix inherited workspace reuse fallback (#8963)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent heartbeats provision execution workspaces before invoking
local or sandboxed adapters.
> - Some follow-up issues intentionally request `reuse_existing` so they
continue in an inherited execution workspace.
> - The heartbeat provisioning path treated missing or archived
workspace rows as if no explicit reuse request existed.
> - That could silently realize and persist a fresh project/default
workspace over an explicit inherited-workspace binding.
> - This pull request keys explicit reuse off the issue preference and
workspace id, then either restores that workspace or fails with a
structured workspace validation error.
> - The benefit is that intentional workspace inheritance remains
auditable and does not silently degrade into unrelated fallback
workspaces.

## Linked Issues or Issue Description

Refs #8058
Refs #6036
Refs #2203

This fixes a narrower heartbeat provisioning bug around explicit
`reuse_existing` issue runs: if the target inherited execution workspace
is missing, archived, or fails restore, provisioning now reports the
reuse failure instead of replacing the issue's workspace binding with a
freshly realized fallback.

## What Changed

- Added explicit helpers for resolving workspace reuse requests and
deciding whether reuse should restore, refresh metadata, or keep prior
replacement-class drift visible.
- Changed heartbeat workspace provisioning so explicit `reuse_existing`
requests go through restore-or-fail behavior instead of falling back to
`realizeExecutionWorkspace` when the stored workspace row is
unavailable.
- Added structured `workspace_validation_failed` details for inherited
workspace reuse failures.
- Added regression coverage for replacement-class drift, restore errors,
missing rows, archived rows, and restore misses.

## Verification

- `pnpm install --frozen-lockfile`
- `pnpm --filter @paperclipai/plugin-sdk ensure-build-deps`
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-workspace-session.test.ts`
- `pnpm --filter @paperclipai/server typecheck`
- `git diff --check origin/master...HEAD`
- Scanned the branch diff and commit messages for credentials, tokens,
private URLs, PII-style values, and internal issue links before pushing;
no unsafe hits remained.

## Risks

- Explicit reuse requests whose stored workspace cannot be restored now
fail the run instead of opportunistically creating a replacement
workspace. That is intentional, but it may surface stale or archived
workspace rows as visible provisioning failures that require repair.
- Non-reuse workspace provisioning still uses the existing realization
path, so the behavior shift is scoped to issues that explicitly request
existing workspace reuse.

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

## Model Used

OpenAI GPT-5 via Codex local agent, with shell/tool use enabled for
repository inspection, code editing, verification, git, and GitHub CLI
operations. Runtime context-window details were not exposed by the
adapter.

## 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-07-04 06:35:06 -07:00
Nicky Leach 7bfaaadcb8 Add dependency wake reconciliation backstop (#8943) 2026-07-03 18:30:51 -07:00
Devin FoleyandPaperclip bcac517f3b Add browser SSH terminal for custom image setup (#8911)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Environment sandboxes already support custom image creation and
refresh through a temporary SSH setup session.
> - The existing workflow makes operators copy an SSH command into an
external terminal before they can install packages or make image
changes.
> - That extra context switch is slower, easier to get wrong, and less
integrated with the setup session Paperclip already tracks.
> - This pull request adds an embedded browser SSH terminal for custom
image setup, so operators can start working in the target sandbox
directly from the environment configuration flow.
> - The implementation uses short-lived websocket attachment tokens,
session-lifetime SSH host-key pinning, and server-managed terminal
cleanup so the feature fits the existing setup-session boundary.
> - The benefit is a smoother custom image creation and refresh
experience without asking users to leave Paperclip for routine sandbox
setup work.

## Linked Issues or Issue Description

No public GitHub issue exists.

### Subsystem affected

Cross-cutting: `server/` custom image setup APIs and websocket handling,
`ui/` environment configuration UI, and shared custom image contracts.

### Problem or motivation

Custom image creation and refresh require an operator to open a separate
SSH client, paste the command shown by Paperclip, perform setup work,
then return to the browser to finish the image flow. This is functional
but awkward for a setup process that already starts and tracks a
temporary sandbox session.

### Proposed solution

Embed an SSH terminal in the custom image setup UI. When a setup session
exposes an SSH payload, Paperclip should open a browser terminal backed
by a server-side websocket session, let the operator run setup commands
in-place, and then close the terminal when setup is finished, cancelled,
expired, or disconnected.

### Alternatives considered

- Keep the existing copy/paste SSH command workflow. This remains a
fallback, but it does not streamline the common path.
- Put SSH credentials directly into websocket URLs. This was avoided so
terminal authentication can happen in an explicit first websocket auth
frame rather than in logged URLs.
- Trust the SSH host blindly for every reconnect. This PR instead pins
the observed host-key fingerprint for the setup-session lifetime.

### Roadmap alignment

This fits the roadmap theme of making agent workspaces usable in more
remote and sandboxed environments while preserving Paperclip's
control-plane model.

### Additional context

Public GitHub search did not find a duplicate issue or PR for `custom
image terminal ssh` in `paperclipai/paperclip`.

## What Changed

- Added server-side terminal session tracking for custom image setup
sessions, including connect-token issuance, websocket attachment,
expiry, resize, input, and shutdown handling.
- Added an embedded browser terminal to the custom image creation and
refresh flow when a setup session provides SSH connection details.
- Moved terminal token authentication out of the websocket URL and into
the first websocket JSON auth frame.
- Added SSH host-key SHA-256 pinning for each terminal session and
documented the provider convention for username-embedded SSH
credentials.
- Updated the custom image environment API and UI so the setup terminal
can open, reconnect, show status, authenticate, resize, and remain
active for the setup-session lifetime once attached.
- Kept custom image setup routes company-scoped and closed active
terminal sessions on setup finish/cancel.
- Added focused unit/integration/UI coverage for token expiry,
setup-session expiry, websocket close paths, host-key pinning, and
terminal session lifecycle behavior.
- Removed the generated lockfile delta from the PR; CI owns temporary
lockfile regeneration for manifest-changing PRs.

## Verification

- `pnpm exec vitest run
server/src/__tests__/server-startup-feedback-export.test.ts
server/src/__tests__/environment-custom-image-terminal-ws.test.ts
server/src/services/environment-custom-image-terminal-sessions.test.ts
server/src/__tests__/environment-custom-image-routes.test.ts
packages/shared/src/environment-custom-images.test.ts
ui/src/pages/CompanyEnvironments.test.tsx`
  - 6 test files passed
  - 58 tests passed
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm --filter @paperclipai/server build`
- `pnpm --filter @paperclipai/ui build`
- `pnpm run typecheck:build-gaps`
- `git diff --check`
- Local sensitive-content scan over the PR diff using patterns for API
keys, private keys, private hostnames, local paths, token fields, and
credential-like strings.
- Findings were limited to removed URL-token code and synthetic test
placeholders such as `ssh-token-secret` and
`terminal-token-terminal-token-123456`.
- No real credentials, private hostnames, local filesystem paths, or
instance-local links were found.
- Remote PR checks were green after the implementation commit, including
Build, Typecheck + Release Registry, General tests, serialized server
suites, e2e, verify, Socket, Snyk, Superagent, and Greptile 5/5.
- Post-merge PR hardening on July 3, 2026: merged `origin/master` at
`47448721e` into the branch, resolved the `CompanyEnvironments.tsx`
import conflict, reran focused tests, server/UI typechecks, server/UI
builds, `pnpm run typecheck:build-gaps`, and `git diff --check`, scanned
the final diff for sensitive content, pushed `4b43558cc`, and confirmed
all remote checks plus Greptile 5/5 were green.
- PR metadata correction on July 3, 2026: changed the title/body framing
from bug-fix language to feature-request language. No source files
changed for this metadata-only update.

## Risks

- Moderate surface area because this adds websocket routing,
setup-session runtime state, package dependencies, and a new custom
image UI path.
- New websocket attachments still require valid short-lived tokens;
established terminal sessions remain bounded by setup-session expiry,
explicit finish/cancel, client close, or server shutdown.
- The terminal-session store is in-memory, so active terminal websocket
tokens and host-key pins do not survive server restarts.
- SSH host-key verification uses session-lifetime TOFU pinning because
the current provider payload does not expose a trusted host-key
fingerprint.
- The external SSH command remains important as a fallback if a browser,
proxy, or network environment cannot sustain the websocket terminal.

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

## Model Used

OpenAI Codex, GPT-5 coding agent with shell/tool execution. Context
window size was not exposed in this runtime.

## 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-07-03 16:44:21 -07:00
Dotta a6b7b12fd7 Harden work timeline security filters (#8923)
Squash merge PR #8923.

Verified before merge:
- PR head: 1d9a8f2291
- GitHub status/check rollup: all completed successfully
- Greptile Review: success, 5/5, no review threads
- Scope: server/src/services/work-timeline.ts and server/src/__tests__/work-timeline-service.test.ts
2026-07-03 05:19:14 -05:00
Devin FoleyandPaperclip c48feee190 Improve live agent feedback during sandboxed runs (#8915)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - A core part of that experience is watching active agent runs without
dropping into raw logs first
> - Local and sandbox-backed adapters already record useful run output,
progress, and tool activity
> - But active issue threads could sit visually stale while the agent
was syncing workspaces, tailing sandbox output, or emitting incremental
tool-call updates
> - Operators need timely, human-readable progress while preserving the
raw transcript underneath
> - This pull request streams sandbox run-log progress into runtime
status, keeps visible issue threads refreshed, and folds repeated ACPX
tool updates into stable transcript cards
> - The benefit is that long-running agent work becomes easier to
supervise without changing the task/comment control-plane model

## Linked Issues or Issue Description

No public GitHub issue exists for this exact change.

Problem/motivation:

- During long-running sandboxed agent work, the issue UI can appear idle
even though the agent is actively syncing, running tools, or producing
incremental output.
- Operators need realtime feedback at the issue-thread layer, not only
after opening raw logs or waiting for the final heartbeat result.
- Related public context: #1808 previously added live-run status dots to
Projects; #4362 touches heartbeat wakeup behavior but is not a duplicate
of this runtime/UI feedback change.

## What Changed

- Added sandbox run-log streaming support and defaulted sandbox-capable
local adapters into the richer live-feedback path.
- Surfaced environment/sandbox sync progress through heartbeat runtime
status with bounded, redacted snippets.
- Added live issue-thread cache patching so visible active runs update
as progress events arrive.
- Folded repeated ACPX `tool_call` updates into one transcript card
instead of stacking duplicate cards.
- Updated adapter docs and added focused regression coverage for sandbox
log streaming, runtime status, ACPX parsing, live updates, transcript
rendering, and issue chat messages.

## Verification

- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/context/LiveUpdatesProvider.test.ts`
- `pnpm exec vitest run
server/src/services/heartbeat-run-runtime-status.test.ts
server/src/__tests__/heartbeat-runtime-state.test.ts
ui/src/context/LiveUpdatesProvider.test.ts`
- `pnpm exec vitest run
packages/adapter-utils/src/execution-target-sandbox.test.ts
packages/adapter-utils/src/sandbox-managed-runtime.test.ts
server/src/services/heartbeat-run-runtime-status.test.ts
server/src/__tests__/agent-live-run-routes.test.ts
server/src/__tests__/heartbeat-runtime-state.test.ts
packages/adapters/acpx-local/src/ui/parse-stdout.test.ts
ui/src/context/LiveUpdatesProvider.test.ts
ui/src/components/transcript/RunTranscriptView.test.tsx
ui/src/lib/issue-chat-messages.test.ts
ui/src/components/IssueChatThread.test.tsx`
- GitHub PR workflow on head `8397953e7b41ccd42e5d9457ee7e4dfb996e4ec5`:
`verify`, build, typecheck/release-registry, e2e, general shards,
serialized server shards, and canary dry run passed.
- Greptile Review on head `8397953e7b41ccd42e5d9457ee7e4dfb996e4ec5`:
Confidence Score 5/5, no unresolved review threads.

## Risks

- Live issue-thread cache patching could miss an edge case for a route
shape not covered by tests.
- Surfacing active-run snippets needs continued care around redaction;
this PR keeps snippets bounded and adds redaction-focused coverage.
- More frequent active-run UI refreshes could expose performance issues
on very large issue threads, though updates are scoped to visible
run/query caches.

## Model Used

OpenAI GPT-5 via Codex, operating as a tool-enabled coding agent with
shell, git, and repository-editing capabilities. Context window size is
not exposed in this runtime.

## 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-07-02 22:21:56 -07:00
Devin FoleyandPaperclip 936687ca55 fix(workspace): restore clean branch drift on finalize (#8914)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent runs can execute inside reusable, runtime-created git worktree
execution workspaces.
> - Those managed worktrees record the expected branch so later
dispatches do not accidentally run an agent in the wrong checkout.
> - Successful run finalization already checked branch coherence, but it
treated every unrecorded branch switch as fatal.
> - A common publishing flow can briefly switch a clean worktree to a
PR/publish branch that points at the same commit as the recorded issue
branch, leaving no divergent work to protect.
> - This pull request keeps the strict finalization guard for unsafe
drift, but lets finalization restore the recorded branch when
same-commit repair is provably safe.
> - The benefit is fewer false failed runs after harmless branch
switches while preserving hard failures for divergent or dirty
worktrees.

## Linked Issues or Issue Description

No public issue exists for this exact finalization failure. Related
public worktree-recovery context: #3087 and #3056, but those address
different worktree realization/reuse recovery paths rather than
successful-run finalization branch repair.

Bug report details:

**What happened?**

When an adapter run succeeded after switching a managed git worktree
from its recorded issue branch to a publish/PR branch, finalization
failed with a managed worktree branch mismatch even when the publish
branch and recorded branch pointed at the same commit and the worktree
was clean.

**Expected behavior**

Finalization should restore the recorded branch only when it can prove
the worktree is clean, registered, and the recorded branch points at the
current `HEAD`. If the actual branch has different commits or unsafe
state, finalization should continue to fail with bounded validation
evidence.

**Steps to reproduce**

1. Create a runtime-managed `git_worktree` execution workspace for an
issue run.
2. During the adapter run, create and check out a new publish branch
without committing new changes.
3. Return adapter success and let heartbeat finalization run.
4. Before this change, finalization records a failed branch check and
fails the run even though the branches point at the same commit.
5. With this change, finalization records the repair operation, restores
the recorded branch, and records a successful finalize row.
6. Repeat with a commit on the publish branch; finalization still fails
because the branch heads differ.

**Paperclip version or commit**

Reproduced against `master` at `bac7307ec`; fixed by this PR at
`64ec605cf`.

**Deployment mode**

Local dev / built from source.

**Agent adapter(s) involved**

Not adapter-specific. This is core heartbeat/workspace finalization
behavior.

**Database mode**

Embedded test Postgres in the focused server test.

**Access context**

Agent run finalization.

**Node.js version**

`v25.6.1`

**Operating system**

`Darwin 24.6.0 arm64`

**Relevant logs or output**

The new focused test intentionally exercises both outcomes:

```text
Test Files  1 passed (1)
Tests       3 passed (3)
```

**Relevant config**

Runtime-created `git_worktree` execution workspace.

**Additional context**

The unsafe divergent branch case still fails with
`workspace_validation_failed` and `git_worktree_branch_incoherence`
evidence.

**Privacy checklist**

Reviewed; this description avoids internal task links, local workspace
paths, credentials, and instance-specific URLs.

## What Changed

- Reused the existing guarded branch-coherence repair helper during
heartbeat finalization when the final branch inspection finds clean
same-commit branch drift.
- Recorded repair metadata in the `workspace_finalize` operation so
reviewers/operators can audit whether finalization repaired branch
drift.
- Preserved failure behavior for divergent branch heads and surfaced the
bounded workspace validation evidence from the repair helper.
- Added focused server coverage for safe finalization repair and unsafe
divergent branch failure.
- Updated execution semantics docs to describe the narrower finalization
rule.

## Verification

- `pnpm exec vitest run
server/src/__tests__/heartbeat-workspace-finalize-branch.test.ts`
- `pnpm --filter @paperclipai/server typecheck`
- `git diff --check`

## Risks

Low to medium risk. The change affects successful-run finalization for
runtime-created git worktree execution workspaces. The repair path is
constrained to clean, registered, same-commit branch drift, and the
focused test confirms divergent branch heads still fail instead of being
restored silently.

## Model Used

OpenAI Codex, GPT-5-based coding agent. Exact hosted model ID was not
exposed in the runtime; tool use and local shell execution were enabled.

## 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-07-02 20:58:26 -07:00
DottaandPaperclip 246e1b38bf [codex] Include checkbox selections in continuation wakes (#8893)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Issue-thread interactions are the subsystem that lets board users
answer structured prompts and resume agent work
> - Checkbox confirmations capture a selected subset of known options,
then wake the assignee through continuation context
> - The wake context previously carried generic interaction metadata,
but not the accepted checkbox option ids or option labels
> - That meant the resumed agent could be woken after a checkbox
confirmation without seeing the board's selected options in the turn
context
> - This pull request carries accepted checkbox selections through the
interaction continuation wake snapshot and renders them into the adapter
wake prompt
> - The benefit is that agents can act on checkbox-confirmation
selections without refetching or guessing the user's choices

## Linked Issues or Issue Description

No public GitHub issue exists for this bug. Searched public issues and
PRs for checkbox confirmation / continuation selection duplicates and
found no matching issue or PR.

### Pre-submission checklist

- [x] I have searched existing open and closed issues and this is not a
duplicate.
- [x] I am on the latest released version of Paperclip or can reproduce
on `master`.
- [x] I have confirmed the error originates in Paperclip itself, not in
my agent adapter, API provider, or local configuration.

### What happened?

When a board user accepted a `request_checkbox_confirmation`
interaction, the assignee continuation wake included generic interaction
metadata but did not include the accepted checkbox selections. The
resumed agent turn therefore had no in-prompt access to the selected
option ids or option labels/descriptions.

### Expected behavior

When a `request_checkbox_confirmation` interaction is accepted, the
resumed agent wake should include the checkbox prompt, selected option
ids, and selected option labels/descriptions so the agent can act on the
selected subset directly.

### Steps to reproduce

1. Create an issue-thread `request_checkbox_confirmation` interaction
with multiple options and `continuationPolicy: "wake_assignee"`.
2. Accept the interaction with one or more selected options.
3. Inspect the continuation wake payload/prompt received by the
assignee.
4. Observe that the selected checkbox options are missing from the wake
context before this fix.

### Paperclip version or commit

Reproduced against the pre-fix code path on `master`; this PR head is
`9d17e70bce373e4850117f30c015c973c4b61789`.

### Deployment mode

Local dev (pnpm dev) / built from source.

### Installation method

Built from source (pnpm dev / pnpm build).

### Agent adapter(s) involved

Not adapter-specific (core bug). The Codex/local adapter path exposed
the missing wake context, but the missing field was in core interaction
continuation payload construction.

### Database mode

Embedded PGlite or external Postgres; the bug is not database-mode
specific.

### Access context

Both. Board users resolve the checkbox interaction, and agent bearer-key
wakes consume the continuation context.

### Node.js version

`v22.22.2`

### Operating system

Linux workspace.

### Relevant logs or output

No runtime exception is required to reproduce this. The failure mode is
missing `checkboxSelection` data in the resolved interaction
continuation wake payload.

### Relevant config

Not config-related.

### Additional context

Root cause: accepted checkbox interaction results were not extracted
into the continuation wake context, and adapter wake payload
normalization/rendering had no typed `checkboxSelection` field.

### Privacy checklist

- [x] I have reviewed all pasted output for PII (usernames, file paths,
API keys, tokens, company names) and redacted where necessary.

## What Changed

- Added checkbox selection extraction for accepted
`request_checkbox_confirmation` interactions and stored it in
interaction continuation wake context.
- Included checkbox selection context in heartbeat wake payload
construction.
- Added adapter-utils normalization and wake prompt rendering for
checkbox prompt, selected ids, and selected option details.
- Added regression coverage for route continuation context, heartbeat
payload summaries, and adapter wake prompt rendering.

## Verification

- `pnpm exec vitest run packages/adapter-utils/src/server-utils.test.ts
server/src/__tests__/heartbeat-context-summary.test.ts
server/src/__tests__/issue-thread-interaction-routes.test.ts`
- `git diff --check origin/master...HEAD`
- `rg -n "checkbox|confirmation|interaction|wake|continuation"
ROADMAP.md`
- `gh pr list --state all --search "checkbox continuation selection
repo:paperclipai/paperclip" --json number,title,state,url,headRefName
--limit 20`
- `gh issue list --state all --search "checkbox confirmation options
repo:paperclipai/paperclip" --json number,title,state,url --limit 20`

## Risks

Low risk. The new payload field is additive, only populated for accepted
checkbox confirmations, and existing continuation fields are preserved.
The main compatibility risk is downstream code assuming an exact wake
payload shape; adapter normalization treats the new field as optional.

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

## Model Used

OpenAI Codex coding agent based on GPT-5, with shell/tool execution in
this workspace.

## 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-07-02 18:39:16 -05:00
Nicky LeachandPaperclip 2c4c110e90 Fix issue create response relation summaries (#8901)
Return blockedBy and blocks relation summaries from issue create paths after blocker relations are synced. Refresh child relation summaries after blockParentUntilDone adds a parent blocker relation.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-02 15:49:18 -07:00
60f7fb4223 PAP-12424 Work Timeline — Phase C: frontend Gantt page (Direction C) (#8880)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Operators need to *see* how work actually flowed across their agents
over time — who was invoked, what they worked on, and how work was
delegated between them
> - The dashboard shows point-in-time state but nothing reconstructs the
temporal, cross-actor picture of heartbeat runs and delegations
> - A read-only company work-timeline endpoint was landed first (server
aggregation over runs/issues/activity); it had no frontend
> - This pull request adds the Gantt-style **Work Timeline** page that
renders that endpoint, plus the small additive server contract change it
needs (shared DTOs + a task title on each span)
> - The benefit is a single dense view — actor rows, concurrency lanes,
delegation connectors, zoom and a mini-map — that makes agent activity
legible without an N+1 fetch storm from the client

## Linked Issues or Issue Description

No public GitHub issue. Problem, in-PR:

- **Gap:** the company work-timeline aggregation endpoint has no UI.
There is no way to visually inspect how heartbeat runs unfolded over
time or how work was delegated between agents.
- **Solution:** a dashboard-adjacent Gantt-style page at
`/:companyPrefix/timeline`, linked from the sidebar's "Work" section,
rendering runs as bars on per-actor rows with delegation connectors,
kickoff chips, zoom, a lens filter, and a mini-map.
- Built with React + custom inline SVG (no chart dependency; consistent
with the existing Tailwind/Radix stack).

## What Changed

- **Frontend Gantt page** (`ui/src/pages/Timeline.tsx`,
`ui/src/components/timeline/WorkTimelineChart.tsx`): actor rows
(agents/system only — humans never get a row), overlapping runs packed
into concurrency sub-lanes, bars = heartbeat runs with a left colour tab
for issue identity, truncated task title + timing/status on hover,
click-through to the task.
- **Human activity markers & human rows** for kickoff/delegation
involving people, without giving humans their own run lane.
- **Kickoff avatar chips** at each bar's leading edge; straight
agent→agent delegation connectors (dashed for
retries/changes-requested); in-progress runs extend to a dashed "now"
line and fade out.
- **Zoom** (hour/day/week, auto-fit), full-window **mini-map** with a
draggable brush, **lens filter** (Everyone / per-user, server-side), and
colour **by task / by status**.
- **Pure layout/transform module** (`ui/src/lib/timeline/layout.ts`) —
packing, kickoff derivation, connector resolution, scales — unit-tested
in isolation.
- **Server contract (additive):** moved the `WorkTimeline*` DTOs into
`@paperclipai/shared` so the aggregation service and the UI consume one
contract; added `issueTitle` to each span so the tooltip shows the task
title with no N+1 client fetch.
- Sidebar link, query keys, API client (`ui/src/api/workTimeline.ts`),
and a Storybook story with fixtures.

## Verification

- `pnpm --filter @paperclipai/shared build` ✅
- `pnpm --filter @paperclipai/server typecheck` ✅ · `pnpm --filter
@paperclipai/ui typecheck` ✅
- `pnpm --filter @paperclipai/ui exec vitest run
src/lib/timeline/layout.test.ts
src/components/timeline/WorkTimelineChart.test.tsx` ✅ (15/15)
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/work-timeline-service.test.ts` ✅ (5/5) — the DTO move +
`issueTitle` are additive; existing service tests use `objectContaining`
and still pass.
- Rendered `WorkTimelineChart` headless against a real slice of company
activity via a Storybook story; manual browser QA of the live page
passed on the feature branch.

## Risks

- **Low risk.** The change is UI-only plus an additive server DTO
refactor (types relocated to `@paperclipai/shared`, one new optional
field). No schema/migration changes, no change to endpoint behaviour
beyond the extra `issueTitle` field. The page is behind its own route
and does not alter existing views.

## Model Used

- Claude, Opus 4.8 (`claude-opus-4-8`), via Claude Code with extended
thinking and tool use.

## Checklist

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

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 12:54:16 -05:00
DottaandPaperclip dea7c4e274 [codex] add company work timeline endpoint (#8875)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Operators need visibility into who initiated work, which agents ran,
and how tasks were delegated across a company.
> - The existing control plane stores the raw data across issues,
heartbeat runs, comments, approvals, interactions, and activity logs.
> - There was no single company-scoped API response that reconstructed
those records into timeline actors, spans, events, and edges for a
Gantt-style view.
> - This pull request adds that aggregation endpoint behind the same
company and issue read authorization model used elsewhere.
> - The benefit is that UI work can consume one bounded endpoint instead
of reimplementing timeline joins client-side.

## Linked Issues or Issue Description

No public GitHub issue exists for this feature.

## Problem or motivation

Paperclip stores enough execution and delegation data to show work over
time, but consumers need a single endpoint that aggregates it
consistently.

## Proposed solution

Add `GET /api/companies/:companyId/timeline` with date and entity
filters, bounded windows, pagination, actor normalization, run spans,
human events, and delegation/assignment edges.

## Alternatives considered

Querying each source separately from the UI would duplicate ACL and
attribution logic and make client rendering depend on storage details.

## Roadmap alignment

This supports operator visibility and auditability, and does not
duplicate a listed roadmap item.

## What Changed

- Added a `workTimelineService` that aggregates issue candidates from
runs, activity, comments, approvals, interactions, and recently touched
issues.
- Added `GET /api/companies/:companyId/timeline` with `from`, `to`,
`userId`, `goalId`, `projectId`, `issueId`, `limit`, and `offset` query
parameters.
- Enforced company-scope access plus per-issue `issue:read` filtering
before emitting spans, events, or edges.
- Added 31-day window capping, in-progress span handling for null
`finishedAt`, retry/continuation metadata, user-lens subtree filtering,
and activity-log run attribution fallback.
- Added embedded-Postgres tests for aggregation joins, route behavior,
ACL filtering, window capping, and user-lens closure.

## Verification

- `pnpm vitest run server/src/__tests__/work-timeline-service.test.ts`
- `pnpm exec tsc -p server/tsconfig.json --noEmit`

Additional smoke attempted:
- `pnpm dev:once` did not start the local app because the existing
embedded instance has pending migration drift: Postgres rejected a
foreign key on `pipeline_case_blockers.company_id` because that column
does not exist. I did not manually alter the embedded database.

## Risks

- Medium risk: this introduces a new aggregate endpoint over several
tables, so query volume should be watched on very large companies.
- The endpoint caps windows and paginates issue candidates to keep the
first version bounded.
- ACL behavior is fail-closed per issue: unreadable issues are filtered
before response rows are emitted.
- No migrations or schema changes are included.

## Model Used

OpenAI GPT-5 via Codex coding agent, with tool use for repository
inspection, editing, local Vitest execution, TypeScript checking, git,
and GitHub CLI operations.

## 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
- [ ] 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-07-02 12:39:49 -05:00
Dotta 2f94a66ba1 Show live descendant status in inbox rows (#8876)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The inbox is where operators quickly scan which issues are active,
blocked, or waiting for attention
> - A blocked parent can still have active descendant work, but the
inbox previously depended on only loaded rows to infer that state
> - That made collapsed or partially loaded issue trees look more stuck
than they really were
> - This pull request carries live descendant summary data through the
issue list API and inbox UI
> - The benefit is a more accurate blocked-inbox signal, so operators
can distinguish truly stalled work from blocked parents that still have
live child activity

## Linked Issues or Issue Description

No public GitHub issue was found for this exact inbox descendant-status
polish.

Feature request fields:

**Subsystem affected**
Cross-cutting: `server/`, `packages/shared`, plugin/MCP API surfaces,
and `ui/` inbox rendering.

**Problem or motivation**
Inbox rows need to show when blocked or collapsed parents still have
live descendant work, even when the live child row is not loaded in the
current client tree. Without a server-provided descendant summary, a
parent can look stalled even though active work continues below it.

**Proposed solution**
Expose an optional live descendant count on issue list results, request
it from inbox views, and use it to render covered blocked status and
live-below indicators. Keep the field opt-in so other issue list callers
keep their existing payload shape and query cost.

**Alternatives considered**
Relying only on client-loaded subtree state was ruled out because it
misses collapsed or unloaded descendants. Always returning the count was
also avoided because most list callers do not need this extra summary.

**Roadmap alignment**
This is scoped operator-visibility polish for the existing inbox. It
does not duplicate a named `ROADMAP.md` milestone.

**Additional context**
The recursive summary query is guarded against parent cycles, and the UI
still falls back to loaded subtree live counts when server summary data
is absent or stale.

## What Changed

- Added optional `includeLiveDescendantSummary` support to issue list
contracts, SDK surfaces, MCP tools, routes, services, and tests.
- Added `liveDescendantCount` to issue list results when requested.
- Updated inbox and blocked-inbox queries to request live descendant
summaries.
- Updated inbox row status rendering so blocked parents with live
descendants show covered blocker treatment without duplicating the
live-below chip.
- Hardened live descendant summary traversal against parent cycles and
preserved the loaded-subtree fallback path for blocked inbox rows.
- Added focused tests for the API parameter, service behavior, helper
logic, cycle handling, and inbox UI query/rendering behavior.

## Verification

- `pnpm exec vitest run
server/src/__tests__/issue-list-assignee-filter-routes.test.ts
ui/src/lib/inbox-live-descendants.test.ts
ui/src/components/IssueColumns.test.tsx
ui/src/components/BlockedInboxView.test.tsx ui/src/pages/Inbox.test.tsx`
- `pnpm --filter @paperclipai/ui typecheck`
- Rebased cleanly onto current upstream `master` before pushing.
- Confirmed the branch diff does not include `pnpm-lock.yaml` or
`.github/workflows/*` changes.

## Risks

Low to moderate risk. The new descendant count is opt-in on list
requests, but it adds query work when the inbox asks for it. The
recursive traversal now tracks visited ancestors to avoid cycle
failures. The UI uses the server count as a supplement to existing
loaded-tree state, so stale or absent counts fall back to the prior
behavior.

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

## Model Used

OpenAI Codex, GPT-5 coding agent, tool-enabled with local shell and git
access. Reasoning mode and context window are managed by the
Paperclip/Codex runtime.

## 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
2026-07-02 10:22:33 -05:00
Devin FoleyandPaperclip b4815bf964 Scope environment custom images to instance environments (#8850)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Environments are now managed as instance-level runtime resources
rather than per-company rows
> - The custom environment image setup tables were introduced with their
own `company_id` columns and route query parameters
> - That split made one saved environment image state depend on an extra
company context even though the environment itself is the durable owner
> - It also made saved-environment probes harder because applying the
active custom image template could require a company context when no
secret-backed config needed one
> - This pull request scopes custom image templates and setup sessions
directly to the saved environment
> - The benefit is that reusable environment images follow the same
instance-scoped model as environments while secret resolution still uses
company context only when secrets require it

## Linked Issues or Issue Description

No matching public GitHub issue was found.

Bug report:

### What happened?

saved environment custom-image routes and persistence required a
`companyId` even though environments are instance-scoped, and saved
sandbox probes did not opt into active custom-image template application
unless a company context was present.

### Expected behavior

custom-image templates and setup sessions should be owned by the saved
environment, and saved sandbox probes should apply the active template
while still requiring a company context only for secret-backed runtime
config.

### Steps to reproduce

1. Configure an instance-scoped sandbox environment with custom-image
setup support.
2. Start or inspect a custom-image session or template for that saved
environment.
3. Probe the saved environment without a custom-image-specific
`companyId` query parameter.

### Paperclip version or commit

current `master` after the environment custom-image template migration.

### Deployment mode

Local dev (pnpm dev) or authenticated local Paperclip instance.

### Installation method

Built from source (pnpm dev / pnpm build).

### Agent adapter(s) involved

Not adapter-specific (core bug).

### Database mode

Embedded PGlite/Postgres dev database.

### Access context

Board human operator.

### Privacy checklist

No logs, secrets, tokens, private URLs, or local machine paths are
included.

Duplicate search performed:

- `gh search prs "environment custom image companyId
repo:paperclipai/paperclip" --state open --limit 20`
- `gh search prs "custom image environment scoped
repo:paperclipai/paperclip" --state open --limit 20`
- `gh search issues "environment custom image
repo:paperclipai/paperclip" --state open --limit 20`

The returned results were unrelated adapter, Docker, auth, or
stale-workspace items.

## What Changed

- Removed redundant `company_id` columns from environment custom-image
templates and setup sessions.
- Added migration `0127_environment_custom_images_instance_scoped` to
collapse duplicate active rows per environment before dropping the old
company-scoped indexes/columns.
- Updated custom-image services, route handlers, shared validators, and
UI API/query keys to use environment-scoped custom-image state.
- Kept runtime secret resolution company-aware only when secret refs or
bindings require a company context.
- Made saved sandbox environment probes opt into active custom-image
template application.
- Updated DB, shared, server, and UI tests for the new
environment-scoped contract.

## Verification

- `pnpm --filter @paperclipai/db run check:migrations`
- `pnpm exec vitest run
packages/db/src/environment-custom-images-schema.test.ts
packages/shared/src/environment-custom-images.test.ts
server/src/__tests__/environment-custom-image-routes.test.ts
server/src/__tests__/environment-custom-images-service.test.ts
server/src/__tests__/environment-routes.test.ts
ui/src/pages/CompanyEnvironments.test.tsx`
- `pnpm -r typecheck`
- `pnpm test:run` before rebasing onto latest `master`; after the rebase
only the migration number changed, and the migration check plus focused
suite, typecheck, and build were rerun.
- `pnpm build`

## Risks

- Migration safety: the migration supersedes duplicate active templates
per environment and fails duplicate active setup sessions before adding
environment-only unique indexes. Operators with duplicate historical
active rows should review which active template is kept.
- Behavior shift: plugin custom-image setup calls now receive
`companyId: "instance"` when no secret binding determines a concrete
company context.
- Secret-backed configs still require an explicit or uniquely inferable
company context; environments with secret bindings spread across
multiple companies continue to fail fast.

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

## Model Used

OpenAI Codex via the `codex_local` adapter, GPT-5-based coding model
with tool-enabled repository inspection, editing, testing, git, and
GitHub CLI access. Exact context-window metadata was not exposed by the
runtime.

## 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-07-01 23:57:31 -07:00
Devin FoleyandPaperclip 2eba718bef Fix sandbox bridge credentials and stalled review recovery (#8844)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The local adapter and heartbeat recovery systems decide whether an
agent has a real control-plane mutation path.
> - Sandboxed local adapters split execution between the trusted host
process and the sandbox shell/tool surface.
> - A host-side adapter can still reach Paperclip while the sandbox
shell surface cannot, which leaves agents thinking no endpoint or
credentials are configured even though the host can still post comments.
> - Execution-policy review stages can also remain pending after a
reviewer run finishes without recording a decision.
> - This pull request makes the sandbox bridge available to the actual
shell mutation surface and adds bounded recovery for
terminal-but-still-pending review participants.
> - The benefit is that agents get a real reachable Paperclip API path
where they need it, and stalled review stages become visible recovery
work instead of silently drifting.

## Linked Issues or Issue Description

No exact public GitHub issue matched this combined failure. I searched
for exact and related terms including `cannot reach the Paperclip
control plane`, `execution_review_participant_recovery`, `sandbox
callback bridge`, `review participant in_review`, and `control plane
sandbox`.

Related public issues:

- Refs #8482 for `in_review` liveness invariant recovery.
- Refs #863 for prior agent API-key reachability confusion.
- Refs #248 for the broader sandboxed agent execution model.

Bug summary:

- What happened: a sandboxed local-adapter run could have host-side
Paperclip access while the sandbox Bash/tool surface lacked a reachable
API endpoint or usable run credentials. Separately, a reviewer run could
finish while its execution-review stage remained pending, leaving the
source issue in `in_review` with no decision and no live participant
run.
- Expected behavior: the mutation surface that agents actually use
should receive a run-scoped Paperclip bridge, and pending review
participants should get one bounded normal-model recovery wake before
moving to explicit blocked/source-scoped recovery.
- Steps to reproduce: run a sandbox-backed local adapter that needs
Bash/curl/tooling to call Paperclip from inside the sandbox, or finish
an execution-policy reviewer run without submitting the pending review
decision.
- Deployment mode: local/authenticated private development instance with
sandbox-backed local adapters.

## What Changed

- Changed sandbox callback bridge startup so bridge credentials are
passed through the sandbox runner environment instead of embedded in the
visible `nohup env ...` command string.
- Added adapter-utils coverage proving the sandbox shell can call
Paperclip through the bridge, forwards the host run JWT with
`X-Paperclip-Run-Id`, and does not leak host or bridge tokens into
stdout/stderr, runner command text, or runtime files.
- Added one bounded execution-review participant recovery path for
terminal reviewer runs whose `executionState` remains pending.
- Escalated exhausted or non-invokable review participant recovery to
blocked/source-scoped recovery with dedicated evidence, activity, and
next-action text.
- Documented the mutation-surface reachability contract in
`doc/execution-semantics.md` and updated the Paperclip skill
authentication guidance for sandbox bridge env vars.

## Verification

- `pnpm exec vitest run
packages/adapter-utils/src/execution-target-sandbox.test.ts`
- `pnpm exec vitest run
server/src/__tests__/heartbeat-process-recovery.test.ts
--no-file-parallelism --maxWorkers=1`
- `pnpm --filter @paperclipai/adapter-utils typecheck`
- `pnpm --filter @paperclipai/server typecheck`
- `git diff --check`
- `curl -fsS $PAPERCLIP_API_URL/api/health` returned `status: ok` on the
local instance.

## Risks

- Medium behavioral risk: more `in_review` issues with
terminal-but-pending reviewer runs will now be retried once and then
blocked explicitly instead of remaining quiet.
- Low sandbox bridge risk: credential delivery moved from command text
to the runner environment, which is less leaky but depends on sandbox
providers honoring the env payload for startup commands.
- No database migration is included.
- Full repo build and CI were not run locally before opening the PR;
targeted server/adapter tests and typechecks passed.

## Model Used

OpenAI GPT-5 via the Codex local agent, with repository tool use and
shell-based code execution. The runtime did not expose a precise
context-window value to the agent.

## 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-07-01 21:38:01 -07:00
scotttongandClaude Opus 4.8 fb2b760915 fix(issues): attribute agent-authored comments instead of rendering them as "Board" (#8833)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Task/issue threads render each comment as a chat bubble; the author
determines whether it shows as a left-aligned agent bubble (name + icon)
or a right-aligned "Board" bubble
> - Comments posted by an agent from a local execution environment are
written with a non-human author id (`local-board`/system), so they were
mis-rendered as blue "Board" bubbles instead of being attributed to the
authoring agent
> - This misattribution is confusing (it looks like the human board said
something an agent actually said) and it can drive false
wake/reconciliation behavior on the affected threads
> - This pull request adds server-side attribution derivation (lossless
run-id join first, then an explicit run-log post marker), persists the
derived agent so the read path stops re-scanning run logs, and stops the
client from labeling agent-derived comments "Board"
> - The benefit is agent comments render as the correct agent, genuine
human board comments are never reattributed, and reads get cheaper after
a one-time persistence

## Linked Issues or Issue Description

<!-- No public GitHub issue — describing the problem in-PR (bug report
shape). -->

**What happened?**

In a task/issue comment thread, comments authored by an agent from a
local execution environment are stored with a non-human author id
(`local-board`/system). The UI renders these as right-aligned blue
"Board" bubbles, implying a human board member authored them. The
mislabeling is also a wake/reconciliation hazard: an agent comment that
reads as "Board" can look like human board input.

**Expected behavior**

Such comments should render as the authoring agent (left-aligned bubble
with agent name + icon). Genuine human/board comments must continue to
render as "Board" and must never be reattributed to an agent.

**Steps to reproduce**

1. Have an agent post a comment on an issue from a local execution
environment (author id `local-board`).
2. Open the issue comment thread in the UI.
3. Observe the agent's comment rendered as a right-aligned blue "Board"
bubble instead of the authoring agent.

**Root cause**

The read path did not resolve the authoring agent for these comments,
and the client fell back to a "Board" label for the `local-board`
author.

## What Changed

- **Server derivation (`server/src/services/issues.ts`):**
- Resolve the authoring agent from the comment's run id first
(`createdByRunId`/`derivedCreatedByRunId` → `heartbeatRuns.agentId`) —
lossless when present.
- Second tier `run_log_comment_post`: read the run log lazily (only for
still-unresolved comments) to match the explicit `comment id:` post
marker.
- **Guard:** never reattribute a comment whose author maps to a genuine
user profile. Only the non-human sentinel (`local-board`, which is
itself a `user` row) and authors absent from the `user` table are
eligible.
- Pure timing-overlap tiers are intentionally **not** used (Option A) —
an agent comment and a human board comment posted during the same run
are indistinguishable rows, so any timing guess risks mislabeling a real
human comment.
- **Persistence
(`packages/db/src/migrations/0126_issue_comment_derived_attribution.sql`,
`packages/db/src/schema/issue_comments.ts`):** add stored `derived_*`
attribution columns and write the resolved agent back with a single bulk
`UPDATE ... FROM (VALUES ...)`, so reads stop recomputing from run logs.
Migration is additive (new nullable columns) with a batched, idempotent
backfill of the lossless run-id tier over historical rows.
- **Types (`packages/shared/src/types/issue.ts`):** expose the persisted
attribution fields and the `IssueCommentDerivedAuthorSource` union.
- **Client (`ui/src/lib/issue-chat-messages.test.ts`):** the message
builder already prefers a resolved agent id (`authorAgentId ??
runAgentId ?? derivedAuthorAgentId`), so once the server persists the
derived agent the bubble renders as the agent automatically — no client
code change needed. Adds a regression guard confirming a genuine board
comment with no derived agent is still rendered as "Board".
- **Tests:** derivation + message-building tests, including assertions
that genuine board/user comments are **not** reattributed.

## Verification

- `cd server && npx vitest run issues-service` — 94 tests pass: run-id
resolution, no-attribution on timing overlap alone (Option A), multi-run
ambiguity, same-agent multi-run, and the genuine-user guard. Exercises
the real persistence path (bulk UPDATE) against the test DB.
- `cd ui && npx vitest run issue-chat-messages` — 27 tests pass; client
no longer labels agent-derived comments "Board", and a genuine board
comment with no derived agent is not re-labeled.
- `cd server && npm run typecheck` — passes (exit 0).
- Manual: on a thread containing old agent-authored comments, the blue
"Board" bubbles render as the authoring agent; a genuine board comment
on the same thread still renders as "Board".

## Risks

- **Mis-reattributing a genuine board comment made during an agent run**
→ mitigated by the human-profile guard (only `local-board`/system
authors are eligible) and by dropping pure timing tiers (Option A): only
the lossless run-id join and the explicit run-log post marker attribute
history.
- **Backfill volume / run-log reads** → the migration backfill is
batched (5000 rows/loop) and results are persisted so reads stop
recomputing; the read-path persistence is a single bulk UPDATE rather
than per-comment round-trips. Migration adds only nullable columns (no
destructive change).
- The persistence/backfill has **not** been run against any production
database as part of opening this PR.

## Model Used

Claude Opus 4.8 (`claude-opus-4-8`), extended thinking, via Claude Code
with tool use.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs — related open
PRs (#6006 narrow attribution run scan, #4729 attribution roll-up, #7014
reaped-run attribution) address different attribution paths; none fix
the `local-board` "Board" bubble rendering this PR targets. Supersedes
#8832 (same change; branch renamed to drop an internal ticket id per
CONTRIBUTING → Branch Naming)
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no internal
Paperclip ticket id 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: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:45:30 -07:00
Nicky LeachandPaperclip 3522b1c9be Emit interaction resolved telemetry (#8824)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Issue-thread interactions are how agents ask users or the board for
decisions and structured input
> - Product telemetry needs to understand when those interactions
resolve without exposing private interaction content
> - Resolution currently happens through several service paths, so
telemetry needs to be emitted consistently from the terminal transitions
> - The interaction service should describe the resolved interaction,
while the telemetry backend owns unknown-value normalization for
dimensions
> - This pull request emits `interaction.resolved` after successful
database writes and removes redundant client-side normalization from the
service
> - The benefit is aggregate-safe telemetry for interaction completion
behavior without leaking raw IDs, answer text, rejection reasons, or
document content

## Linked Issues or Issue Description

No public GitHub issue exists for this internal telemetry follow-up.

Feature context:

- Problem/motivation: Paperclip needs aggregate product telemetry for
issue-thread interaction resolution outcomes while preserving privacy
boundaries around user answers and internal identifiers.
- Proposed solution: Emit `interaction.resolved` once from terminal
interaction resolution paths, passing runtime dimensions through the
shared telemetry helper while preserving aggregate-safe counts and
ID/free-text omission.
- Alternatives considered: Normalizing interaction dimensions in the
interaction service duplicated telemetry backend responsibility and made
unknown-value handling inconsistent across telemetry clients.
- Roadmap alignment: This is a focused telemetry instrumentation
follow-up that builds on the generated telemetry event types from #8818.

## What Changed

- Wires `interaction.resolved` telemetry into terminal issue-thread
interaction resolution paths after successful database writes.
- Passes raw interaction kind, status, continuation policy, resolution
reason, target type, and creator agent role values to the shared
telemetry helper instead of maintaining service-local allowlists.
- Preserves resolver classification, target `none` derivation for
non-confirmation interactions, non-negative aggregate counts, raw ID
omission, and free-text omission.
- Logs telemetry failures without blocking interaction resolution.
- Adds service-level tests for accepted, rejected, answered,
stale-target expiry, superseded-comment expiry, and raw creator-role
pass-through payloads.

## Verification

- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/issue-thread-interactions-telemetry.test.ts
server/src/__tests__/shared-telemetry-events.test.ts`
- `pnpm typecheck`
- GitHub PR checks on the latest head commit are green, including
`verify`, build, e2e, general tests, serialized server suites, security
scans, and Greptile Review.
- Security code review completed before this branch update.

## Risks

- Low operational risk: telemetry is emitted after successful
persistence and telemetry failures are logged without blocking the
user-visible interaction flow.
- Main behavioral risk is duplicate or missing telemetry from a
resolution path; the focused tests cover the terminal resolution
variants.
- Telemetry dimension normalization now depends on the shared telemetry
backend path instead of the interaction service, so backend
normalization must remain the source of truth for unknown or empty
dimension values.
- The existing PR branch name contains an internal task id because this
update continues an already-open PR branch instead of opening a
replacement PR.

## Model Used

OpenAI GPT-5 Codex coding agent, API-based coding environment with
shell, repository, and GitHub CLI tool use. Context window size was not
reported by the runtime.

## 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)
- [ ] 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-07-01 13:43:11 -07:00
d68c34f2cc Fix managed workspace branch coherence recovery (#8826)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Managed issue workspaces are part of the control-plane runtime
boundary: the server records which git worktree and branch an agent run
is allowed to use.
> - Existing reuse checks validated the worktree path and cleanliness,
but did not fully validate that the actual checked-out branch still
matched the recorded execution workspace branch.
> - That gap let an agent run switch a managed worktree onto a
publishing branch without updating the execution workspace record, then
later reuse or finalize the workspace as though it were coherent.
> - The runtime needs a bounded repair path for provably safe mismatches
and a hard validation failure for dirty, divergent, or unrecorded branch
transitions.
> - This pull request adds branch coherence to managed git worktree
validation, records explicit recovery evidence, and prevents finalize
success when a run silently changes branches.
> - The benefit is that branch drift becomes either safely repaired or
visibly recoverable instead of silently corrupting managed workspace
state.

## Linked Issues or Issue Description

No public GitHub issue exists for this bug.

Bug report:

- What happened: a managed agent workspace could be recorded for one
branch while the underlying git worktree was actually checked out on
another branch. Reuse and finalization could still treat the workspace
as healthy.
- Expected behavior: managed git worktrees should verify the actual
branch against the recorded execution workspace branch. Safe same-HEAD
clean mismatches may be repaired, while dirty, divergent, or unrecorded
branch transitions should fail into explicit workspace validation
recovery.
- Reproduction outline: create a runtime-managed issue worktree, switch
its checkout to another branch without updating the execution workspace
record, then attempt reuse or run finalization.
- Deployment mode: local/self-hosted Paperclip server using managed git
workspaces.
- Related public work: Refs #7644 and #7579. Related but not duplicate:
#8275 and #5851.

## What Changed

- Added managed git worktree branch inspection, formatted validation
evidence, and safe same-HEAD repair logic to the workspace runtime
service.
- Validated recorded managed workspace branch state before reuse and
during heartbeat setup.
- Added finalization-time branch guards so runs that silently switch
branches fail with `workspace_validation_failed` instead of recording a
successful finalize.
- Added recovery fingerprints and evidence for
`git_worktree_branch_incoherence`, including manual-repair next actions
for unsafe branch drift.
- Documented branch coherence as part of runtime-created git worktree
workspace coherence.
- Added focused tests for safe branch repair, dirty/divergent recovery
evidence, heartbeat setup validation, and finalize failure/success
paths.

## Verification

- `pnpm install --frozen-lockfile`
- `git diff --check origin/master...HEAD`
- `pnpm exec vitest run server/src/__tests__/workspace-runtime.test.ts
server/src/__tests__/heartbeat-workspace-session.test.ts
server/src/__tests__/issue-recovery-actions.test.ts
server/src/__tests__/heartbeat-workspace-finalize-branch.test.ts`
- `pnpm -r typecheck`
- `pnpm test:run`
- `pnpm build`

Notes:

- An initial full `pnpm test:run` attempt hit a transient `socket hang
up` in one `plugin-routes-authz` case. The exact case passed when rerun
directly, the full `plugin-routes-authz` file passed, and the subsequent
full `pnpm test:run` passed.
- `pnpm build` still emits existing Vite CSS pseudo-element and
chunk-size warnings unrelated to this change.

## Risks

- This intentionally changes behavior for managed runs that switch
branches without recording the transition: they now fail during
workspace validation/finalization instead of silently proceeding.
- The automatic repair path is intentionally narrow. It only repairs
clean branch mismatches when both branches point at the same commit;
dirty or divergent worktrees require manual recovery.
- Recovery fingerprints now include workspace-validation evidence, so
duplicate recovery-action grouping is more precise for
branch-incoherence failures.

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

## Model Used

OpenAI Codex, GPT-5 Codex CLI/API coding agent, with shell/git/test
execution and reasoning mode enabled.

## 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: Cody <noreply@paperclip.ing>
Co-authored-by: Cody <cody@paperclip.ing>
2026-07-01 13:35:58 -07:00
Nicky LeachandPaperclip 8a93a0de4c Implement generated client telemetry types (#8818)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Telemetry is part of the control plane's operational visibility and
needs stable event contracts.
> - The shared telemetry client accepted first-party event names through
a broad string surface, which weakened compile-time guarantees.
> - Plugin telemetry still needs a dynamic path because plugin-defined
events cannot be enumerated in the core generated type module.
> - This pull request vendors generated Paperclip telemetry event and
dimension types, closes the first-party event-name union, and keeps
plugin telemetry on an explicit dynamic method.
> - Review feedback clarified that backend normalization should remain
the source of truth, so telemetry helpers now preserve raw categorical
values while keeping generated per-event type hints.
> - The benefit is stricter first-party telemetry typing without hiding
backend normalization signals or changing batching, flushing, schema
versioning, sinks, or endpoints.

## Linked Issues or Issue Description

No public GitHub issue exists for this internal type-contract
maintenance change.

### Problem or motivation

The shared telemetry client should reject unregistered first-party event
names at compile time, while the plugin telemetry bridge must continue
to emit plugin-defined events through the existing batching and envelope
path. Helper wrappers should also avoid client-side enum coercion so the
backend can detect and record normalization when clients send unexpected
categorical values.

### Proposed solution

Generate and vendor the accepted Paperclip telemetry event and dimension
types, use those types for the first-party `track()` API, keep
plugin-defined telemetry on an explicit dynamic method, and let helper
wrappers pass raw categorical dimensions through to backend validation.

### Alternatives considered

Keeping `track()` open to arbitrary strings would preserve flexibility,
but it would not give first-party callers the type safety this change is
meant to provide. Enumerating plugin events in core was also ruled out
because plugin-defined events are not known to the core package.
Client-side enum normalization was removed after review because it
duplicates backend validation and can hide misbehaving-client signals.

### Roadmap alignment

This is a tightly scoped telemetry contract maintenance change and does
not overlap with a roadmap-level core feature.

## What Changed

- Vendored the generated Paperclip telemetry event and dimension type
module under shared telemetry code.
- Closed the first-party telemetry event-name union to generated
backend-accepted names plus an explicit `RegisteredPluginEventName =
never` extension point.
- Added `TelemetryClient.trackDynamic()` for plugin telemetry bridge
emission while keeping `track()` closed and typed.
- Added JSDoc explaining when to use `track()` versus `trackDynamic()`.
- Updated telemetry helper wrappers to type dimensions from each event's
generated schema entry while passing raw categorical values through for
backend normalization.
- Added `trackInteractionResolved()` and updated focused shared/server
tests for telemetry event typing, raw pass-through behavior, and plugin
telemetry bridging.

## Verification

Local verification passed before the latest push:

- `pnpm --filter @paperclipai/shared typecheck`
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm exec vitest run
packages/shared/src/telemetry/client-types.test.ts
server/src/__tests__/shared-telemetry-events.test.ts
server/src/__tests__/plugin-telemetry-bridge.test.ts
server/src/__tests__/project-goal-telemetry-routes.test.ts
server/src/__tests__/routine-run-telemetry.test.ts
server/src/__tests__/issue-telemetry-routes.test.ts`
- `git diff --check`

Post-push verification completed on head
`3d973ffbea6154b19ad208dcffd1374d1b25b654`:

- GitHub PR checks passed, including `verify`, build, typecheck/release
registry, general test shards, serialized server shards, canary dry run,
e2e, and security checks.
- Greptile Review passed with 5/5 confidence.
- All PR review threads are resolved.

## Risks

Low runtime risk. The change is intended to affect TypeScript contracts
and helper typing while preserving the existing telemetry enqueue,
batching, and backend ingest path. The main intentional behavior shift
is that helper wrappers no longer coerce unexpected categorical values
on the client; those values reach the backend so backend normalization
can record the signal. Private company import source refs still use
`hashPrivateRef` when `isPrivate` is true.

## Model Used

OpenAI GPT-5 Codex, tool-enabled coding agent. Exact context window was
not exposed by the runtime; the agent used repository file access, shell
commands, and GitHub CLI operations.

## 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-07-01 11:39:39 -07:00
DottaandPaperclip ac9a883f8b Expire ask-user questions superseded by comments (#8799)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Issue-thread interactions are how agents ask board users for typed
decisions and structured answers inside an issue thread
> - Confirmation interactions already become stale when a later
board/user comment supersedes the pending decision
> - Question interactions had the same workflow risk, because a
board/user could answer in a comment while the old question card stayed
pending
> - This pull request extends the supersede-by-comment lifecycle to
ask-user-question interactions and makes that status visible in the UI
> - The benefit is agents get a clear continuation signal and users do
not see stale question forms after the discussion has moved on

## Linked Issues or Issue Description

No exact public GitHub issue was found.

Bug report:

**Pre-submission checklist**

- [x] I have searched existing open and closed issues and this is not a
duplicate.
- [x] I am on the latest released version of Paperclip, or can reproduce
on `master`.
- [x] I have confirmed the error originates in Paperclip itself, not in
an agent adapter, API provider, or local configuration.

**What happened?**

Pending `ask_user_questions` interactions could remain open after a
later board/user comment changed or answered the request in-thread. That
left a stale form visible and kept the interaction in a pending state
even though the discussion had moved on.

**Expected behavior**

Question interactions should follow the same default
supersede-on-comment behavior as confirmation interactions, with an
explicit expired result that points to the superseding comment.

**Steps to reproduce**

1. Create an `ask_user_questions` interaction on an issue.
2. Add a board/user comment created at or after that interaction.
3. Observe that before this change, the question interaction stayed
pending instead of expiring as superseded by the comment.

**Paperclip version or commit**

Current `master` before this PR.

**Deployment mode**

Self-hosted server or local dev. The bug is in shared issue-thread
interaction lifecycle handling.

**Installation method**

Built from source.

**Agent adapter(s) involved**

Not adapter-specific. This is a core issue-thread interaction bug.

**Database mode**

Applies to the normal Paperclip database-backed interaction lifecycle.

**Access context**

Board user comments supersede agent-created questions.

**Relevant logs or output**

No crash output. The stale pending interaction was visible in the issue
thread state.

**Relevant config (if applicable)**

None.

**Additional context**

Confirmation-style interactions already supported this stale-by-comment
behavior. This PR brings question interactions into the same lifecycle
model.

**Privacy checklist**

- [x] I have reviewed all pasted output for PII and included no private
instance links, local ticket ids, secrets, logs, or screenshots.

## What Changed

- Added `supersedeOnUserComment` support to `ask_user_questions`
payloads, defaulting it to `true` during interaction creation.
- Expire pending question interactions when a later board/user comment
supersedes them, including a result with `expirationReason:
"superseded_by_comment"` and the superseding `commentId`.
- Updated interaction summaries and cards so expired question requests
show a clear amber state with a jump link to the comment and correct
singular/plural copy.
- Updated agent onboarding guidance to describe the new default and how
to opt out.
- Added shared, server, and UI test coverage for the new lifecycle
behavior.

## Verification

- `pnpm exec vitest run
packages/shared/src/issue-thread-interactions.test.ts
server/src/__tests__/issue-thread-interaction-routes.test.ts
server/src/__tests__/issue-thread-interactions-service.test.ts
ui/src/components/IssueThreadInteractionCard.test.tsx
ui/src/lib/issue-thread-interactions.test.ts --reporter=dot` passed: 5
files, 73 tests.
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck && pnpm --filter @paperclipai/ui
typecheck` passed.
- `pnpm exec vitest run
server/src/__tests__/issue-thread-interactions-service.test.ts
--reporter=dot && pnpm --filter @paperclipai/server typecheck` passed
after the final type-safety cleanup.
- Confirmed the branch is rebased on current `origin/master`.
- Confirmed the diff does not touch `pnpm-lock.yaml`,
`.github/workflows`, or database migrations.

## Risks

- Low-to-medium risk: `ask_user_questions` now defaults to expiring
after later board/user comments. Existing callers that need questions to
stay open through discussion can set `supersedeOnUserComment: false`.
- Expired question interactions store an empty `answers` array, so
downstream consumers should treat the explicit `expirationReason` as the
meaningful outcome.

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

## Model Used

OpenAI Codex, GPT-5-based coding agent in Paperclip CodexCoder runtime,
with terminal and repository tool use. Exact context window is not
exposed in this runtime.

## 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-07-01 09:28:43 -07:00
a8f0ebaa80 Refresh run config before reusing workspaces (#8797)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent runs are assembled by the heartbeat service from agent config,
project workspaces, environment config, secret bindings, skills, and
runtime session state.
> - The heartbeat service intentionally reuses adapter sessions,
execution workspaces, and sandbox leases when that preserves useful
state.
> - Reuse becomes incorrect when the effective next-run config changes
after a saved session, workspace, or lease was created.
> - Stale reuse can make a later run appear pinned to old agent,
environment, secret, instruction, or workspace settings.
> - This pull request records non-sensitive fingerprints for the
effective session, workspace, and lease config at run boundaries.
> - When those fingerprints drift, Paperclip refreshes persisted runtime
config or starts fresh execution instead of reusing stale state.
> - The benefit is predictable next-run config freshness without storing
raw secret values, full env maps, provider credentials, or private path
details.

## Linked Issues or Issue Description

- Refs #8058
- Related PRs checked during dedup search: #4968, #4155, #84, #8480.
These cover nearby workspace/session routing or model-config freshness
areas, but do not duplicate this effective run config fingerprinting
path.

## What Changed

- Added effective run config fingerprinting for session, workspace, and
lease reuse decisions, with canonicalization that ignores generated
runtime noise and redacts sensitive values.
- Updated heartbeat reuse logic to compare stored and next-run
fingerprints, reset stale saved sessions, refresh persisted workspace
config snapshots, replace stale reused workspaces when required, and
avoid stale sandbox lease reuse.
- Included plain environment value drift via value hashes, without
storing the raw env values.
- Root-bound instruction content hashing so legacy direct absolute
instruction paths are represented but not read for config fingerprints.
- Batched secret/version metadata lookups for environment lease
fingerprinting.
- Added workspace operation/run result freshness metadata so operators
can inspect non-sensitive decision categories.
- Surfaced config freshness labels and next-run copy in the UI and docs.
- Added focused coverage for fingerprint redaction, session reset
decisions, workspace refresh/replace behavior, environment lease drift,
and persisted workspace restoration.

## Verification

- `git diff --check`
- Sensitive-data scan before push:
- `git diff --unified=0 origin/master...HEAD | rg -n --pcre2
"(AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|ghp_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,}|sk-[A-Za-z0-9]{20,}|-----BEGIN
(RSA |OPENSSH |EC |DSA )?PRIVATE KEY-----|AKIA[0-9A-Z]{16})"`
- `git diff --unified=0 origin/master...HEAD | rg -n --pcre2
"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"`
- `pnpm exec vitest run
server/src/__tests__/effective-run-config-fingerprints.test.ts
server/src/__tests__/heartbeat-workspace-session.test.ts
server/src/__tests__/environment-runtime.test.ts`
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm -r typecheck`
- `pnpm --filter @paperclipai/db clean`
- `pnpm test:run`
- `pnpm build`
- UI screenshots from Cutter:
-
https://artifacts.cutter.sh/8797/run-2f4827c-2026-06-30T18-57-25/preview/change-01.png
-
https://artifacts.cutter.sh/8797/run-2f4827c-2026-06-30T18-57-25/preview/change-02.png
-
https://artifacts.cutter.sh/8797/run-2f4827c-2026-06-30T18-57-25/preview/change-03.png

## Risks

- Medium: overly broad fingerprints could start fresh sessions,
workspaces, or sandbox leases more often than necessary.
- Medium: missing a config category would allow stale reuse to persist
for that category.
- Medium: legacy direct absolute instruction paths are no longer
content-hashed unless they are paired with an absolute managed
instructions root.
- Low data risk: fingerprint metadata stores hashes and category names,
not raw secrets, raw env values, provider credentials, or private path
details.

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

## Model Used

OpenAI GPT-5 via Codex CLI / Codex coding agent, tool-enabled with
shell, Git, GitHub CLI, local test execution, and code editing. The
exact deployed model variant and context window are not exposed by this
environment.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Cody <cody@paperclip.ing>
2026-06-30 14:50:25 -07:00
dependabot[bot] b755ab55fd build(deps): bump multer from 2.1.1 to 2.2.0 (#8743)
Bumps [multer](https://github.com/expressjs/multer) from 2.1.1 to 2.2.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/expressjs/multer/releases">multer's
releases</a>.</em></p>
<blockquote>
<h2>v2.2.0</h2>
<h2>Important</h2>
<ul>
<li>Fix <a
href="https://www.cve.org/CVERecord?id=CVE-2026-5038">CVE-2026-5038</a>
(<a
href="https://github.com/expressjs/multer/security/advisories/GHSA-3p4h-7m6x-2hcm">GHSA-3p4h-7m6x-2hcm</a>)</li>
<li>Fix <a
href="https://www.cve.org/CVERecord?id=CVE-2026-5079">CVE-2026-5079</a>
(<a
href="https://github.com/expressjs/multer/security/advisories/GHSA-72gw-mp4g-v24j">GHSA-72gw-mp4g-v24j</a>)</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>chore(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/expressjs/multer/pull/1397">expressjs/multer#1397</a></li>
<li>chore(deps): bump github/codeql-action from 4.32.4 to 4.36.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/expressjs/multer/pull/1409">expressjs/multer#1409</a></li>
<li>chore(deps): bump actions/checkout from 6.0.2 to 6.0.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/expressjs/multer/pull/1410">expressjs/multer#1410</a></li>
<li>ci: add Node 26 to test matrix by <a
href="https://github.com/gameroman"><code>@​gameroman</code></a> in <a
href="https://redirect.github.com/expressjs/multer/pull/1404">expressjs/multer#1404</a></li>
<li>Release: 2.2.0 by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/expressjs/multer/pull/1412">expressjs/multer#1412</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/gameroman"><code>@​gameroman</code></a>
made their first contribution in <a
href="https://redirect.github.com/expressjs/multer/pull/1404">expressjs/multer#1404</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/expressjs/multer/compare/v2.1.1...v2.2.0">https://github.com/expressjs/multer/compare/v2.1.1...v2.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/expressjs/multer/blob/main/CHANGELOG.md">multer's
changelog</a>.</em></p>
<blockquote>
<h2>2.2.0</h2>
<ul>
<li>Fix <a
href="https://www.cve.org/CVERecord?id=CVE-2026-5038">CVE-2026-5038</a>
(<a
href="https://github.com/expressjs/multer/security/advisories/GHSA-3p4h-7m6x-2hcm">GHSA-3p4h-7m6x-2hcm</a>)</li>
<li>Fix <a
href="https://www.cve.org/CVERecord?id=CVE-2026-5079">CVE-2026-5079</a>
(<a
href="https://github.com/expressjs/multer/security/advisories/GHSA-72gw-mp4g-v24j">GHSA-72gw-mp4g-v24j</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/expressjs/multer/commit/2e2af08157c66cbbc76539ccbd8869097a0c8feb"><code>2e2af08</code></a>
2.2.0 (<a
href="https://redirect.github.com/expressjs/multer/issues/1412">#1412</a>)</li>
<li><a
href="https://github.com/expressjs/multer/commit/a192b5278f240967f5eb13dd1e9a413b4e1b6533"><code>a192b52</code></a>
feat: add fieldNestingDepth limit option</li>
<li><a
href="https://github.com/expressjs/multer/commit/9c801c7136fdaa8437b84c6455cd46a3467a8058"><code>9c801c7</code></a>
fix: clean up in-progress disk writes on abort</li>
<li><a
href="https://github.com/expressjs/multer/commit/0adb21d0294fe7315344feb6ddee00b0666d9e8a"><code>0adb21d</code></a>
ci: add Node 26 to test matrix (<a
href="https://redirect.github.com/expressjs/multer/issues/1404">#1404</a>)</li>
<li><a
href="https://github.com/expressjs/multer/commit/f5e17c39c818edade71b4deec7d114fdaafd54af"><code>f5e17c3</code></a>
chore(deps): bump actions/checkout from 6.0.2 to 6.0.3 (<a
href="https://redirect.github.com/expressjs/multer/issues/1410">#1410</a>)</li>
<li><a
href="https://github.com/expressjs/multer/commit/de1fefd9d201f0ae48f1de056f00a349dd12f9bc"><code>de1fefd</code></a>
chore(deps): bump github/codeql-action from 4.32.4 to 4.36.1 (<a
href="https://redirect.github.com/expressjs/multer/issues/1409">#1409</a>)</li>
<li><a
href="https://github.com/expressjs/multer/commit/67abfc89f4caa5f842eb75083ddb3854db4cc38a"><code>67abfc8</code></a>
chore(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 (<a
href="https://redirect.github.com/expressjs/multer/issues/1397">#1397</a>)</li>
<li>See full diff in <a
href="https://github.com/expressjs/multer/compare/v2.1.1...v2.2.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=multer&package-manager=npm_and_yarn&previous-version=2.1.1&new-version=2.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 10:04:26 -07:00
dependabot[bot] d2fa57ab98 build(deps): bump sharp from 0.34.5 to 0.35.2 (#8739)
Bumps [sharp](https://github.com/lovell/sharp) from 0.34.5 to 0.35.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/lovell/sharp/releases">sharp's
releases</a>.</em></p>
<blockquote>
<h2>v0.35.2</h2>
<ul>
<li>
<p>TypeScript: Add <code>mediaType</code> to metadata response.
<a
href="https://redirect.github.com/lovell/sharp/issues/4492">#4492</a></p>
</li>
<li>
<p>Improve WebAssembly fallback detection.
<a
href="https://redirect.github.com/lovell/sharp/issues/4513">#4513</a></p>
</li>
<li>
<p>Improve code bundler support with stub binaries.
<a
href="https://redirect.github.com/lovell/sharp/issues/4543">#4543</a></p>
</li>
<li>
<p>Verify GIF <code>effort</code> option is an integer.
<a href="https://redirect.github.com/lovell/sharp/pull/4544">#4544</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>Verify <code>recomb</code> matrix entries are numbers.
<a href="https://redirect.github.com/lovell/sharp/pull/4545">#4545</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>TypeScript: Replace namespace with named exports for ESM.
<a
href="https://redirect.github.com/lovell/sharp/issues/4546">#4546</a></p>
</li>
<li>
<p>Bound dilate and erode width to avoid mask-size overflow.
<a href="https://redirect.github.com/lovell/sharp/pull/4548">#4548</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>Verify <code>convolve</code> kernel values are numbers.
<a href="https://redirect.github.com/lovell/sharp/pull/4549">#4549</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
</ul>
<h2>v0.35.2-rc.2</h2>
<ul>
<li>
<p>TypeScript: Add <code>mediaType</code> to metadata response.
<a
href="https://redirect.github.com/lovell/sharp/issues/4492">#4492</a></p>
</li>
<li>
<p>Improve WebAssembly fallback detection.
<a
href="https://redirect.github.com/lovell/sharp/issues/4513">#4513</a></p>
</li>
<li>
<p>Improve code bundler support with stub binaries.
<a
href="https://redirect.github.com/lovell/sharp/issues/4543">#4543</a></p>
</li>
<li>
<p>Verify GIF <code>effort</code> option is an integer.
<a href="https://redirect.github.com/lovell/sharp/pull/4544">#4544</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>Verify <code>recomb</code> matrix entries are numbers.
<a href="https://redirect.github.com/lovell/sharp/pull/4545">#4545</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>TypeScript: Replace namespace with named exports for ESM.
<a
href="https://redirect.github.com/lovell/sharp/issues/4546">#4546</a></p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/lovell/sharp/commit/c9622a38edfc6fc709764152ea34332ba01619cf"><code>c9622a3</code></a>
Release v0.35.2</li>
<li><a
href="https://github.com/lovell/sharp/commit/cd4568fd41e576345be3c5f774d22e441ac563ac"><code>cd4568f</code></a>
Upgrade to sharp-libvips v1.3.1</li>
<li><a
href="https://github.com/lovell/sharp/commit/78390cf3d22a79c799727564eb1d0ff92d0e759b"><code>78390cf</code></a>
Tests: Add font file to prevent font discovery flakiness (<a
href="https://redirect.github.com/lovell/sharp/issues/4550">#4550</a>)</li>
<li><a
href="https://github.com/lovell/sharp/commit/61210b4d0a6972e83fa5a8cef47e04445114c1e1"><code>61210b4</code></a>
Verify convolve kernel values are numbers (<a
href="https://redirect.github.com/lovell/sharp/issues/4549">#4549</a>)</li>
<li><a
href="https://github.com/lovell/sharp/commit/1cb27dcca43d2bb3b43fad485d9d54ece0ee1f3e"><code>1cb27dc</code></a>
Prerelease v0.35.2-rc.2</li>
<li><a
href="https://github.com/lovell/sharp/commit/c7606c3ca7d8364d36984f44bb81a45c4b7733fb"><code>c7606c3</code></a>
Upgrade to sharp-libvips v1.3.1-rc.0</li>
<li><a
href="https://github.com/lovell/sharp/commit/29d1e9e4d318775590e332f95088cf7f741c8dca"><code>29d1e9e</code></a>
Prerelease v0.35.2-rc.1</li>
<li><a
href="https://github.com/lovell/sharp/commit/bbba0a16bab7a6cc2b6f3023f3dc0337336b39bd"><code>bbba0a1</code></a>
Improve code bundler support with stub binaries</li>
<li><a
href="https://github.com/lovell/sharp/commit/ab528662ea949f60421dc527640d3188894fb57f"><code>ab52866</code></a>
Bound dilate and erode width to avoid mask-size overflow (<a
href="https://redirect.github.com/lovell/sharp/issues/4548">#4548</a>)</li>
<li><a
href="https://github.com/lovell/sharp/commit/0f594dde40ed08c391810da38d994e923fcdfc24"><code>0f594dd</code></a>
Prerelease v0.35.2-rc.0</li>
<li>Additional commits viewable in <a
href="https://github.com/lovell/sharp/compare/v0.34.5...v0.35.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=sharp&package-manager=npm_and_yarn&previous-version=0.34.5&new-version=0.35.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 10:04:17 -07:00
dependabot[bot] 63aef57d49 build(deps): bump dotenv from 17.3.1 to 17.4.2 (#8737)
Bumps [dotenv](https://github.com/motdotla/dotenv) from 17.3.1 to
17.4.2.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md">dotenv's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/motdotla/dotenv/compare/v17.4.1...v17.4.2">17.4.2</a>
(2026-04-12)</h2>
<h3>Changed</h3>
<ul>
<li>Improved skill files - tightened up details (<a
href="https://redirect.github.com/motdotla/dotenv/pull/1009">#1009</a>)</li>
</ul>
<h2><a
href="https://github.com/motdotla/dotenv/compare/v17.4.0...v17.4.1">17.4.1</a>
(2026-04-05)</h2>
<h3>Changed</h3>
<ul>
<li>Change text <code>injecting</code> to <code>injected</code> (<a
href="https://redirect.github.com/motdotla/dotenv/pull/1005">#1005</a>)</li>
</ul>
<h2><a
href="https://github.com/motdotla/dotenv/compare/v17.3.1...v17.4.0">17.4.0</a>
(2026-04-01)</h2>
<h3>Added</h3>
<ul>
<li>Add <code>skills/</code> folder with focused agent skills:
<code>skills/dotenv/SKILL.md</code> (core usage) and
<code>skills/dotenvx/SKILL.md</code> (encryption, multiple environments,
variable expansion) for AI coding agent discovery via the skills.sh
ecosystem (<code>npx skills add motdotla/dotenv</code>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Tighten up logs: <code>◇ injecting env (14) from .env</code> (<a
href="https://redirect.github.com/motdotla/dotenv/pull/1003">#1003</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/motdotla/dotenv/commit/f116f70310abab44fbfddbaeb833698b5bf84a9b"><code>f116f70</code></a>
17.4.2</li>
<li><a
href="https://github.com/motdotla/dotenv/commit/3a8161274fdd745239b86e604f4a7e972a1d3902"><code>3a81612</code></a>
fix visual order of faq</li>
<li><a
href="https://github.com/motdotla/dotenv/commit/13f55a89e136b2024e68d277b836dd5260fc16cf"><code>13f55a8</code></a>
Merge branch 'skill'</li>
<li><a
href="https://github.com/motdotla/dotenv/commit/4bbbf73f0906bd69975c48bf310a84b686e5b1b4"><code>4bbbf73</code></a>
reorganize faq</li>
<li><a
href="https://github.com/motdotla/dotenv/commit/c3da64bb2ba1d0e02f8b9b2b7ccb7e6f7a51d56c"><code>c3da64b</code></a>
Merge pull request <a
href="https://redirect.github.com/motdotla/dotenv/issues/1009">#1009</a>
from motdotla/skill</li>
<li><a
href="https://github.com/motdotla/dotenv/commit/6f743b173fbd6c26f7eab7040d251f9a6c8b977d"><code>6f743b1</code></a>
update source</li>
<li><a
href="https://github.com/motdotla/dotenv/commit/fc2c6247e858a32d4024cb06a5b0c79aa35851f5"><code>fc2c624</code></a>
update skill</li>
<li><a
href="https://github.com/motdotla/dotenv/commit/972315ba74bb2bbba4483d112e853fd26006ef8a"><code>972315b</code></a>
Tighten up skill</li>
<li><a
href="https://github.com/motdotla/dotenv/commit/2795fce3d1ed07b4c570f1e06ab1c0d533c86997"><code>2795fce</code></a>
reorganize faq</li>
<li><a
href="https://github.com/motdotla/dotenv/commit/d5495d4ae8e4e41ef9a682c9e00c81552794274e"><code>d5495d4</code></a>
adjust skill</li>
<li>Additional commits viewable in <a
href="https://github.com/motdotla/dotenv/compare/v17.3.1...v17.4.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dotenv&package-manager=npm_and_yarn&previous-version=17.3.1&new-version=17.4.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 10:04:01 -07:00
dependabot[bot] 01f49b1fa0 build(deps): bump @aws-sdk/client-s3 from 3.1072.0 to 3.1075.0 (#8742)
Bumps
[@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3)
from 3.1072.0 to 3.1075.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/aws/aws-sdk-js-v3/releases">@​aws-sdk/client-s3's
releases</a>.</em></p>
<blockquote>
<h2>v3.1075.0</h2>
<h4>3.1075.0(2026-06-23)</h4>
<h5>New Features</h5>
<ul>
<li><strong>client-kafka:</strong> Amazon MSK Replicator now supports
mTLS authentication when connecting to external Apache Kafka clusters,
enabling customers to replicate data from clusters that require mutual
TLS for client authentication. This capability is supported when
replicating to Amazon MSK Express brokers. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/005f9529d4d3cd0c98b002a3584773b253a702dc">005f9529</a>)</li>
</ul>
<hr />
<p>For list of updated packages, view
<strong>updated-packages.md</strong> in
<strong>assets-3.1075.0.zip</strong></p>
<h2>v3.1074.0</h2>
<h4>3.1074.0(2026-06-22)</h4>
<h5>Chores</h5>
<ul>
<li><strong>xml-builder:</strong>
<ul>
<li>move testing devDeps to root, remove unused nodable dep (<a
href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8118">#8118</a>)
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/ed82880d26cac439d808eca5760da899cf449899">ed82880d</a>)</li>
<li>parse XML internally (<a
href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/7863">#7863</a>)
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/74d0a071437c84a14396dbcc7f07f8480c369c58">74d0a071</a>)</li>
</ul>
</li>
</ul>
<h5>Documentation Changes</h5>
<ul>
<li>typo in contributing.md (<a
href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8116">#8116</a>)
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/87ff33d30edb476912301f87ed6e2afac3cd5a93">87ff33d3</a>)</li>
</ul>
<h5>New Features</h5>
<ul>
<li><strong>clients:</strong> update client endpoints as of 2026-06-22
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/3a55a3338792f712baf2e97d3f3c597fc28707c1">3a55a333</a>)</li>
<li><strong>client-cloudwatch-logs:</strong> CloudWatch Logs Updates -
New APIs introduced to support syslog ingestion to a log group. For more
information, see CloudWatch Logs API documentation. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/01a3b513503169fb86db0bea0889f585c9004b55">01a3b513</a>)</li>
<li><strong>client-bedrock-agentcore:</strong> Adds an optional
extractionMode field to CreateEvent. SKIP retains the event in
short-term memory but excludes it from long-term memory extraction. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/749753adae395e3ab3ab494df119f8d6354ca562">749753ad</a>)</li>
<li><strong>client-omics:</strong> Adds support for scratch ephemeral
storage mounted at tmp (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/331e3023c1049c5188dc4cec3adabae0c62e84f2">331e3023</a>)</li>
<li><strong>client-application-signals:</strong> Application Signals now
supports dynamic instrumentation and Service Events telemetry. Add
instrumentation at runtime without restarts, and use fine-grained
profiling data to quickly pinpoint latency and error root causes. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/f93b1c0333846b2d16c698f8c9b4034f93ab867c">f93b1c03</a>)</li>
<li><strong>client-mediaconnect:</strong> AWS MediaConnect now supports
Content Quality Analysis for Router Inputs, enabling detection of black
frames, frozen frames, and silent audio with configurable thresholds.
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/05054853a5aa6e740597c3932b5e2491b15e3a12">05054853</a>)</li>
<li><strong>client-lambda-core:</strong> Initial release of the AWS
Lambda Core SDK with APIs to create, manage, and tag network connectors
that enable Lambda compute resources to access private resources in your
Amazon VPC. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/e35cdab89fcf7ca679f37776418cb8d8e1269c14">e35cdab8</a>)</li>
<li><strong>client-lambda:</strong> Add support for tagging Network
Connector resources in AWS Lambda. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/fbfc40785e024fe2564e4be02ef425280693fce6">fbfc4078</a>)</li>
<li><strong>client-guardduty:</strong> Added AI-powered investigations
that automatically analyze security findings, correlate related
activity, and produce structured summaries with risk assessment,
confidence scoring, MITRE technique classification, and actionable next
steps. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/83c2983945db4a54b004feed8d2d18935a3df431">83c29839</a>)</li>
<li><strong>client-lambda-microvms:</strong> Lambda MicroVMs GA launch.
Lambda MicroVMs enable isolated and highly responsive execution of
user-supplied or LLM-generated code. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/5519a7e28fae4f57dd852109244b6370ff79f8bb">5519a7e2</a>)</li>
<li><strong>client-kafka:</strong> Amazon MSK Replicator now supports
mTLS authentication when connecting to external Apache Kafka clusters,
enabling customers to replicate data from clusters that require mutual
TLS for client authentication. This capability is supported when
replicating to Amazon MSK Express brokers. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/ce7d1bf501fe6f7d6a454f96c1befc3829e23385">ce7d1bf5</a>)</li>
<li><strong>client-quicksight:</strong> Updated the Amazon Quick Spaces
API to remove unsupported SPACE and ARTIFACT values from the
SpaceQuickSightResourceType enum. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/e1b325d42e491ceb75742bbdb56bfc3b98767ff1">e1b325d4</a>)</li>
<li><strong>client-ec2:</strong> This release adds support for AMI
Watermark and Allowed AMIs integration (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/d1698bed3961295343fdd86d0a57820538023bc7">d1698bed</a>)</li>
<li><strong>client-direct-connect:</strong> Added VIF rate limiting
support for AWS Direct Connect, allowing customers to set bandwidth
allocations on virtual interfaces to manage traffic on dedicated
connections. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/228a95dc0c11cbcc1f007718faf93181c014a854">228a95dc</a>)</li>
</ul>
<h5>Bug Fixes</h5>
<ul>
<li><strong>cloudfront-signer:</strong> filename asterisk apostrophe
encoding fix (<a
href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8119">#8119</a>)
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/35acab408b9bd5350928525c8a67563ae551580a">35acab40</a>)</li>
</ul>
<hr />
<p>For list of updated packages, view
<strong>updated-packages.md</strong> in
<strong>assets-3.1074.0.zip</strong></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md">@​aws-sdk/client-s3's
changelog</a>.</em></p>
<blockquote>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1074.0...v3.1075.0">3.1075.0</a>
(2026-06-23)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1073.0...v3.1074.0">3.1074.0</a>
(2026-06-22)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1072.0...v3.1073.0">3.1073.0</a>
(2026-06-19)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/29ee1999340b8d8288184076df6557541974b13f"><code>29ee199</code></a>
Publish v3.1075.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/c48dfa08aa057f100c69ccb571d35004eddec207"><code>c48dfa0</code></a>
Publish v3.1074.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/74d0a071437c84a14396dbcc7f07f8480c369c58"><code>74d0a07</code></a>
chore(xml-builder): parse XML internally (<a
href="https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3/issues/7863">#7863</a>)</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/ee71adc9663fc2ebaabae455981fd169fd6e97b2"><code>ee71adc</code></a>
Publish v3.1073.0</li>
<li>See full diff in <a
href="https://github.com/aws/aws-sdk-js-v3/commits/v3.1075.0/clients/client-s3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@aws-sdk/client-s3&package-manager=npm_and_yarn&previous-version=3.1072.0&new-version=3.1075.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-30 10:03:31 -07:00
Devin FoleyandPaperclip 8d9f9fd240 Add reusable sandbox custom images (#8794)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - A growing part of that work runs in sandboxed environments rather
than on the operator's local machine.
> - Today sandbox providers can start fresh workspaces and run probes,
but they do not have a shared contract for capturing and reusing
prepared sandbox state.
> - Operators need a way to set up tools, credentials, and project
dependencies once, then reuse that prepared image for later agent runs.
> - This pull request adds reusable sandbox custom images across the
provider contract, server runtime, and board UI.
> - It also keeps probes and sandbox copy flows aligned with
pre-authenticated/custom-image environments.
> - The benefit is faster, more reliable sandbox runs without repeatedly
rebuilding the same environment setup.

## Linked Issues or Issue Description

No public GitHub issue was found for this change. Inline feature request
follows.

### Problem or motivation

Sandboxed agents need reusable prepared runtime state so repeated runs
do not require manual setup every time. Operators often need system
packages, CLIs, SDKs, dependency caches, credentials, and project
tooling available before an agent can work productively.

### Proposed solution

Add a provider-level custom-image capability, server-side setup/capture
lifecycle, Daytona/fake provider support, and board UI controls for
creating, testing, selecting, and deleting custom images.

### Alternatives considered

Leaving this as provider-specific setup outside Paperclip would keep the
control plane blind to image state and would not give agents consistent
environment metadata. Re-running setup commands for every lease is
simpler, but slower and less reliable for interactive or credentialed
setup.

### Roadmap alignment

Checked `ROADMAP.md`; this aligns with the Cloud / Sandbox agents
roadmap area and does not duplicate any related public issue or PR found
by search.

Additional context:
- Subsystem affected: cross-cutting (`packages/db`, `packages/shared`,
`packages/plugins`, `server`, `ui`).
- Duplicate search: searched GitHub for `sandbox custom image` and
`sandbox template environment`; no related public issues or PRs were
found.

## What Changed

- Added custom-image shared types, validators, constants, API paths, and
database schema/migration.
- Added server services/routes for custom-image templates and setup
sessions, including runtime cleanup and provider metadata handling.
- Extended plugin/sandbox provider capabilities for interactive setup,
template capture, and template deletion.
- Implemented custom-image support in the fake sandbox provider and
Daytona provider.
- Updated environment runtime/config handling so active custom images
flow into leases, probes, and agent execution.
- Added board UI controls and API client support for custom-image setup,
capture, selection, status, and error states.
- Hardened sandbox copy/probe behavior for insecure clipboard contexts
and pre-authenticated sandbox images.
- Added targeted coverage across shared validators, DB schema, server
routes/services, provider plugins, adapter probes, and UI flows.

## Verification

- `pnpm install --frozen-lockfile --ignore-scripts`
- `pnpm vitest run
packages/adapters/claude-local/src/server/test.probe.test.ts
packages/adapters/claude-local/src/server/test.ts
packages/adapters/codex-local/src/server/test.remote.test.ts
packages/adapters/codex-local/src/server/test.ts`
- `pnpm --filter @paperclipai/adapter-claude-local typecheck`
- `pnpm --filter @paperclipai/adapter-codex-local typecheck`
- `pnpm vitest run
packages/db/src/environment-custom-images-schema.test.ts
packages/shared/src/environment-custom-images.test.ts
packages/shared/src/validators/plugin.test.ts
server/src/__tests__/environment-custom-images-service.test.ts
server/src/__tests__/workspace-runtime.test.ts
packages/plugins/sandbox-providers/daytona/src/plugin.test.ts
ui/src/pages/CompanyEnvironments.test.tsx
ui/src/pages/CompanySettings.test.tsx`
- `pnpm -r typecheck`
- `pnpm build`
- `rm -rf packages/db/dist && pnpm test:run`
- Public-safety scan of the final diff found no internal Paperclip issue
links, private instance URLs, or real secret patterns.

## Risks

- Adds a database migration and new environment runtime tables, so
migration ordering and rollback need care.
- Provider implementations may differ in how reliably they can
capture/delete images; unsupported providers surface capability-gated UI
states.
- Custom-image state can contain operator-prepared tooling and
credentials inside the provider image, so providers must enforce their
own access controls and cleanup semantics.
- Broad surface area across shared contracts, server runtime, plugins,
adapters, and UI means CI and Greptile review should be watched closely.

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

## Model Used

OpenAI GPT-5 (`gpt-5`) via Codex CLI with tool use and code execution.
Assisted with branch cleanup, conflict resolution, local verification,
and PR preparation. Earlier branch implementation work was assisted by
Paperclip-managed Claude/Codex agents.

## 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-06-30 09:57:49 -07:00
Devin FoleyandPaperclip 0c2ec7deb4 Fix sandboxed Claude and Codex probe behavior (#8775)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Local adapters are the bridge between Paperclip's control plane and
provider CLIs such as Claude Code and Codex.
> - Those adapters can run either on the host machine or inside a
remote/sandbox execution target.
> - Sandbox probes need to validate the same auth/config path that real
sandbox execution will use.
> - The previous probe paths could surface misleading Claude errors,
rely on host-only Codex state, or upload far more Codex home state than
the probe needed.
> - This pull request fixes the Claude and Codex sandbox probe/runtime
behavior together while keeping provider-specific sandbox image work out
of scope.
> - The benefit is faster, clearer adapter health checks that better
match real sandbox execution.

## Linked Issues or Issue Description

No public GitHub issue was found for this exact bug during duplicate
search.

Bug report:

**What happened?**

Sandboxed Claude/Codex adapter tests could diverge from real runtime
auth/config behavior. Claude sandbox probes could show the leading
stream init line instead of the real final error, and Codex sandbox
probes could upload full managed home state or mask a sandbox-local
login with an empty uploaded `CODEX_HOME`.

**Expected behavior**

Sandbox probes should exercise the remote runtime contract, preserve
useful sandbox credentials, avoid relying on unrelated host state, and
report actionable probe failures.

**Steps to reproduce**

1. Configure a remote/sandbox execution target for `claude_local` or
`codex_local`.
2. Run the environment Test/probe path where host credentials differ
from the sandbox's runtime credentials or the managed Codex home
contains session history.
3. Observe that probe behavior can differ from the actual sandbox
runtime path or surface an unhelpful Claude stream initialization line.

**Paperclip version or commit**

Current `master` before this PR, based on `4a2447da3`.

**Deployment mode**

Local development/control-plane deployment with remote sandbox execution
targets.

Related search performed:

- Public issues: `Claude sandbox probe`, `Codex CODEX_HOME sandbox`
returned no matches.
- Public PRs: `Claude Codex sandbox probe`, `codex home sandbox`,
`claude auth sandbox` returned no matches.

## What Changed

- Made Claude sandbox Test probes materialize the same Paperclip-managed
Claude config seed path used by sandbox execution.
- Preserved sandbox-local Claude credentials when materializing remote
Claude config and expanded auth-required detection for `/login` API-key
failures.
- Improved Claude hello-probe diagnostics so the final result/error is
surfaced instead of the unhelpful stream init event, with transient
upstream failures downgraded to warnings.
- Changed Codex probe behavior to upload only minimal auth/config files
instead of the full managed `CODEX_HOME`.
- Let Codex sandbox probes leave `CODEX_HOME` unset when the host has no
credentials, so pre-authenticated sandbox images can be tested directly.
- Excluded bulky host-local Codex session/shell state from sandbox
runtime home uploads.
- Switched the Codex local default model away from the
ChatGPT-unsupported `gpt-5.3-codex` option.
- Added regression coverage for Claude parsing/probe paths, Codex
adapter metadata/argument/probe behavior, and server-level Claude
sandbox environment behavior.

## Verification

Passed locally:

- `pnpm install --frozen-lockfile`
- `pnpm vitest run
packages/adapters/claude-local/src/server/parse.test.ts
packages/adapters/claude-local/src/server/test.probe.test.ts
server/src/__tests__/claude-local-adapter-environment.test.ts`
- `pnpm vitest run packages/adapters/codex-local/src/index.test.ts
packages/adapters/codex-local/src/server/codex-args.test.ts
packages/adapters/codex-local/src/server/test.remote.test.ts`
- `pnpm --filter @paperclipai/adapter-claude-local typecheck`
- `pnpm --filter @paperclipai/adapter-codex-local typecheck`
- `pnpm --filter @paperclipai/server typecheck`
- `git diff --check`

## Risks

- Adapter configuration behavior is sensitive to local vs sandboxed
execution mode, so review should focus on environment detection,
argument construction, and any state written during probe/test runs.
- The Codex default-model change may affect newly created agents that
rely on the adapter default instead of an explicit model.
- Excluding Codex session/shell state from sandbox uploads should be
safe for fresh sandbox runs, but reviewers should confirm no runtime
resume path depends on that host-local state.
- Provider-specific setup/capture behavior is intentionally left to
separate work.

## Model Used

OpenAI GPT-5 Codex via Paperclip `codex_local`; tool-enabled local
coding session with terminal access. Context window size was not exposed
by the runtime.

## 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-06-30 08:41:50 -07:00
DottaandPaperclip 3e31bf09bc [codex] Add pipeline automation title templates (#8787)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Pipeline automations let operators standardize repeated issue and
workflow actions.
> - Pipeline-created issues currently need a way to derive useful titles
from routine variables.
> - Without a configurable title template, automated pipeline output is
harder to scan and distinguish.
> - This pull request adds a title-template field through shared
contracts, server persistence, API routes, and the pipeline settings UI.
> - The benefit is clearer issue titles for pipeline-created work while
preserving the existing pipeline behavior when no template is
configured.

## Linked Issues or Issue Description

Refs #8790

This PR adds configurable generated-issue title templates for pipeline
automations.

## What Changed

- Added `issueTitleTemplate` to the shared pipeline automation contract
and field constants.
- Persisted and returned the title template through pipeline service and
route code.
- Applied title-template rendering when pipeline automations create
issue work.
- Added pipeline settings UI controls for editing the title template and
reusing routine variables.
- Moved title-token cursor restoration out of the React state updater
and into a layout effect.
- Added server and UI coverage for storing, returning, and rendering
pipeline title templates.

## Verification

- `NODE_ENV=test pnpm run preflight:workspace-links && NODE_ENV=test
pnpm exec vitest run server/src/__tests__/pipelines-service.test.ts
server/src/__tests__/pipelines-routes.test.ts
ui/src/pages/PipelineSettings.test.ts`
- Result before review follow-up: 3 files passed, 58 tests passed.
- `pnpm --filter @paperclipai/ui exec vitest run
src/pages/PipelineSettings.test.ts`
- Result after review follow-up: 1 file passed, 7 tests passed.
- Branch was merged with current `paperclipai:master` at `f019f54bb3`
before opening this PR.
- Searched existing PRs for the same head branch and for pipeline
title-template duplicates; no matching existing PR was found.
- Note: GitHub could not open a PR directly from `cryppadotta/paperclip`
because that repository is not a fork of `paperclipai/paperclip`. The
same updated branch SHA was pushed to `paperclipai/paperclip` so this PR
can compare normally against `master`.

## Risks

Low to moderate risk. The change touches pipeline automation persistence
and generated issue creation, so regressions would most likely appear as
missing or incorrectly rendered generated issue titles. Existing
behavior should remain unchanged when `issueTitleTemplate` is unset.

## Model Used

OpenAI Codex, GPT-5-based coding agent, tool-enabled execution in a
Paperclip heartbeat, with repository inspection, Git, GitHub CLI, and
local 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
- [ ] 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-06-30 07:52:40 -07:00
Devin FoleyandPaperclip Agent f019f54bb3 Fix active heartbeat run reaping (#8776)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Heartbeat monitoring is the subsystem that keeps agent execution
visible and recovers work only when execution continuity is genuinely
lost.
> - Routes and scheduler paths can construct separate heartbeat service
instances inside the same server process.
> - Active adapter execution tracking was scoped to each service
instance, so the periodic orphan reaper could miss a run that another
service instance was actively executing.
> - Remote or sandbox adapters are especially exposed because they may
not persist a local process PID/group and may go quiet while the remote
command is still alive.
> - This pull request makes active in-process adapter execution tracking
shared across heartbeat service instances and adds a regression for the
cross-instance reaper case.
> - The benefit is fewer false `process_lost` failures for long-running
or quiet sandbox/remote agent runs.

## Linked Issues or Issue Description

No public GitHub issue exists. This PR describes the bug inline using
the bug report template fields.

### What happened?

An actively executing heartbeat run could be finalized as `process_lost`
by the orphan reaper when adapter execution was active through one
`heartbeatService()` instance but the reaper ran through another
instance in the same server process.

### Expected behavior

The orphan reaper should skip runs that are still actively executing
in-process, regardless of which `heartbeatService()` instance is doing
the reaping.

### Steps to reproduce

1. Create two `heartbeatService()` instances in the same process.
2. Start an adapter run through the first instance.
3. Backdate the run row enough for orphan reaping to consider it stale.
4. Run orphan reaping through the second instance while the first
instance is still awaiting adapter execution.
5. Observe that the old instance-local tracking can mark the live run as
`process_lost`.

### Paperclip version or commit

Reproduced against `master` before commit
`44ba6d8bb4f7ae1ca3715697f750844d770d83a3`.

### Deployment mode

Self-hosted/local server process with route and scheduler code paths
constructing separate heartbeat service instances. Remote or sandbox
adapters are the highest-risk case because they may not have local PID
metadata and can be quiet while still running.

## What Changed

- Moved active adapter execution tracking from the `heartbeatService()`
closure to module-level process state shared by heartbeat service
instances.
- Added a regression test that starts a run through one heartbeat
service instance and runs orphan reaping through another, proving the
active run is not reaped and can finish normally.

## Verification

- `pnpm exec vitest run
server/src/__tests__/heartbeat-process-recovery.test.ts` passes: 61
tests.
- `pnpm -r typecheck` passes.
- `pnpm build` passes; existing UI build warnings remain for
`::highlight(...)`, large chunks, and a mixed static/dynamic import.
- `pnpm test:run` does not fully pass in this local environment: 1
unrelated existing failure in
`server/src/__tests__/workspace-runtime.test.ts` for `auto-detects the
default branch via symbolic-ref when origin/HEAD is set`. The fixture
command fails with `git push -u origin main master` because the temp
repo has no `master` ref.
- Reran the isolated failing test with `pnpm exec vitest run
server/src/__tests__/workspace-runtime.test.ts -t "auto-detects the
default branch via symbolic-ref when origin/HEAD is set"`; it reproduces
the same missing-`master` ref failure.

## Risks

- Low risk for single-process Paperclip servers: this only broadens
in-process active run tracking across service instances.
- Multi-process deployments still need persisted or distributed
execution liveness to coordinate reaping across processes; this PR does
not claim to solve cross-process recovery.
- A run could be skipped by the reaper while its adapter promise is
active, but the existing `finally` path removes the active marker after
execution settles.

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

## Model Used

OpenAI GPT-5 via Codex, with tool use and local command execution. The
runtime did not expose a separate context-window value.

## 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 — targeted regression,
typecheck, and build pass; full `pnpm test:run` has the unrelated
missing-`master` ref fixture failure documented above
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes — no
docs change needed for this internal bug fix
- [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 Agent <noreply@paperclip.ing>
2026-06-30 00:40:56 -07:00
Devin FoleyandPaperclip a7a73d5bc7 Fix stale server info debug metadata (#8753)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The experimental server info debug view helps local operators
inspect what code a running dev instance is actually serving
> - The view was moved into the account-menu drawer, which only mounts
while that drawer is open
> - That made stale health-query data easier to see after restarts, and
the server was also caching the running commit at process boot
> - A clean commit label alone is incomplete when the checkout has
uncommitted local changes
> - This pull request keeps the drawer health data fresh, refreshes git
metadata on demand, and adds a path-free checkout-state summary
> - The benefit is that the debug view reports restart time, running
commit, and dirty-checkout state without exposing local paths, secrets,
logs, or environment details

## Linked Issues or Issue Description

Fixes: #8752

## What Changed

- `SidebarServerInfo.tsx`: refetch the health query whenever the drawer
opens and poll every 2s while the dev server is active.
- `server-info.ts`: keep `processStartedAt` stable while refreshing git
HEAD through a short TTL cache instead of freezing commit metadata at
module boot.
- Shared health contract/OpenAPI: add `serverInfo.git.localChanges` with
only staged, unstaged, and untracked counts plus safe unavailable
fallbacks.
- `SidebarServerInfo.tsx`: add a `Checkout state` row that renders
clean/dirty/unavailable copy without file paths.
- Tests: cover stale drawer refresh, interval polling, TTL commit
refresh, health response shape, checkout-state count parsing, and
path-free UI rendering.

## Verification

- `npx vitest run server/src/__tests__/server-info.test.ts
server/src/__tests__/health.test.ts
ui/src/components/SidebarServerInfo.test.tsx` -> 3 files / 19 tests
passing.
- `pnpm install --frozen-lockfile --ignore-scripts` -> refreshed stale
workspace links without lockfile/source churn.
- `pnpm --filter @paperclipai/shared --filter @paperclipai/server
--filter @paperclipai/ui typecheck` -> passing.
- `pnpm --filter @paperclipai/ui typecheck` -> passing after the
Greptile test-coverage fix.
- `pnpm check:tokens` -> no forbidden tokens found.
- Local diff scans for obvious secrets, credentials, private URLs, local
paths, and PII patterns -> no matches.
- GitHub PR checks on head `56defd446` -> all green, including `verify`,
canary dry run, e2e, security scans, and Greptile Review.
- Greptile latest summary -> Confidence Score 5/5, 0 new comments; the
prior P2 polling-coverage thread is resolved.

## Risks

Low risk. The UI remains behind the experimental
`enableServerInfoDebugView` flag. The extra git status call is throttled
by the existing server-info TTL and reports only counts, not paths or
file names. If git status is unavailable, the commit row still works and
the checkout-state row shows clear fallback copy.

## Model Used

Claude Opus (claude-opus-4-8), extended thinking, with tool use / code
execution assisted the original stale-metadata fix. OpenAI GPT-5 via
Codex local, with tool use and code execution, added the checkout-state
follow-up, Greptile fix-up, and PR verification.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-29 13:10:58 -07:00
DottaandPaperclip 5e3d6e3627 [codex] Preserve plan review context in agent wakes (#8649)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Planning work relies on issue documents, request-confirmation
interactions, and inline plan annotations
> - Agents can be woken after a plan comment, annotation, or
confirmation decision
> - The wake payload needs enough plan-review context for the agent to
act on the specific feedback instead of losing the thread and falling
back to broad refetches
> - This pull request adds bounded plan-review context to wake payloads
and heartbeat context
> - It also teaches the adapter wake prompt renderer to surface those
open plan annotations and interaction results directly
> - The benefit is that agents can continue plan review and plan
acceptance flows with the relevant comments in hand while keeping wake
payloads bounded and company-scoped

## Linked Issues or Issue Description

No matching public GitHub issue was found.

### Subsystem affected

Cross-cutting: `server/`, `packages/shared`, and
`packages/adapter-utils`.

### Problem or motivation

Plan-review continuations can wake an agent after a plan comment, inline
annotation, or request-confirmation decision without enough inline
context about the open plan annotations or accepted/rejected
confirmation target. That makes scoped wakes less reliable because the
agent may need to refetch broad issue history before it can tell what
feedback should be incorporated.

### Proposed solution

Include bounded, company-scoped plan review context in wake payloads and
heartbeat context. The context includes open `plan` annotation threads,
recent annotation comments, truncation metadata, and plan-confirmation
interaction target/result details. Render that information in the
adapter wake prompt so agents see the relevant plan-review feedback
immediately.

### Alternatives considered

Relying on agents to fetch the full issue thread after every plan-review
wake was rejected because it is slower, harder to audit, and easier to
mishandle when the wake is meant to be scoped to a specific comment,
annotation, or interaction result.

### Roadmap alignment

This supports the roadmap areas for Agent Reviews and Approvals, Deep
Planning, and Enforced Outcomes by making plan approval continuations
explicit and actionable.

### Additional context

The implementation keeps payload size bounded with per-thread,
per-comment, and total-body limits. Resolved annotation threads are
intentionally omitted so the wake focuses on feedback still needing
action.

## What Changed

- Added shared `PlanReviewContext` types for plan annotation threads,
comments, interaction targets, and continuation results.
- Added server-side plan review context assembly for open `plan`
annotation threads with bounded thread/comment/body limits.
- Included plan review context in heartbeat context and scoped wake
payloads for planning, annotation, comment, and plan-confirmation
interaction wakes.
- Rendered plan annotation deltas, open plan comments, interaction
results, and accepted target revisions in adapter wake prompts.
- Added focused regression coverage for scoped plan review context, wake
prompt rendering, annotation filtering, and safe standard-mode
annotation wakes.
- Addressed Greptile feedback by bounding the plan-comment DB fetch and
removing unused plan review context input fields.

## Verification

- `pnpm run preflight:workspace-links`
- `pnpm exec vitest run --project @paperclipai/adapter-utils
packages/adapter-utils/src/server-utils.test.ts`
- `pnpm exec vitest run --project @paperclipai/server
--no-file-parallelism --maxWorkers=1
server/src/__tests__/document-annotations-service.test.ts
server/src/__tests__/issue-thread-interaction-routes.test.ts
server/src/__tests__/issues-goal-context-routes.test.ts`
- `pnpm --filter @paperclipai/shared typecheck`
- `pnpm --filter @paperclipai/adapter-utils typecheck`
- `pnpm --filter @paperclipai/server typecheck`
- `git diff --check public-gh/master...HEAD`
- GitHub PR checks are green on
`36d0ac6a5dce27b9d62e201bf6d9829170c5974e`n- Rebased onto current
`paperclipai/paperclip:master` and confirmed GitHub reports the PR as
mergeable
- Greptile Review completed successfully after 2 comments were addressed
and resolved; 0 unresolved review threads remain

## Risks

- Medium: wake payloads now include additional plan-review data, so
limits and truncation behavior need to stay conservative as annotation
volume grows.
- Low migration risk: no database schema or migration changes.
- Low repository hygiene risk: this PR does not touch `pnpm-lock.yaml`,
`.github/workflows`, or media assets.

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

## Model Used

OpenAI Codex using `gpt-5` as a coding agent with shell/tool execution.
Reasoning mode and exact context window were not exposed by the runtime.

## 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-06-29 13:26:26 -05:00
Dotta e6407b3225 refactor: revert X mention poller backend (#8709)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The core server and database packages should only carry features
that are ready to remain in the product surface.
> - The X mention poller backend added database tables, Drizzle schema
exports, a server service, and a server test suite.
> - That backend work needs to be removed from core for now so the main
app does not carry unused X mention poller infrastructure.
> - A clean revert is safer than leaving partially unused database and
service code behind.
> - This pull request removes the poller backend artifacts and keeps the
migration journal aligned with the reverted migration history.
> - The benefit is that fresh environments no longer create or expose
the X mention poller backend tables or service code.

## Linked Issues or Issue Description

No public GitHub issue exists for this revert.

Duplicate PR search: searched open PRs in `paperclipai/paperclip` for "x
mention poller"; only this PR matched.

### What happened?

Core contained X mention poller backend infrastructure that should not
remain in the main Paperclip product surface right now.

### Expected behavior

Fresh core installs and migrations should not create the X mention
poller tables, and the server/db packages should not expose the removed
poller service or schema exports.

### Steps to reproduce

1. Inspect the prior migration journal after the original poller backend
commit.
2. Inspect the Drizzle schema exports.
3. Inspect the server services and tests for X mention poller backend
artifacts.

### Paperclip version or commit

This PR reverts the backend artifacts from the current `master` history.

### Deployment mode

Local development and CI.

## What Changed

- Deleted the `0125_x_mention_poller` migration and removed its journal
entry so fresh environments do not create the X mention poller tables.
- Removed the X mention Drizzle schema file and schema exports from the
db package.
- Removed the X mention poller server service and its server test suite.
- Left the functional diff unchanged from the original revert.

## Verification

- `rg -n "x_mentions|x-mention-poller|mention
poller|0125_x_mention_poller|xMention" packages server` returned no
matches.
- `pnpm --filter @paperclipai/db typecheck`
- `pnpm --filter @paperclipai/server typecheck`
- Current functional CI checks are green; this metadata update is
intended to re-run and clear the `commitperclip PR Review` gate.

## Risks

- Developers who already applied migration `0125_x_mention_poller`
locally will keep four stale tables that Drizzle no longer tracks:
`x_mention_sources`, `x_mention_author_allowlist`, `x_mentions`, and
`x_mention_budget_ledger`.
- Manual local cleanup for those developers is to drop the stale
`x_mention_*` tables from their local database after confirming they do
not need that local data.
- Fresh environments that have not applied the removed migration should
be unaffected.

## Model Used

OpenAI Codex, GPT-5 family, via the ACPX-backed Codex local adapter.
Tool use included local shell inspection and GitHub CLI metadata
updates.

## Checklist

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

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents and operators increasingly need external event sources to
become durable Paperclip work inputs
> - X mentions are one such source, but intake needs to be safe before
any downstream automation consumes them
> - The backend needs stable source state, idempotent mention storage,
author gating, rate-limit handling, and budget accounting
> - This pull request adds the database contract and service layer for X
mention polling and hydration queueing
> - The benefit is that future X-triggered workflows can build on a
controlled, test-covered ingestion path instead of calling the X API
directly

## Linked Issues or Issue Description

- No public GitHub issue exists for this exact backend extraction.
- Problem: Paperclip does not yet have a durable, budget-aware backend
path for ingesting X mentions as external work inputs.
- Proposed solution: add X mention source, mention, allowlist, and
budget ledger tables plus a poller service that stores mentions
idempotently, queues only allowlisted authors for hydration, tracks
cursor state, records spend decisions, and fails closed when cost
estimates are unavailable.
- Related but not duplicate: #8609, #8199, and #7316 touch internal
mention wake behavior rather than X API mention ingestion.

## What Changed

- Added X mention poller database tables and schema exports for sources,
stored mentions, author allowlists, and budget ledger entries.
- Added a server-side X mention poller service with cursoring,
idempotent upsert behavior, allowlist gating, hydration queue handling,
rate-limit backoff, and budget pause behavior.
- Added focused Vitest coverage for intake gating, duplicate retries,
cursor safety, rate limits, budget failures, and hydration budget
pauses.

## Verification

- `pnpm exec vitest run server/src/__tests__/x-mention-poller.test.ts`
- `pnpm --filter @paperclipai/db typecheck`
- `pnpm --filter @paperclipai/server typecheck`

## Risks

- Migration ordering matters because this adds migration
`0125_x_mention_poller.sql`; it should merge after the existing `0124`
migrations on `master`.
- The service is backend-only and adapter-driven in this PR, so product
behavior should not change until callers wire it into a runtime path.
- Budget accounting intentionally fails closed when estimates are
missing, which may pause a source rather than risk unbounded API spend.

## Model Used

- OpenAI Codex, GPT-5-based coding agent, tool-enabled local repository
and terminal workflow.

## 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-06-28 05:44:43 -05:00