Files
PaperClipAI/tests/runner-e2e/CATALOG-PRESERVATION.md
T
f4337bb5fb test(evals): land the chat catalog eval harness on master (#19614)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The chat-feature evals measure whether agents complete real chat
requests through the product
> - The chat catalog eval harness and its repairs live on the
`chat-eval/master-candidate` branch, not on master
> - Today's work made 139 of 242 chat evals pass in verified single-case
live runs. Each product fix landed on master as its own pull request
> - The eval-side changes (setups, graders, fault seams, evidence
capture) still exist only on the candidate
> - This pull request lands the harness on master. Master stays the
source of truth for product behavior
> - The benefit is one tree: evals run against master commits, and
product fixes reach the evals as soon as they merge

## Linked Issues or Issue Description

Refs #19441, Refs #19599, Refs #20270, Refs #20334, Refs #20342, Refs
#20344, Refs #20354, Refs #20360, Refs #20373, Refs #20382, Refs #20409

**What existing behavior does this improve?**
The chat catalog eval harness and the product it evaluates live on a
long-running branch outside master. Eval fixes do not reach master, so
master-based eval runs use old setups and graders.

**Subsystem affected**
`tests/runner-e2e` chat catalog harness, plus a small set of product
changes that exist only on the candidate.

**Proposed change**
Land the harness on master. Every product fix from this eval work
already merged to master as its own pull request. Conflicts keep
master's product behavior.

## What Changed

- Most of the diff (808 of 851 files) is under `tests/runner-e2e/`:
chat-catalog domains, scenarios, descriptors, the TestOps manifest,
private evidence tooling, and their tests.
- Graders now check saved state, setup literals and rendered or clicked
links. Many keyword and regex checks on free-form replies are removed.
Each changed grader has a bumped `oracleVersion` and calibration tests
(a valid reply, a reworded valid reply, and broken variants that must
fail).
- The shared link helper `hasLink` no longer treats a list link (for
example `/COM/issues?view=mine`) as a link to every task without a URL
key.
- Setup fixes build real state through supported product routes: routine
history, agent grants through the board grant route, budget holds with a
real cap, and a storage-layer archive fault for
`inbox-search.archive-partial-failure`.
- Browser boundary journeys (sign-in, chat-disabled, onboarding) now
write the standard pass evidence files.
- Retargeted cases, approved by the maintainer:
`agent-chat.chat-disabled` (Conference Room gate),
`agents.restore-instructions` (no saved instruction history),
`access.manage-membership` (member permission edits stay board-only).
- The private evidence trusted files (`manual-private-handoff.ts`,
`manual-private-retention.ts`, `manual-private-report-assets.ts`) are
byte-identical to master.
- Product files outside `tests/` (43 files, +1,328 −49) carry
candidate-only changes that master does not yet have. Most are tests.
The main code changes are in `request-human-input.ts`,
`heartbeat-run-summary.ts`, `native-completion-feedback.ts`,
`native-run-finalizer.ts`, `openapi.ts`, `secrets.ts` and
`IssueChatLongThreadPerf.tsx`.

## Verification

- `pnpm vitest run chat-catalog-domains chat-catalog-contract.test.ts
chat-catalog-consistency.test.ts unit-launcher.test.mjs
--testTimeout=180000` in `tests/runner-e2e`: 269 files pass, 3,550 tests
pass.
- `node --test chat-full-catalog-testops-manifest.test.mjs`: 10 pass.
- `node tests/runner-e2e/source-sdk-public-inputs.mjs <HEAD> --check`:
no change.
- `tsc` for `server` and `tests/runner-e2e`: clean.
- Live single-case verification: 139 of 242 cases passed on paid runs,
and a person read the saved evidence for each. These are single-case
runs, not one full-cohort run.

## Risks

- Large diff. Most of it is test-only, but the 43 non-test files change
product code paths. Review those files first.
- Some graders are now less strict on reply wording. A person must read
replies for meaning on those cases.
- 42 cases need disposable outside accounts (Notion, Slack, GitHub,
Daytona and others) and stay blocked. `access.invite-teammate` stays
failing until local agent isolation lands, because the runner's durable
state keeps a live invite token.
- The paid workflow compares the trusted private-evidence files with
master. They are unchanged, so this risk is low.

## Model Used

Anthropic Claude Opus 5.5 (`claude-opus-5-5`), with tool use and code
execution, in Claude Code. Subagents used the same model.

## 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
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-11-10 08:02:11 -06:00

108 lines
6.6 KiB
Markdown

# Preserved chat catalog source
This branch consolidates reviewed eval changes for all **244** frozen scenarios:
242 lazy catalog entries and the two existing standalone chat flows. It preserves
source implementations, controls and evidence contracts. It does not establish
that all scenarios are ready to run or that this composed head has passed a live
campaign. The machine-readable inventory is `chat-catalog-preservation.json`.
The production baseline remains `39e811c9c5226979fce42e052a27cfb28301018a`.
No production, workflow, lockfile or SDK source change is included. The real
new-company, formal-hire and routine-history definitions retain prerequisites
18103, 18105 and 18033 respectively. Those focused fixes are excluded here; their
candidate outcomes remain separate from frozen-baseline qualification.
Composition preserves the per-scenario descriptor union, both independent SDK
privacy and new-company security sections, the final formal-hire clock module,
and the stronger shared Notes provider used by status cards and routine history.
The accepted original-deadline and multipart controls are included, as is the
new-company successor's original phase deadline and remaining-time wizard clamp.
Frozen queries, contexts, outcomes, turn/human counts and overall caps are retained.
The accepted SDK2 overlay binds least-scope setup to the actual public Agent
lifecycle/version and a new real plugin resume receipt within the existing
90-second wait. Managed-routine setup identifies only its saved routine and
plugin through ordinary conversation context and independent CEO readback;
structural JSON comparisons ignore object key order while preserving all values,
arrays, ownership and explanation checks. A pending question still fails the
required outcome.
The task prerequisite overlay binds two genuine ready owners to their completed
public manual pauses, exact versions and holds before inventory seeding. It also
adds the owned browser Origin to the existing human attachment upload, preserving
the real board mutation guard and exact company/task/comment/byte checks. Neither
overlay changes canonical messages, native/human counts, overall caps or an
exhausted case's result. The production core fixes remain excluded.
The document and decision-audience overlay preserves exact public document
identity, revision and bytes through the shipped Plans control, and reads a
pending addressed decision through the actual authenticated recipient's feed.
It requires both the owner and recipient identities. Its measured final failures
remain unchanged and exhausted; source preservation gives them no new cycle.
The outbound-email observer accepts ordinary standing-chat work with a null
parent only when the canonical source run, creator, public audit and real native
assignment admission agree. It also preserves the supported public issue-create
wake shape. The email task still links explicitly to that work and the exact
owned thread/endpoint; original draft, recipient, native send, provider receipt,
duplicate and truthful delivery checks remain. Actual authorized AgentMail
resources and input delivery are separate prerequisites, with no source-only
runtime pass or implicit credential-transfer permission.
Readiness is separate from importability. Declared unsupported fresh contexts,
public capability/profile gaps and external resource/authorization requirements
remain explicit. The preserved plugin configure/disable fixture still has a known
secret-ref schema mismatch: it sends an object where its public string schema
requires a secret UUID. Disable's returned final reached that setup request and
received HTTP 400. Configure's returned final stopped earlier while waiting for
the initial chat response; its later UI/configuration leg was not exercised, so
the schema mismatch there is a source finding. Both spent raw failures remain
unchanged and are not rerun by this consolidation. Other measured failures retain
their actual interpretation.
The legacy Projects manual-order surface required by sidebar-order is absent
from both frozen-production layouts; this source does not revive it or inject a
classic interface to manufacture the frozen context.
Every historical result remains attached to its original source revision, full
fingerprint, provider/model/build/database evidence, ordinal, usage, cost, privacy
and cleanup. The integrated source changes broad fingerprint closures; none of
the older qualified passes is transferred to this head. No attempt budget is reset,
and no live launch or publication authority comes from this source preservation.
## Integration candidate, 2026-10-31
This owned integration branch combines preserved source `e2b35be76f` with
master `51ea624344`. The original preservation branch and its historical results
remain unchanged. No historical pass transfers to this composed source.
The frozen 244-case OpenCode catalog keeps its historical IDs and DeepSeek 1017
model. The two shipped subscription aliases and the separate TestOps backlog cell
remain selectable alongside it; they do not change the frozen denominator.
The standalone aliases retain the current shipped 120-second turn limit.
Catalog phase and attempt budgets remain separately declared by their fixtures.
The integration compatibility checks distinguish the 244 historical cells from
the three shipped aliases. Fixtures implement current run-observation and
conversation-link custody contracts. The standalone flows keep shipped timeout
behavior; catalog-native setup still verifies its separately declared policy.
Synthetic public-schema tests hash their copied synthetic inputs, while the
production frozen source manifest and all private-value rejection checks remain
unchanged. No SDK runtime qualification follows from those synthetic tests.
The refreshed base includes current master's committed Agent Chat reply recovery
and durable retry deadlines. It also contains event-driven issue/receipt recovery
and the guard against a native run changing its own task status. These are
upstream product changes, not qualifications
of the preserved scenarios. Fresh pilots remain bound to their exact source.
## TestOps completion pilot
The dedicated main-only `chat-completion-testops.yml` workflow may select only
`projects.project-work`, `projects.project-defaults`, and
`instance-operations.restart-service` on the native OpenCode 1017 profile.
It needs the TestOps admission marker, a real job-run identity, attempt one,
and the same source-bound AWS host verification as the existing campaign.
The entry point preserves original queries, grading, clocks and zero retries.
Registration is separate from a real TestOps pass and verified result upload.
The broader catalog remains on this integration branch.