mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-30 05:16:50 +01:00
441b35fd0dcfb520aecbb6cf0157bc2b716dd4f4
63
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5bf0142d45 |
fix(server): schedule Discord command registration from saved deadlines (#17557)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Chat connections register and verify provider commands in the background. > - Discord command recovery ran inside the recurring Gateway runtime scan. > - Its existing durable records already store verification and retry deadlines. > - This pull request gives command registration its own shared-coordinator worker and scoped commit notifications. > - Idle command work stops querying between real deadlines. Existing command authority and recovery remain intact. ## Linked Issues or Issue Description Refs #17554 and #17561. Both foundations have merged. This slice targets master. Runtime discovery and the other chat maintenance duties remain separate work. **What happened?** The chat runtime maintenance loop called Discord command registration on every reconciliation. It repeatedly read durable command state even when the next remote verification or retry was minutes away. **Expected behavior** Use committed producer changes and saved deadlines. Keep the existing five-minute verification policy, Retry-After, uncertain-write quarantine, namespace ownership, and credential fences. Do not add a database table for the timer. **Steps to reproduce** Configure a Discord connection and let command registration settle. In the parent revision, repeated runtime reconciliation still invokes command recovery. This revision reconstructs command deadlines at startup and removes that call from runtime reconciliation. ## What Changed - Expose normalized deadlines from the existing registration store. Park indefinite retries and invalid or foreign-owned records. Signal before store-owned claims, receipts, and retry-result writes. - Discover eligible endpoints in bounded pages. Refresh only affected endpoint, connection, or company scopes after commits. Dispatch at most 25 due commands per pass with fair company rotation. - Wire configuration, credentials, provider lifecycle/failure paths, inbound activation, generic connection mutation/removal/health, access revocation, and company deletion. - Register the worker through the chat service and shared coordinator. Preserve direct foreground setup calls. Refresh an existing local Gateway through its current owner after command work. - Preserve dirty work during drain and concurrent changes, back off unresolved attempts, and join admitted provider work during shutdown. - Document producer coverage, retained deadlines, supported writers, verification failures, and remaining runtime/Cloud obligations in `doc/idle-discord-command-registration.md` and its dated audit. ## Verification Published head: `547fdf2139144e1e6484198278bf4bb0eade8794`. It normally integrates master at `f8563d25077b17681ab6ef5949f7b07415a58ede`, including landed health #17554 and company deletion #17561. Squash ancestry caused merge conflicts; resolution applied this slice's exact 26-file owned patch from its recorded parent to pinned master. Every other path matches master. Migration 0394 and the current lockfile are preserved. - **141 distinct targeted cases pass** on reconciled production source: 78 complete command-store, batching, coordinator and startup-timing cases; 8 real automatic Discord and held-transaction Slack cases; and 55 complete startup/export and company-deletion cases. The 1,581 other chat integration cases were deselected. - Server typecheck and build pass. The company-deletion fixture self-migrates an initially empty isolated database. The two Discord fixtures use separate migrated clones; this is not a fresh-schema claim for those fixtures. Signal-listener warnings remain recorded without assertion failures. - The parent integration preserves health and command notifications at shared producer sites. It changes no provider behavior, schema or coordinator contract. Prior producer, backlog, drain/resume, malformed-hint, transaction, namespace, shutdown and retry regressions remain in the complete command suite. - [Landing compatibility acceptance](https://github.com/paperclipai/paperclip/blob/547fdf2139144e1e6484198278bf4bb0eade8794/doc/idle-discord-command-registration.md#acceptance-after-the-company-deletion-parent-landed-october-27) records current scope and the earlier failures. Older full-matrix or combined-stack runs apply only to their stated revisions. - Fresh exact-head Greptile, Ponytail if present and all CI are required. No full local repository suite, live provider, Cloud alarm, host suspension or savings claim is made. ## Risks - Discord still has real five-minute verification and failure-retry obligations. This does not prove host sleep or external alarm coverage. - Runtime discovery, receipt-to-runtime projection, Gateway lease renewal and persistent sockets remain separate. The remaining runtime poll can still read command receipts; it no longer invokes the command protocol. - Process-local signals cover integrated writers. Independent SQL writers and other replicas require an explicit wake contract. Existing authorization and durable ownership checks remain authoritative. - Refreshes coalesce with a 30-second minimum spacing. Saved work is never discarded because a call returned without progress. - No schema migration, new table, workflow or lockfile change is introduced by this slice. Landed parent repairs are retained. The receiver child must receive this integration before landing. ## Model Used OpenAI Codex, GPT-6 family, with repository tools, code execution, and reasoning. The exact serving version and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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> |
||
|
|
94a780286f |
fix(server): schedule tool health from committed changes and deadlines (#17554)
## Thinking Path > - Paperclip manages AI-agent work and its connected tools. > - Idle hosted instances need their database and network activity to stop. > - The maintenance tick queries tool connections even when no health check is due. > - Existing connection rows already contain eligibility and the last health observation. > - This pull request reconstructs health deadlines and refreshes them after committed changes. > - The shared coordinator preserves retries, drain, and shutdown without another private timer. ## Linked Issues or Issue Description **What happened?** The aggregate maintenance tick scans connection health every 30 seconds. Empty instances and connections with fresh health observations still cause SQL activity. **Expected behavior** No eligible connection means no recurring health SQL. Eligible connections retain the existing 15-minute proactive check. Configuration changes and health observations update the schedule after commit. **Steps to reproduce** Start a server with heartbeat scheduling enabled and no tool connections. Let startup finish and observe two maintenance ticks. The old code repeats the health inventory query. The new startup regression verifies that those ticks do not invoke the health inventory. **Paperclip version or commit** This branch includes merged parent #17518 and master `96727b3cfefb61f85ffe1fbc29a9b6dd6837efe8`. The 47 changed paths belong to the single tool-connection health duty. No database file differs from master. Related: #14638 covers runtime-auth exclusions. #15448, #15325, and #11910 concern MCP failure classification. This PR preserves those provider policies and does not replace their work. ## What Changed - Keep the GitHub error-projection unit fixture at the health-write boundary and verify the real transaction path in the PostgreSQL health-worker suite. - Add a health schedule owned by tool access. Read lean eligibility fields and saved observation timestamps. - Register health work with the existing coordinator. Refresh only dirty connection/application/company scopes using bounded inventory pages, check due connections in fair company batches, continue concrete due backlog after one second, and retain failures with backoff. - Notify before supported eligibility and observation writes in their owning transactions. Cover API/gallery setup, OAuth, catalog/gateway observations, email, voice, access removal, deletion, and settings. - Commit connection creation with grant, binding, and runtime-slot SQL before its wake. Keep provider calls outside the new transactions. - Keep provider-to-transport mapping in the chat catalog. SDK-only chat changes do not wake health work. - Replace aggregate health scans, retain the public manual sweep, and document the producer audit and remaining sleep limits. - Keep metadata-only example and Smoke Lab installs scoped. Lock and re-read application type before publishing a real eligibility change. - Keep failed inventory reads on their own retry deadline while healthy due batches continue. - Apply fixture migrations before using external disposable databases in all six producer suites. ## Verification Published head: `8c1d293d1ae2b7db753ab20f5a2a2edec1fb0a62`. Fresh CI and reviews are required for this exact head. - **623 distinct targeted cases pass.** The final four complete health, fair-batching, GitHub health recovery, and startup suites pass 80 cases after the retry fix. Five complete producer suites pass 543 cases: tool access 469, access 18, email 45, GitHub events four, and Smoke Lab seven. The earlier 26 health cases are part of this total, not additional cases. - The six producer suites first passed against separate, initially empty PostgreSQL 17 databases at `acbf262843`. They apply their own migrations. The subsequent repair changes only the health worker and its regression; its complete final consumer suites pass on that integrated parent. Server typecheck and build pass with the final repair. - **Installer amplification:** five real installs with 205 unrelated connections reproduced 1,035 example rows and 1,045 Smoke Lab rows. Repeated metadata installs now load only changed fixture connections. The same cases restore an excluded application through each installer and require all 205 unrelated IDs to re-enter the schedule. - **Concurrent eligibility:** a real PostgreSQL lock-wait case requires the installer to notify after a concurrent type change. A mutation that retains the lock but uses the old lookup fails the settled-hint assertion; original source was restored byte for byte. - **Retry isolation:** the failing baseline read one unavailable company three times while another company's 60 due checks drained. Final tests require one initial read, at least 30 seconds between failed reads, prompt healthy progress, eventual recovery, and SQL quiet after settlement. - Real-service producer coverage includes AgentMail activation/pause, GitHub installation changes, and member access removal. Lifecycle coverage includes outer commit/rollback, startup reconstruction, drain/resume, failure, and shutdown. - Failure history and exact evidence scope: [health acceptance](https://github.com/paperclipai/paperclip/blob/8c1d293d1ae2b7db753ab20f5a2a2edec1fb0a62/doc/idle-tool-connection-health.md#acceptance-follow-up-after-the-plugin-parent-merged-october-27), [producer audit](https://github.com/paperclipai/paperclip/blob/8c1d293d1ae2b7db753ab20f5a2a2edec1fb0a62/doc/plans/2026-10-24-tool-connection-health-sleep-audit.md). Prior remote failures and earlier 706-case evidence remain historical. Startup tests emitted listener-count warnings; all assertions passed. No full local repository-suite, deployed sleep, fleet savings, or live provider qualification claim is made. ## Risks - Supported live writers must use the transaction signals. Independent SQL writers and other replicas need their own wake integration. - Configured eligible connections still have a real proactive health obligation. This does not prove Cloud alarm coverage or host/database suspension. - Existing manual probes and catalog operations can overlap. This migration does not introduce a credential-version CAS or change provider failure policy. - Voice remains eligible under the previous health policy. Its generic probe can still report an unsupported transport; changing that behavior is separate work. - No database migration, new table, workflow, or lockfile change. This PR includes its merged parent and current inspected master; later stack PRs and all current-head acceptance gates remain separate. ## Model Used OpenAI Codex, GPT-6 family, with repository tools, code execution, and reasoning. The exact serving version and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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> |
||
|
|
13709b4c7a |
feat(connections): let agents configure connections within delegated authority (#17737)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Connections provide governed tools, chat channels, model accounts,
and gateways.
> - Several management routes require a human board actor even when an
agent has the required grant.
> - Default agents must configure these resources within the responsible
user's authority.
> - This pull request adds a shared authorization path to the existing
REST and native API surface.
> - Human authentication, execution approvals, and local host boundaries
remain enforced.
> - The benefit is that a standard agent can complete authorized setup
with a bounded human handoff.
## Linked Issues or Issue Description
**Subsystem affected**
Server authorization, connection services, shared contracts, native API
discovery, database schema.
**Problem or motivation**
Connection administration is available in the web app but often
unavailable to agents. Agent grants, responsible-user authority,
credential ownership, and actor attribution need separate checks.
Opening gateway-token creation also requires preserving the issuing
agent's delegated authority during token use.
**Proposed solution**
Use the existing authorization evaluator for every connection family.
Enforce current responsible-user authority, effective trust, grant
scope, resource visibility, and target-agent access. Keep existing agent
grants unchanged. Expose authorized configuration through default
`search_api` and `call_api`. Save human authentication steps and let
agents continue after completion.
**Roadmap alignment**
This change completes the API access path for the existing Connected
Apps, Personal & Shared AI Accounts, and governed MCP Gateway
capabilities in `ROADMAP.md`. It follows the maintainer's requested
design. Related work: #11899 enforces connection execution access and
creator/manager rules; this PR extends agent management across
connection families. It does not replace that execution-policy work.
## What Changed
- Add shared connection management context and mandatory
responsible-user, trust, scope, and target checks.
- Allow authorized agents to configure tool, chat/email, GitHub/Slack,
AI, profile, and gateway resources through existing routes.
- Preserve human credential ownership and record the actual agent,
responsible user, and run or key in audit data.
- Preserve saved browser authentication handoffs and callback session
checks.
- Bind agent-issued durable gateway tokens to their responsible user and
recheck delegated authority at use.
- Add explicit REST transport and management capability metadata,
built-in guidance, and sensitive-response handling.
- Intersect caller and endpoint-agent Slack test/invitation policies,
including independent and shared rates. Require the addressed human’s
current endpoint identity link before completing identity handoffs.
- Add production-authenticated integration scenarios. Companion #17739
contains the saved setup UI (including the required human
import/rotation step), product and permission documentation,
catalog/Vercel credential and callback ownership, and operation maps to
keep each review below 100 files. Both PRs must ship together; merge
this implementation first, then its companion.
## Verification
- Current implementation head:
`2ecd6451d0d0c8d82121a4e3fa4ce94c5befbbd6`, including master
`ea727dc3c2`, 99 files. The latest follow-up fixes the two valid
findings from the preceding f9 review. Exact-head Greptile has completed
at5/5 with no findings and Superagent passed. Full exact-head Linux CI
workflow40446606056 completed SUCCESS; only the queued external
Paperclip Review remains pending; earlier Linux passes do not qualify
this successor.
- Latest preserved-stack verification passed **2,165 tests** in fresh
PostgreSQL: **70 actual-auth scenarios**, 27 OpenAPI contracts, 2,022
native API tests and 46 saved GitHub wizard cases. **141 existing
gateway/policy acceptance tests** also passed. Workspace
typecheck/build, maps and token gates passed. The first workspace
typecheck was blocked by sandbox tsx IPC permissions; its authorized
rerun passed. This is focused local evidence; the full Linux CI matrix
is still required.
- Issuer/target gateway policy regressions were red before the fix. Both
decisions now intersect, including Block/Ask first/rates, same
credential identity and current token/user/agent authority after
approval. Invocations retain their token and actual requesting agent;
deleted tokens fail closed. Thirteen actual-auth cases cover revocation,
narrowed scope, approvals, shared rates and board compatibility.
Intermediate missing-token attribution, review-context and
implicit-session actor failures remain in the qualification record; all
final cases pass.
- Activity pagination now retains a bounded cursor across private-only
windows. The actual-JWT regression reaches three older readable events
after 27 private ones without exposing private details. A native
device-login regression was red for plaintext receipts; local check and
test-call results now use existing protected-response handling. The
passing actual-auth case proves encrypted persistence, exact replay,
redacted history and no response asset.
- Previous-head `5b55195593` Linux CI initially failed e2e shard 4/8 in
the existing connection-intent continuation test: periodic recovery
queued a repair at 01:21:47, the scripted journey completed the task at
01:21:48, and the extra queued run was cancelled at 01:21:49 because the
task was terminal. The assertion selected that latest cancelled run.
GitHub refused the first attempt while the workflow was nonterminal.
After completion, the single evidence-supported failed-job rerun was
accepted as **attempt 2** on the same head (workflow 40431202466). The
failed shard and final E2E aggregate passed on attempt 2, and the
complete Linux workflow for that head is successful. The original
failure remains part of qualification. No additional unchanged-code
rerun will be used for this failure.
- Companion CI also has an unchanged login-cleanup idleness timeout,
retained in its qualification record. That same 16-case suite passed in
this parent Linux run and a fresh local database. Both preceding
workflows passed after their single failed-job reruns as attempt 2; the
original failures remain recorded. No additional unchanged-code rerun
was used.
- Migration `0380_broken_aqueduct.sql` was regenerated through the
repository workflow after master took 0379 for project Git
authorization. It adds the responsible-user column with `IF NOT EXISTS`,
preserves upstream migrations, and satisfies snapshot retention and
migration safety checks.
- Upstream published Copilot v62 and v63 identities remain byte-for-byte
unchanged. The combined guidance is now v64, digest
`sha256:22e31f95ef972bcead98a4a707c9f33433558fd111e390e027a2bbb4346e112a`.
The normal shared TypeScript/Rust identity check and **61 Copilot
installation tests passed**. The old source-identity assertion first
failed against unchanged published v63; regenerating a new v64 preserves
the published release.
- Workspace `pnpm -r typecheck` and `pnpm build`, map validation, and UI
token gates passed on the final combined stack after the upstream merge.
Node 24.22.1 / pnpm 9.15.4 were used.
- **Earlier 82 API/OpenAPI tests passed** in fresh PostgreSQL 18: 55
assembled-server scenarios and 27 contracts. They use real persistent
agent keys, run JWTs, human sessions, production defaults, and
deterministic provider fixtures. No actor injection establishes access.
- The new email regression was red before per-account scope filtering.
The Arcade regression was red before human ownership and inventory-key
fixes; it also verifies actual-agent audit identity and a human-session
inventory read. The activity regression measured **200 authorization
checks before the fix and one afterward** for the same one-item page.
- **82 GitHub UI tests passed**, including all three new
failed-replacement regressions that were red before their fix. The UI
preserves an earlier copy only after confirming its committed
generation. Changed or unreadable results block copying and reconnecting
until reconciled. Human-only secret responses now include their
nonsecret committed generation.
- Private test status now rechecks the originating principal and linked
task, including mandatory agent/responsible-user privacy. Cross-agent
tests require the full caller tool access decision and the same
credential identity, regardless of auth label; caller and target
policies/approvals and rate limits apply before execution and after
human approval. A profile-only precondition was found to reject valid
allow-policy and scoped-grant access and has been removed. Both
permitted-access cases and a no-auth-label identity regression were red
before the correction; caller-specific Block still prevents provider
execution. The private-status regression was also red before its fix.
- The tool-activity regression measured 100 capability decisions and 102
run captures on a 100-event page before the fix. It now uses two task
decisions and at most two captures while retaining the same 50 visible
events, private-event filtering, and 403 after audit-grant revocation.
The regression was red before request-context reuse and task-decision
sharing; final server typecheck/build also pass.
- Generic chat configure/reconnect now hands agent-supplied verification
credentials to the addressed human before provider work or vault
changes. Actual key/JWT regressions were red for Slack signing-key
replacement and generic channel secret-reference rebinding. They now
prove unchanged refs and vaulted signing value, human setup, permitted
agent bot-token repair, and governed test messages. All 82 API/OpenAPI
cases pass in fresh PostgreSQL. Eight native receipt protections and
final server typecheck/build also pass.
- The preceding review found that old healthy state could retire a
credential-entry card before a human changed anything. The actual-JWT
regression was red. Saved field generations now change only with
protected values and commit with refs plus a verification fence; retries
retain the baseline. Old health, bot-token repair and unchanged entry
stay pending. New signing verification and current authority permit
continuation. A separate red race proved that user revocation during
provider authentication could return 403 after refs changed; authority
is now checked before persistence and inside the credential transaction.
The final 82 API/OpenAPI cases, four neighboring real-database
Slack/GitHub lifecycle cases, and final server typecheck/build pass.
- A preceding full run crossed a rate-window boundary. Database rows
prove one consumed slot at 23:35 and another at 23:36 for the same
policy/bucket. Only Date is frozen in the rate test cases; transport and
asynchronous timers remain real. Production rate behavior is unchanged,
and the final full run passes. An intermediate fixture failure that
overwrote hidden generation metadata with an API projection is retained
in the qualification record.
- Linux CI on an earlier head found two rate-admission assertions that
omitted the newly persisted bucket key. The failures were reproduced
locally; both assertions now verify the exact actor/tool bucket and all
49 policy-service tests pass. The companion qualification record retains
the initial and intermediate failures. Catalog creator attribution is
preserved in the companion to keep this implementation review at 99
files.
- The latest review reproduced three regressions before repair: complete
human replacements failed on unavailable old signing secrets, fresh
GitHub links incorrectly selected reconnect, and different
credential-entry requests shared an idempotency key. Each old protected
ref now has a narrow known-unavailable fallback; unexpected resolver
failures and company/scope violations still abort. Fresh imports keep
their credential form, configured endpoints keep reconnect, and
canonical field sets/completion modes distinguish handoffs while
matching retries retain their baseline. All 55 actual-auth scenarios and
27 separately run OpenAPI contracts pass, as do server typecheck/build.
Companion #17739 also passes all 41 wizard tests including actual
fresh-form submission, UI typecheck, maps and token gates. Earlier red
results and a mistyped OpenAPI filename are retained in qualification.
- The configured GitHub handoff regression was red in the
browser-component tests and actual-auth link/persistence tests. Saved
links now name requested fields and all/any completion mode; the
companion form submits those supplied fields through reconnect and
retains other saved credentials. Webhook/client-secret reconnect remains
human-only; first-setup secret restrictions remain. All 46 wizard tests
pass, including combined modes and legacy links. A duplicate review
referenced the older companion bf760912; the current form is already
fixed, linked in the reply, and its thread is resolved.
- Linux CI on
|
||
|
|
f0877a9c7c |
fix: recover native work and requalify saved computers (#17724)
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/32/changes/paperclip/32 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip manages AI agents and preserves their work after an interruption. > - Native Stop must confirm termination and save the workspace. > - Task and run views must show the current recovery receipt. > - A new external reply can arrive while that cleanup is pending. > - The reply must return to its original chat owner after cleanup. > - A successful fresh retry also becomes the task’s bound workspace for its next ordinary turn. > - Managed computer updates can invalidate a saved snapshot qualification. > - This pull request fixes those instructions, acknowledgements, handoffs and the existing native-agent Test path. > - The operator can continue with new input while the stopped turn remains preserved. ## Linked Issues or Issue Description **What happened?** Stopped native runs could keep the initial workspace-repair instruction after files were recovered. Native Stop could also leave the shared cancellation state at requested after remote termination was confirmed. A new GitHub reply saved during cleanup could then remain queued because cleanup did not ask its original inbound owner to reconsider the receipt. After a managed snapshot update, an existing native agent could also need qualification while the generic environment Test required instance-admin access. **Expected behavior** Show the current saved-work state. Acknowledge Stop only after exact termination proof. Let an authorized operator use the existing saved-agent Run test to qualify its current computer. After cleanup, recheck the saved reply's current authority and admit it once as new input. Preserve the stopped run and uncertain external effects. **Steps to reproduce** 1. Stop an active native turn before it returns a semantic result. 2. Send a new authorized external reply while cleanup is pending. 3. Let workspace recovery and provider cleanup finish. Inspect the run instruction, Stop acknowledgement and queued reply. Related work: #17594 preserves native processes through controller outages. #17401 addresses a separate bootstrap failure. This pull request does not replace those fixes. ## What Changed - Use the exact run's workspace recovery receipt for task and run guidance, including the Activity ledger. - Retire an obsolete exact-session notice through the existing bounded reconciler. Preserve the separate no-replay hold. - Write the shared native Stop acknowledgement only after the audited Stop intent and every exact remote lease receipt match. - Delegate saved external input to the live inbound owner. Recheck its source, actor, endpoint, principal and conversation generation. Promote the same receipt in the transaction that creates its new run. - Use that owner from the cleanup callback and existing stranded-queue catch-up after a lost callback or restart. A denied source cannot abort other items. - Reuse the current private task directory after a successful fresh retry. Re-read the company/task/workspace binding and validate the canonical stable or attempt namespace without recreating missing files; keep a later fresh retry separate. - Extend the existing agent-scoped qualification owner to native agents. The clean saved-agent Test qualifies its exact computer before runtime testing. Reuse a current proof; require a real probe and verified cleanup for a stale proof. Preserve draft tests and metadata-only external/pool previews. - Update execution semantics, capability maps and the recovery verification recipe. Add a production-page Storybook interaction for the normal native Test. ## Verification - **Red:** persisted recovery states returned stale instructions; an exact terminated native lease left shared Stop requested; the real GitHub subscribed-message fixture left zero successors after cleanup. The controlled baseline restored the previous production source, reproduced the failure, then restored the fixed bytes with matching SHA-256 hashes. - **Green:** 382 durable-chat, native-continuation, Stop and recovery tests pass. The real GitHub/PostgreSQL handoff matrix passes 12/12. It covers callback, application restart, callback/sweep race, valid input behind a deleted source, and denial for unknown stop, wrong allocation, paused endpoint, revoked principal, deleted or changed source, changed conversation generation and foreign scope. Repeated callbacks preserve one receipt, its actor, one successor and the unchanged stopped predecessor. - **Workspace continuation red/green:** the real PostgreSQL preparation flow created a fresh attempt and saved a marker, then rejected the next ordinary turn with the same binding mismatch observed in deployed use. The repaired preparation and filesystem suites pass 86/86: stable and attempt-root reuse, saved-marker preservation, a later clean sibling, changed current bindings, foreign company/task, closed workspace, traversal, missing path and symlink refusal. No task row reset or old-turn replay is used. - **Qualification red/green:** a native saved-agent qualification returned 422, and its normal Test skipped qualification. The repaired path passes 224 qualification/immutable-snapshot/environment tests and 176 UI/upgrade tests. It covers revoked authority, foreign or changed computer, current-proof reuse, failed/missing proof, draft settings, settings changed during the probe, and external/pool previews. On exact current source, the real local Harness / Runtime UI also qualified a newly saved disposable Computer with missing proof through actual Daytona, then completed the actual OpenCode/OpenRouter hello probe using `openrouter/deepseek/deepseek-v4.1-flash-1017`. Supported availability changed from Legacy-only to Paperclip Runner after proof persistence. Qualification and runtime leases both completed normal release/cleanup. The five prior task run IDs were unchanged; no task wake was created. This is macOS source-server/UI with real Linux Daytona and provider services, not a hosted UI claim. Test probes are archived by the existing inspection contract; release does not claim physical deletion. - Full workspace `pnpm -r typecheck`, `pnpm build`, token, map and diff checks pass at `f6450f4739fc8141815b8b7c35fde22a655c5f90`. The broad local `pnpm test:run` passed 24,899 tests and reported one existing nested-clone test timeout at 15 seconds. The complete failing file then passed 21/21 with the normal timeout; the exact case also passed on the pinned earlier baseline. The broad runner stopped before its later groups. No timeout or production workaround was added. Prior head `f6450f4` has 53 successful checks, two conditional Storybook skips and Greptile 5/5 with no inline threads. New workspace-reuse head `fcb13399ec70f92f71bd8250081251dca3f48962` passes workspace typecheck, full build, 86 scoped tests, maps and diff checks; Current-head CI has 53 successful checks and two conditional Storybook skips; Greptile is 5/5 with no inline findings. Deployed ordinary-turn reuse acceptance passed as described below. - **Hosted Stop proof:** the real GitHub issue-mention path used native OpenCode, `openrouter/deepseek/deepseek-v4.1-flash-1017`, Daytona and an exact low-trust task boundary. Normal UI Stop interrupted an active Bash call. Native and shared acknowledgements matched the exact lease. Automatic recovery saved exactly `STARTED\n` (8 bytes), with no finish marker. Reload showed Stopped and saved work recovered. Only the original cancelled run remained. Normal five-minute cleanup completed its exact provider-destruction transition. - **Limits:** the provider buffered command output, so the marker was read after recovery. The approved local provider credential could not inspect the hosted sandbox; its 404 is not deletion proof. Cleanup success comes from the exact lease's platform destruction transition. An earlier hosted stale instruction disappeared after rollout with unchanged raw run/action data; that historical cause remains unexplained. Original incident holds and publication receipts were untouched. - **Hosted handoff proof:** after QA deployed the combined candidate containing `46b2e99`, startup admitted the previously saved GitHub author reply without another comment, Retry or manual action. The new native run used the exact original wake receipt and saved comment. It completed once, committed an external-response wait, preserved the stopped predecessor, emptied the queue and left the task In review. The answer appeared in the original GitHub conversation. Workspace finalization and the exact lease's normal destruction transition succeeded. - **Hosted workspace proof:** on the combined candidate containing `fcb13399`, normal Retry preserved the original authenticated GitHub request and completed a fresh native attempt. One later ordinary same-head author reply then completed in the exact same workspace ID and attempt directory, with no Retry/fresh directive. Its input tree digest matched the Retry's finalized digest; final copyback preserved that digest. The persisted assessment row and all five prior run records were unchanged, exactly one new reply run completed, and the task returned to In review with an empty queue and no live run. Both exact leases completed normal verified destruction. This used real native OpenCode, the exact DeepSeek/OpenRouter model and Daytona, without workspace-row repair or a new remote marker. - **Publication limit:** the workspace audit compares the persisted assessment and run history. The ordinary reply exposed a separate destination-summary fallback that changed the visible GitHub summary despite the preserved assessment row. The publication track is repairing that behavior; this proof does not claim the visible summary was preserved. - **Deployment boundary:** current-head CI/review and hosted same-source Retry/ordinary-workspace reuse acceptance passed. The separate visible-summary publication failure remains owned by the publication track. Combined hosted UI confirmation of the native-agent Test path is coordinated separately. Actual missing-proof UI/provider qualification has passed in the isolated local instance above; prior hosted Stop and same-input handoff proof remains separate. No merge or deployment is performed by this pull request. ## Risks Recovery state and termination receipts must match the exact source run and allocation. Missing or foreign proof keeps the hold. The chat owner must retain the original receipt and actor and recheck current authority. Cleanup cannot grant authority or replay the stopped turn. Existing native ownership, Stop, budget, permission and uncertain-effect guards remain in place. ## Model Used OpenAI GPT-6.1 Sol (`gpt-6.1-sol`) through Codex, with reasoning, repository tools, source editing and test execution. The context-window size is not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (affected suites and isolated failing file pass; broad timeout retained above) - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green (current fcb has 53 successful checks/two conditional Storybook skips) - [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> |
||
|
|
338bf75761 |
fix(chat): admit task Retry after GitHub reconnect (#17733)
## Thinking Path > - Paperclip manages agents and their tasks. > - Task Retry must preserve saved input and enforce current access. > - A GitHub reconnect invalidates old runtime callbacks. > - Retry reused that old callback authority and rejected valid new intent. > - Retry also replayed an older failed request when a follow-up was already saved. > - This change admits a deliberate Retry under current authority and transfers saved input once. ## Linked Issues or Issue Description Refs #16965, #17053 and #17317. These repairs preserve work and contain old executors. This change fixes the subsequent chat admission boundary. A search found no overlapping open reconnect/admission fix. **What happened?** Ordinary task Retry returned `chat_failed_run_retry_not_authorized` after the same GitHub App reconnected. The endpoint was healthy, but the saved request still carried its old runtime generation. A newer queued follow-up also made Retry reject the older failed request instead of continuing the follow-up. No successor was admitted. HTTP qualification found two related defects. Concurrent clicks could omit the canonical chat action from a response. Signed-in board dispatch also passed an incomplete task resource to the permission resolver, which rejected a permitted mutation. **Expected behavior** A deliberate Retry checks current authority for the same App, sender, repository, conversation and task. It continues saved input once. A later reconnect, changed App, revoked access or changed source prevents dispatch. Old runtime callbacks remain invalid. **Steps to reproduce** 1. Admit a GitHub request and record a failed native run. 2. Save a follow-up while execution is blocked. 3. Reconnect the same GitHub App. 4. Click ordinary task Retry. 5. Before this change, admission returns 409. Without reconnect, the newer input alone also causes 409. **Paperclip version or commit** Baseline source: `41c42895fa862c586ff841f8c50200d93ffc83a4`. **Deployment mode** Source checkout on macOS. Regressions use real PostgreSQL transactions and the assembled chat, HTTP route and heartbeat admission services. Provider boundaries are simulated. No hosted recovery is claimed. ## What Changed - Record the admitting App identity for new GitHub deliveries. Historical deliveries can use their original working-comment binding. Reauthorize deliberate Retry under a pinned current generation and credential-reference fingerprint. - Select the complete saved-input queue from the failed run's actual conversation before replaying the older failed batch. Keep exact-run Retry bounded while ordinary task Retry supports larger queues. Transfer its receipts with the dispatch transaction. Recover the same ownership after restart or a lost response. Release unadmitted input after a definitive rejection. - Preserve canonical chat action IDs across concurrent clicks. Supply current task status and assignment fields to board mutation checks. - Keep exact-run Retry, stale webhook, containment, source integrity, publication, pause and budget checks. Update recovery contracts and verification recipes. ## Verification - Red: all three new PostgreSQL regressions failed on unchanged production code. Reconnect failed at chat authorization. Newer input failed at the obsolete-source guard. The combined case also failed. - Green: 61 selected chat integration cases passed. These include 27 new cases and 34 existing cases for containment, retained-source recovery, exact batches and source revocation. - A further red/green PostgreSQL regression reproduces the 51-message overflow identified during review. All 51 messages reach one successor, including a later Retry of that successor. A separate 52-message consumed-batch regression also passes. - A competing conversation retains its own deferred message. Distinct automatic policy contexts are checked independently; revoking only the later policy blocks the whole unadmitted batch. Batch validation still rejects a later message with a changed App binding or deleted source. A real PostgreSQL query capture reduced the 51-message preparation from 1,103 calls to fewer than 180. - All 16 durable task Retry tests passed. - The real HTTP route returns 202 and admits one queued successor for concurrent deliveries. Fault injection covers rollback during input handoff, response loss after dispatch commit, and permission loss when resuming an existing durable wait. A wait only adopts input after current admission succeeds; a one-shot settlement marker keeps status projection read-only. A new deliberate Retry works after another reconnect or a failed successor. - Current-App, repository, sender, source edit/delete, reassignment, endpoint pause and board-permission controls passed. Historical deliveries remain unchanged. - Final-head CI: 55 checks passed, three expected skips. The unchanged minute-bucket rate-limit assertion passed locally against PostgreSQL and on its one CI rerun. Greptile reviewed the final commit at 5/5 with no unresolved threads. - Workspace typecheck and full build passed. Map alignment, module boundaries, UI token gates and `git diff --check` passed. - Hosted task recovery and a live provider turn remain unverified. The local tests hold agent capacity to inspect admission without starting a model or publishing a GitHub response. ## Risks - A deliberate GitHub Retry can admit old saved input under current connection authority. It requires the same App binding and current access. It pins that admission; it does not rewrite the historical delivery or make stale callbacks valid. - The durable chat queue has an optional admission callback. It transfers input only when the transaction contains a valid queued execution or saved wait. Other chat consumers have no callback and retain their behavior. - No migration, Cloud dependency, deployment, configuration change or workspace cleanup is included. ## Model Used OpenAI GPT-6 through Codex, with reasoning, source inspection, code execution and GitHub tools. The exact serving variant and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
7ae81c9fa7 |
fix(slack): support rich questions and complete review delivery (#17255)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Questions and review decisions must work in the conversation where a task started. > - Slack omitted question context and did not publish several review kinds. > - Some answers saved in Paperclip also lost their authorized continuation or their final Slack reply. > - A settled card and a successful run did not prove that the user received the result. > - This pull request preserves complete questions and follows the existing answer and delivery receipts through continuation. > - Users can read the request, submit an authorized decision, and receive the resumed task's result in the same conversation. ## Linked Issues or Issue Description Refs #17045 and #17218. **What happened?** Slack question cards could omit instructions and editable starting text. Checkbox reviews, item verdicts, task suggestions, and connection requests had no publication path. Complex question answers submitted in Paperclip could fail continuation authorization. Several review continuations completed without delivering their result to Slack. **Expected behavior** Show the actual question and context. Use native Slack controls when they preserve the form contract. Otherwise provide an explicit Paperclip review link. Persist one authorized response, resume through the existing delivery path, settle the card, and deliver the useful result to its originating conversation. **Steps to reproduce** 1. Start a task in Slack and ask a text or choice question with instructions and help text. 2. Submit native text and choice responses, then submit a complex form through Paperclip. 3. Accept a checklist, submit item decisions, select suggested tasks, or decline a connection request. 4. Inspect the saved answer, continuation run, original Slack card, and final Slack reply independently. ## What Changed - Preserve full prompts, context, descriptions, recommendations, help, and editable starting text. Use direct buttons for short choices, inline searchable selects for longer lists, and native checkboxes with explicit submission for multiple choices. - Add native custom-answer and validated-text modals, ordinary confirmation buttons, checklist decisions, per-item verdicts with reasons, suggested-task creation/dismissal, and connection decline. Keep governed approvals, permission grants, and forms that cannot be represented faithfully in the full Paperclip review surface. - Keep Slack-specific canonical-validation feedback in its owning platform module. Shared callbacks delegate without interpreting provider presentation. - Reuse the existing canonical interaction transactions, callback receipts, publication queue, and continuation delivery. Share ordinary confirmation handling across Telegram and Slack. Recheck current authorization and commit response receipts atomically. - Settle cards with the saved answer and remove stale controls. Ignore passive Slack link callbacks so opening a task does not display a false answer error. - Validate exact multi-select receipt mappings during native continuation. Recover automation-origin connection replies from their published prompt after validating the durable connection receipt. - Keep oversized multi-select handoffs free of unused native tokens, and retain the complete Paperclip form for 101–128 choices plus Other. Make the original-conversation audience explicit before submitting a Slack modal. - Add rollback, provider serialization, callback, continuation, and negative authorization regressions. Update the connector playbook and feature/access maps. No React or application UI changes are included. - Add a durable Q01–Q11 qualification index and provider coverage matrix. Require distinct functional, good-experience, and best-available-control assessments; real unanswered/answering/settled evidence; saved results, continuation and navigation proof; and retained failures. Mark other providers unaudited rather than assuming Slack parity. ## Verification Candidate: `e0017d446b1016a38d65382366cd1408cce33039`. The eleven-core-format live Slack gallery is pinned to `c3d458b2a06b660448940fd8cf33c5906f0058d5`; subsequent boundary fixes and the sharing notice have automated verification, not new live screenshots. - Real Slack UI testing covered all 11 formats: text, closed choice, long single select, multiple choices, choices with a custom answer, pattern-validated text, confirmation, checklist, item verdicts, suggested tasks, and connection requests. Each has unanswered/answering/answered screenshots as applicable, an inspected saved result, one continuation, and an individual experience review in the local HTML gallery. - The dedicated private QA app/channel used signed callbacks to the local candidate. A separately approved password-protected, read-only preview proved connection-review, suggested-task review, and created-task navigation. Anonymous access, writes, and credential routes were denied. No OAuth grant was attempted. - Real testing exposed and repaired a multi-select continuation failure and a misleading error on link-button clicks. Failed attempts remain in the evidence. The final navigation replay opened the exact pending connection request and declined it in Slack without granting access. Suggested-task creation produced the selected child with the correct parent and description. - Final review-fix verification: **32 form tests**, **28 provider/form-rendering tests**, **30 publication tests**, and **171 native continuation/authorization tests** passed. Earlier **3 atomic-resolution rollback**, **9 targeted callback/publication/Telegram**, and **28 review-continuation** cases passed. The final Slack/Teams modal subset also passed. The automation-origin connection cases, 101/128 custom-choice cases, and oversized multi-select continuation reproduced before their fixes and passed afterward; failing logs remain retained. These counts describe relevant runs, not a reliability percentage. - CI on `b5885b85fd` exposed a test fixture that assumed every Slack modal block was an input; the new sharing notice correctly renders a non-input block. The fixture now selects input blocks safely. The exact signed-modal correction/one-continuation test passed locally, together with 14 Slack form/modal tests. The failing CI log and its specific cause remain recorded. - `pnpm -r typecheck` and `pnpm build` passed. Server typechecking was repeated after the final source changes. Map and module-boundary checks and `git diff --check` passed. - The full `pnpm test:run` was attempted and stopped after repeated embedded PostgreSQL semaphore exhaustion on this host. Its 1,395-test chat suite found two stale native-control assertions; both were corrected and re-tested in a focused run. Focused database suites used separate disposable databases on existing local PostgreSQL. The full suite is not claimed green; new-head CI must complete before merge. - Final-head CI passed on `e0017d446b1016a38d65382366cd1408cce33039`: all test/build jobs and required `ci / verify` and `ci / e2e` gates are green ([run](https://github.com/paperclipai/paperclip/actions/runs/40115430194)). Greptile and Ponytail both reviewed this exact head at 5/5, the security scan passed, and all review threads are resolved. - All three QA app callbacks were restored to staging. Both temporary tunnels and local proxies were closed. The local endpoint was archived and its local credential copies removed. The candidate app was stopped. Limits: provider execution used a deterministic Claude protocol fixture, not an LLM. This is local real-provider UX proof, not deployed staging or broader Codie/Claude qualification. The public preview intentionally blocked ancillary artifact routes, so its destination pages could show a partial-history warning. The complete permission-grant flow and every oversized/mixed-form branch were not driven manually. Earlier fixture, test, and provider failures remain recorded. ## Risks - New reply routes require durable origin proof. Incorrect receipt matching could lose a reply or route it incorrectly. Tests cover missing, forged, mismatched, and revoked authority. - Governed forms keep their Paperclip resolution checks. This change does not grant new approval authority to Slack. - Existing completed review results can become deliverable through the repaired publication path without another provider run. - No schema, lockfile, workflow, public task-status model, or runtime-instruction change is included. This branch is not deployed. ## Model Used OpenAI Codex, GPT-6 family, with code execution and tool use. The exact backend model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either linked existing issues or described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [x] I have run focused tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green on the new head - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups on the new head - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
a2d26a83fe |
fix(inbox): keep automatic work out of Mine by default
Keep channel and routine attribution out of Mine unless the person participates directly, is assigned the task, or receives a current addressed request. Apply the same source rules to unread state, archives, and task notifications. Preserve direct comments and current human action requests. Restore the two expressions damaged by redaction during the earlier master merge. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
9966f31bee |
fix(chat): keep permission failures scoped to the rejected operation (#16847)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - External channels deliver agent replies through a durable publication queue. > - A provider can reject one operation while other operations remain allowed. > - The shared error classifier treated generic 403 and permission errors as failures of the whole connection. > - Failure handlers then changed the user's enabled setting and removed all assigned channel tools. > - This pull request limits permission failures to the rejected operation and preserves connection intent during authentication failures. > - Unrelated work can continue, while confirmed authentication failures still stop endpoint traffic. ## Linked Issues or Issue Description Refs #16137. Follows #16138, which distinguishes local authorization errors from provider errors. This change also narrows provider permission failures. Related #16806 handles a separate task-continuation tool-binding defect. A provider 403 or missing-scope response currently disables a connection that may still support other operations. The expected behavior is a visible operation failure with unrelated work preserved. Confirmed authentication failures must stop sends without changing the user's enabled setting. ## What Changed - Classify generic 403, adapter permission errors, and Slack missing-scope/no-permission responses as failed operations. - Preserve rate-limit retries, known destination quarantine, and confirmed authentication failures. - Preserve connection status and enabled intent when publication, provider-reply, or form-open authentication fails. The endpoint still enters attention and its runtime stops. - Add GitHub regressions for retained discovery and successful later publication after 403, and no further sends after 401. - Mark authentication health failed and fence persistent receiver startup, background reconciliation, and receiver callbacks. Keep signed GitHub lifecycle events available during an authentication stop. Verify Discord reconciliation and Photon restart preserve the stop, while transient Discord disconnects still recover. - Update provider, publication, and modal regression expectations and the execution contract and verification maps. ## Verification - Red: five new classifier cases returned endpoint attention before the repair. The signed-installation-removal regression also reproduced a blocked lifecycle event after a 401 before narrowing the receiver guard. - Green: all 35 classifier tests pass. - Green: 19 PostgreSQL-backed cases pass through the production channel services, including GitHub discovery/publication, Slack provider replies and question modals, Telegram credential/destination failures, rate limiting, and Discord/Photon authentication-stop persistence. - Map structural checks and `git diff --check` pass. - `pnpm -r typecheck` and `pnpm build` pass. All CI gates are green on `7e379bcd98aa8363e42efe7f8a4b2589b7111ae6`; Greptile is 5/5 on that exact commit with no unresolved findings. - The monolithic local `pnpm test:run` was started, then stopped after its revision passed the full CI matrix and was superseded by the authentication-stop repair. Final full-suite verification passed in CI shards; all 19 final local provider regressions pass. - The tests run from this source checkout on macOS arm64 with isolated PostgreSQL and controlled provider failures. They do not prove live GitHub recovery or deployment. No live connection settings were changed. ## Risks - Permission failures now leave unrelated work available. The rejected operation remains failed and is not automatically replayed. Provider authorization still applies to every request. - Keeping a connection enabled must not bypass an authentication stop. GitHub verifies blocked tool discovery and later sends; Discord and Photon verify background reconciliation and restart cannot clear the stop. Failed connection health is an execution gate while the endpoint requires attention. - Explicit disable, disconnect, signed installation revocation, and existing destination-specific denial handling remain unchanged. No migration or API schema change is required. - Previously disabled connections are not automatically re-enabled because an upgrade cannot safely infer the user's intent. ## Model Used - OpenAI Codex, GPT-6 family. The runtime does not expose the exact deployment model ID or context-window size. Used reasoning, shell tools, repository edits, and test execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
becdc3b08e |
perf(slack): remove delays before mention acknowledgements (#16491)
Slack mentions now start eyes reactions after the authorized task/comment commits, independently of attachments, subscription and scheduler acceptance. Omit unused optional URL-preview polling while retaining message text, links and files. Keep receipt failures and missing-file warnings independent, including terminal cleanup of older multi-line diagnostics. Verified with full current-head CI and E2E, Superagent and legacy security checks, Apex 5/5 with no unresolved findings, 19 selected real-PostgreSQL receipt/authorization/cleanup cases, and full frozen-source typecheck/build. The first CI attempt's unchanged Cursor probe timeout is retained in the PR; the one failed-only retry passed under unchanged deadlines. Live Slack latency still requires deployed acceptance. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
09a2f0b7b0 |
refactor(server): isolate provider message admission and runtime policies (#16289)
## Thinking Path > - Paperclip helps people manage AI agents for work. > - Chat channels turn external messages into shared task workflows. > - The main service still contains some provider decisions. > - These decisions belong with the existing channel modules. > - This pull request isolates provider message-admission and runtime policies. > - Shared authorization, persistence, and runtime ownership keep their current order. ## Linked Issues or Issue Description Refs: #16235. Stack part 3/3. Base: `master`. #16276 and #16283 are merged. **What existing behavior does this improve?** Provider ownership and readability in the chat channel service. **Current behavior** The entry point combines shared workflows with provider decisions. **Proposed behavior** Provider modules own their decisions. Shared modules own product state and authorization. **Reason and benefit** Maintainers can find provider behavior in its channel folder. **Breaking changes** None intended. Public service methods and durable data shapes stay compatible. ## What Changed - Move Discord SDK admission and its barrier to the Discord message module. - Move Photon live-message eviction and startup recovery policy to its runtime callbacks module. - Move Slack mention eligibility and Teams setup-channel eligibility to their message modules. - Keep Photon deferred ingress and Speko conversation policy with their provider modules. - Keep ordered SDK message batching in a shared runtime module with a live per-message ingress callback. - Keep receiver leases, cache lifetime, startup failure cleanup, authorization locks, and transaction ownership shared. - Reduce `chat-channels.ts` from 3,570 to 3,548 lines. ## Verification - The same 46 runtime/admission integration cases and all 18 Photon channel cases passed before and after in the owned Linux container. - The existing first-channel Teams orphan-admission case passed before and after moving its eligibility predicate. - The same 94 SDK adapter and lifecycle-normalization tests passed locally. - Server typecheck and module-boundary checks passed. - Token comparison confirms ordered SDK batching and every processor argument, plus Photon invalidation and its live runtime lookup. - The shared factory creates no cache or worker. It reads the ingress policy for each message and awaits processing in order. - The extraction rebased without conflicts onto master after #16276 and #16283 merged. Git range-diff reports the same patch. Final head `7b63b569e2a0dbcc959310f565f77f367fa64aa0` has the same patch by range-diff. The 94 SDK/lifecycle tests, server typecheck, and boundary check passed on the final head. All CI gates pass on that exact head. Greptile reviewed it at 5/5 with no inline findings or unresolved review threads. - One Runner CI test failed its original short timing window. The unchanged test passed earlier-head CI and local reproduction. The single failed-job retry passed. - Cumulative `pnpm -r typecheck` and `pnpm build` passed. All 1,321 channel integration cases passed. The normal UI, CLI, database, adapter, plugin, and serialized API test selections ran. - The first Linux `pnpm test:run` returned 1. Original-source runs reproduced the local failures. Container-only repairs supplied missing tools, process reaping, and sufficient Node heap. The existing mocked-fetch CLI telemetry fixture passed with the image opt-out flag overridden only for that fixture. - One local venue limitation remains: adapter-utils T24 fails unchanged on both original and final source in the Linux container. Its entire 56-case suite passes before and after on the host. All other failed or aborted suites passed in repaired reruns. No test assertion or timeout changed. - These fixtures prove application integration. They do not prove live provider execution. ## Risks - A captured option value or changed callback order could affect deferred ingress or stale-runtime handling. - The ingress callback and runtime getter remain live. Core maps and receiver lease operations keep one owner. - No schema migration or public API change is included. ## Model Used OpenAI GPT-6, running in Codex with reasoning, tool use, and code execution. The exact deployment identifier and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
7df55f3dcc |
refactor(server): isolate provider webhook lifecycle decisions (#16283)
## Thinking Path > - Paperclip helps people manage AI agents for work. > - Chat channels turn external messages into shared task workflows. > - The main service still contains some provider decisions. > - These decisions belong with the existing channel modules. > - This pull request moves webhook recovery and payload-scope decisions to their provider modules. > - Shared authorization, persistence, and runtime ownership keep their current order. ## Linked Issues or Issue Description Refs: #16235. Stack part 2/3. Base: `master`. #16276 is merged. **What existing behavior does this improve?** Provider ownership and readability in the chat channel service. **Current behavior** The entry point combines shared workflows with provider decisions. **Proposed behavior** Provider modules own their decisions. Shared modules own product state and authorization. **Reason and benefit** Maintainers can find provider behavior in its channel folder. **Breaking changes** None intended. Public service methods and durable data shapes stay compatible. ## What Changed - Move GitHub revoked-installation recovery classification to `github/webhook-scope.ts`. - Move Teams payload-scope validation to its message module. - Record normalized GitHub, Telegram, and Teams lifecycle events through one shared durable call. - Keep Slack callback ordering and persistence failures outside parser catches. - Reduce `chat-channels.ts` from 3,598 to 3,570 lines. ## Verification - The same 86 selected webhook/lifecycle integration cases passed before and after in an owned Linux container. - The same 17 selected Telegram edit and Teams edit/delete/restore cases passed before and after in that container. - The same 94 SDK adapter and lifecycle-normalization tests passed locally before and after. - Server typecheck and module-boundary checks passed. - Token comparison confirms the shared recording payload and runtime fence, plus the Teams scope and parser inputs. - The host database baseline failed before assertions because System V shared-memory IDs were exhausted. No other PostgreSQL server or host setting was changed. Database verification used an isolated container under its unprivileged user. - The extraction rebased without conflicts after #16276 merged. Git range-diff reports the same patch. The 94 SDK/lifecycle tests and server typecheck passed on this base. All CI gates pass on rebased head `d835d7c3815c168226fa646aec6370b6a8ac94c1`. Greptile reviewed that exact head at 5/5, with no inline findings or unresolved review threads. - Cumulative `pnpm -r typecheck` and `pnpm build` passed. All 1,321 channel integration cases passed. The normal UI, CLI, database, adapter, plugin, and serialized API test selections ran. - The first Linux `pnpm test:run` returned 1. Original-source runs reproduced the local failures. Container-only repairs supplied missing tools, process reaping, and sufficient Node heap. The existing mocked-fetch CLI telemetry fixture passed with the image opt-out flag overridden only for that fixture. - One local venue limitation remains: adapter-utils T24 fails unchanged on both original and final source in the Linux container. Its entire 56-case suite passes before and after on the host. All other failed or aborted suites passed in repaired reruns. No test assertion or timeout changed. - These fixtures exercise application state and the service entry point. They do not prove live provider execution. ## Risks - A scope or ordering error could record an event for the wrong provider context. - The selected parser returns normalized data. The shared service keeps durable recording and runtime fencing. - No database migration or API change is included. ## Model Used OpenAI GPT-6, running in Codex with reasoning, tool use, and code execution. The exact deployment identifier and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
f16c0ad5c8 |
refactor(server): isolate chat conversation and control policies (#16276)
## Thinking Path > - Paperclip helps people manage AI agents for work. > - Chat channels turn external messages into shared task workflows. > - The main service still contains some provider decisions. > - These decisions belong with the existing channel modules. > - This pull request separates conversation binding and Telegram control policy. > - Shared authorization, persistence, and runtime ownership keep their current order. ## Linked Issues or Issue Description Refs: #16235. Stack part 1/3. Base: `master`. **What existing behavior does this improve?** Provider ownership and readability in the chat channel service. **Current behavior** The entry point combines shared workflows with provider decisions. **Proposed behavior** Provider modules own their decisions. Shared modules own product state and authorization. **Reason and benefit** Maintainers can find provider behavior in its channel folder. **Breaking changes** None intended. Public service methods and durable data shapes stay compatible. ## What Changed - Keep shared conversation lookup and completion in `inbound/conversation-binding.ts`. - Move Photon binding-completion policy to its messages module. - Move Telegram command classification, forum behavior, and chronology exemptions to its commands module. - Keep the original conversation generation separate from the retained task binding. - Reduce `chat-channels.ts` from 3,649 to 3,598 lines. ## Verification - The same 62 selected Telegram/Teams integration cases passed before and after extraction. - All 18 Photon channel integration cases passed before and after extraction in separate test processes. - The initial combined baseline command had a Photon database-startup hook timeout. No Photon assertion ran in that invocation. The unchanged Photon suite then passed in isolation with its existing timeouts. - Server typecheck and the module-boundary check passed. - A token comparison confirms the moved lookup, completion, and generation logic, after normalizing the explicit policy callbacks. - All current-head CI checks passed. Greptile reviewed this exact head at 5/5 with no findings. - Cumulative `pnpm -r typecheck` and `pnpm build` passed. All 1,321 channel integration cases passed. The normal UI, CLI, database, adapter, plugin, and serialized API test selections ran. - The first Linux `pnpm test:run` returned 1. Original-source runs reproduced the local failures. Container-only repairs supplied missing tools, process reaping, and sufficient Node heap. The existing mocked-fetch CLI telemetry fixture passed with the image opt-out flag overridden only for that fixture. - One local venue limitation remains: adapter-utils T24 fails unchanged on both original and final source in the Linux container. Its entire 56-case suite passes before and after on the host. All other failed or aborted suites passed in repaired reruns. No test assertion or timeout changed. - These fixtures exercise the assembled service and persisted state. They do not prove live third-party execution. ## Risks - Changing query order or losing the original generation could bind a message to the wrong task. - The workflow retains the original lookup result and all existing query and write conditions. - No schema migration or API change is included. ## Model Used OpenAI GPT-6, running in Codex with reasoning, tool use, and code execution. The exact deployment identifier and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
f69c6a8a35 |
fix(github): retry and recover review publication (#16284)
## Thinking Path
> - Paperclip manages agent work and its published results.
> - GitHub review bots publish task-bound assessments through governed
tools.
> - A review can survive a caller timeout because its publication intent
is durable.
> - A transient provider failure still returned a failed receipt before
recovery.
> - Gateway replay could return an empty cached result, and publication
retries had no dedicated scheduler deadline.
> - This pull request adds bounded retries, receipt recovery, and an
independent durable worker.
> - A temporary GitHub failure can recover without another review or
duplicate publication.
## Linked Issues or Issue Description
Refs #16275. That change increased the GitHub tool deadline. This change
repairs retry and recovery behavior.
**What happened?**
A one-off GitHub HTTP 503 or 429 left the caller with a failed
publication receipt. The saved retry did not have its own scheduler
worker. An identical gateway call after a timeout could return an empty
cached result instead of the saved publication receipt.
**Expected behavior**
Temporary failures should retry under current authority. Pending work
should resume at its saved deadline after restart. Exact retries should
return the current receipt. Lost responses must not create duplicate
comments, findings, or checks.
**Steps to reproduce**
1. Admit an advisory PR review request and begin its assessment.
2. Return HTTP 503 or 429 for the first summary-comment PATCH, then let
GitHub succeed.
3. Submit the assessment through the run-scoped tool gateway.
4. On master, the result says publication failed. With this change, the
same call returns the processed receipt and neutral check.
5. For receipt recovery, use a shorter caller deadline and repeat the
exact call after publication finishes.
**Paperclip version or commit**
Reproduced on master at `6cb6ac3b8e40cb90d734ba115a2f22f850ff9477`.
## What Changed
- Classify transient transport, server, and rate-limit failures. Honor
Retry-After and primary reset deadlines. Stop retries for permanent
permission and validation errors.
- Retry safe reads and installation-token issuance within a bounded call
window. Retry publication writes through the existing outbox and
provider receipt checks.
- Wait for up to three publication attempts within a 45-second retry
window. Keep the durable eight-failure cap and enforce saved deadlines
on explicit retries.
- Register an independent GitHub publication worker with
transaction-owned wake notifications, startup recovery, and per-PR lease
deadlines.
- Recover exact comment, progress, and assessment gateway calls from
their stored publication. Require the same company, agent, task, run,
connection, tool, arguments, and current policy. Clear stale timeout
errors after recovery. Approved exact retries read the current receipt
through the existing signed replay path; the worker retains the verified
approval for deferred writes and still rejects revocation.
- Add regression coverage and update the connector guide and
feature/access maps.
## Verification
- Red: both one-off HTTP 503 and 429 regressions failed on master with a
failed publication receipt.
- Green: the same tests passed after the change.
- GitHub review workflows: 133 covered against isolated PostgreSQL 18.
The final combined run passed 132 and hit one fifteen-second timeout
under concurrent build load. All three variants of that workflow passed
in isolation. The earlier combined run passed all 131 workflows before
the two approval regressions were added.
- Retry policy and delivery coordinator tests: 35 passed.
- Additional focused checks passed for the actual eight-failure cap,
exact-argument conflicts, policy revocation, and timeout receipt
recovery. The approved deferred-publication and revocation regressions
failed before the review repair and passed after it, with one approval
request preserved.
- `pnpm -r typecheck`: passed. `pnpm build`: passed. `node
scripts/check-maps.mjs`: passed.
- The broad local `pnpm test:run` path remains blocked by the host's
exhausted PostgreSQL shared-memory slots. The changed database-backed
workflows use an isolated Docker database instead. All Paperclip CI jobs
passed at
|
||
|
|
75189b8762 |
refactor(server): isolate channel runtime admission and maintenance (#16235)
## Thinking Path > - Paperclip helps people manage AI agents for work. > - Chat channels turn provider messages into shared task workflows. > - The main service still implements provider details beside common authorization and persistence. > - These details belong in the existing channel folders. > - This pull request moves Discord runtime command capture and root receipts, Speko runtime and authority, and GitHub maintenance scheduling behind explicit typed functions. > - The service keeps its shared workflow and selects the provider implementation directly. ## Linked Issues or Issue Description Refs: #16192. Stack part 5/5. Depends on #16233. Base: `master` (parent PR merged). **What existing behavior does this improve?** The ownership and readability of provider behavior in the chat channel service. **Current behavior** The service implements Discord runtime command capture and root receipts, Speko runtime and authority, and GitHub maintenance scheduling inline. **Proposed behavior** Channel modules own these details. The core calls their typed functions. Runtime and database effects retain their current order. **Reason and benefit** Maintainers can find channel behavior in its channel folder without following a generic provider framework. **Breaking changes** None intended. Public service entry points and durable data shapes stay compatible. ## What Changed - Extract Discord runtime command capture and root receipts, Speko runtime and authority, and GitHub maintenance scheduling into the existing channel folders. - Keep shared company scope, authorization, and transaction ownership in their current workflow. - Reduce `chat-channels.ts` from 3715 to 3649 lines. ## Verification - The same 167 selected chat-runtime cases and 87 voice ownership cases passed before and after extraction. Full workspace typecheck and build passed. Token parity checks passed for six moved control-flow blocks. - Server typecheck passed. - `node scripts/check-module-boundaries.mjs` passed. - Full workspace typecheck and build passed on the cumulative stack. All current-head CI gates passed. Greptile completed at 5/5 with no findings. - The full local `pnpm test:run` command exited with three database fixture-startup hook timeouts. It reported 19,529 passing tests and 250 skipped tests. No assertion failed. Its later test groups did not run because the driver stops on the first failing group. - The timed-out files were `environment-custom-images-service.test.ts`, `generic-mcp-connection.test.ts`, and `modules/wake-queue/adapters/postgres.test.ts`. All 166 tests in these files passed in isolation on both baseline `edcfcaf3f6` and stack head `faaca26d46`, with existing timeouts and assertions. The tests and database-startup helper are unchanged. - Provider fixtures prove application integration. They do not prove live third-party execution. ## Risks - Incorrect inputs or changed await order could affect provider handling and recovery. - Existing integration tests exercise the assembled service before and after extraction. - No database migration or API change is included. ## Model Used OpenAI GPT-6, running in Codex with reasoning, tool use, and code execution. The exact deployment identifier and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
c1994056f9 |
refactor(server): isolate channel registration and setup services (#16233)
## Thinking Path > - Paperclip helps people manage AI agents for work. > - Chat channels turn provider messages into shared task workflows. > - The main service still implements provider details beside common authorization and persistence. > - These details belong in the existing channel folders. > - This pull request moves Slack registration, account linking, test-message setup, GitHub setup progress, and Telegram webhook URL restrictions behind explicit typed functions. > - The service keeps its shared workflow and selects the provider implementation directly. ## Linked Issues or Issue Description Refs: #16192. Stack part 4/5. Depends on #16232. Base: `master` (parent PR merged). **What existing behavior does this improve?** The ownership and readability of provider behavior in the chat channel service. **Current behavior** The service implements Slack registration, account linking, test-message setup, GitHub setup progress, and Telegram webhook URL restrictions inline. **Proposed behavior** Channel modules own these details. The core calls their typed functions. Runtime and database effects retain their current order. **Reason and benefit** Maintainers can find channel behavior in its channel folder without following a generic provider framework. **Breaking changes** None intended. Public service entry points and durable data shapes stay compatible. ## What Changed - Extract Slack registration, account linking, test-message setup, GitHub setup progress, and Telegram webhook URL restrictions into the existing channel folders. - Keep shared company scope, authorization, and transaction ownership in their current workflow. - Reduce `chat-channels.ts` from 3813 to 3715 lines. ## Verification - The same 97 selected setup integration cases passed before and after extraction. The cases cover Slack installer linking and welcome eligibility, GitHub registration, and Telegram webhook restrictions. - Server typecheck passed. - `node scripts/check-module-boundaries.mjs` passed. - Full workspace typecheck and build passed on the cumulative stack. All current-head CI gates passed. Greptile completed at 5/5 with no findings. - The full local `pnpm test:run` command exited with three database fixture-startup hook timeouts. It reported 19,529 passing tests and 250 skipped tests. No assertion failed. Its later test groups did not run because the driver stops on the first failing group. - The timed-out files were `environment-custom-images-service.test.ts`, `generic-mcp-connection.test.ts`, and `modules/wake-queue/adapters/postgres.test.ts`. All 166 tests in these files passed in isolation on both baseline `edcfcaf3f6` and stack head `faaca26d46`, with existing timeouts and assertions. The tests and database-startup helper are unchanged. - Provider fixtures prove application integration. They do not prove live third-party execution. ## Risks - Incorrect inputs or changed await order could affect provider handling and recovery. - Existing integration tests exercise the assembled service before and after extraction. - No database migration or API change is included. ## Model Used OpenAI GPT-6, running in Codex with reasoning, tool use, and code execution. The exact deployment identifier and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
875943ac83 |
refactor(server): isolate provider webhook lifecycle processing (#16232)
## Thinking Path > - Paperclip helps people manage AI agents for work. > - Chat channels turn provider messages into shared task workflows. > - The main service still implements provider details beside common authorization and persistence. > - These details belong in the existing channel folders. > - This pull request moves GitHub webhook runtime deadlines and Slack lifecycle processing behind explicit typed functions. > - The service keeps its shared workflow and selects the provider implementation directly. ## Linked Issues or Issue Description Refs: #16192. Stack part 3/5. Depends on #16231. Base: `master` (parent PR merged). **What existing behavior does this improve?** The ownership and readability of provider behavior in the chat channel service. **Current behavior** The service implements GitHub webhook runtime deadlines and Slack lifecycle processing inline. **Proposed behavior** Channel modules own these details. The core calls their typed functions. Runtime and database effects retain their current order. **Reason and benefit** Maintainers can find channel behavior in its channel folder without following a generic provider framework. **Breaking changes** None intended. Public service entry points and durable data shapes stay compatible. ## What Changed - Extract GitHub webhook runtime deadlines and Slack lifecycle processing into the existing channel folders. - Keep shared company scope, authorization, and transaction ownership in their current workflow. - Reduce `chat-channels.ts` from 3906 to 3813 lines. ## Verification - The same 61 selected webhook/lifecycle integration cases passed before and after extraction. They cover cold GitHub runtime startup, signed ingress, installation recovery, Slack lifecycle effects, and Telegram/Teams edits. - Server typecheck passed. - `node scripts/check-module-boundaries.mjs` passed. - Full workspace typecheck and build passed on the cumulative stack. All current-head CI gates passed. Greptile completed at 5/5 with no findings. - The full local `pnpm test:run` command exited with three database fixture-startup hook timeouts. It reported 19,529 passing tests and 250 skipped tests. No assertion failed. Its later test groups did not run because the driver stops on the first failing group. - The timed-out files were `environment-custom-images-service.test.ts`, `generic-mcp-connection.test.ts`, and `modules/wake-queue/adapters/postgres.test.ts`. All 166 tests in these files passed in isolation on both baseline `edcfcaf3f6` and stack head `faaca26d46`, with existing timeouts and assertions. The tests and database-startup helper are unchanged. - Provider fixtures prove application integration. They do not prove live third-party execution. ## Risks - Incorrect inputs or changed await order could affect provider handling and recovery. - Existing integration tests exercise the assembled service before and after extraction. - No database migration or API change is included. ## Model Used OpenAI GPT-6, running in Codex with reasoning, tool use, and code execution. The exact deployment identifier and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
f6608f382f |
refactor(server): isolate GitHub task preparation and review containment (#16231)
## Thinking Path > - Paperclip helps people manage AI agents for work. > - Chat channels turn provider messages into shared task workflows. > - The main service still implements provider details beside common authorization and persistence. > - These details belong in the existing channel folders. > - This pull request moves GitHub task prompts, review provenance, and shared guest containment behind explicit typed functions. > - The service keeps its shared workflow and selects the provider implementation directly. ## Linked Issues or Issue Description Refs: #16192. Stack part 2/5. Depends on #16230. Base: `codex/chat-channel-inbound-policies`. **What existing behavior does this improve?** The ownership and readability of provider behavior in the chat channel service. **Current behavior** The service implements GitHub task prompts, review provenance, and shared guest containment inline. **Proposed behavior** Channel modules own these details. The core calls their typed functions. Runtime and database effects retain their current order. **Reason and benefit** Maintainers can find channel behavior in its channel folder without following a generic provider framework. **Breaking changes** None intended. Public service entry points and durable data shapes stay compatible. ## What Changed - Extract GitHub task prompts, review provenance, and shared guest containment into the existing channel folders. - Keep shared company scope, authorization, and transaction ownership in their current workflow. - Reduce `chat-channels.ts` from 3970 to 3906 lines. ## Verification - The same 130 selected GitHub and low-trust integration cases passed before and after extraction. Existing transactions still own containment, authority receipts, and review rows. - Server typecheck passed. - `node scripts/check-module-boundaries.mjs` passed. - Full workspace typecheck and build passed on the cumulative stack. All current-head CI gates passed. Greptile completed at 5/5 with no findings. - The full local `pnpm test:run` command exited with three database fixture-startup hook timeouts. It reported 19,529 passing tests and 250 skipped tests. No assertion failed. Its later test groups did not run because the driver stops on the first failing group. - The timed-out files were `environment-custom-images-service.test.ts`, `generic-mcp-connection.test.ts`, and `modules/wake-queue/adapters/postgres.test.ts`. All 166 tests in these files passed in isolation on both baseline `edcfcaf3f6` and stack head `faaca26d46`, with existing timeouts and assertions. The tests and database-startup helper are unchanged. - Provider fixtures prove application integration. They do not prove live third-party execution. ## Risks - Incorrect inputs or changed await order could affect provider handling and recovery. - Existing integration tests exercise the assembled service before and after extraction. - No database migration or API change is included. ## Model Used OpenAI GPT-6, running in Codex with reasoning, tool use, and code execution. The exact deployment identifier and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
3e8e1efb84 |
refactor(server): isolate inbound channel message policies (#16230)
## Thinking Path > - Paperclip helps people manage AI agents for work. > - Chat channels turn provider messages into shared task workflows. > - The main service still implements provider details beside common authorization and persistence. > - These details belong in the existing channel folders. > - This pull request moves inbound message filtering, command rendering, reply metadata, and setup-reply settlement behind explicit typed functions. > - The service keeps its shared workflow and selects the provider implementation directly. ## Linked Issues or Issue Description Refs: #16192. Stack part 1/5. Base: `master`. **What existing behavior does this improve?** The ownership and readability of provider behavior in the chat channel service. **Current behavior** The service implements inbound message filtering, command rendering, reply metadata, and setup-reply settlement inline. **Proposed behavior** Channel modules own these details. The core calls their typed functions. Runtime and database effects retain their current order. **Reason and benefit** Maintainers can find channel behavior in its channel folder without following a generic provider framework. **Breaking changes** None intended. Public service entry points and durable data shapes stay compatible. ## What Changed - Extract inbound message filtering, command rendering, reply metadata, and setup-reply settlement into the existing channel folders. - Keep shared company scope, authorization, and transaction ownership in their current workflow. - Reduce `chat-channels.ts` from 4082 to 3970 lines. ## Verification - The same 14 selected chat/Photon integration cases passed before and after extraction, including Telegram forum controls, guidance retries, Teams setup replies, and Photon conversation reuse. - Server typecheck passed. - `node scripts/check-module-boundaries.mjs` passed. - Full workspace typecheck and build passed on the cumulative stack. All current-head CI gates passed. Greptile completed at 5/5 with no findings. - The full local `pnpm test:run` command exited with three database fixture-startup hook timeouts. It reported 19,529 passing tests and 250 skipped tests. No assertion failed. Its later test groups did not run because the driver stops on the first failing group. - The timed-out files were `environment-custom-images-service.test.ts`, `generic-mcp-connection.test.ts`, and `modules/wake-queue/adapters/postgres.test.ts`. All 166 tests in these files passed in isolation on both baseline `edcfcaf3f6` and stack head `faaca26d46`, with existing timeouts and assertions. The tests and database-startup helper are unchanged. - Provider fixtures prove application integration. They do not prove live third-party execution. ## Risks - Incorrect inputs or changed await order could affect provider handling and recovery. - Existing integration tests exercise the assembled service before and after extraction. - No database migration or API change is included. ## Model Used OpenAI GPT-6, running in Codex with reasoning, tool use, and code execution. The exact deployment identifier and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
e43af9770a |
refactor(server): isolate publication recovery and Board sends (#16192)
## Thinking Path > - Paperclip publishes task messages through several chat providers. > - Operator recovery must keep durable receipts and task authority consistent. > - The service combines shared publication transactions with provider recovery details. > - Provider-specific recovery belongs beside its transport implementation. > - This pull request extracts publication requests and resolution workflows. > - Shared workflows keep transaction ownership and delegate provider operations. ## Linked Issues or Issue Description Depends on #16187. Refs #16185, #16183, and #16180. Review against the parent branch. **What existing behavior does this improve?** The structure of publication requests, Board sends, and operator recovery. **Current behavior** Six public publication methods live in the main service and include provider-specific transfer and receipt operations. **Proposed behavior** Move shared requests and resolution to publications modules. Move Teams file resolution and Board preparation, Slack file receipts and Board staging, and Photon retry records to their provider folders. **Reason and benefit** Provider recovery is easier to locate without moving transaction and idempotency ownership into providers. ## What Changed - Extract six public publication methods into two shared workflow factories (629 and 467 lines). - Reduce chat-channels.ts from 5,337 to 4,078 lines. The full stack reduces it from 7,919 lines. - Extract Teams transfer resolution and cold-runtime Board preparation. - Extract Slack upload receipt resolution and Board send staging. - Extract Photon operator retry records. - Preserve the same public service API and keep provider operations in the original transactions. ## Verification - Merge preparation: replayed this stack onto current master after #16180 landed. Preserve master's new Telegram scheduling methods and connection-scoped Photon notifications. Server typecheck, callback syntax audit, and module-boundary check passed. Fresh local integration and wiring checks passed (1,318 tests). The dedicated Photon suite passed 18 before and 18 after the conflict resolution. This final slice was replayed onto merged #16187 with all chat-channel source unchanged. Current-head CI and review are running. Earlier verification below describes previous stack commits. - Publication, attachment, Board send, and operator recovery baseline: 261 passed before and 261 passed after; 1,034 other cases excluded. - Server typecheck, module-boundary check, and git diff --check passed. - Syntax audit reconstructs all six public method bodies from the provider helpers and matches the original AST. Unrelated service functions and the public API match too. - Final repository typecheck passed. Build passed. The broad local test run encountered heartbeat fixture setup failures under the macOS PostgreSQL shared-memory limit and was interrupted after 868 seconds (exit 130). Four confirmed abandoned guard slots were reclaimed without stopping active databases. The complete chat integration suite and source-wiring checks passed separately (1,309 tests). - Greptile rates current head 55417debfe 5/5 with zero inline findings. All 55 CI checks pass on that head. Tests use local PostgreSQL and fixture transports, not live provider execution. - Previous stack validation on #16192 (55417debfe): repository typecheck and build passed; all 1,295 chat integration cases plus 14 source-wiring checks passed locally (1,309 total). All five PRs have current-head 5/5 reviews and 55 passing CI checks. The broad local pnpm test:run hit PostgreSQL shared-memory fixture failures and was interrupted after 868 seconds (exit 130); it is not a local full-suite pass. ## Risks Operator recovery can duplicate a send if receipt updates move out of their transaction. The extracted helpers use the caller transaction. Teams preparation remains outside Board locks, and repeated send identities retain their existing receipt. Public method names and return values stay the same. ## Model Used OpenAI GPT-6 via Codex, with code execution and repository tools. The precise serving variant and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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> |
||
|
|
f18247b7e7 |
refactor(server): isolate durable chat wakeup workflows (#16187)
## Thinking Path > - Paperclip accepts chat messages as durable task input. > - Wakeups must preserve current company, identity, and task permissions. > - The main service mixes those shared checks with provider message rules. > - Shared wakeup workflows should own persistence and queue ordering. > - This pull request extracts wakeup authorization, processing, and notices. > - Slack and GitHub rules move into their provider folders. ## Linked Issues or Issue Description Depends on #16185. Refs #16183 and #16180. Review against the parent branch. Related open #13620 covers durable chat wakeup feature work; this PR only moves existing behavior. **What existing behavior does this improve?** The structure of durable inbound wakeup processing. **Current behavior** The service contains authorization, durable wake receipts, queue notices, and provider authority details. **Proposed behavior** Use three cohesive inbound modules and provider-owned authority functions. **Reason and benefit** The shared transaction and company checks stay together while provider rules have a clear home. ## What Changed - Move wakeup authorization, processing, and notices into inbound modules (245, 418, and 377 lines). - Move Slack mention checks and GitHub automatic-event admission and acknowledgements into provider folders. - Preserve lock order, durable receipt ordering, notice cursor lifetime, and the live heartbeat dependency. - Reduce chat-channels.ts from 6,340 to 5,337 lines, including blank-gap cleanup. ## Verification - Merge preparation: replayed this stack onto current master after #16180 landed. Preserve master's new Telegram scheduling methods and connection-scoped Photon notifications. Server typecheck, callback syntax audit, and module-boundary check passed. Fresh local integration and wiring checks passed (1,318 tests). The dedicated Photon suite passed 18 before and 18 after the conflict resolution. This slice was replayed onto merged #16185 with its chat-channel source unchanged. Current-head CI and review are running. Earlier verification below describes previous stack commits. - Existing wakeup, queue, retry, and authorization integration cases: 212 passed before and 212 passed after; 1,083 other cases excluded. - Server typecheck, module-boundary check, and git diff --check passed. - Syntax-tree audit compares all 12 moved functions, cursor state, retained service functions, and public API after explicit provider delegations. - The first three stack PRs have 55 passing CI checks and current-head 5/5 reviews. - Final stack checks are recorded below. The first broad local run encountered a PostgreSQL shared-memory fixture limit and was interrupted after that failure. - Greptile rates current head 1462819f53 5/5 with zero inline findings. All 55 CI checks now pass. Initial CI failures: the first workspace job hit EADDRINUSE in sandbox-callback-bridge.test.ts, and cloud-auth.spec.ts hit a disposed Playwright response. Both jobs passed on retry without source changes. Integration uses local PostgreSQL and fixture provider transports, not live providers. - Previous stack validation on #16192 (55417debfe): repository typecheck and build passed; all 1,295 chat integration cases plus 14 source-wiring checks passed locally (1,309 total). All five PRs have current-head 5/5 reviews and 55 passing CI checks. The broad local pnpm test:run hit PostgreSQL shared-memory fixture failures and was interrupted after 868 seconds (exit 130); it is not a local full-suite pass. ## Risks Authorization and wakeups must retain the same locks and transaction scope. Factories receive narrow dependencies and initialize before their consumers. The notice cursor stays per service. Shutdown and heartbeat reads remain live. Provider helpers do not own transactions. ## Model Used OpenAI GPT-6 via Codex, with code execution and repository tools. The precise serving variant and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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> |
||
|
|
721e87ac02 |
refactor(server): separate receiver ownership and provider callbacks (#16185)
## Thinking Path > - Paperclip accepts provider callbacks as durable task input. > - Runtime ownership prevents two servers from accepting the same receiver stream. > - Discord and Photon share the lease machinery but have different callback details. > - Moving that shared machinery into Discord would create the wrong platform dependency. > - This pull request extracts common receiver ownership and puts provider callbacks in their own folders. > - The service keeps startup and shutdown coordination. ## Linked Issues or Issue Description Depends on #16183; review against the parent branch. Refs #16180 and #16080. Related open work: #15532 changes Discord command reconciliation scheduling. This extraction preserves existing scheduling. **What existing behavior does this improve?** The structure of shared receiver ownership and Discord/Photon runtime callbacks. **Current behavior** The shared entry point mixes lease acquisition, renewal, provider capability checks, and Photon checkpoint transactions. **Proposed behavior** Put the common lease operations in runtime/ownership.ts and the protocol details in the provider folders. **Reason and benefit** The ownership lifetime stays explicit without making Photon depend on Discord implementation code. ## What Changed - Extract 11 receiver-ownership helpers into runtime/ownership.ts (397 lines). Expose only the operations used by the service. - Extract Photon ownership checks and checkpoint callbacks (44 lines). Retain the same runtime context object. - Extract Discord command and capability reconciliation (112 lines). - Keep the original service-owned lease map, runtime versions, stop tasks, and shutdown sequence. Read shutdown and test overrides through live accessors. - Reduce chat-channels.ts from 6,880 to 6,340 lines, including removal of blank gaps left by extractions. ## Verification - Merge preparation: replayed this stack onto current master after #16180 landed. Preserve master's new Telegram scheduling methods and connection-scoped Photon notifications. Server typecheck, callback syntax audit, and module-boundary check passed. Fresh local integration and wiring checks passed (1,318 tests). The dedicated Photon suite passed 18 before and 18 after the conflict resolution. Current head is 6d52aba35f; CI and review are running. Earlier verification below describes the previous stack commits. - Existing Discord, Photon, and runtime integration cases: 110 passed before and 110 passed after; 1,185 other cases excluded. - Server typecheck, module-boundary check, and git diff --check passed. - Syntax-tree comparison: 11 ownership helpers, two Photon callback bodies, Discord reconciliation, unrelated service functions, and the full public API/shutdown return expression preserve structure. Intentional binding changes are audited. - Both preceding PRs have 55 passing CI checks and current-head 5/5 reviews. - Repository typecheck and build passed earlier in this stack. Final stack checks are recorded below. The first broad local run hit a macOS PostgreSQL shared-memory fixture limit and was interrupted after that failure. - All 55 CI checks pass on df15f9dd9c. Greptile rates that head 5/5 with no inline findings. Tests use real local persistence with fixture runtimes; they do not prove live Discord or Photon execution. - Previous stack validation on #16192 (55417debfe): repository typecheck and build passed; all 1,295 chat integration cases plus 14 source-wiring checks passed locally (1,309 total). All five PRs have current-head 5/5 reviews and 55 passing CI checks. The broad local pnpm test:run hit PostgreSQL shared-memory fixture failures and was interrupted after 868 seconds (exit 130); it is not a local full-suite pass. ## Risks Lease loss and partial startup can create overlapping receivers if cleanup order changes. The service retains the same map objects and shutdown ordering. The ownership module reads current shutdown state, and Photon callbacks retain the exact mutable runtime context reference. No new worker or timer starts during module initialization. ## Model Used OpenAI GPT-6 via Codex, with code execution and repository tools. The precise serving variant and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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> |
||
|
|
ba00e9ef1a |
refactor(server): isolate provider webhook handling (#16183)
## Thinking Path > - Paperclip connects provider messages to governed agent work. > - Webhooks must authenticate and persist messages before acknowledging them. > - The shared service still contains GitHub and Slack protocol details. > - The platform-boundary rule places those details in provider folders. > - This pull request extracts provider webhook handling behind typed methods. > - The service retains dispatch, runtime selection, and durable lifecycle recording. ## Linked Issues or Issue Description Depends on #16180; review this PR against its parent branch. Refs #16080. Related open work: #16163 changes GitHub automatic-author policy. This extraction preserves that policy implementation. **What existing behavior does this improve?** The ownership and readability of GitHub and Slack webhook handling. **Current behavior** The shared service implements GitHub signatures, replay fences, automatic event messages, and Slack callback verification. **Proposed behavior** Place those details in the respective provider folders and keep the common dispatcher small. **Reason and benefit** Provider code can be reviewed without reading the shared task service. ## What Changed - Extract GitHub request-local deadline and replay scope (60 lines). - Extract GitHub authentication and durable-ingress coordination (280 lines). - Extract GitHub event admission, message construction, and policy-skip receipts (140 lines). - Extract Slack workspace validation and authenticated callback observation (131 lines). - Keep the same service-owned background task set and GitHub provenance maps. Forward late-initialized callbacks without reading them during construction. - Reduce chat-channels.ts from 7,383 to 6,880 lines: 503 net lines removed. ## Verification - Merge preparation: replayed this stack onto current master after #16180 landed. Preserve master's new Telegram scheduling methods and connection-scoped Photon notifications. Server typecheck, callback syntax audit, and module-boundary check passed. Fresh integration, CI, and current-head review are running. Earlier verification below describes the previous stack commits. - Parent baseline: 544 selected GitHub, Slack, and webhook integration cases passed; 751 other cases excluded. - Initial extracted run: 543 passed and one idle-queue scan assertion failed. The idle-queue case passed separately on both the parent and extracted code. Its publication implementation is unchanged. The full selected-suite retry passed all 544 cases; the initial failure remains documented and its cause is not established. - Server typecheck, module-boundary check, and git diff --check passed. - Syntax-tree comparison verifies unchanged request-scope logic, durable ingress, leased authentication, event handling, workspace validation, and callback recording. All unrelated service functions remain unchanged. - Repository typecheck and production build passed for the parent extraction. Full-stack verification will run at the final handoff. The first broad local run hit a macOS PostgreSQL shared-memory fixture limit and was interrupted after that failure. - All 55 current-head CI checks passed. Greptile: 5/5 on f74ecb5094, with zero inline findings. No live third-party execution is claimed. - Previous stack validation on #16192 (55417debfe): repository typecheck and build passed; all 1,295 chat integration cases plus 14 source-wiring checks passed locally (1,309 total). All five PRs have current-head 5/5 reviews and 55 passing CI checks. The broad local pnpm test:run hit PostgreSQL shared-memory fixture failures and was interrupted after 868 seconds (exit 130); it is not a local full-suite pass. ## Risks Moving callback code can change initialization timing or lose request-scoped state. The new factories retain live option getters, the exact runtime context and provenance maps, and typed forwarding for late initialization. Authentication stays inside the existing credential lease. The common lifecycle write still completes before returning provider success. ## Model Used OpenAI GPT-6 via Codex, with code execution and repository tools. The precise serving variant and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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> |
||
|
|
1e64c875b2 |
refactor(server): move Slack recovery into channel modules (#16180)
## Thinking Path
> - Paperclip manages AI agents and their work.
> - Chat channels connect provider messages to governed tasks.
> - Slack task recovery still lives in the shared channel service.
> - Its provider sends and recovery state belong in the Slack folder.
> - This pull request moves Slack task-start resolution and
Board-message recovery into two modules.
> - The service keeps the public dispatcher and the existing shared
authorization owners.
## Linked Issues or Issue Description
Refs #16080. Related open work: #15421 changes linked-user task trust;
#15532 changes Discord reconciliation. This extraction changes neither
behavior.
**What existing behavior does this improve?**
The ownership and readability of Slack task-start and Board-message
recovery.
**Current behavior**
The 7,919-line shared service implements Slack retry and cancellation
details.
**Proposed behavior**
Keep those implementations in the Slack folder. Preserve public methods
and all state transitions.
**Reason and benefit**
The channel boundary follows rules/chat-channel-platform-boundaries.mdc
and makes Slack recovery easier to review.
## What Changed
- Move Slack task-start operator resolution into
slack/task-start-resolution.ts (488 lines).
- Move the durable Slack Board-message worker into
slack/board-messages.ts (104 lines).
- Keep initial endpoint/action lookup and provider-effect dispatch in
the service. Pass the original endpoint record to avoid a new read or
race.
- Preserve live reads of heartbeat and deferred-processing options.
- Reduce chat-channels.ts from 7,919 to 7,383 lines: 536 net lines
removed.
## Verification
- Existing Slack integration cases: 282 passed before and 282 passed
after; 1,013 non-Slack cases excluded by the filter.
- pnpm -r typecheck: passed. The first sandboxed attempt could not
create a local tsx IPC socket; the permitted rerun passed.
- pnpm build: passed.
- Module-boundary check and git diff --check: passed.
- Normalized TypeScript AST comparison: moved Board worker and Slack
resolution tail unchanged; all other service function declarations
unchanged.
- All 55 current-head CI checks passed; two optional Storybook checks
skipped. Greptile: 5/5 on
|
||
|
|
833769ab55 |
perf(chat): schedule Telegram maintenance from commits and deadlines (#16094)
Replace periodic Telegram discovery and maintenance scans with bounded startup recovery, connection-specific commit notifications, and durable action deadlines. Preserve ownership, inactive subscription parking, retry and cleanup recovery, and atomic credential binding updates. Verified full typecheck/build, 30 focused scheduler tests, 12 database-backed recovery cases, all current-head CI checks, and Greptile 5/5 with no unresolved threads. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
df06df2306 |
fix(slack): allow direct messages without at-mentions (#16151)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Slack connections let people start and continue agent tasks. > - The Require at-mention setting currently applies to channels and direct messages. > - A person who sends a direct message has already selected the agent. > - This pull request exempts direct messages from mention checks, including queued work. > - People can talk normally in DMs while channel messages keep the configured mention rule. ## Linked Issues or Issue Description Refs #15612, which introduced the Require at-mention setting. Searches found no duplicate PR for the DM exemption. **What happened?** With Require at-mention enabled, a plain Slack DM does not start or continue agent work. New Slack connections enable the setting by default. **Expected behavior** Direct messages do not need an at-mention. Top-level DM replies remain top-level. Channel messages and channel thread replies still follow the saved mention setting. **Steps to reproduce** 1. Enable Allow direct messages and Require at-mention on a Slack connection. 2. Send a plain DM from an authorized sender. 3. Confirm the agent responds without an at-mention. Send a plain follow-up and confirm it also works. 4. Confirm unmentioned channel messages remain filtered when Require at-mention is enabled. 5. Disable Allow direct messages and confirm new DMs remain blocked. **Paperclip version or commit** Source baseline: `eb06c9fedd`. **Deployment mode** Built from source. Automated tests use disposable local Postgres and provider fixtures. This change has not been deployed or retested in live Slack. ## What Changed - Exempt DMs at inbound admission, task mutation, work authorization, and heartbeat queue claim. - Keep channel mention checks and all existing sender, endpoint, and destination checks. - Update regressions for new connections, follow-ups, deferred delivery, and coalesced queued messages. - Clarify the Slack settings copy, connection documentation, and verification maps. - Refresh the affected Storybook review references after source inspection. ## Verification - Passed 55 Slack and durable scheduler tests with Vitest on the current rebased commit, including admission through the extracted inbound module. - Passed `pnpm -r typecheck` and `pnpm build` on the rebased PR commit. - Passed token gates and map checks. - Passed Storybook catalog validation after rebase: 223 files and 2,210 stories. - Full local `pnpm test:run` was stopped before completion after three failures in the unchanged tool-access suite. All 418 tests in that suite passed in a standalone rerun. The focused regressions passed; full GitHub CI remains the merge gate. - Greptile reviewed commit `b0293fa6571403c5e01c30bb7b5fcc5e91b88c97`: 5/5, with no findings or unresolved review threads. All 55 GitHub checks passed on this commit; two optional Storybook jobs were skipped. - No live Slack messages were sent during implementation verification. ## Risks Existing Slack connections now accept authorized plain DMs even when Require at-mention is enabled. Allow direct messages and sender authorization still apply. Queued DM work follows the same exemption. Channel behavior and DM reply routing are unchanged. No schema or migration change is required. ## Model Used OpenAI GPT-6, running as Codex, with reasoning, tool use, and code execution. The runtime does not expose a more specific model ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [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> |
||
|
|
eb06c9fedd |
refactor(server): split chat channel workflows into provider and shared modules (#16080)
Move provider operations into channel folders and shared chat work into named interaction, setup, admission, delivery and publication workflows. Consolidate reviewed PRs #16085, #16089, #16096 and #16105. Preserve upstream execution-default and recovery behavior. The main service is 7,917 lines. All 55 current-head CI checks pass, with two optional Storybook skips. Greptile is 5/5 with no findings. All 1,294 current chat integration cases, repository-wide typecheck and build pass locally. Broad local tool-route timing/socket failures are recorded in the PR. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
d837b65be8 |
refactor(server): move provider setup, inventory and delivery into channel folders (#16058)
Consolidate the ten reviewed provider-folder extractions. Preserve the verified source tree and current master changes. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
e168512f7b |
perf(chat): stop polling failed run retries (#15871)
Stop one-second scans of failed chat-run retries. Wake the existing retry queue after transaction commits and at saved retry or stale-claim deadlines. Preserve claim fences, authorization, recovery, and idempotent agent admission. Resolve conflicts with the current chat-service extraction by applying the retry signals and shared deadline predicate in the failed-run retry module. Verified with pnpm typecheck, pnpm build, all 1,328 chat and coordinator regression tests, and current-head CI. Greptile reviewed the final head at 5/5 with no unresolved threads. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
f329b24ee1 |
feat: give tasks durable project-optional workspaces (#15749)
Give tasks durable company-scoped workspace bindings independent of project assignment, channel defaults and authorized repository preparation. Reuse verified input seeds and sparse output recovery while preserving trust, privacy and controller provisioning boundaries.
Full CI and E2E, Superagent, legacy checks and Greptile Apex 5/5 passed on reviewed head
|
||
|
|
64bd6e9e07 |
refactor(chat): extract delivery, reaction, and setup boundaries (#16024)
## Thinking Path > - Paperclip manages AI agents and their work. > - Chat channels connect that work to provider conversations. > - One shared service contains callback, delivery, reaction, and setup logic. > - These responsibilities have distinct contracts and existing public-path tests. > - This PR moves ten cohesive responsibilities into focused modules. > - The service retains shared runtime ownership and scheduling. > - Provider behavior is easier to locate and review. ## Linked Issues or Issue Description Refs #15995, #16026, #16027, #16030, #16031, #16035, #16037, #16038, #16041, #16043. This PR consolidates the reviewed extraction stack. The plan is `doc/plans/2026-10-12-chat-channel-delivery-boundaries-refactor.md`. ## What Changed - Move Slack callback verification into the Slack folder. - Move Discord Gateway events and root-thread admission/recovery into the Discord folder. - Extract durable receipt reactions and inbound reaction admission/replay. - Extract inbound attachment ingestion and outbound integrity-checked hydration. Preserve the public hydration export. - Extract durable provider effects. Keep Telegram callback notices in the Telegram folder. - Extract conversation/activity reads and setup qualification. Keep Slack and Teams projections in their channel folders. - Preserve the merged managed Slack setup behavior, shared workers, credential leases, and transaction boundaries. - Reduce `chat-channels.ts` from 26,493 lines / 1,048,769 bytes to 21,460 lines / 862,284 bytes. This removes 5,033 lines from the service. ## Verification - Each extraction passed its selected existing tests before and after through public service paths. - On updated master, all 55 selected Slack cases passed before extraction. All 194 selected chat/managed-Slack cases passed on the final stack tip. - `pnpm -r typecheck`, `pnpm build`, module-boundary checks, and whitespace checks passed on that tip. - The normalized syntax audit verifies 69 moved declarations and all retained statements, including their relative order, against updated master. - The eight earlier stack merges retain the exact validated repository tree. The combined root equals the validated tip merged with current master. All chat-channel files remain byte-identical to the validated tip. Current combined-root CI and review are pending. - Full local verification remains unverified. The unchanged `workspace-git-snapshot-streaming.test.ts:56` stress test timed out at 300,000 ms in a clean run and again in isolation. The full run was stopped after the reproduced failure. No timeout or assertion was weakened. - These checks use assembled services, real local databases, and provider fixtures. They do not prove live third-party execution. Reviewers can run the public-path suites: ```sh pnpm exec vitest run server/src/__tests__/chat-channels.integration.test.ts server/src/services/chat-outbound-attachment-hydration.test.ts server/src/__tests__/slack-development-manager.test.ts ``` ## Risks - Factory wiring must preserve live values, shared state, and initialization order. Identity-link construction retains deferred access to the provider-effects callback. - Credential fences, authorization transactions, and delivery settlement must keep their original ordering. Syntax parity and public-path integration cases cover these boundaries. - Full local verification has the recorded Git-streaming timeout. The combined PR must pass master’s required CI before merging into master. ## Model Used OpenAI Codex, GPT-6 family, with reasoning and repository tools. The exact runtime model ID and context-window size are not exposed in this session. No separate agent was used. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
f0e12c8519 |
Add managed Slack setup with an independent own-app path (#15679)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Slack connects a person to an agent through an installed app and a verified identity. > - Independent installations must remain usable without Paperclip Cloud or manager credentials. > - Approved Cloud deployments can use Slack manager grants to create and install each agent's app. > - Both paths should share credential storage, identity checks, recovery, and the existing runtime. > - This pull request adds gated managed setup and keeps independent app setup under Advanced. > - It also makes ongoing connection settings and personal test messages easier to use. ## Linked Issues or Issue Description **Subsystem affected** Slack setup, connection settings, tenant credential storage, and the Cloud connector handoff. **Problem or motivation** Approved deployments need an installation flow without pasted configuration tokens. Open-source users must retain their independent Slack app flow. A connection manager also needs a simple way to check a bot from Settings. **Proposed solution** Use the managed path when the instance is configured to support it. Choose agent and Connect are the two visible stops. Continue starts authorization or installation. Use your own app remains under Advanced before creation. Save personal manager grants by company, Paperclip user, Slack user, workspace, and manager app. Reuse only verified identities for test messages. Unknown identities must complete a private Slack connection challenge before linking and receiving the test DM. **Alternatives considered** A shared bot would change each agent's Slack identity. Requiring Slack CLI or a hosted service for self-hosted users would remove independent installation. **Roadmap alignment** This maintainer-requested change improves Connected Apps and experimental Agent Chat. It adds provisioning and management controls to the existing Slack runtime. **Additional context** The companion Cloud broker profile is a separate deployment prerequisite. Managed setup remains gated. Existing-app adoption is deferred. ## What Changed - Extract Slack registration, provider requests, completion, customer-owned setup, managed setup, and personal manager grants into focused services. Preserve the compatibility facade and independent removal cleanup. - Add company-scoped manager grants and a registration reference through an additive, idempotent migration after current master. Keep runtime credentials separate from app-registration secrets. - Add authenticated manager authorization, sealed handoff, serialized refresh and revocation, app creation, managed installation, and installer-bound OAuth fallback. - Preserve creation intent, block automatic uncertain recreation, save credentials before downstream checks, and validate app, workspace, bot, scopes, and installer identity. - Add the two-stop production wizard and ordered stories. Keep the own-app, manual, existing-app, and legacy-draft paths. - Simplify Settings. Open Slack configuration targets the saved app. The test-message action has its own row. Remove the old manual-avatar section, channel-message section, and broken permissions link. - Add paginated account discovery and a private connection challenge for unknown accounts. Expired invitations stop waiting and offer a new private invitation. Save send receipts before provider dispatch and preserve confirmed delivery when activity logging fails. - Reinstall the saved managed app on explicit reconnect, replace revoked credentials, and resume completion. Persist reconnect intent and duplicate-request receipts without creating another app. - Update provider browser tests, recovery tests, secret redaction, setup documentation, and the agent prompt. Preserve current master's durable verification scheduling. ## Verification - Full workspace typecheck and repository build passed on `56d389d47a`. The subsequent reconnect retry fix in `288364eada` also passed UI typecheck and UI build. - 114 focused Slack registration cases and 13 production managed-wizard cases passed, including fresh-token reconnect, retry after installation failure, and duplicate reconnect requests. - All nine affected Slack browser cases passed against the production UI and a disposable fixture server. They cover managed setup, automatic setup, own-app selection, refresh, recovery, mobile behavior, and connection settings. - Eight focused real-database test-message cases passed. They cover a private ownership challenge, saved grant reuse, account pagination, revoked and conflicting links, workspace mismatch, disabled DMs, revoked membership, audit failure, ambiguous dispatch, and secret canaries. - UI token gates and the production Storybook build passed. - Greptile reviewed exact head `288364eada5d9c114fad991ff634612639d06672` at 5/5 with no actionable findings or unresolved review threads. - The full repository test suite and current-head CI are running. Their final results will replace this line before merge. - Earlier live feature previews created two bots in the authorized Paperclip Slack workspace and reused one personal manager grant. Local managed Continue created and installed a bot without a configuration token or a separate Add to Slack action. Avatars, welcome DMs, signed callbacks, and direct replies were observed. A Settings test DM also arrived in the signed-in user's Slack account. - Earlier staging thread qualification required manual publication recovery for one bot. Current-head live qualification remains required before enabling the production default. Fixture results do not establish Slack approval behavior in other workspaces. ## Risks - Personal manager tokens can create apps. They stay in scoped vault entries. The manager client secret stays at the broker. Company, actor/session, origin, and app identity checks apply throughout setup. - The additive migration must also work on qualification instances that applied earlier branch migrations. Table, column, index, and constraint creation is idempotent. - Creation and message timeouts can leave uncertain outcomes. Saved request IDs prevent automatic duplicate dispatch. - Unknown Slack identities must receive and complete their private challenge while signed in. Account selection alone does not grant Paperclip permissions. Existing revoked or conflicting links are not overwritten. - A development-only manager transport uses an explicitly configured private credential file for local qualification. Production ignores this transport; no manager credentials are bundled with open source. - Managed rollout requires Slack approval, the companion broker deployment, configured secrets, and final live qualification. Removing a connection does not delete its Slack app. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, code execution, and browser tools. The session does not expose the exact serving model ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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> |
||
|
|
0d0e138dad |
refactor(chat): extract channel status, receipts, drafts and authority workflows (#15995)
## Thinking Path > - Paperclip manages AI agents and their work. > - Chat channels connect that work to provider conversations. > - Provider workflows still fill the shared service. > - Their authority and recovery rules need clear homes. > - This PR lands five reviewed extractions into channel folders. > - Shared authorization, state and worker lifetime stay explicit. ## Linked Issues or Issue Description Refs #15976, #15996, #15999, #16001 and #16002. This root PR now contains all five extractions from batch three. The four upper PRs were merged into their parents. The combined tree matches reviewed stack head `789e918b5af49ec1958076ce4d22d31006205302` exactly. ## What Changed - Extract Slack session status and accepted-file receipt recovery. - Extract Telegram publication drafts and Stop handling. - Extract Photon events and native responses. - Extract Teams file-transfer authority. - Reduce `chat-channels.ts` from 29,897 to 26,461 lines (3,436 lines, 11.5%). - Preserve function bodies, runtime-map identity, leases and transaction boundaries. ## Verification - All 117 selected public-service cases passed before and after their respective extractions. - All 30 moved declarations and remaining service statements preserve normalized syntax across the five slices. - Server typecheck, module boundaries and whitespace checks passed. - Cumulative `pnpm -r typecheck` and `pnpm build` passed. Combined-head CI and review are pending on `5de1b0b99d71049a72440e8c131bf4bb30bdf3f3`. - Fixtures exercise assembled services and disposable databases, not live third-party providers. - Cumulative local `pnpm test:run` on `789e918b5af49ec1958076ce4d22d31006205302` exited 1: 32,414 passed, 125 skipped, one failure. `company-skills-routes.test.ts:1691` (`stars, forks, and comments on skills through company-scoped endpoints`) failed with `socket hang up`; that test and its route are unchanged by this stack. The same 58-case suite then passed in isolation without code changes. The original command did not reach 111 later serialized suites; its failure is retained, so the full-local-test checklist remains unchecked. ```sh pnpm exec vitest run server/src/__tests__/chat-channels.integration.test.ts -t 'Slack session|Slack turns to Idle|signed Slack session stop|denies guest Slack stops' ``` - Combined-head CI attempt 1: five runners received a shutdown signal at 19:13:08 UTC (server shard 10/12, serialized shards 2/9 and 7/9, E2E shards 3/8 and 7/8). These jobs stopped during execution without a failing test assertion. [Original workflow](https://github.com/paperclipai/paperclip/actions/runs/38293566028). The affected jobs will receive one unchanged retry after the other jobs finish. ## Risks - Changes cross durable provider recovery and authority boundaries. The moved bodies preserve syntax, and 117 focused public-service cases passed before and after their extractions. - Shared workers, timers, runtime maps and generic authorization remain in the service. - The full local test run failed in an unchanged company-skills route test; its result and the unrun suites are recorded above. ## Model Used OpenAI Codex, GPT-6 family, with reasoning and repository tools. The exact runtime model ID and context-window size are not exposed in this session. No separate agent was used. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
a2ac5c2715 |
refactor(chat): isolate Telegram, Slack, GitHub and Discord workflows (#15976)
## Thinking Path > - Paperclip manages AI agents and their work. > - Chat channels connect that work to external conversations. > - The shared chat service still contains provider-specific workflows. > - Those workflows are hard to inspect in a 34,000-line file. > - This stack extracts Telegram, Slack, GitHub and Discord workflows into their channel folders. > - Shared authorization and service lifetime remain explicit. ## Linked Issues or Issue Description Refs #15823, #15834, #15836, #15844 and #15845. Root of the second behavior-preserving channel-folder refactor stack. The dependent PRs #15979, #15981, #15985 and #15987 have merged into this branch; this PR lands all five extractions on master. ## What Changed - Move Telegram maintenance and subscription repair into `chat-channels/telegram/maintenance.ts`. - Move Slack session stopping and task starts into `chat-channels/slack/session-stop.ts` and `task-start.ts`. - Move GitHub webhook intake and recovery into `chat-channels/github/webhook-ingress.ts`. - Move Discord command registration and handling into `chat-channels/discord/commands.ts`. - Share type-only runtime records while preserving shared authorization, transactions, live lease checks and worker ownership. - Reduce the original service from 34,603 to 29,897 lines, removing 4,706 lines (13.6%). ## Verification - All 205 selected integration cases passed before and after their respective extractions: Telegram 41, Slack session stop 2 multi-step scenarios, GitHub 84, Slack task start 25 and Discord 53. Each dependent PR records its focused reproduction command. - Server typecheck, module boundaries and whitespace checks passed. - Per-slice syntax comparisons passed for moved declarations and remaining service statements, allowing only the documented live callback substitutions. - Tests exercise the public service with disposable databases and fixture provider transports. They do not claim live third-party execution. - Cumulative workspace typecheck and build passed on the final stack. - Current-head CI passed on the combined stack commit `d5b37dbe512e3e199932b6608cdc17639eda555a`; Greptile is 5/5 with no unresolved threads. - The [original serialized shard](https://github.com/paperclipai/paperclip/actions/runs/38266518817/job/114870022249) timed out in unchanged `adapter-auth-signal-routes.test.ts`. The exact case passed locally without changes, and the [single job retry](https://github.com/paperclipai/paperclip/actions/runs/38266518817/job/114874019933) passed. The original timeout remains recorded. Reproduce the original Telegram slice’s focused suite: ```sh pnpm exec vitest run server/src/__tests__/chat-channels.integration.test.ts -t 'Telegram durable private draft Stop|Telegram maintenance|Telegram webhook|Telegram.*(pause|remove)|Telegram.*commands' ``` - Cumulative local `pnpm test:run` exited 1: the first server group had **18,770 passed, 105 skipped, and one timeout** in unchanged `server/src/services/workspace-git-snapshot-streaming.test.ts:56` (300,000 ms on macOS). The fail-fast runner did not reach its later workspace and serialized groups. An unchanged isolated rerun passed using the existing timeout; this does not turn the original full run green. The test and its Git utility code are outside this refactor; all current-head CI jobs passed. - Reproduce that diagnostic alone: `pnpm exec vitest run server/src/services/workspace-git-snapshot-streaming.test.ts`. ## Risks - Credential lease ownership and provider-confirmation ordering must remain unchanged. Existing rotation, lease-loss, recovery and durable Stop cases pass. - The channel factories create no workers or timers and preserve live runtime, shutdown and gateway-ownership reads. ## Model Used OpenAI Codex, GPT-6 family, with reasoning and repository tools. The exact runtime model ID and context-window size are not exposed in this session. No separate agent was used. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
d497d1ccec |
refactor(chat): extract failed-run retry coordination (#15845)
## Thinking Path > - Paperclip manages agent work and sends results back to chat. > - A failed chat run can be retried only while its original source remains authorized. > - That decision includes persisted source evidence and native runtime state. > - Retry claims also share in-flight promises and depend on service shutdown. > - This PR groups retry authorization, execution and notices in one module. > - The service retains the live admission, runtime and shutdown boundaries. ## Linked Issues or Issue Description Refs #15844, #15836, #15834 and #15823. Stack slice 5 of 5, based on `codex/chat-publication-replacement`. Merge each predecessor first, then retarget this PR. Do not merge the stack out of order. Stack order: #15823 (provider messages) → #15834 (resource reconciliation) → #15836 (identity links) → #15844 (publication replacement) → #15845 (failed-run retries). GitHub native stack merging preserves this order and automatically restacks the remaining branches. ## What Changed - Extract failed-run retry admission and coordination while keeping the in-flight map, cursor, error class and authority registrations scoped to one chat service. - Move the exact Teams uncertain-file continuation proof into `microsoft-teams/file-transfer-source.ts`. - Pass the existing transaction, explicit source identifiers and denial factory. Return only the proven publication ID. - Keep committed-result, complete source-batch, ancestor and other-uncertain-effect checks in shared `failed-run-retry.ts`. - Keep native execution recovery together; its provider references describe runner backends, not chat channels. - The retry coordinator is 1,825 lines and the Teams proof is 149 lines. Restack on revised #15844 and record the reassessment. ## Verification - Baseline: 59 retry cases and six negative Teams authority cases passed. The combined 65 cases passed after the move. - Cases cover retry ownership, service restart/lifetime, ambiguous Teams receipts, sibling unknown effects, changed source authority and active attempts. - Teams guard, joins, locks, attempt checks and selected ID match after explicit input substitutions. The shared coordinator retains its state and cleanup ownership. - Server typecheck, module-boundary and whitespace checks passed. - Integration uses disposable databases and fixture provider transports; no live third-party execution is claimed. - Fresh Greptile review is 5/5 on `4f7151409717458717633aa270441a8faf33664e`, with a successful check and no open review threads. - Final-stack `pnpm -r typecheck` and `pnpm build` passed at `57ec5ba94aecd860471f9b14db46f99120c7c790`. - All CI checks passed on `57ec5ba94aecd860471f9b14db46f99120c7c790`. - Full local `pnpm test:run` stopped in the general-server group: 18,763 passed, 105 skipped, and one test timed out after 20 seconds in unchanged `workspace-runtime.test.ts` ("does not accept an occupied allocated port when listener ownership is unavailable"). The same case passed in an isolated rerun without code, assertion or timeout changes (1 passed, 175 excluded). The original timeout is retained as a failed full run; later workspace and serialized groups were not reached. The full local gate remains unverified. - Merge verification on the restacked tree: 118 focused identity, publication, Photon and retry integration tests passed; server typecheck and module-boundary checks passed. GitHub’s rebased trees exactly match the previously reviewed file contents. - All current-head required checks passed on `4f7151409717458717633aa270441a8faf33664e`: full CI; Greptile 5/5 with no unresolved threads. ## Risks - Authorization must remain fail-closed across committed output and retry admission. The helper proves only the Teams transfer; the caller still checks the complete source and result in the same transaction. - In-flight promises, error-class identity, registration cleanup, cursor state and the live shutdown getter must remain per-service. Their code is unchanged by this channel-folder move. - This PR depends on #15844. Merge and retarget in stack order. ## Model Used OpenAI Codex, GPT-6 family, with reasoning and repository tools. The exact runtime model ID and context-window size are not exposed in this session. No separate agent was used. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
5a72061ccc |
refactor(chat): extract publication replacement decisions (#15844)
## Thinking Path > - Paperclip publishes agent progress and results back to chat. > - Some updates replace an earlier message while others need a new message. > - The current outbound link and task generation determine that authority. > - These decisions are spread through the large chat service. > - This PR groups publication replacement and supersession decisions in one module. > - Reviewers can follow those decisions without reading provider transport code. ## Linked Issues or Issue Description Refs #15836, #15834 and #15823. Stack slice 4 of 5, based on `codex/chat-identity-links`. Merge the predecessor first, then retarget this PR. Do not merge the stack out of order. Stack order: #15823 (provider messages) → #15834 (resource reconciliation) → #15836 (identity links) → #15844 (publication replacement) → #15845 (failed-run retries). GitHub native stack merging preserves this order and automatically restacks the remaining branches. ## What Changed - Extract shared publication replacement and supersession queries from the large service. - Keep exact outbound ownership, run/wake scope, consumed progress, interaction replacement and retained-source authorization together. - Put the iMessage typing-versus-progress policy in `imessage-photon/publications.ts`. - Preserve endpoint lookup timing and all ownership query bodies. The multi-provider close allowlist remains shared dispatch metadata. - Restack onto the revised #15836 and record why this boundary remains mostly shared. ## Verification - The same 49 existing publication and Photon integration cases passed before and after the provider-policy move. Other cases were excluded by the filter. - Cases cover close-owned progress, ambiguous delivery, interleaved Slack control, Telegram confirmation, FIFO replacement and Photon channel behavior. - Server typecheck, module-boundary and whitespace checks passed. Only the iMessage predicate/reason moved; ownership queries are unchanged. - Historical server shard 2 hit a cleanup deadlock; its unchanged [isolated rerun passed](https://github.com/paperclipai/paperclip/actions/runs/38134431077/job/114457999409). [Original failure](https://github.com/paperclipai/paperclip/actions/runs/38134431077/job/114455332022). - Tests use disposable databases and fixture provider transports, not live third-party execution. - Fresh Greptile review is 5/5 on `8e2da97b6dc11eb446128b61c789edb529c50d5a`, with a successful check and no open review threads. - Final-stack `pnpm -r typecheck` and `pnpm build` passed at `57ec5ba94aecd860471f9b14db46f99120c7c790`. - Historical pre-restack CI failed on `ci / General tests (server (11/12))` and its aggregate `ci / verify`. All 1,255 tests passed, but worker-exit cleanup in unchanged `server/src/__tests__/setup-supertest.ts:32` failed with EACCES removing a temporary `paperclip-vitest-home-*` directory. The [original job](https://github.com/paperclipai/paperclip/actions/runs/38256549828/job/114836065382) and the [single unchanged rerun](https://github.com/paperclipai/paperclip/actions/runs/38256549828/job/114839735273) failed the same way. No further reruns were requested. After GitHub automatically restacked the branches, the full cumulative run on #15845 passed this server shard. This middle PR uses the repository’s policy-only stack CI scope; the top PR runs all suites. - The final full-local-suite outcome for this cumulative stack is recorded in #15845; do not infer that gate from the focused tests above. - Merge verification on the restacked tree: 118 focused identity, publication, Photon and retry integration tests passed; server typecheck and module-boundary checks passed. GitHub’s rebased trees exactly match the previously reviewed file contents. - All current-head required checks passed on `8e2da97b6dc11eb446128b61c789edb529c50d5a`: policy CI (middle-stack scope; full cumulative suites passed on #15845); Greptile 5/5 with no unresolved threads. ## Risks - Splitting shared ownership queries per channel would duplicate authorization rules. They remain in the shared module. - Preserve the issue-to-run lock order and retained-source callback. The factory creates no worker or mutable state. - This PR depends on #15836. Merge and retarget in stack order. ## Model Used OpenAI Codex, GPT-6 family, with reasoning and repository tools. The exact runtime model ID and context-window size are not exposed in this session. No separate agent was used. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
de79750939 |
refactor(chat): extract identity linking (#15836)
## Thinking Path > - Paperclip connects provider identities to company members. > - A confirmed identity determines whose permissions apply to chat messages. > - Token consumption and membership checks must remain atomic. > - These operations currently share the large chat channel service. > - This PR moves identity linking into one module with explicit runtime callbacks. > - Reviewers can inspect the complete identity-link flow together. ## Linked Issues or Issue Description Refs #15834 and #15823. Stack slice 3 of 5, based on `codex/chat-resource-reconciliation`. Merge the predecessor first, then retarget this PR. Do not merge the stack out of order. Stack order: #15823 (provider messages) → #15834 (resource reconciliation) → #15836 (identity links) → #15844 (publication replacement) → #15845 (failed-run retries). GitHub native stack merging preserves this order and automatically restacks the remaining branches. ## What Changed - Extract company-scoped identity linking into shared `identity-links.ts`. - Move Slack connect receipt queries, access requests and confirmation-notice staging into `slack/identity-links.ts`. - Move GitHub identity fields into `github/identity-links.ts`. - Preserve shared token consumption, link locks, membership checks and revocation. - Stage the Slack notice inside the original confirmation transaction. Schedule delivery after commit. Keep runtime and public URL callbacks live. - Restack on the revised resource PR #15834 and record the architectural reassessment in the plan. ## Verification - Four existing service integration cases passed before and after. The Slack connect case covers discovery, preview, access requests, duplicate requests, member confirmation, provider notice, consumed tokens and endpoint isolation. - Receipt queries, the access-request transaction and notice payload match the previous implementation with explicit parameter substitutions. - Server typecheck, module-boundary and whitespace checks passed. - These are local database and fixture transport tests, not live Slack execution. - Fresh Greptile review is 5/5 on `7b44962f09fe8043c77ed40e05f761f31c64b33c`, with a successful check and no open review threads. - Final-stack `pnpm -r typecheck` and `pnpm build` passed at `57ec5ba94aecd860471f9b14db46f99120c7c790`. - All CI checks passed on `62ee045a4728da2d756be3d2e40d13e592a0b5a9`. - The [original workspace shard](https://github.com/paperclipai/paperclip/actions/runs/38256203686/job/114834873234) timed out waiting for the CLI import/export test server health endpoint. Its [single unchanged rerun passed](https://github.com/paperclipai/paperclip/actions/runs/38256203686/job/114838954081). The original timeout remains part of the evidence. - The final full-local-suite outcome for this cumulative stack is recorded in #15845; do not infer that gate from the focused tests above. - Merge verification on the restacked tree: 118 focused identity, publication, Photon and retry integration tests passed; server typecheck and module-boundary checks passed. GitHub’s rebased trees exactly match the previously reviewed file contents. - All current-head required checks passed on `7b44962f09fe8043c77ed40e05f761f31c64b33c`: full CI; Greptile 5/5 with no unresolved threads. ## Risks - Confirmation must retain transaction and token ownership. The Slack helper receives the existing transaction and stages the same effect; scheduling remains after commit in the shared coordinator. - This PR depends on #15834. Merge predecessors and retarget before merging this PR. ## Model Used OpenAI Codex, GPT-6 family, with reasoning and repository tools. The exact runtime model ID and context-window size are not exposed in this session. No separate agent was used. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
3a213ab987 |
refactor(chat): extract resource reconciliation and availability (#15834)
## Thinking Path > - Paperclip manages AI agents and their work. > - Chat resources control which provider destinations can admit that work. > - Inventory updates and lifecycle callbacks must preserve company scope and operator choices. > - These rules share a large service with runtime and credential ownership. > - This PR extracts resource reconciliation and its availability transaction. > - Reviewers can inspect resource changes together while the service retains runtime control. ## Linked Issues or Issue Description Refs #15823 (merged). Slice 2 of 5 now targets `master`. Remaining order: #15834 → #15836 → #15844 → #15845. ## What Changed - Extract shared resource inventory, audited selection and availability settlement from the large service. - Put GitHub repository parsing, rename/transfer repair, webhook recovery and listing in `github/resources.ts`. - Put Telegram group migration in `telegram/resources.ts`, using the coordinator's existing transaction and timestamp. - Put Slack labels, Teams IDs and Photon participant parsing in their channel folders. - Keep lease assertions, delivery settlement and the resource upsert between Telegram migration steps in the shared coordinator. - The shared module is 598 lines; provider resource modules total 409 lines. Update the dated plan with this reassessment. ## Verification - On updated master, 15 existing resource integration cases and one Telegram migration case passed before this folder move. The same 16 cases passed after. Other cases were excluded by the filter. - Eight moved declarations and three transaction blocks match the prior implementation. The GitHub provider guard remains in the caller. - Server TypeScript, module-boundary and whitespace checks passed. Rebuilt plugin SDK types after rebasing onto current master. - Historical browser shard 8 timed out on inbox retry; its unchanged [rerun passed](https://github.com/paperclipai/paperclip/actions/runs/38134430238/job/114457529315). [Original failure](https://github.com/paperclipai/paperclip/actions/runs/38134430238/job/114455332214). - Tests use local disposable databases and fixture provider transports. No live third-party execution is claimed. - Fresh Greptile review is 5/5 on `e914f532ca66c429125492c1723df38afc6e13d7`, with a successful check and no open review threads. - Final-stack `pnpm -r typecheck` and `pnpm build` passed at `57ec5ba94aecd860471f9b14db46f99120c7c790`. - All CI checks passed on `e914f532ca66c429125492c1723df38afc6e13d7`. - The final full-local-suite outcome for this cumulative stack is recorded in #15845; do not infer that gate from the focused tests above. ## Risks - Resource identity and migrations depend on lock and write order. Provider modules use the original transaction; statement order and credential fencing remain unchanged. - Shared selection and availability still contain provider dispatch predicates. They coordinate common state transitions and should remain shared. - Full local tests and current-revision CI remain required for a green handoff. ## Model Used OpenAI Codex, GPT-6 family, with reasoning and repository tools. The exact runtime model ID and context-window size are not exposed in this session. No separate agent was used. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
fb21a3f30a |
refactor(chat): extract provider message normalization (#15823)
## Thinking Path > - Paperclip manages AI agents and keeps their work attached to company tasks. > - Chat providers deliver messages and corrections into those tasks. > - The chat channel service has grown to 39,155 lines. > - Provider message normalization has no database or worker ownership of its own. > - This pull request moves that responsibility into one module while preserving the service body. > - Reviewers can now find provider identities, timestamps, and edit revisions together. ## Linked Issues or Issue Description **What existing behavior does this improve?** Maintenance of inbound chat message normalization in the server. **Subsystem affected** Server chat channels. **Current behavior** Provider message parsers and identity rules share a 39,155-line file with credentials, runtime ownership, database admission, and publication workers. **Proposed behavior** Move provider message normalization into `chat-channels/provider-messages.ts`. Keep service exports and runtime behavior unchanged. **Reason and benefit** This creates a clear first boundary for an incremental refactor. A dated plan ranks the next four larger extractions. No duplicate chat refactor was found in the GitHub title search. **Breaking changes** None intended. No schema, endpoint, transport, or public service API changes. Stack order: #15823 (provider messages) → #15834 (resource reconciliation) → #15836 (identity links) → #15844 (publication replacement) → #15845 (failed-run retries). Merge in this order; retarget each child after its predecessor lands. ## What Changed - Move provider message parsing into `chat-channels/telegram/messages.ts`, `slack/messages.ts`, `discord/messages.ts`, `microsoft-teams/messages.ts` and `github/messages.ts`. - Keep shared actor normalization, actor data and the inbound text limit in `chat-channels/message-lifecycle.ts`. These six modules total 566 lines / 19,534 bytes. - Import provider modules directly. Follow this provider-folder convention for future extractions. - Preserve exact actor IDs, edit hashes, timestamp provenance, and Telegram message identity rules. - Narrow two input types to the Teams parser method and the retained delivery fields actually read. - Reduce `chat-channels.ts` from 39,155 lines / 1,509,090 bytes to 38,643 lines / 1,491,703 bytes. - Record five ranked extraction candidates and verification evidence in the dated plan. ## Verification - The original extraction passed complete CI and 5/5 review at `cbba30a526`. Those results are historical; the updated head is `90ac517e6c310c8cf194dbbd668006f740e58f3a`. - Structural comparison: all 21 moved declarations match the base after normalizing exports and two type-only changes. All remaining non-import declarations, including the complete service body, match the base. - Provider-folder update: the same 48 public service integration cases passed locally before and after the move on PR #15823. They cover Slack/Discord revision identity, Teams edits, GitHub edits, Telegram rich messages and provider chronology. - All 22 message declarations retain identical bodies; the service changes imports only. The four dependent extractions rebased without conflicts. - Final-stack workspace `pnpm -r typecheck` passed. Module-boundary and whitespace checks passed. - Final-stack `pnpm build` passed. The fresh `pnpm test:run` was interrupted after PostgreSQL startup failures recurred. An isolated `native-status-arbiter-corpus.test.ts` run failed during database initialization after five attempts; all 45 tests skipped. All 32 host shared-memory slots were occupied. The full local gate remains unverified; only the task-owned run was stopped. - Greptile rated updated head `90ac517e6c310c8cf194dbbd668006f740e58f3a` 5/5 with no inline review threads. - Updated-head CI passed: 53 successful checks and two skipped checks, including all chat integration shards, typecheck, build and browser suites. - Tests use disposable databases and fixture provider transports. No live third-party execution is claimed. ## Risks - A wrong module import or changed revision identity could affect message admission. Existing service-path tests and the declaration comparison cover those risks. - Authentication, company-scoped transactions, leases, background workers, and shutdown remain in the original service. - The service closure remains large. Resource reconciliation is the recommended next extraction. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, local code execution, and repository tools. The exact runtime model ID and context-window size are not exposed in this session. No separate planning or review agent was used. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
e733bddc45 |
perf(chat): stop polling provider action and session sync queues (#15822)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Chat stores pending provider actions in durable database rows. > - Three action queues still scan every second when empty. > - These scans keep idle databases active. > - This pull request wakes those queues after a commit or at their next deadline. > - Empty queues stop querying while existing recovery rules remain in place. ## Linked Issues or Issue Description Refs #15808, #15802, #15625. Related sleep work: #15750, #15757. **What existing behavior does this improve?** Provider messages and notices, accepted GitHub webhook receipts, and Slack session status synchronization. **Current behavior** Chat maintenance scans these three queues every second. It also rechecks paused Slack sync rows every 30 seconds. **Proposed behavior** Reuse the transaction-aware action workers and existing chat_actions rows. Wake after commits. Restore unfinished work on startup. Use stored retry and stale-claim deadlines. Stop scanning when empty. Park paused Slack sync rows until an endpoint change. ## What Changed - Add three topics to the existing action worker registration. No tables, migrations, triggers, or external services. - Signal producers, claims, retry updates, terminal settlements, and operator resolution inside their owning transaction. Provider I/O remains outside transactions. - Share pending-state and deadline predicates between dispatch and scheduling. Exclude terminal history and uncertain provider sends. - Preserve GitHub receipt attempt fences and provider-send quarantine. Preserve Slack's 30-minute refresh while a session is processing. - Remove these workers from periodic app maintenance. Update the sleep inventory and add regression coverage. ## Verification - Passed: 13 focused tests across scheduler, app wiring, and real PostgreSQL integration. Covers actual commit wakes with deferred fast paths disabled, GitHub retries and startup recovery, stale-send quarantine, Slack publication-to-sync delivery, paused deadlines, and idle queues. - Passed: pnpm typecheck. - Passed: full chat integration and related coordinator suites, **1,274 tests across five files**. - Passed: pnpm build. - Greptile: **5/5**, no actionable findings, completed on `dc284cd275e5f6df624d60b27954421f2bcdbee2`. - Hosted CI: **54 checks passed**, two intentionally skipped Storybook checks, no failures or pending checks on `dc284cd275e5f6df624d60b27954421f2bcdbee2`. Provider responses are simulated. PostgreSQL, transactions, service dispatch, and scheduling are real. No live Slack or GitHub App was used. ## Risks - Writers must emit the existing process-local transaction signal. Independent database clients and direct SQL still need explicit integration or startup recovery. - Accepted GitHub receipts are covered. Finding callbacks GitHub never delivered still uses the separate provider recovery lane. - Other chat maintenance and persistent transports still run. This does not establish whole-instance sleep. - Existing claim, revision, credential, and authorization checks remain authoritative during concurrent foreground and scheduled dispatch. ## Model Used OpenAI Codex (GPT-6), with repository inspection, code execution, and automated tests. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b1ebe3de3c |
perf(chat): wake action queues from commits and deadlines (#15808)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Chat keeps durable rows for provider actions and setup messages. > - Five action queues still scan the database every second when empty. > - Empty scans add idle database traffic and prevent cost savings from sleep. > - This pull request wakes these queues when their writes commit or their next deadline arrives. > - Existing rows retain retry and restart recovery. Empty queues stop scanning. ## Linked Issues or Issue Description Refs #15802, #15625, #15750, #15757. Related allocation work: #15153. **What existing behavior does this improve?** Idle chat reconciliation for Slack Board messages, Slack slash-command task starts, Slack setup verification messages, receipt reactions, and Slack session stops. **Current behavior** The app runs these five queue scans through chat maintenance every second, including when no work exists. **Proposed behavior** Each queue has an independent worker on the existing scheduler. Producers and foreground claim/retry/settlement writes announce work inside their database transaction. The worker wakes after the outer transaction settles. Startup restores durable work. Shared dispatch and deadline predicates select real retries and abandoned claims. Empty queues disarm. **Subsystem affected** Server chat services. No schema or migration changes. ## What Changed - Register five action workers alongside the three delivery workers from #15802. Remove their scans from periodic app maintenance. - Share action eligibility between dispatch and deadline selection. Park paused Board messages and task starts until endpoint changes. Preserve uncertain-send quarantine. - Wake setup verification after account, welcome, registration, or authenticated callback changes. Exclude prerequisites that need another event. - Persist a retry time for failed provider-confirmed task admission. Its own commit notification cannot cause an immediate retry loop. - Reuse the existing transaction signals and scheduler registration code. Provider calls remain outside database transactions. - Update the instance-sleep inventory and add scheduler and PostgreSQL regression coverage. ## Verification - Passed: 37 scheduler, coordinator, and app-wiring tests, including an idle hour with no further scans or timers. - Passed: seven focused PostgreSQL chat cases. These cover deadline eligibility, startup recovery, outer-commit wakes, actual producer signals, and signed-callback verification without maintenance polling. - Passed: `pnpm typecheck`. - Passed: full chat integration suite and related publication/coordinator tests, **1,278 tests** across six files, including **1,228 chat integration cases**. - Passed: `pnpm build`. - After the review fix, seven focused PostgreSQL integration cases and the server typecheck passed again. Deadline and dispatch queries now exclude completed action history. - Greptile: **5/5** on `35a979fce6bb9ab910fab3373ec8e537fc2d01a9`, with the prior finding resolved and no new findings. - Fixed a CI timing failure in the GitHub mention integration test: asynchronous admission now has an explicit ten-second assertion deadline instead of the default one second. The failure reproduced locally; all five mention variants and all 398 cases in the matching CI shard pass after the fix. - Hosted CI passed on `35a979fce6bb9ab910fab3373ec8e537fc2d01a9`: **54 successful checks**, two intentionally skipped Storybook checks, no failures or pending checks. Provider responses are simulated in the integration suite. PostgreSQL, transactions, service dispatch, and scheduling are real. No live Slack workspace was used. ## Risks - Every producer that changes runnable state must emit a transaction signal. This change covers the five queues and their foreground dispatch/retry paths. Direct SQL and independent DB owners still need explicit integration or startup recovery. - Missing retry or claim deadlines can strand work. Tests compare the dispatch and deadline behavior, including paused and uncertain states. - Other provider maintenance, sockets, and scheduled jobs remain. This change does not establish full instance sleep. - No new tables, migrations, or provider credentials are required. ## Model Used OpenAI Codex (GPT-6), with repository inspection, code execution, and automated tests. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
a7dd5284b5 |
feat: add company fast-response acknowledgements (#15748)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Human messages start agent work through task, chat, and external-channel intake. > - Agent startup can delay the first visible response. > - A small direct model call can acknowledge the request while normal work starts. > - This response must remain separate from evidence that the agent answered or completed work. > - This pull request adds optional company-wide fast responses with durable receipts, access checks, and cost accounting. > - Users receive prompt acknowledgement without changing the agent execution path. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting: database, shared contracts, server orchestration, connections, and UI. **Problem or motivation** Users can wait for an agent to start before they receive a contextual response. Generic progress messages do not confirm what the user asked. An acknowledgement must not falsely complete work or satisfy an unanswered turn. **Proposed solution** Add a disabled-by-default experimental fast-response model using an existing shared API connection. Generate one short acknowledgement for each accepted human turn. Use the existing agent identity and external publication outboxes. Retain platform provenance and account for the inference independently. **Alternatives considered** Running the acknowledgement through the agent runtime adds startup latency. Restricting implementation to OpenRouter leaves other existing API connections unsupported. This change supports all existing API connections and uses OpenRouter for live verification. **Roadmap alignment** This extends existing agent communication and connection settings. ROADMAP.md and open pull requests were checked. No duplicate fast-response implementation was found. The maintainer supplied the feature plan directly. ## What Changed - Add Experimental fast responses to instance settings. Keep the feature off by default. Enforce the flag at intake, dispatch, and publication. - Move Decision model and Fast response setup to company Settings → Connections when the experiment is enabled. Place Connections below Environments. Separate the model sections with clear headings and a divider. Keep Decision model in General when the experiment is off. Route Costs setup links to the available settings page. - Make the acknowledgement prompt a multiline template string. Ask for a brief, positive response in the user’s language. - Add settings, connection/model selection, sponsorship, fixed-sample testing, and Costs history. - Add a Vercel AI SDK text service for existing native, routed, Bedrock, and local API connections. - Add durable per-turn requests, a bounded worker, a three-second admission deadline, and one inference attempt. - Integrate task creation, task and agent chat, steering, queued follow-ups, experimental board chat, shared chat intake, and email. - Preserve receipt provenance and exclude receipts from completion, recovery, interaction resolution, and agent wakeups. - Recheck authorization, source validity, real replies, budgets, and destination binding before publication. Preserve accounting for suppressed or uncertain outcomes. - Add provider contracts, database race tests, channel outbox tests, UI tests, Stories, and documentation. Keep decision-model execution unchanged. ## Verification - Local `pnpm -r typecheck`, `pnpm build`, and UI token gates pass after rebase. The UI typecheck and build also pass after the final navigation fixes. All 37 focused navigation tests pass. The first full local `pnpm test:run` invocation reported seven chat failures. All seven passed in isolated reruns after fixture updates and host cleanup. This invocation was stopped after the full final-head CI suite passed. - Initial local database tests hit macOS shared-memory exhaustion. A diagnostic confirmed `shmget: No space left on device` with the system limit of 32 IDs. Three abandoned, unattached PostgreSQL IPC headers were reclaimed. The isolated rerun passed all 31 fast-response and channel tests. The two additional Slack regression cases also passed in a separate rerun. No active database was stopped. - UI token gates pass. Provider contract tests cover all supported API connection types. Fast-response tests cover uniqueness, authorization, budgets, expiry, cancellation, restart, real-reply races, and the experimental flag. - The test drive verified that disabling the experiment hides Connections and redirects its direct URL. Enabling it restores the saved OpenRouter setup. After restart on the final commit, the OpenRouter settings sample returned “Sure, I’ll take care of fixing the border around the settings panel.” in 428 ms. It used 260 input and 31 output tokens and recorded $0.0000576 in reported cost. - Earlier live OpenRouter verification produced a receipt in 1.013 seconds for a new task. The real agent then supplied its substantive answer. A separate settings test took 1.34 seconds, used 246 input and 23 output tokens, and recorded $0.0000361. - Live Slack verification on final commit `24016fa525961ebc7a4acffdc5019ce123970549` passed for a fresh initial task and a follow-up in a disposable bot DM. The initial acknowledgement appeared 2.405 seconds after the Slack message and 1.413 seconds after durable acceptance; the follow-up appeared in 2.322 seconds and 1.160 seconds respectively. The recorded generation/settlement durations were 898 ms and 697 ms. The initial call used 291 input / 39 output tokens and cost $0.00006705; the follow-up used 281 / 47 and cost $0.00007035. - The Slack acknowledgements retained the assigned agent identity and `origin: fast_response`, source-turn references, and no fabricated run ID. A status snapshot after the initial receipt showed the task still `in_progress` with its real execution run. The agent then read the CSV fixture and correctly reported two ready items, two blockers, and their owners. Both replies stayed in the originating DM, and no duplicate generic working message followed the delivered contextual acknowledgements. The `new` command started a fresh conversation session without generating a fast response. - An earlier eligible Slack turn generated a response but suppressed publication. Its reported cost was retained, generic progress remained, and the real agent completed the requested result. This is recorded separately from the two delivered acknowledgements; the history did not expose a precise suppression reason. - Slack verification used real signed provider events, the existing intake/publication paths, and a user-approved temporary webhook-only HTTPS tunnel. Subscriptions were limited to direct-message events. The test bot was paused and the tunnel stopped afterward. Live channel/group-thread and GitHub journeys remain unverified; their mocked tests cover intake, destination binding, publication, and continued underlying work. - Greptile reviewed final commit `24016fa525961ebc7a4acffdc5019ce123970549` at 5/5. Both new review findings are fixed and all threads are resolved. [Final-head CI run](https://github.com/paperclipai/paperclip/actions/runs/38060015730) passed. This includes grouped server/chat/workspace tests, serialized suites, runner checks, browser journeys, typecheck, build, release registry, policy, and the canary dry run. - Manual check: enable Experimental fast responses. Open company Settings → Connections. Select a shared API connection and model. Save and use Test response. Submit a task message and confirm that its receipt does not complete the task. ## Risks - The migration adds receipt and configuration tables plus accounting references. It uses idempotent statements and follows the current migration sequence. - A slow provider, authorization change, or real-agent reply can suppress an acknowledgement. Existing progress feedback remains available. - Unknown provider billing retains a reservation until reconciliation. External deliveries with uncertain outcomes must not be blindly repeated. - Live Slack initial-task and follow-up DM journeys pass. Live Slack channel/group-thread and GitHub journeys remain unverified. The PR remains a draft and records these gaps. Final-head repository CI and automated review pass. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository tools, code execution, and browser interaction. The runtime does not expose an exact model snapshot ID or context-window size; these are not asserted. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
19e9facc5b |
perf(chat): wake delivery queues from commits and deadlines (#15802)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Chat connectors store incoming messages and outgoing publications in durable queues. > - The app checks these queues every second, even when they are empty. > - Empty scans keep the database active and hinder instance sleep. > - This pull request wakes three queue workers after transactions settle and at known retry or recovery deadlines. > - Empty queues stop scheduling checks. Existing rows retain their ordering, retry, and recovery rules. ## Linked Issues or Issue Description **What existing behavior does this improve?** Idle database activity from incoming chat deliveries, outgoing publications, and Slack upload receipt recovery. **Subsystem affected** `server/` — chat delivery and background work scheduling. **Current behavior** The app's one-second chat timer scans the three queues together with provider and action maintenance. Empty queues continue to query PostgreSQL. **Proposed behavior** Register three independent workers with the existing delivery coordinator. Producers announce work inside their database transactions. Commit wakes the corresponding worker. Startup restores outstanding work; persisted retries and stale claims supply the next deadline. An empty queue has no recurring scan. **Reason and benefit** Remove avoidable queue reads without requiring a new table, an external scheduler, or a persistent PostgreSQL listener. **Breaking changes** No schema or public API change. Work notifications are scoped to the app's shared database owner. Direct SQL and independent database roots do not send these notifications; startup still scans durable work. **Additional context** Refs #15625, #15750, and #15757 for the preceding sleep work. Related: #15153 reduces chat query allocation while retaining polling. This PR changes when the three queue workers run; it does not add query caching. ## What Changed - Register independent incoming delivery, publication, and Slack receipt workers on the shared scheduler. - Add transaction work signals at queue writes, endpoint state changes, and action transitions that unblock publications. Keep provider I/O outside the added transactions. - Restore deadlines from durable retry times, abandoned claims, and publication lease expiry. Share publication and receipt eligibility rules between dispatch and deadline queries. Respect incoming conversation order and lifecycle dependencies. - Exclude publications blocked by unresolved Slack tool sends. Wake them when the tool receipt changes. - Wake publication dispatch when an endpoint send finishes so free slots refill. Preserve per-endpoint concurrency, conversation order, and conservative handling of uncertain sends. - Wake receipt recovery when a stale publication becomes `delivery_unknown`, and wake queues when a provider connection recovers. - Commit interaction publications with their callback tokens so dispatch cannot see an incomplete card. - Keep provider runtimes, other action outboxes, milestone and wake-notice projection, Teams protocol maintenance, GitHub recovery, and Slack session synchronization on their existing maintenance cadence. This PR does not make the whole chat subsystem idle. - Update the instance sleep inventory with this partial migration and its remaining work. ## Verification - All 1,225 PostgreSQL chat integration cases passed across the three hosted chat shards. These cover retry and lease deadlines, blocked followers, unresolved Slack sends, provider recovery, commit visibility, and endpoint slot refill. - 32 local app-wiring, queue-worker, and delivery-coordinator tests passed after updating the wiring assertion for event-driven dispatch. Fake timers cover an hour of idle time without queue scans. - Related publication, interaction, receipt, and wake-notice tests passed locally. The 13 interaction integration cases include atomic rollback when callback-token storage fails. - Local `pnpm typecheck`, `pnpm build`, and final server typecheck passed. All hosted checks passed on the final commit, including build, typecheck, test shards, release registry checks, and the canary dry run (54 successful checks; two Storybook checks skipped for this backend change). - The last local PostgreSQL rerun was skipped because the embedded database startup probe failed after five attempts. The hosted PostgreSQL cases ran successfully; their skips only partition cases across shards. - `git diff --check` passed. Greptile is 5/5 on the final commit with no unresolved findings. ## Risks - Every producer that makes queued work eligible must send a transaction work signal. The tests exercise commit visibility, concurrent wakes, worker failures, and restart recovery. Future direct SQL writers must participate in this contract. - The existing database work-signal layer reconciles uncertain transaction outcomes. This PR adds no work-signal table or schema migration. - Provider and action maintenance still polls. Further changes are required before an idle chat-enabled instance can sleep. - Tests use real PostgreSQL with simulated provider responses; they do not send messages through live provider accounts. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, tool use, and code execution. The exact serving model ID and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] 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> |
||
|
|
3ec7309d91 |
feat(voice): add experimental Speko task connection runtime (#15727)
First PR: runtime. UI: #15728. Qualification: #15729.
## Thinking Path
> - Paperclip manages agent work through tasks and governed connections.
> - Chat connections already bind external conversations to those tasks.
> - Speko handles voice and telephony, while the selected Paperclip
agent does the work.
> - A call needs durable session authority, ordered follow-ups, and safe
result delivery.
> - This PR adds an explicit voice transport to the existing connection
runtime.
> - The UI and qualification suites follow in linked PRs. Speko stays
experimental.
## Linked Issues or Issue Description
**Problem or motivation**
Phone and browser voice conversations cannot use the chat connection
task lifecycle. A separate voice runtime is needed to preserve task
authority, retries, and reply history.
**Proposed solution**
Add company-scoped voice sessions, signed callbacks, durable replies,
inbound intake, and an agent-facing outbound-call tool. Reuse existing
tasks, queues, secrets, and publications.
**Roadmap alignment**
This extends the experimental chat connector entry points under Agent
Chat and Connected Apps. The project owner requested this feature.
Refs #11418 for the original provider catalog proposal. This
implementation uses the newer chat connection infrastructure rather than
an MCP catalog-only integration. Refs #15721 for remote OpenCode
startup.
## What Changed
- Add additive voice schema, shared contracts, session APIs, and
provider callbacks.
- Bind browser, inbound, and outbound sessions to an endpoint, task, and
selected agent.
- Add low-trust guest intake in an explicitly selected sandbox and keep
ordinary approval rules.
- Submit task work through session-scoped tools and push approved
replies through Speko POST /v1/calls/{id}/messages.
- Distinguish provider acceptance from confirmed spoken playback.
Reconcile reports without downloading recordings.
- Add protocol, migration, persistence, provider, and
delivery-diagnostic tests.
## Verification
- Master
|
||
|
|
ed2c22ea8c |
feat(connections): simplify dedicated GitHub App setup (#15416)
## Thinking Path > - Paperclip manages agent work and the tools each agent can use. > - GitHub bots need their own App identity and restricted repository access. > - Manual App configuration and repeated setup gates make that connection hard to finish. > - GitHub can create an App from a manifest, but people must approve creation and repository access. > - Each Paperclip stack should own configuration, credentials, signature verification, and task admission. > - This change uses Cloud as an encrypted callback and event gateway, then completes setup in the stack. > - GitHub review bots have their own experimental setting. Chat connector opt-in does not control them. ## Linked Issues or Issue Description **What existing behavior does this improve?** Dedicated GitHub App setup, bot settings, and task-scoped GitHub replies. **Current behavior** Users must configure an App, copy credentials, repeat repository selection, and complete manual verification gates. Review settings are hard to scan. Mentions in descriptions can be missed, and automatic completion text can produce an extra GitHub comment. **Proposed behavior** Choose an agent and connect GitHub under a personal account or organization. GitHub asks for creation and installation consent. Paperclip resumes the same draft, stores secrets locally, imports access, verifies delivery, and opens Settings. Each accepted request has one editable App-owned comment for progress and results. Review assessments produce deterministic checks for the reviewed commit. **Breaking changes** GitHub bots require their own default-off experimental opt-in. The setup-method and delegated-agent screens are removed. Per-person automatic-run flags remain readable but are replaced by author filters. Existing connections, direct webhooks, saved restrictions, and manual existing-App recovery remain supported. Companion gateway: https://github.com/paperclipai/paperclip-cloud/pull/688 (merged). The roadmap and related PRs were checked; no duplicate dedicated-App wizard was found. ## What Changed - Add an independent **GitHub review bots** setting across the catalog, routes, identity admission, and task controls. Existing bots continue running when the UI setting is off. - Replace setup with Choose agent and Connect GitHub. Support personal and organization owners, inline low-trust conversion, saved drafts, known organization suggestions, automatic completion, and same-App recovery. - Keep manifests, OAuth PKCE, credential exchange, vault storage, installation verification, and original webhook-signature validation in the stack. Use the Cloud sealed gateway for public callbacks and outbound local delivery. - Add resumable owner metadata in migration 0323. Retry a failed registration renewal through the same durable replacement rather than creating another App route. - Support authorized mentions in issue and PR bodies, comments, inline comments, and review summaries. Preserve attachments, edited-source identity, duplicate protection, and lifecycle invalidation. Filter requests explicitly addressed to another connected bot. - Give agents task-scoped review, comment, and update tools. Update one working comment through progress and final output. Close coalesced requests and recover delayed acknowledgements, including deleted earlier working comments. Preserve automatic replies for legacy connections without saved review configuration. Preserve partial publication evidence and quarantine uncertain automatic fallbacks without blocking Board messages or questions. - Reorganize Settings and Access with rich slash-skill instructions, numeric passing scores, clear automation controls, formal-review tooltips, member and contributor sections, and verified App branding links. Preserve invalid score drafts and automation choices across tabs. - Paginate repositories in 20-row batches with search and a true connection-wide toggle. Batch verification at GitHub's 500-ID token limit. Keep saved repository overrides while hiding their editor. - Give each review a detail URL that remains usable beyond the newest 100 records. Synchronize the manager OpenAPI contracts and add recovery, authorization, UI, and browser regressions. - Reconcile the current master branch and retain its agent avatar, feature catalog, and extracted heartbeat preparation code. Preserve a saved test-drive port and recover from an occupied high port. ## Verification - Focused UI, independent experimental-setting, and CLI tests: 199 passed. - `pnpm -r typecheck`, `pnpm build`, and `pnpm check:token-gates` passed. The broad local Vitest attempt was interrupted after resource timeouts and stale expectations; the affected regressions passed focused reruns. The latest-head full CI matrix passed, including all browser shards, server/chat suites, builds, typechecking, canary packaging, and Docker context integrity. A Docker Hub 429 required a CI retry; it passed without changing the code. - Final review repairs: 127 attachment/event tests and server typecheck passed. All 13 final integration regressions passed under the normal CI timeout, covering legacy reply compatibility, deleted coalesced comments, inline-only review completion, progress edits, and native final recovery. Restart-safe description/review attachments passed the attachment suite. - Final regressions: four reply/lifecycle tests, both native GitHub wait tests, 171 feature-gate/reply-contract tests, the routed review preview, and five scheduler/reply regressions passed. The final fixture repair also passed all six setup-continuation cases and all three complete chat-test shards in CI, covering terminal receipts and retries under the normal CI timeout. One loaded-host receipt run exceeded its local timeout; the exact case passed in an isolated rerun and the complete CI shard. - GitHub integration tests cover personal and organization setup, retry recovery, edited mentions, attachment provenance, coalesced requests, delayed acknowledgements, partial review writes, old review URLs, and company boundaries. - Browser qualification: both GitHub journeys, all five provider setup/management journeys, and the GitHub uncertain-send recovery journey passed. GitHub setup, reconnect, and task replies run with chat disabled; chat enabled alone cannot expose GitHub bots. The disposable qualification database was removed after testing. - Earlier live qualification verified App-owned issue replies, native slash-skill invocation, progress comment edits, and a 5/5 PR review with a passing current-head check in the dedicated permissions-smoke repository. These live checks did not use personal credentials as bot execution authority. ## Risks - Deploy the merged Cloud gateway protocol before the stack update. Each callback and encrypted event must retain the original instance and tenant binding. - Migration 0323 uses idempotent column additions for test installations that already applied the earlier draft migration number. - A verified connection does not prove runtime isolation or a completed review. Runtime checks remain separate. - Required merge checks must be configured in GitHub. A passing numeric score does not formally approve a PR; approval and request-changes tools remain opt-in. - Existing-App credentials cannot silently renew an uncertain manifest exchange. Recovery preserves the existing App, draft, connection, and agent. - Repository changes save immediately. Global toggles affect all currently available repositories, including unloaded rows, without granting new installation access. - A failed or uncertain tool write suppresses automatic fallback text; the governed outbox retains its evidence. Deleted or replaced response comments are not recreated through a personal credential fallback. - GitHub logo upload remains an optional human action in GitHub App settings. Runtime provisioning, delegated setup, screenshot publication, and production push delivery remain deferred. ## Model Used OpenAI Codex, based on GPT-6, with tool use and code execution. The exact runtime model identifier and context size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub references) - [x] My branch name describes the change and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass (focused suites; complete test matrix is checked in CI) - [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> |
||
|
|
00d944f96c |
fix(chat-channels): resume follow-ups after Slack Stop (#15737)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Chat channels let verified users stop an agent and send another message from Slack. > - Native execution needs the stopping user's identity to recognize a deliberate Stop. > - Slack omitted that identity, so a stopped run could create a recovery hold. > - A pending AI login request for another user could then block the new message. > - This pull request records the verified stop actor and scopes AI login waits to the current user. > - Users can start a fresh turn after a verified Stop while access and approval gates remain in force. ## Linked Issues or Issue Description **What happened?** A user stops a native run from its bound Slack thread. Slack confirms the Stop. The user sends a follow-up and receives a queued acknowledgement, but execution does not start. The run can acquire a recovery hold. A pending AI login request addressed to another user then blocks explicit continuation. **Expected behavior** An acknowledged operator Stop ends the current response. A new authorized user message starts through normal admission after the previous execution has stopped. An AI login request for another user stays pending but does not gate this user's turn. Tool access, approvals, unknown identities, and unconfirmed cleanup still block execution. **Steps to reproduce** 1. Start a native agent run in a Slack thread with a pending AI login request addressed to a different user. 2. Stop the run with the signed Slack Stop action. 3. Send a new message from a verified linked user. 4. Observe the recovery hold and the pending-decision message on the saved follow-up. Refs: #15421 for the related verified linked-user authority path. That change separates guest and trusted tasks; this change handles cancellation and login wait scope. ## What Changed - Pass the verified Slack user's identity to canonical run cancellation. - Scope AI login waits by the current run's responsible user, with a company-scoped lookup. - Use the same wait predicate for explicit continuation, native execution, and recovery decisions. - Admit already-saved native follow-ups posted after Stop through the existing continuation checks. Keep pre-stop and delivered messages held. - Keep pending cards and their authorization state intact. - Add regression tests for signed Slack Stop, fresh-turn admission, and same-user, unknown-user, tool-access, and company-boundary gates. - Give the two affected database setup hooks the standard 90-second budget. - Document Slack Stop and user-scoped AI login waits. ## Verification - Red: signed Slack Stop omitted the cancelling user; direct continuation and already-saved post-Stop continuation both returned `null`. - Green: 57 continuation/audience checks passed, including legacy operator Stops, pre-stop input, delivered input, same-user login, unknown identity, company boundaries, cleanup, ownership, pauses, and approvals. - The combined signed Slack Stop and original gate check passed: 39 tests. - Existing native question/completion suite: 33 tests passed. - `pnpm -r typecheck` passed. - `pnpm build` passed. - Rebased regression check: 18 tests passed on current master. The reviewed database-support setup change passed all 7 audience checks. - Full latest-head CI passed, including all server, chat, package, serialized-server, Runner, browser, build, and canary gates. - The duplicate local `pnpm test:run` was stopped after the full CI matrix passed. It was slow on the contended host; no failure had been reported. The focused reproduction command is: ```sh pnpm exec vitest run server/src/services/issue-question-context.test.ts server/src/services/explicit-native-continuation.test.ts server/src/__tests__/chat-channels.integration.test.ts --fsModuleCache --testTimeout 60000 -t 'AI connection wait audience|scopes connection waits|resumes an already-saved follow-up|durably retries a signed Slack session stop' ``` - Manual evidence: inspected the bound thread's cancelled run, queued messages, recovery hold, and login card. The staging deployment has not been changed. ## Risks - AI login wait behavior changes only when both the addressee and current responsible user are known and differ. Missing identity retains the gate. - Starting a new turn does not grant access or answer the old card. Credential selection still uses the new run's authority. - Process, remote cleanup, recovery, task ownership, pause, budget, and approval checks remain in place. - No schema migration or public API change. ## Model Used OpenAI GPT-6 through Codex, with reasoning, repository inspection, browser inspection, and code execution. The exact runtime model ID and context window are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
3fc64c5156 |
feat(slack): add Require at-mention setting (#15612)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Slack messages can create tasks and continue existing tasks. > - A reply in a subscribed thread can start agent work without a new mention. > - Some users want to control each reply with an explicit bot mention. > - This pull request adds a Require at-mention setting to Slack app settings. > - The setting checks new messages and queued messages before they start work. ## Linked Issues or Issue Description **What existing behavior does this improve?** Slack app settings and the rules that admit inbound messages. **Subsystem affected** Server, UI, database, and shared API contracts. **Current behavior** After the bot joins a thread, an ordinary reply can wake the agent. Direct messages do not need a bot mention. **Proposed behavior** Add Require at-mention below Allow direct messages. When enabled, each channel message, thread reply, and direct message must mention the bot. Direct messages must also be allowed. **Reason and benefit** Users can prevent ordinary conversation from starting agent work. **Breaking changes** New Slack connections require a bot mention by default. Existing connections keep their saved setting. Work that has already started is not cancelled. **Additional context** A search for existing at-mention PR titles found no duplicate. ## What Changed - Add the endpoint field, schema validation, API response, and UI toggle. New Slack connections enable the setting. - Add an idempotent database migration and generated metadata. Renumber it to 0321 after current master. - Check the current setting at inbound admission, task mutation, and the first heartbeat queue claim. - Keep Slack tool access and recovery for already-running work when the setting changes. - Cancel queued batches that contain an unmentioned input, including coalesced messages. - Dispatch promoted follow-ups after the scheduler releases its agent start lock. Preserve these checks in the new queue and run-control modules. - Filter unmentioned messages without retaining their content. - Keep provider-message deduplication and existing access checks. - Add thread, DM, duplicate-delivery, queued-message, and new-connection default regression tests. - Document the setting and its scope. ## Verification - Previous head `16791bb7`: typecheck, build, all server shards, Runner checks, and E2E passed. Two chat shards failed in three fixtures that used unmentioned Slack messages. - Update setup follow-ups to mention the Slack bot. Disable the mention rule explicitly in the callback ordering test, which tests ordinary subscribed replies. - Previous local checks passed: six Slack integration cases, all 46 durable chat scheduler tests, all 24 queue/run-control tests, migration safety, and UI token gates. - Greptile reviewed `16791bb7` with 5/5. All review threads are resolved. - Head `53163c20f`: all five focused integration cases passed. These cover all three prior CI failures and both default-on channel/DM cases. Fresh CI and Greptile are running. - Full local recursive typecheck, build, and repository tests were not repeated for this fixture-only change. CI supplies these checks. - Manual check: create a Slack connection. Require at-mention must be on. An ordinary thread reply or DM must not wake the agent. A bot mention must wake it once. Disable the setting and confirm ordinary replies work again. ## Risks - The migration adds a non-null boolean with a false default. Apply it before the new server runs. - The setting also applies to DMs. The UI help text states this. - Enabling it blocks queued unmentioned work but does not cancel a run that has already started. - Full local verification is limited by the environment constraints above; latest-head CI must pass before merge. ## Model Used OpenAI GPT-6 (Codex agent), with reasoning, tool use, and code execution. The runtime does not expose a more specific model version or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [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> |
||
|
|
f47614046d |
fix(slack): upload agent avatars directly during Cloud setup (#15566)
## Thinking Path > - Paperclip helps people manage AI agents for work. > - Slack setup creates a dedicated bot for an agent. > - The setup should upload that agent's avatar. > - The current upload asks Slack to fetch an image from the board origin. > - Cloud requires a tenant session at that origin, so Slack receives HTTP 401. > - This change renders the PNG on the server and uploads the file directly. ## Linked Issues or Issue Description Refs #15413. **What happened?** Automatic Slack setup left the app and bot with default icons on Cloud staging. An unauthenticated request to the exact avatar URL returned HTTP 401 with `tenant_session_required`. Local setup did not expose this Cloud ingress requirement. **Expected behavior** New Slack bots receive the assigned agent's 512-pixel avatar with the Paperclip dark background. **Steps to reproduce** 1. Create a Slack app through automatic setup on a Cloud tenant. 2. Complete installation. 3. Inspect the bot avatar in Slack. The previous URL-based upload cannot fetch the image without a tenant session. ## What Changed - Render the assigned agent's preset PNG with the existing bounded worker pool. - Send PNG bytes as multipart `file` data to `apps.icon.set` instead of passing a board URL. - Keep the temporary token in the Authorization header. Let fetch set the multipart boundary. - Recheck management permission and credential-lease ownership after rendering. Close the worker pool during chat service shutdown. - Cover actual PNG dimensions, uploaded bytes, failure recovery, and secret-safe responses. Update deployment documentation. ## Verification - Passed: 84 focused tests across automatic Slack registration and on-demand agent avatars. - Passed: full repository build. - Passed: full repository typecheck. All 54 current-head GitHub checks passed, including the complete test matrix, all browser shards, build, typecheck, canary, and security checks. Greptile completed on `79e79f6fc` with 5/5 and no actionable findings or open review threads. - The Cloud fetch failure was reproduced without browser credentials. No Cloud access rule was changed. - A real Slack upload with this new path still requires deployment and a fresh automatic setup. Existing apps retain the manual avatar-upload fallback. ## Risks - The renderer can time out or Slack can reject the upload. Both failures preserve the saved app and leave installation usable. - The renderer adds a bounded, lazy worker pool to Slack registration. Shutdown closes it. - No migration, bot permissions, credential retention, or Cloud authentication behavior changes. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository tools, code execution, and browser inspection. The runtime does not expose a more specific authoring model ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d66acb7ac1 |
feat: automate Slack bot app setup and installation (#15413)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Chat connectors give each agent a customer-owned bot and task-backed conversations. > - Manual Slack setup requires app creation and copying durable credentials. > - Operators need a shorter setup that an assisting agent can use safely. > - This pull request creates the app through Slack's Manifest API and installs it through OAuth. > - Durable registration state supports recovery without creating another app. > - A four-screen wizard, automatic avatar upload, and OAuth account linking reduce setup work. > - Connector settings and per-turn tool guidance support daily use after installation. ## Linked Issues or Issue Description **Subsystem affected** Native Slack bot setup, company secret storage, chat connector management, and agent tool guidance. **Problem or motivation** New Slack bots require manual app creation and copying a signing secret and bot token. Interrupted setup can create duplicate apps. The setup and management screens contain unnecessary controls. Agents also need guidance for native questions, files, thread replies, and governed Slack actions. **Proposed solution** Use a temporary app-configuration access token to create a customer-owned app. Save durable secrets in the vault. Bind OAuth to the initiating actor, company, endpoint, registration revision, scopes, and configured origins. Preserve manual and existing-app recovery. Link the installing user's account, send a welcome DM, and advance from saved server evidence. Keep request-URL recovery instructions available if automatic connection detection waits. **Alternatives considered** The Slack CLI adds installation requirements. Socket Mode changes transport. A shared Paperclip-owned app changes app ownership. These alternatives are outside this change. **Roadmap alignment** This extends existing chat connectors and secrets capabilities. Related public work: #14037 and #13954 cover Slack MCP prerequisites and user OAuth. No duplicate bot-registration PR was found. ## What Changed - Share one reviewed manifest builder between automatic registration and manual setup. - Add replay-safe migration 0318 and company-bound registration state with vault references and uncertain-creation recovery. - Add registration, installation, callback, and resume APIs with short-lived, single-use OAuth state. - Save installation credentials before downstream checks and preserve bot identity constraints. - Reduce automatic setup to four screens. Keep advanced app details, manual recovery, and existing-app setup. - Upload the agent avatar with the Paperclip dark background. Link the OAuth installer's account and send setup DMs. - Show agent and connector-owner avatars. Simplify settings, access, and conversation screens. - Discover joined Slack channels and enable them by default. Start a task from a bare mention and admit same-thread follow-ups. - Refresh Slack tool guidance each turn. Add native-form, file, approval, and delivery regressions plus manual model probe definitions and sanitized acceptance records. - Update deployment/database docs, OpenAPI, redaction, removal cleanup, production Storybook stories, and provider browser tests. - Merge current master and move the registration migration after its latest migration without rewriting published commits. The completed Slack success view intentionally has a single centered **Done** action and no **Save & exit**, as explicitly requested by the product owner. `DESIGN.md` records this exception; unfinished setup steps retain the aligned wizard footer. ## Verification - Passed after the master merge: repository typecheck, full build, Storybook build, design-token gates, module-boundary gates, and migration generation. - Passed: all 352 focused Slack deterministic tests and all 14 affected provider browser tests. Browser tests use controlled provider fixtures and a separate throwaway instance. - Passed on current head `c5d01e0e2`: the complete GitHub test matrix (general server, chat, all workspaces, serialized server, and Runner), all eight browser shards, typecheck/release registry, build, canary dry run, security checks, and policy gates. There are 52 passing checks and no pending or failing checks. - Greptile completed on the exact current head with 5/5 and no actionable findings or open review threads. - Local repair verification passed 93 focused tests, including same-app reinstall after revocation and rejection of consent started before revocation, the AgentMail browser journey, and repository typecheck. Local build and Storybook build also passed. The redundant local full-suite rerun was stopped after the complete current-head CI matrix passed. - Real Slack setup and agent replies were exercised in the authorized isolated test drive during the setup iteration. - The ten additional model probes were attempted with legacy `codex_local`, `gpt-5.6-sol`: five passed, two failed, and three were partly verified. Native runtime is not qualified. See `server/src/services/connectors/slack/evals/2026-10-08-acceptance.md` for evidence and limits. - Passing model probes cover native forms, downloaded file bytes, bare mentions with thread replies, explicit posts/reactions, and saved approval denial. - The controlled uncertain-write probe found wrong delivery-check IDs. The canvas fallback attempt used an invented tool name. Search pagination/native search, a private-source denied-tool receipt, and distinct board/webhook origins remain unqualified. Reviewer path: enable Chat connectors, start Slack chat setup, select an agent, enter an app-configuration access token, and approve Slack installation. Send a message to the bot and confirm that setup advances to success. Inspect settings and allowed channels. See `doc/connections/SLACK-AUTOMATIC-SETUP.md` for deployment and recovery. ## Risks - Slack app creation has no provider idempotency guarantee. A timeout after dispatch stays uncertain until the operator checks Slack. - OAuth needs a stable public HTTPS board origin. Webhook ingress may use a separate configured HTTPS origin. Workspace policy can delay installation. - Migration 0318 can replay safely on instances that applied the earlier development migration. - OAuth installation now links the installer to the initiating Paperclip user. Identity checks and company access rules still apply. - Joined channels now enable bot responses by default. Linked-user authorization and per-action approval rules still apply. - Model behavior has the documented delivery-check and canvas fallback failures. A passing CI run does not establish that every model probe passed. - Removing the connection does not delete the customer's Slack app. No new first-party telemetry is added. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, repository tools, code execution, and browser verification. The runtime does not expose a more specific authoring model ID or context-window size. The live bot probes used OpenAI `gpt-5.6-sol` through `codex_local` in legacy mode. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [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> |
||
|
|
5405b1f46f |
Synchronize chat delivery tests with completed drains (#15480)
Expose the already tracked and caught deferred-work promise to test schedulers while preserving default setImmediate behavior. Assert Slack delivery ordering while the primary lease is held, then join the drains; update the existing GitHub test to assert the resulting quiescent queue. Verified all 1,063 chat tests, full typecheck/build, negative synchronization control, independent review and exact-head CI. An unchanged browser shard retry passed and is documented. Greptile 5/5 with no unresolved comments. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
3a726e676f |
feat: enforce private task permissions across execution and data (#10633)
Enforce private task and project access across direct reads, search, execution, files, plugins, live delivery, and sharing mutations. Preserve downward-only sharing, current responsible-user authorization, and audited emergency access. Bind historical draft assets with migration 0314. Co-Authored-By: Paperclip <noreply@paperclip.ing> |