Commit Graph
2 Commits
Author SHA1 Message Date
DottaandPaperclip c99bcd89fe fix: preserve Product TestOps evidence and CI readiness (#19000)
## Thinking Path

> - Paperclip manages agent work through governed product workflows.
> - Product E2E tests check those workflows through the app and Runner.
> - A trusted reporter sends retained results to TestOps.
> - Free-form metadata and a short upload observer can lose safe, valid
evidence.
> - UUID navigation can also discard task metadata before the canonical
query returns.
> - Hermetic CI files start child processes that need CPU capacity
within their readiness limits.
> - This change closes the reporting contract, retains authenticated
core aliases, and reserves CI CPU capacity.
> - Original case identities, conditions, assertions, verdicts and
deadlines remain intact.

## Linked Issues or Issue Description

Refs #18983. This addresses its late [metadata disclosure
finding](https://github.com/paperclipai/paperclip/pull/18983#discussion_r4470789114)
and [upload readiness
finding](https://github.com/paperclipai/paperclip/pull/18983#discussion_r4470790366).

**What happened?**

The reporter accepted model IDs and matcher names through syntax
filters. A secret-shaped string could pass those filters. First-task
results also use their top-level model field for an observed alias.
Treating it as configured metadata can reject valid retained evidence.
The upload observer stopped after 22 seconds of waits.

[Required CI on the earlier
head](https://github.com/paperclipai/paperclip/actions/runs/41886885193)
also found two real browser title failures and five native package
readiness failures. A deterministic control reproduced metadata loss
during UUID-to-identifier navigation. A separate fixed-resource control
reproduced startup deadline failures with four concurrent hermetic
fixtures, while one and two fixtures passed.

**Expected behavior**

Reject unknown transmitted metadata before creating upload files.
Preserve every original matcher verdict and attempt receipt. Observe
server processing without rerunning the product. Keep authenticated task
metadata visible through canonical navigation. Reserve capacity for
hermetic child processes without changing the original readiness
deadlines.

**Steps to reproduce**

Use a secret-shaped model ID or cleanup state in retained evidence,
return an observed first-task model alias, or let upload processing
settle after 40 seconds of virtual time. Hold the canonical core query
pending after an authenticated UUID read. For the CPU control, run the
same providerless startup/recovery fixture alone, four times
concurrently, and twice concurrently under a fixed 4-vCPU quota and its
original 8-second readiness limit.

## What Changed

- Bind configured model receipts to each exact declared case model. Four
first-task cases use captured agent configuration; their observed
aliases and fallback text remain digest-only. A missing capture stays
null / Not recorded. The other 16 cells use their configured profile
model. Reject wrong or unknown configuration before any upload file
exists.
- Keep the existing model distribution: 18 Codex cells on `gpt-5.6-sol`,
configured-repository case 9 on its existing `gpt-6.1-sol` override, and
task-workspaces case 54 on `openrouter/deepseek/deepseek-v4-flash-0731`.
The repository override exists at the [original canary
source](https://github.com/paperclipai/paperclip/blob/86814c6550f52e99ede150a883bdc773cbb540e3/tests/runner-e2e/catalog.ts#L1148).
No model configuration changes.
- Allow only existing Matcher kinds, closed failure classes, and cleanup
states `passed`, `failed`, or `not_started`. Publish each matcher's
kind, ordinal, original boolean verdict and SHA256 path receipt. Full
conditions remain in the linked original workflow artifact; raw dynamic
path bytes do not enter TestOps.
- Observe the same upload for at most 55 seconds of poll waits. Product
scenarios, provider retries and scenario deadlines do not change.
- Retain task core data under only the authenticated response's own UUID
and identifier core keys. Preserve existing canonical data. Keep
arbitrary references and full-detail keys empty until their own reads.
- Retain a first-failure trace for the existing Cloud recovery test.
Keep its assertions, timeout, retries, mock data and artifact policy
unchanged. This adds diagnosis evidence; it does not claim to fix that
separate Cloud title timeout.
- Reserve half the available CPUs for Runner package CI workers, with
the existing upper cap of four. A 4-vCPU host uses two workers; an
8-vCPU host still uses four. Local defaults and test selection do not
change.

## Verification

- Reporting controls first reproduced the two original gaps. All 14 Node
contract tests now pass. Unknown configuration creates neither a result
directory nor an export summary. A model valid for a different selected
case is also rejected. Original functional failures and earlier
accounting receipts survive.
- The catalog compatibility test passes for all 20 selected cells, exact
model tuples, real pure grader outputs and actual
`projectFirstTaskResult` shapes. It covers observed aliases, fallback
text, absent evidence and wrong or secret-shaped configured metadata.
These are contract controls, not live journey passes.
- Virtual-clock controls accept a correct result that settles at 40
seconds and reject a persistently wrong verdict after 55 seconds. They
make no product or provider calls.
- Two new core-cache controls failed before repair. The query/cache
suites now pass all 8 tests. They hold canonical refresh pending and
verify title/company retention, newer canonical data, full-detail
enrichment and unrelated keys. UI typecheck and token gates pass.
- The unchanged exact UUID cross-company link/upload browser test passed
once after repair: 5.8-second scenario, 32.0-second complete command.
The unchanged exact Cloud task-entry diagnostic passed once: 5.4-second
scenario, 23.3-second complete command. Its original canonical-only
timeout remains unexplained. All five Cloud tests still collect after
the trace setting.
- The providerless Linux control used the retained Runner and compiled
controller from source `3a2249dd`, with a fixed 4-vCPU quota and
original 8-second readiness limit. Solo passed 1/1; four concurrent
fixtures failed 4/4; two concurrent fixtures passed 2/2. At each
failure, Rust had accepted command 2 but startup was still pending;
checkpoint and published status agreed, one connection was
authenticated, no replay backlog existed, and the sidecar had not
launched. Passing controls preserved the expected startup failure
through controller replacement. No network or credentials were
available.
- That control uses Linux amd64 emulation and Node 24.21; hosted CI used
Node 24.22.1. It supports the worker-cap change, but does not prove that
the original `m5n.xlarge` host caused every CI failure. The original red
attempts remain recorded.
- Actual config-load controls verify 1 CPU → 1 worker, 2 → 1, 4 → 2, 8 →
4 and 16 → 4, with no local, timeout or retry override. The isolated
policy change preserves the same 297 test-file inventory; integration of
current master `89703c3ff7` retains all 298 current native package
files. The original PR package/native command plans remain unchanged.
- Final head `877e28da32f2d2f0d12906c89aff085e2c6ea943` passes both
required checks, `ci / verify` and `ci / e2e`, in [CI run 41897677652,
attempt
2](https://github.com/paperclipai/paperclip/actions/runs/41897677652/attempts/2).
The native package passes 4,950 tests with 10 existing skips. All eight
browser shards pass; the Cloud shard passes all 41 tests, including all
four unchanged recovery cases.
- Attempt 1 preserved 46 successful jobs but its one-file heartbeat
recovery shard hit the original 20-minute job limit without a named
assertion or completion verdict. Its cause remains unidentified. One
explicitly bounded debug replay retained those 46 successes and ran only
that leaf and its dependent rollup. The unchanged file passed all 412
tests (346.91-second file, 371.34-second Vitest command, 7m11s job).
Source, cases and deadlines did not change. This establishes
intermittency, not a causal repair. The original timeout and debug pass
both remain recorded.
- Fresh [Greptile
5/5](https://github.com/paperclipai/paperclip/pull/19000#issuecomment-6637604918)
and [Ponytail
5/5](https://github.com/paperclipai/paperclip/pull/19000#issuecomment-6637489454)
reviews name exact head `877e28`. The single review thread is resolved.
Live TestOps bootstrap and complete 20-case acceptance remain held until
reviewed delivery. CI and focused controls do not count as product plan
passes.

## Risks

- Future model or Matcher kind changes require a reviewed
reporting-contract update.
- TestOps shows a closed Matcher kind and ordinal. The path digest binds
the original condition in retained evidence.
- Core alias data retains the existing authenticated query-client and
server company boundaries. It never becomes full-detail evidence.
- Fewer CI workers can increase one job's duration. The full suite must
verify the final policy. The paid evaluation matrix and its parallelism
do not change.
- The original Cloud title timeout and the first-attempt heartbeat CI
hang do not have proven causes. Current unchanged assertions pass, but
this does not establish repeatability. The Cloud test now retains its
first-failure trace. A successful upload or focused control alone cannot
establish a complete product pass.

## Model Used

OpenAI Codex with reasoning, tool use and code execution. The host does
not expose the exact model ID or context window to this session.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-11-04 14:41:28 -06:00
DottaandPaperclip b99dd57c82 test(evals): run Product regression from TestOps (#18983)
## Thinking Path

> - Paperclip manages agent work through governed product workflows.
> - Product E2E tests check those workflows through the real app and
runner.
> - The saved Product regression plan has 20 imported case identities.
> - The plan has no live executor, so historical baseline rows do not
qualify its current behavior.
> - The existing paid full-stack workflow already owns all 20 required
journeys.
> - This change binds TestOps selection and reporting to that workflow
without changing the product oracle or paid admission.
> - Maintainers can run the plan and inspect current case verdicts and
retained evidence.

## Linked Issues or Issue Description

**What happened?**

The standing Product regression plan has no executor. Its dashboard
points at a historical 355-result snapshot across several suites and
revisions.

**Expected behavior**

A TestOps plan run must select the intended existing full-stack cells,
execute them on GitHub, and report their original case IDs, assertions
and source revision. Missing evidence must remain a visible failure.

**Steps to reproduce**

Open the Product regression plan and inspect Executors. There is no live
job. The existing full-stack workflow accepts exact cell IDs but has no
TestOps selection or reporting path.

**Paperclip version or commit**

The branch includes reviewed master correction 04a24f4e06. This change
does not alter scenario prompts, models, deadlines or assertions.

Related public work: #18542 establishes the separate chat-catalog lane.
#18666 repairs its workflow URL binding. These changes do not implement
this Product plan.

## What Changed

- Add optional TestOps service inputs and a manual bootstrap selector to
the existing full-stack workflow.
- Map the original 20 case IDs and full names to existing native
Codex/local cells, with the existing native OpenCode/local
task-workspaces case.
- Keep reporting tokens in trusted default-branch selection and
publication jobs. Keep the existing paid provider authorization and
protected environments.
- Bind retained results to the workflow, job run, launch, source
revision and selection hash. Preserve missing-result failures and
earlier attempt verdict receipts.
- Verify uploaded identities, coverage and verdicts. Document full-plan
and subset reporting limits.
- Keep the outstanding-decision reservation live while its existing
deletion-fence test asserts the original 409 guard. Release the test
provider in finally. Production deletion and accounting code stay
unchanged.

## Verification

- `node --test tests/runner-e2e/product-regression-testops.test.mjs`: 13
positive and negative controls pass, including the separated CLI
handoff.
- Existing paid-workflow security regression passes.
- `actionlint -shellcheck= .github/workflows/runner-full-stack-e2e.yml`:
passes.
- The Product E2E catalog compatibility test confirms all 20 exact cells
exist: passes.
- `pnpm test:e2e:runner:typecheck`: passes.
- Fresh Greptile review of final head 61ef7a6e is 5/5 (11 files, no new
findings); both initial reporting findings are repaired and resolved.
- `server/src/__tests__/decision-models.test.ts`: all 37 controls pass
on a disposable official PostgreSQL 18 container in 22.02 seconds. The
unchanged focused case passed once and all five local samples; the
original Linux CI failure remains retained. This is not a claimed
deterministic local red reproduction. The new gate explicitly preserves
the outstanding-reservation precondition.
- The existing master readiness-fixture correction passes all three
retained-workspace controls on the same database in 25.79 seconds. It is
incorporated from master, not duplicated in this PR's diff.
- Final-head Linux CI also passed all 37 decision-model controls in
7.047 seconds; the server shard passed 120 files and 2,004 tests. See
[the retained successful
shard](https://github.com/paperclipai/paperclip/actions/runs/41870214517/job/126715358759).
- Previous CI failures are retained: [three stale readiness-fixture
cases](https://github.com/paperclipai/paperclip/actions/runs/41864061890/job/126694812885)
and [the reservation fixture
race](https://github.com/paperclipai/paperclip/actions/runs/41864061890/job/126694812894).
The separate [Canary Dry
Run](https://github.com/paperclipai/paperclip/actions/runs/41864061890/job/126694811605)
recorded a lost self-hosted runner connection before any step. The
fixture repairs are verified on changed source; the separate
Spot-interrupted CI attempt and its bounded retry are recorded below.
- Actual one-cell GitHub canary on the unchanged product source:
https://github.com/paperclipai/paperclip/actions/runs/41860189801 . The
native Codex/local message-marker case passed all six assertions and
cleanup in 35.24 seconds. The persisted issue is Done and its one run
succeeded. This is supporting evidence; it is not TestOps acceptance.
- Final-head CI attempt 1 was interrupted: three failed jobs have EC2
`Server.SpotInstanceTermination` receipts; six cancelled jobs show the
same simultaneous shutdown. Original logs are retained. One [failed-job
retry](https://github.com/paperclipai/paperclip/actions/runs/41870214517/attempts/2)
passed all nine interrupted checks while preserving prior successful
jobs.
- Final-head full repository CI passes, including both required `ci /
verify` and `ci / e2e` gates. GitHub still requires a non-author
code-owner approval for the workflow change; normal auto-merge is
queued. A fresh TestOps-triggered subset/full-plan acceptance remains
pending. Local projection checks do not establish a live Product pass.

## Risks

- The first bootstrap upload must establish the official TestOps job
before the saved plan can use it.
- This lane tests one declared local native configuration per case. It
does not qualify the historical 355-row matrix.
- Upload failures remain visible. A missing retained report produces
broken case results and cannot pass.
- The existing non-TestOps campaign path must keep its selection and
scheduling behavior; paid-workflow regression coverage remains in place.

## Model Used

OpenAI Codex with reasoning, code execution and tool use. The host does
not expose the exact model ID or context window to this session.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-11-04 11:17:39 -06:00