mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-22 16:51:28 +02:00
Merge origin/master and integrate environment selection
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
commit
fed4802b72
159 files changed
+13953
-2027
No files matched your search
+9
-1
@@ -433,6 +433,14 @@ run/turn ids, payload digest, attempt/acknowledgement state, and one of `steered
|
||||
`issue_thread_interactions.result`. Deleting the interaction cascades its receipt,
|
||||
while deleting a referenced run clears that run pointer without deleting history.
|
||||
|
||||
The question-history index covers `(company_id, idempotency_key)` for every
|
||||
`question-response:` wake state, including failed, cancelled, and skipped
|
||||
receipts excluded from the delivery-idempotency fence. Migration `0332` creates
|
||||
this nonunique index concurrently through the standard migration executor.
|
||||
Apply it with `pnpm db:migrate` on a direct connection before enabling the new
|
||||
sleep guard. The executor retries interrupted invalid builds and records history
|
||||
only after the index is valid. It does not delete delivery or wake records.
|
||||
|
||||
## Plugin database namespaces
|
||||
|
||||
The plugin runtime tracks plugin-owned database namespaces and migrations in `plugin_database_namespaces` and `plugin_migrations`. Hosted deployments that separate runtime and migration connections should set `DATABASE_MIGRATION_URL`; plugin namespace migration work uses the migration connection when present.
|
||||
@@ -739,7 +747,7 @@ transaction boundary.
|
||||
|
||||
### Task workspace records (2026-10-09)
|
||||
|
||||
Migration [0331_harsh_newton_destine.sql](../packages/db/src/migrations/0331_harsh_newton_destine.sql) makes `execution_workspaces.project_id` nullable and changes its project reference to `ON DELETE RESTRICT`: source-project policy cannot disappear while a workspace still depends on it. `issues.execution_workspace_id` remains the sole active task binding. Versioned selection/pending-selection JSON and a binding revision record intent and protect transitions; they are not additional active bindings.
|
||||
Migration [0333_pretty_infant_terrible.sql](../packages/db/src/migrations/0333_pretty_infant_terrible.sql) makes `execution_workspaces.project_id` nullable and changes its project reference to `ON DELETE RESTRICT`: source-project policy cannot disappear while a workspace still depends on it. `issues.execution_workspace_id` remains the sole active task binding. Versioned selection/pending-selection JSON and a binding revision record intent and protect transitions; they are not additional active bindings.
|
||||
|
||||
`execution_workspace_repositories` is company-scoped inventory beneath an execution workspace. It records repository identity, contained relative path, requested ref, pinned commit, preparation state and idempotency receipts. Credentials are resolved at use and are never stored in this inventory. Connection/destination `execution_defaults` JSON contains optional typed project/workspace choices, never arbitrary host paths or commands.
|
||||
|
||||
|
||||
+9
-1
@@ -1360,12 +1360,20 @@ lifecycle and ownership callbacks update its teardown state immediately, includi
|
||||
when preparation later throws. Public sandbox lifecycle and model fallback helpers
|
||||
remain re-exported by `heartbeat.ts`.
|
||||
|
||||
Environment selection is in `server/src/services/heartbeat/environment-selection.ts`.
|
||||
`selectHeartbeatEnvironment` resolves environment policy and workspace reuse,
|
||||
including immutable native recovery bindings, managed sandbox enforcement, and
|
||||
Kubernetes provisioning. It validates native chat isolation and checks shared
|
||||
workspace contention before acquisition. It can defer a sandbox run or add a
|
||||
concurrency note to the task context. The executor retains lease ownership,
|
||||
dispatch gates, and terminal cleanup.
|
||||
|
||||
Workspace preparation is in `server/src/services/heartbeat/workspace-preparation.ts`.
|
||||
`prepareHeartbeatWorkspace` resolves and provisions the workspace, persists its
|
||||
metadata and issue binding, then acquires and realizes the execution environment.
|
||||
It preserves the immutable workspace binding used by native recovery and records
|
||||
preparation spans even when acquisition or realization fails. The executor retains
|
||||
environment selection, dispatch gates, and terminal lease cleanup. Persistence
|
||||
dispatch gates and terminal lease cleanup. Persistence
|
||||
failures still clean newly created workspace artifacts before propagating.
|
||||
|
||||
Runtime execution is in `server/src/services/heartbeat/runtime-execution.ts`.
|
||||
|
||||
+22
-1
@@ -64,6 +64,10 @@ internal traceability tag.
|
||||
## Core Invariants
|
||||
|
||||
- canaries publish from `master`
|
||||
- the canary publisher checks out the exact master push SHA. It verifies the
|
||||
repository, event, branch, and checked-out commit before attaching local
|
||||
`master` at that same SHA. It never switches to a newer branch tip. The local
|
||||
release script still rejects detached or non-master checkouts.
|
||||
- nightlies republish a commit that already shipped a canary (the commit must
|
||||
carry a `canary/v*` tag), and only after the release smoke suite passes
|
||||
against that exact published canary
|
||||
@@ -100,7 +104,7 @@ It:
|
||||
- publishes the user-facing `paperclipai` package last, so `paperclipai@canary` does not advance before the full package set exists
|
||||
- verifies that `canary` resolves to the just-published version and that published internal dependencies exist on npm
|
||||
- installs `paperclipai@canary` into a clean temporary prefix as the final npm gate
|
||||
- starts the exact published canary through a separate fresh npm install for the onboarding smoke; only npm `ETARGET` install failures retry, up to three attempts within two minutes, before onboarding runs once under the existing five-minute startup deadline
|
||||
- starts the exact published canary through a separate fresh npm install for the onboarding smoke; npm `ETARGET` and verified canary tarball availability failures retry, up to three attempts within two minutes, before onboarding runs once under the existing five-minute startup deadline
|
||||
- fails by default if npm leaves `latest` pointing at a canary; use `--allow-canary-latest` only when that state is intentional
|
||||
- creates a git tag `canary/vYYYY.MDD.P-canary.N`
|
||||
|
||||
@@ -112,6 +116,23 @@ current patches and manifests while the separate lockfile-refresh PR is still
|
||||
pending, without resolving new dependencies in the smoke job. The smoke still installs and tests
|
||||
the exact published canary version, not a workspace build.
|
||||
|
||||
The tarball retry applies only to an unambiguous npm `E404` for a canonical
|
||||
public-registry tarball of a CI-published Paperclip package at that exact canary
|
||||
version. The helper queries npm's effective global and applicable scoped registry
|
||||
in the failed install's prefix, working directory, and environment. A custom or
|
||||
unknown effective registry fails. Configuration output stays private in memory.
|
||||
Fresh primary-registry metadata must match the package, version, and tarball URL
|
||||
and announce a valid SHA512 integrity value. This establishes the announced
|
||||
artifact identity; it does not download the tarball or independently verify its
|
||||
contents. The actual npm install still checks tarball integrity.
|
||||
|
||||
Configuration and metadata checks share a five-second deadline, including the
|
||||
response body, within the same two-minute acquisition budget. Metadata is limited
|
||||
to 64 KiB. Redirects, authentication errors, missing metadata, conflicting npm
|
||||
errors, and other artifacts fail. A persistent promised-tarball failure also
|
||||
fails after three installs. Onboarding errors never restart acquisition or
|
||||
repeat onboarding.
|
||||
|
||||
The lockfile artifact is retained for 14 days. A publisher-job rerun replaces its
|
||||
source-named artifact; a smoke-only rerun uses the existing artifact. A missing
|
||||
artifact fails the job rather than falling back to a different dependency set.
|
||||
|
||||
@@ -2129,3 +2129,7 @@ Chat connection and destination settings may supply project/workspace defaults.
|
||||
Agents inspect/select workspaces and request contained repository preparation through ordinary authorized APIs. Repository preparation is idempotent and may require the next admission; it never claims a host-only clone is available in an already-running remote session. Simultaneous tasks may still explicitly share one physical local/SSH folder. Remote sharing requires actual placement and coherent persistence capability.
|
||||
|
||||
See [the layer architecture](plans/2026-10-09-task-workspaces.md) for resolution rules, module ownership, persistence versions, rollout, and verification.
|
||||
|
||||
## Company fast-response service
|
||||
|
||||
Companies may configure an optional shared API connection and model for short acknowledgements of accepted human turns. Fast responses use direct SDK inference alongside normal agent work, with a three-second admission deadline, bounded prompts/output, current authorization and independent `fast_response` accounting. They are server-marked platform receipts attributed to the agent, never completion, interaction or recovery evidence. Company-sponsored unlinked external senders are explicit; linked-user permission denials are never bypassed. See [fast-responses.md](fast-responses.md) for provider, delivery, history and endpoint contracts.
|
||||
@@ -764,3 +764,7 @@ A company may configure a shared decision model for optional Paperclip features.
|
||||
Organizational projects, task files, personal agent home, and provider home are separate concepts. App and chat tasks share one workspace policy: preserve a binding or explicit configured folder, otherwise allocate a stable task directory. A repository is optional and can be prepared without creating a project. Optional connection and destination defaults feed the same task policy; they do not grant permissions or relocate existing conversations.
|
||||
|
||||
Agents select authorized workspace/repository intent while the harness owns paths, preparation, persistence and safe transitions. Intentional simultaneous sharing of one physical local/SSH folder remains supported. Provider sessions keep their admitted root through completion and recovery. See [SPEC-implementation.md](SPEC-implementation.md) and [the layer architecture](plans/2026-10-09-task-workspaces.md) for the versioned contracts and rollout constraints.
|
||||
|
||||
### Fast responses
|
||||
|
||||
A company may use a shared API model to acknowledge accepted human messages across tasks, agent chat and external channels while normal work starts. Acknowledgements retain their platform provenance and cannot satisfy execution or completion requirements. The bounded inference, authorization, sponsorship and independent accounting contract is defined in [fast-responses.md](fast-responses.md).
|
||||
@@ -1712,27 +1712,31 @@ The broker implements this in `discoverOAuthEndpoints`
|
||||
unconditional. `oauthEndpointsForConnection` resolves endpoints in this
|
||||
order:
|
||||
|
||||
1. If the manifest's method `defaults` ship a **complete** pair
|
||||
(`authorizationEndpoint` **and** `tokenEndpoint`), those are used
|
||||
unconditionally. `discoverOAuthEndpoints` never runs in this case, so
|
||||
endpoints stored on the connection's own OAuth config and 401 challenge
|
||||
hints are **not consulted at all**.
|
||||
2. Otherwise, for `mcp_remote` connections, the broker calls
|
||||
1. A method's `defaults.discoveryUrl` is authoritative. The broker resolves
|
||||
that document before cached endpoints, including when a saved connection
|
||||
resumes or reconnects. It must describe the MCP resource or its authorization
|
||||
server, not a separate web/API OAuth service. Failure stops setup.
|
||||
2. A complete manifest pair (`authorizationEndpoint` and `tokenEndpoint`)
|
||||
replaces discovery when the method does not support dynamic registration,
|
||||
or when the connection uses an operator-entered client. A method that can
|
||||
register automatically still discovers its MCP authorization server.
|
||||
3. Otherwise, for `mcp_remote` connections, the broker calls
|
||||
`discoverOAuthEndpoints`, which first checks endpoints already stored on
|
||||
the connection's own OAuth config (falling back field-by-field to the 401
|
||||
challenge hints); a complete stored/hinted pair is used as-is — no
|
||||
`.well-known` fetch.
|
||||
3. Only when neither of the above yields a complete pair does the broker run
|
||||
4. Only when none of the above yields a complete pair does the broker run
|
||||
the RFC 9728 → RFC 8414 discovery chain above.
|
||||
|
||||
Consequence: complete manifest endpoint hints are **authoritative, not
|
||||
hints** — they override even endpoints that an earlier discovery persisted
|
||||
on the connection, and if they go stale the broker keeps using them. For
|
||||
discovery-capable vendors, ship only `serverUrl` in `defaults` (as
|
||||
`notion.json` does) so the broker discovers fresh endpoints at connect
|
||||
time; add explicit `authorizationEndpoint`/`tokenEndpoint` only for vendors
|
||||
that do not publish RFC 9728/8414 metadata, and then own keeping them
|
||||
current.
|
||||
For discovery-capable vendors, prefer `serverUrl` alone (as `notion.json`
|
||||
does), or pin the reviewed protected-resource document when the provider
|
||||
requires an exact path. Keep explicit metadata and endpoint URLs current.
|
||||
When changing discovery precedence, test each affected catalog method against
|
||||
its actual metadata shape. Cover both new setup and a saved registration.
|
||||
A metadata preflight that finds registration somewhere in its search is not
|
||||
proof that sign-in selects that issuer. Sentry's web/API and MCP hosts both
|
||||
serve valid metadata, but only its MCP issuer supports automatic registration;
|
||||
see [Sentry](./SENTRY.md).
|
||||
|
||||
### Dynamic client registration (RFC 7591)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Runtime authentication: [AI Connections](./AI-CONNECTIONS.md).
|
||||
Long-term memory: [Experimental memory connectors](./MEMORY.md).
|
||||
|
||||
Provider notes: [Google Workspace](./GOOGLE-WORKSPACE.md),
|
||||
[Gmail](./GMAIL.md), [Asana](./ASANA.md), [PostHog](./POSTHOG.md), [Neon](./NEON.md), [Superagent](./SUPERAGENT.md), [Gauge](./GAUGE.md),
|
||||
[Gmail](./GMAIL.md), [Asana](./ASANA.md), [Sentry](./SENTRY.md), [PostHog](./POSTHOG.md), [Neon](./NEON.md), [Superagent](./SUPERAGENT.md), [Gauge](./GAUGE.md),
|
||||
[AgentMail](./AGENTMAIL.md), [Telem.AI](./TELEM.md), [iMessage Photon](./IMESSAGE-PHOTON.md), and
|
||||
[Enterpret](./ENTERPRET.md). Optional credential custody:
|
||||
[Vercel Connect](./VERCEL-CONNECT.md).
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# Sentry
|
||||
|
||||
Paperclip connects to Sentry's [official MCP server](https://mcp.sentry.dev/)
|
||||
at `https://mcp.sentry.dev/mcp`. Browser sign-in uses the MCP authorization
|
||||
server. A normal connection does not require a customer-created OAuth app.
|
||||
|
||||
## Discovery
|
||||
|
||||
The method pins the [MCP protected-resource metadata](https://mcp.sentry.dev/.well-known/oauth-protected-resource/mcp).
|
||||
That document names `https://mcp.sentry.dev` as its authorization server.
|
||||
Its [authorization-server metadata](https://mcp.sentry.dev/.well-known/oauth-authorization-server)
|
||||
advertises automatic client registration, PKCE S256, refresh tokens, and
|
||||
client ID metadata documents. Paperclip retains its normal client selection
|
||||
and binding checks.
|
||||
|
||||
Do not use `https://sentry.io/.well-known/oauth-authorization-server` for this
|
||||
method. That server describes the web/API OAuth service. It does not advertise
|
||||
MCP client registration. Both metadata URLs return valid JSON, so checking
|
||||
only HTTP status or the presence of authorization/token endpoints misses this
|
||||
failure.
|
||||
|
||||
## Repair an existing connection
|
||||
|
||||
After deploying the corrected catalog, resume or reconnect the existing Sentry
|
||||
connection. Keep its connection identity and access policies. Complete browser
|
||||
consent if required. Confirm the intended organization and projects through a
|
||||
read-only tool call from the assigned agent.
|
||||
|
||||
The catalog repair fixes setup and reconnect discovery. It cannot restore an
|
||||
expired or revoked grant without the owner's consent. If the saved connection
|
||||
changes to **Finish setup**, inspect its health error, refresh outcome, and
|
||||
transition timestamp separately. A setup error alone does not prove why the
|
||||
previous grant stopped working.
|
||||
|
||||
## Verification
|
||||
|
||||
The service regression uses separate, realistic metadata for both Sentry
|
||||
hosts. It checks new registration and reuse of an existing MCP registration,
|
||||
the authorization URL, resource, requested scopes, and PKCE. These fixtures
|
||||
prove Paperclip's endpoint selection; they do not prove live account consent.
|
||||
|
||||
Before claiming restoration, verify browser consent, catalog discovery, and a
|
||||
real agent read. Record token refresh separately. Do not publish credentials
|
||||
or unredacted authorization URLs in evidence.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Company decision models
|
||||
|
||||
Company Settings → General → **Decision model** configures one shared API connection for optional Paperclip features. New companies remain unconfigured. A connection manager selects or adds an OpenAI or OpenRouter connection, saves, and can run a small billed setup test. Test answers appear only in that session; request metadata and charges appear under Activity → Costs → Decisions.
|
||||
Decision model setup remains available in Company Settings → General when fast responses are off. Enabling **Experimental fast responses** in Company Settings → Experimental moves model setup to the Connections page. Company Settings → Connections → **Decision model** configures one shared API connection for optional Paperclip features. New companies remain unconfigured. A connection manager selects or adds an OpenAI or OpenRouter connection, saves, and can run a small billed setup test. Test answers appear only in that session; request metadata and charges appear under Activity → Costs → Decisions.
|
||||
|
||||
**Allow company-sponsored background decisions defaults on.** Saving authorizes internal background features to charge the selected connection without a responsible human. An explicit off setting survives later edits, including changing the connection or omitting the field from an update. Deleting the selected connection or grant preserves the setting and blocks calls until a valid replacement is selected. Disabling decisions prevents new calls. It does not cancel or erase calls already dispatched.
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# Company fast responses
|
||||
|
||||
Fast response is an optional company service that acknowledges an accepted human turn while the assigned agent follows its normal execution path. It starts disabled. First enable **Experimental fast responses** in **Company settings → Experimental**; this reveals Connections below Environments and allows generation. Turning it off hides that page and suppresses new requests and pending delivery, while retaining settings, history, and recorded charges. Decision model setup remains accessible under General while the experiment is off. Configure a shared API connection and model in **Company settings → Connections → Fast response**, beside the decision model configuration. OpenRouter's recommended model is `openai/gpt-oss-120b`. Subscription accounts are ineligible.
|
||||
|
||||
The direct Vercel AI SDK service supports OpenAI Responses, Anthropic Messages, Google, xAI, OpenRouter, Bedrock, and connection-configured Responses, Messages, Chat Completions, and local endpoints. Routing, region, endpoint and authentication come from the saved connection. Model choices reuse existing catalogs; custom endpoints permit manual IDs. Decision-model execution is independent.
|
||||
|
||||
**Allow company-sponsored fast responses** defaults on. It covers accepted external senders without linked Paperclip users. A linked user must retain both task access and connection audience permission; denial never falls back to sponsorship. Connection management permissions govern settings, model selection and tests. Costs history uses company cost visibility, with task links checked separately.
|
||||
|
||||
## Accepted turns and receipts
|
||||
|
||||
Task creation, task comments (including comments submitted with updates), persistent agent chat, steering and queued follow-ups enqueue at human acceptance boundaries. Shared external chat intake covers the existing Slack, GitHub and other chat connectors; email has its own authorization and publication adapter. Experimental board chat uses the same inference service.
|
||||
|
||||
The durable request is unique by `(company_id, source_key)`. The worker runs at most eight pending requests per sweep, receives database work signals, and expires excess work. A claimed request is never regenerated after a restart. A stale claimed request becomes an unknown billing outcome with its reservation retained.
|
||||
|
||||
The visible acknowledgement is an ordinary attributed issue comment with server-owned `origin = fast_response`, a request reference and no heartbeat run. Its source turn is retained on the request. Message details explain its provenance. It must not settle a conversation, supersede an interaction, count as recovery progress, trigger an agent subscription, or inherit a worked-run summary. Agent context labels receipts and includes standing guidance to start substantive work without another generic acknowledgement. Receipt insertion does not steer or interrupt an active model.
|
||||
|
||||
## Bounded generation and delivery
|
||||
|
||||
The prompt includes the current message, agent name, accepted/queued state, permitted task title, up to two prior visible turns, and attachment names/types only. External adapters supply only destination-authorized context; they do not copy the internal task history. The serialized prompt has a 4 KiB limit, dropping older turns first and marking a shortened current message. Instructions are sent as a system message, with conversation content as untrusted data.
|
||||
|
||||
Generation requests one sentence (two permitted), at most 256 output tokens and 320 visible characters. Optional reasoning is disabled or minimized where supported. There are no tools, agent runtime, repository access or SDK retries. Empty, overlong, truncated, question-shaped or unsafe formatted output is discarded. The prompt prohibits invented findings, completed-work claims, questions and ETAs, and distinguishes queued work from execution.
|
||||
|
||||
The deadline is three seconds from acceptance through publication admission. Access, configuration, source validity, assignment, pause/cancellation, conversation generation and real-agent replies are checked before admission and again before the comment/outbox is committed. Native visible text also suppresses obsolete receipts. Failure quietly preserves existing progress feedback.
|
||||
|
||||
External publication uses the existing sanitized outbox, exact originating endpoint/conversation, transport leases and final authorization checks. Published contextual receipts suppress subsequent generic queued/working notices for the same turn. Reactions and typing remain on their existing paths. Expired receipts are not posted; ambiguous external attempts stay subject to existing delivery reconciliation rather than being blindly retried.
|
||||
|
||||
## Accounting and endpoints
|
||||
|
||||
Every dispatched attempt uses the existing accounting lock, budget checks, reservation and cost ledger with `usageKind = fast_response`. Settlement is idempotent and keeps actual charges even when output is suppressed. OpenRouter supplies reported costs. Direct OpenAI/Anthropic models covered by the repository's reviewed rate cards receive explicit estimates. Unsupported pricing and ambiguous network outcomes remain unpriced, never fabricated as zero; reservations remain held until billing reconciliation.
|
||||
|
||||
**Costs → Fast responses** shows connection, model, tokens, cost, timing, generation outcome and current publication outcome. Operational request rows contain identifiers and safe outcome codes, not prompts. Delivered comment text remains in conversation history.
|
||||
|
||||
Company-scoped endpoints under `/api/companies/:companyId/fast-response`:
|
||||
|
||||
| Method/path | Purpose |
|
||||
| --- | --- |
|
||||
| `GET /` | Settings, eligible shared connections, management capability |
|
||||
| `PUT /` | Save enabled, connection/grant, model and sponsorship |
|
||||
| `GET /models?connectionId=…` | Existing catalog or connection-configured models |
|
||||
| `GET /availability` | Local authorization/connection availability, no inference |
|
||||
| `POST /test` | Fixed border-styling sample; text, duration and usage; no conversation comment |
|
||||
| `GET /history` | Metadata-only usage history with existing cost date/limit parameters |
|
||||
|
||||
## Verification
|
||||
|
||||
Provider-contract tests use the real SDK adapters with mocked HTTP, including endpoint/auth/model/output/token/abort/error behavior. Database tests cover deduplication, simultaneous workers, provenance, completion isolation, revoked audience access, real-reply races, source mutation/deletion/cancellation/reassignment, retained charges and unknown billing. Stories cover configured, disabled, revoked, testing, timeout, result and mobile settings states.
|
||||
|
||||
Live OpenRouter latency, prompt quality and complete Paperclip/Slack/GitHub journeys are a separate evidence category. Passing contract tests does not establish those live results. Live verification requires an authorized OpenRouter connection and designated channel test destinations.
|
||||
@@ -129,6 +129,16 @@ company/agent's linked run has finished without retry or accounting debt.
|
||||
Image-setup history still blocks: promotion can succeed before teardown is
|
||||
confirmed, so a terminal label does not prove that its provider resource is gone.
|
||||
|
||||
Completed question-answer deliveries permit sleep only after acknowledgement
|
||||
and completion of their exact target run in the same company, without retry or
|
||||
accounting debt. A fallback without a target run requires its exact question's
|
||||
finished durable wake receipt in the same company. A coalesced fallback also
|
||||
requires its exact company/agent's linked run to finish without retry or
|
||||
accounting debt. The question-history index covers every wake status.
|
||||
Pending deliveries, missing
|
||||
completion evidence, and unfinished handoffs still block. Failed deliveries
|
||||
without a pending target are history; other work checks still apply.
|
||||
|
||||
Every enabled plugin blocks sleep. A version label does not prove that arbitrary
|
||||
worker code has no background activity. No plugin approval or configuration
|
||||
bypass is supported. Scheduled and externally triggered work needs a durable
|
||||
|
||||
@@ -422,9 +422,31 @@ Longer polling intervals alone do not complete an item.
|
||||
eligibility predicate so paused endpoints, unknown outcomes, blocked followers,
|
||||
and receipts owned by a live sender do not cause empty scans. Completion wakes
|
||||
refill free endpoint slots without waiting for slow peers. No new tables.
|
||||
Remaining **1s** maintenance: provider runtimes, provider-specific action
|
||||
outboxes, run milestone/wake-notice projection, GitHub operation recovery,
|
||||
Teams protocol maintenance, and Slack session sync. GitHub pre-ingress recovery
|
||||
Five additional queues now use independent commit/deadline workers:
|
||||
Slack Board messages, slash-command task starts, setup verification messages,
|
||||
receipt reactions, and Slack session stops. Their producers and foreground
|
||||
claim/retry/settlement writes signal inside the owning transaction. The same
|
||||
eligibility predicates drive dispatch and deadline selection. Paused task
|
||||
starts/Board messages and uncertain sends have no recurring deadline.
|
||||
Verification waits for account linking, welcome completion, and a verified
|
||||
callback; those state changes wake it. Failed confirmed task admission saves
|
||||
a retry deadline so its commit cannot cause an immediate retry loop.
|
||||
Startup restores existing rows, and empty workers disarm. No new tables.
|
||||
Tests cover an idle hour, real producer notifications, PostgreSQL deadline
|
||||
selection, stale claims, outer-transaction wakes, and callback-driven setup.
|
||||
Three more existing action queues now use commit/deadline workers: provider
|
||||
messages/notices, accepted GitHub webhook receipts, and Slack session sync.
|
||||
Foreground claims, retries, operator resolution, and settlement writes signal
|
||||
in their transaction. Shared predicates select pending rows and deadlines;
|
||||
terminal history and uncertain provider sends have no deadline. Stale provider
|
||||
sends remain quarantined, while GitHub receipts retain bounded replay and
|
||||
their existing attempt fences. Slack sync retains the 30-minute refresh for
|
||||
running sessions and pauses without rescheduling until an endpoint change.
|
||||
Tests exercise real producers with deferred fast paths disabled, retry and
|
||||
startup recovery, stale-send quarantine, and zero scans after settlement.
|
||||
Remaining **1s** maintenance: provider runtimes, Telegram maintenance, failed
|
||||
chat-run retries, run milestone/wake-notice projection, GitHub operation
|
||||
recovery, and Teams protocol maintenance. GitHub pre-ingress recovery
|
||||
must still inspect provider history: a lost callback has no local queue row.
|
||||
This slice does **not** yet make the whole chat subsystem quiet. Independent
|
||||
DB roots/direct SQL require startup recovery, as with the other migrated queues.
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# Fast response implementation and verification
|
||||
|
||||
## Finish line
|
||||
|
||||
Optional company-wide acknowledgements use existing API connections, preserve the normal agent turn, retain server-controlled provenance, and account for provider work exactly once. OpenRouter leads live verification; other providers are verified by HTTP contracts. Existing decision behavior remains unchanged.
|
||||
|
||||
## Implementation
|
||||
|
||||
- Company settings, shared API connection selection, model catalog/manual IDs, fixed sample test, availability and Costs history.
|
||||
- SDK-backed direct generation across native providers and configured Messages, Responses, Chat Completions, Bedrock and local routes.
|
||||
- Durable deduplicated accepted-turn requests with a three-second admission deadline, bounded workers, authorization and budget checks, one inference attempt, and restart quarantine.
|
||||
- Platform receipts in task and agent chat, board chat and shared external intake/publication, excluded from completion, unanswered-turn recovery and interaction resolution.
|
||||
- Small context prompts, source isolation for external destinations, provenance details and labeled agent context.
|
||||
|
||||
## Evidence collected
|
||||
|
||||
Isolated checkout `codex/fast-response`, app at `http://127.0.0.1:3109`, cloned database under `/private/tmp/paperclip-fast-response-home`.
|
||||
|
||||
- Live OpenRouter `openai/gpt-oss-120b` settings test: UI 0.95 seconds, 212 input / 31 output tokens, reported cost 0.00504 cents.
|
||||
- Live task `DOT-302`: initial acknowledgement admitted in 1.013 seconds, 261 input / 38 output tokens, reported cost 0.006195 cents. Subsequent human turns also received receipts.
|
||||
- The dedicated OpenCode/OpenRouter agent subsequently produced a substantive recommendation in the same task. Its real run succeeded. The receipt did not complete the task; final task status remained in progress because the agent did not mark it done.
|
||||
- Provider and service tests cover duplicate workers, provenance/no fabricated run, unchanged task status, unanswered-turn protection, reply/cancel/delete/reassign/edit/revoke races, expiry, unknown billing and fixed sample isolation.
|
||||
- Full build passed after rebasing onto master, including the final UI refinements. Repository typecheck passed after the rebase; server typecheck also passed after review fixes. The full test run was stopped after setup timeouts and failures in workspace-runtime/execution-workspace suites; it is not green evidence.
|
||||
- All 40 provider contracts passed. Slack/GitHub shared intake/outbox contracts and the email reply-only outbox contract passed. Token gates passed after rebase. The regenerated migration 0324 follows master migration 0323 and passes migration safety checks.
|
||||
- Final review corrected accepted/queued wording: a run serving the current turn does not count as older work. Email uses the same state check.
|
||||
|
||||
- The post-rebase focused provider/service/UI run passed all 62 tests. Review regressions now cover receipt labeling in native session handoff, model catalogs isolated from host CLI configuration, route transaction boundaries, Costs navigation, and email migration probe rollback.
|
||||
- A final OpenRouter sample exposed copied JSON output. The prompt now explicitly requests plain text and structured output is rejected while retaining charges. The corrected live sample returned a contextual acknowledgement in 1.374 seconds, 246 input / 22 output tokens, reported cost 0.0035600 cents.
|
||||
|
||||
- Rebased onto the email commit/deadline scheduler: receipt publication signals its existing worker in the same transaction. Three email scheduling/receipt checks passed.
|
||||
- Review follow-ups share queued-state detection across Slack/GitHub/task/email and defer GitHub generic working comments while a contextual receipt can arrive. Eight focused channel checks passed, plus a substantive GitHub reply after receipt; server typecheck passed. Failed generation preserves generic feedback and uncertain external delivery does not trigger a duplicate acknowledgement.
|
||||
|
||||
- Review found quarantined history could lose its label in the prompt. Current and recent comments now use the established quarantine sanitizer; all 22 fast-response service tests passed, including both new source-trust cases, and server typecheck passed.
|
||||
|
||||
## Verification still required
|
||||
|
||||
- Live Slack bot creation and conversation; browser login completed. A narrow callback relay is prepared. Cloudflare tunneling was rejected by automatic approval review; explicit user authorization is pending.
|
||||
- Live GitHub test journey in `paperclipai/paperclip-permissions-smoke-20260926-pap57-fee7428e`.
|
||||
- Latest-head CI and automated review. CI identified additional startup/route fixtures and exact guidance/wiring expectations that need to include fast responses; the corrected focused runs passed (12 closed-workspace routes, 5 native answer continuations, 36 startup tests, and 14 publication/reconciliation tests). Native continuation verification explicitly disables the ambient worktree suppression flag only in the test process. Copied historical run recovery failed during live testing; execution in the cloned workspace is now disarmed, and the app health endpoint reports startup ready.
|
||||
|
||||
No credentials or prompt bodies belong in this record.
|
||||
Reference in new issue
Block a user