Files
PaperClipAI/tests/runner-e2e/reliability-testops.mjs
T
DottaandClaude Opus 5.5 38068de553 chore(evals): commit the Reliability TestOps plan and case identities (#19604)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Runner E2E cases run from Allure TestOps plans through
`runner-full-stack-e2e.yml`
> - #19549 added the "Reliability — staging soak" plan. Its selection
fails closed until real TestOps identities are committed
> - Registration run
https://github.com/paperclipai/paperclip/actions/runs/42289820474 on
master (02214b1a3c) completed. It created plan 135 with cases 885–891
and assigned the plan to the standing GitHub job 166
> - This pull request commits those identities into
`reliability-testops.mjs`
> - The benefit is that a TestOps launch of plan 135 now selects the
seven reliability cells

## Linked Issues or Issue Description

Refs #19549
Refs #19601

**What happened?**
The Reliability TestOps plan exists in TestOps, but the repository still
had an empty `reliabilityRegistration`. A launch therefore failed closed
with `product_regression_testops_reliability_unregistered`.

**Expected behavior**
A launch of plan 135 maps each TestOps case ID to its runner E2E cell
and runs it.

**Steps to reproduce**
1. Launch plan 135 from TestOps before this change.
2. The selection fails with `reliability_unregistered`.

## What Changed

- `tests/runner-e2e/reliability-testops.mjs`: set
`reliabilityRegistration` to plan 135 and the seven case IDs from the
registration receipt.

## Verification

- `node --test tests/runner-e2e/reliability-testops.test.mjs
tests/runner-e2e/product-regression-testops.test.mjs`: 28/28 pass.
- `registeredReliabilityCases()` with plan-2 IDs reserved resolves all
seven cells: 885 interrupt-redirect, 886 reassign-midrun, 887
three-turn-revise, 888 long-silent-command, 889 tree-pause-release, 890
queue-steer (Codex), 891 queued-across-restart.
- The registration receipt from run 42289820474 reports `complete: true`
with assignment and parameters created.

## Risks

- Low risk. The change only adds identities. A launch of plan 135 runs
seven paid cells under the existing admission and budget caps. Nothing
runs per PR or on a schedule.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`) in Claude Code with tool use
(shell, GitHub CLI), standard context.

## 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>
2026-11-06 15:22:02 -06:00

70 lines
3.7 KiB
JavaScript

// The TestOps "Reliability — staging soak" plan: a sibling of the standing
// Product regression plan (plan 2) on the same trusted workflow, TestOps job,
// selection, projection, upload and verification path. Each case selects one
// existing everyday-workflows reliability cell; it does not change the prompt,
// grader, budget or runtime. Six plan cells run native OpenCode with DeepSeek
// 1017 through OpenRouter. queue-steer must steer an active turn, which the
// OpenCode driver does not support (`steering: false`), so the plan uses the
// existing native Codex Daytona cell for it. The other native Codex and ACPX
// reliability cells stay explicit-only extras outside the plan.
export const reliabilityPlanKey = 'reliability';
export const reliabilityPlanName = 'Reliability — staging soak';
export const reliabilitySuite = 'everyday-workflows';
export const reliabilityProfile = 'runner-opencode-deepseek-1017';
export const reliabilityModel = 'openrouter/deepseek/deepseek-v4.1-flash-1017';
const steeringProfile = ['runner-codex', 'gpt-5.6-sol'];
// Daytona only where the soak failure was a sandbox lease failure (S49, S52/S52b,
// S55). The catalog test binds this table to everyday-reliability-cases.ts.
export const reliabilityDefinitions = Object.freeze([
['interrupt-redirect', 'local', 'S47'],
['reassign-midrun', 'local', 'S48'],
['three-turn-revise', 'daytona', 'S49'],
['long-silent-command', 'daytona', 'S52/S52b'],
['tree-pause-release', 'local', 'S50/S50b'],
['queue-steer', 'daytona', 'H2', ...steeringProfile],
['queued-across-restart', 'daytona', 'S55/U9'],
].map(([name, environment, signature, profile = reliabilityProfile, model = reliabilityModel]) => Object.freeze({
plan: reliabilityPlanKey, suite: reliabilitySuite, name, environment, signature, profile, model,
fullName: `paperclip.Product E2E.${reliabilitySuite}.${name}`,
executionId: `${reliabilitySuite}.${profile}.${environment}.${name}`,
})));
// TestOps assigns these identities; they are never invented here. Fill them,
// in one reviewed change, from the receipt of the trusted
// `runner-e2e-testops-registration.yml` workflow (operation `register`).
// Until every case and the plan have an identity, selecting this plan fails
// closed with `product_regression_testops_reliability_unregistered`.
export const reliabilityRegistration = Object.freeze({
planId: 135,
caseIds: Object.freeze({
'interrupt-redirect': 885,
'reassign-midrun': 886,
'three-turn-revise': 887,
'long-silent-command': 888,
'tree-pause-release': 889,
'queue-steer': 890,
'queued-across-restart': 891,
}),
});
const fail = code => { throw new Error(`product_regression_testops_${code}`); };
const positive = value => Number.isSafeInteger(value) && value > 0;
/**
* Bind the reviewed TestOps identities to the reliability cells. Returns null
* while nothing is registered; any partial, duplicate, foreign or malformed
* registration fails instead of selecting a subset.
*/
export function registeredReliabilityCases(registration = reliabilityRegistration, reservedCaseIds = [], reservedPlanIds = [2]) {
const ids = registration?.caseIds ?? {};
if (registration?.planId == null && Object.keys(ids).length === 0) return null;
const names = reliabilityDefinitions.map(row => row.name);
if (!positive(registration.planId) || reservedPlanIds.includes(registration.planId)
|| Object.keys(ids).length !== names.length || names.some(name => !positive(ids[name]))
|| new Set(names.map(name => ids[name])).size !== names.length
|| names.some(name => reservedCaseIds.includes(ids[name]))) fail('reliability_registration_invalid');
return Object.freeze(reliabilityDefinitions.map(row => Object.freeze({ id: ids[row.name], ...row })));
}