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
77 changes: 77 additions & 0 deletions scientific-bounty-arbitration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Scientific Bounty Arbitration

Self-contained scientific bounty trust-layer milestone for [SCIBASE.AI issue #18](https://github.com/SCIBASE-AI/SCIBASE.AI/issues/18).

The issue asks for a full scientific bounty system. This module focuses on a distinct and reviewable slice: validating a challenge, packaging submissions, detecting reviewer conflicts, scoring eligible reviews, recording arbitration decisions, and producing payout/IP readiness records.

## What It Adds

- Challenge validation for required posting fields and rubric integrity.
- Submission manifest builder that maps artifacts to deliverables and records hashes.
- Workspace security summary for private submission spaces, scoped team access, version-control refs, and audit-trail hashes.
- Reviewer conflict detection for sponsor affiliation, submission team membership, and collaborator overlap.
- Weighted rubric scoring using only eligible independent reviews.
- Arbitration record with blocker reasons, final score, decision status, and decision log hash.
- Payout plan with milestone schedule, team splits, payout readiness, and IP transfer status.
- Sponsor feedback loop records that expose eligible reviewer comments, requested changes, submitter responses, due dates, and feedback hashes.
- Reward distribution ledger covering primary award routes, milestone releases, honorable-mention recognitions, payee types, committed totals, and escrow balance.
- Challenge lifecycle report with intake, escrow funding, secure workspace, deliverable manifest, independent review, arbitration, feedback-loop closure, milestone release, reward ledger, payout routing, and IP handoff gates.
- Sample bounty fixture, tests, requirement map, CLI demo, and short demo GIF.

## Run

```bash
cd scientific-bounty-arbitration
npm run check
npm test
npm run demo
```

Expected demo shape:

```json
{
"challenge": "Regional flood-risk forecasting model",
"decision": "award-recommended",
"finalScore": 86.95,
"eligibleReviewers": 2,
"workspaceSecurity": {
"status": "ready",
"versionControlRef": "riverwatch/final-submission@7f4c9b2"
},
"payoutStatus": "ready",
"payoutRoutes": [
{ "payeeId": "researcher-1", "amount": 600 },
{ "payeeId": "researcher-2", "amount": 400 }
],
"feedbackLoop": {
"status": "closed",
"items": 2,
"openItemCount": 0
},
"rewardLedger": {
"status": "balanced",
"committedTotal": 1100
},
"lifecycle": {
"status": "ready-for-release",
"escrowReleaseInstruction": "release USD 1000 to 2 route(s) after sponsor approval"
}
}
```

## Demo Artifact

See [docs/demo.gif](docs/demo.gif) for a short visual walkthrough. The SVG source is included at [docs/demo.svg](docs/demo.svg).

## Files

- `src/arbitration.js` - challenge validation, manifests, scoring, arbitration, lifecycle gates, and payout planning.
- `data/sample-bounty.json` - reviewable scientific challenge/submission fixture.
- `test/arbitration.test.js` - dependency-free Node tests.
- `scripts/demo.js` - CLI demo.
- `docs/issue-18-requirement-map.md` - maps the implementation to bounty requirements.

## AI-Assisted Disclosure

This contribution was produced with AI assistance and manually verified with the local commands above.
168 changes: 168 additions & 0 deletions scientific-bounty-arbitration/data/sample-bounty.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
{
"challenge": {
"id": "challenge-climate-forecast",
"title": "Regional flood-risk forecasting model",
"sponsorId": "sponsor-climate-lab",
"problemDescription": "Develop a reproducible model that forecasts regional flood-risk windows using public rainfall and river-gauge data.",
"scientificContext": "Climate nonprofits need faster ways to compare model outputs and award teams that produce reproducible forecasts.",
"deliverables": [
{ "id": "model", "title": "Working forecasting model", "required": true },
{ "id": "dataset", "title": "Cleaned public dataset", "required": true },
{ "id": "whitepaper", "title": "Methodology whitepaper", "required": true },
{ "id": "demo", "title": "Short model walkthrough", "required": false }
],
"rubric": [
{ "id": "accuracy", "label": "Forecast accuracy", "weight": 40, "deliverableId": "model" },
{ "id": "reproducibility", "label": "Reproducibility", "weight": 30, "deliverableId": "dataset" },
{ "id": "clarity", "label": "Scientific clarity", "weight": 20, "deliverableId": "whitepaper" },
{ "id": "impact", "label": "Sponsor impact", "weight": 10 }
],
"timeline": {
"opensAt": "2026-05-01",
"prototypeDueAt": "2026-06-01",
"finalDueAt": "2026-07-01"
},
"prize": {
"amount": 1000,
"currency": "USD",
"escrow": {
"provider": "algora",
"status": "funded",
"amount": 1100,
"reference": "algora-claim-P5uXJ4HFySs31nVh"
},
"recognitions": [
{
"label": "honorable mention",
"payeeId": "student-climate-team",
"payeeType": "institution",
"amount": 100,
"reason": "Best open data documentation"
}
],
"milestones": [
{ "label": "prototype accepted", "percent": 30 },
{ "label": "final award", "percent": 70 }
]
},
"ipPolicy": {
"defaultOwner": "solver",
"transferOnPayout": true,
"licenseBeforePayout": "evaluation-only"
},
"participation": {
"visibility": "public",
"anonymousAllowed": true,
"ndaRequired": false
},
"feedbackPolicy": {
"responseDueAt": "2026-07-05T17:00:00Z"
}
},
"submission": {
"id": "submission-riverwatch",
"teamId": "team-riverwatch",
"teamMembers": ["researcher-1", "researcher-2"],
"anonymous": false,
"teamSplits": [
{ "payeeId": "researcher-1", "percent": 0.6 },
{ "payeeId": "researcher-2", "percent": 0.4 }
],
"milestoneEvidence": [
{
"label": "prototype accepted",
"status": "accepted",
"acceptedAt": "2026-06-03T12:00:00Z",
"artifactIds": ["artifact-model", "artifact-data"]
},
{
"label": "final award",
"status": "accepted",
"acceptedAt": "2026-07-02T12:00:00Z",
"artifactIds": ["artifact-model", "artifact-data", "artifact-whitepaper"]
}
],
"feedbackResponses": [
{
"reviewId": "review-a-final",
"status": "accepted",
"respondedAt": "2026-07-03T10:15:00Z",
"notes": "Added final calibration appendix and linked model cards."
},
{
"reviewId": "review-b-final",
"status": "accepted",
"respondedAt": "2026-07-03T11:05:00Z",
"notes": "Published data dictionary errata and rerun logs."
}
],
"workspace": {
"id": "workspace-submission-riverwatch",
"visibility": "private",
"accessControl": {
"allowedTeamIds": ["team-riverwatch"],
"allowedReviewerIds": ["reviewer-a", "reviewer-b"]
},
"versionControl": {
"enabled": true,
"provider": "git",
"ref": "riverwatch/final-submission@7f4c9b2"
}
},
"artifacts": [
{ "id": "artifact-model", "deliverableId": "model", "uri": "ipfs://model", "version": "1.0.0" },
{ "id": "artifact-data", "deliverableId": "dataset", "uri": "ipfs://dataset", "version": "1.0.0" },
{ "id": "artifact-whitepaper", "deliverableId": "whitepaper", "uri": "ipfs://whitepaper", "version": "1.0.0" }
],
"auditTrail": [
{ "action": "workspace-created", "actor": "researcher-1" },
{ "action": "artifact-submitted", "actor": "researcher-2" }
]
},
"reviewers": [
{
"id": "reviewer-a",
"name": "Independent hydrology reviewer",
"affiliations": ["university-water-center"],
"collaborators": []
},
{
"id": "reviewer-b",
"name": "Open data reviewer",
"affiliations": ["open-data-lab"],
"collaborators": []
},
{
"id": "reviewer-c",
"name": "Conflicted sponsor reviewer",
"affiliations": ["sponsor-climate-lab"],
"collaborators": []
}
],
"reviews": [
{
"id": "review-a-final",
"reviewerId": "reviewer-a",
"scores": { "accuracy": 86, "reproducibility": 90, "clarity": 82, "impact": 88 },
"recommendation": "award",
"comments": "Strong reproducibility package; request final calibration appendix before release.",
"requestedChanges": ["attach-calibration-appendix"]
},
{
"id": "review-b-final",
"reviewerId": "reviewer-b",
"scores": { "accuracy": 84, "reproducibility": 92, "clarity": 85, "impact": 91 },
"recommendation": "award",
"comments": "Open data quality is high after the final rerun evidence.",
"requestedChanges": []
},
{
"id": "review-c-final",
"reviewerId": "reviewer-c",
"scores": { "accuracy": 100, "reproducibility": 100, "clarity": 100, "impact": 100 },
"recommendation": "award",
"comments": "Conflicted sponsor score excluded from arbitration.",
"requestedChanges": []
}
]
}
Binary file added scientific-bounty-arbitration/docs/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added scientific-bounty-arbitration/docs/demo.mp4
Binary file not shown.
33 changes: 33 additions & 0 deletions scientific-bounty-arbitration/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.
28 changes: 28 additions & 0 deletions scientific-bounty-arbitration/docs/issue-18-requirement-map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Issue #18 Requirement Map

This module is a distinct milestone for SCIBASE issue #18, Scientific Bounty System. It focuses on the trust layer needed after teams submit work: deliverable validation, arbitration, scoring, lifecycle gates, payout readiness, and IP-safe acceptance.

| Issue requirement | Implementation |
| --- | --- |
| Challenge posting portal requirements | `validateChallenge()` checks required problem, context, deliverables, rubric, timeline, prize, and IP fields before publication. |
| Evaluation criteria and scoring rubric | `scoreSubmission()` averages eligible reviewer scores across weighted rubric items and applies deliverable penalties. |
| Submission package builder | `buildSubmissionManifest()` maps artifacts to required deliverables and produces hashes for auditability. |
| Secure private submission workspace | `buildWorkspaceSecuritySummary()` checks private visibility, scoped team access, enabled version control, and audit-trail presence. |
| Version control and audit logs | Submission manifests preserve artifact hashes, version-control refs, audit trail references, and an audit-trail hash. |
| Arbitration workflow | `buildArbitrationRecord()` combines challenge validation, reviewer conflict checks, eligible reviews, score, blockers, and a decision log hash. |
| Third-party reviewers or peer validators | `detectReviewerConflicts()` marks reviewer eligibility and excludes sponsor/team/collaborator conflicts. |
| Feedback loop between submitters and sponsors | `buildSponsorFeedbackLoop()` exposes eligible reviewer comments/requested changes, submitter responses, due dates, open item counts, and feedback hashes. |
| Smart payout engine | `buildPayoutPlan()` routes prize splits, milestone schedule, payout readiness, and acceptance record hash. |
| Escrowed prize funds, milestone release, and honorable mentions | `buildChallengeLifecycleReport()`, `buildMilestoneReleasePlan()`, and `buildRewardDistributionLedger()` verify escrow funding, accepted milestone evidence, release amounts, honorable-mention recognitions, balanced committed totals, payout routes, and release instruction text. |
| IP management options | Payout planning distinguishes solver-retained IP from transfer-after-payout records. |
| Reviewer-friendly demo | `npm run demo` prints a deterministic sponsor summary, lifecycle gates, milestone releases, and payout routing for `data/sample-bounty.json`. |

## Verification

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

The module is dependency-free and isolated under `scientific-bounty-arbitration/`.
12 changes: 12 additions & 0 deletions scientific-bounty-arbitration/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "scibase-scientific-bounty-arbitration",
"version": "0.1.0",
"private": true,
"description": "Scientific bounty arbitration and payout readiness module for SCIBASE issue #18.",
"type": "commonjs",
"scripts": {
"check": "node --check src/arbitration.js && node --check scripts/demo.js && node --check test/arbitration.test.js",
"demo": "node scripts/demo.js",
"test": "node test/arbitration.test.js"
}
}
48 changes: 48 additions & 0 deletions scientific-bounty-arbitration/scripts/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"use strict";

