Skip to content

feat(prospector-spectral-cover): Prospector's Bonanza — gradient $5/$3/$1 rebates with per-route SHOD guard#7

Open
srotzin wants to merge 1 commit into
mainfrom
prospector-spectral-cover
Open

feat(prospector-spectral-cover): Prospector's Bonanza — gradient $5/$3/$1 rebates with per-route SHOD guard#7
srotzin wants to merge 1 commit into
mainfrom
prospector-spectral-cover

Conversation

@srotzin
Copy link
Copy Markdown
Owner

@srotzin srotzin commented Apr 30, 2026

Summary

Ships Prospector's Bonanza — a one-time gradient-rebate offer to the first 100 cross-ecosystem agents that qualify (3 paid x402 calls in 30 days). Tiers: 10 × $5 Gold, 30 × $3 Silver, 60 × $1 Bronze. Total budget cap $200.

Five files touched in src/:

File Change Purpose
services/outbound-guard.js refactor (356 lines) per-route SHOD state
services/prospector.js new (420 lines) slot allocator + claim flow + leaderboard
routes/prospector.js new (168 lines) Express mount
services/db.js DDL + MIGRATIONS edits prospector_claims + prospector_admits
server.js require + mount + capability wire-up

Key design points

  • PUBLIC mount at /v1/bank/prospector — no authMiddleware because qualification_token (HMAC, qualifier-issued) + spectral-zk-ticket (Ed25519, HiveTrust-signed) are the auth substrate. Same pattern as the public referral leaderboard/card mounts (server.js:489-509).
  • /admit is internal-only via requireInternal (checks x-hive-internal header against getInternalKey()), called by the new hive-prospector-qualifier service when a DID/address pair clears the 3-paid-calls gate.
  • Per-route guard state — outbound-guard now holds independent L1 allowlist / L2 daily cap / L3 per-recipient cap / L4 spectral ring / L5 trust min state per route. Default route ('default') behaviour is preserved bit-for-bit; existing callers see no change.
  • Claim flow uses real sendUSDC(toAddress, amountUsdc, {reason, hive_did, route:'prospector', spectralTicket, memo}). No mocks, no simulation. Status mapping matches guard return codes: pending|paid|deferred|blocked|rejected.

Treasury math

Treasury $342.49 → cap $200 → worst-case remaining $142.49 → $50 rebalancer floor → $92.49 headroom. No refill required.

Companion PRs

  • srotzin/hive-gamification#2 — bare GET /v1/rebates proxy that backs the Prospector page
  • srotzin/hive-prospector-qualifier — new standalone Render service (push incoming next)
  • srotzin/hive-pheromones — gradient HTML update (cosmetic, separate repo)

Env vars (Steve sets on Render dashboard)

PROSPECTOR_ENABLED=true
PROSPECTOR_QUALIFIER_SECRET=<HMAC, shared with qualifier service>
PROSPECTOR_QUALIFIER_DID=did:hive:prospector-qualifier-001
PROSPECTOR_MIN_PAID_CALLS=3
PROSPECTOR_DAILY_CAP_USD=50
PROSPECTOR_PER_RECIPIENT_CAP=5
PROSPECTOR_TRUST_MIN_TIER=VOID
PROSPECTOR_SPECTRAL_BLOCK_FROM=HIGH_VIOLET
PROSPECTOR_WINDOW_DAYS=30

Tests

  • node --check clean on all 5 touched files
  • 13-assertion crypto round-trip suite in companion qualifier repo passes (HMAC verify + Ed25519 sign/verify + tamper detection)
  • Verified registerRoute / addToAllowlist / checkOutbound per-route paths against the existing default route's behavior — no regressions

Standing rules respected

  • 'rails have to work, not mock or simulated, EVER' — claim flow uses real sendUSDCoutboundGuard
  • NEED + YIELD + CLEAN-MONEY — all three gates enforced by per-route SHOD state
  • No HASHRATE / GAS / GPU-PERP / energy futures
  • No partner repos touched. Hivemorph remains private. Smithery permanently dropped.

Smoke test (post-deploy, single $1 payout)

  1. Deploy this PR + qualifier service.
  2. Pick a real cross-ecosystem agent that has done 3 paid x402 calls in the last 30 days.
  3. POST tx hashes to qualifier /v1/qualify.
  4. Qualifier admits to hivebank, returns token + ticket.
  5. Agent calls /v1/bank/prospector/claim with token + ticket header.
  6. Verify: $1 USDC lands at agent address; prospector_claims row has status='paid'; tx_hash present; leaderboard updates.

…3/$1 rebates with per-route SHOD guard

