Skip to content

Wish bridge: gate auto-issues on qualified demand, not raw count#437

Merged
MikeyPetrillo merged 2 commits into
mainfrom
claude/sweet-brown-i99jl3
Jul 18, 2026
Merged

Wish bridge: gate auto-issues on qualified demand, not raw count#437
MikeyPetrillo merged 2 commits into
mainfrom
claude/sweet-brown-i99jl3

Conversation

@MikeyPetrillo

Copy link
Copy Markdown
Owner

Problem

The wish-to-issue bridge opened a GitHub issue for any wish cluster reaching count 5, with no quality check. That gate is trivially gamed: a single script POSTing the same string 5 times mints an issue. On 2026-07-17 one source drove three clusters to 18-103 identical hits in a few hours ('synthora mesh', 'em spectrum intelligence', '962 m2m services'), each auto-opening a junk issue (now closed).

Fix

New clusterQualifies predicate in src/wish.js requires, on top of the count threshold, a sign of independent demand:

  • two or more distinct sources (api / mcp / find-miss), or
  • demand sustained past 24h (QUALIFY_MIN_SPAN_MS).

A genuine gap is hit by different agents across surfaces or recurs over days; a scripted burst is one source in one sitting and clears neither bar. Both observed synthora clusters (single-source, few-hour span) are now unqualified.

getWishesAggregate exposes a per-cluster qualified flag; the wish-issues workflow selects on .qualified == true instead of .count >= threshold. A cached pre-deploy response lacks the field, so the gate fails closed (opens nothing) during rollout.

Honest limit, stated in-code (same framing as the router's per-seller Sybil cap): a patient spammer can still drip over 24h or add a decoy hit on a second surface. This raises the cost from 5 curls to sustained-or-multi-surface; it is not full Sybil resistance. Every wish is still recorded and visible on /api/wishes regardless; only auto-issue creation is gated.

Tests

scripts/test-wish.js: clusterQualifies unit cases (below-threshold, single-source burst, both synthora shapes, two-source, span boundary) plus end-to-end through recordWish + getWishesAggregate. Aggregate-shape exact-keys test and the demand-radar consumer test updated for the additive field. Full suite 35/35 wish + 36/36 demand-radar green; workflow YAML validated and the jq gate simulated (qualified selected, both bursts skipped, missing-field fail-closed).

🤖 Generated with Claude Code

MikeyPetrillo and others added 2 commits July 17, 2026 13:54
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The wish-to-issue bridge opened a GitHub issue for any cluster reaching
count 5. That gate is trivially gamed: a single script POSTing the same
string 5 times mints an issue. Observed 2026-07-17: one source drove three
clusters to 18-103 identical hits in a few hours (synthora mesh / em
spectrum intelligence), each of which auto-opened a junk issue.

New clusterQualifies predicate (src/wish.js) requires, on top of the count
threshold, a sign of independent demand: either two or more distinct sources
(api / mcp / find-miss) or demand sustained past QUALIFY_MIN_SPAN_MS (24h).
A genuine gap is hit by different agents across surfaces or recurs over
days; a scripted burst is one source in one sitting and clears neither bar.
getWishesAggregate exposes a per-cluster qualified flag, and the wish-issues
workflow now selects on that flag instead of raw count. A cached pre-deploy
response lacks the field, so the gate fails closed and opens nothing.

Honest limit (same framing as the router's per-seller Sybil cap): a patient
spammer can still drip over 24h or add a decoy hit on a second surface. This
raises the cost from 5 curls to sustained-or-multi-surface; it is not full
Sybil resistance. The wish is always recorded and visible on /api/wishes
regardless; only auto-issue creation is gated.

Tests: clusterQualifies unit cases (below-threshold, single-source burst,
both synthora shapes, two-source, span boundary) plus end-to-end through
recordWish + getWishesAggregate. Aggregate-shape and demand-radar consumer
tests updated for the additive field.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MikeyPetrillo
MikeyPetrillo marked this pull request as ready for review July 18, 2026 01:45
@MikeyPetrillo
MikeyPetrillo merged commit 82eac89 into main Jul 18, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant