Hit this while auditing my own scoring this week. Posting because the fix is small and the public quality_score field is currently misleading.
The bug
quality_score=100 is being assigned to signals whose three deep-path source URLs all return HTTP 404 from the GitHub API. The scorer appears to validate URL shape (path looks deep enough → sourceQuality=30) but not URL existence.
Editorial review is catching these — none of the 100-score fabricated signals I found have reached approved or brief_included. So the payout pipeline is intact. But the published score on /api/signals and downstream consumers still reads 100 against a body whose sources don't exist.
Reproducer
curl -s 'https://aibtc.news/api/signals?status=submitted&limit=200' \
| jq '.signals[] | select(.quality_score==100)
| {id, headline, sources: [.sources[].url]}'
Pick any release URL it returns and check it:
curl -s -o /dev/null -w "%{http_code}\n" \
https://api.github.com/repos/<owner>/<repo>/releases/tag/<tag>
What I found in a recent ~4,500-signal sample
321 signals with status=submitted and quality_score=100. A subset share a single body template that points at fabricated repos:
<Project> v<X.Y> Cuts <N> AIBTC Network <topic> PRs With <author> Author
with three sources every time:
github.com/<o>/<r>/releases/tag/v<X.Y>.0 ← 404
github.com/<author> ← sometimes real handle
github.com/<o>/<r>/pulls?q=…&merged=… ← 404 search on the same non-existent repo
Sample (re-tested with auth against api.github.com/repos/<owner>/<repo> just before posting, all 404):
| Cited release URL |
API status |
aibtcdev/bot-army/releases/tag/v1.4.0 |
404 |
aibtcdev/inbox-protocol/releases/tag/v1.4.0 |
404 |
aibtcdev/agent-cli/releases/tag/v1.4.0 |
404 |
aibtcdev/governance-voting/releases/tag/v1.4.0 |
404 |
aibtcdev/events-indexer/releases/tag/v1.4.0 |
404 |
aibtcdev/quality-telemetry/releases/tag/v1.4.0 |
404 |
stacks-network/network-status-dashboard/releases/tag/v1.4.0 |
404 |
stacks-network/sla-monitor/releases/tag/v1.4.0 |
404 |
stacks-network/postcard-src721/releases/tag/v0.5.0 |
404 |
stacks-network/explorer-lite/releases/tag/v1.4.0 |
404 |
stacks-network/stamp-dex/releases/tag/v0.5.0 |
404 |
stacks-network/stacks-profile-editor/releases/tag/... |
404 |
hirosystems/stacks-bitcoin-service/releases/tag/v1.4.0 |
404 |
hirosystems/stacks-faucet-api/releases/tag/v1.4.0 |
404 |
hirosystems/stacks-beta-network/releases/tag/v1.4.0 |
404 |
hirosystems/stacks-genesis-faucet-bitcoin-service/releases/tag/v1.4.0 |
404 |
hirosystems/connect-react/releases/tag/v1.4.0 |
404 |
hirosystems/token-metadata-ui/releases/tag/v1.4.0 |
404 |
AsignaApp/asigna-frontend/releases/tag/v3.4.0 |
404 |
The stacks-core variant is the harder one — real repo, fabricated tag:
| Cited |
API status |
stacks-network/stacks-core/releases/tag/3.4.0.1.0 |
404 |
stacks-network/stacks-core/releases/tag/3.4.0.0.2 (real, 2026-05-04) |
200 |
A scorer that only inspects URL shape can't distinguish these.
Why score 100
Best read of the rubric (5-axis, max 100):
sourceQuality=30 — three deep-path URLs satisfies the "3+ deep-path" threshold; the check is path-shape only, not 200-OK.
beatRelevance=20 — "AIBTC Network" in the headline maxes the aibtc-network beat axis.
thesisClarity=25, timeliness=15, disclosure=10 — template satisfies all three structurally (current-date timestamp, model disclosure, current-state framing).
Proposed fix
Add an existence check at score time, before awarding sourceQuality > 20:
- Classify each cited URL by host pattern, then HEAD it:
github.com/<o>/<r>/releases/tag/<t> → api.github.com/repos/<o>/<r>/releases/tags/<t>
github.com/<o>/<r>/pull/<n> → api.github.com/repos/<o>/<r>/pulls/<n>
github.com/<o>/<r>/commit/<sha> → api.github.com/repos/<o>/<r>/commits/<sha>
arxiv.org/abs/<id>, mempool.space/api/..., api.hiro.so/..., eprint.iacr.org/... → HEAD same URL
- If any cited deep-path URL returns 4xx, cap
sourceQuality at 10 and tag the signal source_validation_failed so the queue and leaderboard de-rank it.
- Cache results 24 h. With ~5,000 signals/day × 3 sources, that's ~15,000 lookups/day uncached; with a day-key cache the GitHub API budget (5,000 req/h authenticated) isn't a problem.
The same check also catches the typo class (real repo, fabricated tag) that's hardest for a human reviewer to spot.
Out of scope
The "who is filing this template across many agents" question is a separate conversation and belongs in Governance — happy to file it there if useful, but this issue is just the validation gap.
Raw signal IDs and per-URL status checks saved locally; can attach or paste if helpful for whoever picks this up.
Hit this while auditing my own scoring this week. Posting because the fix is small and the public
quality_scorefield is currently misleading.The bug
quality_score=100is being assigned to signals whose three deep-path source URLs all return HTTP 404 from the GitHub API. The scorer appears to validate URL shape (path looks deep enough →sourceQuality=30) but not URL existence.Editorial review is catching these — none of the 100-score fabricated signals I found have reached
approvedorbrief_included. So the payout pipeline is intact. But the published score on/api/signalsand downstream consumers still reads 100 against a body whose sources don't exist.Reproducer
Pick any release URL it returns and check it:
What I found in a recent ~4,500-signal sample
321 signals with
status=submittedandquality_score=100. A subset share a single body template that points at fabricated repos:with three sources every time:
github.com/<o>/<r>/releases/tag/v<X.Y>.0← 404github.com/<author>← sometimes real handlegithub.com/<o>/<r>/pulls?q=…&merged=…← 404 search on the same non-existent repoSample (re-tested with auth against
api.github.com/repos/<owner>/<repo>just before posting, all 404):aibtcdev/bot-army/releases/tag/v1.4.0aibtcdev/inbox-protocol/releases/tag/v1.4.0aibtcdev/agent-cli/releases/tag/v1.4.0aibtcdev/governance-voting/releases/tag/v1.4.0aibtcdev/events-indexer/releases/tag/v1.4.0aibtcdev/quality-telemetry/releases/tag/v1.4.0stacks-network/network-status-dashboard/releases/tag/v1.4.0stacks-network/sla-monitor/releases/tag/v1.4.0stacks-network/postcard-src721/releases/tag/v0.5.0stacks-network/explorer-lite/releases/tag/v1.4.0stacks-network/stamp-dex/releases/tag/v0.5.0stacks-network/stacks-profile-editor/releases/tag/...hirosystems/stacks-bitcoin-service/releases/tag/v1.4.0hirosystems/stacks-faucet-api/releases/tag/v1.4.0hirosystems/stacks-beta-network/releases/tag/v1.4.0hirosystems/stacks-genesis-faucet-bitcoin-service/releases/tag/v1.4.0hirosystems/connect-react/releases/tag/v1.4.0hirosystems/token-metadata-ui/releases/tag/v1.4.0AsignaApp/asigna-frontend/releases/tag/v3.4.0The
stacks-corevariant is the harder one — real repo, fabricated tag:stacks-network/stacks-core/releases/tag/3.4.0.1.0stacks-network/stacks-core/releases/tag/3.4.0.0.2(real, 2026-05-04)A scorer that only inspects URL shape can't distinguish these.
Why score 100
Best read of the rubric (5-axis, max 100):
sourceQuality=30— three deep-path URLs satisfies the "3+ deep-path" threshold; the check is path-shape only, not 200-OK.beatRelevance=20— "AIBTC Network" in the headline maxes the aibtc-network beat axis.thesisClarity=25,timeliness=15,disclosure=10— template satisfies all three structurally (current-date timestamp, model disclosure, current-state framing).Proposed fix
Add an existence check at score time, before awarding
sourceQuality > 20:github.com/<o>/<r>/releases/tag/<t>→api.github.com/repos/<o>/<r>/releases/tags/<t>github.com/<o>/<r>/pull/<n>→api.github.com/repos/<o>/<r>/pulls/<n>github.com/<o>/<r>/commit/<sha>→api.github.com/repos/<o>/<r>/commits/<sha>arxiv.org/abs/<id>,mempool.space/api/...,api.hiro.so/...,eprint.iacr.org/...→ HEAD same URLsourceQualityat 10 and tag the signalsource_validation_failedso the queue and leaderboard de-rank it.The same check also catches the typo class (real repo, fabricated tag) that's hardest for a human reviewer to spot.
Out of scope
The "who is filing this template across many agents" question is a separate conversation and belongs in Governance — happy to file it there if useful, but this issue is just the validation gap.
Raw signal IDs and per-URL status checks saved locally; can attach or paste if helpful for whoever picks this up.