test: drive 402 through real escalation consumers - #56
Conversation
thegeorgepu
left a comment
There was a problem hiding this comment.
GO at exact head e948eb8ead6ea5bbeb7f356196f14dd29557c837.
I verified both real 402 variants through the production advisor, council, scope, and loop-recovery consumers. Each case terminates with the original status: 402 retained as the cause, never attempts a same-class retry or cheaper fallback, and emits no unavailable-class continuation. The queued second 402 plus successful Forte response is a valid tripwire: forcing the classifier to return transient makes the test fail at advisor-in-flight with Missing expected rejection after that retry/fallback path becomes reachable.
The focused test and adjacent classifier/no-downgrade tests pass; npm run check passes; the aggregate harness locally reached and passed the new group, and all hosted aggregate/check jobs are green. The branch is ahead 1 / behind 0 against main.
No actionable findings.
This review is AI-generated by Codex.
What this changes
Replaces the hand-copied 402 control-flow assertion with a deterministic integration test that drives real
status: 402errors through advisor, council, scope, and loopbreak. Each case asserts a terminal throw, exactly one stronger-class attempt, an untouched same-class retry and cheaper fallback, and no unavailable-class or continuation warning. The test is registered in the aggregate Vinci harness.The test also accepts
VINCI_TEST_402_CONSUMER=advisor|council|scope|loopbreakso mutation testing can prove every real consumer fails independently when account errors are misclassified.Why
Fixes #40. The classifier was pinned, but none of its escalation consumers were; a consumer could silently reintroduce downgrade-on-billing-error while the existing copied test stayed green.
Layer
vinci/- the Vinci layerpackages/**/vinci-*.ts- a Vinci change inside an upstream packagepackages/- this probably belongs upstream, see CONTRIBUTING.mdExact successor
main:6e19f1418718e9e33fdfa2d0d6c03054c5768470240ddebe1948b82772e5b70f199e8e53ce557ce0159eff82ed9fae10ac3627c1df6347bf1790401b369804e144232a58dff8c594c991a636425ce9e2e948eb8ead6ea5bbeb7f356196f14dd29557c837, currentmain6e19f1418718e9e33fdfa2d0d6c03054c5768470The successor differs from
mainin exactly two declared paths:vinci/test/402-escalation-no-downgrade.mjsvinci/test/run.shThere was no overlap between changes added to
mainsince the original PR base and either PR path, the classifier, or the four consumer extensions.Checks
npm run checkis clean - errors, warnings and infos alike./test.shpasses (not applicable: this is a Vinci-harness-only test change)## [Unreleased]entry (not applicable: test-only, no product behavior changed)package-lock.jsonchangesFocused Node 22 checks passed on the exact successor:
node vinci/test/402-escalation-no-downgrade.mjsnode vinci/test/402-classification-integration.mjsnode vinci/test/no-downgrade-integration.mjsVINCI_TEST_402_CONSUMERselectionsMutation verification: changing the classifier's account result to
transientmade every selected consumer independently exit 1 with its ownMissing expected rejectionassertion (advisor-in-flight,council-in-flight,scope-in-flight, andloopbreak-in-flight). Separately replacing each consumer's preserved cause with a new error carrying the same message andstatus: 402made every selected consumer independently fail the strict cause-identity assertion. Restoring production sources made the complete and individually selected matrices pass. No production mutation remains.The supported local Node 22 offline harness passed all groups through 365/365 units, worker suites, containment broker 42/42, package first-party 30/30, loopbreak 84/84, scope 83/83, unattended 96/96, shell 33/33, coding-agent 101/101, Crew 184/184, resultbudget 15/15, and the first UI suite 33/33. The final 23-case UI group stopped emitting progress on this macOS host and was interrupted after 254 seconds; the harness then completed its native PTY check successfully and exited nonzero only for the interrupted UI group. Fresh exact-head hosted Node 22/24 lanes remain the authoritative full-harness gate. An earlier
npx --package nodewrapper run is not counted because it contaminated nested npm execution; rerunning directly with the cached Node 22 binary made package first-party pass 30/30.Packaging evidence:
0.0.51was created.vinci workerreached its usage refusal; packaged CLI reported0.0.51.Fresh exact-head hosted checks are all green:
33890967535:checkjob101082244752,offline (22)job101082244616,upstream-suitejob101082244278,sandbox-macosjob101082244680, andoffline (24)job101082244851.33890967341:build-check-testjob101082244590.Required final review: GO for exact head
240ddebe1948b82772e5b70f199e8e53ce557ce0/ tree159eff82ed9fae10ac3627c1df6347bf1790401b, with no actionable findings. The reviewer independently reproduced the cause-identity mutation failure and the restored positive path.Anything reviewers should know
The provider stub throws the original error object with
status: 402, and the assertion checks that the terminal wrapper retains that error as its cause. Two 402 variants run through all four consumers. A second same-class 402 and a successful cheaper response remain queued as tripwires, proving neither retry nor downgrade occurs.No billing policy or runtime code changed. Outbox, CFT, provider/model, GPU, and Sentinel boundaries are unchanged.