mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 13:24:55 +01:00
merge: integrate agent lifecycle ownership from master
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
commit
ad5d8826ad
159 files changed
+7173
-2805
No files matched your search
@@ -0,0 +1,264 @@
|
||||
# Agent lifecycle
|
||||
|
||||
The agent lifecycle module controls hiring, pause, resume, and termination.
|
||||
Its public entry point is `server/src/modules/agent-lifecycle/index.ts`.
|
||||
Use its commands to create an agent or change its lifecycle state.
|
||||
Do not pass a database transaction to a command.
|
||||
Each hire or transition command owns its transaction.
|
||||
|
||||
## Application use
|
||||
|
||||
Application code imports the configured factory from `services/agent-lifecycle.ts`.
|
||||
This service supplies the module dependencies. Use the root database connection.
|
||||
Apply the existing caller authorization checks before you call a command.
|
||||
|
||||
```ts
|
||||
import { createAgentLifecycle } from "../services/agent-lifecycle.js";
|
||||
|
||||
const lifecycle = createAgentLifecycle(db);
|
||||
await lifecycle.updateConfiguration(agentId, { title: "Engineer" });
|
||||
await lifecycle.pauseAgent(agentId);
|
||||
const state = await lifecycle.get(agentId);
|
||||
```
|
||||
|
||||
The pause command records the request. The worker completes the external steps.
|
||||
Read `lifecycleState` to check progress.
|
||||
Configuration updates accept only the fields in `AGENT_CONFIGURATION_FIELDS`.
|
||||
They reject identity, company, accounting totals, timestamp, and lifecycle fields.
|
||||
The public update schema also rejects spend totals. Budget limit changes remain
|
||||
permitted through `budgetMonthlyCents`.
|
||||
|
||||
Do not import module adapters or construct module dependencies in a caller.
|
||||
The company deletion service uses the separate deletion entry point.
|
||||
The listed configuration workflows use the restricted transaction service.
|
||||
These are the only transaction integrations. They are described below.
|
||||
|
||||
## States
|
||||
|
||||
| State | Meaning | Next state |
|
||||
| --- | --- | --- |
|
||||
| `pending_approval` | The hire needs board approval. | `preparing` or `rejected` |
|
||||
| `preparing` | Required plugins prepare the agent. | `verifying` |
|
||||
| `verifying` | The host tests the saved harness configuration. | `ready` |
|
||||
| `ready` | The lifecycle permits work. | `pausing` or `terminating` |
|
||||
| `pausing` | The host stops work. Required plugins stop their resources. | `paused` |
|
||||
| `paused` | A pause hold prevents work. | `resuming` or `terminating` |
|
||||
| `resuming` | Required plugins start their resources. | The state saved before pause |
|
||||
| `terminating` | The host revokes keys and stops work. | `cleaning_up` |
|
||||
| `cleaning_up` | Required plugins remove their resources. | `terminated` |
|
||||
| `terminated` | Termination is complete. | None |
|
||||
| `rejected` | The board rejected the hire. | None |
|
||||
|
||||
Termination can start before preparation or verification completes.
|
||||
An old result cannot complete a newer operation.
|
||||
Deletion requires completed termination or a rejected hire.
|
||||
The existing restrictions for built-in agents and accounting still apply.
|
||||
|
||||
## Commands and transactions
|
||||
|
||||
`requestHire` writes the agent record before preparation starts.
|
||||
An approved hire starts preparation after the transaction commits.
|
||||
A proposed hire waits for `approveHire`.
|
||||
`approveHire` and `rejectHire` accept an agent ID or `{ approvalId }`.
|
||||
Both forms use the same hire decision path. An agent ID also resolves its open
|
||||
hire approval. The approval and the agent change commit together.
|
||||
The existing company approval rules still apply.
|
||||
|
||||
`pauseAgent`, `resumeAgent`, and `terminateAgent` record the requested change.
|
||||
They do not wait for external resource operations.
|
||||
`retry` makes a failed step available for another attempt.
|
||||
`reconcilePolicyHolds` updates budget and company holds for the specified company.
|
||||
The background policy check processes at most 100 eligible agents each minute.
|
||||
It continues from the last agent ID and returns to the start after the last page.
|
||||
Pending hires and agents in termination or a final state are excluded.
|
||||
An explicit company or budget change still updates all affected agents immediately.
|
||||
`updateAndTransition` applies a configuration change and a lifecycle command
|
||||
in one transaction. A failed command does not save the configuration change.
|
||||
|
||||
The onboarding and invitation services own their feature workflows.
|
||||
They commit the hire through `requestHire` before they save the other records.
|
||||
A separate database transaction holds only the workflow lock.
|
||||
It prevents concurrent requests for the same workflow.
|
||||
The hire command commits through its own connection and transaction.
|
||||
A failure in the lock transaction cannot undo a committed hire.
|
||||
If a later step fails, a retry uses the existing agent.
|
||||
The onboarding revision is saved only after its content and audit record commit.
|
||||
|
||||
The approval service owns comments, revisions, and general approval records.
|
||||
The lifecycle module resolves a hire approval and changes the agent in one
|
||||
transaction. It retains the original credential owner when it approves a hire.
|
||||
|
||||
The company deletion service owns the company data cascade.
|
||||
It requests agent termination before it starts that cascade.
|
||||
It locks the company in the deletion transaction and removes dependent records.
|
||||
It then calls `agentLifecycleCompanyDeletion.deleteCompanyData(tx, companyId)`
|
||||
through the module's separate `company-deletion.ts` entry point.
|
||||
This operation implements the shared `CompanyDeletionParticipant` interface.
|
||||
It locks the agent rows, checks their states, and deletes them.
|
||||
All agents must be terminated or rejected. Otherwise, it throws an error.
|
||||
The error rolls back all database changes in the deletion transaction.
|
||||
A concurrent hire makes deletion fail or waits until deletion ends.
|
||||
The module's delete statement also restricts removal to terminated or rejected agents.
|
||||
`purgeAgent` deletes a single agent. It owns the transaction and checks the agent
|
||||
state before it calls the service to remove dependent records.
|
||||
The service checks accounting holds. The module then deletes the agent record.
|
||||
An error rolls back both operations. Neither path permits incomplete termination.
|
||||
|
||||
The ordinary agent service owns reads, permissions, and keys.
|
||||
The configuration service owns validation and configuration revisions.
|
||||
The lifecycle module owns the agent configuration write.
|
||||
Credential checks remain in the agent credential service.
|
||||
Secret proposal approval saves the secret before it applies the agent binding.
|
||||
If the binding fails, the secret remains approved and the binding remains pending.
|
||||
A retry uses the approved secret. It does not create another secret.
|
||||
The binding transaction checks authorization, expiry, and the current reporting
|
||||
structure again before it changes the agent.
|
||||
The hire service owns names, appearance, permissions, credential binding,
|
||||
connection installs, identity setup, and primary-agent selection.
|
||||
The module calls the hire service before and after the agent record write.
|
||||
These operations use the lifecycle transaction. A failed operation rolls back
|
||||
the hire and its dependent records.
|
||||
The module owns the initial state, approval transition, and lifecycle events.
|
||||
The service in `services/agent-lifecycle.ts` supplies these integrations to the
|
||||
module. The module does not import services or routes. Shared record queries
|
||||
and validation functions are in `lib/`. They do not call lifecycle commands.
|
||||
The application supplies the worker driver at startup.
|
||||
`updateConfiguration` owns the transaction for an ordinary configuration update.
|
||||
The module locks the agent. The configuration service validates and prepares the
|
||||
patch. The module saves it and invalidates an old verification result when
|
||||
execution configuration changes during setup. The service then updates dependent
|
||||
records and saves the configuration revision in the same transaction.
|
||||
There is no separate invalidation operation for callers.
|
||||
Configuration writes reject caller-supplied lifecycle fields.
|
||||
For `updateAndTransition`, lifecycle owns the transaction and calls the
|
||||
same configuration operation. Both changes commit together.
|
||||
|
||||
Some workflows must save an agent reference and their own records together.
|
||||
The module exposes `configuration.ts` for these transactions. Only
|
||||
`services/agent-configuration-transaction.ts` can import it.
|
||||
This service supplies the module integrations. It cannot save a configuration
|
||||
without the module's invalidation check.
|
||||
Its permitted callers are secret binding approval, Connection adoption, runner
|
||||
pairing, avatar updates, instruction revisions, and skill reassignment.
|
||||
The boundary check lists these callers. Ordinary callers use the root command.
|
||||
Budget changes always use a root command so enforcement follows the commit.
|
||||
The transaction integration cannot approve, pause, resume, or terminate an agent.
|
||||
It does not start a worker before the caller commits. The periodic scan recovers
|
||||
pending setup work after the commit.
|
||||
|
||||
Manual, budget, and company pause holds are independent.
|
||||
A manual resume does not remove a budget or company hold.
|
||||
Restoring a company does not remove a manual hold.
|
||||
Budget and company policy still prevent admission while the pause work runs.
|
||||
|
||||
The legacy `status` field remains available to existing clients.
|
||||
It shows `paused` during preparation, verification, pause, and resume.
|
||||
It shows `terminated` as soon as termination starts.
|
||||
Execution code can change this field only when the lifecycle is `ready`.
|
||||
Use `lifecycleState` to distinguish the steps.
|
||||
This change does not change the user interface.
|
||||
|
||||
## Required plugin work
|
||||
|
||||
A plugin can declare `agentLifecycle: true` in its manifest.
|
||||
It must also request `agents.lifecycle.manage`.
|
||||
The plugin implements `onAgentLifecycle` in the SDK.
|
||||
This method is separate from event delivery and event acknowledgment.
|
||||
|
||||
The host selects the required plugins before the first lifecycle step.
|
||||
`setRequiredPlugins` stores their IDs on the agent.
|
||||
The host is not a plugin ID. Each operation records host completion and
|
||||
completed plugin IDs separately. The host step must finish before plugin calls.
|
||||
A disabled or removed plugin cannot silently release an existing requirement.
|
||||
Restore that plugin to complete the operation.
|
||||
A later plugin installation does not change an existing selection.
|
||||
|
||||
Each request contains these fields:
|
||||
|
||||
- `companyId` and `agentId` identify the agent.
|
||||
- `phase` identifies the lifecycle step.
|
||||
- `operationId` identifies the operation.
|
||||
- `version` identifies the state revision.
|
||||
|
||||
Return the same `operationId` and `version` with `status: "complete"` or
|
||||
`status: "pending"`.
|
||||
Return `complete` only after the requested effect is complete.
|
||||
Return `pending` while external work continues.
|
||||
Throw an error when the step fails.
|
||||
The host stores a fixed error message. It does not store the provider error text.
|
||||
Server logs identify the failed step, phase, operation, and plugin when available.
|
||||
They include only known error codes. Unknown codes become `unclassified`.
|
||||
They do not include provider messages, stacks, or configuration values.
|
||||
A failure before the agent is read can have only a step and agent ID.
|
||||
A scan failure has no agent ID.
|
||||
|
||||
Calls can repeat after a timeout or a server restart.
|
||||
A plugin must make repeated calls safe.
|
||||
It must retain the highest version for each company and agent.
|
||||
It must reject an older request after it accepts a newer version.
|
||||
It must also prevent an older operation from creating resources after cleanup.
|
||||
Serialize external effects or remove resources from a late completion.
|
||||
Do not treat a host timeout as cancellation of the external effect.
|
||||
|
||||
## Verification and recovery
|
||||
|
||||
The harness verification service uses the existing environment-test code.
|
||||
It owns test configuration, credential selection, and test result checks.
|
||||
It tests the saved agent configuration and the selected environment.
|
||||
A failed login or an incomplete probe cannot complete verification.
|
||||
The lifecycle module receives completion, pending work, or failure through its
|
||||
driver. It owns the state transition and has no harness test rules.
|
||||
The current UI can also run a test before the hire.
|
||||
Some adapters can charge for these tests.
|
||||
It uses the saved responsible user for managed credentials.
|
||||
The host does not grant new credential access for this test.
|
||||
A connection pool selects an account for a separate lifecycle test operation.
|
||||
An external controller must complete its existing readiness test.
|
||||
|
||||
Task requests can enter the durable run queue during preparation, verification,
|
||||
and resume. Execution waits for readiness. Queue recovery does not require
|
||||
periodic agent heartbeats to be enabled.
|
||||
|
||||
A cancelled run record does not prove that execution stopped.
|
||||
The host also checks process ownership, controller leases, and environment cleanup.
|
||||
Required plugin cleanup cannot start while these checks are incomplete.
|
||||
|
||||
The worker starts after a committed command.
|
||||
A periodic scan recovers work after a process stops.
|
||||
A database lease permits one active attempt for each agent.
|
||||
The worker renews that lease during external calls.
|
||||
Each result must match the current revision and lease owner.
|
||||
Shutdown waits for active work.
|
||||
|
||||
The agent API returns `lifecycleState`, `lifecycleVersion`, and `lifecycleError`.
|
||||
A board user can retry through `POST /api/agents/:id/lifecycle/retry`.
|
||||
The route applies the existing company access checks.
|
||||
|
||||
## Existing installations
|
||||
|
||||
Migration `0320_daily_onslaught.sql` maps the current status of each agent.
|
||||
Active execution states become `ready`.
|
||||
Paused, pending, and terminated agents retain their current meaning.
|
||||
The migration retains each existing pause reason as a hold.
|
||||
It does not provision external resources or record a successful harness test.
|
||||
Resource backfill is a separate task.
|
||||
|
||||
Run the normal database migration process before starting the new server.
|
||||
Stop older server processes during the change.
|
||||
An older process can write the legacy status without the new lifecycle checks.
|
||||
|
||||
`pnpm check:module-boundaries` checks the module imports and agent writes.
|
||||
Tests and migration fixtures can write records directly.
|
||||
Production creation and lifecycle state writes must use the lifecycle module.
|
||||
Production record deletion must also use the lifecycle module.
|
||||
Execution configuration writes must use the module. The offline worktree seed
|
||||
command can disable timers in a copied database before the server starts.
|
||||
|
||||
## Extension rules
|
||||
|
||||
Add a lifecycle command to the module entry point. Put state transition rules in
|
||||
`domain/policy.ts`. Put database operations in the module adapters.
|
||||
Keep harness and provider rules in services. Supply external work through the
|
||||
worker driver. Report completion only after that work is complete.
|
||||
Add a test for a failed or repeated operation. Run `pnpm check:module-boundaries`
|
||||
to check the import and write boundaries.
|
||||
@@ -6,7 +6,17 @@ It binds master's shared protocol-validation sources without changing the
|
||||
executable or supplying new paid qualification. Historical checkpoints below
|
||||
retain their original identities and outcomes.
|
||||
|
||||
Historical source candidate (2026-10-01): **Copilot profile v12 is unqualified**.
|
||||
Historical source candidate (2026-10-02): **Copilot profile v13 is unqualified**.
|
||||
Pi's explicit reasoning-mode support changed four shared transport and schema
|
||||
source files included in Copilot's execution identity. Version 13 records those
|
||||
source hashes with digest
|
||||
`sha256:3ff08fbe76fe4549c9eb01e8794428d8909c65c151d775220f2ec111d9e6f7c1`.
|
||||
The Copilot executable closure, model and provider behavior are unchanged. The
|
||||
historical v12 declaration is preserved; v12 warm sessions are rejected by the
|
||||
current candidate. This identity update supplies no new paid qualification.
|
||||
Fresh runtime packages and local/Daytona qualification remain required.
|
||||
|
||||
Historical source candidate (2026-10-01): **Copilot profile v12 was unqualified**.
|
||||
Receipt v2 preserves the original `inputSha256` and separately captures
|
||||
`normalizedInputSha256` from the same invocation's validated outgoing body.
|
||||
For the native sidecar, only a successful, correlated `tool.resolve` commits
|
||||
|
||||
@@ -22,7 +22,92 @@ for the exact source/image evidence and merge status.
|
||||
All dated checkpoints below describe historical qualification attempts. Their
|
||||
failures and profile numbers are retained; they are not current release gates.
|
||||
|
||||
## Historical Pi 1.0 candidate (2026-10-02, profile v12)
|
||||
## Historical Pi 1.0 candidate (2026-10-02, profile v13)
|
||||
|
||||
Pi remains pinned to **`@earendil-works/pi-coding-agent@1.0.0`**, with
|
||||
`pi-acp@0.0.33`, ACPX `0.13.1`, and Node `24.21.0`. Profile 13 adds explicit
|
||||
reasoning-mode selection and rejects previous profile identities. It is a new
|
||||
qualification candidate; profile-12 results below remain historical evidence.
|
||||
|
||||
Pi's new field also changes four shared files covered by Copilot's source
|
||||
identity. Copilot therefore advances to a still-unqualified profile v13 without
|
||||
changing its executable or model. Pi's profile-13 identity and native closure
|
||||
remain unchanged. Final artifacts must bind the corrected source; the initial
|
||||
ARM startup and 61 contract passes alone do not establish production readiness.
|
||||
|
||||
The normal Pi configuration records `piThinkingLevel` as `off`, `low`, `high`,
|
||||
or `max`. New configurations and qualification cases explicitly select `low`.
|
||||
The runner binds that setting to the session identity and requires native
|
||||
confirmation of the effective level before sending the prompt, including after
|
||||
session restoration. An unsupported level, absent acknowledgement, or effective
|
||||
level different from the requested value must fail admission. Changing the
|
||||
level requires a new compatible session; a warm session cannot silently retain
|
||||
its previous setting.
|
||||
|
||||
The wrapper obtains available levels from Pi's native
|
||||
`get_available_thinking_levels` RPC, exposes them through ACP session modes and
|
||||
the `thought_level` configuration option, and confirms changes with native
|
||||
`get_state`. This avoids advertising the static `minimal`, `medium`, or `xhigh`
|
||||
aliases when the selected model does not support them. For the pinned DeepSeek
|
||||
model, Pi 1.0 supports `off`, `low`, `high`, and `max`. Pi's implicit `medium`
|
||||
default resolves to `high`; Pi 0.84.2 also resolved that default to `high`, so
|
||||
this is a configuration gap rather than evidence of a new Pi 1.0 default.
|
||||
|
||||
The [provider-free wire proof](../../packages/paperclip-runner/test-fixtures/pi-acp/thinking-modes.v13.darwin-arm64.json)
|
||||
records actual Pi 1.0 request bodies changing from `high` to `low` through ACP,
|
||||
truthful `max` restoration, blocked non-loopback connections, and owned-process
|
||||
retirement. Synthetic responses establish propagation, not paid qualification.
|
||||
|
||||
The paid profile-12 hello passed in the actual installed application. Its first
|
||||
question continuation failed at the unchanged 120-second native deadline after
|
||||
1,019 reasoning deltas and no emitted tool call or question. The required tool
|
||||
was present with its exact schema. This establishes model activity without the
|
||||
required interaction; it does not prove the reasoning setting caused the timeout.
|
||||
The test remains failed. Profile-13 deterministic, local paid, Runner, native
|
||||
control, and Daytona results must be established independently.
|
||||
|
||||
| Capability | Native / ACP surface | Paperclip surface | Remaining boundary |
|
||||
| --- | --- | --- | --- |
|
||||
| Supported thinking levels | `get_available_thinking_levels`; ACP available session modes and `thought_level` choices | Pi reasoning-level configuration | Model selection is explicit and unrestricted; historical qualification used the recorded model and level. |
|
||||
| Set and verify thinking level | Native `set_thinking_level`, then `get_state`; ACP `session/set_mode` / config option | Saved agent setting, typed runner input, effective-mode admission | Live setting changes during an active turn are not exposed; a new compatible session is required. |
|
||||
| Recover selected level | Native restored state plus explicit effective-level verification | Mode-bound durable session identity | Old profiles and missing or mismatched mode identity cannot reuse a warm session. |
|
||||
| Provider notice severity and pricing provenance | `paperclip/pi_notice` and canonical `provider.notice.recorded` | Retained run event, usage metadata, and safe summary with severity in the activity row | Summary/severity rendering has deterministic coverage; paid visual verification of the rebuilt UI remains pending. Pricing estimates remain distinct from provider billing receipts. |
|
||||
|
||||
## Historical profile-13 qualification checkpoint (2026-10-02)
|
||||
|
||||
The installed candidate from source `eac50643213d0902a93a5384bae2f1d6c065c9f2`
|
||||
uses Pi 1.0.0, the explicit OpenRouter DeepSeek model above, and verified `low`
|
||||
reasoning. Paid local Product E2E passes cover hello, semantic question/answer
|
||||
continuation, all four native question forms, and human permission denial with
|
||||
no file side effect. The paid extended Runner `get-task-context` case also
|
||||
passes through the packaged runner against its authenticated, seeded test
|
||||
control plane. Runner protocol evidence does not qualify the Product UI.
|
||||
|
||||
Three local attempts remain failed: file-edit validation, pending-input
|
||||
controller restart, and three-turn warm continuation. The first two exposed
|
||||
assertion gaps: streamed command output supplies the exit receipt, and a
|
||||
pre-start submission may precede assignment of the native turn ID. Narrow
|
||||
fixture repairs have positive and negative coverage; neither failed attempt
|
||||
has been regraded and both require fresh live runs.
|
||||
|
||||
The warm attempt completed its first turn and edited files on its second, but
|
||||
its final semantic tool stayed pending until the existing deadline. OpenRouter
|
||||
metadata joins the exact native session and records the final response as
|
||||
cancelled with no finish reason. This supports an unfinished upstream response
|
||||
at cancellation; it does not establish why the response stopped progressing.
|
||||
A real pinned SDK/wrapper replay proves both restored-session completion with
|
||||
the new agent home and completion contract, and safe cancellation when complete
|
||||
tool JSON arrives without the provider's stream finish marker. The latter
|
||||
executes no semantic mutation. No timeout or runtime policy was changed to make
|
||||
that replay pass.
|
||||
|
||||
Fresh builds must incorporate the subsequent launch, UI, and fixture fixes.
|
||||
macOS Intel startup, the remaining local and Runner cases, Linux/Daytona, and
|
||||
final source-wide checks remain qualification gates. The provider remains
|
||||
unqualified until that evidence is complete. API-key usage observations cover
|
||||
the capped qualification campaign; native pricing estimates are not bills.
|
||||
|
||||
## Historical Pi 1.0 profile-v12 checkpoint (2026-10-02)
|
||||
|
||||
The candidate now pins **`@earendil-works/pi-coding-agent@1.0.0`** with
|
||||
`pi-acp@0.0.33`, ACPX `0.13.1`, and portable Node `24.21.0`. Pi v11 and older
|
||||
@@ -97,6 +182,76 @@ Pi's published CLI mode union is `text | json | rpc`; no native ACP mode is
|
||||
present in this release. The reviewed `pi-acp` wrapper remains necessary.
|
||||
|
||||
|
||||
## Explicit Linux companion setup for a Mac controller
|
||||
|
||||
A Mac controller needs independently verified Linux runner bytes for Daytona.
|
||||
Its host Pi installation is not a Linux provider pack. The operator imports a
|
||||
release companion once, before launching agents:
|
||||
|
||||
```sh
|
||||
paperclipai runtime import-remote /path/to/release/linux-x64 --sha256 MANIFEST_SHA256
|
||||
```
|
||||
|
||||
Obtain `MANIFEST_SHA256` from the trusted release channel, separately from the
|
||||
copied directory. The directory contains `companion.json`,
|
||||
`bin/paperclip-runnerd`, and the complete `provider-pack/`. Import verifies the
|
||||
installed server's exact build commit, qualified Pi profile, Linux x64 ELF,
|
||||
manifest digest, and every file, mode, directory and contained symbolic link.
|
||||
External hardlinks, escaping links, extra or modified files, and unsafe modes
|
||||
are rejected. This command performs no network requests or model calls and does
|
||||
not run the Linux executable on the Mac.
|
||||
|
||||
The destination is the private `remote-companions/linux-x64` directory beneath
|
||||
the actual installed `@paperclipai/server` package. It must be writable by the
|
||||
operator, outside the task workspace, and protected with the same host access
|
||||
controls as the server installation. It is not an agent workspace or a remote
|
||||
image's self-reported authority. An existing different or damaged installation
|
||||
is never replaced automatically. Stop all runs before an operator removes or
|
||||
upgrades that cache. Verification and copying use asynchronous 1 MiB chunks,
|
||||
yield between chunks, and enforce the same full inventory and ten-minute bound.
|
||||
Directory entries must retain owner read/write/search permissions so failed imports
|
||||
can drain their owned cleanup. SIGINT/SIGTERM are deferred through owned filesystem
|
||||
phases and drain cleanup;
|
||||
an uncatchable kill or host failure leaves the import unadmitted until the
|
||||
operator resolves its retained lock or incomplete directory. Do not move the
|
||||
cache into a task workspace to work around permissions.
|
||||
|
||||
Normal remote Pi resolves this authority without binary or pack environment
|
||||
overrides. The controller re-verifies its complete inventory and uses the exact
|
||||
Linux daemon identity. Existing remote verification compares image bytes against
|
||||
that local authority; a mismatch takes the existing verified upload path.
|
||||
Controller restart and warm-session recovery retain the original Runner artifact
|
||||
identity checks. Cursor, Copilot and explicit operator overrides keep their
|
||||
existing admission rules.
|
||||
|
||||
For release maintainers, assemble the Linux daemon and default provider pack
|
||||
for the **same final commit** as the public server/CLI packages. A reused daemon
|
||||
requires complete native source/config/protocol input equality and retains its
|
||||
original compiler/build provenance; the manifest does not claim recompilation. In a fresh
|
||||
release directory place those outputs at `bin/paperclip-runnerd` and
|
||||
`provider-pack/`, preserving the pack's relative links and modes. Then run the
|
||||
source-owned manifest generator after building the matching server:
|
||||
|
||||
```sh
|
||||
node scripts/create-runner-remote-companion.mjs /path/to/release/linux-x64 FINAL_SOURCE_SHA
|
||||
```
|
||||
|
||||
Publish the complete companion directory (or distribute it through the normal
|
||||
trusted release channel) together with the printed manifest SHA256 and the
|
||||
source/profile/platform provenance. The import command accepts an already
|
||||
extracted directory, not an archive or URL. The release companion must remain
|
||||
available with that release; a short-lived qualification artifact is not a
|
||||
release distribution. No release publication is implied by the tests here.
|
||||
|
||||
Build/publish the Daytona image from those same daemon/pack outputs and configure
|
||||
its immutable OCI digest through the ordinary Daytona environment `image` field.
|
||||
The image digest and companion manifest are output metadata, not new source
|
||||
constants, so publication does not require another source commit. The final live
|
||||
proof must use the installed public CLI, this import command, and ordinary image
|
||||
configuration without E2E remote binary/provider-pack overrides. That installed
|
||||
and paid proof remains pending.
|
||||
|
||||
|
||||
Historical v10 qualification checkpoint (2026-09-30): **Pi profile v10 remains unqualified.** The capped-key/login prerequisite remains blocked. Native USD is unknown. The optional private budget helper is not integrated; Cursor's account-cycle cap does not establish Pi's provider spending bound. V10 keeps the native wrapper and closures unchanged, binds the shared ACPX patch under a new digest, and rejects v9 sessions. Fresh exact-runtime admission and final controller verification remain pending.
|
||||
|
||||
Historical v9 checkpoint (2026-09-30): **Pi profile v9 remains unqualified**. Current runtime source is `5b8e4454ef0bf12d0bb068c2e41d8c9df9356a1c`; controller/Product harness source is `40064d28522de25fea85c1297f35b41bb8a8897a`. Runtime builds for macOS ARM64/x64 and Linux x64 are complete. No paid profile-v9 pass is claimed. A credential with a verifiable spend limit is still needed for the remaining paid qualification. The optional transport-budget candidate is frozen on a separate branch and is not integrated or a live spending guarantee. See the [comparative capability report](runner-rich-acp-capabilities.md) for current qualification gates and the field audit. The dated observations below retain their original profile identities.
|
||||
@@ -209,8 +364,8 @@ addressed by v4. Version 2 hello completion and every failure remain retained.
|
||||
The wider local and Linux x64 Daytona matrix remains pending; this document does
|
||||
not promote the candidate to a qualified production runtime.
|
||||
|
||||
The runner pins `pi-acp@0.0.33` and
|
||||
`@earendil-works/pi-coding-agent@0.84.2`. The candidate model is
|
||||
At this historical pre-1.0 checkpoint, the runner pinned `pi-acp@0.0.33` and
|
||||
`@earendil-works/pi-coding-agent@0.84.2`. The candidate model was
|
||||
`openrouter/deepseek/deepseek-v4-flash-0731`; only an explicitly bound OpenRouter
|
||||
credential may reach this profile. `patches/pi-acp@0.0.33.patch` repairs the ACP
|
||||
wrapper. `pi-runtime-extension.ts` supplies the runner-owned semantic bridge and
|
||||
@@ -985,3 +1140,37 @@ that ID unchanged into the shared MCP dedupe boundary. This is a further
|
||||
integration defect. The shared dedupe guard and canonical grader remain intact.
|
||||
Both runs lack terminal usage; measured billing is $0.002440082 and cleanup
|
||||
passes. Restart and refreshed hello are held until this defect is repaired.
|
||||
|
||||
## Explicit host installation
|
||||
|
||||
For a published local Paperclip installation, run `paperclipai runtime setup pi`
|
||||
with the same installed CLI and account that owns the server package. This is an
|
||||
explicit download and verification step; npm installation and agent launch never
|
||||
perform it automatically. It installs only this host's supported platform
|
||||
(macOS ARM64, macOS x64, or Linux x64), using the source-pinned Node archive, npm
|
||||
lock, wrapper patch and complete Pi closure. Node 24, npm, git, tar and the normal
|
||||
platform dependency inspector (`otool` or `ldd`) must be available. The server
|
||||
package must be writable by the installing account. Explicit setup preserves
|
||||
`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`, their lowercase equivalents,
|
||||
`SSL_CERT_FILE`, `SSL_CERT_DIR` and
|
||||
`NODE_EXTRA_CA_CERTS` for public downloads, and enables Node's environment proxy
|
||||
handling. The provisioner keeps the same closed allowlist. Instance settings,
|
||||
provider credentials, user npm configuration, `HOME`, `NODE_OPTIONS` and
|
||||
`NODE_PATH` are excluded; TLS certificate validation stays enabled.
|
||||
|
||||
The public server carries a self-contained setup tool and small pinned inputs in
|
||||
`dist/vendor/paperclip-runner/cli`; the installed host closure lives in that
|
||||
server package's `provider-assets/pi/<platform>`. Setup validates an existing
|
||||
closure again before accepting it. A corrupt existing installation is left
|
||||
untouched and rejected; reinstall the same Paperclip release into a clean package
|
||||
location and repeat setup. Concurrent setup is rejected. Cancellation drains the
|
||||
current bounded download/build command before removing its private staging tree;
|
||||
allow that cleanup to complete before trying again.
|
||||
|
||||
Then select Pi with an explicit provider/model ID and bind its provider credential
|
||||
through the normal agent environment configuration. Setup itself makes no model request.
|
||||
A missing host closure produces explicit setup guidance. Daytona uses the
|
||||
separately built and verified Linux provider pack in its runner image; running
|
||||
local setup does not install or qualify a remote image. Published-tar local and
|
||||
Daytona startup evidence must bind the final installation candidate, with no
|
||||
candidate qualification flags, before a production-readiness claim.
|
||||
@@ -22,6 +22,100 @@ for the exact source/image evidence and merge status.
|
||||
All dated checkpoints below describe historical qualification attempts. Their
|
||||
failures and profile numbers are retained; they are not current release gates.
|
||||
|
||||
## Historical Pi 1.0 qualification checkpoint — October 2, 2026
|
||||
|
||||
Pi uses `@earendil-works/pi-coding-agent@1.0.0`, `pi-acp@0.0.33`, and ACPX
|
||||
`0.13.1`. Profile **13** adds explicit, native-acknowledged reasoning selection
|
||||
for the exact model `openrouter/deepseek/deepseek-v4-flash-0731`. New Pi
|
||||
configuration and qualification cases select `low`. This candidate is not yet
|
||||
production qualified. Cursor v10 and Copilot v13 remain gated.
|
||||
|
||||
The installed profile-13 candidate at `eac50643213d0902a93a5384bae2f1d6c065c9f2`
|
||||
has paid local passes for hello, semantic question continuation, all four native
|
||||
question forms, and human permission denial without a file side effect. Its
|
||||
paid extended Runner `get-task-context` case passes against the authenticated
|
||||
seeded test control plane. That protocol case does not qualify the Product UI.
|
||||
File validation, pending-input controller restart, and three-turn warm
|
||||
continuation remain failed and unregraded. Assertion repairs and an actual
|
||||
SDK/wrapper replay now cover the identified boundaries; fresh live proof is
|
||||
still required. See the [historical Pi checkpoint](runner-pi-capabilities.md#historical-profile-13-qualification-checkpoint-2026-10-02)
|
||||
for the request-stream diagnosis and remaining platform gates.
|
||||
|
||||
Copilot's declaration hashes the shared sidecar, sidecar protocol, direct driver,
|
||||
and generated schema bundle. Pi's reasoning field changed those four files, so
|
||||
Copilot's pending declaration advances to v13 with digest
|
||||
`sha256:3ff08fbe76fe4549c9eb01e8794428d8909c65c151d775220f2ec111d9e6f7c1`.
|
||||
Its executable, distribution closure, model, permissions, and qualification
|
||||
status are unchanged. The v12 declaration remains historical, and v12 warm
|
||||
sessions are rejected. This source-identity repair supplies no Copilot paid proof.
|
||||
|
||||
The first profile-13 source (`f5c5fde38`) built a fresh ARM daemon and Pi pack,
|
||||
then passed original startup and all 61 native/ACP contract tests without model
|
||||
calls. Its full Runner suite found three missing-mode test fixtures and the
|
||||
stale Copilot declaration. Those failures are retained. The corrected final
|
||||
source still requires fresh platform builds, complete checks, and paid tests.
|
||||
|
||||
Profile 12 passed one paid local hello through the actual installed public
|
||||
CLI/server and normal runtime setup. The next question-continuation case failed
|
||||
at the unchanged 120-second native deadline: Pi emitted 1,019 reasoning deltas,
|
||||
but no tool call or question. The tool and schema were present. One native turn
|
||||
was submitted; the two visible start rows were canonical and mirrored activity,
|
||||
not evidence of two provider requests. Both attempts completed owned-process,
|
||||
IPC, temporary-root, installed-inventory, and post-run accounting checks.
|
||||
|
||||
The dedicated key recorded $0.000510742 for the hello and $0.004995065 for the
|
||||
failed question. Including the earlier profile-11 failure ($0.000142518), its
|
||||
observed total was $0.005648325 at that reconciliation. These are observed key
|
||||
usage changes, not native per-request bills. No failed result has been regraded.
|
||||
|
||||
Diagnosis found that the runner did not select the ACP reasoning mode. The
|
||||
pinned model's implicit Pi `medium` setting resolves to `high`; this behavior
|
||||
also existed in Pi 0.84.2. Pi 1.0 exposes a genuine `low` level. Profile 13 carries
|
||||
an explicit setting through configuration, transport, and durable identity,
|
||||
and requires the native effective level to match before a prompt is sent.
|
||||
It does not increase the timeout. The timed-out HTTP body was not captured,
|
||||
so source-derived default mapping does not establish the cause of that failure.
|
||||
Fresh qualification must use the new profile and exact final build.
|
||||
|
||||
Historical source `4c58da84fd86a0cd7bc1d952987b031786fc6b2b` passed full Runner
|
||||
verification and normal Intel startup at 28.295 seconds under the original
|
||||
30-second limit, plus all 48 native/ACP contract tests. The Intel result has
|
||||
only 1.705 seconds of margin and does not establish broad cold-start reliability.
|
||||
Its fresh Linux daemon, Pi pack, and image were built and inventoried; live
|
||||
Daytona qualification remained pending. The public Mac installation reproduced
|
||||
the complete Pi dependency closure using npm 11.19.0 from the verified Node
|
||||
archive. None of these artifacts qualifies profile 13.
|
||||
|
||||
The same source's full repository check failed six stale test assertions and
|
||||
an `ETXTBSY` binary-staging error; the downstream Grok check then lacked built
|
||||
server output. Typecheck, token gates, and Product E2E typecheck/unit checks
|
||||
passed. The stale assertions have targeted repairs. A Linux process owner was
|
||||
not captured for `ETXTBSY`; two exact native fixtures later passed on ARM with
|
||||
all owned daemon handles closed, which does not resolve the Linux failure.
|
||||
The next complete source run retains bounded executable-holder evidence around
|
||||
check boundaries. A later run on obsolete harness source was canceled by the
|
||||
lead and is retained as incomplete, not successful verification.
|
||||
|
||||
Normal Daytona setup has an explicit operator command to import a verified
|
||||
Linux companion into the installed server. It binds the trusted manifest to the
|
||||
installed source, Pi profile, daemon, and complete provider-pack inventory, then
|
||||
uses ordinary remote execution without test-only binary or pack overrides.
|
||||
The final installed import, image publication, and paid proof remain required.
|
||||
|
||||
The dedicated Pi test key has a $5 lifetime OpenRouter-credit limit. Its BYOK
|
||||
charges are outside that provider-enforced limit, so qualification additionally
|
||||
uses the reviewed no-BYOK operational policy, fresh account/key evidence, one
|
||||
paid case at a time, and usage monitoring. The $5 reservation is counted once
|
||||
within the combined $100 campaign budget. Native price estimates are never
|
||||
substituted for provider bills.
|
||||
|
||||
The [Pi capability inventory](runner-pi-capabilities.md#historical-pi-10-candidate-2026-10-02-profile-v13)
|
||||
records native interfaces, ACP mappings, user surfaces, and explicit gaps.
|
||||
The comparison below remains the supported-surface map; old observations retain
|
||||
their exact historical profile identities. Final source checks and profile-13
|
||||
local Product, Runner protocol, native-control, and Daytona qualification remain
|
||||
pending.
|
||||
|
||||
Historical source checkpoint (2026-10-01): **Cursor v10, Copilot v12 and Pi v10
|
||||
remain unqualified**. Copilot receipt v2 distinguishes original provider
|
||||
arguments from the validated outgoing completion input. The sidecar commits
|
||||
@@ -73,7 +167,7 @@ as `25303cf84953985b961b95f89aff0bdb864b2d65`, from head
|
||||
unchanged; this adds no paid proof. Those definitions remain the historical
|
||||
Cursor v8 checkpoint and require a separate reviewed Cursor v9 update.
|
||||
|
||||
Current checkpoint (2026-09-30): **Cursor v9, Copilot v8 and Pi v10 remain unqualified.** The frozen runtime is `5c69b69ef2aeab8d8a367b25a8d894cc5308befa`; controller candidate is `a8df2064d68f40fbf4dec670c4b8478c4b1b1b3f`. All profiles bind shared ACPX patch SHA-256 `bd5393058a218040d217fa85449d59a6f30507de54cd645bf0ef21422823f85e`. No profile is promoted and no prior grade is changed.
|
||||
Historical checkpoint (2026-09-30): **Cursor v9, Copilot v8 and Pi v10 remain unqualified.** The frozen runtime is `5c69b69ef2aeab8d8a367b25a8d894cc5308befa`; controller candidate is `a8df2064d68f40fbf4dec670c4b8478c4b1b1b3f`. All profiles bind shared ACPX patch SHA-256 `bd5393058a218040d217fa85449d59a6f30507de54cd645bf0ef21422823f85e`. No profile is promoted and no prior grade is changed.
|
||||
|
||||
Current-profile protocol eval definitions merged in [paperclip-evals #36](https://github.com/paperclipai/paperclip-evals/pull/36) as `d987357461933baca0d4c10cc081f40e7eae5c1b`: 136 deterministic tests and 21 validated cells. These definitions do not supply paid qualification evidence.
|
||||
|
||||
@@ -683,22 +777,22 @@ deterministic evidence are mapped separately after the comparison.
|
||||
|
||||
| Capability | Codex app-server benchmark | Cursor ACP candidate | Copilot ACP candidate | Pi ACP candidate |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Exact model | Selected and reported model | Explicit ID required; exact echo, paid semantic protocol and five local semantic product cases passed | Explicit ID required; exact `gpt-5.6-luna` echo, paid semantic protocol and local completion/file/plan/restart passed | Exact `openrouter/deepseek/deepseek-v4-flash-0731`; model echo and v2/v3 paid Product completion/file/question cases passed; v5 native controls passed |
|
||||
| Exact model | Selected and reported model | Explicit ID required; exact echo, paid semantic protocol and five local semantic product cases passed | Explicit ID required; exact `gpt-5.6-luna` echo, paid semantic protocol and local completion/file/plan/restart passed | Exact `openrouter/deepseek/deepseek-v4-flash-0731`, native-verified `low`; profile-13 paid hello, semantic continuation, native questions and human denial pass; file/restart/warm failures remain open |
|
||||
| Text and tools | Typed thread/turn/item events | Standard ACP updates; child activity kept separate | Standard ACP plus opt-in native session events | Wrapper text/tool updates and owned tool gates |
|
||||
| Active steering | Dedicated `turn/steer` | Concurrent prompt replaces/cancels, so it is not steering | Concurrent prompt replaces/cancels, so it is not steering | Owned `pi/steer` requires handshake, exact active turn and acknowledgment; real active-turn probe passed |
|
||||
| Queued follow-up | Product continuation controls | Controller can schedule a later prompt; native queue not established | Native pending-message activity exists; no qualified ACP queue responder | Owned `pi/follow_up`, separately named and ordered; real queued marker followed the steered current response |
|
||||
| Active steering | Dedicated `turn/steer` | Concurrent prompt replaces/cancels, so it is not steering | Concurrent prompt replaces/cancels, so it is not steering | Owned `pi/steer` requires handshake, exact active turn and acknowledgment; historical probe passed, profile-13 paid proof pending |
|
||||
| Queued follow-up | Product continuation controls | Controller can schedule a later prompt; native queue not established | Native pending-message activity exists; no qualified ACP queue responder | Owned `pi/follow_up`, separately named and ordered; historical marker-order proof, profile-13 paid proof pending |
|
||||
| Cancellation | Typed interrupt and process lifecycle | ACP cancel; paid command cleanup pending | ACP cancel; attached async native settlement passes offline. Explicit detached work is rejected before side effects; it is not supported background settlement | Native abort; wrapper waits for `agent_settled` and treats provider errors as failure |
|
||||
| Session continuity | Read/load/history/fork and durable identity | Session load/list observed; paid semantic warm continuation passed; native history replay unverified and fork absent in tested methods | Session load plus native history events; semantic pending-question controller recovery passed | Private Pi JSONL mapping/load; native RPC `fork`, `clone`, `get_fork_messages` are not mapped through this ACP wrapper; unresolved UI promises cannot survive provider death |
|
||||
| Questions | Typed input requests and response correlation | `cursor/ask_question`, option identity and multiple selection preserved | Native ask-user capability exists, but pinned ACP does not wire its responder; do not display a false answerable form | `select`, `confirm`, `input`, `editor` through typed form elicitation |
|
||||
| Permissions | Durable typed approvals | Standard ACP permission options; denied shell write had no observed side effects; separately labeled exact-correlation assessment | Standard ACP; real native reject_once prevented marker creation; session decision scope inspected | Native pre-tool gate; allow once, exact-operation session grant, deny; paths rechecked after wait |
|
||||
| Plans | Typed plan and collaboration mode | `cursor/create_plan` includes full plan and revision-bound accept/reject/cancel; todo activity separate | Native plan events displayed; native plan-decision callback not exposed in ACP | No native structured plan event; authenticated Paperclip planning tools available |
|
||||
| Authenticated tools | Runner bridge and governed operations | ACP HTTP MCP binding; paid context/history reads passed | ACP HTTP MCP binding; paid context read passed | Owned extension registers exact bound MCP tools; four authenticated semantic reads succeeded in a paid partial run; no ambient servers |
|
||||
| Authenticated tools | Runner bridge and governed operations | ACP HTTP MCP binding; paid context/history reads passed | ACP HTTP MCP binding; paid context read passed | Owned extension registers exact bound MCP tools; profile-13 paid Product completion/questions and seeded Runner context pass; no ambient servers |
|
||||
| Delegation | Typed agent roles and lifecycle | Opt-in subagent lifecycle, nested ownership and bounded child activity; never parent transcript flattening | Native session details retain agent/model fields with unknown originating turn; typed turn-owned delegation is not inferred | No built-in ACP delegation protocol; arbitrary extensions are excluded |
|
||||
| Files/diffs | Typed file changes and artifact references | Standard tool changes plus validated image references | Correlated ACP tool events remain available; native session file/workspace details are session notices, not attributed task file changes | Wrapper-retained read/write/edit diffs; common typed/UI projection remains partial; semantic artifact tools |
|
||||
| Images/artifacts | Typed references and registered work products | Existing contained files only, provenance, `registered:false` | Native session artifact details are bounded notices with no inferred turn ownership or automatic registration | Image/resource tool blocks preserved by wrapper; dedicated artifact channel absent |
|
||||
| Image/attachment input | Typed input conversion | ACP advertises images, but the runner turn converter currently forwards text only | ACP advertises images/embedded context, but the runner turn converter currently forwards text only | Native Pi/ACP image input exists, but the runner turn converter currently forwards text only |
|
||||
| Usage | Per-request receipt and model context | Pinned ACP omitted receipts on denied and successful turns; account UI confirms included usage separately | ACP/native tokens retained; account UI confirms included credits separately, without a per-run USD receipt | Assistant-message and compaction token receipts; dollar cost is a catalog pricing estimate, never authoritative billing |
|
||||
| Config/model changes | Typed configurable controls | Agent/Plan/Ask setup is bound to native configuration acknowledgements and recovery; unsolicited mode drift fails admission. Rich parameterized model picker remains unused | Model/reasoning/mode options exist; runtime policy remains authoritative | Exact pinned candidate model; arbitrary slash commands/config/extensions disabled |
|
||||
| Config/model changes | Typed configurable controls | Agent/Plan/Ask setup is bound to native configuration acknowledgements and recovery; unsolicited mode drift fails admission. Rich parameterized model picker remains unused | Model/reasoning/mode options exist; runtime policy remains authoritative | Exact model; native available levels and set/get-state confirmation map through ACP mode/config to typed `piThinkingLevel`, recovery identity and UI setup. Active-turn mode changes and arbitrary slash commands/extensions remain disabled |
|
||||
| Reconnect/restart | Durable controller replay and qualified provider restoration | Semantic pending question survived a real controller restart; exact native callback restoration remains unverified | Semantic pending question survived controller restart with the same interaction and provider session; native callback restoration remains unverified | Wrapper explicitly advertises live-process-only pending-input recovery |
|
||||
|
||||
| Shared capability | User-visible surface | Inspectable implementation / deterministic evidence |
|
||||
@@ -763,7 +857,7 @@ configuration defaults to full auto; it never overrides read-only task policy.
|
||||
## Distribution and isolation
|
||||
|
||||
Cursor pins `2026.09.26-dd393fe`; Copilot pins `1.0.88`; Pi pins wrapper `0.0.33`,
|
||||
runtime `1.0.0` (Pi profile v12), portable Node and its full npm lock. Native distribution hashes
|
||||
runtime `1.0.0` (Pi profile v13), portable Node and its full npm lock. Native distribution hashes
|
||||
cover macOS ARM64, macOS x64 and Linux x64. Source-owned closure pins remain
|
||||
separate from profile declaration digests. Native admission reads held files,
|
||||
verifies every admitted byte, creates a private immutable snapshot and retains
|
||||
@@ -792,8 +886,8 @@ qualification gates, not claims that a JavaScript path check confines a shell.
|
||||
|
||||
| Priority | Exposed but unused, partial, or unverified | Reason and next proof |
|
||||
| --- | --- | --- |
|
||||
| P0 | Remaining paid product cases on local and Daytona | Current Cursor7/Copilot7/Pi9 require authenticated local and Daytona evidence on the exact current runtime. Historical Cursor4 passed hello/question/plan/restart but its latest file marker failed despite correct bytes. Copilot4 passed all five basic local journeys and Daytona hello. Pi7 passed native questions but continuation exposed the final-message bug repaired in8. The semaphore blocker is resolved and Cursor's approved on-demand cap is $25. Native interaction, denial, settlement, platform and complete cost/cleanup gates remain open; no old profile pass qualifies new bytes. |
|
||||
| P0 | Pi fresh-profile Product verification | Historical v4 plan startup failed with unavailable Postgres semaphores. Historical v6 attempts exposed profile admission and verified-runtime startup faults, repaired without raising deadlines. Preserve every failed attempt and run unchanged canonical cases against the final build; do not remove unrelated IPC objects. |
|
||||
| P0 | Remaining paid product cases on local and Daytona | Current Cursor10/Copilot13/Pi13 require authenticated local and Daytona evidence on the exact current runtime. The current Pi checkpoint above supersedes older profile coverage. Historical Cursor4 passed hello/question/plan/restart but its latest file marker failed despite correct bytes. Copilot4 passed all five basic local journeys and Daytona hello. Pi7 passed native questions but continuation exposed the final-message bug repaired in8. The semaphore blocker is resolved and Cursor's approved on-demand cap is $25. Native interaction, denial, settlement, platform and complete cost/cleanup gates remain open; no old profile pass qualifies new bytes. |
|
||||
| P0 | Pi profile-13 Product and platform verification | Four paid local cases and one seeded Runner case pass. File validation, pending-input restart and warm continuation remain failed; assertion repairs do not regrade them. Finish the remaining local, Runner/native-control, Intel startup and Linux/Daytona cases on fresh final builds. Earlier semaphore and v6 startup faults remain historical evidence; never remove unrelated IPC objects. |
|
||||
| P0 | Copilot native ask-user and plan-decision callbacks | Pinned ACP does not install native responders. Prove no blocking request is exposed, or add a qualified responder/wrapper; never swallow the request. |
|
||||
| P0 | Broader Copilot denial and background settlement qualification | Pinned 1.0.88 and isolated 1.0.89 settle attached async commands, but deliberately detached work can finish after end_turn. The earlier paid detached success depended on that model waiting and is not general settlement evidence. Profiles v3/v4 reject explicit detached admission before effects; governed long-lived background work remains unsupported. Denial and process-death recovery pass offline; paid local/Daytona proof remains required. |
|
||||
| P0 | Cursor native question availability | Explicit Luna and Composer native-only Plan-mode probes admitted the selected model and trusted instructions but emitted no question callback. The vendor-patch reversal and actual MCP-context constructor proof identify no local native-tool removal. Effective native tool selection is beyond the remote AgentService boundary; seek upstream catalog/availability evidence. No further blind model grid or semantic-question substitution qualifies this feature. |
|
||||
@@ -808,7 +902,7 @@ qualification gates, not claims that a JavaScript path check confines a shell.
|
||||
| P1 | User attachments and image prompting | `AcpxRuntimeTurnInput` and the common runtime adapter currently forward text only, despite underlying image-input support. Implement validated attachment-to-ACP content conversion and model-specific capability admission, then qualify real local/Daytona image prompts. This is an implementation gap as well as a live-verification gap. |
|
||||
| P1 | Copilot native session event attribution | `_session_event` omits an originating turn. Preserve bounded event fields as session-scoped notices with `turnAttribution: unknown`; typed delegation, artifacts and compaction need an explicit native correlation contract before turn-owned projection. Standard correlated ACP events remain separate. |
|
||||
| P1 | Copilot session-store files and export/artifact URIs | Provider paths are not task-workspace paths. Add a separately authorized export flow with validated bytes and provenance; do not resolve arbitrary URLs or auto-register. |
|
||||
| P1 | Pi native fork/history/export interfaces | Pinned Pi 0.84.2 native RPC exposes `fork(entryId)`, `clone`, `get_fork_messages` and `export_html`. The wrapper does not map them to runner controls. Add durable branch lineage for fork/clone and an authorized, contained artifact flow for HTML export before exposing them; do not label these native capabilities absent. |
|
||||
| P1 | Pi native fork/history/export interfaces | Pi native RPC exposes `fork(entryId)`, `clone`, `get_fork_messages` and `export_html`; these remain available in the pinned 1.0.0 release. The wrapper does not map them to runner controls. Add durable branch lineage for fork/clone and an authorized, contained artifact flow for HTML export before exposing them; do not label these native capabilities absent. |
|
||||
| P1 | Complete usage/billing provenance | Missing cache fields remain unknown. Pi price estimates are displayed separately. Budget qualification requires actual spend coverage, not an estimate presented as a bill. |
|
||||
| P1 | Fork/history and richer configuration controls | Cursor session mode now has explicit admission-bound setup. Arbitrary session discovery/forking, mid-turn configuration changes and the parameterized model picker still need company-scoped controls and durable lineage. |
|
||||
| P1 | Exact pending-request restoration after process death | Session transcript restoration does not restore callbacks. Expire unresolved requests unless a provider proves exact restoration. |
|
||||
@@ -816,7 +910,7 @@ qualification gates, not claims that a JavaScript path check confines a shell.
|
||||
| P2 | Remaining Copilot native diagnostic/config/account events | The provider inventory records every event and field, its projection or reason for omission. Preserve bounded useful context; avoid credentials, raw environment or unbounded blobs. |
|
||||
| P2 | Pi empty or whitespace-only submitted input/editor text | Canonical required text rejects blank responses; optional blank responses are omitted. Defaults can be empty and nonblank text preserves boundary whitespace. Add explicit empty-text semantics across TypeScript, Rust and UI before claiming complete native empty-answer parity. |
|
||||
| P2 | Pi native extension surfaces and unsupported slash commands | Arbitrary extensions/templates/themes may execute ambient code. Only reviewed runner-owned capabilities are admitted; structured native plan/goals are not fabricated. Native fork/clone/export are separate unmapped capabilities above. |
|
||||
| P2 | Pi status/widget/title/editor and session/configuration notifications | `setStatus`, `setWidget`, `setTitle` and `set_editor_text` have no UI projection and are unused by the owned extension. Native session-name and thinking-level events also lack a dedicated projection. Add reviewed bounded notice schemas and governed configuration controls before exposing these fields; `notify` and interactive input already have separate bridges. |
|
||||
| P2 | Pi status/widget/title/editor and session/configuration notifications | `setStatus`, `setWidget`, `setTitle` and `set_editor_text` have no UI projection and are unused by the owned extension. Native session-name and thinking-level notifications also lack a dedicated projection, although selected thinking level is now handled through ACP mode/config and native confirmation. Provider notice summary/severity has deterministic UI coverage, with rebuilt paid visual proof pending. Add bounded schemas for the remaining fields; `notify` and interactive input already have separate bridges. |
|
||||
| P2 | Pi invocation and history provenance metadata | The v4 wrapper retains `nativeToolCallId`, `modelIteration`, `historyMessageIndex` and `identityScope` in private ACP-wire metadata. Closed common tool and permission projections omit them from the UI. Normalized IDs still correlate live tool, MCP and permission events. Add bounded, redacted display-only provenance fields and parity tests before surfacing the native metadata. |
|
||||
| P2 | Conditional native-plan follow-up fields | Cursor's optional rejection-reason field also appears for accept/cancel. The current question renderer has no conditional fields; add conditional presentation without changing the revision-bound decision receipt. |
|
||||
| P2 | Cursor command exit code projection | The paid file case preserved native `exitCode: 0` inside output text, while the canonical command field remained null. Normalize a typed, correlated exit code without parsing arbitrary prose; current independent file assertions do not prove this field. |
|
||||
|
||||
@@ -36,15 +36,15 @@ Docker materialization, Git installer, or extra login isolation wholesale.
|
||||
## Current slice: Codex defaults
|
||||
|
||||
Authorized 2026-10-09. Canonical branch: `codex/codex-runner-default`.
|
||||
Master base: `835a022936ddc7a152b9feab0c0420d02249a6d1`.
|
||||
Integration base: master `2dd9811e8be1dab59cccd86cdb25e8953b02fe07`.
|
||||
Canonical PR: [draft #15683](https://github.com/paperclipai/paperclip/pull/15683).
|
||||
Latest reviewed candidate: `1be8502f27b042566df5fc2d88e46dbcfc8484f3`.
|
||||
Latest pushed candidate before integration: `4275309f9d619055f48a9b21cb0ad0a1ff7c2c63`.
|
||||
The follow-up fixes configure-on-first-use for an existing built-in that still
|
||||
needs setup. The PR remains under 100 files, with no workflow or lockfile
|
||||
changes. Fresh final-head CI and review are required after that fix.
|
||||
Preview: [isolated Codex QA](http://127.0.0.1:3125), normal dev supervisor,
|
||||
separate database. Hosted Linux live onboarding passed at `38199ea8`; execution
|
||||
code is unchanged at `1be8502f`. UI changes have separate revision-bound proof.
|
||||
separate database. Hosted Linux live onboarding passed at `38199ea8`; it remains
|
||||
historical proof after the lifecycle integration. UI has separate revision-bound proof.
|
||||
Attended local subscription and managed staging journeys remain unverified.
|
||||
|
||||
New Codex agents select Paperclip Runner on qualified Linux x64 targets. Users
|
||||
@@ -78,13 +78,13 @@ Claude's explicit native fixture is unchanged until its later default PR.
|
||||
|
||||
| Area | Owner | Current state |
|
||||
| --- | --- | --- |
|
||||
| Shared contract, server resolution, setup readiness | Core worker | 394 focused cases and 147 guard/inheritance controls pass; server noemit passes; counts overlap |
|
||||
| Shared contract, server resolution, setup readiness | Core worker | Integrated lifecycle: 210 core cases, 109 connection cases and five affected refresh controls pass; server noemit passes; counts overlap |
|
||||
| Production create/edit/onboarding UI and stories | UI worker | 171 fresh focused cases, 30 desktop/10 mobile captures and six keyboard checks; built-in follow-up passes 15 cases, UI typecheck and token gates |
|
||||
| Built-ins, plugins, approvals, imports/exports, CLI | Creation-path worker | 105 portability, eight approval, three CLI and three asset checks pass; 77 corrected skill-route cases pass; full Linux checks pending on final head |
|
||||
| Built-ins, plugins, approvals, imports/exports, CLI | Creation-path worker | Integrated lifecycle: 105 portability, eight approval and three asset cases pass; 73 DB cases skipped on macOS; final Linux checks required |
|
||||
| Execution/dev gate, E2E gaps, packaging, live journeys | Lead | Selected Linux onboarding case passes all 13 assertions, actual task/artifact/follow-up and cleanup; 149 public-projection/support cases pass |
|
||||
| Full CI and final review | Lead | Native compilation passes at `1be8502f`; main CI is running; its fresh 4/5 review finding is fixed locally, with final-head replay required |
|
||||
| Full CI and final review | Lead | All seven known findings fixed/resolved; master lifecycle merge conflicts resolved locally; new combined head needs full CI and fresh review |
|
||||
| Local subscription task + follow-up | Lead | Embedded-browser onboarding prepared; attended sign-in unfinished; macOS automatic legacy selection is expected |
|
||||
| Managed staging API/subscription onboarding | Lead | Dedicated tenant access, serving revision, snapshot and cleanup ownership unresolved; Fleet Admin needs attended sign-in |
|
||||
| Managed staging API/subscription onboarding | Lead | Fleet Admin sign-in completed; dedicated tenant exists, active/awake and pinned to old release; scoped one-hour QA owner access approved; final serving revision/snapshot/runtime/cleanup qualification pending |
|
||||
| Shipped npm/Docker/cloud artifacts | Lead | Clean Linux npm consumer passes at the prior candidate: 18 packages, no Codex payloads, host dependency from official npm; final-head replay pending; actual cloud composition is post-merge |
|
||||
|
||||
Keep CPU-heavy Rust/Docker builds in hosted CI. Use Node 24, bounded workers,
|
||||
@@ -220,9 +220,11 @@ proof is in progress. Existing UI verification passed 28 desktop/eight mobile
|
||||
renders, six keyboard/footer cases and two touch/wheel journeys. Final CI/review
|
||||
must run after this combined follow-up is frozen.
|
||||
|
||||
The isolated preview remains [3125](http://127.0.0.1:3125/COD/dashboard).
|
||||
Its supervisor now uses the correct port and the backend restarted at
|
||||
The isolated preview uses [3125](http://127.0.0.1:3125/COD/dashboard).
|
||||
Its supervisor uses the correct port and the prior backend restarted at
|
||||
`2026-10-09T15:28:08.305Z`. No user preview or the separate OAuth proxy was stopped.
|
||||
The owned supervisor/backend were gracefully paused during lifecycle integration;
|
||||
restart and serving-source verification are required before another live journey.
|
||||
The first-agent name draft survived reload. The cached local daemon is not proof
|
||||
of the new native Rust seams; Linux hosted build/live execution supply that proof.
|
||||
Attended subscription login and current access to the dedicated managed staging
|
||||
@@ -252,6 +254,38 @@ running, with no test failure observed yet.
|
||||
Next action: freeze the built-in setup follow-up, require green
|
||||
exact-head CI and fresh 5/5 review, and publish sanitized retained evidence when
|
||||
operator access is available. Complete the attended and managed staging journeys
|
||||
when access is available. The PR stays
|
||||
when their remaining resources are ready. The PR stays
|
||||
a draft and is neither merge-ready nor production-ready yet. Merge and production
|
||||
deployment remain outside authorization.
|
||||
|
||||
### 2026-10-09 Current-master lifecycle integration
|
||||
|
||||
Master merged [#15631](https://github.com/paperclipai/paperclip/pull/15631) during
|
||||
qualification. GitHub blocked the new candidate on nine real merge conflicts.
|
||||
The integration preserves master's agent lifecycle ownership. Common runner
|
||||
resolution now runs in `prepareAgentHire`; approval activation retains the frozen
|
||||
reviewed runner, responsible-user identity and credential restrictions. Existing
|
||||
agent updates keep their saved execution. Obsolete source edits were removed,
|
||||
and redundant generic API prose was dropped while the agent-creation skill and
|
||||
its reference retain the complete runner contract. The diff remains 99 files.
|
||||
|
||||
Focused integration checks pass: 210 core, 109 connection, five affected refresh,
|
||||
105 portability, eight approval and three built-in asset cases. Counts overlap.
|
||||
Server noemit and the existing lifecycle-boundary scanner pass. Shared, DB and
|
||||
plugin SDK JavaScript outputs were refreshed without migrations, Rust or Docker.
|
||||
The 73 DB-heavy cases were skipped on macOS and require hosted Linux proof.
|
||||
The full local route-fixture attempt was interrupted and is incomplete evidence;
|
||||
loopback restrictions were identified before its bounded affected-case rerun.
|
||||
That unrestricted rerun passes all 61 selected cases; 108 unrelated cases were
|
||||
excluded and remain part of required full hosted CI.
|
||||
|
||||
The human completed Fleet Admin sign-in. The dedicated QA stack exists and is
|
||||
active, awake, healthy and user-managed, so ordinary fleet rollouts skip it.
|
||||
It still serves historical Core `2dbe43a4`, not this candidate. The human approved
|
||||
one hour of scoped owner access for this QA tenant through the audited admin flow.
|
||||
No release change, provider task, new image or fleet-wide action has run here.
|
||||
|
||||
Next action: freeze/push the integrated candidate,
|
||||
require exact-head CI and fresh 5/5 review, restart the matched local preview and
|
||||
qualify the dedicated managed target against that candidate. The previous Linux
|
||||
run is retained evidence; it must not be relabeled as the new live measurement.
|
||||
Reference in new issue
Block a user