mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-24 10:13:11 +02:00
## Thinking Path > - Paperclip manages AI agents and their work. > - The experimental Runner owns provider processes and durable sessions. > - Pi needs working task execution and human controls. > - The five-PR stack must preserve changes already on master. > - Each layer now carries the complete integrated source for a safe sequential fallback. > - This PR belongs to native GitHub stack #15602, ending at #14956. ## Linked Issues or Issue Description Refs #14436, #14631, #14743 and #14956. Ship Pi 1.0 through the experimental Paperclip Runner. The five PRs are #14921, #14922, #14923, #14924 and #14956. The user authorized the complete merge after checks pass. Existing `pi_local` execution is unchanged. Accounting and wider provider/platform qualification remain deferred. ## What Changed - Recover missing final replies after workspace finalization changes owners, using accepted-turn evidence without rerunning work or granting external-chat publication. - Preserve the admitted Pi instruction root across warm runs, while retaining changed-root rejection. - Give Pi a bounded 15-second default shutdown grace so stop, drain acknowledgement and durable suspension can complete. Explicit deadlines and other providers retain their existing behavior. - Integrate the Pi 1.0 runtime and master contracts. - Use Pi profile 22. Preserve explicit caller-selected models and exact native thinking levels. Keep Pi's wrapper, helper, extension and question/control behavior unchanged from the qualified profile-19 runtime. - Preserve master's Dot lifecycle and consent fields, configured task environment, status guards and current Codex/Claude dependency versions. Cursor stays qualified. Copilot stays pending; profile 17 binds the changed shared protocol validation sources. - Exclude general AWS IAM credentials from Pi static/custom provider bindings and selected task projections; preserve the provider-scoped Bedrock bearer key. Profile 21 is retained as historical provenance. Rust and cloud install probes use the current declaration. - Patch bundled brace-expansion 5.0.9 to the exact official 5.0.12 payload. Pin the patch and complete runtime closures. Include the patch in normal installed setup tooling. Keep the upstream Pi shrinkwrap as provenance and permit only this exact security correction. - Include current attestation files in the Docker build context. Keep the repository lockfile unchanged from master. CI and private image builds resolve manifest changes before their frozen installation. ## Verification - Full local `pnpm -r typecheck` passes, including Runner Rust, server and UI. Focused integration checks pass: 194 Runner admission/environment tests, 63 profile/credential tests with one expected skip, 152 Dot/UI configuration tests, and Pi transcript/notice tests. - Full local `pnpm build` passes on the final source. - Fresh final-source checks pass: all 698 Rust workspace tests (32 binaries), 156 credential/profile/controller tests with one expected skip, Runner TypeScript typecheck, and 20 package/setup/sandbox tests. - The profile-21 Pi materializer passes on the native host with the official pinned Node 24.21.0 and its npm. It verifies all 150 locked packages, the patched dependency and the exact closure. Setup/package bundle tests and UI token gates pass. - The old hashes were reproduced for all three supported targets before calculating the patched graph. New closure hashes are darwin-arm64 `282022db10150c6632b3444df421342e7d534bdf5d5fb1097a2e79d0625a2bcf`, darwin-x64 `64e251e19009f755c0b04f73ce2138246faab71a961b0f13d75ebfcc34bef12e`, and linux-x64 `713b1fdff42fb56a1518bdc084f181d70bee8ebadc3e4b1d76321ed9108c8410`. Independent native platform execution is separate from graph identity reproduction. - Historical cloud qualification remains unchanged: all seven core cases pass on shipping source `10dc43c9ec65d88c2f782d62afb296d09494f215`, harness `1a4408a48cfb5a1f094a311141c257c92cd7a893`, image `sha256:5b3a775b383591bda1b0c1889e509acc70ce7f37c53f09733c81d59037f02280`, and accepted Sonnet 4.6/low fixture. All 215 canonical files and all seven cleanup checks pass independent verification. These are profile-19 results and are not relabeled as fresh profile-22 runs. - Current Pi digest: `sha256:e92078bee3c23bec4100aa589013a44613d054cd686826534025d8019e9f39a9`. [The readiness plan](https://github.com/paperclipai/paperclip/blob/codex/pi-production-readiness/doc/plans/2026-10-02-pi-production-readiness.md) preserves campaign and failed-attempt provenance. - Merge only after every PR's current-head CI and fresh review pass. Linux CI covers the full suites, build and browser tests. The local embedded Postgres API-authority suite cannot start on this macOS/Node 26 host, so Linux CI must confirm that suite. ### Fresh profile-22 core qualification — 2026-10-08 All seven accepted core cases pass canonically on Pi profile 22, with `openrouter/anthropic/claude-sonnet-4.6` and native-confirmed low thinking. This model is a fixture; production accepts the caller's explicit Pi provider/model. Runtime/install source: `3241a992f2a7703e59e97ed0fd3e5d6405de4401`. Frozen accepted harness: `1a4408a48cfb5a1f094a311141c257c92cd7a893`. Immutable cloud image: `ghcr.io/paperclipai/paperclip-daytona-runner@sha256:506f22db7edd78f37c0c40bec1cc084af1850455026dbf467194bfbb8fcef141`. Pi digest: `sha256:e92078bee3c23bec4100aa589013a44613d054cd686826534025d8019e9f39a9`. [Hosted Linux image and clean-install verification](https://github.com/paperclipai/paperclip/actions/runs/37868328023) passes, including all 20 source-bound archives, normal CLI/Pi setup, companion import and the production pack reader. This exact installation source includes the latest master integration and the corrected Pi warm instruction-root fence. Full local typecheck/build and current-head hosted CI verify the final stack. All 13 focused real-root regressions pass. The full local executor suite passed 662 tests; 15 database tests could not start the Mac embedded PostgreSQL service. Hosted Linux CI passes the full required verification and E2E checks. These fresh results keep their own source identity; profile-19 results remain historical. | Core path | Canonical campaign | Retained archive SHA-256 | | --- | --- | --- | | File edit, validation, download and Done | `pi-core22-replyfix-0-1791511228` | 23 files; `a473e8603a3dd4737863291f8d3d1e392391f0b16d433c3e0e0e9d8baf7a97b0` | | Pending question and controller restart | `pi-core22-replyfix-1-1791511376` | 33 files; `6b829c4eb74e1f32a89c692a4ae7130dbfc1c6d3cf13915effe2103d9e242c8e` | | Three-turn session/process/workspace continuity | `pi-core22-replyfix-2-1791511587` | 23 files; `7a87021f8f9a3fdd3c58bb4467f8d82c635e3ea4795d6e75f144d9aa14818df8` | | Four typed questions and browser reconnects | `pi-core22-replyfix-3-1791511881` | 42 files; `9e31755252be1f4f9cb0626c984c142d4d1ae5f5bee3a7af08444db8d12c280a` | | Plan approval and completion | `pi-core22-replyfix-4-1791512031` | 22 files; `a0383ce1aab38e7b5a25ce0e9dd3bebea5c037ebd96ae6b29dae19015da2ae2c` | | Same-turn steering and permission denial | `pi-core22-replyfix-5-1791512261` | 39 files; `c929b8c7070f0b66aedc17e65ca46e6beab1e363926ac9f7e2a75fb250f05949` | | Stop during pending permission | `pi-core22-replyfix-6-1791512390` | 33 files; `7f0a58ae0f4d5bfc76149435f4e322537089c5bd16e7ffe9b5ad71f10a621a07` | All 215 canonical files (28714587 bytes) are independently hash-verified. All seven cleanup grades pass, with no owned runtime process or temporary root after each case. Automatic retries are zero. The owned cloud host stopped normally after retention. The prior profile-22 warm attempt remains failed and separately retained: archive SHA-256 `1e54eba5ec72b50cee1534b23d1d1d4f21a090006b8a64501ba70db972abfde5`. Its original canonical classification is preserved. Diagnosis reproduced a product bug comparing an agent-files root against an unset checkpoint-only field. The fix stores the admitted physical root separately from the adopted per-run collection capability. The real-root regression fails before the fix and passes afterward, including rejection of a changed physical root. Fixture, grader, model and all seven accepted case IDs are unchanged; this fresh campaign tests final-reply publication after file registration first. The intermediate restart attempt also remains failed and retained: archive SHA-256 `5dcaefdf1d17cf4cd54fd4cf810f45e736667392339b8ce7caf08bb4e225277f`. Its original canonical classification is preserved. Pi resumed, wrote the verified answer and completed its task; exact runner suspension was proven, but idle stop consumed about 5.2s and left under 3s for the drain acknowledgement. The Pi-only default shutdown grace is now 15s, preserving a full 5s drain round trip and a finite suspension reserve. Explicit caller deadlines, other provider defaults, literal drain receipts and exact suspension identity checks remain unchanged. The timing regression fails before this correction and passes afterward; all 18 focused settlement tests and Runner typecheck pass. The final-source file attempt is also preserved as failed (`candidate_failure`), archive SHA-256 `db6767b6773ea618997927ac77bdb005a5ac81492c7b9c0ffbc900449f829bc9`. Native edit, validation, exact downloadable artifact and Done/succeeded all passed, and the exact final reply was durably recorded. A workspace recovery owner completed before the live heartbeat reached presentation, leaving that reply absent from task chat. Recovery now materializes only a completed final reply from the accepted turn of an ordinary internal Done task, preserving issue/run/contract binding, suppression, external-chat authorization and same-run deduplication. The database regression covers the generated file-preparation receipt, suppression, unapproved external continuation and replay. Server typecheck and all 49 response-selection tests pass; hosted Linux verifies the database regression because embedded PostgreSQL cannot start on this Mac. The delayed-final-answer database regression passes on [the final root-source Linux server shard](https://github.com/paperclipai/paperclip/actions/runs/37868262553/job/113628594152), alongside 1,108 passing tests. The first root Runner shard had one unchanged durable-resume test exceed its 5-second timeout; the identical top-source shard and the isolated exact test passed. One rerun of that failed job and its required aggregate passed without source or test changes. The original failed job log and the single-rerun receipt remain retained. ### October 9 merge verification Current merge head: `5a8fe63512a7166aaef5cf50065a25008aa8b44b`. All current-head checks pass, including `ci / verify` and `ci / e2e`; exact-head Greptile review is 5/5 with no unresolved threads. Current master conflicts are resolved. The user authorized the maintainer override of the code-owner review gate after these checks. The seven retained live core cases remain bound to source `3241a992f2a7703e59e97ed0fd3e5d6405de4401` and its recorded cloud image. ## Risks - The security correction changes the dependency closure and profile identity. Old sessions must reopen on the new profile. Exact identities and credential bindings fail closed. - The runner remains experimental and requires explicit selection. Legacy Pi Local is unchanged. Caller model IDs pass through; the E2E model is a fixture. - Accounting and the broad platform/provider matrix remain deferred. This merge does not publish a release or deploy a service. ## Model Used OpenAI GPT-6 through Codex assisted with reasoning, repository inspection, editing and tool use. The exact serving ID and context window are not exposed in this session. Final live qualification uses Pi 1.0.0 with `openrouter/anthropic/claude-sonnet-4.6` and native-confirmed low thinking. ## 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 #` 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>
364 lines
20 KiB
Markdown
364 lines
20 KiB
Markdown
# Direct live Runner protocol evals
|
|
|
|
For choosing between Runner Evals and full-stack Product E2E Evals, and for
|
|
shared guidance on provenance, history, cost, and failure classification, see
|
|
the [Paperclip evaluation guide](../../../doc/evals.md). This document remains
|
|
the authoritative Runner Evals live protocol runbook.
|
|
|
|
## One Evalbook presentation
|
|
|
|
Every new report uses the canonical Evalbook grid and the existing Runner Lab
|
|
chat viewer for attempt drill-downs. There is no plain-HTML attempt fallback.
|
|
The grid, Latest, test-design, inventory and server-gate pages load the same
|
|
built stylesheet and fonts as the chat viewer. The long-term S3 history index
|
|
references that stylesheet inside an immutable campaign, so every page keeps
|
|
the same dark theme. Static site styles live in
|
|
`devtools/issue-thread/src/evalbook-site.css`, scoped to `.evalbook-site`;
|
|
colors and typography come from the Runner Lab token layer.
|
|
Missing recordings show a notice in the same viewer; missing viewer builds
|
|
fail generation. Build with
|
|
`pnpm --filter @paperclipai/paperclip-runner build:issue-thread` and provide
|
|
`--viewer-root` or `PAPERCLIP_EVAL_VIEWER_ROOT` to the canonical Python renderer.
|
|
|
|
The Actions artifact contains full evidence. S3 uses the same viewer with a
|
|
closed public DTO: only isolated mock-run conversation text, scrubbed private
|
|
references, named tool outcomes, and checks. Tool arguments/results, reasoning,
|
|
provider identities, and company snapshots stay private. The public notice
|
|
explains these redactions. An unverified isolation boundary yields no public
|
|
conversation, not a guessed reconstruction.
|
|
|
|
Public attempts use inert JSON and one shared viewer asset directory. The
|
|
publisher verifies each shell and asset against the exact same-run viewer build,
|
|
checks the public payload contract and local links, and rejects other scripts.
|
|
The CSP prohibits network calls, forms and external resources. Supply
|
|
`PAPERCLIP_RUNNER_PROTOCOL_EVAL_VIEWER_DIR` to the publisher. The workflow sends
|
|
a viewer-only artifact to that job; raw attempts and provider secrets stay out.
|
|
After publication succeeds, the publishing job writes **Open this run's
|
|
Evalbook** and **All eval runs** links to the Actions summary. Its deployment
|
|
URL also points to the exact immutable report, not to the downloadable ZIP.
|
|
Failed publication does not advertise a successful deployment.
|
|
|
|
Before uploading, the report job runs the actual built application in Chromium
|
|
against representative passing, failing and missing-recording pages in both
|
|
reports. It checks initial rendering, tool expansion, read-only controls,
|
|
navigation, reload, a narrow viewport and the public no-API-request boundary.
|
|
In full-evidence reports, a tool's **View in Evidence** link selects the Evidence
|
|
tab and highlights its record, including when reopening that same record after
|
|
switching tabs. The browser check exercises this cross-link too.
|
|
Run the same check locally with
|
|
`node packages/paperclip-runner/scripts/verify-runner-evalbook-viewer.mjs --report-root /path/to/report`.
|
|
Add `--screenshots /path/to/proof` for visual evidence. Public screenshots are
|
|
retained in the aggregate Actions artifact, not added to the public report's
|
|
closed file allowlist.
|
|
|
|
These screenshots are generated acceptance-test evidence from the scrubbed
|
|
completed campaign, not a separate report design:
|
|
|
|

