Commit Graph
6162 Commits
Author SHA1 Message Date
Dotta 7bcc1d222b Merge branch 'codex/sleep-stack-06' into codex/sleep-stack-08
* codex/sleep-stack-06:
  fix(ui): invalidate pending startup work on sign-out
  fix(server): park persisted deferred admission refusals
  test(server): preserve attention feed beyond blocker root budget
2026-10-30 20:51:06 -05:00
Dotta 203346b122 Merge branch 'codex/sleep-stack-05' into codex/sleep-stack-06
* codex/sleep-stack-05:
  fix(ui): invalidate pending startup work on sign-out
  fix(server): park persisted deferred admission refusals
  test(server): preserve attention feed beyond blocker root budget
2026-10-30 20:51:05 -05:00
Dotta 4a2155d9ef Merge branch 'codex/sleep-stack-03' into codex/sleep-stack-05
* codex/sleep-stack-03:
  fix(ui): invalidate pending startup work on sign-out
  fix(server): park persisted deferred admission refusals
  test(server): preserve attention feed beyond blocker root budget
2026-10-30 20:51:05 -05:00
Dotta efe830b6b7 Merge branch 'codex/sleep-stack-01' into codex/sleep-stack-03
* codex/sleep-stack-01:
  fix(ui): invalidate pending startup work on sign-out
  fix(server): park persisted deferred admission refusals
  test(server): preserve attention feed beyond blocker root budget
2026-10-30 20:51:05 -05:00
Dotta 2248af92a8 Merge branch 'codex/sleep-stack-07' into codex/sleep-stack-01
* codex/sleep-stack-07:
  fix(ui): invalidate pending startup work on sign-out
  fix(server): park persisted deferred admission refusals
2026-10-30 20:51:05 -05:00
Dotta a91c4280aa Merge commit '295f4f82722d92b93d8b5135399bca937116b536' into codex/sleep-stack-01
* commit '295f4f82722d92b93d8b5135399bca937116b536':
  test(server): preserve attention feed beyond blocker root budget
2026-10-30 20:51:04 -05:00
DottaandPaperclip 11e92e3875 merge: preserve typed admission refusals and status-card source signals
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:51:04 -05:00
Dotta 6cf6495fd8 Merge branch 'codex/sleep-stack-02b' into codex/sleep-stack-c1
* codex/sleep-stack-02b:
  fix(ui): invalidate pending startup work on sign-out
2026-10-30 20:50:39 -05:00
Dotta c0fe0feffb Merge commit '19a97bbe57d1ebd3691c70dd822488efe7e5d3e1' into codex/sleep-stack-c1
* commit '19a97bbe57d1ebd3691c70dd822488efe7e5d3e1':
  fix(server): park persisted deferred admission refusals
2026-10-30 20:50:39 -05:00
Dotta 67cd9b285d Merge branch 'codex/sleep-stack-02a' into codex/sleep-stack-02b
* codex/sleep-stack-02a:
  fix(ui): invalidate pending startup work on sign-out
2026-10-30 20:50:38 -05:00
Dotta cec3046246 Merge commit 'a8783f8acebdb50b30cc8118e9d20da18d04fd3b' into codex/sleep-stack-02a
* commit 'a8783f8acebdb50b30cc8118e9d20da18d04fd3b':
  fix(ui): invalidate pending startup work on sign-out
2026-10-30 20:50:38 -05:00
DottaandPaperclip a8783f8ace fix(ui): invalidate pending startup work on sign-out
Keep session-readiness failures inside the existing bounded retry policy.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:44:52 -05:00
DottaandPaperclip 19a97bbe57 fix(server): park persisted deferred admission refusals
Distinguish a budget or agent refusal saved on the existing receipt from genuine recovery failure. Preserve HTTP409 messages and details, grant each new wait reason its existing finite grace, and retain failure backoff for unsaved or unexpected errors. Prove actual Retry admission,25-minute SQL quiet, independent warm producer-to-process release, missing/cancelled receipts and real PostgreSQL write failure.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:35:57 -05:00
DottaandPaperclip 295f4f8272 test(server): preserve attention feed beyond blocker root budget
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:35:52 -05:00
Dotta fdea31dd67 Merge branch 'codex/sleep-stack-06' into codex/sleep-stack-08
* codex/sleep-stack-06:
  fix(ui): supersede startup jobs when newer edits are admitted
