mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-23 00:53:38 +02:00
## Thinking Path > - Paperclip is the open source control plane for agent companies. > - People choose a harness when creating an agent. > - The server should resolve that harness to a qualified runner. > - Codex is the first harness in the staged default rollout. > - Saved agents must retain their execution choices. > - New Codex agents therefore use Paperclip Runner on qualified macOS/Linux targets, with an explicit Legacy override. ## Linked Issues or Issue Description Refs #16028, #15555, #15673, #15422, #15631, #15926, #15932, #16149. The runtime/install prerequisite and release repair are merged. This slice owns Codex creation, setup, configuration and preservation. Other harness defaults remain unchanged. It adds no database migration; incoming master migrations, required maps and regression coverage are retained. ## What Changed - Resolve `runner: auto | paperclip | legacy` at the common creation boundary across onboarding, API/CLI, hires, built-ins, plugins and imports. Freeze pending hires and export resolved execution choices. - Preserve existing runners on upgrades, unrelated edits and import updates, including compatible accounts, workspace settings, Codex effort and intentional clears. - Use the underlying harness picker and branding; put the runner override in Advanced. Use the shared dropdown and update production-component stories and creation contracts. - Support qualified Apple Silicon, Intel Mac, Linux x64 and Linux ARM64. Linux requires GNU libc 2.39+. Disabled, external, unsupported and unqualified combinations retain their applicable Legacy execution. - Test the selected runtime/account/model/environment. Ordinary Connect probes eligible immutable managed targets and refreshes scoped discovery. Creation/discovery do not provision. Auth, dependency, incompatible-setting and cleanup failures remain actionable without changing runners. - Keep setup probes read-only, preserve local/SSH isolation and resolve packaged assets before staging credentials. Bound cleanup reads by the remaining absolute deadline; physically close every owned ingress socket before endpoint release. Unconfirmed cleanup retains recovery state. - Preserve validated completed-onboarding callbacks through startup recovery. First file-producing work belongs to the child task and uses the existing dependency/block handoff and task-scoped registration. - Reuse existing E2E fixtures, artifact checks, reporting and controls. Keep Docker/Cargo/native compilation remote. Paperclip tarballs contain no Codex payloads; official optional npm platform dependencies remain. ## Verification Current tested head: `1c03a8815672d82c264a9b08d4ea1984e8fae107`. **Merge-ready: required CI, fresh review, package qualification, Mac core acceptance and Test task/follow-up acceptance pass.** The existing attachment and native-continuity oracles independently verify both Test downloads, run attribution and unchanged native/provider/workspace identities. The maintainer authorized a code-owner-review exception for this PR only. The first Test setup failure and normal Board completion-review friction are retained below. Actual post-merge packages and private Cloud distribution remain separate qualification gates. - [Current CI](https://github.com/paperclipai/paperclip/actions/runs/38564241625): all 48 ordinary jobs and required verify/E2E pass. Attempt 1 retained six simultaneous host-shutdown cancellations. One failed-only retry passes those six lanes and two aggregates, preserving 40 successes. Actual integration checkout `53104c1` combines this head with master `c80`; it is not relabeled as the branch tree. Fresh exact-head Greptile 5/5, 30 resolved threads, no actionable findings. - [Exact-source package qualification](https://github.com/paperclipai/paperclip/actions/runs/38565287239): nine applicable jobs pass, nine conditional jobs skip. Four remote native producers; Linux x64 clean install; Intel Mac, Apple Silicon and Linux ARM64 native startup/physical cleanup controls. All 18 tarballs/four daemon source/hash/manifest bindings and 343 migrations through 0344 verify. No Codex payload is packed. These hosted tarballs are not a published npm canary. - Normal Apple Silicon installation and credential-free native startup/cleanup pass using the packaged daemon, with no source build or provider turn. Fresh installed DB initialization passes. Upgrade 651a→1c03 preserves all three complete execution configs, accounts, ten recorded run profiles, paused budgets, active incidents, cost summaries and two historical unpriced events. Historical recovery state is retained. - Cleanup regressions: four delayed-read baseline failures become 15 passing deadline/authority controls. No-acknowledgement and prior-error socket ownership regressions become 12 passing controls. Direct runtime/server types, maps: 35 areas / 176 IDs, diff checks and independent reviews pass. Permission/auth/reconnect policy and the 10-second setup budget remain intact. - Existing source coverage includes creation/selection/imports, pending approvals, recovery, account/lifecycle handling, mounted forms, dropdowns and E2E support. Full typechecks/tests/build/token and applicable Storybook checks pass in the recorded current CI; no duplicate suite or weakened grader. - Literal 9546 live Mac proof: ordinary Auto Codex onboarding, useful document, real completed-child callback/reply, seven successful native runs, manual follow-up and independently downloaded1,101-byte child file. Existing Legacy title edit/reload preserves execution; two real Legacy runs produce independently checked15/34-byte files. These remain historical source records. - Current literal 1c03 Mac core acceptance passes independent checks: ordinary Auto native Codex onboarding without runner override; only timeout 180 seconds/concurrency 1 saved; six successful native runs and six serialized turns (maximum overlap 1); both same-task continuity checks and five mechanical callback checks; actual rendered parent reply and exact child downloads. The useful handoff advances from revision 1 to 2. Both files are 48 bytes, SHA-256 `8b742bd4e8123a7c078f0a8d9f3449fbfa8a320d7d90be641a2818db3c53d92c` and `f42db9774fa06e804ab7d596fc8b922a2b638921c418b87d0111151d290a6afe`; exactly one byte changes and old history remains. The agent is paused with zero active runs/errors. Both artifact work products have `isPrimary=false`, and descriptive titles fail a stricter title-helper assumption; these retained results are scoped editorial follow-up, not new merge gates. Six source-bound screenshots are uploaded and verified in the private primary QA report. - [Literal 9546 managed proof](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-38485488621-1/index.html): original 19 assertions and completed judge pass, four native turns, child-bound240-byte file and session/workspace continuity. Checkout reports a verified generated target-lock mutation; full final porcelain was not retained. Signed execution-image identity remains separate from Core source. - Actual 651a Test deployment succeeds on one owned/pinned target. One ordinary Auto API-key Connect then fails native cleanup before hire. Controller turn/drain/suspend completion and service-recorded environment cleanup are observed; they do not certify physical deletion or native authority retirement. Failure/recovery/unknown holds are retained. No Legacy switch or unchanged paid retry. The two source repairs above require actual treatment. - [Current immutable Core preview](https://github.com/paperclipai/paperclip/actions/runs/38570365725) and matching DB/shared artifacts pass. One owned, pinned Test target serves exact `1c03`; identical migration history correctly skips the migrator. Ordinary Auto Codex Connect succeeds and hires native; saved native selection and QA bounds survive reload. The initial child preparation attempt fails before provider work, with actual stdout identifying `renewal_deadline`; its trigger remains unknown and the failure is retained. Normal Board **Try again** and **Resume** recover the child to Done, producing a browser-verified 44-byte file, SHA-256 `0a8458b1efcc2d7a0d815689458c4caab039a46c7c7a3e5805de6bc8b1a96ecc`. The actual parent callback reports the completed child document/file. The existing validator requires a parent-owned attachment, so recovery enters normal Review; after byte checking, normal **Approve completion** reaches parent Done. No forced status or duplicate parent file is used. The validator is unchanged from integrated and current master. Autonomous initial callback-to-Done is not proven. The same-child follow-up completes document revision 2 and publishes a second independently downloaded 44-byte file, SHA-256 `22022257300fae762784632d08d3bbe0bab61e2ce81f91864a14dcd7aa464591`; only the revision digit changes. The unchanged existing native-continuity and attachment oracles pass. All ten recorded runs are terminal: nine native successes and the retained pre-provider setup failure. The QA agent is paused with zero active runs. The pre-existing parent evidence scope mismatch is a separate follow-up, with ordinary completion review exercised rather than a forced status or relaxed validation. This unsigned Core preview remains distinct from post-merge private Cloud composition. ## Risks - Saved agents are not migrated. Explicit runner changes use normal configuration/session rules; historical runs retain their recorded execution. - Native readiness depends on verified assets and server-owned target qualification. A Legacy probe, HTTP200 or successful account save cannot prove native readiness. - Recovery exceptions remain restricted to validated completed-onboarding reports; process-loss, ownership and terminal-state safeguards remain active. Unexecuted live journeys stay open. - Linux ARM paid tasks, Windows, Alpine and 32-bit ARM remain deferred. Cold Cargo cache misses are recorded; no warm-cache speedup is claimed. - Historical invoices/physical cleanup remain unconfirmed and held. After merge, exact published npm canary, signed standard image/migrator, private composition and serving/live acceptance still require qualification. Production deployment/default promotion is not authorized. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, tools, code execution and parallel agents. Exact serving snapshot and context-window size are not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used with available 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 linked public issues or PRs above - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal ticket id - [x] I have run the stated focused tests locally and they pass - [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 on the current candidate - [x] Greptile is 5/5 with no open findings on the current candidate - [x] I will address all reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
366 lines
21 KiB
Markdown
366 lines
21 KiB
Markdown
# Runner E2E security for a public repository
|
|
|
|
## Attended connection authentication
|
|
|
|
See [PROVIDER-CONNECTIONS.md](PROVIDER-CONNECTIONS.md) for the explicit-only
|
|
`provider-connections` suite, local/staging target ownership, dedicated browser
|
|
profiles, credential handoffs, private evidence, and cleanup contract.
|
|
|
|
Provider-connection results may retain closed diagnostic codes and terminal run
|
|
status before managed-instance teardown. Only error records and failed tool
|
|
receipts are inspected; raw error messages, child stderr, model output and
|
|
reasoning are not retained. Unknown causes and unavailable logs stay explicit.
|
|
The optional installed-Gemini filesystem smoke uses synthetic credentials and
|
|
loopback model responses, makes no real provider calls, and removes its
|
|
disposable home/workspace.
|
|
|
|
The explicit [public MCP suite](PUBLIC-MCP.md) also creates a disposable browser
|
|
account and OAuth grant. Signup and token exchange use Node fetch, credentials
|
|
stay outside model context, and dynamic cookie/code/token values join the
|
|
attempt's redaction set. Tracing, video and automatic screenshots are disabled
|
|
for that suite; only reviewed fixture task routes may produce public screenshots.
|
|
External API evidence retains visible answers and tool outcomes, never raw model
|
|
reasoning. Empty provider configuration directories prevent operator plugins and
|
|
MCP credentials from being inherited. All grants are revoked during cleanup and
|
|
the launcher removes the isolated database and provider homes.
|
|
|
|
This suite can spend provider money, expose selected local and workflow API credentials to isolated
|
|
test processes, publish a container, retain private visual evidence, and write
|
|
public structured evidence. Treat changes to the workflow, harness, fixture
|
|
prompts, evidence packager, and publisher as security-sensitive production
|
|
changes.
|
|
|
|
## GitHub authorization
|
|
|
|
Set `RUNNER_E2E_ALLOWED_ACTOR_IDS` to a non-empty JSON array of numeric GitHub
|
|
user IDs. Keep the list equal to the owners of `.github/**` in
|
|
`.github/CODEOWNERS`. For example, use `[123456,789012]`. Resolve each ID from
|
|
the authenticated CLI and verify the login before adding it:
|
|
|
|
```bash
|
|
gh api users/LOGIN --jq '{login,id}'
|
|
```
|
|
|
|
The paid workflows reject manual dispatches when the workflow definition does
|
|
not come from the default branch. A trusted dispatcher may name any branch in
|
|
`paperclipai/paperclip` as the code under test. The authorization job resolves
|
|
that branch through the GitHub API and passes only its immutable commit SHA to a
|
|
credential-free target-lock job. That job checks out the commit, regenerates
|
|
`pnpm-lock.yaml` once with lifecycle scripts disabled and lockfile-only mode,
|
|
then uploads the file under a run-attempt-scoped artifact ID. Catalog, image,
|
|
shared-build, provider-pack, and paid test jobs download that exact artifact by
|
|
ID, verify its recorded SHA-256, and restore it before setup or a frozen
|
|
dependency install. The lock resolver receives no provider credentials and
|
|
must never run repository lifecycle scripts. The shared-build and provider-pack
|
|
jobs also receive no provider credentials and disable dependency lifecycle
|
|
scripts; they package outputs with SHA-256 sidecars that consumers verify
|
|
before extraction. The paid test job installs with lifecycle scripts disabled,
|
|
and materializes the exact pinned OpenCode executable from its lockfile-verified
|
|
optional package without invoking package lifecycle code. Provider secrets are
|
|
scoped only to the final test step rather than dependency setup. Report sanitization and AWS
|
|
history publication explicitly use the trusted workflow commit and do not
|
|
consume the target lockfile. Never run the workflow definition from the target
|
|
branch.
|
|
|
|
The workflows verify both the original actor and triggering actor for every
|
|
scheduled or manual attempt, including human reruns. Every
|
|
secret-bearing job repeats this check as its first step so GitHub's partial-job
|
|
rerun feature cannot bypass a successful predecessor authorization job. The
|
|
legacy manually dispatched E2E workflow uses the same gate. Numeric IDs are
|
|
stable across username changes and prevent lookalike-name authorization.
|
|
|
|
The full-stack and live campaigns have one Sunday UTC schedule each and also
|
|
support explicit manual dispatch. Their legacy-named nightly repository
|
|
variables remain independent kill switches. Neither paid workflow accepts
|
|
pull-request, push, workflow-run, or reusable-workflow triggers.
|
|
|
|
Protect the default branch, require review for workflow/harness paths, restrict
|
|
workflow dispatch permission, and restrict repository variable/environment
|
|
administration to the same trusted maintainers. Configure the organization to
|
|
allow only approved GitHub Actions. A malicious change merged into the default
|
|
branch executes with the same authority as the suite.
|
|
|
|
Every external action in the paid workflow is pinned to a full commit SHA. Keep
|
|
the adjacent major-version comment for update tooling, and resolve and review a
|
|
new immutable SHA before upgrading an action. The credential-free security test
|
|
rejects mutable tag or branch references.
|
|
|
|
## Secrets and protected environments
|
|
|
|
Explicit Grok subscription campaigns may select `GROK_AUTH_JSON` from the same
|
|
protected paid environment. Deliver it only to that subscription profile's paid
|
|
test step. Prefer a dedicated test-account login and refresh it before a campaign.
|
|
The fixture stores only the selected login in its disposable company home, rejects
|
|
ambient/redirected homes, and removes the login during teardown. Token fragments
|
|
and account identifiers inside its JSON join the evidence redaction set. The
|
|
subscription suite remains manual-only and never falls back to `XAI_API_KEY`.
|
|
|
|
Create `runner-e2e-paid`, restrict deployments to the default branch, and put
|
|
only `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `OPENROUTER_API_KEY`, `XAI_API_KEY`, and
|
|
`DAYTONA_API_KEY` in it. `KIMI_MODEL_API_KEY` remains a local-only catalog name
|
|
for pending explicit profiles and is intentionally absent from the workflow
|
|
environment. Product E2E pending-profile admission remains gated separately.
|
|
Do not duplicate these credentials as repository- or
|
|
organization-level Actions secrets: environment scoping is the boundary that
|
|
prevents branch or pull-request jobs from requesting them. Require approval
|
|
from an account in `RUNNER_E2E_ALLOWED_ACTOR_IDS` for this environment and
|
|
disable administrator bypass. The authorize, target-lock, catalog, image,
|
|
report, history, and Pages jobs receive none of these secrets.
|
|
Each full-stack matrix cell receives only its selected profile credential, plus
|
|
Daytona only for Daytona cells. Secret-bearing and OIDC jobs use frozen installs
|
|
without a shared dependency cache.
|
|
On disposable GitHub Linux runners with Ubuntu's unprivileged-user-namespace
|
|
restriction, the authorized default-branch workflow provisions an AppArmor profile before provider credentials are exposed. The profile is attached to the exact
|
|
lockfile-pinned Codex executable. It grants `userns` so Codex can construct its
|
|
filesystem sandbox; it does not disable the kernel restriction or Codex's
|
|
workspace policy. Setup fails before invoking a model if the noninteractive
|
|
profile load fails. Target-controlled tests only probe the existing sandbox and never invoke sudo or load host policy. This host-only profile disappears with the ephemeral runner.
|
|
See [Ubuntu's namespace restriction documentation](https://documentation.ubuntu.com/security/security-features/privilege-restriction/apparmor/).
|
|
Local developer machines are never modified by this setup. Legacy Codex fixtures
|
|
disable optional shell-environment snapshots to avoid persisting credentials;
|
|
other suites retain the persisted-state scanner. The `first-task` suite omits
|
|
private home/workspace credential-persistence scanning so its evaluation focuses
|
|
on onboarding behavior. Artifact redaction and publication scanning remain in
|
|
force for every suite.
|
|
The Paperclip server process also receives none; the browser posts each value
|
|
once to the encrypted company secret API and agents/environments retain only
|
|
secret references.
|
|
|
|
The explicit managed first-task cell observes the wizard's two owned setup
|
|
responses only to correlate their exact lease IDs with same-company environment
|
|
records. Raw probe/setup responses, account references, opaque provider lease
|
|
identities and setup screenshots remain private. Public first-task evidence
|
|
continues through the existing projection. Missing or foreign lease identities
|
|
cannot acquire attribution or a zero-cost estimate; incomplete setup coverage
|
|
stays unavailable even if later task-run billing succeeds. Platform qualification
|
|
uses the existing permission-gated environment probe, without granting new
|
|
permissions or accepting fixture-authored qualification metadata.
|
|
|
|
The context-integrity catalog lists six pending Kimi/Grok cells for discovery:
|
|
two cases each across `legacy-kimi-cli`, `legacy-kimi-acp`, and `legacy-grok`.
|
|
The launcher and direct Playwright runner reject these profiles before loading
|
|
credentials. Pi has no qualified model source and is not cataloged. Admission
|
|
remains blocked until identity, authentication, skills, session, and billing
|
|
evidence is qualified together.
|
|
|
|
Create `runner-e2e-history`, also default-branch-only, for the OIDC publishing
|
|
job. It contains no long-lived AWS key. Required reviewers may be added when a
|
|
human approval on every nightly publication is acceptable; otherwise rely on
|
|
the actor gate, environment branch restriction, and protected default branch.
|
|
|
|
## Runner fleet isolation
|
|
|
|
When `RUNNER_E2E_AWS_ENABLED=true`, paid matrix cells, reusable runner builds,
|
|
and Daytona image builds use the exact RunsOn fleet
|
|
selector `runs-on/fleet=paperclip-public-pr-x64/env=public-ci`, matching the AWS
|
|
fleet selected by `pr-trusted.yml` only after its stable numeric-ID trust gate.
|
|
Any other or missing toggle value falls back to the GitHub-hosted
|
|
`ubuntu-latest` runner and its lower concurrency ceiling. The workflow chooses
|
|
between those two reviewed literal labels; it never evaluates a configured
|
|
runner label.
|
|
|
|
Daytona image builds depend on successful campaign authorization and keep the
|
|
existing GHCR publication and signing permissions. They receive no provider
|
|
credentials and do not enter the `runner-e2e-paid` environment.
|
|
|
|
Keep both runner targets restricted to `paperclipai/paperclip` and workflows
|
|
that independently authorize trusted source revisions. Never let a fork or
|
|
untrusted pull-request workflow target them. The RunsOn fleet must launch a
|
|
fresh ephemeral instance for every job, prohibit persistent runner reuse, and
|
|
disable interactive SSH/debug access unless a separate incident procedure
|
|
explicitly authorizes it.
|
|
|
|
Changing the runner does not widen who can authorize secret access. The paid
|
|
workflow still has only schedule and manual triggers, requires its trusted
|
|
definition to come from the protected default branch, requires allowlisted
|
|
stable actor IDs before checkout, and repeats that authorization as the first
|
|
matrix step. Provider credentials come only from the protected
|
|
`runner-e2e-paid` environment. The fleet selector is an exact workflow literal;
|
|
the only repository-controlled routing input is its boolean rollout switch, so
|
|
configuration cannot redirect a secret-bearing job to an arbitrary runner.
|
|
|
|
The optional target branch is code, not workflow authority. A CODEOWNER who
|
|
dispatches a target branch explicitly authorizes that branch's selected test
|
|
process to receive the cell's scoped provider credential. The workflow resolves
|
|
the target only inside the same repository, pins one SHA for the campaign, and
|
|
checks it out only after authorization. Target-controlled code cannot replace
|
|
the report sanitizer or the AWS history publisher. Fork refs and
|
|
target-controlled workflow definitions do not enter this path.
|
|
|
|
## AWS OIDC and S3
|
|
|
|
The AWS role trust policy should accept only GitHub's OIDC audience and the
|
|
publishing environment subject:
|
|
|
|
```json
|
|
{
|
|
"Version": "2012-10-17",
|
|
"Statement": [
|
|
{
|
|
"Effect": "Allow",
|
|
"Principal": {
|
|
"Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
|
|
},
|
|
"Action": "sts:AssumeRoleWithWebIdentity",
|
|
"Condition": {
|
|
"StringEquals": {
|
|
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
|
|
"token.actions.githubusercontent.com:sub": "repo:paperclipai/paperclip:environment:runner-e2e-history"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Grant only List on the bucket prefix and Get/Put on its objects. Do not grant
|
|
Delete, ACL, bucket-policy, or wildcard-resource permissions:
|
|
|
|
```json
|
|
{
|
|
"Version": "2012-10-17",
|
|
"Statement": [
|
|
{
|
|
"Effect": "Allow",
|
|
"Action": "s3:ListBucket",
|
|
"Resource": "arn:aws:s3:::BUCKET",
|
|
"Condition": {
|
|
"StringLike": { "s3:prefix": ["runner-e2e", "runner-e2e/*"] }
|
|
}
|
|
},
|
|
{
|
|
"Effect": "Allow",
|
|
"Action": ["s3:GetObject", "s3:PutObject"],
|
|
"Resource": "arn:aws:s3:::BUCKET/runner-e2e/*"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Enable S3 versioning, default encryption, and Block Public Access. Disable
|
|
object ACLs. CloudFront receives read-only access through Origin Access Control;
|
|
the bucket itself stays private. Log S3 data writes and alert on attempts to
|
|
write outside the prefix or assume the role with a different subject.
|
|
|
|
Campaign prefixes are content-digested and immutable. The publisher refuses a
|
|
different digest at an existing campaign key. Only the compact history and
|
|
latest pointers are mutable, and S3 versioning makes those updates recoverable.
|
|
|
|
## Public evidence boundary
|
|
|
|
CloudFront and GitHub Pages are public. Fixture identifiers, timing, token
|
|
usage, costs, normalized results, and trusted runner PNG screenshots are
|
|
expected public data. Each
|
|
public screenshot must carry the explicit `public-runner-fixture` marker in
|
|
the normalized result. This includes a `failure.png` capture. Screenshot paths
|
|
must be safe PNG basenames and must be tied to the exact normalized execution
|
|
ID and attempt. The runner capture helper accepts only the exact issue route
|
|
for the live fixture that the harness created. Other issue routes, credential
|
|
pages, setup pages, and administration pages fail closed. The
|
|
CloudFront-backed S3 history also publishes one
|
|
synthetic campaign-summary PNG generated by trusted publisher code solely from
|
|
fixed catalog labels and sanitized numeric/status fields. Video, archives,
|
|
generated Playwright/blob/HTML report trees, SVG or other active content,
|
|
credentials, Paperclip homes, databases, workspaces, master keys,
|
|
raw/unredacted logs, unmarked images, and unallowlisted files are not public.
|
|
Per-attempt JSON snapshots, result copies, logs, Markdown, and text files stay
|
|
in the retained Actions artifact. Credential redaction does not remove hidden
|
|
reasoning or provider session identities, so a text extension never admits a
|
|
file to the public bundle. Graded results remain in `normalized-results.json`.
|
|
|
|
The packaged evidence uploaded as a 30-day GitHub Actions artifact has a
|
|
different, broader boundary. Text is exact-value and key-shape scanned and
|
|
redacted. PNG and WebM are raw-byte scanned; SVG is rejected during packaging
|
|
because it is active content. Raster pixels cannot be exhaustively
|
|
secret-scanned by bytes, so fixture authors must treat every marked capture as
|
|
public and must never extend the allowed task route to credentials, secrets,
|
|
private user data, or other non-public content. Adding or changing a marked
|
|
capture requires review of the visible page state. Videos remain
|
|
access-controlled.
|
|
|
|
Before permanent publication, the campaign publisher creates a separate S3
|
|
stage and retains only result PNGs with the explicit `public-runner-fixture`
|
|
marker under `evidence/`. This applies even to malformed JSON and renamed
|
|
process logs. Original packaged evidence and grades remain unchanged.
|
|
It then launches publisher-only Chromium with networking blocked to render one
|
|
`public-images/campaign-summary.png`. That fixed-path PNG is capped at 12 MiB
|
|
and its signature is validated. Per-attempt XML is excluded because browsers
|
|
can process XML/XSLT;
|
|
the only public XML is the root `junit.xml`, which the report aggregator
|
|
constructs from fixed markup and XML-escaped fields. Videos, archives,
|
|
raw/unallowlisted logs, SVG, undeclared images, generated reports, and symlinks
|
|
fail closed or are removed before the immutable manifest is calculated.
|
|
|
|
GitHub Pages is built from a second stage without the synthetic summary PNG but
|
|
with the same trusted-fixture screenshot allowlist. A leak detected by the
|
|
existing packager scan fails the cell and withholds the unsafe file.
|
|
|
|
Rotate the affected credential immediately if a secret-scanning failure or
|
|
unexpected public object is observed. Preserve the access-controlled Actions
|
|
artifact and S3 object versions for incident analysis; do not weaken scanning
|
|
to make a campaign publish.
|
|
|
|
`agent-chat-qualification.worker-crash-retry` is local-only and explicit-only.
|
|
Linux with Python pidfd support is required; unsupported hosts fail before signalling.
|
|
The fault target comes from the public run detail, must be native and running,
|
|
and must have an exact `--run-id` command argument. PID 1, the harness PID,
|
|
noninteger PIDs, remote profiles, and mismatched identities are refused. The
|
|
fixture workspace must be within the disposable instance root. The helper pins an owned pidfd, verifies the exact run argument and recorded
|
|
process start ticks again after evidence capture, and signals through that handle.
|
|
PID reuse cannot redirect the signal. This is one
|
|
specific process signal, never a name-based or machine-wide process kill.
|
|
The bounded fixture command is released even on failure; normal instance cleanup
|
|
still owns all disposable processes and files. No credentials enter the prompt,
|
|
fault metadata, or structured grading fixtures.
|
|
|
|
### Candidate ACP qualification
|
|
|
|
The explicit-only `extended-harnesses` launcher removes ambient candidate
|
|
admission, then authorizes only selected candidate/model pairs in its isolated
|
|
server process. The server never reads admission from agent configuration,
|
|
resolved credential bindings, or provider environment. Invalid, duplicate and
|
|
mismatched authorization fails closed. Verified packaging and normal company
|
|
and tool governance still apply. `CURSOR_AUTH_TOKEN` and
|
|
`COPILOT_GITHUB_TOKEN` enter via encrypted company secret references, and all
|
|
Cursor, Copilot, GitHub and GH environment variables are stripped from the
|
|
server environment. GitHub PAT shapes are included in retained-evidence scans.
|
|
Candidates have no automatic infrastructure retries; spending must be reconciled
|
|
before a deliberate repeat.
|
|
|
|
Copilot protection fixtures use production browser/public API permission and
|
|
cancellation paths. Their local one-shot socket accepts a nonce/PID only and owns
|
|
one fixed bounded child; it cannot select commands, arguments, or paths. The exact
|
|
native client command is supplied by the fixture, while production notices retain
|
|
only its SHA-256. The fixture keeps private process identities local, closes its
|
|
owned socket/child in cleanup, and never signals API-reported PIDs. Directory
|
|
watch loss makes the denial oracle incomplete; it must not become a no-effect pass.
|
|
|
|
Pi Daytona controls bind process identity to the independent Linux observer's
|
|
PID, start ticks and boot ID within the exact admitted run/lease/sandbox. The
|
|
controller's `processStartedAt` annotations may change as launch metadata settles
|
|
and do not identify a remote process birth. Every remote snapshot and retirement
|
|
seal must retain the original birth identity and complete no-effect journal.
|
|
Local controls retain their separate public process-authority comparison.
|
|
|
|
Pi provider-death admission accepts the native bootstrap's `/proc/self/fd/3`
|
|
or `/proc/self/fd/7` wrapper launch only after binding that held descriptor and
|
|
the wrapper executable to the sealed snapshot Node inode. Exact guard and
|
|
entrypoint paths, closure hashes, Pi title, run/lease ancestry and fresh process
|
|
birth checks remain required. Other descriptor aliases, missing descriptors and
|
|
foreign inodes fail before any signal. Native Linux calibration exercises both
|
|
descriptor launches with synthetic owned processes and no provider credentials;
|
|
it does not qualify paid Pi behavior or change previous failed grades.
|
|
|
|
The private resource-admission marker and raw cleanup results control recovery-state retention independently of evidence packaging. A worker crash after admission keeps the owner-only recovery database; a confirmed pre-allocation bootstrap failure does not. Neither the marker nor the database enters published evidence.
|
|
|
|
## Task workspace fixture source
|
|
|
|
The explicit task-workspaces cells fetch the existing public octocat/Hello-World
|
|
repository through normal anonymous repository preparation. They do not clone the
|
|
Paperclip checkout, copy its Git credentials, create remote repositories or push.
|
|
The agent's synthetic commit remains in the disposable task workspace. Independent
|
|
Git reads validate that workspace's canonical path is inside the isolated instance
|
|
before examining history. The existing credential redactor, private evidence
|
|
packager and task-only screenshot allowlist remain authoritative. Each cell has a
|
|
single attempt, three requested turns and company/agent budget hard stops.
|