⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
src/queue-intelligence.ts:242-244 documents sanitizePublicComment's escape hatch:
EXPLICIT-PHRASE entries in FORBIDDEN_PUBLIC_COMMENT_WORDS ("trust score", "reward", "scoreability", ...)
are NEVER skippable by this flag -- those name the actual private concept regardless of repo, so they stay
enforced everywhere; only the over-broad bare-word check is ever relaxed
The code does the opposite — :253: const forbidden = options?.allowBareScoreTerm ? ALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDS : FORBIDDEN_PUBLIC_COMMENT_WORDS;
"reward" and "rewards" are members of AMBIGUOUS_PUBLIC_COMMENT_WORDS (:58-59), not ALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDS. So sanitizePublicComment("12 TAO reward for this", { allowBareScoreTerm: true }) returns the string unchanged instead of throwing. The flag is live in production: src/services/ai-review.ts:3324 sets it for any repo in LOOPOVER_PUBLIC_SCORE_TERMS_ALLOWED_REPOS. The doc's second claim — "only the over-broad bare-word check is ever relaxed" — is also false: the whole 7-word ambiguous tier is relaxed.
The file already contains the correct, newer description of this behaviour in the #9432 block at :248-252. The older JSDoc immediately above it was never updated, so sanitizePublicComment now carries two contradictory contracts, and the wrong one is the one that reads as a safety guarantee.
Two further factual errors in the same paragraph, both about what BARE_SCORE_TERM_PATTERN = /\bscore\w*\b/i (:115) actually matches:
:217-218 claims the pattern catches "scoring". It cannot — "scoring" contains no score substring. The file itself states this correctly 100 lines earlier, at :112-114.
:241-243 cites metagraphed's totalScore / baseTotalScore / credibility field names as the motivating example. /\bscore\w*\b/i.test("totalScore") is false (no word boundary between l and S), and credibility appears in no list.
Requirements
- Rewrite the JSDoc block at
src/queue-intelligence.ts:210-247 so every claim is true of the code as written:
- State that
allowBareScoreTerm swaps FORBIDDEN_PUBLIC_COMMENT_WORDS for ALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDS, i.e. it relaxes the entire AMBIGUOUS_PUBLIC_COMMENT_WORDS tier, and refer to that tier by its constant name rather than listing words inline.
- Remove the false "reward ... NEVER skippable" claim and the false "only the over-broad bare-word check is ever relaxed" claim.
- Remove
"scoring" from the list of words the bare pattern catches, and remove or correct the totalScore/baseTotalScore/credibility motivating example so it names strings the pattern actually matches.
- Decide the behaviour question the doc raises, in favour of the doc's safety intent, and implement it: move
"reward" and "rewards" from AMBIGUOUS_PUBLIC_COMMENT_WORDS to ALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDS, so a bare reward is rejected on every repo including allowlisted ones. Compound phrases already in the always-forbidden tier are unaffected.
- Add an invariant test pinning the two tiers against the JSDoc's claims, so the doc and the constants cannot drift again: assert
ALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDS contains every word the doc names as never-skippable, and that the two tiers are disjoint.
- No change to
BARE_SCORE_TERM_PATTERN, to isPublicScoreTermSafeForRepo, or to the allowlist env var.
⚠️ Required pattern: the #9432 block already at src/queue-intelligence.ts:248-252 is the accurate description — the rewritten JSDoc must agree with it, and the two blocks must not restate the same thing twice. The tier-pinning invariant test should follow the source-pinned drift-guard convention in test/unit/advisory-spend-gate.test.ts:49-71. It does NOT satisfy this issue to fix only the comment and leave reward relaxable on allowlisted repos; to move reward to the always-forbidden tier without correcting the three false statements in the JSDoc; or to add a third word list.
Deliverables
All Deliverables above are required in a single PR. A PR that satisfies only some of them — for example correcting the comment without moving reward/rewards to the always-forbidden tier — does not resolve this issue.
Test Coverage Requirements
99%+ Codecov patch coverage, branch-counted, on src/**; src/queue-intelligence.ts is inside coverage.include. Both arms of the allowBareScoreTerm ternary at :253 must be exercised against a reward-bearing string and a bare-score string, so all four flag-by-word combinations are covered.
Expected Outcome
A repo on the public-score-terms allowlist can no longer have a bare reward reach a public GitHub comment, and the function's JSDoc describes what the code does rather than a stronger guarantee it never provided. The word-tier invariant test makes the next divergence a CI failure.
Links & Resources
src/queue-intelligence.ts:55-62, :110-118, :210-260; src/services/ai-review.ts:3324; test/unit/advisory-spend-gate.test.ts:49-71.
Context
src/queue-intelligence.ts:242-244documentssanitizePublicComment's escape hatch:The code does the opposite —
:253:const forbidden = options?.allowBareScoreTerm ? ALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDS : FORBIDDEN_PUBLIC_COMMENT_WORDS;"reward"and"rewards"are members ofAMBIGUOUS_PUBLIC_COMMENT_WORDS(:58-59), notALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDS. SosanitizePublicComment("12 TAO reward for this", { allowBareScoreTerm: true })returns the string unchanged instead of throwing. The flag is live in production:src/services/ai-review.ts:3324sets it for any repo inLOOPOVER_PUBLIC_SCORE_TERMS_ALLOWED_REPOS. The doc's second claim — "only the over-broad bare-word check is ever relaxed" — is also false: the whole 7-word ambiguous tier is relaxed.The file already contains the correct, newer description of this behaviour in the
#9432block at:248-252. The older JSDoc immediately above it was never updated, sosanitizePublicCommentnow carries two contradictory contracts, and the wrong one is the one that reads as a safety guarantee.Two further factual errors in the same paragraph, both about what
BARE_SCORE_TERM_PATTERN = /\bscore\w*\b/i(:115) actually matches::217-218claims the pattern catches"scoring". It cannot —"scoring"contains noscoresubstring. The file itself states this correctly 100 lines earlier, at:112-114.:241-243cites metagraphed'stotalScore/baseTotalScore/credibilityfield names as the motivating example./\bscore\w*\b/i.test("totalScore")isfalse(no word boundary betweenlandS), andcredibilityappears in no list.Requirements
src/queue-intelligence.ts:210-247so every claim is true of the code as written:allowBareScoreTermswapsFORBIDDEN_PUBLIC_COMMENT_WORDSforALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDS, i.e. it relaxes the entireAMBIGUOUS_PUBLIC_COMMENT_WORDStier, and refer to that tier by its constant name rather than listing words inline."scoring"from the list of words the bare pattern catches, and remove or correct thetotalScore/baseTotalScore/credibilitymotivating example so it names strings the pattern actually matches."reward"and"rewards"fromAMBIGUOUS_PUBLIC_COMMENT_WORDStoALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDS, so a barerewardis rejected on every repo including allowlisted ones. Compound phrases already in the always-forbidden tier are unaffected.ALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDScontains every word the doc names as never-skippable, and that the two tiers are disjoint.BARE_SCORE_TERM_PATTERN, toisPublicScoreTermSafeForRepo, or to the allowlist env var.Deliverables
sanitizePublicComment("12 TAO reward for this", { allowBareScoreTerm: true })throws — asserted by a named regression test citing the doc/code contradiction.sanitizePublicComment("this scores well", { allowBareScoreTerm: true })still does not throw (the intended relaxation is preserved) — asserted.sanitizePublicComment("12 TAO reward for this")(flag off) still throws — asserted, so the fix is not a behaviour swap.ALWAYS_FORBIDDEN_PUBLIC_COMMENT_WORDSandAMBIGUOUS_PUBLIC_COMMENT_WORDSare disjoint, and every word the JSDoc names as never-skippable is in the always-forbidden tier.src/queue-intelligence.ts:210-247no longer contains the string"scoring"as a claimed match, no longer namestotalScore/baseTotalScore/credibilityas caught by the bare pattern, and no longer claims the ambiguous tier is enforced under the flag.All Deliverables above are required in a single PR. A PR that satisfies only some of them — for example correcting the comment without moving
reward/rewardsto the always-forbidden tier — does not resolve this issue.Test Coverage Requirements
99%+ Codecov patch coverage, branch-counted, on
src/**;src/queue-intelligence.tsis insidecoverage.include. Both arms of theallowBareScoreTermternary at:253must be exercised against areward-bearing string and a bare-scorestring, so all four flag-by-word combinations are covered.Expected Outcome
A repo on the public-score-terms allowlist can no longer have a bare
rewardreach a public GitHub comment, and the function's JSDoc describes what the code does rather than a stronger guarantee it never provided. The word-tier invariant test makes the next divergence a CI failure.Links & Resources
src/queue-intelligence.ts:55-62,:110-118,:210-260;src/services/ai-review.ts:3324;test/unit/advisory-spend-gate.test.ts:49-71.