2026-10-30 20:34:08 -05:00
Dotta 298ab659bc Merge branch 'codex/sleep-stack-05' into codex/sleep-stack-06
* codex/sleep-stack-05:
  fix(ui): supersede startup jobs when newer edits are admitted
2026-10-30 20:34:07 -05:00
Dotta 554602c5b4 Merge branch 'codex/sleep-stack-03' into codex/sleep-stack-05
* codex/sleep-stack-03:
  fix(ui): supersede startup jobs when newer edits are admitted
2026-10-30 20:34:07 -05:00
Dotta ebfa9e981d Merge branch 'codex/sleep-stack-01' into codex/sleep-stack-03
* codex/sleep-stack-01:
  fix(ui): supersede startup jobs when newer edits are admitted
2026-10-30 20:34:07 -05:00
Dotta bcc2cd2e21 Merge branch 'codex/sleep-stack-07' into codex/sleep-stack-01
* codex/sleep-stack-07:
  fix(ui): supersede startup jobs when newer edits are admitted
2026-10-30 20:34:06 -05:00
Dotta 17c1a82192 Merge branch 'codex/sleep-stack-c1' into codex/sleep-stack-07
* codex/sleep-stack-c1:
  fix(ui): supersede startup jobs when newer edits are admitted
2026-10-30 20:34:06 -05:00
Dotta 077d9d8b0a Merge branch 'codex/sleep-stack-02b' into codex/sleep-stack-c1
* codex/sleep-stack-02b:
  fix(ui): supersede startup jobs when newer edits are admitted
2026-10-30 20:34:06 -05:00
Dotta 476472bd9c Merge branch 'codex/sleep-stack-02a' into codex/sleep-stack-02b
* codex/sleep-stack-02a:
  fix(ui): supersede startup jobs when newer edits are admitted
2026-10-30 20:34:05 -05:00
Dotta f0a54cf6f9 Merge commit 'b257ae2014866fe31b96e09c5eba92940fc835ba' into codex/sleep-stack-02a
* commit 'b257ae2014866fe31b96e09c5eba92940fc835ba':
  fix(ui): supersede startup jobs when newer edits are admitted
2026-10-30 20:34:05 -05:00
DottaandPaperclip b257ae2014 fix(ui): supersede startup jobs when newer edits are admitted
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:29:15 -05:00
DottaandPaperclip 8c72649a39 merge: preserve backup expiry alongside source-driven workers
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:27:24 -05:00
DottaandPaperclip 28f37718da merge: retain external refresh and predecessor notifications
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:27:08 -05:00
DottaandPaperclip 8cc1e2be07 merge: preserve confirmation and attention mutation notifications
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:26:35 -05:00
DottaandPaperclip 40bd4df17b merge: preserve routine projections across retained execution producers
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:26:14 -05:00
DottaandPaperclip 688f35763d merge: preserve attention, status-card and recovery source ownership
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:25:15 -05:00
DottaandPaperclip 9b4beff72b merge: preserve status-card and recovery producers in the review stack
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:24:40 -05:00
DottaandPaperclip 290d12cf4b merge: rehearse issue-recovery predecessor for saved receipts
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:24:05 -05:00
DottaandPaperclip dee5296b8a merge: rehearse current dispatch predecessor for issue recovery
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:23:55 -05:00
DottaandPaperclip fcc107739c merge: rehearse current master and UI prerequisite for dispatch
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:23:37 -05:00
DottaandPaperclip 8f58be556a fix(ui): retain startup autosave through session recovery
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:18:43 -05:00
DottaandPaperclip 255713e0cd fix(server): bound and coalesce issue retention invalidations
Bound reverse ancestor discovery before materializing adjacency, deduplicate cycles and emit one canonical affected-issue batch per write. Overflow delegates complete company reconstruction to existing paging instead of dropping eligibility or creating per-ancestor worker debt. Prove real high-fanin producer bursts, PostgreSQL execution limits, canonical cyclic batches and far ancestor archive deadlines.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 20:02:36 -05:00
DottaandPaperclip dff6c00468 Join receipt acceptance passes before advancing saved deadlines
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 19:50:27 -05:00
DottaandPaperclip 8911cca5d0 fix(server): retain live evidence beyond blocker graph admission
Keep bounded returned child facts independent of graph node and edge admission, and use the existing live-work predicate for running status, active runs and pending waits. Cover the opposite query ordering with 1,999 explicit blockers, fresh retention checks, no archive/outbox and unchanged SQL/resource bounds.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 19:49:06 -05:00
Dotta 0adba98c10 Merge commit 'e3fff84b6f81448c730dd165253a1a673f8d19b3' into codex/sleep-deferred-execution-receipts
* commit 'e3fff84b6f81448c730dd165253a1a673f8d19b3':
  fix: scope comment-triggered recovery to the affected issue
  test: await issue recovery dispatch and cancellation settlement
