mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-03 17:51:58 +01:00
## Thinking Path > - Paperclip manages AI agents that do real work. > - Product evals verify the saved outcome of that work. > - TestOps plans select and dispatch these evals. > - Operator launchers check a unique launch name before they request work. > - TestOps expects an encoded filter, but the launchers send plain name text. > - This change uses the vendor filter format in the shared TestOps API owner. > - The existing checks can then prevent duplicate launch requests. ## Linked Issues or Issue Description Refs #18516, #18608, and #18542. The completion pilot registered successfully after #18608. Its optional API launcher then stopped with HTTP 400 in [run 41477551241](https://github.com/paperclipai/paperclip/actions/runs/41477551241). It stopped before the launch mutation marker. No evaluation was dispatched by that request. The launch search API uses Base64 of UTF-8 JSON filters. The launchers sent plain name text. I confirmed the format in the deployed public [vendor filter codec](https://paperclip.testops.cloud/es-testops-CICoDnkU.js) and its launch UI. The encoded name filter displayed the existing pilot launch. The TestOps UI separately dispatched [the genuine three-case pilot](https://github.com/paperclipai/paperclip/actions/runs/41478906153); this PR does not create another run or claim that pilot passed. ## What Changed - Add the typed name-filter encoder to the existing TestOps API module. - Use it in the backlog and completion launch preflight requests. The full-catalog route uses the same completion adapter. - Preserve the exact launch name, nonce, selection, authorization, once-only markers, and no-resend behavior. - Add protocol controls through both real launch functions. Document the wire format. ## Verification - Red: both new consumer controls reproduce the HTTP 400 boundary with plain name text. The other 109 API controls pass. - Green: all 111 API controls pass after the fix. All 166 related API, pilot contract, and full-catalog controls pass with Node 24.22.2. - The first broad local invocation lacked the `yaml` dependency in the new worktree. Its failure log is retained. Reusing the existing installed dependencies allowed all 166 controls to run and pass without further source changes. - The vendor-format query displayed the existing uniquely named pilot launch in the authenticated TestOps UI. No launch POST or model call was used for this read-only verification. - Diff check passes. All required CI checks pass on exact head `b55bdc6753fa042e4c2465e7b9b366b8126b4730` ([run 41480643021](https://github.com/paperclipai/paperclip/actions/runs/41480643021)). Both current-head reviews are 5/5, with zero unresolved findings. No TypeScript, compiled product, workflow, grader, model, clock, retry, or evidence-boundary changes. ## Risks The vendor can change its search format. The format is kept in the existing provider-specific API module, and both launch consumers have protocol controls. Existing duplicate detection and uncertain-response refusal remain in place. The already-running UI pilot is independent of this fix. ## Model Used OpenAI GPT-6 through Codex assisted with reasoning, repository inspection, code execution, and native accessibility tool use. The host does not expose the exact model revision or context-window size. ## 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 linked existing issues or described the issue in-PR following the relevant issue template - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [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 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
399 lines
25 KiB
Markdown
399 lines
25 KiB
Markdown
# Chat feature evals
|
|
|
|
`chat-features` promotes two entries from the [scenario catalog](chat-scenarios/README.md)
|
|
into real Product E2E executions. The scope is deliberately small: prove the
|
|
fixture, browser interaction, independent grading and report loop before adding
|
|
more features. Catalog coverage is not live acceptance.
|
|
|
|
| Scenario | Actual user request | Independent outcome |
|
|
| --- | --- | --- |
|
|
| `tasks.create-backlog` | Add a task for Morgan to draft the launch announcement in Launch, but don't start it yet. | Exactly one task, Launch project, Morgan assignee, backlog at creation, no worker execution, usable chat link after reload. |
|
|
| `tasks.delegate-announcement` | Have Morgan write a two-sentence launch announcement using the Launch project brief, save it on the task, and send me the result here when it's finished. | Exactly one task, actual Morgan execution, current worker-authored document grounded in the project brief, task Done, automatic completion response in the original chat, usable result after reload. |
|
|
|
|
The queries are read directly from `chat-scenarios/tasks.yaml`. Context and
|
|
expected outcomes stay evaluator-side. The fixture creates a disposable company,
|
|
CEO, Morgan and Launch project through production APIs; both agents use the
|
|
shipped role instructions. The brief contains a product, date and random invitation
|
|
code absent from the user query. The browser sends one message through Agent Chat.
|
|
The harness never creates the result task, writes the announcement, completes the
|
|
task, or sends a hidden follow-up.
|
|
|
|
## Run the first slice
|
|
|
|
Follow the installation steps in [README.md](README.md#local-commands). The Codex
|
|
subscription profile uses the catalog's recorded default model and an
|
|
explicit `CODEX_AUTH_JSON` login. Load that login privately into the launcher
|
|
environment; do not print it or save it in tracked configuration. The existing
|
|
subscription fixture stages only `auth.json` in the disposable company login slot
|
|
and removes it with the isolated instance.
|
|
|
|
The local native OpenCode profile uses the current production-qualified model
|
|
and `OPENROUTER_API_KEY` through the existing encrypted company-secret fixture.
|
|
Each of the two journeys has a cell for each original profile. These four cells
|
|
remain unchanged; the TestOps profile below adds one separately named backlog cell.
|
|
|
|
```sh
|
|
pnpm test:e2e:runner:typecheck
|
|
pnpm test:e2e:runner:unit
|
|
pnpm test:e2e:runner -- --list --suite chat-features
|
|
pnpm test:e2e:runner -- --id chat-features.runner-codex-subscription.local.create-backlog --max-automatic-retries 0
|
|
pnpm test:e2e:runner -- --id chat-features.runner-codex-subscription.local.delegate-announcement --max-automatic-retries 0
|
|
pnpm test:e2e:runner -- --id chat-features.runner-opencode.local.delegate-announcement --max-automatic-retries 0
|
|
```
|
|
|
|
Run creation first and inspect its packaged report before delegation. For the original Codex
|
|
acceptance, run each cell three times against fresh fixtures on the same definition
|
|
revision. Keep every attempt, including failures; a retry does not erase one. A
|
|
fixture or product correction starts a new three-sample measurement. All cells
|
|
are explicit-only and excluded from `--all`; this does not implement or qualify
|
|
the rest of the YAML inventory.
|
|
|
|
## OpenCode TestOps integration acceptance
|
|
|
|
The additional explicit cell
|
|
`chat-features.runner-opencode-deepseek-1017.local.create-backlog` runs the same backlog
|
|
query, public fixture and saved-state oracle on native OpenCode with
|
|
`openrouter/deepseek/deepseek-v4.1-flash-1017`. It requires only the selected
|
|
`OPENROUTER_API_KEY` profile credential. The launcher stores an encrypted secret
|
|
reference for the disposable agents; no key belongs in catalog data or chat.
|
|
This selected model is a qualification candidate. Other OpenCode suites keep
|
|
their existing model, and delegation is not registered for this profile.
|
|
|
|
```sh
|
|
pnpm test:e2e:runner -- --id chat-features.runner-opencode-deepseek-1017.local.create-backlog --max-automatic-retries 0
|
|
```
|
|
|
|
Use a separately named TestOps integration-acceptance plan and launch for this
|
|
single cell. It retains one human request, one accounted controller work run,
|
|
120-second turns, a seven-minute attempt, the five-minute stable-state bound
|
|
and zero automatic retries. Morgan is created as fixture context but must not
|
|
execute the saved backlog task. Existing setup probes and unknown usage remain
|
|
reported separately. The original 244-scenario campaign, failed attempts and
|
|
Codex measurements are not reset or regraded by this measurement.
|
|
|
|
The existing normalized result, JUnit and packaged report carry the outcome to
|
|
the execution integration. Catalog selection and provider-free oracle checks
|
|
do not establish an AWS model pass or a successful TestOps upload. Accept this
|
|
integration only after the real AWS execution and its TestOps result agree.
|
|
|
|
## Bounds and grading
|
|
|
|
Creation expects one accounted native work run; delegation expects three (CEO
|
|
handoff, Morgan work, CEO completion response). Runs have a 120-second timeout
|
|
and attempts a seven-minute deadline. The visible task and completion reply must
|
|
settle within five minutes after the human request, including a five-second stable
|
|
observation. This is an independent journey acceptance bound: three runs may not
|
|
each consume their maximum timeout and still pass. The outer attempt also covers
|
|
fixture setup, reload and link checks, and evidence collection. A failed provider
|
|
run rejects immediately; the historical missing turn-start event was not a
|
|
five-minute poll timeout. Automatic retries are disabled. Company
|
|
and agent budgets are 500 cents each, CEO daily work runs are capped at three,
|
|
Morgan at one, and periodic heartbeats are disabled. Initial production hello
|
|
probes fall outside heartbeat usage and budget accounting; detailed setup tokens
|
|
and cost are unavailable. These limits are not an absolute inference or cash cap.
|
|
Subscription cost coverage must remain explicit in the report.
|
|
|
|
An obsolete CEO assignment can leave a cancelled queue entry when the CEO creates
|
|
a task and then assigns it to Morgan. Grader v2 distinguishes that entry from
|
|
provider work only when the dispatch gate records `issue_assignee_changed`, an
|
|
explicitly null start time, no native issue, and its unchanged stale-queue stop
|
|
receipt. The entry must belong to this company and the one task now assigned to
|
|
Morgan. It stays in the full observation and final ledger, with its events and an
|
|
explicit provider-log omission reason. Active, unrelated, or unproved cancellations
|
|
still fail. The three successful work runs, worker output, completion delivery,
|
|
and original deadlines remain required. Backlog creation still permits no task wake.
|
|
|
|
Because this subscription currently reports unpriced usage, setup explicitly sets
|
|
`unpricedUsagePolicy: allow` on the disposable company and both agents through the
|
|
public budget API and verifies all three policies. The 500-cent hard stops remain
|
|
enabled for reported costs; they cannot cap unknown dollar usage. Run caps and
|
|
deadlines remain independent bounds. Without this explicit funding prerequisite,
|
|
the default policy pauses the company after the first unpriced run and cancels
|
|
the delegated worker. Such a pause is not a successful chat journey.
|
|
|
|
`chat-feature.json` retains the scenario ID, capability IDs, grader version,
|
|
saved records, audit attribution, rendered links and individual checks.
|
|
`chat-feature-runs.json` uses the existing native run evidence collector, including
|
|
on failures. Setup evidence records fixture IDs, synthetic brief, readiness and
|
|
saved budgets. Ordinary Product E2E evidence packaging, redaction, cleanup, failure
|
|
classification and dashboards own the result. The definition digest includes the
|
|
query, defaults, flow and grader sources.
|
|
Individual saved-state checks are also recorded when the journey fails, so the
|
|
report shows partial progress without turning it into a passing workflow.
|
|
|
|
The grader rejects duplicate tasks, wrong owners/projects/companies, early execution,
|
|
missing audit attribution, missing or stale deliverables, extra human nudges and
|
|
uncorrelated completion replies. Document provenance binds the current revision
|
|
to Morgan's actual run. The completion check reuses `completionDelivery`; a
|
|
handoff promise or a marker alone cannot establish delivery. Chromium verifies
|
|
the task link and reload persistence.
|
|
|
|
The checks establish the specified saved state, two-sentence structure, required
|
|
brief facts and result access. They do not score writing quality or every semantic
|
|
claim in the response. Inspect the retained conversation and announcement before
|
|
accepting the first samples; the existing completion semantic-review rubric still
|
|
applies. Oracle calibration tests exercise both valid evidence and plausible wrong
|
|
outcomes without calling a model.
|
|
|
|
Only after this loop is stable should another scenario be promoted. Keep each
|
|
starting condition explicit: connected versus missing connection, allowed versus
|
|
approval-required, and so on. Reuse the fixture/report infrastructure and add a
|
|
case-specific outcome oracle; do not make all YAML paragraphs executable through
|
|
an unconstrained model judge.
|
|
|
|
## Initial measurement — 2026-10-26
|
|
|
|
Three fresh samples per cell on definition
|
|
`7fb20426ce3f1dd4efeddfb79f231336ea65a16b9c2a73bf6131e997acd74e9d`
|
|
produced **5/6 passes**: backlog creation 3/3 and delegation 2/3. These used local
|
|
native Codex subscription execution with `gpt-5.6-sol`. All six cleaned up
|
|
successfully. Both workflows have successful browser-to-provider evidence, but
|
|
the initial repeatability target is not met.
|
|
|
|
In campaign `local-2026-10-26T15-48-12-199Z`, the first CEO run in delegation
|
|
failed before creating a task: `runnerd did not report the provider turn identity`.
|
|
Retained events show submission and provider startup, followed by the transport's
|
|
turn-start deadline. The precise cause of the missing event remains unresolved;
|
|
the existing machine classification is retained without claiming that the provider
|
|
or infrastructure has been proven responsible. Investigate this before expanding
|
|
the suite. No replacement sample erased this failure.
|
|
|
|
The local `results/chat-feature-acceptance/acceptance.md` records every sample and
|
|
earlier failed revision; its sibling dashboard uses the standard report generator.
|
|
Results are ignored generated artifacts, so retain or publish them through the
|
|
existing Product E2E pipeline when handing this measurement to another machine.
|
|
|
|
### Follow-up measurement — 2026-10-26
|
|
|
|
The unchanged delegation cell subsequently passed three fresh executions:
|
|
`local-2026-10-26T16-50-50-751Z`, `local-2026-10-26T16-54-58-203Z`, and
|
|
`local-2026-10-26T16-58-39-074Z`. The latter two campaigns also ran backlog
|
|
creation concurrently and passed both cells. All five selected executions used
|
|
one attempt with zero automatic retries, retained the same definition above,
|
|
and passed cleanup. Five existing turn-identity, early-terminal and runner-exit
|
|
regressions passed as well.
|
|
|
|
These are green rechecks, not a demonstrated repair of the earlier startup
|
|
interruption: no production code, timing limits or oracle assertions changed,
|
|
and the missing turn-start event did not reproduce. Keep the original failure
|
|
in the history. Across the original final-definition batch and this recheck,
|
|
backlog is 5/5 and delegation is 5/6. The local
|
|
`results/chat-feature-recheck/verification.md` records the follow-up evidence;
|
|
its standard dashboard is explicitly scoped to the latest campaign.
|
|
|
|
## TestOps completion pilot
|
|
|
|
The separate `Chat completion TestOps` workflow connects only these preserved
|
|
catalog cases to the private Paperclip Evals project:
|
|
|
|
- `projects.project-work`
|
|
- `projects.project-defaults`
|
|
- `instance-operations.restart-service`
|
|
|
|
It evaluates the immutable catalog source in
|
|
`chat-completion-testops-contract.mjs`. This keeps the broader catalog on its
|
|
integration branch. The source includes the bounded TestOps host prerequisite
|
|
from #18515. Changing the pin requires source review. The original DeepSeek
|
|
1017 model, case clocks, independent checks, and zero retries remain fixed.
|
|
Source registration does not establish a new live result.
|
|
|
|
Run the named plan **Chat completion pilot — OpenCode 1017** in TestOps. The
|
|
adapter validates the actual project, plan, job, launch and selected cases before
|
|
build or provider access. A selected subset runs only those cases. The AWS matrix
|
|
has concurrency one and does not cancel sibling cases after a failure.
|
|
|
|
The main-only reporter uses the existing protected `ALLURE_TOKEN`; the evaluated
|
|
app and worker never receive it. Original evidence stays in the existing private
|
|
AWS storage with the unchanged validators, scanners, byte bounds and exact-key
|
|
policies. A separate trusted projection carries verdicts, checks, accounting and
|
|
private-evidence receipts. The final PNGs are verified in protected storage;
|
|
only their checksums and availability are recorded in TestOps. GitHub artifacts
|
|
contain metadata only. Raw logs, screenshots, hidden
|
|
reasoning, API snapshots, credentials and provider sessions are not attachments.
|
|
Original failed grades and cleanup failures remain failed. Same-run readback
|
|
requires matching results and complete result-owned attachment metadata within
|
|
the existing bounded processing window; it does not claim remote byte hashes.
|
|
|
|
Initial setup uses the existing workflow operations:
|
|
|
|
1. Dispatch reviewed `master` once with `operation=bootstrap`. This creates or
|
|
reconciles only the three exact automated cases and the dedicated plan. It
|
|
registers the GitHub job with an empty Allure results directory. It reuses
|
|
only the existing enabled GitHub integration from
|
|
`CHAT_TESTOPS_INTEGRATION_ID`. No model or fabricated result is created.
|
|
The observation receipt captures a closed parameter-shape inspection before
|
|
binding. Only the observed single `Branch/defaultValue` definition for
|
|
`refs/heads/master` is accepted. Bootstrap enables the job and assigns cases
|
|
while preserving that definition; the plan uses its default branch.
|
|
Assignment inspection records unassigned and existing-job counts before
|
|
binding. A single unassigned bucket must cover the exact selected cases;
|
|
foreign jobs and unknown or incomplete buckets stop before writes.
|
|
2. Read the closed registration receipt. Store its observed `binding` JSON as
|
|
`CHAT_COMPLETION_TESTOPS_BINDING` in `runner-e2e-testops-reporting`.
|
|
3. Use TestOps **Run**. For the initial operator launch, set an exact next
|
|
workflow run number in `CHAT_COMPLETION_TESTOPS_LAUNCH_RUN_NUMBER`, set a new
|
|
32-hex `CHAT_COMPLETION_TESTOPS_LAUNCH_NONCE`, then dispatch `launch-plan`
|
|
once. Its request produces the TestOps-owned `evaluate` dispatch. Do not
|
|
manually dispatch an additional evaluation after an uncertain launch.
|
|
4. Verify the fresh TestOps launch, all selected case results, source links,
|
|
independent checks, private-evidence receipts and cleanup. Inspect screenshots
|
|
through authenticated private-history retrieval. Retain earlier failed attempts.
|
|
|
|
Launch preflight searches use TestOps' typed name filter, encoded as Base64 of
|
|
UTF-8 JSON in the `search` query parameter. Plain name text returns HTTP 400.
|
|
The backlog and completion launchers share this encoding; the full-catalog
|
|
launcher uses the completion adapter. Existing nonce and once-only guards still
|
|
apply before a plan-run request.
|
|
|
|
The runtime accepts only `operation`, `ALLURE_JOB_RUN_ID` and reserved username
|
|
metadata. It rejects arbitrary source/model/budget selectors, branch workflows,
|
|
replays and foreign cases. All secret-bearing jobs recheck actual GitHub run and
|
|
actor identities. The existing one-case backlog plan remains independent.
|
|
|
|
## Full catalog in TestOps
|
|
|
|
The [Chat catalog TestOps workflow](../../.github/workflows/chat-catalog-testops.yml)
|
|
registers all 244 scenarios from the 35 YAML areas in a separate
|
|
**Chat feature catalog — OpenCode 1017 (candidate)** plan. Its source-derived
|
|
manifest is `chat-full-catalog-testops-manifest.json`. The existing backlog plan
|
|
and three-case completion pilot keep their own jobs, selections and history.
|
|
Legacy aliases reuse existing TestOps case identities without renaming them.
|
|
|
|
The catalog contains 236 Agent Chat routes, five browser boundaries, one external
|
|
assistant route and two Slack routes. An execution mapping is not a passing
|
|
measurement. Five implementations declare incomplete coverage. Six routes do not
|
|
produce the generic final PNG required by the unchanged evidence owner. Eighteen
|
|
declare additional credentials and 37 declare external inputs. These groups
|
|
overlap. Exact requirements and limitations appear in each case's preconditions.
|
|
A declared credential does not establish whether its runtime reference exists.
|
|
|
|
This lane runs the app and fixtures from candidate
|
|
`3b66c3c144360ddf32714a0742fd774b8ceafb16`. Its app and domain definitions are
|
|
unchanged from `de0941835cc8f0d01c982574ee258e110babdbeb`; the successor adds only
|
|
finite TestOps host admission. Trusted selection, evidence transfer and publishing
|
|
use the workflow's immutable master revision. Each result records both revisions.
|
|
A pass qualifies that candidate measurement, not the current master app. Other
|
|
lanes sharing a case retain their own sources. This integration does not merge
|
|
the broad catalog branch or its core fixes, reset earlier campaign ordinals, or
|
|
change the previous 196-of-244 acceptance gate.
|
|
|
|
Native execution uses OpenCode and
|
|
`openrouter/deepseek/deepseek-v4.1-flash-1017` on the existing AWS fleet. Each case
|
|
keeps its original query, oracle, run counts, clocks, budgets and zero automatic
|
|
retries. Browser boundaries and the external assistant retain their original
|
|
surfaces and may have zero native work runs. The external companion keeps its own
|
|
declared provider requirement. Setup inference and unpriced usage are not free.
|
|
|
|
Initial setup uses the existing reporting environment:
|
|
|
|
1. Dispatch reviewed master with `operation=bootstrap`. It reconciles the exact
|
|
244 cases and the dedicated plan, then registers and binds its own GitHub job.
|
|
Missing cases use one marked POST each. Existing cases retain their identities
|
|
and history. Alias conflicts, foreign selections and uncertain writes stop
|
|
setup. It makes no model call or synthetic test result.
|
|
2. Read the registration receipt. Store its compact `binding` JSON as
|
|
`CHAT_FULL_CATALOG_TESTOPS_BINDING`. It contains observed plan, job, integration
|
|
and case IDs plus registered full names, and fits one GitHub environment
|
|
variable. The job must retain its observed single `Branch/defaultValue`
|
|
definition for `refs/heads/master`.
|
|
3. Use normal TestOps **Run** for the full plan or a selected subset. The service's
|
|
actual expected case list controls execution. Do not manually dispatch another
|
|
evaluation after an uncertain request. Initial route verification uses a small
|
|
selection and does not qualify all 244 cases.
|
|
|
|
Each worker executes one case. Selections of up to three cases run serially.
|
|
Larger selections allow eight independent cases and one external-input case at
|
|
once. External-input cases remain serial because they can share QA resources.
|
|
A full run can take hours. Its elapsed time depends on setup and fleet capacity;
|
|
the declared case clocks are not a completion-time guarantee. Each worker and
|
|
report reader has a singleton private-evidence approval and exact-key AWS
|
|
session; the existing eight-cell
|
|
authority limit is unchanged. Reports wait for all selected workers. A
|
|
credential-free job then validates and merges their metadata projections. The
|
|
protected reporter uploads original outcomes and verifies every selected result,
|
|
including paginated selections over 100 cases. Failed originals and failed
|
|
cleanup remain failed beside passed results. Missing originals cannot become
|
|
fabricated measurements or a full-selection pass.
|
|
|
|
Raw evidence and final PNGs remain in protected storage. Public GitHub artifacts
|
|
and TestOps attachments contain only allowlisted provenance, checks, accounting
|
|
and private-evidence receipts. Raw conversations, screenshots, provider sessions
|
|
and credentials do not enter the public artifact path. Additional credentials
|
|
reach only cases that declare them. External inputs use the existing selected-case
|
|
private-input owner, disposable-resource checks and oracle commitments.
|
|
Unconfigured inputs remain setup blockers.
|
|
|
|
## TestOps-backed AWS backlog cell
|
|
|
|
The dedicated `Chat feature TestOps` workflow accepts only the shipped default
|
|
branch and the fixed OpenCode backlog cell. `evaluate` is the default operation
|
|
and requires TestOps' `ALLURE_JOB_RUN_ID`. A protected reporting job verifies the
|
|
project, singleton plan, assigned public workflow, selected case and current
|
|
GitHub run before any build or provider access. The evaluated process receives
|
|
no TestOps token. It retains the original one-query, one-work-run, 120-second
|
|
turn, 420-second attempt, 300-second settled-state and zero-retry limits.
|
|
|
|
Two metadata operations prepare that route. `bootstrap` registers the actual
|
|
public CI job through pinned `allurectl` with an empty results directory and
|
|
reconciles only the dedicated case and singleton plan. It produces no passing
|
|
test result. After the registered job and protected case/plan/job identifiers
|
|
are verified, `launch-plan` sends one TestOps plan-run request and exits.
|
|
The TestOps job then dispatches `evaluate`; an operator must not dispatch a
|
|
second evaluation manually. Missing or ambiguous registration and selection
|
|
metadata stops before inference.
|
|
|
|
The workflow reuses the existing AWS fleet and strict private evidence storage.
|
|
Its shipped-main authority is separate from manual candidate approval. Original
|
|
logs, provider records and failure evidence remain private. The reporting adapter
|
|
exports only a source/run-bound normalized result, JUnit and screenshots already
|
|
marked by the owned fixture screenshot producer with matching file hashes.
|
|
A separate protected reporting job converts that projection to the exact TestOps
|
|
case. Failed grades and cleanup failures remain failed.
|
|
|
|
Reporting setup uses the master-only `runner-e2e-testops-reporting` environment,
|
|
with the existing reporting token delivered through the reviewed sealed-box
|
|
bootstrap. `CHAT_TESTOPS_CASE_ID`, `CHAT_TESTOPS_PLAN_ID` and
|
|
`CHAT_TESTOPS_JOB_ID` must name the observed dedicated mapping; the numeric
|
|
`CHAT_TESTOPS_GITHUB_WORKFLOW_ID` supports TestOps' registered workflow URL.
|
|
No arbitrary source, model, case, retry or budget input is accepted.
|
|
|
|
The initial `launch-plan` administrator operation also requires a protected
|
|
`CHAT_TESTOPS_LAUNCH_RUN_NUMBER`. After registration, the trusted operator creates
|
|
this variable once with the reviewed next workflow run number and reads it back.
|
|
The launcher compares GitHub's actual run number, attempt, workflow, source and
|
|
actors before any TestOps mutation. A later dispatch or replay cannot reuse that
|
|
approved number. Missing or uncertain metadata stops; an uncertain request needs
|
|
reconciliation rather than a new send. The nonce and launch search provide
|
|
additional evidence. Normal TestOps **Run** uses `evaluate` and is independent of
|
|
this one-time administrator fence. The launch nonce is protected configuration,
|
|
not a dispatch input. Job parameter IDs are opaque. The launcher preserves the
|
|
API's exact ID/value pair for `refs/heads/master` and uses the fixed workflow's
|
|
`evaluate` default. An operation parameter is used only when the protected
|
|
`CHAT_TESTOPS_OPERATION_PARAMETER_ID` matches a returned ID with a `bootstrap`
|
|
or `evaluate` value; the launcher then sets it to `evaluate`. Other values,
|
|
duplicate IDs and conflicting configuration are rejected. No relationship to
|
|
global environment-variable IDs or names is inferred.
|
|
|
|
`CHAT_TESTOPS_INTEGRATION_ID` names the reviewed existing project GitHub
|
|
integration. The launcher verifies its project, type and enabled state, then binds
|
|
only the newly registered public job to it. It never changes integration settings
|
|
or credentials. Since the job response does not expose that association, only the
|
|
real TestOps-to-GitHub dispatch can qualify it.
|
|
|
|
After `allurectl watch` finishes, the same protected reporter checks the actual
|
|
TestOps job-run, launch, selected case, result source/status and attachment
|
|
metadata. Processing reads are bounded to 12 polls, five-second gaps and a
|
|
120-second processing deadline. Unknown or missing results remain unverified.
|
|
The check downloads no attachment content and claims no server-side attachment
|
|
byte hash. Its closed receipt is retained separately. An upload success alone
|
|
is not a passing feature result, and verifying an original failure cannot turn
|
|
that failure into a pass.
|
|
|
|
Build and worker installs use the existing reviewed report-lock policy. Only its
|
|
committed input or output lock is accepted; its authenticated correction is the
|
|
only allowed normalization. Dependency manifests, patch inputs and policy must
|
|
remain unchanged. Installs are frozen with lifecycle scripts disabled. The
|
|
credential-free build rechecks that boundary before packaging, and the worker
|
|
matches the source/lock receipt before installing. Arbitrary resolver drift is
|
|
rejected before provider access.
|