Merge origin/master and integrate environment selection

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-11 06:18:05 -05:00
commit fed4802b72
159 files changed
+13953 -2027

No files matched your search

+9 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+4
View File
@@ -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.
+4
View File
@@ -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).
+19 -15
View File
@@ -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)
+1 -1
View File
@@ -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).
+44
View File
@@ -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 -1
View File
@@ -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.
+48
View File
@@ -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.
+10
View File
@@ -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.
+41
View File
@@ -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.