From 1e768c04f0001d594ee9fd455f6ac009c8781dcf Mon Sep 17 00:00:00 2001 From: auruminternum <267466919+auruminternum@users.noreply.github.com> Date: Mon, 1 Jun 2026 20:34:19 -0600 Subject: [PATCH] Add bounty transparency schema --- .topics/.schemas/README.md | 16 +- .topics/.schemas/tiinex.bounty.v1.md | 281 ++++++++++++++++++ .../001-bounty-transparency-example.trace.md | 71 +++++ scripts/validate-bounty-trace.mjs | 111 +++++++ 4 files changed, 472 insertions(+), 7 deletions(-) create mode 100644 .topics/.schemas/tiinex.bounty.v1.md create mode 100644 .topics/bounties/001-bounty-transparency-example.trace.md create mode 100644 scripts/validate-bounty-trace.mjs diff --git a/.topics/.schemas/README.md b/.topics/.schemas/README.md index 65cff1e..709bfce 100644 --- a/.topics/.schemas/README.md +++ b/.topics/.schemas/README.md @@ -31,12 +31,14 @@ The schema notes exist to reduce that ambiguity. done criteria, and optional subtasks - [tiinex.evidence.v1.md](tiinex.evidence.v1.md): preserved supporting material with provenance and fidelity limits -- [tiinex.feedback.v1.md](tiinex.feedback.v1.md): interaction-shaped signal with - source, target, and disposition -- [tiinex.decision.v1.md](tiinex.decision.v1.md): landed decisions and what now - governs -- [tiinex.pointer.v1.md](tiinex.pointer.v1.md): thin continuity redirects toward - an upstream trace or origin +- [tiinex.feedback.v1.md](tiinex.feedback.v1.md): interaction-shaped signal with + source, target, and disposition +- [tiinex.decision.v1.md](tiinex.decision.v1.md): landed decisions and what now + governs +- [tiinex.bounty.v1.md](tiinex.bounty.v1.md): bounty, prize, and reward claims + with traceable eligibility, submission, settlement, and payment evidence +- [tiinex.pointer.v1.md](tiinex.pointer.v1.md): thin continuity redirects toward + an upstream trace or origin ## Supporting Schemas @@ -77,4 +79,4 @@ separate: That separation matters because provenance problems often begin when one system stores all of those meanings in one opaque layer that later readers cannot -inspect directly. \ No newline at end of file +inspect directly. diff --git a/.topics/.schemas/tiinex.bounty.v1.md b/.topics/.schemas/tiinex.bounty.v1.md new file mode 100644 index 0000000..2bb97a3 --- /dev/null +++ b/.topics/.schemas/tiinex.bounty.v1.md @@ -0,0 +1,281 @@ +# Continuity Context + +- Envelope Schema: [tiinex.continuation.v1](tiinex.continuation.v1.md) +- Parent + - Parent Schema: [tiinex.decision.v1](tiinex.decision.v1.md) + - Created At: 2026-05-28 22:50:17 + - Trace: [tiinex.decision.v1.md](tiinex.decision.v1.md) +- Current + - Current Schema: [tiinex.bounty.v1](tiinex.bounty.v1.md) + - Created At: 2026-06-02 00:00:00 + - Summary: Shared schema for bounty, prize, and reward artifacts where eligibility, submission state, and settlement evidence must stay traceable. + +--- + +# tiinex.bounty.v1 + +- Status: provisional shared schema note +- Schema Definition: [tiinex.decision.v1](tiinex.decision.v1.md) +- Origin: + - [relative](../../../ai-provenance/.topics/trace-format/001.trace.md) + - [browse + git](https://github.com/Tiinex/ai-provenance/blob/2b82ee6538836765463c7a5524c2120aa3aa4983/.topics/trace-format/001.trace.md) + +## Summary + +This schema id names bounty, prize, or reward artifacts whose main job is to +make the reward contract, submission lineage, acceptance state, and settlement +evidence readable without relying on hidden platform state. + +It exists for work where a later reader needs to distinguish a promised reward, +a submitted claim, an accepted claim, and a paid claim. + +## Required Body Expectations + +Artifacts using `tiinex.bounty.v1` should contain a readable body after the +continuity envelope. + +The body should include, at minimum: + +- a title identifying the bounty or reward artifact +- the sponsor, program, or source surface that offered the bounty +- the stated reward amount, unit, and any known payment constraints +- the contributor or claimant identity used for the submission +- the submission artifact, claim, pull request, issue, file, or other concrete + deliverable being evaluated +- the current settlement state +- enough eligibility evidence that a later reader can see why the claim is + pending, accepted, rejected, paid, expired, or blocked + +## Recommended Body Sections + +The exact section names may vary, but bounty artifacts should usually provide +some combination of: + +- reward source +- reward terms +- claimant +- submission artifact +- eligibility evidence +- settlement state +- payment evidence +- review or dispute history +- interpretation limits + +## Envelope Expectations + +When this body schema is used, it is expected to sit inside an envelope that +identifies at least: + +- `Envelope Schema` +- `Current -> Current Schema: tiinex.bounty.v1` +- `Current -> Created At` +- `Current -> Authors` + +Recommended envelope-side companions are: + +- `Current -> Why` +- `Current -> Summary` +- parent signal when the bounty artifact specializes an evidence, feedback, or + decision trace + +## Required Bounty Semantics + +Bounty artifacts using `tiinex.bounty.v1` should make it clear: + +- who offered the reward +- who made the submission or claim +- what exact artifact is being evaluated for the reward +- what reward amount was visible or promised +- what state the claim is currently in +- what evidence supports that state +- what evidence is missing before the reward can be counted as collected + +The settlement state should use one of these normalized values when possible: + +- `open` +- `submitted` +- `in_review` +- `accepted` +- `rejected` +- `expired` +- `blocked` +- `paid` +- `disputed` +- `unknown` + +If the reward is not yet paid, the artifact should not describe the amount as +earned or collected. It should preserve the amount as offered, claimed, or +accepted according to the actual evidence. + +If payment evidence is unavailable, redacted, or unsafe to disclose, the +artifact should say so explicitly. It should not include private wallet +addresses, payout account identifiers, secrets, access tokens, or hidden +runtime instructions. + +## Validation-Friendly Shape + +Keep bounty artifacts in a stable order so humans and validators can scan them +the same way. + +Preferred order: + +1. title +2. Reward Source +3. Reward Terms +4. Claimant +5. Submission Artifact +6. Eligibility Evidence +7. Settlement State +8. Payment Evidence +9. Interpretation Notes + +Preferred anchors: + +- `Reward Source` +- `Reward Terms` +- `Claimant` +- `Submission Artifact` +- `Eligibility Evidence` +- `Settlement State` + +If a section is omitted, leave it out cleanly rather than renaming it for a +one-off use. Use close equivalents only when the artifact genuinely needs a +different label, and keep the meaning obvious in the first line. + +## Recommended Fields + +- `Current -> Authors` +- `Current -> Why` +- `Current -> Summary` +- sponsor or program name +- source surface such as GitHub, Reddit, Algora, IssueHunt, Ubiquity, Opire, + or another named channel +- source reference such as a URL, issue number, post id, comment id, or program + id +- reward amount and unit +- claimant identity as used on the source surface +- submission artifact reference +- normalized settlement state +- eligibility evidence references +- payment evidence or explicit missing-payment note +- review, dispute, or expiry conditions when known + +## File Naming Conventions + +Artifacts using `tiinex.bounty.v1` should normally follow the same +lineage-first trace naming as other continuity artifacts. + +Recommended form: + +- `.trace.md` +- `-.trace.md` + +Examples: + +- `001.trace.md` +- `001-2.trace.md` +- `001-2-bounty-claim.trace.md` +- `001-3-settlement-evidence.trace.md` + +Rules: + +- keep the lineage label first +- use a short slug when it helps distinguish one bounty or settlement artifact + from another +- keep the `.trace.md` suffix stable + +## What This Schema Is For + +Use `tiinex.bounty.v1` when the artifact is primarily trying to: + +- preserve bounty or reward terms in a trace-readable form +- link a submission artifact to a visible reward source +- separate offered, submitted, accepted, and paid states +- preserve enough settlement evidence that a later reader can audit whether a + reward should be counted as collected +- keep reward work from becoming dependent on hidden platform state + +## What This Schema Is Not For + +Do not use this schema for generic work logs, broad business plans, or payment +instructions that are not tied to a traceable reward claim. + +It is not primarily for: + +- private payout setup +- wallet or bank account records +- generic project management +- broad revenue forecasts +- hidden prompt, hidden runtime, or secret-collection artifacts +- opaque platform dashboards without preserved evidence + +## Minimal Example + +```md +# Continuity Context + +- Envelope Schema: tiinex.continuation.v1 +- Current + - Current Schema: tiinex.bounty.v1 + - Created At: 2026-06-02 00:00:00 + - Authors: Example Contributor + - Summary: Example bounty artifact showing a submitted but unpaid claim. + +--- + +# Example Submitted Bounty Claim + +## Reward Source + +- Surface: GitHub +- Sponsor: Example Sponsor +- Reference: https://example.invalid/org/repo/issues/123 + +## Reward Terms + +- Amount: 100 +- Unit: USD +- Terms Summary: Reward is paid only after maintainer acceptance. + +## Claimant + +- Identity: example-contributor +- Surface: GitHub + +## Submission Artifact + +- Type: pull request +- Reference: https://example.invalid/org/repo/pull/456 + +## Eligibility Evidence + +- The source issue was open when the submission was made. +- The pull request addresses the requested behavior. + +## Settlement State + +- State: submitted +- Counted As Collected: no + +## Payment Evidence + +- Status: none yet +``` + +## Interpretation Notes + +- a bounty artifact should optimize for settlement truth, not optimism +- offered or claimed amounts should not be counted as collected until payment + or acceptance evidence supports that stronger state +- private payout destinations should stay out of the public artifact unless a + separate schema and consent boundary makes them safe to publish +- if a reward source becomes unreachable, the artifact should still preserve + enough terms and state evidence to make the claim auditable + +--- + +# Continuity Integrity + +- sha256-base64url-c14n-v1 + - Towards: [tiinex.decision.v1.md](tiinex.decision.v1.md) + - Value: pending-new-schema-note diff --git a/.topics/bounties/001-bounty-transparency-example.trace.md b/.topics/bounties/001-bounty-transparency-example.trace.md new file mode 100644 index 0000000..94fb07f --- /dev/null +++ b/.topics/bounties/001-bounty-transparency-example.trace.md @@ -0,0 +1,71 @@ +# Continuity Context + +- Envelope Schema: [.topics/.schemas/tiinex.continuation.v1.md](../.schemas/tiinex.continuation.v1.md) +- Parent + - Parent Schema: [.topics/.schemas/tiinex.schema.v1.md](../.schemas/tiinex.schema.v1.md) + - Created At: 2026-06-02 00:00:00 + - Trace: [.topics/.schemas/tiinex.bounty.v1.md](../.schemas/tiinex.bounty.v1.md) +- Current + - Current Schema: [.topics/.schemas/tiinex.bounty.v1.md](../.schemas/tiinex.bounty.v1.md) + - Created At: 2026-06-02 00:00:00 + - Authors: auruminternum + - Why: Demonstrates how a reward claim can preserve offer, submission, and settlement state without counting unpaid work as collected revenue. + - Summary: Example bounty trace that validates against the local bounty schema checker. + +--- + +# Example Reward Claim With Explicit Settlement State + +## Reward Source + +- Surface: GitHub +- Sponsor: Example Sponsor +- Reference: https://example.invalid/example/reward/issues/100 + +## Reward Terms + +- Amount: 100 +- Unit: USD +- Terms Summary: The reward is payable only after the sponsor accepts the submitted artifact. +- Payment Constraints: Payout destination is intentionally not included in the public trace. + +## Claimant + +- Identity: auruminternum +- Surface: GitHub + +## Submission Artifact + +- Type: pull request +- Reference: https://example.invalid/example/reward/pull/101 +- Submitted At: 2026-06-02 00:00:00 + +## Eligibility Evidence + +- Source issue was visible before work began. +- Submission reference is concrete and reviewable. +- No private payout address or hidden runtime instruction is required to inspect the claim state. + +## Settlement State + +- State: submitted +- Counted As Collected: no +- Reason: no acceptance or payment evidence has been recorded yet + +## Payment Evidence + +- Status: none yet +- Missing Evidence: sponsor acceptance, payout confirmation, or settlement receipt + +## Interpretation Notes + +- This is a synthetic example for schema validation, not a real payment claim. +- It shows how a trace can carry reward value without overstating unpaid work as earned cash. + +--- + +# Continuity Integrity + +- schema-example-only + - Towards: [.topics/.schemas/tiinex.bounty.v1.md](../.schemas/tiinex.bounty.v1.md) + - Value: not-a-cryptographic-integrity-claim diff --git a/scripts/validate-bounty-trace.mjs b/scripts/validate-bounty-trace.mjs new file mode 100644 index 0000000..daca8b5 --- /dev/null +++ b/scripts/validate-bounty-trace.mjs @@ -0,0 +1,111 @@ +#!/usr/bin/env node + +import { readFile } from "node:fs/promises"; + +const requiredSections = [ + "Reward Source", + "Reward Terms", + "Claimant", + "Submission Artifact", + "Eligibility Evidence", + "Settlement State", +]; + +const allowedStates = new Set([ + "open", + "submitted", + "in_review", + "accepted", + "rejected", + "expired", + "blocked", + "paid", + "disputed", + "unknown", +]); + +function hasSection(markdown, section) { + const pattern = new RegExp(`^##\\s+${section.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*$`, "m"); + return pattern.test(markdown); +} + +function getSectionBody(markdown, section) { + const lines = markdown.split(/\r?\n/); + const startIndex = lines.findIndex((line) => line.trim() === `## ${section}`); + if (startIndex === -1) { + return null; + } + + const body = []; + for (const line of lines.slice(startIndex + 1)) { + if (/^##\s+/.test(line)) { + break; + } + body.push(line); + } + return body.join("\n"); +} + +function findSettlementState(markdown) { + const sectionBody = getSectionBody(markdown, "Settlement State"); + if (sectionBody === null) { + return null; + } + + const stateMatch = sectionBody.match(/^\s*-\s*State:\s*([A-Za-z_]+)\s*$/m); + return stateMatch ? stateMatch[1] : null; +} + +function validateBountyTrace(markdown) { + const errors = []; + + if (!/Current Schema:.*tiinex\.bounty\.v1/.test(markdown)) { + errors.push("Current Schema must reference tiinex.bounty.v1."); + } + + if (!/Authors:\s*\S+/.test(markdown)) { + errors.push("Current -> Authors must be present."); + } + + for (const section of requiredSections) { + if (!hasSection(markdown, section)) { + errors.push(`Missing required section: ${section}.`); + } + } + + const settlementState = findSettlementState(markdown); + if (!settlementState) { + errors.push("Settlement State must include a '- State: ' row."); + } else if (!allowedStates.has(settlementState)) { + errors.push(`Settlement State '${settlementState}' is not normalized.`); + } + + if (/State:\s*paid\b/i.test(markdown) && !hasSection(markdown, "Payment Evidence")) { + errors.push("Paid claims must include Payment Evidence."); + } + + if (/Counted As Collected:\s*yes/i.test(markdown) && !/State:\s*(accepted|paid)\b/i.test(markdown)) { + errors.push("Collected claims must be accepted or paid."); + } + + return errors; +} + +const filePath = process.argv[2]; +if (!filePath) { + console.error("Usage: node scripts/validate-bounty-trace.mjs "); + process.exit(2); +} + +const markdown = await readFile(filePath, "utf8"); +const errors = validateBountyTrace(markdown); + +if (errors.length > 0) { + console.error(`Bounty trace validation failed for ${filePath}:`); + for (const error of errors) { + console.error(`- ${error}`); + } + process.exit(1); +} + +console.log(`Bounty trace validation passed for ${filePath}.`);