Commit Graph
5 Commits
Author SHA1 Message Date
DottaandPaperclip 61b2455319 fix(runtime): preserve failed sources and durable checkpoint authority (#19038)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - A volume-free web server must preserve retained native session data.
> - An old failed follow-up can keep its own snapshot while its
controller file still belongs to the preceding successful turn.
> - The Runner correctly refuses to import that file as the failed
turn's execution authority.
> - That refusal also blocks migration when no warm supervisor is
present.
> - This pull request preserves the file after it proves the older run's
lineage, and uses existing typed database authority when present.
> - Failed history and files survive, while normal execution authority
stays unchanged.

## Linked Issues or Issue Description

Refs #19024, which preserves the related older-supervisor case. The
duplicate search found no PR for this older-controller case.

**What happened?**

Offline native-controller migration stops with
`native_runner_checkpoint_binding_mismatch` for a failed retained
follow-up. The local controller still contains the preceding successful
run. A per-turn source can have no supervisor file, so the
older-supervisor archive path does not apply. Read-only checks matched
the database snapshots and controller-file hashes between the original
source and the isolated rehearsal copy.

**Expected behavior**

Preserve the available file as evidence through the existing encrypted
archive. Require a valid older controller, a completed successful prior
run, and the same company, agent, task, native session, Runner and
provider thread. Keep successful sources and active owners outside this
archival fallback. When a valid typed database checkpoint already
exists, derive only its missing recovery metadata and ignore obsolete
local projections.

**Steps to reproduce**

Create a successful native turn and a later failed follow-up in the same
session. Retain the successful controller file. Keep the failed snapshot
and admitted input in the database. Leave the per-turn source without a
supervisor. Run offline migration. The new positive regression fails
with the binding mismatch before this change.

## What Changed

- Share the scoped older-successful-run proof with the existing
supervisor preservation path.
- Validate the older controller through the Runner parser and artifact
checks before archive publication.
- Archive this failed legacy source without changing its snapshot,
status, ownership, queued work or session pointer.
- Preserve the normal refusal for foreign, changed, active, successful,
invalid and already-durable cases.
- Permit evidence archival for a stale observed coordinator only with
exact host-owned stop receipts for every remote lease, no current task
ownership, no result and no retry deadline. Recheck the proof before
publication.
- Use execution start for lifecycle ordering. A queued follow-up can
predate its prior turn completion, and a remote stop can predate a later
recovery timeout.
- Resolve destruction receipts through the existing reusable-lease
handoff verifier. Reject stopped tips, broken chains and competing tips.
- Prefer a valid typed database checkpoint over a stale or absent local
warm supervisor. Add only missing recovery metadata after current
admitted-input and checkpoint binding checks.
- Document the evidence and execution-authority boundary.

## Verification

- Positive regression: red before the owner change and green afterward.
- `pnpm exec vitest run
server/src/services/native-runtime/native-controller-migration.integration.test.ts
server/src/services/native-runtime/native-controller-recovery.integration.test.ts
server/src/services/native-runtime/native-harness-backup-storage.integration.test.ts`:
81 checks passed across migration, recovery and durable storage.
- The checks cover storage failure, repeated migration, exact file
restoration after old-home deletion, unchanged history and ownership,
and refusal to treat the archive as executable recovery authority.
- A second regression reproduced the archive fence refusal for an
observed failed source with a valid stopped-remote receipt. Negative
controls cover missing, foreign, old and revoked receipts, live leases,
pending results, retry deadlines and task ownership. Revoking the
receipt during upload prevents publication.
- Two additional regressions cover a follow-up queued before the prior
turn finished and a remote stop before a later logical failure. Both
fail with the earlier timestamp comparisons and pass with
execution-start ordering. Genuine execution overlap and old receipts
stay blocked.
- Two historical source snapshots and controller-file hashes matched in
a read-only live-versus-copy check. The first candidate reached the
archive fence and exposed the observed-coordinator case. That failure is
retained. A fresh candidate replay is required for the expanded proof.
It does not qualify the full packaged migration or hosted Railway
handoff.
- Existing typed-authority checks cover stale and missing supervisors,
repeat migration, byte-identical checkpoint rows, unchanged
snapshots/owners/history, old-home deletion and ordinary queued-turn
recovery. Foreign Runner, session and snapshot controls remain blocked.
- Handoff checks cover an exact destroyed successor, a stopped
successor, a broken proof and a competing tip.
- Isolated replay of the two retained typed-checkpoint sources imported
only derived recovery metadata. Checks confirmed unchanged checkpoint
rows (12 and 9 parts), history, snapshots, finalization owners and
task-session pointers. The replay used three source-module overlays with
a blocked provider network; it does not qualify the released bundle.
- Final-head CI attempt 1 passed typecheck, build and the migration
suites but failed one unrelated budget-concurrency assertion in
`decision-models.test.ts` (one provider call observed instead of two).
The original log is retained. The isolated local comparison cannot
classify the timing failure because this checkout has stale linked
budget schema exports. The one retry of that failed CI job passed, and
final-head CI attempt 2 is green. The original failure remains retained;
its cause is not established.
- Full local typecheck, repository tests and build are not claimed. The
server typecheck reports pre-existing linked declaration mismatches
outside the changed files; the full clean CI typecheck has passed. This
checkout uses linked generated declarations; clean CI is required before
merge. Prior head d71dc913 had passing full CI and a 5/5 Greptile
review. Head 8ff3a22109 adds the handoff and typed-authority fixes. Its
fresh full CI is green and Greptile is 5/5, with no unresolved review
threads. Earlier head7729 hit unrelated 5-second CLI ZIP and 15-second
setup-token test timeouts; those failures remain retained.

## Risks

This path preserves evidence for a source that has already failed. It
does not make that source resumable. The Runner must accept the older
controller under its own identity and artifact binding. Scoped
successful history must match its session and provider thread. The
archive owner still requires stopped writers, a finished failed run and
no live lease. An observed coordinator also needs exact remote-stop
receipts after execution started, no accepted result or retry deadline,
and no current task ownership. The coordinator stays unchanged. Existing
durable authority stays authoritative.

## Model Used

OpenAI Codex, exact model ID `gpt-6.1-sol`, with reasoning, tool use and
code execution. The host does not expose context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have described the issue in-PR following the bug template
- [x] I have not referenced internal or instance-local Paperclip issues
or links
- [x] My branch name describes the change and contains no internal
ticket id or instance-derived details
- [x] I have run the relevant tests locally; verification limits are
listed above
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-11-04 15:37:54 -06:00
DottaandPaperclip 3a283fbc9b fix(runtime): preserve failed sources with older warm supervisors (#19024)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - A volume-free web server needs durable recovery data for retained
sessions.
> - An old failed follow-up can retain its snapshot while the warm
supervisor still holds the preceding successful turn.
> - The migration refuses to treat those different snapshots as the same
execution authority.
> - That refusal also blocks the tenant even when the failed source can
be preserved as an archive.
> - This pull request archives that narrow case after it verifies the
older successful snapshot and all scope bindings.
> - The failed run keeps its history and files while valid controller
recovery keeps its existing proof requirements.

## Linked Issues or Issue Description

Refs #18959, which added the existing failed-controller archive path. No
duplicate PR for this case was found.

**What happened?**

Offline controller migration stops with `stale_supervisor_snapshot` for
an old failed warm follow-up. Its local supervisor still contains the
prior successful turn. Read-only checks found the same database snapshot
and supervisor bytes in the live source and the isolated copy. The
mismatch predates the rehearsal.

**Expected behavior**

Preserve the failed run's database state and available local files in
the existing durable archive. Only archive when the older supervisor
matches a completed successful run in the same company, agent, task,
native session and Runner instance. Keep current execution and
controller authority checks intact.

**Steps to reproduce**

Create a successful native turn and a later failed warm follow-up. Keep
the successful snapshot in the supervisor file and the failed snapshot
in the database. Give the failed source local controller bytes but no
durable controller checkpoint. Run the offline migration. The new
regression fails with `stale_supervisor_snapshot` before this change.

## What Changed

- Verify the older supervisor against scoped successful history and the
same provider thread.
- Use the existing encrypted archive owner for that failed legacy
source.
- Preserve snapshots, run status, ownership, queued work and the
session's last-run pointer.
- Keep foreign, changed, active, successful and already-durable sources
outside this path.
- Document the preservation and recovery boundary.

## Verification

- New positive regression: red on the original owner, green after the
change.
- Native migration and controller recovery: 27 checks passed. Final
migration checks also cover refusal to replace a durable checkpoint.
- Storage failure blocks publication. Repeated migration is safe. The
archive restores the exact controller and supervisor bytes after the old
home is deleted.
- The archived failed source does not gain executable recovery
authority.
- Local server typecheck is blocked by reused workspace declarations for
accounting, bootstrap and ingress contracts. No diagnostic names either
modified owner or test file. Full local typecheck, repo-wide tests and
build are not claimed; clean CI is required before merge. The exact-head
CI has now passed typecheck, build, policy, Runner checks, browser E2E,
and all server test shards.
- Rehearsal verification against the copied historical source remains
required. Full tenant migration and hosted deployment qualification
remain separate gates.

## Risks

The archive preserves evidence for an already failed source. It does not
certify that source as resumable. A prior snapshot must match exactly,
and the normal archive owner checks the terminal failed binding before
it publishes. Existing durable checkpoints remain authoritative. A
missing or changed proof still blocks migration.

## Model Used

OpenAI Codex, exact model ID `gpt-6.1-sol`, with reasoning, tool use and
code execution. The host does not expose context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have described the issue in-PR following the bug template
- [x] I have not referenced internal or instance-local Paperclip issues
or links
- [x] My branch name describes the change and contains no internal
ticket id or instance-derived details
- [x] I have run the relevant tests locally; retained failures and
limits are listed above
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-11-04 13:40:53 -06:00
Dotta 55d7df2bad fix(runtime): bound checkpoint data and preserve durable failed sessions (#18959)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Native Runner checkpoints preserve controller state across server
replacements.
> - Enrollment imports legacy controller state into those durable
checkpoints.
> - The importer passed extra source fields into each encrypted record,
duplicating the whole source and exhausting memory.
> - Some failed runs already had durable checkpoints but no session
snapshot. Re-importing them incorrectly required resumable state.
> - This PR stores only each record's binding and contents, and
preserves matching failed checkpoints without changing their recovery
status.

## Linked Issues or Issue Description

Refs #18957 and #18943.

**What happened?**

A 538-record migrated checkpoint stored 1,108,851,510 bytes of encrypted
material. Every record included the full 1.4 MB legacy source. Large
writes disconnected and later reads exhausted memory.

**Expected behavior**

Each encrypted record contains only its company, issue, run, part and
contents.

**Steps to reproduce**

Run offline controller migration with a retained controller that has
many commands. Decrypt a saved envelope and inspect its fields. The old
writer also includes the entire offline migration input.

**Paperclip version or commit**

Reproduced on `a1f3637c96dfadaf3a15ae9c83aa8227f4fed20e`.

## What Changed

- Serialize only company, issue, run, part and contents in encrypted
checkpoint envelopes.
- Preserve an already-durable failed checkpoint when its run, runner and
session match and the legacy session snapshot is absent. Keep its
failure, recovery blockers, owner and pointers unchanged.
- Report the number of failed checkpoints preserved during maintenance.
- Test exact encrypted contents, idempotent preservation after removing
the old home, and rejection of successful or foreign-session sources.
- Document the migration findings and verification boundaries.

## Verification

- The oversized-envelope regression failed before the serializer fix.
- The already-durable failed-source regression failed before the
preservation fix.
- Four focused test files: 44 tests passed. The migration suite passed
all 5 tests again after adding the foreign-session control.
- Server typecheck passed. Greptile reviewed `c4f02a064c` at 5/5 with no
findings. The exact-head PR workflow passed, including typecheck, build
and all required tests.
- Live staging repair preserved all 16 affected checkpoint sets: 2,982
records, 6,400,144,676 bytes reduced to 15,419,528 bytes. Each record
matched its legacy source and passed re-encryption verification.
Original encrypted rows and source files remain on the retained volume.
- Full hosted enrollment and active-agent deployment proof remain
pending. Deployment will follow the normal staging release pipeline.

## Risks

The serializer affects normal and migrated checkpoint writes. The
decoder already accepts the same five fields and continues to accept
older envelopes. Preservation applies only to a failed run with an
exact, validated durable checkpoint and no session snapshot; it grants
no new recovery authority. This change does not rewrite existing
database records automatically. Existing failures and missing provider
files remain failures until their owning recovery path resolves them.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, tool use and code execution.
The exact deployment model ID and context-window size are not exposed in
this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-11-04 07:14:58 -06:00
DottaandPaperclip d12de135a7 fix(runtime): preserve legacy identities and bound checkpoint imports (#18957)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Ephemeral web servers must preserve native Runner sessions before
removing local storage.
> - Legacy session imports validate the workspace and saved provider
authority.
> - A protocol lease can retain a logical workspace ID while copy-back
uses a separate physical sandbox lease ID.
> - Comparing these different IDs blocks valid legacy sessions during
enrollment.
> - This pull request checks the workspace binding, retains the full
saved protocol identity check, and bounds checkpoint inserts inside the
owner transaction.
> - Existing sessions can migrate without changing their identity or
discarding files.

## Linked Issues or Issue Description

Refs #18943 and #18841.

**What happened?**

The first full staging enrollment stopped with
`native_controller_migration_artifact_binding`. A successful native
session had valid controller and provider-pack identities, but its
physical sandbox lease had a different ID.

**Expected behavior**

Import the original session when its workspace and saved provider
authority match. Reject foreign workspaces and protocol identities.

**Steps to reproduce**

Create a retained session whose sync record points to the execution
workspace and a separate physical lease. Run the offline controller
migration. The prior comparison rejects this valid record.

**Paperclip version or commit**

Reproduced on `84aa989bf9d08fc005ac273c37f9e1d860a4db25`.

**Deployment mode**

Docker with external PostgreSQL and shared object storage.

## What Changed

- Compare the sync record's workspace ID with the frozen execution
workspace.
- Keep the full saved provider-pack check for company, agent, workspace,
session, Runner, protocol lease, remote path, and provider digest.
- Use distinct physical and protocol IDs in the database-backed
migration fixture. Reject a foreign workspace and a changed protocol
lease before any checkpoint import.
- Limit migration inserts to 64 records and about 512 KiB of serialized
rows per statement. Send a larger individual record alone. Keep all
statements in the same transaction.
- Verify that a conflict in a later batch rolls back earlier batches,
then import and decrypt the complete checkpoint.
- Record both live failures and the comparison evidence in the
preservation plan.

## Verification

- The updated fixture failed on the original comparison and passes with
this fix.
- Targeted migration, controller recovery, and provider authority tests:
39 passed.
- Full repository typecheck and the latest server typecheck passed
locally. The complete PR workflow passed on `a1f3637c96` (run
41827558125), including build and test gates. The Docker Compose setup
download failed once before the test step; its infrastructure retry
passed. A separate full local test/build run is still in progress.
- A read-only staging preflight inspected 807 selected legacy sessions.
It found zero mismatches under the corrected workspace and full
saved-provider checks.
- A single 538-record, 2.2 MB checkpoint insert repeatedly closed the
live database connection on pooled and direct endpoints. A
forced-rollback comparison imported the identical checkpoint with
batches of 64. An unbatched control failed again after cache warm-up.
The exact server-side disconnect cause remains unknown; all failed
receipts are retained.
- The original failed enrollment and volume are retained. The corrected
importer committed 32 additional sessions and 2,982 checkpoint records.
Full import and deploy handoff remain pending while memory use is
investigated.

## Risks

The import checks durable session authority. A weaker identity check
could import the wrong session. This change retains the saved provider
authority validation and adds an explicit foreign-protocol rejection
test. Batching adds statements for large imports, but a late failure
still rolls back the complete owner transaction. It does not rewrite
session identity, change provider lifecycle, or detach any volume.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, tool use, and code
execution. The exact deployment model ID and context window are not
exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-11-04 06:36:31 -06:00
DottaandPaperclip 612d9931a6 Support per-turn Runner sessions on ephemeral web servers (#18932)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The web server controls native Runner sessions in remote sandboxes.
> - An ephemeral web server must recover without its previous local
filesystem.
> - The existing admission rule accepts warm sessions. Managed Claude,
Grok, and OpenCode sessions resolve to per-turn execution.
> - Per-turn execution also needs durable provider-session bytes after
the sandbox is retired.
> - This pull request adds encrypted backup publication and removes the
warm-only admission rule.
> - Both lifecycle modes can use the existing native ownership and
checkpoint contracts during a web deployment.

## Linked Issues or Issue Description

Refs: #18518, #18529, #18826, #18835, #18841, #18864, #18887.

**What existing behavior does this improve?**

Native Runner execution on web servers with
`PAPERCLIP_EPHEMERAL_SERVER=true`.

**Current behavior**

The admission rule requires a warm Runner lifecycle. Managed provider
credentials can resolve an agent to per-turn execution, so enabling the
ephemeral deployment profile blocks those turns. A database controller
checkpoint does not preserve provider files after the old web home and
per-turn sandbox are removed.

**Proposed behavior**

Admit native execution in either resolved lifecycle. Keep provider and
credential choices unchanged. Publish encrypted provider state to shared
storage before sandbox cleanup. Restore it from a fresh web home for the
next turn. Use the existing controller lease and generation checks for
active takeover.

**Reason and benefit**

Operators can remove the web server volume without excluding per-turn
providers or forcing managed accounts into warm sessions. New native
Daytona profiles automatically enter both rolling-deployment
qualification lanes.

**Breaking changes**

The additive migration creates a backup publication ledger. Existing
volume-backed local-disk installations retain their local backup path.
S3 installations publish encrypted backups and require a stable secrets
master key. Existing-volume enrollment must import surviving session
data before detaching the volume.

## What Changed

- Admit native Runner execution independently of its warm or per-turn
lifecycle. Keep host-owned legacy execution excluded from ephemeral
deployments.
- Store private provider state as encrypted objects. Journal uploads
before I/O, read them back, and fence publication against the current
native owner. Keep the previous published backup when storage or
ownership checks fail.
- Restore exact provider bytes into a private cache. Require an exact
durable backup before sandbox cleanup. Extend the existing bounded
retention pass to retire stored objects without adding idle polling.
- Import selected legacy controller and provider state in the existing
offline maintenance process. Preserve queued work, task pointers,
pending recovery, and original files. Prefer canonical database
checkpoints.
- Preserve already-failed legacy controllers with missing original
artifact proof as encrypted archives. These archives do not become
execution authority. Successful retained sessions still require proof.
Report archival and executable imports separately.
- Verify unmanaged Grok API keys through the existing xAI account
validator. The live test exposed a readiness gap that kept remote Grok
agents paused after platform checks. Preserve failed credentials and the
separate runtime warning.
- Ingest Grok whole-prompt usage at the owning ACP boundary. Bind the
receipt to the exact outbound request/session; reject replay, conflicts,
and incomplete authority. Separate turn cost from cumulative session
cost in the sidecar schema and Rust normalization. Preserve managed
billing identity and identify direct xAI API credentials.
- Preserve published workspace directory names across cold allocations,
including destroyed-allocation cleanup. Keep unpublished epoch/lease
directories isolated and refuse to overwrite an occupied preparation.
This fixes the cold-session identity regression exposed by #18922.
- Increase bounded checkpoint-header inspection to 1 MiB. Retain the
aggregate inspection limit.
- Register all nine native Daytona profiles in per-turn and warm
rolling-deployment suites. Delete the entire departing server home,
exercise ordinary reads and writes, require active ownership transfer,
then check a later turn on another fresh server. Permit only exact
notification replay after reconnect.

Ownership stays with the existing modules: Runner validates its protocol
state; Core validates run scope and controller ownership; storage owns
object I/O; the maintenance process owns offline conversion; the E2E
wrapper owns process replacement and probes. No provider protocol is
added to the shared admission rule. Grok receipt parsing stays in its
provider module. The shared sidecar gains an explicit cost basis because
its existing price field means session-cumulative spend, while Grok
reports prompt totals. Existing consumers retain cumulative behavior
when the new field is absent.

## Verification

- Focused native admission, archive validation, publication fencing,
cleanup, readiness, legacy import, and E2E observer tests pass. Real
PostgreSQL cases verify that queued intent and historical recovery rows
stay unchanged.
- Full typecheck and build pass on the rebased branch. The review
follow-up passes server typecheck, 29 focused
PostgreSQL/archive/readiness tests, and module-boundary checks. Revision
fb8d39a7a1 reached 55 successful CI checks and Greptile 5/5 with no
unresolved threads. The Grok follow-up passes Runner/server typechecks,
238 ACP runtime/projection/usage tests, 16 sidecar-schema tests, the
Rust cost regression, and Core billing regression. The e9aae9cf revision
passed all 57 successful checks, with 5 skips and 2 neutral checks, and
exact-head Greptile 5/5. The latest 9cbec30a4f follow-up changes only
E2E catalog/admission controls; its 291 affected tests pass, all 57
check contexts succeeded (5 skips, 2 neutral), and exact-head Greptile
is 5/5 with no open review threads.
- Migration numbering and safety checks pass.
- A local real PostgreSQL/S3 roundtrip preserved 2,870,101,591 payload
bytes across 89,100 archive entries after deleting the source directory.
Restored SHA-256 matched; upload/readback took 56.5 seconds, restore
74.8 seconds, process peak RSS was 1.40 GB, and all fixture resources
were removed.
- Archives preserve contained relative links, reject link
chains/traversal, and enforce independent byte/entry/object limits.
Offline verification streams hashes. Orphaned deleted-run backups stay
on the original volume. Obsolete object retention preserves the selected
backup, live lease references, and pending uploads with owners.
- Isolated API-key Codex deployment: original active runner/session
transferred to the replacement and committed. All 567 reads, 57 writes,
and 57 readbacks succeeded. A second replacement completed a
same-session continuation with all 287 reads and 29 writes succeeding.
The strict cell failed two agent-authored shell commands; this result is
retained as failed.
- Isolated API-key Claude deployment: original active runner/session
transferred and committed. All 584 reads, 59 writes, and 59 readbacks
succeeded. A second replacement completed a same-provider-session
continuation, with 211 reads and 22 writes succeeding. The strict cell
failed an initial completion call that omitted a registered attachment
citation; the agent corrected it. This result is retained as failed.
- Isolated API-key OpenCode deployment: the same active runner/session
transferred and committed. All 481 reads, 49 writes, and 49 readbacks
succeeded. A second replacement retained the provider session and
completed useful work, with 156 reads and 16 writes succeeding. The
strict cell failed agent tool calls: a denied external-directory write,
malformed artifact hashes, and a second completion after the first
result was committed. There was one submitted/completed turn and one
committed result; reconnect notification replay was identical. This
result is retained as failed.
- Grok's real first turn now completes with settled usage and provider
cost ($0.41397); the next turn is admitted normally. That attempt then
exposed a shared workspace-path identity regression before deployment.
Three cold-restore cases reproduced it before the fix; 106
workspace/transport tests and four focused cold-restore cases pass
afterward, including destroyed allocation and occupied-directory
preservation. Server typecheck and build pass. At b5b0dbb03f both
controller switches passed the read/write probe without failure, and the
active runner retained its process while the controller generation
advanced. The third turn exposed an invalid reasoning-token subset
check; ad07e681ba fixes it with the actual receipt regression. Two later
live attempts failed with an upstream Grok rate limit before deployment.
A tiny preflight prompt succeeded before the second attempt, but the
full workload was still rate-limited. The final live gate remains
incomplete. No accounting or identity guard was bypassed. Earlier failed
attempts and their exact resource-cleanup receipts remain recorded.
- Earlier Codex/Claude/OpenCode receipts predate #18922; they establish
their tested revisions. Current-head live qualification remains pending;
#18943 separately preserves pre-enrollment logical/provider workspace
addresses and adds actual legacy migration proof. Its first Codex
migration attempt stopped safely at skill-version verification.
- Earlier attempts remain recorded: missing local provider-pack setup
blocked one Claude launch, and the observer rejected identical reconnect
replay in another. Setup and the observer were corrected before the
latest run.
- Named staging enrollment has not started. Its serving revision and
post-deployment journeys remain separate delivery gates.

- Broader E2E harness validation exposed deployment-catalog and
installed-lane coverage drift; the affected 291 controls now pass.
Twelve other failures reproduce on unchanged base 1a39dea9aa. They
concern cleanup call expectations, dated operating-overhead fixtures, a
Pi profile-version expectation and workflow-security expectations. No
baseline failure is reported as passing.

## Risks

- Provider archives can contain credentials. Objects use authenticated
encryption with scoped associated data and a wrapped data key. The
original stable master key remains required.
- Storage failure prevents publication and sandbox cleanup. Operators
must keep shared storage available and preserve the previous volume
during enrollment.
- Legacy state without verified identity cannot become executable
recovery authority. Archival preserves evidence and existing failures;
it does not recover already-lost provider files or clear blocked tasks.
- Local overlap probes establish the tested application behavior. They
do not establish Railway routing behavior or live managed-subscription
qualification.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, tool use, code execution,
and live integration tests. The exact runtime variant and context-window
size are not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-11-04 02:12:51 -06:00