2026-10-30 19:45:15 -05:00
DottaandPaperclip c74f5f12ba Retain moved receipt deadlines and wake released execution gates
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 19:45:15 -05:00
DottaandPaperclip 6469daec07 fix: bound status-card active-hours calculation work
Reuse bounded timezone formatters and upcoming openings only within their exact searched closed ranges. Short-circuit empty windows while preserving the existing cold DST search and precise instant eligibility. Verify cost bounds, cache eviction, timezone transitions and twenty-card ordinary source delivery.

Co-Authored-By: Paperclip <paperclip@paperclip.ing>
2026-10-30 19:41:19 -05:00
DottaandPaperclip e3fff84b6f fix: scope comment-triggered recovery to the affected issue
Preserve company reconstruction for graph, run and eligibility changes. A real PostgreSQL producer regression verifies one assignment check among1000 open tasks, with broader eligibility reconstruction still intact.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 19:39:21 -05:00
DottaandPaperclip 7bb1af657a test: await issue recovery dispatch and cancellation settlement
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 19:38:27 -05:00
DottaandPaperclip 71d7b9f09e fix(server): bound blocker facts and preserve origin authority
Resolve liveness/stranded references through trusted company issue rows, including valid none sentinels. Bound shared blocker nodes, edges and query results; return private deferred-root completeness so retention immediately performs finite exact source checks. Preserve already-observed live work, completed-root classification and true deadlines. Cover historical producer metadata, moved recovery tasks, many-heavy graph limits, quiet rechecks and faithful transaction fixtures.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 19:35:20 -05:00
DottaandPaperclip ac6c5191ee Drive saved execution receipts from committed work and deadlines
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 19:22:39 -05:00
Dotta f201195a92 test: await committed recovery and adapter admission outcomes 2026-10-30 19:20:10 -05:00
Dotta 4ef018cfe6 test: model retention reads in native cleanup transaction fixture 2026-10-30 19:17:14 -05:00
Nicky LeachandPaperclip 493e229d93 perf(runner): cache verified native executable digests (#18390)
## Thinking Path

> - Paperclip manages AI agents and their task execution.
> - Runner checks qualified native programs before it starts a provider.
> - Installation checks and command opening can hash the same program
again.
> - A new sidecar process repeats this work on a later warm task.
> - This pull request stores the computed digest in a private filesystem
cache.
> - Every cache hit still checks the independently selected trusted
digest and current file metadata.
> - An unchanged program can start without another full native file
read.

## Linked Issues or Issue Description

**What existing behavior does this improve?**
Repeated **qualified ACPX** native executable admission in Runner.
Claude, ACPX-Codex, and Grok use this verifier in both Core-owned and
plugin-backed launches. The ordinary native Codex app-server launcher is
a different path and is not changed. A retained provider that opens no
new native command has no saved hash work here. The measured Claude task
path does not require a comment backlog.

**Current behavior**
Installation verification and final command opening each read and hash
the native executable. The qualified Linux x64 Claude file is
241,667,256 bytes. A new verification and command lease reads
483,334,512 native bytes. Another Node process repeats both reads.

**Proposed behavior**
Store the actual computed SHA-256 digest by device, inode, size,
nanosecond modification time, and nanosecond change time. Reuse it
across Runner and sidecar processes. Compare each hit with the current
build-owned digest. Hash the file on a miss or changed identity. This
replaces the earlier Claude-only deferral design in this same PR.

**Reason and benefit**
The first verification and command lease reads the native file once.
Later processes read none of its native bytes while its identity stays
the same. Related: #16372 established qualified executable admission.
This change is independent of other preparation PRs. It does not change
provider pins or profile versions.

## What Changed

- Add a shared filesystem digest cache under the absolute OS temporary
root at `paperclip-runner-<uid>/executable-digests-v1`.
- Use private directories and files, versioned hash-only filenames,
bounded JSON entries, and atomic temporary-file replacement. Cache files
contain a version and the computed digest. They contain no credentials
or source paths.
- Fall back to full hashing when the cache is missing, unreadable,
malformed, or unusable. Keep current expected-digest selection outside
the cache.
- Keep cache data outside task homes. Neither `HOME` nor task cwd
selects the path. The OS temporary-root selection honors absolute
platform `TMPDIR`, `TMP`, or `TEMP` overrides. A relative root disables
caching. Hosts must keep that root outside task workspaces. Temp cleanup
causes a later rehash.
- Keep the no-follow executable open, regular-file and size checks,
execute permission, descriptor ownership, before/after identity checks,
and preparation-to-launch identity comparison. Cache publication occurs
before the final identity checks.
- Use this path for standalone installation checks and final command
opening. Remove the earlier pending-digest type and Claude-only launch
helper. Runtime host and profile selection keep their original
structure.
- Test changed content, all fingerprint fields, symlinks, mode changes,
inode replacement, mutation during lookup/publication, concurrent cache
writers, wrong trusted pins, and cache failures.
- Include a deliberate trust-boundary test: a process running as the
same OS user can plant a matching cached digest for changed bytes. It
opens a test descriptor and executes nothing.

In plain language: Runner remembers the hash for the same file. It still
checks which file it opened and which hash the build requires. The cache
trusts the OS user who can write it.

## Verification

From `packages/paperclip-runner`:

- `../../node_modules/.bin/vitest run
src/drivers/acpx/executable-digest-cache.test.ts
src/drivers/acpx/installation-integrity.test.ts
src/drivers/acpx/runtime-host.test.ts` — 177 passed, 6 platform-specific
skips.
- `../../node_modules/.bin/tsc -p tsconfig.json --noEmit` — passed.
- `git diff --check` and the added-line secret, PII, private-address,
and code-comment scan — passed.

The offline comparison uses baseline
`45a3a92e6dc52d20923b9aa34a22fee2ec5443f9` and treatment
`c4356df12032448de90516ae329d8f939af10984`. Each sample starts a
different Node process. Each normal sample runs the actual qualified
installation verifier and opens a command lease. Seven samples per case
follow one warmup. The cache is removed before each cold case. The next
process reuses its entry. Baseline order alternates around the treatment
pair. Command digest and package paths match in every pair.

| Verifier plus command opening | Baseline | Cold cache | Later process
hit |
| --- | ---: | ---: | ---: |
| Full native reads | 2 | 1 | 0 |
| Native bytes read | 483,334,512 | 241,667,256 | 0 |
| Local median, ms | 1041.26 | 602.70 | 130.17 |
| Local range, ms | 994.20–1133.11 | 580.27–999.83 | 121.96–179.45 |
| Median whole child process, ms | 1379.96 | 988.75 | 523.01 |

Raw verifier-plus-open samples in ms:

- Baseline: 1133.11, 1074.40, 1061.99, 1041.26, 994.20, 1036.12,
1037.70.
- Cold: 647.13, 646.33, 999.83, 584.83, 580.27, 583.37, 602.70.
- Later process hit: 179.45, 138.37, 134.39, 130.17, 121.96, 122.33,
126.68.

Separate direct-opener fault probes use a disposable copy of that same
native file:

| Change | Native bytes read | Result | Local open, ms |
| --- | ---: | --- | ---: |
| First copied file | 241,667,256 | Accepted | 526.14 |
| Next process, different HOME and task cwd | 0 | Accepted | 24.91 |
| Changed timestamps | 241,667,256 | Accepted after hashing | 531.40 |
| New inode, identical bytes | 241,667,256 | Accepted after hashing |
536.70 |
| Corrupt byte, same size and exactly restored mtime | 241,667,256 |
Rejected | Whole process: 841.36 |
| Different independent trusted pin | 0 | Rejected | Whole process:
374.76 |

The corruption probe keeps `mtimeNs` exactly equal before and after, at
`1000000000000000000`. Its changed `ctimeNs` invalidates the entry.
Cache expiry is not required. The changed-pin probe rejects the old
actual digest without a native read.

The cached image is
`sha256:99ce80690a0c13328f41fd84156cc73e1ac562eaed3120fd41d04d7acdfb325d`.
The Node binary is `/opt/paperclip/runner/libexec/node`, version
`v24.20.0`. The artifact is Claude SDK `0.3.286`, with expected digest
`sha256:fe503f65c6289d59c23e5b21ae44f03583f997dd33a2cbfc75ab4f96fb8fc73f`.
The container used a read-only root, a disposable writable tmpfs, and
disabled network. No provider process, model request, credential, or
deployment was used.

**These elapsed values are diagnostics from Linux x64 CPU emulation on
an ARM64 Docker host. They are not production latency or TTFT
estimates.** The exact byte counts, cross-process reuse, output
equality, and invalidation results are the portable evidence.

The saved phase 0 exports have no directly comparable native executable
hashing span. Their broad `runner.transport.attach` spans include other
work. A production comparison within 20% is therefore unavailable for
this seam. The earlier local 919 ms control was also an emulation
diagnostic; it is not a production baseline.

The initial Docker attempt was denied access to the local socket by the
sandbox. The same offline command then ran with local socket permission.
An initial fault probe restored mtime through a `Date`, which did not
prove exact nanosecond equality. Its raw report is retained as
historical; the final probe sets and verifies an exact mtime before and
after corruption. The prior Claude-only implementation and its checks
and measurements remain historical evidence. They do not qualify this
replacement.

The superseded home-directory cache head had one browser recovery test
timeout in its GitHub workflow. It expected a saved title after session
recovery. The failure is retained. No browser code was changed; the
current head reruns CI after moving the cache outside task homes.

No full local CI suite was run, as requested. GitHub CI supplies full
regression coverage. Current head
`c4356df12032448de90516ae329d8f939af10984` passed the complete [GitHub
workflow](https://github.com/paperclipai/paperclip/actions/runs/41145223331),
including all browser shards. Its latest checks have 56 successes and 2
intended skips, including both security scans started when the PR became
ready. Standard Greptile reviewed this exact head at 5/5 with no open
findings. Apex then reviewed the same head at 5/5 under the documented
OS-user trust policy. It reported no new findings. There are no
unresolved review threads. The PR is ready for review and remains
unmerged.

## Risks

- This deliberately weakens protection against the same OS user. That
user can write the cache and can plant a chosen digest for a file
fingerprint. A cache hit trusts that record; metadata identity is not a
fresh content hash. The explicit fault test documents this accepted
policy.
- A read-only administrator-owned Runner can use this user-writable
cache. The cache has no signature, secret, or daemon. It does not
require a Launcher or ROM change.
- Other users cannot use normal cache permissions to write these
entries. Cache errors fall back to hashing. Removing the cache directory
restores full hashing. Old fingerprints leave small unused entries until
the cache is removed or OS temp cleanup evicts it. Temp eviction costs
one later full hash.
- A changed file normally rehashes. A digest that differs from the
independent current pin still fails admission. Existing command,
package, credential, process-lifetime, and final dispatch checks remain.
- No schema, public protocol, package dependency, profile version, or
provider pin changes.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, code editing, test
execution, and tool use. This session does not expose a more precise
serving model ID or context-window capacity.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used with the details available to this
session
- [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 enhancement
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
- [x] The targeted local tests pass; the full local suite was not run as
requested
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation
- [x] I have considered and documented risks
- [x] All Paperclip CI gates are green for the replacement head
- [x] Standard Greptile is 5/5 with no open findings for the replacement
head
- [x] Apex is 5/5 on the current head with no unresolved findings
- [x] I will address review findings before requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
canary/v2026.1031.0-canary.1
2026-10-30 17:07:32 -07:00
Devin FoleyandPaperclip 87ae20ae65 fix(server): reconcile failed sandbox cleanup with signed absence (#18407)
Reconcile failed ephemeral Cloud leases through a signed cleanup-only absence observation when local historical inspection is unavailable. Preserve failure outcomes, exact resource bindings, retention and row-version fences; grant no run-continuation authority.

All 54 current-head checks/statuses passed. Greptile is 5/5, Medium, with no findings or unresolved threads. The 38 focused tests pass; both new reconciliation cases fail without the fallback. Isolated baseline and branch idle suites each pass all 225 cases. The original broader local teardown timeout is retained in the PR, and the full local run remains in progress.

Cloud protocol support is already serving in staging. Exact candidate composition and hosted provider sleep/wake qualification follow this merge. Production has not been changed.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 17:04:04 -07:00
DottaandPaperclip e41bde2146 fix(server): bound graph queries and scope issue retention work
Chunk graph recovery, agent and workspace inputs; prove a70000-node PostgreSQL graph stays below parameter limits. Route ordinary issue writes through identity-scoped dependency invalidation for old/new parents, blocker ancestors, run links and liveness origins. Correlate all issue-related attention sources, preserve unrelated deadlines, and canonicalize notification keys. Exercise actual held/burst producers, visibility, relation and incident transitions.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-30 19:01:12 -05:00
Dotta 32044a63e1 fix: scope status-card deletion notifications to its company 2026-10-30 19:00:51 -05:00