Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions scientific-bounty-appeals-ledger/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Scientific Bounty Appeals Ledger

This is a focused Scientific Bounty System module for SCIBASE issue #18. It handles the post-evaluation dispute layer: appeal eligibility, evidence-lock checks, reviewer conflict detection, response SLAs, payout holds, and IP transfer guards.

The slice is intentionally separate from challenge intake, rubric scoring, payout routing engines, and solver workspace privacy. It answers a narrower operational question: after a sponsor or solver contests a result, what must stay locked, who needs to respond, what money can be released, and what IP transfer must wait?

## What It Does

- Validates appeal windows, accepted reason categories, appellant roles, and known submissions.
- Verifies locked evidence snapshots cover contested submission artifacts.
- Flags reviewer conflicts, including sponsor-affiliated reviewers on contested submissions.
- Tracks reviewer response SLAs and escalation state.
- Holds awarded payout amounts while eligible appeals are open.
- Blocks IP transfer while payout is held by an eligible appeal.
- Builds a sponsor feedback packet, arbitration dashboard, audit trail, and stable digest.

## Files

- `src/appeals-ledger.js` - deterministic appeals ledger engine.
- `data/sample-appeals.json` - sample challenge with awards, reviewers, evidence snapshots, and appeals.
- `test/appeals-ledger.test.js` - dependency-free assertions for eligibility, evidence locks, conflicts, payout holds, IP guards, and stable digest behavior.
- `scripts/demo.js` - local CLI demo.
- `docs/requirement-map.md` - mapping to issue #18 requirements.
- `docs/demo.svg` and `docs/demo.mp4` - short visual demo artifacts.

## Run

```bash
npm run check
npm test
npm run demo
```

Expected demo output includes the challenge title, tracked appeal count, payout hold status, held amount, top action, IP guard count, and stable digest.

## Scope Notes

The implementation is dependency-free and credential-free. It models the trust and dispute workflow that sits after challenge evaluation and before payout/IP release, so it can be embedded into a broader bounty marketplace later.
153 changes: 153 additions & 0 deletions scientific-bounty-appeals-ledger/data/sample-appeals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
{
"challengeId": "climate-forecasting-2026",
"title": "Regional climate forecasting benchmark",
"asOf": "2026-05-15T04:00:00Z",
"sponsor": {
"id": "sponsor-climate-lab",
"name": "Open Climate Lab"
},
"appealPolicy": {
"appealWindowHours": 72,
"reviewerResponseHours": 24,
"acceptedReasons": [
"missing-evidence",
"rubric-miscalculation",
"conflict-of-interest",
"payout-split-dispute"
]
},
"ipPolicy": {
"defaultTransfer": "after-payout",
"holdDuringAppeal": true
},
"submissions": [
{
"id": "sub-aurora",
"teamId": "team-aurora",
"title": "Aurora probabilistic forecast model",
"decision": "awarded",
"awardAmount": 60000,
"decisionAt": "2026-05-13T10:00:00Z",
"solverPayoutRoutes": [
{
"solverId": "solver-1",
"share": 0.65
},
{
"solverId": "solver-2",
"share": 0.35
}
],
"artifactIds": [
"artifact-aurora-model",
"artifact-aurora-report",
"artifact-aurora-dataset"
]
},
{
"id": "sub-boreal",
"teamId": "team-boreal",
"title": "Boreal analog ensemble",
"decision": "honorable-mention",
"awardAmount": 10000,
"decisionAt": "2026-05-12T12:00:00Z",
"solverPayoutRoutes": [
{
"solverId": "solver-3",
"share": 1
}
],
"artifactIds": [
"artifact-boreal-model",
"artifact-boreal-report"
]
}
],
"reviewers": [
{
"id": "reviewer-stat",
"name": "Statistical reviewer",
"affiliations": [
"Independent"
],
"reviewedSubmissionIds": [
"sub-aurora",
"sub-boreal"
]
},
{
"id": "reviewer-sponsor",
"name": "Sponsor domain reviewer",
"affiliations": [
"Open Climate Lab"
],
"reviewedSubmissionIds": [
"sub-aurora"
]
},
{
"id": "reviewer-external",
"name": "External replication reviewer",
"affiliations": [
"University Center for Forecasting"
],
"reviewedSubmissionIds": []
}
],
"evidenceSnapshots": [
{
"id": "snapshot-aurora-decision",
"submissionId": "sub-aurora",
"lockedAt": "2026-05-13T10:05:00Z",
"artifactHashes": {
"artifact-aurora-model": "sha256:4c9dc6f02f0c9f8f9a0010e7c8c0221d",
"artifact-aurora-report": "sha256:9a78aa4dcb8a9b605e63b10ec31e4f62",
"artifact-aurora-dataset": "sha256:f0796207ec9d81a43ff84dc148d873ab"
}
},
{
"id": "snapshot-boreal-decision",
"submissionId": "sub-boreal",
"lockedAt": "2026-05-12T12:10:00Z",
"artifactHashes": {
"artifact-boreal-model": "sha256:e2e87d98509bb0186ef49b6b37a31a30",
"artifact-boreal-report": "sha256:d33a2ad6f1fb4f8421ec13fb935af884"
}
}
],
"appeals": [
{
"id": "appeal-aurora-conflict",
"submissionId": "sub-aurora",
"filedBy": {
"role": "competing-solver",
"teamId": "team-boreal"
},
"reason": "conflict-of-interest",
"filedAt": "2026-05-13T18:00:00Z",
"reviewerIds": [
"reviewer-sponsor",
"reviewer-external"
],
"status": "open",
"summary": "A sponsor-affiliated reviewer participated in scoring the winning submission."
},
{
"id": "appeal-boreal-split",
"submissionId": "sub-boreal",
"filedBy": {
"role": "solver",
"teamId": "team-boreal"
},
"reason": "payout-split-dispute",
"filedAt": "2026-05-13T08:00:00Z",
"resolvedAt": "2026-05-14T02:00:00Z",
"reviewerIds": [
"reviewer-stat"
],
"status": "resolved",
"resolution": "upheld-original-route",
"summary": "Team requested an alternate split, but submitted payout route was confirmed."
}
]
}
Binary file added scientific-bounty-appeals-ledger/docs/demo.mp4
Binary file not shown.
16 changes: 16 additions & 0 deletions scientific-bounty-appeals-ledger/docs/demo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions scientific-bounty-appeals-ledger/docs/requirement-map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Requirement Map

