test(rate): pin the shared scorer's check order #250
No reviewers
Labels
No labels
move-to-repo
coilyco-bridge-deploy
move-to-repo
coilyco-flight-deck-agent-compose
move-to-repo
coilyco-gaming-eco-app
move-to-repo
coilysiren-inbox
move-to-repo
unknown
🔒⚠️📦⚠️🔒 SANDBOXED 🔒⚠️📦⚠️🔒
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
c#
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-gaming/sirens-echo!250
Loading…
Reference in a new issue
No description provided.
Delete branch "test/score-order"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Tests only, no behavior change. Follows
b128603.Why
b128603extractedScoreEvaluationCaseso the rate runner and the gate share one set of checks. That is the right call for the reason the commit gives — a second checking system would drift, and the rate would then measure something the gate does not enforce.I verified the extraction is faithful: same checks, same order, same error strings, and the only semantic change (returning the raw content when
ParseReplyfails) is discarded by the gate and needed by the rate runner.But the refactor changed what the check order is worth. Inline in
runEvaluation, the order only decided which message a failing gate printed. Shared, it decides two things:Swap two checks and both runners keep working, stay green, and quietly attribute failures to the wrong cause. A rate is evidence, and evidence attributed to the wrong check is worse than no rate — it is the "measuring something other than what you think" failure that motivated sharing the scorer in the first place.
Nothing referenced
ScoreEvaluationCasefrom a test. The gate's tests cover it indirectly, as the commit says, but indirect coverage does not pin order.What this adds
internal/community/scoreorder_test.go:…KeepsGateCheckOrder— five precedence boundaries: parse before all, grounding before identity, identity before style, forbidden-phrase last. Each probe reply trips more than one check, so only precedence can explain the result.…AcceptsACleanReply— the control. Without it every precedence assertion would pass against a scorer that rejects everything.…ReturnsTheReplyItRejected— the contract the rate runner depends on: a rejected reply is still returned so it can be persisted verbatim, including the raw content when parsing is what failed.That last one matters because
b128603persists every reply on purpose — three first-pass findings in the source QA were defects in the check rather than in the agent, and only the text separated them.Verified by mutation
Swapped
ValidateGroundingandValidateIdentityClaim:Caught by the intended assertion.
go vet,gofmt, fullgo test ./..., andpre-commit run --filesall clean.Separately, on the harness itself
I checked
rate-deepagainst the five properties I asked for on the issue. It meets them, and adds three I did not ask for and should have — errors excluded from the denominator, replies persisted verbatim, and the gate's checks reused rather than reimplemented.I confirmed the "never fails the build" property specifically:
ci.ymlnever invokes it and.ward/ward.yamlmarks it "Gates nothing." The verdict can fail, but only for someone who invoked the verb deliberately, which is correct for a measurement run.Quail (QA)