const sample = require("../data/sample-bounty.json");
const { buildScientificBountyPacket } = require("../src/arbitration");

const packet = buildScientificBountyPacket(
sample.challenge,
sample.submission,
sample.reviewers,
sample.reviews,
);

console.log(
JSON.stringify(
{
challenge: sample.challenge.title,
decision: packet.sponsorSummary.decision,
finalScore: packet.sponsorSummary.finalScore,
eligibleReviewers: packet.sponsorSummary.eligibleReviewers,
workspaceSecurity: packet.arbitration.score.manifest.workspaceSecurity,
payoutStatus: packet.payout.status,
payoutRoutes: packet.payout.routes,
ipTransferStatus: packet.payout.ipTransferStatus,
feedbackLoop: {
status: packet.lifecycle.feedbackLoop.status,
items: packet.lifecycle.feedbackLoop.feedbackItems.length,
openItemCount: packet.lifecycle.feedbackLoop.openItemCount,
},
rewardLedger: {
status: packet.lifecycle.rewardLedger.status,
committedTotal: packet.lifecycle.rewardLedger.committedTotal,
recognitionRoutes: packet.lifecycle.rewardLedger.recognitionRoutes,
},
lifecycle: {
status: packet.lifecycle.status,
gates: packet.lifecycle.gates.map((gate) => ({
id: gate.id,
status: gate.status,
})),
milestoneReleases: packet.lifecycle.milestoneReleases,
escrowReleaseInstruction: packet.lifecycle.escrowReleaseInstruction,
},
decisionLogHash: packet.arbitration.decisionLogHash,
},
null,
2,
),
);
Loading