mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 13:24:55 +01:00
Merge current master and decision admission fixes from work-folders base
Co-Authored-By: Paperclip <noreply@paperclip.ing> * codex/work-folders-base-refresh: (25 commits) fix: retain saved messages while decisions are pending fix(server): stop reporting expected managed-cloud transients to Sentry (#13323) fix: promote review tasks when continuations start (#13318) fix: require explicit native completion reviews (#13314) fix(onboarding): make chief-of-staff hiring reliable (#13317) fix: fence native startup against cancellation (#13316) chore(skills): allow verified PR merges (#13313) feat: add experimental persistent agent chat (#13284) chore(lockfile): refresh pnpm-lock.yaml (#13279) fix(ui): improve mobile task spacing (#13304) fix(connections): repair and simplify Google Workspace setup (#13289) fix(ui): stabilize steered chat activity presentation (#13246) fix(ui): make feed cards fully clickable (#13294) ci: activate shared PR dependency cache restores (#13302) test: remove cold executable reads from runner integrity deadlines (#13301) ci: reuse dependency caches without per-PR uploads (#13300) fix(ui): hide profile feedback flag on Cloud (#13292) feat(ui): refine dashboard cards, charts, and recent lists (#13269) fix: protect starting runs during overlapping deployments (#13285) fix: reliably interrupt and resume legacy message queues (#13275) ... # Conflicts: # packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs
This commit is contained in:
commit
bb80a847c4
385 files changed
+114493
-3058
No files matched your search
@@ -386,3 +386,18 @@ pnpm secrets:migrate-inline-env --apply
|
||||
```
|
||||
|
||||
Hosted AWS provider notes live in [SECRETS-AWS-PROVIDER.md](./SECRETS-AWS-PROVIDER.md).
|
||||
|
||||
### Persistent agent conversations
|
||||
|
||||
Migration `0274_agent_chat.sql` adds conversation identity/state and session generation/boundary columns to `issues`, plus idempotent client request IDs and processed session-boundary generations to `issue_comments`. The company/agent/user unique index resolves concurrent first writes to one issue. A check constraint preserves the assigned-agent identity and prevents terminal conversation status. Comment request IDs are unique per issue and user. There is no separate chat/message store. Provider sessions continue to use `agent_task_sessions`; `/new` removes only the matching conversation session, and session writers fence stale generations against the issue row.
|
||||
|
||||
## Legacy controller ownership
|
||||
|
||||
Legacy run claims atomically record `controller_boot_id`, a database-clock
|
||||
`controller_lease_expires_at`, and `execution_stage` before workspace provisioning.
|
||||
The lease renews independently of output. A different container must not infer
|
||||
controller death from its own process map or numeric PIDs. Expiration grants
|
||||
cleanup authority; it does not prove that remote inference has stopped. Recovery
|
||||
revokes the previous boot identity with a conditional update. Its own claim also
|
||||
expires so another sweep can finish cleanup after a restart. Historical rows keep
|
||||
null ownership fields and follow the previous recovery path.
|
||||
@@ -417,6 +417,19 @@ configs with `database.mode: postgres`, suppresses the invocation directory's
|
||||
guard. The selected instance's own environment file still loads. The command
|
||||
selects the first available loopback port at or above `3100`.
|
||||
|
||||
Source-checkout startup builds the shared and plugin SDK packages when needed.
|
||||
It prints build progress and any wait for another build. Interrupted builds
|
||||
release their lock after the compiler stops; later startups recover locks whose
|
||||
owner and compiler have exited. Empty locks from older versions are recovered
|
||||
once they are at least two minutes old. The command remains in the foreground
|
||||
after printing its ready URL to serve the instance; use Ctrl-C to stop it.
|
||||
Each package gets a completion marker only after a successful build. A hard
|
||||
kill leaves that marker absent, so the next startup rebuilds partial output.
|
||||
The marker records source and output content fingerprints, so recovery does
|
||||
not depend on filesystem timestamp precision. Direct `tsc` builds that produce
|
||||
identical output reuse the marker. Changed or partial output is rebuilt once
|
||||
before later startups reuse the completed build.
|
||||
|
||||
Claude uses `ANTHROPIC_API_KEY`; Codex uses `OPENAI_API_KEY`; OpenCode uses
|
||||
`OPENROUTER_API_KEY` and requires an `openrouter/...` model. `--api-key-env`
|
||||
can name a different source variable while the agent still receives the
|
||||
|
||||
@@ -160,3 +160,17 @@ Paperclip’s core identity is a **control plane for autonomous AI companies**,
|
||||
|
||||
9. **Thin core, rich edges**
|
||||
Put optional chat, knowledge, and special surfaces into plugins/extensions rather than bloating the control plane.
|
||||
|
||||
### Experimental persistent agent conversations
|
||||
|
||||
Agent Chat is an opt-in core task presentation (`enableAgentChat`, off by default). Each person has one persistent task-backed conversation per agent and company, with ordinary company task visibility. The shared task composer, transcript, tools, files, and document panel remain the interaction surface. Agents clarify goals and hand substantial execution to linked, assigned tasks; a reply ends a turn without completing the conversation. `/new` starts fresh provider context in the same conversation while preserving visible history and artifacts. Healthy idle conversations wait for a message and do not count as unfinished execution work. See `doc/plans/2026-09-10-agent-chat.md` for the implementation contract.
|
||||
|
||||
### Agent chat project handoff (2026-09-11)
|
||||
|
||||
Chat supports research and full plan drafting/revision in its existing plan document. On handoff, each ordinary assigned task receives the relevant plan in its own `plan` document, committed with task creation before execution is scheduled. The source plan remains in the conversation. Plan acceptance hands off execution; it never switches the conversation into implementation.
|
||||
|
||||
Chat instructions require selecting a suitable project, reusing an existing one where appropriate. The project requirement is prompt-only; ordinary projectless tasks remain supported. New parent relationships beneath conversation tasks are rejected by task services, including direct API creation and reparenting. Existing children remain readable/editable and can be moved elsewhere. The Subtasks panel is unchanged.
|
||||
|
||||
The `create_project` runtime tool uses the normal project API with durable idempotency. `list_projects` and `list_project_repositories` support selection. Multiple `repositoryIds` select authorized catalog entries; multiple HTTPS GitHub `repositoryUrls` register existing repositories absent from the catalog. IDs and URLs may be combined, but cannot accompany an explicit `workspace`. URLs do not create repositories on GitHub or grant credentials. Execution uses normal repository access rules. Repository IDs are revalidated against the authenticated run's responsible user and connection grants. Agents should consider proper available repositories, clarify material ambiguity, and use repository-free projects when appropriate for non-code work.
|
||||
|
||||
Confirmed project creation appears as a durable card in the shared task transcript, including selected repository links. Tasks are linked inline. Failed creation never produces a success card. Tool evals cover planning/handoff, project/repository selection, retries, permission and mode denials, and ordinary delegation regressions using the production chat directive.
|
||||
@@ -1267,6 +1267,11 @@ Scheduler must skip invocation when:
|
||||
- an existing run is active
|
||||
- hard budget limit has been hit
|
||||
|
||||
Legacy execution records a renewable controller lease when claiming a queued run,
|
||||
before provisioning. A live lease protects the run during overlapping service
|
||||
deployments. An expired controller loses dispatch authority; a recovery worker
|
||||
must establish that the previous execution stopped before starting a successor.
|
||||
|
||||
## 11.7 Durable agent session goals
|
||||
|
||||
Runner Protocol v2 negotiates a required `sessionGoals` capability and typed
|
||||
@@ -1574,10 +1579,32 @@ Export/import behavior in V1:
|
||||
- import preview reports skill-policy and legacy-grant mappings before apply and rejects unknown policy schema versions
|
||||
- GitHub imports warn on unpinned refs instead of blocking
|
||||
|
||||
### User messages after native execution recovery stops
|
||||
### Experimental task-backed agent chat (2026-09-10)
|
||||
|
||||
An authenticated user message can start a fresh native conversation turn once
|
||||
the prior execution is confirmed stopped. Retain the source history and uncertain
|
||||
`enableAgentChat` is an instance experimental flag, default false. Conversation containers remain issues, unique by `(company_id, conversation_agent_id, conversation_user_id)`. The authenticated board actor supplies ownership; local trusted mode uses `local-board`. Ordinary company task access applies. A conversation's agent assignment and identity are immutable through ordinary updates; terminal status mutations are rejected.
|
||||
|
||||
`GET /api/companies/:companyId/chats/:agentRef` reads an existing conversation or null. `POST` atomically resolves its issue on first send/upload. Existing issue comment, attachment, document, interaction, and run APIs apply thereafter. User chat comments require an idempotent UUID `clientRequestId`. Conversation delivery preserves comment order through the existing issue execution queue; the durable comment outbox repairs the commit-to-enqueue crash window.
|
||||
|
||||
The server owns conversation state: `waiting` plus `in_review` denotes a healthy idle conversation, and `active` denotes an unanswered or executing turn. Successful replies settle a turn; they do not finish the issue. Idle containers are excluded from execution-work counts, ordinary task lists, timer work, and recovery invocations. Failed/unanswered turns retain normal handling. Child completion never wakes or completes the conversation. Search and direct task access preserve history.
|
||||
|
||||
Standalone `/new` is an ordered queue command with no model response. It advances a durable session generation and boundary comment, resets only this issue's provider context, and preserves the issue ID and history. Generation checks reject stale context writes and replies. Fresh replay excludes earlier messages and summaries. The shared transcript renders a session divider.
|
||||
|
||||
Chat prompts retain agent instructions and tools while directing clarification and task creation. Substantial execution belongs to linked, assigned ordinary issues. Ask mode remains non-mutating. Feature disablement prevents new turns and resets while retaining data and lifecycle protection; already-running turns may settle normally.
|
||||
|
||||
### Agent chat project handoff (2026-09-11)
|
||||
|
||||
Chat supports research and full plan drafting/revision in its existing plan document. On handoff, each ordinary assigned task receives the relevant plan in its own `plan` document, committed with task creation before execution is scheduled. The source plan remains in the conversation. Plan acceptance hands off execution; it never switches the conversation into implementation.
|
||||
|
||||
Chat instructions require selecting a suitable project, reusing an existing one where appropriate. The project requirement is prompt-only; ordinary projectless tasks remain supported. New parent relationships beneath conversation tasks are rejected by task services, including direct API creation and reparenting. Existing children remain readable/editable and can be moved elsewhere. The Subtasks panel is unchanged.
|
||||
|
||||
The `create_project` runtime tool uses the normal project API with durable idempotency. `list_projects` and `list_project_repositories` support selection. Multiple `repositoryIds` select authorized catalog entries; multiple HTTPS GitHub `repositoryUrls` register existing repositories absent from the catalog. IDs and URLs may be combined, but cannot accompany an explicit `workspace`. URLs do not create repositories on GitHub or grant credentials. Execution uses normal repository access rules. Repository IDs are revalidated against the authenticated run's responsible user and connection grants. Agents should consider proper available repositories, clarify material ambiguity, and use repository-free projects when appropriate for non-code work.
|
||||
|
||||
Confirmed project creation appears as a durable card in the shared task transcript, including selected repository links. Tasks are linked inline. Failed creation never produces a success card. Tool evals cover planning/handoff, project/repository selection, retries, permission and mode denials, and ordinary delegation regressions using the production chat directive.
|
||||
|
||||
### User continuation after execution recovery stops
|
||||
|
||||
An authenticated user message or an exact failed-run Retry can start a fresh
|
||||
native or legacy conversation turn once the prior execution is confirmed stopped. Retain the source history and uncertain
|
||||
action outcomes; do not replay tool calls or reset the failed incident's automatic
|
||||
retry budget. Existing pause, approval, budget, ownership, and dependency gates
|
||||
remain in effect. See `doc/execution-semantics.md` for admission and stop-proof
|
||||
@@ -1595,3 +1622,14 @@ normal task conversation; rich email cards show the correspondence and delivery
|
||||
outcomes without a separate email composer. See
|
||||
[AgentMail connections](connections/AGENTMAIL.md) for setup, transports, recovery,
|
||||
authorization, and the API/CLI contract.
|
||||
|
||||
### Native task completion
|
||||
|
||||
For ordinary low-risk tasks, accept the current agent's structured `done` claim
|
||||
subject to explicit workflow constraints. Missing independent evidence or a
|
||||
`needs_review` label alone must not create a human approval. Require a concrete
|
||||
reviewer decision for a new review request. Keep unfinished work with the agent,
|
||||
with bounded continuation and visible recovery. Preserve explicit approvals,
|
||||
current task ownership, cancellation, dependencies, and newer task state. See
|
||||
`doc/architecture/native-status-arbitration.md` for finish feedback and the
|
||||
provenance-checked cleanup of historical automatic completion reviews.
|
||||
+12
@@ -277,6 +277,8 @@ All agent communication flows through the **task system**.
|
||||
|
||||
There is no separate messaging or chat system. Tasks are the communication channel. This keeps all context attached to the work it relates to and creates a natural audit trail.
|
||||
|
||||
Experimental Agent Chat presents one persistent task per person and agent as a simplified conversation. It retains the task composer, transcript, tools, attachments, documents, and existing Subtasks panel, with ordinary company visibility. New execution tasks are ordinary project tasks, not children of the conversation. Idle conversations wait for a message without entering execution-task work queues. Agents clarify goals here and create assigned tasks for substantial execution. `/new` resets provider context at an ordered session boundary within the same task while preserving visible history. `enableAgentChat` is disabled by default; the V1 lifecycle and rollout contract is specified in `SPEC-implementation.md`.
|
||||
|
||||
### Implications
|
||||
|
||||
- An agent's "inbox" is: tasks assigned to them + comments on tasks they're involved in
|
||||
@@ -549,6 +551,16 @@ Things Paperclip explicitly does **not** do:
|
||||
8. **Progressive deployment.** Trivial to start local, straightforward to scale to hosted.
|
||||
9. **Extensible core.** Clean boundaries so plugins can add capabilities (Adapters, knowledge base, revenue tracking) without modifying core.
|
||||
|
||||
### Agent chat project handoff (2026-09-11)
|
||||
|
||||
Chat supports research and full plan drafting/revision in its existing plan document. On handoff, each ordinary assigned task receives the relevant plan in its own `plan` document, committed with task creation before execution is scheduled. The source plan remains in the conversation. Plan acceptance hands off execution; it never switches the conversation into implementation.
|
||||
|
||||
Chat instructions require selecting a suitable project, reusing an existing one where appropriate. The project requirement is prompt-only; ordinary projectless tasks remain supported. New parent relationships beneath conversation tasks are rejected by task services, including direct API creation and reparenting. Existing children remain readable/editable and can be moved elsewhere. The Subtasks panel is unchanged.
|
||||
|
||||
The `create_project` runtime tool uses the normal project API with durable idempotency. `list_projects` and `list_project_repositories` support selection. Multiple `repositoryIds` select authorized catalog entries; multiple HTTPS GitHub `repositoryUrls` register existing repositories absent from the catalog. IDs and URLs may be combined, but cannot accompany an explicit `workspace`. URLs do not create repositories on GitHub or grant credentials. Execution uses normal repository access rules. Repository IDs are revalidated against the authenticated run's responsible user and connection grants. Agents should consider proper available repositories, clarify material ambiguity, and use repository-free projects when appropriate for non-code work.
|
||||
|
||||
Confirmed project creation appears as a durable card in the shared task transcript, including selected repository links. Tasks are linked inline. Failed creation never produces a success card. Tool evals cover planning/handoff, project/repository selection, retries, permission and mode denials, and ordinary delegation regressions using the production chat directive.
|
||||
|
||||
### Paused task messages
|
||||
|
||||
A paused task takes over the composer with an amber notice and a Resume action.
|
||||
|
||||
@@ -136,7 +136,8 @@ conditions before model disposition:
|
||||
| Run failed | Preserve | Schedule recovery |
|
||||
| Approval, interaction, or execution stage is pending | `in_review` | Materialize/bind the governance gate and notify its owner |
|
||||
| Completion satisfies its authority policy | `done` | Release checkout |
|
||||
| Runner reports `needs_review` | `in_review` | Bind a reviewer and notify the owner |
|
||||
| Runner reports a concrete attention request with a reviewer and decision | `in_review` | Bind the requested reviewer |
|
||||
| Runner reports `needs_review` without a decision, or an incomplete completion claim | Keep work with the agent | No automatic human approval; at most one corrective continuation, then a visible recovery action |
|
||||
| Runner reports a task-wide blocker | `blocked` | Persist blocker owner and unblock action |
|
||||
| Runner reports a current-track blocker | `in_progress` | Enqueue another productive track |
|
||||
| Runner reports `yielded` with a valid continuation | `in_progress` | Enqueue the declared continuation |
|
||||
@@ -280,3 +281,33 @@ Common patterns:
|
||||
See also
|
||||
[`durable-continuation-scheduler.md`](./durable-continuation-scheduler.md) for
|
||||
the scheduler and recovery behavior that follows an `in_progress` decision.
|
||||
|
||||
## Explicit completion reviews
|
||||
|
||||
Ordinary task completion uses the agent's structured `done` claim under the
|
||||
contract's low-risk claim policy. Unknown evidence references remain diagnostic
|
||||
information; they do not create human approval requirements. Cancellation,
|
||||
newer task state, unresolved dependencies, and explicit governance still win.
|
||||
|
||||
Paperclip no longer creates a generic "Native completion review" because a
|
||||
report is incomplete, verification failed, or the agent says `needs_review`.
|
||||
A new review interaction requires an explicit attention request naming the
|
||||
reviewer's responsibility and the decision. The card displays that request.
|
||||
Waiting for CI remains agent work, not a human completion approval.
|
||||
|
||||
The native runner returns current approval/dependency constraints to the agent
|
||||
when it calls `paperclip_finish`. An empty `needs_review` report without an
|
||||
existing gate is rejected with instructions to correct it. The final reply must
|
||||
explain any required user action and link to the relevant task or approval.
|
||||
The tool acknowledges receipt, not a premature status commit: final status is
|
||||
committed only after the provider turn and workspace finalization settle.
|
||||
|
||||
On upgrade, bounded cleanup withdraws only unanswered, system-created fallback
|
||||
cards proven by their decision/effect ledger, original prompt/target, empty
|
||||
attention request list, and low-risk claim policy. Explicit or answered reviews
|
||||
and stronger completion policies are preserved. Withdrawal has audit history
|
||||
and retires chat actions. Reconciliation reassesses only the current successful
|
||||
run's result, with the same task status/version and completion contract and no
|
||||
newer execution owner. It applies normal governance and dependency checks and
|
||||
appends a decision; it never marks every affected task done blindly. A persisted
|
||||
withdrawal marker makes restart between cleanup and reassessment retryable.
|
||||
@@ -49,6 +49,13 @@ job still runs one test worker. The partition covers every suite exactly once;
|
||||
normal PR and local test groups keep their existing shape. More jobs increase
|
||||
concurrent runner demand, so compare queue time as well as test duration.
|
||||
|
||||
All release verification installs, including the Runner scorer and chaos evals,
|
||||
allow pnpm to refresh an outdated lockfile. Contributor PRs leave lockfile updates
|
||||
to the separate refresh bot, so a dependency-changing master commit can arrive
|
||||
before that bot's PR merges. Verification must install and test that commit
|
||||
without waiting for another merge. The generated lockfile stays in the job's
|
||||
workspace; these checks do not commit it back to the repository.
|
||||
|
||||
The artifact wait runs for up to 30 minutes and reports what is missing. Only
|
||||
an HTTP 404 means publication is pending; authorization errors, upstream outages,
|
||||
and identity mismatches fail the job. A failed, cancelled, or skipped prerequisite
|
||||
@@ -191,7 +198,37 @@ all typechecks still execute. A missing or invalidated cache triggers compilatio
|
||||
|
||||
The Refresh Lockfile workflow does not cache the pnpm store. Its resolution-only
|
||||
command does not download packages and can save an empty default-branch cache
|
||||
before full install jobs finish. Jobs that install dependencies retain caching.
|
||||
before full install jobs finish. The PR policy job also leaves store caching off.
|
||||
|
||||
PR install jobs restore the pnpm store without saving it. They hash the checked-in
|
||||
lockfile before downloading the policy job's regenerated lockfile, matching the
|
||||
key format used by master install jobs. A same-OS, same-architecture pnpm fallback
|
||||
can reuse older package downloads when the exact key is absent. Each job still
|
||||
installs with `--frozen-lockfile` against the policy artifact when one exists;
|
||||
cache contents do not select dependency versions. A cache miss downloads packages
|
||||
normally. New PR-only dependencies may be downloaded again on each PR run until
|
||||
master populates a cache that contains them.
|
||||
|
||||
This avoids storing a full dependency archive under every PR merge ref. Those
|
||||
copies competed with the Rust caches for the repository's storage limit. Keep
|
||||
master cache writes enabled so trusted post-merge installs refresh shared stores.
|
||||
After activating the new trusted workflow pin, verify cache restores and package
|
||||
reuse in an allowlisted PR, and verify that no new `node-cache-` entries appear
|
||||
under its `refs/pull/<number>/merge` ref. Existing copies can expire normally.
|
||||
|
||||
The repository cache storage ceiling is managed in GitHub Settings, separately
|
||||
from this workflow. Check it with:
|
||||
|
||||
```sh
|
||||
gh api repos/paperclipai/paperclip/actions/cache/storage-limit
|
||||
```
|
||||
|
||||
Increasing the repository limit above 10 GB can require an organization owner to
|
||||
raise the maximum in organization Settings → Actions → General first. Repository
|
||||
administration access alone cannot override that maximum. Paid cache storage also
|
||||
requires a payment method and sufficient Actions Cache Storage budget; see the
|
||||
[GitHub cache storage documentation](https://docs.github.com/en/actions/reference/workflows-and-actions/dependency-caching#increasing-cache-size).
|
||||
Preserve populated master pnpm and Rust caches when inspecting pressure.
|
||||
|
||||
After deploying this correction, remove any existing empty default-branch entry
|
||||
for the current lockfile key. List cache IDs, branches, and archive sizes first:
|
||||
|
||||
@@ -60,8 +60,10 @@ Google makes Workspace MCP generally available.
|
||||
| Google People | `https://people.googleapis.com/mcp/v1` | Read contacts |
|
||||
| Google Workspace Search | `https://workspacemcp.googleapis.com/mcp/v1` | Search Workspace |
|
||||
|
||||
The setup flow asks for the capability first. It then offers the authentication
|
||||
methods available for that capability:
|
||||
The setup flow asks for the capability first. When the managed method is
|
||||
available, it uses Paperclip by default. A small **Use your own Google OAuth app**
|
||||
link reveals the custom client fields; **Use Paperclip instead** returns to the
|
||||
managed method. The available authentication methods are:
|
||||
|
||||
- **Connect with Paperclip** uses the Paperclip Cloud broker when that exact
|
||||
profile is returned for this enrolled instance by the signed
|
||||
@@ -80,6 +82,14 @@ default organization grant, while still recording which signed-in Google
|
||||
principal completed consent so refresh and reconnect stay bound to that
|
||||
principal.
|
||||
|
||||
Catalog discovery and connection creation use the same signed, instance-specific
|
||||
profile availability. Local enrollment files and Cloud-delivered environment
|
||||
identities follow this same path; neither enables managed methods globally in
|
||||
the static app definitions. Saved connections remain recognizable for OAuth
|
||||
callback, refresh, and revoke, while the broker enforces current profile access.
|
||||
Switching capability or authentication methods preserves the selected credential
|
||||
owner when the new method supports that owner.
|
||||
|
||||
## Broker profiles
|
||||
|
||||
The Paperclip-managed method signs every broker request with one explicit
|
||||
|
||||
@@ -154,6 +154,11 @@ New comments received during an execution hold retain their individual deferred
|
||||
|
||||
The conversation groups repeated empty pre-start reconciliation cancellations into a neutral waiting notice. Started runs, actual startup failures, and run history remain inspectable. No historical run records are deleted.
|
||||
|
||||
The legacy remote ACP process-session relay runs on the control-plane host. Its
|
||||
launch command uses the host's absolute Node executable even when the adapter's
|
||||
launch environment is sanitized for a remote sandbox; the sandbox PATH remains
|
||||
owned by the sandbox image.
|
||||
|
||||
### Pre-dispatch configuration validation
|
||||
|
||||
Pre-dispatch configuration validation is a distinct gate that runs after ownership and checkout are resolved but before the control plane actually dispatches a run.
|
||||
@@ -352,6 +357,8 @@ A board comment can be an interrupt, an ownership change, both, or neither. Pape
|
||||
|
||||
An interrupt stops the current live execution path for the issue. It does not, by itself, select the next owner. If an active run is interrupted by the board, the run may still terminate with the underlying `cancelled` status, but the issue activity and wake context should make the operator intent visible as an interruption rather than an unexplained runtime failure.
|
||||
|
||||
For legacy runners, **Interrupt** on a queued message stops the active run and explicitly continues the pending queue after execution cleanup. It validates the queue revision and target run, then dispatches the requested queue’s current message bodies in their saved order. Other actors’ queues cannot consume that interrupt. The persisted interrupt intent is retried by the scheduler after a promotion error or server restart until that queue is dispatched or discarded. Edits and discards remain authoritative until dispatch; deleting the final message must not create an empty continuation. Pending messages remain visible after a run stops. Cancelling only the run preserves the queue for a later explicit wake; pausing the task retains its separate queue-cancellation behavior. Native same-turn steering keeps its separate acknowledgement protocol. Legacy Codex uses Ctrl-C to stop its tool sessions and cannot retry a missing-session fallback after the provider has confirmed that the session started.
|
||||
|
||||
An ownership change selects who owns the issue after the comment is committed:
|
||||
|
||||
- setting `assigneeAgentId` makes the named agent the owner
|
||||
@@ -832,6 +839,14 @@ Every continuation carries the triggering request, ordered user direction, inter
|
||||
|
||||
### Interrupted conversation continuation
|
||||
|
||||
Before provider dispatch, chat-control admission retries transient database lock
|
||||
contention with up to 50 waits of 100 ms. Each attempt starts a new transaction
|
||||
and rechecks the current run and committed conversation-close evidence. No lock
|
||||
is held between attempts, and no provider call is retried. Queue claims remain
|
||||
nonblocking. Persistent contention retains the bounded admission failure, with
|
||||
an explicit database-lock error; missing or invalid source evidence still stops
|
||||
the run without retrying the admission check.
|
||||
|
||||
An interrupted conversation does not permanently block its task. For local conversational adapters, Paperclip starts a new bounded turn with the existing session when compatible, or the full task conversation when the session is unavailable. The prompt says: “Your previous run was interrupted. Continue from where you left off.” The agent decides what remains from the history and latest user request. Paperclip never automatically replays recorded tool calls. Unknown past action outcomes are not a task-wide execution gate, and no action-reconciliation questionnaire is required.
|
||||
|
||||
Shutdown, process loss, and provider failure use the existing durable failure retry counter and delay. Ordinary failure recovery permits at most two automatic retries in a failure chain. Accepted-interaction infrastructure recovery retains its existing bounded policy. Repeated scheduler visits reuse the same successor; restarting the server does not reset the counter. After exhaustion, automatic attempts stop. A new explicit user message can start a fresh run and failure budget. Productive max-turn continuation and confirmed workspace waits keep their separate existing semantics.
|
||||
@@ -846,7 +861,7 @@ Local recovery records a server-authored stop receipt before it clears a verifie
|
||||
|
||||
If cleanup or another execution gate is still pending, the message stays in its existing queue receipt. Startup and periodic scheduling reconsider up to 50 due receipts per pass, at most once per 30 seconds per receipt, without calling a model or resetting recovery attempts. Cleanup callbacks use the same admission path. The issue lock prevents concurrent workers from delivering an adopted or discarded receipt again. The queued-message area shows the current wait reason. Pauses, approvals, budgets, ownership, and external chat authorization remain enforced. A message sent before the run finished does not grant new post-stop authority.
|
||||
|
||||
Historical legacy interruption holds for conversational adapters no longer block new messages or Resume. Classification uses the run’s saved adapter invocation or continuation policy, never the agent’s current adapter settings. Missing historical adapter evidence retains the hold. A terminal row with a live predecessor process or unreleased environment lease still blocks actual admission and Resume. Retry scheduling can happen before cleanup, but grants no execution authority. Recovery folds their obsolete no-replay bookkeeping without changing task ownership, status, or automatically waking old work. The audit trail remains readable. Native integrity and ownership holds, and non-conversational adapter holds, remain enforced.
|
||||
Historical legacy interruption holds for conversational adapters no longer block new messages or Resume. Automatic classification uses the server-owned adapter identity saved atomically at run claim, the saved adapter invocation, or the continuation policy, never the agent’s current adapter settings. Missing historical adapter evidence retains the automatic hold; an explicit user continuation can retire it after proving the predecessor stopped. A terminal row with a live predecessor process, an unreleased environment lease, or failed/pending cleanup still blocks actual admission and Resume; a release timestamp alone does not prove cleanup succeeded. Retry scheduling can happen before cleanup, but grants no execution authority. Recovery folds their obsolete no-replay bookkeeping without changing task ownership, status, or automatically waking old work. The audit trail remains readable. Native integrity and ownership holds, and non-conversational adapter holds, remain enforced.
|
||||
|
||||
The server projection remains available for diagnostics. Normal working, finishing, and interaction waits add no badges or cards to task lists or feeds. Active transcript headers keep saying Working during automatic retry and execution confirmation; attempts, causes, and recovery decisions belong in the run log. Recovery uses the existing transcript and run log rather than adding a reconciliation form. A cancelled run that never started says “Couldn't start” instead of implying that the agent answered.
|
||||
|
||||
@@ -870,16 +885,23 @@ new run. Preserve the baseline across recovery of the same run and start a new
|
||||
delta when attaching a new run. Other stale-event and authority checks remain.
|
||||
|
||||
|
||||
### Explicit user continuation after a native failure
|
||||
### Explicit user continuation after execution failure
|
||||
|
||||
An execution recovery hold blocks automatic replay. A new authenticated user
|
||||
comment can authorize a fresh native conversation turn after the predecessor's
|
||||
comment or exact failed-run Retry can authorize a fresh native or legacy
|
||||
conversation turn after the predecessor's
|
||||
execution is confirmed stopped. This is a new request, not another automatic
|
||||
attempt in the failed incident. The old attempt count and unknown action outcomes
|
||||
remain unchanged.
|
||||
remain unchanged. Known non-conversation adapter evidence still requires its
|
||||
original reconciliation flow even if the agent's current settings change.
|
||||
Pre-upgrade runs with no adapter evidence may receive a new explicit user turn
|
||||
only after termination is proven; their old adapter and action outcomes remain
|
||||
unknown, and they do not gain automatic replay eligibility.
|
||||
|
||||
Admission validates the persisted comment's author, task, and time against every
|
||||
held predecessor. An agent-authored comment, an old queued request, or a generic
|
||||
held predecessor. Retry validates the selected failed run's company, task, and
|
||||
agent and preserves that run's identity through admission and history loading.
|
||||
Duplicate Retry requests adopt the same successor. An agent-authored comment, an old queued request, or a generic
|
||||
system wake cannot release a hold. The source task keeps its assignee. Process
|
||||
ownership, active controllers, cleanup leases, pause, approval, budget, and normal
|
||||
execution gates still apply. Dependency-blocked interaction mode remains limited
|
||||
@@ -891,7 +913,7 @@ request, task history, completed work, and the interruption notice. It receives
|
||||
no instruction to repeat old tool calls. Later messages cannot reset the old
|
||||
incident's retry budget or create another automatic replacement for it.
|
||||
|
||||
Native admission verifies local process identities for local runs. Remote runs
|
||||
Explicit continuation verifies local process identities for local runs. Remote runs
|
||||
instead require a provider termination receipt for every lease, with successful
|
||||
cleanup and no active ownership. This applies to both per-turn and warm native
|
||||
runners. A stop receipt retires only the settled cleanup owner for that exact company, run, provider, and sandbox resource, without changing its checkpoint or recorded action outcomes. Independent remote sandboxes have separate cleanup gates, including when one run owns multiple sandboxes. Successful pending-cleanup retries persist the same receipt and reconsider deferred user messages; a delivery failure never reverts successful provider cleanup. A failed checkpoint does not prevent destruction of a terminal run's isolated sandbox; busy ownership still prevents it.
|
||||
@@ -900,6 +922,15 @@ no receipt remain supported but cannot authorize remote continuation. A terminal
|
||||
database status or a PID check on the wrong host is insufficient.
|
||||
No historical task is automatically awakened by this change.
|
||||
|
||||
Startup waits for provider plugin initialization before remote recovery and
|
||||
lease cleanup. The task's blocked notice offers Retry, and a refused retry
|
||||
shows the actual recovery hold. Each explicit user Retry can make one scoped
|
||||
cleanup attempt for its failed run even after automatic cleanup is exhausted.
|
||||
If that attempt fails, a later user Retry may try again after the provider
|
||||
recovers. The failed cleanup keeps the execution hold in place. Retry does not reset
|
||||
the automatic limit or clean up another task's leases. Provider shutdown must
|
||||
still be confirmed before a new conversation is admitted.
|
||||
|
||||
### Explicit Recovery Action
|
||||
|
||||
Paperclip opens an explicit recovery action when the system can identify a problem but cannot safely complete the work itself.
|
||||
@@ -956,3 +987,25 @@ For a board operator, the intended meaning is:
|
||||
- blockers explain waiting
|
||||
|
||||
That is the execution contract Paperclip should present to operators.
|
||||
|
||||
### Cancellation during native startup
|
||||
|
||||
Cancellation records a preparation fence while holding the run row lock. Native
|
||||
runtime selection checks that fence, the running status, and the current startup
|
||||
controller lease in the same transaction that creates the native coordinator.
|
||||
The native executor rechecks cancellation and terminal status when claiming the
|
||||
coordinator, before starting or attaching a provider.
|
||||
|
||||
A cancelled startup can continue from a newer authenticated user message after
|
||||
cleanup. The server requires either its explicit before-selection fence or an
|
||||
unclaimed native coordinator (zero attempts and controller generations, no
|
||||
controller, lease, or result). It also checks for contradictory launch/process
|
||||
evidence and verifies local cleanup or exact remote termination receipts. The
|
||||
preparer must have finished or its startup lease must have expired. A missing
|
||||
PID alone does not establish this proof.
|
||||
|
||||
The existing bounded saved-message worker rechecks this proof after restart.
|
||||
Admission atomically settles an unclaimed coordinator and admits one fresh turn,
|
||||
preserving history, unknown action outcomes, and attempt counts. Pauses, approvals,
|
||||
budgets, task ownership, and terminal task status still gate admission. No
|
||||
automatic provider replay is authorized by a cancelled startup.
|
||||
@@ -0,0 +1,296 @@
|
||||
# Persistent agent chat, backed by tasks
|
||||
|
||||
Date: 2026-09-10
|
||||
Status: Implemented behind `enableAgentChat`; verification recorded in the implementation handoff.
|
||||
|
||||
## Contract
|
||||
|
||||
Each person has one persistent conversation with each agent in a company. A conversation is an ordinary issue with fixed `conversationAgentId` and `conversationUserId`, a matching agent assignee, and a unique company/agent/user identity. The authenticated board actor supplies the user identity (`local-board` in local trusted mode). Company task authorization still applies: these are separate conversations, not private messages.
|
||||
|
||||
Opening an unused conversation performs a read. First send or upload resolves its backing issue atomically through `POST /api/companies/:companyId/chats/:agentRef`. `GET` on the same path returns the existing issue or null. Comments, documents, files, interactions, runs, and subscriptions use the existing task APIs. User chat comments require a stable `clientRequestId`; retries return the same comment. Comment rows also provide a durable delivery outbox, serialized across servers before admission to the normal execution queue.
|
||||
|
||||
Idle conversations are `in_review` with server-owned `conversationState: waiting`. A new message makes the conversation active. A successful run parks it only after a durable agent response, with no later pending message. Failed or unanswered turns retain ordinary error handling. Finalizers, assignment recovery, liveness classification, timer eligibility, and work counts distinguish conversations from execution tasks. Completion or reassignment cannot terminate or transfer the container. Child completion does not wake the conversation.
|
||||
|
||||
## Session boundaries
|
||||
|
||||
Standalone `/new` is an ordinary queued user comment. The shared composer offers it as a slash command. It executes at a turn boundary without invoking the provider, increments `conversationSessionGeneration`, and records `conversationBoundaryCommentId` plus the generation on the command comment. Processing a retried command is idempotent. Only the matching agent/task provider session is deleted; agent-wide state and other task sessions are untouched.
|
||||
|
||||
A board-authored `/new` also releases pause holds rooted at the chat without waking the stopped turn. Dispatch admits the verified reset even when the previous turn has a no-replay recovery disposition; after the boundary, that old disposition remains auditable but does not block a fresh session. Pending clarification questions from the old session expire, including questions configured to survive ordinary comments. The reset run adds no empty-response notice.
|
||||
|
||||
Provider-session writes and run-authored replies check the generation. Cancelled conversation runs cannot issue mutating API calls, post late replies, or restore provider sessions. Fresh prompt replay is bounded to nondeleted comments after the boundary and before the current wake comment, with source-trust sanitization. Automatic task continuation summaries are omitted for conversations. History, artifacts, plans, and linked tasks retain their IDs and remain available for explicit inspection. The shared transcript renders processed command comments as session dividers.
|
||||
|
||||
## Agent policy
|
||||
|
||||
`server/src/services/agent-conversations.ts` owns the chat directive. The task prompt includes it on initial turns, retries, resumed turns, and fresh sessions. It asks the agent to clarify material gaps, then create and assign ordinary project tasks with outcomes, context, copied plans, and acceptance criteria before claiming they exist. It explicitly overrides ordinary completion and accepted-plan execution instructions for the container. Ask mode stays non-mutating; plan mode supports clarification and planning. Normal tools, approvals, budgets, assignment, and execution policies continue to apply.
|
||||
|
||||
## Shared production composition
|
||||
|
||||
`TaskDetailSurface` in `IssueDetail.tsx` is the shared controller and surface. `AgentChat.tsx` resolves the canonical task and provides an ephemeral view model before the first write. It does not implement a second transcript, composer, file panel, or run controller. The chat presentation hides task metadata and the seeded description bubble, uses task breadcrumb typography with agent avatar/name and a configuration-page gear, and defaults the existing task side panel to artifacts/plans rather than Properties.
|
||||
|
||||
Company-prefixed `chats/:agentRef` routes open the current person's conversation. Direct task URLs remain supported. The existing Agents roster provides a Chat action. The shared sidebar lists starred agents alphabetically, then four recent unstarred conversations, without a divider. Stars appear on hover or keyboard focus. Existing resource memberships store stars; company/user-scoped recent-navigation storage records conversation visits only. The gear goes to agent runtime configuration; See all agents goes to `/agents/all`.
|
||||
|
||||
## Rollout
|
||||
|
||||
`enableAgentChat` defaults to false in the shared feature catalog, validator, server settings, and Experimental settings UI. Navigation, resolution, new messages, and reset commands are gated. Turning the flag off preserves data, allows already-running turns to settle, and prevents new chat execution. Lifecycle protection is independent of flag state; task links remain readable under normal authorization.
|
||||
|
||||
## Verification
|
||||
|
||||
Database and route tests cover concurrent canonical creation, independent users with ordinary company visibility, client retry identity, cross-company denial, local identity, ordered concurrent delivery, separate queued resets, generation fences, replay boundaries, idle recovery classification, disabled admission, and child wake suppression. Shared composer/sidebar/settings tests and Storybook fixtures cover the production composition. Storybook scenarios include first conversation, returning, working, paused, failed send, long history, session boundary, disabled feature, light theme, and ordinary task comparison.
|
||||
|
||||
Required handoff checks: targeted tests; token gates; Storybook build; repository typecheck, tests, and build; browser checks of first send, session divider, stars, switching, drafts, configuration, roster, and disabled states. Fixture navigation is not a claim of a live provider evaluation: task creation quality remains prompt-guided and should be observed during the experimental rollout.
|
||||
|
||||
### Implementation verification — 2026-09-10
|
||||
|
||||
- Repository typecheck (`pnpm -r typecheck`), production build (`pnpm build`), token gates, and Storybook build passed.
|
||||
- Final UI suite: 563 files, 5,622 tests passed. The shared controller/live-update regression pass covers first send and upload, preservation of agent routes, read-only unused conversations, personal live-update resolution, and durable session-divider refresh.
|
||||
- General server lane: 8,345 passed and 38 skipped initially; the four failures (a stale module loaded during editing and three socket disconnects) passed in a fresh 68-test rerun. The conversation suite also executes a real process adapter: two ordinary turns invoke it twice, `/new` invokes it zero times, and each answered turn returns to idle.
|
||||
- All 144 serialized route suites were exercised. The skill-route socket failure and queued-comment fixture cleanup failures passed in a 70-test rerun. Queue test cleanup now clears its full company-scoped foreign-key closure rather than ignoring failed deletes.
|
||||
- Shared, database, CLI, adapter, skills-catalog, and plugin project suites passed. The CLI migration test exposed and verified the cloned-database constraint upgrade fix. Adapter suites that exceeded the default five-second timeout passed with capped workers and a 30-second test timeout. Tests ran against isolated temporary homes and databases; repository-standard unsupported integration cases remained skipped.
|
||||
- Browser checks used the production composition with fixture APIs: first send, retry and draft retention, agent switching, stars, configuration/roster navigation, linked subtasks, paused-agent controls, disabled navigation, long history, and `/new` preserving earlier messages and plans. Live-update unit tests cover the socket/cache behavior independently of Storybook fixtures. No live-model task-handoff quality evaluation was performed.
|
||||
|
||||
The broad `pnpm test:run` attempt was followed by isolated group/file reruns for the failures above; this is not a claim that the initial monolithic command exited successfully. The experiment remains off by default.
|
||||
|
||||
## September 11 reset regression verification
|
||||
|
||||
The initial live demo checked an idle reset but missed Stop followed by `/new`. In the reported Claude run, dispatch cancelled both the reset and follow-up before reset processing; the provider generation stayed at zero, and the cancelled old turn posted a late reply. Regression coverage now includes pause plus a prior no-replay recovery disposition, reset and immediate follow-up queue order, cancelled-run write rejection, expiring persistent clarification questions, and suppressing empty reset-run transcript notices.
|
||||
|
||||
Live Codex and Claude checks confirmed fresh context after pause → `/new` → follow-up. An additional Claude check stopped an actively streaming turn containing a unique code word, reset, and asked for that word without history inspection. Claude reported it was absent; the chat returned to waiting.
|
||||
|
||||
### Agent chat project handoff (2026-09-11)
|
||||
|
||||
Chat supports research and full plan drafting/revision in its existing plan document. On handoff, each ordinary assigned task receives the relevant plan in its own `plan` document, committed with task creation before execution is scheduled. The source plan remains in the conversation. Plan acceptance hands off execution; it never switches the conversation into implementation.
|
||||
|
||||
Chat instructions require selecting a suitable project, reusing an existing one where appropriate. The project requirement is prompt-only; ordinary projectless tasks remain supported. New parent relationships beneath conversation tasks are rejected by task services, including direct API creation and reparenting. Existing children remain readable/editable and can be moved elsewhere. The Subtasks panel is unchanged.
|
||||
|
||||
The `create_project` runtime tool uses the normal project API with durable idempotency. `list_projects` and `list_project_repositories` support selection. Multiple `repositoryIds` select authorized catalog entries; multiple HTTPS GitHub `repositoryUrls` register existing repositories absent from the catalog. IDs and URLs may be combined, but cannot accompany an explicit `workspace`. URLs do not create repositories on GitHub or grant credentials. Execution uses normal repository access rules. Repository IDs are revalidated against the authenticated run's responsible user and connection grants. Agents should consider proper available repositories, clarify material ambiguity, and use repository-free projects when appropriate for non-code work.
|
||||
|
||||
Confirmed project creation appears as a durable card in the shared task transcript, including selected repository links. Tasks are linked inline. Failed creation never produces a success card. Tool evals cover planning/handoff, project/repository selection, retries, permission and mode denials, and ordinary delegation regressions using the production chat directive.
|
||||
|
||||
|
||||
### Project handoff verification (September 11)
|
||||
|
||||
The real-server tool tests cover concurrent project retries, task/plan atomic creation, ordinary child delegation, import/reparenting rejection under conversations, mode restrictions, cancellation, repository URL normalization, and committed project cards. The ordinary task review-path guard now exempts conversations; the server owns their waiting state after a successful reply. The chat directive explicitly tells agents to reply and end their turn without inventing a reviewer or changing status.
|
||||
|
||||
Five focused Codex live evals passed: existing-project reuse, new project/task handoff, multiple repository URLs, plan-only drafting, and authorized repository discovery. Four provider-free contract evals passed for retries, missing access, Ask-mode denial, and persisted handoff plans. The companion harness has 30 passing tests. The qualified Claude eval profile could not start on macOS without its explicit eval credential (it additionally requires Linux x64); it was not bypassed.
|
||||
|
||||
A separate local Claude agent drafted and revised a chat plan, created Garden Club Demo through the dedicated project tool, and created normal assigned task AGE-7 with its initial plan. The plan was persisted at 16:47:51.426 UTC before execution started at 16:47:51.492 UTC; the task completed with an output document and the original chat plan remained. Local Codex created Repository URL Demo with two URLs absent from its catalog; both appeared on the inline card and project configuration. The card persisted across reload and `/new`. Light and dark production-composition stories were inspected in the browser.
|
||||
|
||||
The broad general-server run reported 8,362 passing tests and two failures from pre-fix modules cached before the review guard and explicit-workspace card changes. The fresh current-source API run passed all 21 tests across four files, including both regressions. Remaining repository groups are verified separately so the initial monolithic exit is not represented as a clean pass.
|
||||
|
||||
The full UI lane passed 5,626 tests and the CLI passed 484. The shared and skills-catalog projects passed. The remaining database/adapter/plugin group passed 2,365 tests; a migration startup failure passed alone (1 test), after reducing workers to avoid embedded-Postgres contention. Existing unsupported integration tests remained skipped.
|
||||
|
||||
Both serialized server shards are now verified: all 144 suites passed across their final runs/resumed segments. An outdated project-route mock and the new MCP transport's missing OpenAPI inventory entry were corrected; embedded-Postgres startup failures passed in isolated retries. The API catalog now includes the task-run-only MCP transport and points project discovery/creation to their dedicated tools; its focused suite passed 824 tests. The catalog census has 792 operations (555 authored REST contract cases).
|
||||
|
||||
Repository-wide typecheck and build, Storybook build, and token gates passed. The final API metadata change also passed server typecheck/build. Two follow-up Codex live cases passed with the final directive, and all 11 retained deterministic/live artifacts passed the stronger persisted-state scoring, including detection of unintended tasks created through API fallback. These results do not turn the earlier failed monolithic test command into a clean run.
|
||||
|
||||
|
||||
### 2026-09-11: E2E regression coverage
|
||||
|
||||
Persistent conversations now have dedicated `tests/e2e/agent-chat.spec.ts`
|
||||
coverage using a deterministic process adapter against a disposable real server.
|
||||
The authenticated suite additionally checks separate canonical chats, personal
|
||||
stars/recency, shared company visibility, and cross-company denial for two people.
|
||||
The runner catalog registers `agent-chat`: six scenarios on four local
|
||||
Codex/Claude profiles (24 paid cells). See `tests/runner-e2e/README.md` for launch
|
||||
commands, credential preflight, evidence, and reset/child-run accounting.
|
||||
|
||||
Browser testing identified a company-cache shape mismatch in chat live updates
|
||||
and a dropped reset marker in compact run summaries. Preserve the shared cache
|
||||
contract and `conversationReset` summary field so messages refresh live and reset
|
||||
boundaries do not render empty model-completion notices.
|
||||
|
||||
Local acceptance on 2026-09-11: all 20 deterministic chat scenarios and two
|
||||
existing repository browser scenarios passed against a fresh test instance.
|
||||
The new authenticated two-person scenario passed independently. Runner fixture
|
||||
checks passed (121 tests), and the live-update/run-summary regression checks
|
||||
passed (46 tests). Repository typecheck, build, Storybook build, and token gates
|
||||
passed. Paid Codex and Claude smoke attempts failed credential preflight because
|
||||
`OPENAI_API_KEY` and `ANTHROPIC_API_KEY` were unavailable; the 24-cell matrix is
|
||||
registered but has no claimed paid passing coverage from this run.
|
||||
|
||||
|
||||
### 2026-09-11: Paid runner regression fixes
|
||||
|
||||
The first GitHub campaign exercised all 24 cells and exposed provider-session,
|
||||
queue/lifecycle, plan-review, and shared-feed issues. Follow-up work uses focused
|
||||
provider-free regressions first, then individual paid cells on disposable
|
||||
instances; the running demo remains untouched.
|
||||
|
||||
Claude session serialization now retains its MCP server identity. Conversation
|
||||
containers ignore dependency and child-completion wakes, while pending questions
|
||||
and plan reviews count as durable replies and settle the conversation to waiting.
|
||||
Rejected plan feedback is included in both full and resumed prompt assembly;
|
||||
acceptance resolves the implicit current-task target and hands off the selected
|
||||
plan revision before execution begins.
|
||||
|
||||
Native provider handling preserves FIFO events and terminal schema, projects
|
||||
committed normal replies into chat, and verifies ownership when a restored ACPX
|
||||
session lazily launches its provider during model selection. Linux Codex preflight
|
||||
uses an exact executable AppArmor profile and a provider-free sandbox probe. The
|
||||
focused GitHub campaign `34638268637` passed native Codex continuity/restart and
|
||||
fresh-session reset on both selected cells.
|
||||
|
||||
The shared project card hydrates repository links from the authorized project
|
||||
record while retaining its original durable creation receipt. Regression coverage
|
||||
checks a second repository arriving after creation, reload, and `/new`. Handoff
|
||||
fixtures check committed repository workspaces and actual output documents rather
|
||||
than assuming URL registration adds an entry to the external connection catalog
|
||||
or requiring an unspecified output document key. Failure classification avoids
|
||||
paid retries for explicit non-retryable provider-session failures.
|
||||
|
||||
All 20 deterministic chat browser scenarios and Storybook build passed after
|
||||
these fixes. Focused live checks additionally passed legacy Codex project reuse
|
||||
and repository handoff, legacy Claude plan revision/acceptance/handoff, and native
|
||||
Claude planning, Stop/reset/resume, fresh sessions, and multiple repositories.
|
||||
Final campaign results and broad verification are recorded below when complete.
|
||||
|
||||
The next full campaign (`34640536416`) reached 18/24 passing cells and identified
|
||||
three additional issues. Execution prompts now include the task's persisted plan
|
||||
and selected revision on both fresh and resumed runs; a plan handed off without a
|
||||
description therefore still reaches its executor. Native durable redaction keeps
|
||||
explicit literal/exact acceptance identifiers while continuing to redact actual
|
||||
credential-shaped values. Recovery for an older conversation generation or an
|
||||
already answered turn cannot block a reset or healthy idle chat. Regression tests
|
||||
also preserve recovery for current unanswered turns and unprepared failures.
|
||||
|
||||
Fixture assertions now accept concrete clarification requests without requiring a
|
||||
question mark. They check the approved revision and final execution output rather
|
||||
than rejecting an old draft quoted in plan revision history. Restart verification
|
||||
opens the canonical chat route after reconnecting, preserving the continuity and
|
||||
no-unsolicited-run checks. Stable inconsistent idle states fail promptly instead
|
||||
of waiting through a long timeout and hiding a product race behind a paid retry.
|
||||
Focused native Claude project reuse and multiple-repository handoffs, and legacy
|
||||
Claude multiple-repository handoff, passed on their first attempts with these fixes.
|
||||
|
||||
The focused legacy Claude Stop/reset/resume regression also passed on its first
|
||||
attempt. Latest repository-wide typecheck, build, and token gates passed. Final
|
||||
runner fixture checks passed 151 tests; fresh chat/prompt/recovery checks passed
|
||||
209 tests, and the native session executor file passed 207 tests. Broad local
|
||||
verification is recorded as resumed groups rather than a clean monolithic run:
|
||||
the original command encountered source edits during execution, generated-evidence
|
||||
scanner input, and cold-import/process-startup timeouts under concurrent load.
|
||||
The guidance scanner now excludes only generated runner evidence and has a
|
||||
regression proving authored runner guidance remains scanned. Focused UI, database,
|
||||
publication, and canonical-path CLI reruns passed without product changes.
|
||||
|
||||
Broader adapter verification exposed OpenCode test fixtures reading the developer's
|
||||
real configuration directory. Those fixtures now allocate and restore isolated
|
||||
XDG configuration directories; all 44 source tests and package typecheck pass.
|
||||
The remaining workspace projects were run even after earlier groups stopped at a
|
||||
failure, and the original failure logs remain available alongside focused reruns.
|
||||
|
||||
Campaign `34642700703` passed 19/24 cells. Its remaining failures were traced to
|
||||
one clarification-oracle phrasing, revision-write guidance, runner teardown after
|
||||
a successful restart, and native mutation content passing through diagnostic
|
||||
redaction. The clarification fixture now also recognizes substantive requests
|
||||
for a brief or details. Revision instructions and HTTP conflict errors explicitly
|
||||
map the GET `latestRevisionId` to PUT `baseRevisionId`; a live Codex
|
||||
plan/revise/accept/handoff run passed on its first attempt with that fix.
|
||||
|
||||
Playwright now gives the restart supervisor a bounded SIGTERM shutdown so it can
|
||||
reap children and close log streams. A real zero-provider Playwright regression
|
||||
verifies restart, child process exit, and port closure; cleanup failure still
|
||||
fails the campaign. Native schema-declared task/project/document prose retains
|
||||
its complete contents while credentials and diagnostic data remain scrubbed.
|
||||
Regression coverage includes long plans beyond the diagnostic preview limit.
|
||||
The macOS fake Anthropic service now clears inherited nonblocking socket mode
|
||||
before its bounded request read; all 271 Rust library tests passed afterward.
|
||||
|
||||
All 144 serialized server suites have passing coverage across the resumed shards
|
||||
and focused reruns. Three route fixtures moved cold module imports into bounded
|
||||
setup hooks, preserving their HTTP assertion timeouts; the final affected files
|
||||
passed 119 tests. The completed workspace groups likewise have passing focused
|
||||
reruns for every observed failure. These results are recorded alongside, rather
|
||||
than replacing, the earlier failed monolithic invocation.
|
||||
|
||||
The ACPX sidecar decoder was an additional execution boundary: it applied generic
|
||||
diagnostic redaction before the native semantic-input stage. It now uses the same
|
||||
schema-declared prose policy at decode. The regression feeds a real
|
||||
`runtime.tool_called` event through decoding, pending-call state, and semantic
|
||||
projection, checking complete long-plan contents, protected credentials, unknown
|
||||
operation handling, and matching content digests. The decoder/state checks passed
|
||||
22 tests and durable-state checks passed 30 tests before the next paid campaign.
|
||||
|
||||
The final local native Claude repository handoff preserved the exact previously
|
||||
corrupted task description, plan, and execution output. Its product assertions
|
||||
passed on the first attempt; post-run secret scanning then exposed PostgreSQL
|
||||
removing `instances/<id>/db/postmaster.pid` after directory enumeration. Only
|
||||
ENOENT for that exact transient path is now tolerated. Existing PID contents,
|
||||
other scan errors, mandatory evidence, and process/lease cleanup remain enforced.
|
||||
All 157 runner fixture tests and final repository typecheck/build passed.
|
||||
Campaign `34645293835` tests the complete set of fixes.
|
||||
|
||||
Campaign `34645293835` passed 20/24 cells. Two failures exposed narrow lifecycle
|
||||
races: a successful native chat turn could be mistaken for productive unfinished
|
||||
work before response publication, and an agent comment deferred behind an active
|
||||
execution could wake its assignee after that execution completed. Recovery now
|
||||
leaves the first case to the conversation finalizer; queue promotion cancels the
|
||||
stale terminal-task continuation while retaining human reopening and notifications
|
||||
to other agents. The recovery regression fails with the guard removed and passes
|
||||
with it restored; all 20 comment-wake batching tests and server typecheck pass.
|
||||
|
||||
The other failures distinguish requested approval from ordinary draft planning,
|
||||
and a persisted Paperclip document from a workspace file. The chat directive now
|
||||
explains how to create a revision-bound approval card when explicitly requested,
|
||||
including after a revision. Paid fixtures name the requested Paperclip document
|
||||
explicitly while retaining strict checks of approvals, transferred plans, and
|
||||
persisted execution output.
|
||||
|
||||
Native reconciliation also preserves assessment lineage within its owning run
|
||||
when the task's previous status decision belongs to a different run. Decision
|
||||
lineage still spans runs; the database ownership constraint remains unchanged.
|
||||
The regression reproduces the original foreign-key failure without the fix and
|
||||
passes for absent, same-run, and different-run predecessors with it. The next
|
||||
24-cell campaign is `34646672139`, pinned to `3556fa25f`.
|
||||
|
||||
Campaign `34646672139` passed 23/24 cells: all native cases and all legacy Claude
|
||||
cases passed. The remaining legacy Codex plan-revision failure exposed an adapter
|
||||
prompt omission. Its resume delta discarded the server's task-context Markdown,
|
||||
including both the chat directive and document-concurrency guidance. Codex now
|
||||
selects the same full/compact task-context Markdown as Claude on initial and
|
||||
resumed sessions. Both adapters suppress generic task-completion and child-task
|
||||
planning directives in chat, leaving the central chat policy authoritative.
|
||||
The approval and output assertions remain unchanged.
|
||||
|
||||
Fresh chat prompts use a small conversation-safe default template that retains
|
||||
connection guidance, permissions, budgets, cancellation, and mutation honesty.
|
||||
Explicit custom agent templates remain intact. Native execution and continuation
|
||||
prompts also carry the conversation flag so shared wake rendering cannot reinsert
|
||||
ordinary completion/subtask instructions. The integration regression inspects
|
||||
both fake-CLI stdin and the recorded adapter invocation with the production chat
|
||||
directive; removing the task-context section reproduces the failure. Shared prompt
|
||||
checks (102), actual Codex prompt cases (3), native resume checks (11), affected
|
||||
package typechecks, and server typecheck pass. Campaign `34648511170` tests all
|
||||
24 cells on `abacbdfd2`.
|
||||
|
||||
The complete Codex/Claude execution regression files passed 46 tests. Final
|
||||
repository-wide typecheck and build also passed on `abacbdfd2`, after all prompt
|
||||
changes.
|
||||
|
||||
Final paid verification: campaign `34648511170` passed **24/24** chat cases on
|
||||
`abacbdfd2`: legacy Codex 6/6, legacy Claude 6/6, native Codex 6/6, and native
|
||||
ACPX Claude 6/6. All cells completed by 21:34 UTC on September 11, within the
|
||||
requested three-hour repair window. No acceptance assertions were disabled.
|
||||
|
||||
- [Exact campaign results](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-34648511170-1/summary.md)
|
||||
- [GitHub run and retained evidence](https://github.com/paperclipai/paperclip/actions/runs/34648511170)
|
||||
|
||||
The [HTML dashboard](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-34648511170-1/index.html?report=agent-chat#suite-agent-chat)
|
||||
was repaired from retained evidence after its older trusted catalog omitted the
|
||||
branch-only suite. It now includes the chat suite and 32 screenshots, including
|
||||
eight draft/revised plan captures recovered from their original Playwright
|
||||
attachments. No paid cells were rerun; result records, tested SHA, timestamps,
|
||||
usage, billing, attempts, and cleanup outcomes remain unchanged.
|
||||
|
||||
Reporting now discovers validated display-only entries for unknown selected
|
||||
execution IDs, and publication rejects missing declared screenshots. The exact
|
||||
chat plan filenames are included in packaged evidence. All 165 runner unit tests
|
||||
and runner TypeScript checks passed. Browser verification covered suite
|
||||
filtering, restored plan images, and gallery navigation. This explicitly
|
||||
authorized repair replaces only this campaign's report objects; normal
|
||||
immutable-publication protections remain unchanged.
|
||||
|
||||
The published summary and normalized results were verified after publication:
|
||||
exactly 24 unique expected cells, all passed on attempt 1, all cleanup checks
|
||||
passed, all evidence valid with no evidence errors, and every result bound to
|
||||
`abacbdfd2f660709ec37312cdb758284c8399d04`. The public report returned HTTP 200.
|
||||
Reference in new issue
Block a user