mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-09 16:02:36 +01:00
## 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>
70 lines
3.7 KiB
JavaScript
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 })));
|
|
}
|