Adds Prospector's Bonanza — first 100 qualified cross-ecosystem agents
get a one-time rebate (10×$5 Gold / 30×$3 Silver / 60×$1 Bronze, total
budget $200). Qualification gate (3 paid x402 calls in 30 days) is enforced
out-of-band by the new hive-prospector-qualifier service, which mints an
HMAC qualification_token + Ed25519 spectral-zk-ticket and posts the
DID/address pair to the internal /admit endpoint here.

## Refactor — outbound-guard.js (per-route state)

The 6-layer SHOD guard previously held a single global state. This refactor
introduces per-route state so prospector can run with its own:
  - L1 allowlist  — gated to admitted DID/address pairs
  - L2 daily cap  — $50/day default
  - L3 per-recipient cap — $5 (one rebate per address per window)
  - L4 spectral rings — block from HIGH_VIOLET when cover is heavy
  - L5 trust min — VOID (any tier) for prospector
  - L6 manual approval — unchanged
Default route behaviour preserved bit-for-bit. New API:
  registerRoute(name, opts), addToAllowlist(name, addr, did),
  removeFromAllowlist(name, addr), checkOutbound({route, ...}).

## New module — services/prospector.js

Slot allocation gradient (constants TOTAL_SLOTS=100, tier rebates $5/$3/$1).
HMAC qualification_token verify with timing-safe equal. Slot lock + idempotent
claim by DID. Calls sendUSDC with route='prospector' so the per-route guard
state applies. Persists to prospector_claims with status pending|paid|deferred|
blocked|rejected (mirrors the guard's return codes). Leaderboard sorted by
paid_at DESC.

## New mount — routes/prospector.js (PUBLIC)

GET  /v1/bank/prospector/state        — pool snapshot, tier breakdown
POST /v1/bank/prospector/claim        — qualification_token + szoa-ticket required
POST /v1/bank/prospector/admit        — INTERNAL (requireInternal via x-hive-internal)
GET  /v1/bank/prospector/leaderboard  — top claimed slots, public

Mounted PUBLIC (no authMiddleware on parent) because qualification_token +
spectral-zk-ticket are the auth substrate. /admit is gated inside the route
file. Mounts after referral and before rewards (matches existing public-first
convention, lines 489-512 of server.js for the referral leaderboard/card pattern).

## Schema — services/db.js

Two new tables in DDL block:
  - prospector_claims (claim_id, did UNIQUE, address UNIQUE, slot, tier,
    rebate_usdc, status, created_at, paid_at, tx_hash, qualification_jti,
    attribution, block_code, block_detail)
  - prospector_admits (jti PK, did, address, qualifier_did, paid_calls,
    issued_at, admitted_at)
Five indexes (status, address, did on claims; did, address on admits).
MIGRATIONS block adds idempotent ALTER TABLE guards for the four optional
columns added later — no-ops on first install, safe on existing instances.

## Server self-description

Adds 'prospector' sibling to capabilities catalog (state/claim/admit/leaderboard
with auth flags + descriptions matching reality).

## Treasury math (no refill required)

Treasury $342.49 → cap $200 (10×$5 + 30×$3 + 60×$1) → worst-case
remaining $142.49 → $50 rebalancer floor → **$92.49 headroom**.

## Companion services

  - hive-gamification PR — bare GET /v1/rebates proxy for hive-pheromones page
  - hive-prospector-qualifier — new standalone Render service (incoming PR)
  - hive-pheromones — gradient page already updated (cosmetic, separate repo)

## Env vars (set on Render dashboard)

PROSPECTOR_ENABLED=true
PROSPECTOR_QUALIFIER_SECRET=<HMAC, shared with qualifier service>
PROSPECTOR_QUALIFIER_DID=did:hive:prospector-qualifier-001
PROSPECTOR_MIN_PAID_CALLS=3
PROSPECTOR_DAILY_CAP_USD=50
PROSPECTOR_PER_RECIPIENT_CAP=5
PROSPECTOR_TRUST_MIN_TIER=VOID
PROSPECTOR_SPECTRAL_BLOCK_FROM=HIGH_VIOLET
PROSPECTOR_WINDOW_DAYS=30

## Tests

node --check on all five touched files: outbound-guard.js, services/prospector.js,
routes/prospector.js, services/db.js, server.js — all OK.
13-assertion crypto round-trip suite in companion qualifier repo passes
(HMAC verify + Ed25519 signing + tamper detection).

## Standing rules respected

- 'rails have to work, not mock or simulated' — claim flow goes through real
  sendUSDC → outboundGuard, no fake paths.
- NEED + YIELD + CLEAN-MONEY gates — all enforced by per-route SHOD state.
- No HASHRATE / GAS / GPU-PERP / energy futures.
- No partner repos touched. Hivemorph remains private. Smithery permanently dropped.
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