|
|

|
|

|
|
|
|
### Refresh a completed report without calling models
|
|
|
|
Download the aggregate Actions artifact, then:
|
|
|
|
```sh
|
|
node packages/paperclip-runner/scripts/refresh-runner-protocol-eval-report.mjs \
|
|
--source /path/to/downloaded-aggregate \
|
|
--evals-root /path/to/paperclip-evals \
|
|
--viewer-root packages/paperclip-runner/dist-issue-thread \
|
|
--output /path/to/new-refresh-directory \
|
|
--revision chat-v1
|
|
```
|
|
|
|
Publish the returned `reportRoot` with the normal history publisher. The new ID
|
|
is `gha-RUN-ATTEMPT-report-chat-v1`. Original reports remain immutable; history
|
|
adds a labeled refresh and retains the source campaign, original measurement
|
|
timestamp, renderer digest, and `providerCalls: 0`. Scores and evaluated source
|
|
revisions do not change. This is not a new model qualification run. Future live
|
|
runs create chat reports automatically.
|
|
Refreshes are ordered by their render time in the history list, but keep the
|
|
original measurement timestamp and never replace the latest or latest-green
|
|
qualification identities. The HTML history links each measurement to its newest
|
|
presentation, while retaining every original bundle and listing refreshes separately.
|
|
Refreshes also recover retry-inclusive estimated and provider-list costs from the
|
|
retained attempt records. They never add another model-cost measurement.
|
|
|
|
This is the provider-backed, one-turn protocol qualification layer in
|
|
`paperclipai/paperclip-evals/evals/paperclip-runner`. It is intentionally
|
|
separate from both the browser full-stack model E2E and the stress-derived
|
|
workflow schedule in `runner-workflow-evals.md`.
|
|
|
|
The canonical unit of work is one live roster plus one authored case. A full
|
|
campaign selects every enabled lane declared by
|
|
`campaigns/live-direct-full.json` at one immutable `paperclip-evals` commit.
|
|
That includes the complete 35-case provider rosters and the smaller ACPX Codex
|
|
control roster. A disabled roster remains available for an explicit diagnostic
|
|
selection, but is never inferred into a paid `all` run from the files present
|
|
on disk. The native resume reliability gate is not a normal one-turn roster:
|
|
it requires its separately governed external-resource campaign and remains
|
|
opt-in.
|
|
|
|
Managed-provider evidence identifies the immutable deployed provider artifact:
|
|
Claude Managed uses its Agent version, while AgentCore uses its qualification
|
|
revision. Transport API or beta versions remain separate protocol metadata and
|
|
must not replace that runtime identity in a report.
|
|
|
|
## Hosted campaign
|
|
|
|
Use the `Runner Direct Live Protocol Evals` workflow. Dispatch the workflow
|
|
from the default branch and provide:
|
|
|
|
- `target_branch`: the Paperclip branch to build and test;
|
|
- `evals_sha`: an exact 40-character commit from
|
|
`paperclipai/paperclip-evals`;
|
|
- `rosters`: `all` for every enabled lane in the canonical
|
|
`live-direct-full.json` campaign, or a comma-separated diagnostic subset.
|
|
Disabled lanes remain available only through an explicit diagnostic
|
|
selection; `all` never spends against a lane that the eval program has
|
|
marked disabled;
|
|
- `max_infrastructure_retries`: zero through three, applied only when an
|
|
attempt explicitly reports a retryable infrastructure failure.
|
|
|
|
Native suspension failures are non-retryable infrastructure failures. The CLI
|
|
retains only allowlisted close diagnostics: suspension and provider-drain
|
|
booleans, the suspension-command status, the durable Runner lifecycle, and
|
|
whether its identity matches. Missing or conflicting suspension evidence never
|
|
becomes a pass. Preserve the original artifact before correcting a close defect
|
|
and explicitly authorizing a new attempt.
|
|
|
|
Pi cleanup stops an idle provider during close preparation through the exact
|
|
native process owner. Native code rejects active turns or pending callbacks on
|
|
that idle path. It proves release of the original inherited lifetime fence and
|
|
preserves the attested provider identity. The subsequent drain and suspension
|
|
barriers still require their durable receipts. An unconfirmed provider exit
|
|
cannot certify a reusable checkpoint.
|
|
- `grok_authentication`: `api_key` (the compatibility default) or `subscription`.
|
|
Subscription requires an explicitly selected Grok roster and the owner-approved
|
|
`GROK_AUTH_JSON` secret in the protected `runner-e2e-paid` environment. API mode
|
|
uses only `XAI_API_KEY`. A missing selected credential fails; it never changes
|
|
authentication mode or falls back to another credential.
|
|
|
|
For subscription qualification, pass `-f grok_authentication=subscription` when
|
|
dispatching the default-branch workflow. The immutable catalog, retained cell,
|
|
campaign roster, and result record carry `authenticationMode`. The cell reads it
|
|
from the pinned eval program's actual roster summary, and aggregation rejects
|
|
missing or mismatched authentication evidence. Select an eval revision that
|
|
supports Grok subscription admission and records this summary field. Keep API
|
|
and subscription campaigns separate when interpreting results. Remove temporary
|
|
subscription test secrets after the authorized qualification completes.
|
|
|
|
The authorization job resolves the Paperclip branch to a commit and verifies
|
|
the supplied eval commit before any checkout. A short-lived bot token generated
|
|
from `COMMITPERCLIP_KEY` authorizes each checkout of the private eval repository;
|
|
the token is masked and is never forwarded to a provider process. The workflow
|
|
uses the same numeric actor
|
|
allowlist, protected `runner-e2e-paid` environment, RunsOn fleet selector, and
|
|
`RUNNER_E2E_MAX_PARALLEL` ceiling as the full-stack E2E workflow. Two balanced
|
|
GitHub matrices keep each matrix below GitHub's 256-job limit while keeping
|
|
their combined concurrency at or below that shared ceiling. Runner TypeScript,
|
|
the native daemon, provider dependencies, and the attempt viewer are built
|
|
once and reused by every cell. Because the complete suite requires two matrix
|
|
shards, this workflow accepts a shared concurrency ceiling from 2 through 100.
|
|
|
|
The reused provider runtime is created with `pnpm deploy --prod` from the
|
|
frozen workspace lock. That preserves the repository's qualified dependency
|
|
versions and patched ACP server bytes. Do not replace this step with a fresh
|
|
`npm install` of the packed Runner tarball: npm cannot apply the workspace's
|
|
`patchedDependencies`, so the resulting ACPX executables no longer match their
|
|
qualified digests.
|
|
|
|
Candidate ACPX evals require both `--candidate-profile <agent>` and
|
|
`--expected-acpx-profile <JSON>`. The eval program supplies the exact configured
|
|
profile as the JSON argument. Before creating a runtime context or provider
|
|
service, the built CLI compares every profile field, including model, version
|
|
and command digest, with its own resolved profile. Missing, extra or mismatched
|
|
fields fail admission. Older CLIs reject the new flag before execution; there
|
|
is no retry without the check. The daemon's own profile admission and binary
|
|
digest check remain independent gates. Post-run scoring still compares the
|
|
retained profile as evidence, but cannot replace this pre-launch check.
|
|
|
|
The direct eval CLI also materializes a minimal immutable native runtime
|
|
context in each isolated attempt workspace. This keeps the direct layer on the
|
|
same `paperclip.native-execution-input.v3` contract as production, including
|
|
the AgentCore HarnessSkill upload path, without borrowing any browser E2E
|
|
setup.
|
|
|
|
The direct CLI resolves native Codex from the pinned Codex ACP dependency, as
|
|
the browser E2E launcher does; no globally installed `codex` is required.
|
|
Its isolated fixture sessions explicitly use unattended ACPX `approve-all`
|
|
permissions, matching the full-stack ACPX test profiles. OpenCode retains its
|
|
existing semantic-only permission boundary.
|
|
The seeded mock control plane still enforces tool grants, company boundaries,
|
|
and governance checks. These test-only choices do not change production
|
|
permission defaults and are not a qualification of interactive approval UI.
|
|
|
|
AgentCore eval admission waits up to 125 seconds, capped by the configured
|
|
whole-turn timeout. Its network worker already allows 120 seconds for cold
|
|
invocation delivery; the generic 30-second facade wait must not cut that
|
|
delivery short during parallel fleet startup. Other providers retain their
|
|
existing admission timeout.
|
|
|
|
The runtime instructions distinguish the fixture's `finish_task`/`block_task`
|
|
state changes from native `paperclip_finish`/`paperclip_block` run-result
|
|
reporting. This layer has no production server to apply a reported run result
|
|
to a task. Its completion cases still require the actual semantic operation
|
|
and durable mock-state change; reporting success alone does not pass them.
|
|
The current turn request defines the requested work. Shared seed descriptions,
|
|
old eval notes, or past accepted interactions are background state, not a
|
|
replacement objective or proof that a newly requested action is already done.
|
|
Finishing the provider turn does not authorize an unrequested mock task-state
|
|
change or completion comment. These harness instructions keep single-operation
|
|
cases bounded while leaving their operation and state-effect assertions intact.
|
|
For a bounded request, the harness also asks for only the context needed to act.
|
|
A brief progress request does not require an investigation of unrelated history
|
|
or documents. Its grader still requires the actual successful mutation.
|
|
|
|
ACPX accounting uses the qualified server's billable token semantics: Claude
|
|
and Codex already include reasoning in output, and Codex has no cache-write
|
|
billing category. Other missing categories remain unknown. ACPX stores Codex's
|
|
terminal prompt-response usage without streaming it, so the sidecar forwards
|
|
the single newly persisted receipt bound to that exact turn before its terminal
|
|
event. It never substitutes a previous turn's receipt or context occupancy for
|
|
billable usage. These receipt corrections also apply to non-eval ACPX sessions.
|
|
The durable redactor preserves these known numeric token-counter fields;
|
|
string/object values under the same names remain redacted as sensitive data.
|
|
|
|
`all` means the maintained enabled campaign, not every matching file in the
|
|
roster directory. A missing campaign file fails closed. Within an enabled
|
|
lane, a missing remote profile or unavailable provider is retained as an
|
|
infrastructure result; it is not silently omitted. The current ACPX Pi roster
|
|
is declared disabled because its Runner security profile is not qualified, so
|
|
it runs only when selected explicitly for diagnosis. Use a roster subset only
|
|
for diagnosis, not to claim the full maintained campaign is green.
|
|
|
|
A provider turn that reaches a durable failed, interrupted, or otherwise
|
|
non-completed terminal still produces an attempt artifact and is scored as a
|
|
behavior result. It is an infrastructure failure only when the harness cannot
|
|
produce usable evidence, such as an unavailable provider, invalid profile, or
|
|
transport failure. Automatic retries therefore never rerun a measured behavior
|
|
failure merely to improve its score.
|
|
|
|
## Required protected configuration
|
|
|
|
The paid jobs read only the credential selected for each roster:
|
|
|
|
- `OPENAI_API_KEY` for native Codex and ACPX Codex;
|
|
- `ANTHROPIC_API_KEY` for ACPX Claude and Claude Managed;
|
|
- `OPENROUTER_API_KEY` for native OpenCode and ACPX Pi;
|
|
- `XAI_API_KEY` for an explicitly selected ACPX Grok roster;
|
|
- short-lived GitHub OIDC workload identity for AWS AgentCore.
|
|
|
|
Claude Managed also requires the four nonsecret
|
|
`PAPERCLIP_CLAUDE_MANAGED_*` profile variables. AgentCore requires the
|
|
nonsecret `PAPERCLIP_AWS_AGENTCORE_*` profile variables, including
|
|
`PAPERCLIP_AWS_AGENTCORE_EXECUTION_ROLE_ARN` and the immutable
|
|
`PAPERCLIP_AWS_AGENTCORE_QUALIFICATION_REVISION`; the eval fails closed when
|
|
that deployed revision differs from the pinned roster config. The currently
|
|
qualified context-aware harness revision is
|
|
`aws-agentcore-harness-context-v2`. The workflow
|
|
writes the GitHub OIDC token to a mode-`0600` file and never forwards long-lived
|
|
AWS access keys.
|
|
Provision the AgentCore stack with `--github-oidc-provider-arn` so that scoped
|
|
role admits only the `paperclipai/paperclip` repository's protected
|
|
`runner-e2e-paid` environment as its web-identity subject.
|
|
Scheduled runs additionally require `RUNNER_PROTOCOL_EVAL_NIGHTLY_ENABLED=true`
|
|
and the pinned `RUNNER_PROTOCOL_EVALS_SHA` repository variable.
|
|
|
|
## Reports and history
|
|
|
|
Each cell uploads its immutable run directory to an access-controlled Actions
|
|
artifact. The trusted report job merges all expected cells, represents missing
|
|
cell artifacts as infrastructure failures, and invokes the report program from
|
|
the pinned eval commit. The full artifact contains the canonical Evalbook grid,
|
|
read-only Runner issue-thread attempt pages, and raw immutable run records.
|
|
|
|
Public publishing uses a separate projection and a separate trusted OIDC job.
|
|
The projection retains model/config identity, status, usage totals, and check
|
|
outcomes and scrubbed mock conversation, but removes provider session identifiers, semantic-tool
|
|
payloads, state revisions, traces, remote profile identities, and raw failure
|
|
text. The same Evalbook `report` command renders that projection, so the public
|
|
grid, test pages and chat viewer have the standard Evalbook layout. The publisher rejects
|
|
untrusted scripts, remote resources, symlinks, unknown paths, broken links, raw session
|
|
fields, and credential-shaped values.
|
|
|
|
S3 publication is additive:
|
|
|
|
```text
|
|
runner-protocol-evals/
|
|
index.html
|
|
history.json
|
|
latest.json
|
|
latest-green.json
|
|
campaigns/
|
|
gha-<run-id>-<run-attempt>/
|
|
index.html
|
|
latest.html
|
|
inventory.html
|
|
tests/*.html
|
|
attempts/*.html
|
|
campaign.json
|
|
bundle-manifest.json
|
|
```
|
|
|
|
Campaign files use immutable cache headers and a digest manifest. Reusing a
|
|
campaign ID with different bytes fails closed. Only the root history and
|
|
pointer files are mutable, and the publisher never deletes objects. The root
|
|
history retains **all** run records; it no longer drops entries after 200 campaigns.
|
|
|
|
The history index includes:
|
|
|
|
- Pass-rate and cost timelines, grouped by identical cell/model/driver membership
|
|
and eval-suite SHA. Different suites and subsets cannot silently share a baseline.
|
|
- Regression and recovery lists against the previous matching run, linking to the
|
|
affected tests. Infrastructure failures stay distinct from behavior failures.
|
|
- Estimated cost and provider-reported list cost, shown separately, never added.
|
|
New campaigns include all retained attempts (including retries). Backfilled old
|
|
campaigns with only final-cell usage are labeled **historical final attempts only**.
|
|
Missing usage is unknown, not zero; partial totals use `≥` and display coverage.
|
|
- Exact Paperclip and eval-suite commit links (full SHA on hover), the source ref,
|
|
and the GitHub Actions run. These identify the code **evaluated**, not merely
|
|
the commit used to render an old report.
|
|
- A separate report-refresh list, excluded from trend points and model-spend totals.
|
|
|
|
`history.json` stores a versioned, derived `analytics` projection separately from
|
|
immutable campaign records. The publisher backfills missing analytics from each
|
|
original `campaign.json`; a refresh may enrich costs using retained raw attempts
|
|
only when its source metadata and scores still match the original record.
|
|
|
|
The publishing job uses dedicated `RUNNER_PROTOCOL_EVAL_HISTORY_*` variables
|
|
when present and falls back to the existing Runner E2E history role, region,
|
|
bucket, and public base URL. Its default top-level prefix is
|
|
`runner-protocol-evals`, distinct from `runner-e2e`. The AWS role must allow
|
|
additive writes and reads for that prefix.
|
|
|
|
## Local publisher checks
|
|
|
|
These tests make no provider or AWS calls:
|
|
|
|
```sh
|
|
pnpm --filter @paperclipai/paperclip-runner test:runner-protocol-eval-publish
|
|
```
|
|
|
|
To inspect the catalog without executing it, point the command at a local
|
|
evals checkout:
|
|
|
|
```sh
|
|
pnpm --filter @paperclipai/paperclip-runner \
|
|
report:runner-protocol-eval:catalog -- \
|
|
--evals-root /path/to/paperclip-evals \
|
|
--campaign-id gha-1-1 \
|
|
--output /tmp/runner-protocol-eval-catalog.json
|
|
```
|
|
|
|
|
|
For Grok qualification, select `protocol-live-acpx-grok` and its exact eval
|
|
revision. Set `max_parallel: 2` when the API key has a low custom rate limit;
|
|
this admits one case per shard. The override can only lower the configured
|
|
campaign ceiling and cannot change the key's provider limits. Retain any
|
|
rate-limited attempts as failures. The build installs the target's pinned,
|
|
checksum-verified Grok binary before packaging the portable runtime. Targets
|
|
without the Grok package keep their existing build behavior. This protocol
|
|
workflow uses the explicitly selected API key; subscription credentials are
|
|
not delivered by it.
|