mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-07 07:23:08 +02:00
faaa9b22e5511cb4e8ef84378589935691d2e5fd
1131
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 |
||
|
|
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> |
||
|
|
7bfaaadcb8 | Add dependency wake reconciliation backstop (#8943) | ||
|
|
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> |
||
|
|
a6b7b12fd7 |
Harden work timeline security filters (#8923)
Squash merge PR #8923.
Verified before merge:
- PR head:
|
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 /> [](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> |
||
|
|
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 /> [](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> |
||
|
|
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 /> [](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> |
||
|
|
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 /> [](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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 |
||
|
|
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> |