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
37 changes: 37 additions & 0 deletions scientific-bounty-system/team-payout-split-ledger/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Team Payout Split Ledger

This slice supports issue #18, Scientific Bounty System. It adds a deterministic
ledger for allocating accepted scientific bounty awards across teams,
institutions, and milestone deliverables.

The module uses synthetic challenge data only. It does not process payment
credentials, identity documents, tax records, or banking details. Instead, it
tracks privacy-safe payout route states such as `verified`, `pending`, and
`blocked`.

## Checks

- Locked milestones cannot release money until accepted.
- Contributor splits must total 10000 basis points.
- Institution overhead is capped per challenge policy.
- Every contributor must keep a minimum solver share after overhead.
- Payout routes must be verified before the release is marked payable.
- Generated receipts preserve the award basis, hold reasons, and next actions.

## Local Verification

```bash
node scientific-bounty-system/team-payout-split-ledger/test.js
node scientific-bounty-system/team-payout-split-ledger/demo.js
git diff --check
```

The demo writes deterministic artifacts under
`scientific-bounty-system/team-payout-split-ledger/artifacts/`.

## Files

- `ledger.js` - allocation, policy checks, and receipt generation.
- `data/challenges.json` - synthetic bounty challenge packets.
- `test.js` - Node built-in tests.
- `demo.js` - deterministic JSON, Markdown, and SVG artifact generation.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
{
"summary": {
"total": 3,
"payable": 1,
"blocked": 2,
"held": 2,
"unlockedCents": 230000,
"lockedCents": 40000
},
"ledgers": [
{
"challengeId": "bio-marker-panel",
"title": "Biomarker validation panel",
"currency": "USD",
"totalPrizeCents": 120000,
"unlockedAmountCents": 80000,
"lockedAmountCents": 40000,
"payable": true,
"allocations": [
{
"contributorId": "solver-alpha",
"role": "analysis lead",
"payoutRouteStatus": "verified",
"grossCents": 44000,
"institutionCents": 8000,
"solverCents": 36000
},
{
"contributorId": "solver-beta",
"role": "wet-lab validation",
"payoutRouteStatus": "verified",
"grossCents": 24000,
"institutionCents": 4000,
"solverCents": 20000
},
{
"contributorId": "solver-gamma",
"role": "reproducibility reviewer",
"payoutRouteStatus": "verified",
"grossCents": 12000,
"institutionCents": 0,
"solverCents": 12000
}
],
"findings": [
{
"code": "milestone_locked",
"severity": "hold",
"target": "replication",
"message": "replication is pending_sponsor_review; funds stay locked until sponsor acceptance.",
"action": "Wait for sponsor acceptance or revise the deliverable packet."
}
],
"receipt": {
"awardBasis": "2 accepted milestone(s), 1 locked milestone(s)",
"releaseStatus": "ready_for_sponsor_review",
"acceptedMilestones": [
"proposal",
"prototype"
],
"lockedMilestones": [
"replication"
],
"totalAllocatedCents": 80000,
"nextActions": [
"Wait for sponsor acceptance or revise the deliverable packet."
]
}
},
{
"challengeId": "climate-forecast",
"title": "Regional climate forecast benchmark",
"currency": "USD",
"totalPrizeCents": 90000,
"unlockedAmountCents": 90000,
"lockedAmountCents": 0,
"payable": false,
"allocations": [
{
"contributorId": "solver-delta",
"role": "model owner",
"payoutRouteStatus": "verified",
"grossCents": 63000,
"institutionCents": 22500,
"solverCents": 40500
},
{
"contributorId": "solver-epsilon",
"role": "data engineer",
"payoutRouteStatus": "pending",
"grossCents": 22500,
"institutionCents": 0,
"solverCents": 22500
}
],
"findings": [
{
"code": "payout_route_unverified",
"severity": "block",
"target": "solver-epsilon",
"message": "solver-epsilon has payout route status pending.",
"action": "Hold release for this contributor until payout route verification is complete."
},
{
"code": "split_total_mismatch",
"severity": "block",
"target": "climate-forecast",
"message": "Contributor splits total 9500 basis points instead of 10000.",
"action": "Rebalance contributor splits before payout approval."
},
{
"code": "institution_overhead_exceeds_cap",
"severity": "block",
"target": "solver-delta",
"message": "solver-delta routes 2500 basis points to an institution, above the 1200 cap.",
"action": "Lower institution overhead or attach sponsor-approved exception evidence."
}
],
"receipt": {
"awardBasis": "2 accepted milestone(s), 0 locked milestone(s)",
"releaseStatus": "blocked",
"acceptedMilestones": [
"proposal",
"forecast-model"
],
"lockedMilestones": [],
"totalAllocatedCents": 85500,
"nextActions": [
"Hold release for this contributor until payout route verification is complete.",
"Rebalance contributor splits before payout approval.",
"Lower institution overhead or attach sponsor-approved exception evidence."
]
}
},
{
"challengeId": "quantum-noise",
"title": "Quantum noise reduction challenge",
"currency": "USD",
"totalPrizeCents": 60000,
"unlockedAmountCents": 60000,
"lockedAmountCents": 0,
"payable": false,
"allocations": [
{
"contributorId": "solver-zeta",
"role": "principal investigator",
"payoutRouteStatus": "verified",
"grossCents": 54000,
"institutionCents": 48000,
"solverCents": 6000
},
{
"contributorId": "solver-eta",
"role": "experiment reviewer",
"payoutRouteStatus": "verified",
"grossCents": 6000,
"institutionCents": 0,
"solverCents": 6000
}
],
"findings": [
{
"code": "institution_overhead_exceeds_cap",
"severity": "block",
"target": "solver-zeta",
"message": "solver-zeta routes 8000 basis points to an institution, above the 1500 cap.",
"action": "Lower institution overhead or attach sponsor-approved exception evidence."
},
{
"code": "solver_share_below_minimum",
"severity": "hold",
"target": "solver-zeta",
"message": "solver-zeta keeps 1000 basis points after overhead, below the 1200 minimum.",
"action": "Increase direct solver share or move institution recovery outside the bounty payout."
},
{
"code": "solver_share_below_minimum",
"severity": "hold",
"target": "solver-eta",
"message": "solver-eta keeps 1000 basis points after overhead, below the 1200 minimum.",
"action": "Increase direct solver share or move institution recovery outside the bounty payout."
}
],
"receipt": {
"awardBasis": "2 accepted milestone(s), 0 locked milestone(s)",
"releaseStatus": "blocked",
"acceptedMilestones": [
"proposal",
"prototype"
],
"lockedMilestones": [],
"totalAllocatedCents": 60000,
"nextActions": [
"Lower institution overhead or attach sponsor-approved exception evidence.",
"Increase direct solver share or move institution recovery outside the bounty payout."
]
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Team Payout Split Ledger

## Summary

- Challenges reviewed: 3
- Payable ledgers: 1
- Blocked ledgers: 2
- Held ledgers: 2
- Unlocked funds: $2300.00
- Locked funds: $400.00

## Challenge Ledgers

### bio-marker-panel

- Title: Biomarker validation panel
- Payable: true
- Unlocked: $800.00
- Locked: $400.00
- Receipt status: ready_for_sponsor_review
- hold: milestone_locked - replication is pending_sponsor_review; funds stay locked until sponsor acceptance.

### climate-forecast

- Title: Regional climate forecast benchmark
- Payable: false
- Unlocked: $900.00
- Locked: $0.00
- Receipt status: blocked
- block: payout_route_unverified - solver-epsilon has payout route status pending.
- block: split_total_mismatch - Contributor splits total 9500 basis points instead of 10000.
- block: institution_overhead_exceeds_cap - solver-delta routes 2500 basis points to an institution, above the 1200 cap.

### quantum-noise

- Title: Quantum noise reduction challenge
- Payable: false
- Unlocked: $600.00
- Locked: $0.00
- Receipt status: blocked
- block: institution_overhead_exceeds_cap - solver-zeta routes 8000 basis points to an institution, above the 1500 cap.
- hold: solver_share_below_minimum - solver-zeta keeps 1000 basis points after overhead, below the 1200 minimum.
- hold: solver_share_below_minimum - solver-eta keeps 1000 basis points after overhead, below the 1200 minimum.

Loading