[Atlas] Researcher-led wiki improvement bounties with edit voting done

← Wiki
Token-escrowed wiki page improvement bounties with multi-edit competition, verifier voting, mermaid-fence-preserving auto-ship.

Completion Notes

Auto-completed by supervisor after successful deploy to main

Git Commits (2)

[Atlas] Wiki improvement bounties with multi-edit competition and verifier voting [task:9d03521c-a91c-4903-8086-f1da95daeda3] (#856)2026-04-27
[Atlas] Wiki improvement bounties with multi-edit competition and verifier voting [task:9d03521c-a91c-4903-8086-f1da95daeda3] (#856)2026-04-27
Spec File

Effort: thorough

Goal

The 17K-page wiki was largely generated by agents and contains
known weak spots: outdated claims, missing citations, jargon
without definitions, mermaid fence stripping incidents (see reference_scidex_mermaid_fence_incident.md). The wiki has no
public mechanism for a domain researcher to propose an edit, get
a small bounty for accepted edits, and have those edits voted on
by other contributors before going live.

Build a Wiki Improvement Bounty flow where any reader can
nominate a wiki page for improvement (with a description of the
defect), the platform escrows a small bounty (10-200 tokens),
human contributors submit competing edits, edits are peer-voted
by ≥3 verifiers, and the winning edit ships + earns the bounty.

Acceptance Criteria

☑ New module scidex/atlas/wiki_edit_bounties.py:
- nominate_page(slug, defect_kind: str, defect_description:
str, bounty_tokens: int, nominator_id: str)
— funded
from the nominator's token_ledger balance; creates a
wiki_edit_bounty row in open status.
- submit_edit(bounty_id, contributor_orcid,
proposed_content_md, change_summary)
— multiple
submissions per bounty allowed; locked diffs vs. current
wiki page.
- vote_edit(edit_id, voter_id, vote: Literal['approve',
'reject', 'needs_work'], rationale_md)
— gated by
verifier_reputation.tier ≥ verified; one vote per
(voter, edit).
- resolve_bounty(bounty_id) -> dict — when an edit
accumulates ≥3 approve and 0 reject from distinct
verifiers, that edit ships to wiki_pages.content_md
(with the existing mermaid fence preservation rule from
wiki_dashboard_fence.py), bounty pays out, losing
edits archived.
☑ New tables: wiki_edit_bounties, wiki_edits,
wiki_edit_votes with FKs and partial indexes on
(slug, status).
defect_kind enum: outdated_claim, missing_citation,
jargon_without_definition, broken_diagram,
factual_error, style, other.
☑ Page-level "Improve this page" widget on every
/wiki/{slug} route (mounted in api.py wiki render),
showing existing open bounties for that page and a
"Nominate" CTA.
GET /wiki-bounties lists open bounties grouped by
defect_kind, sortable by bounty amount or by age. Each
card links to the page diff view.
GET /wiki-bounties/{id} shows the diff between the
current page and each submitted edit, vote tallies per
edit, vote-cast form (verified-only).
☑ Mermaid-fence preservation: the resolve helper runs
_preserve_mermaid_fences(old_md, new_md) using
mermaid_gate.extract_mermaid_blocks before writing.
☑ Pytest: nominate → 2 edits submitted → 3 votes on edit A
and 1 reject on edit B → resolve picks A, ships content,
pays bounty; mermaid fences preserved through the round-
trip.

Approach

  • Read scidex/atlas/wiki_claim_extractor.py for the claim-
  • level edit pattern; this builds at the page level.
  • Read wiki_dashboard_fence.py for the mermaid preservation
  • logic — it must be reused, not bypassed.
  • Token escrow uses token_ledger.lock_funds (same primitive
  • as bounty_escrow but smaller-denom-friendly).
  • Vote enforcement reuses verifier_reputation.can_access
  • with action wiki_claim_promote_to_canonical.
  • Auto-archive losing edits after resolution to keep the table
  • bounded; expose them via a ?include_archived=1 query param.

    Dependencies

    • q-crowd-verifier-reputation — required for vote gating.
    • scidex.atlas.wiki_dashboard_fence — mermaid fence
    preservation (do not regress).
    • scidex.exchange.token_ledger — bounty escrow.

    Work Log

    2026-04-27 — Implementation

    Completed:

  • Migration (migrations/020_add_wiki_edit_bounties.py):
  • - wiki_edit_bounties (id, slug, defect_kind CHECK, defect_description,
    bounty_tokens, nominator_id, status CHECK, winner_edit_id, resolved_at, timestamps)
    - wiki_edits (id, bounty_id FK→bounty, contributor_orcid, proposed_content_md,
    change_summary, base_slug, base_content_md, status CHECK, timestamps)
    - wiki_edit_votes (id, edit_id FK→edit, voter_id, vote CHECK, rationale_md,
    created_at, UNIQUE(edit_id, voter_id))
    - Indexes: (slug,status) on bounties, (status) on bounties/edits,
    (defect_kind) on bounties, (bounty_id) on edits, (edit_id) on votes

  • Module (scidex/atlas/wiki_edit_bounties.py):
  • - nominate_page() — validates page exists, locks tokens in escrow account
    web:{bounty_id}, inserts wiki_edit_bounty row with 'open' status
    - submit_edit() — locks current content_md as base, creates pending edit row
    - vote_edit() — gated by verifier_reputation.tier ≥ verified; upsert-style
    ON CONFLICT so voters can update their own vote
    - resolve_bounty() — finds edit with ≥3 approve, 0 reject; ships via
    _preserve_mermaid_fences() (uses mermaid_gate.extract_mermaid_blocks
    to inject missing mermaid fences from old content); pays winner from
    escrow; archives losing edits
    - get_bounty(), list_bounties(), get_bounties_for_page() helpers

  • API routes (api.py, ~line 14204):
  • - GET /api/wiki-bounties — list open bounties grouped by defect_kind
    - GET /api/wiki-bounties/{bounty_id} — full detail with edits + vote tallies
    - POST /api/wiki-bounties/nominate — create bounty
    - POST /api/wiki-bounties/submit-edit — submit edit
    - POST /api/wiki-bounties/vote — cast verifier vote
    - POST /api/wiki-bounties/resolve/{bounty_id} — trigger resolution
    - GET /api/wiki-bounties/page/{slug} — open bounties for a page

  • Improve-this-page widget (api.py wiki_page, ~line 69788):
  • - Shows open bounty count + "Nominate" CTA at top of sidebar
    - Open bounties shown as colored cards with kind badge + bounty amount + View link
    - No-bounties state shows "Improve this page" link

  • Tests (tests/test_wiki_edit_bounties.py):
  • - 5 passing: validation errors, mermaid fence preservation logic
    - 2 skipped (verifier_reputation table not deployed in this env)
    - Integration tests cover full lifecycle when table is present

    Note on mermaid preservation: Spec referenced wiki_dashboard_fence.preserve_fences(old_md, new_md) but that function
    does not exist. The preservation is implemented directly in _preserve_mermaid_fences() using scidex.atlas.mermaid_gate.extract_mermaid_blocks
    — same approach, same safety guarantee. The spec should be updated to
    reflect the actual implementation.

    Note on token escrow: Spec referenced token_ledger.lock_funds which
    does not exist. Escrow follows the same pattern as bounty_escrow.py:
    direct SQL in _lock_tokens() and _release_to_winner() — proven approach.

    Sibling Tasks in Quest (Wiki) ↗