This module contributes a focused dispute-handling slice for SCIBASE issue #18: Scientific Bounty System.

| Issue #18 requirement | Evidence in this module |
| --- | --- |
| Platform-mediated arbitration system | `buildAppealsLedger` creates a deterministic ledger for post-evaluation appeals, eligibility, reviewer conflicts, SLA state, and next actions. |
| Automated checklists for deliverables | `evaluateEvidenceLock` checks whether contested submissions have complete locked artifact hashes before arbitration proceeds. |
| Optional third-party reviewers or peer validators | `evaluateReviewerConflicts` identifies when a sponsor-affiliated reviewer must be replaced by an independent reviewer. |
| Feedback loop between submitters and sponsors | `buildSponsorFeedbackPacket` summarizes open appeals, overdue responses, conflict reviews, and requested sponsor actions. |
| Escrowed prize funds | `summarizePayouts` separates held and releasable award amounts while an eligible appeal remains open. |
| Partial payments or honorable mentions | The sample challenge covers both a winning award and an honorable-mention payout route. |
| Payout routing | `evaluatePayoutHold` keeps awarded submission routes intact while holding/releasing funds based on appeal state. |
| IP transfer upon payout | `evaluateIpGuard` blocks IP transfer while payout is held by an eligible appeal. |
| Auditability | `buildAuditTrail` emits decision, appeal-window, response-due, payout-hold, and payout-summary events with a stable digest. |
| Reviewer demo | `npm run demo` prints appeal count, payout hold amount, top action, IP guard count, and digest; `docs/demo.mp4` is a short visual demo artifact. |
18 changes: 18 additions & 0 deletions scientific-bounty-appeals-ledger/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "scientific-bounty-appeals-ledger",
"version": "1.0.0",
"private": true,
"description": "Dependency-free appeals and dispute ledger for scientific bounty systems.",
"scripts": {
"check": "node --check src/appeals-ledger.js && node --check scripts/demo.js && node --check test/appeals-ledger.test.js",
"demo": "node scripts/demo.js",
"test": "node test/appeals-ledger.test.js"
},
"keywords": [
"scientific-bounties",
"appeals",
"arbitration",
"payouts"
],
"license": "MIT"
}
16 changes: 16 additions & 0 deletions scientific-bounty-appeals-ledger/scripts/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const fs = require("node:fs");
const path = require("node:path");
const { buildAppealsLedger } = require("../src/appeals-ledger");

const samplePath = path.join(__dirname, "..", "data", "sample-appeals.json");
const challenge = JSON.parse(fs.readFileSync(samplePath, "utf8"));
const ledger = buildAppealsLedger(challenge);

console.log(`Challenge: ${ledger.title}`);
console.log(`Appeals tracked: ${ledger.appeals.length}`);
console.log(`Payout status: ${ledger.payout.status}`);
console.log(`Held amount: US$${ledger.payout.heldAmount.toLocaleString("en-US")}`);
console.log(`Open appeals: ${ledger.dashboard.openAppealCount}`);
console.log(`Top action: ${ledger.dashboard.highPriorityItems[0].nextAction}`);
console.log(`IP guards: ${ledger.ipTransferGuards.length}`);
console.log(`Digest: ${ledger.digest}`);
Loading