EN

Karma & Accountability

The accountability layer: four deliberately asymmetric verdicts, grading on the score actually played rather than the ninetieth minute, and a ledger derived on every read so the total can never drift from the 104 matches that produced it.

Part of the Paulopus case study. A prediction product that never keeps score is just an opinion generator. The whole point of Paulopus was to let the octopus commit to a scoreline before kickoff and then be graded, in public, against what actually happened. Karma is the accountability layer that makes the bragging cost something. This is how it was scored, graded, derived, and displayed — across 104 graded matches ending at a net karma of +25.

Four verdicts, deliberately asymmetric

Decision. Every locked prediction resolves into exactly one of four verdicts, and the reward curve had to punish confidently-wrong calls, not just fail to reward them. A binary hit/miss would have let the octopus fire off safe draws forever with no downside.

Approach. The karma scorer is a deterministic function with a full verdict test matrix — same inputs always produce the same verdict, no model in the loop. Exact scoreline is Perfect, right result and goal-difference feel is Inspired, wrong-but-not-embarrassing is Missed, and a wrong result — the 1X2 outcome itself was wrong — is a RedCard, the only verdict that subtracts.

Artifact.

VerdictPoints
Perfect+1.5
Inspired+1
Missed0
RedCard-1

Result. Perfect started at +2 and was later cut to +1.5 to narrow the reward gap versus the other three, which stayed unchanged; because grading is derived, that single constant change re-graded every finished match automatically rather than requiring a data migration.

Grading on what actually happened, not the 90th minute

Decision. Early on, matches were graded against the 90-minute regulation score. In a knockout tournament that quietly lies: a game level after 90 minutes but won on penalties should not read as a missed result when the octopus called the right winner.

Approach. Scoring was reworked to grade on the played score — extra time if it exists, otherwise regulation, with penalty shootouts excluded as goals — and on the real winner, meaning whoever advanced, decided by shootout when the played score is level. Each match record carries a decidedBy field so the rule knows which score to trust.

Artifact.

{ "matchId": "M099", "stage": "qf",
  "predicted": "1-2", "actual": "1-2",
  "verdict": "Perfect", "decidedBy": "extra_time" }

Result. Nine knockout matches decided beyond 90 minutes had been graded wrong under the old rule. Regrounding them moved the karma total from 15.5 to 25.0 and the appreciation text was rewritten to match the corrected verdicts, so the ledger and the octopus's own words agree.

A ledger with nothing to drift

Decision. The obvious design is to store a running karma total and update it as results land. The obvious design is also how totals silently desync from the matches that supposedly produced them.

Approach. There is no stored ledger. Karma is derived on read from the match records themselves — counts, net total, and streaks are all recomputed from the same list every time the page loads. The score-sync step re-grades each finished match rather than mutating a total, so the only source of truth is the outcomes.

Artifact.

"aggregate": {
  "counts": { "Perfect": 14, "Inspired": 39, "Missed": 16, "RedCard": 35 },
  "netKarma": 25,
  "graded": 104,
  "ungraded": 0
}

Result. Net karma is just 14×1.5 + 39×1 + 16×0 + 35×(−1) = 25. Nothing to reconcile, nothing to backfill: the aggregate is a pure function of 104 verdicts, so it cannot disagree with the rows it came from.

Four graded matches with no prediction on file

Decision. The prediction model was rebuilt mid-project — write-once locks were replaced by a regenerable drafts revision history so a pronostic could be revised right up to kickoff. Four already-played matches now carry a verdict but no prediction on file; they appear to have lost their originating prediction somewhere in that migration. They still had to count.

Approach. Verdict and points are stored on each match and were preserved through the migration, so grading survives even where the source scoreline did not. The four affected records (M001, M002, M007, M019) carry "predicted": null but keep their verdict and are included in every aggregate.

Artifact.

{ "matchId": "M002", "predicted": null,
  "actual": "2-1", "verdict": "RedCard", "points": -1 }

Result. Two of the four are RedCards, one Inspired, one Missed. They are baked into the 104 count, the +25 net, and the streak math — which is exactly why the numbers on this page match the octopus's own karma page rather than some cleaner recomputed figure. Accountability includes owning the calls whose paperwork got lost.

The gauge that can't lie about its own colors

Decision. The karma page needed to show the full shape of the record at a glance, not just a headline number, and its earlier two-cell display (only Inspired and Red Cards) hid the Perfects and Misses.

Approach. The home page's proportional verdict gauge was extended to render all four counts, each tinted from one shared VERDICT_PALETTE so the segment, the count, and the badge for a given verdict draw from the same color and can't drift apart. The gauge renders verdict share proportionally and is shown together with the running karma score.

Artifact.

VerdictCountShare of 104
Perfect1413%
Inspired3938%
Missed1615%
RedCard3534%

Result. The breakdown reads honestly: the octopus is right-ish (Perfect plus Inspired) 53 times out of 104, and dead wrong 35 times. The gauge shows the RedCard third instead of burying it, which is the point of an accountability page.

Streaks and the analytics behind the swagger

Decision. A net total flattens the story. A run of ten good calls and a run of four RedCards are both accountability facts worth surfacing.

Approach. The derived aggregate also computes streaks and flags notable calls and misses, and the karma analytics page was extended with a cumulative trend line and a karma-by-tournament-experience histogram, each backed by its own derivation over the match list.

Artifact.

"streaks": { "longestPositive": 10, "longestRedCard": 4 }

Result. A best run of ten straight positive verdicts against a worst run of four RedCards — the shape of a predictor that is genuinely streaky, not lucky. Every one of these figures traces back to the same 104 outcomes, which is the only promise the karma system actually makes: the score is whatever the results say it is.

Karma & Accountability
  • slugkarma-accountability-0
  • contentPart of the [Paulopus](/plant/paulopus#execution) case study. A prediction product that never keeps score is just an opinion generator. The whole point of Paulopus was to let the octopus commit to a scoreline before kickoff and then be graded, in public, against what actually happened. Karma is the accountability layer that makes the bragging cost something. This is how it was scored, graded, derived, and displayed — across 104 graded matches ending at a net karma of +25. ## Four verdicts, deliberately asymmetric **Decision.** Every locked prediction resolves into exactly one of four verdicts, and the reward curve had to punish confidently-wrong calls, not just fail to reward them. A binary hit/miss would have let the octopus fire off safe draws forever with no downside. **Approach.** The karma scorer is a deterministic function with a full verdict test matrix — same inputs always produce the same verdict, no model in the loop. Exact scoreline is Perfect, right result and goal-difference feel is Inspired, wrong-but-not-embarrassing is Missed, and a wrong result — the 1X2 outcome itself was wrong — is a RedCard, the only verdict that subtracts. **Artifact.** | Verdict | Points | | --- | --- | | Perfect | +1.5 | | Inspired | +1 | | Missed | 0 | | RedCard | -1 | **Result.** Perfect started at +2 and was later cut to +1.5 to narrow the reward gap versus the other three, which stayed unchanged; because grading is derived, that single constant change re-graded every finished match automatically rather than requiring a data migration. ## Grading on what actually happened, not the 90th minute **Decision.** Early on, matches were graded against the 90-minute regulation score. In a knockout tournament that quietly lies: a game level after 90 minutes but won on penalties should not read as a missed result when the octopus called the right winner. **Approach.** Scoring was reworked to grade on the *played* score — extra time if it exists, otherwise regulation, with penalty shootouts excluded as goals — and on the *real* winner, meaning whoever advanced, decided by shootout when the played score is level. Each match record carries a `decidedBy` field so the rule knows which score to trust. **Artifact.** ```json { "matchId": "M099", "stage": "qf", "predicted": "1-2", "actual": "1-2", "verdict": "Perfect", "decidedBy": "extra_time" } ``` **Result.** Nine knockout matches decided beyond 90 minutes had been graded wrong under the old rule. Regrounding them moved the karma total from 15.5 to 25.0 and the appreciation text was rewritten to match the corrected verdicts, so the ledger and the octopus's own words agree. ## A ledger with nothing to drift **Decision.** The obvious design is to store a running karma total and update it as results land. The obvious design is also how totals silently desync from the matches that supposedly produced them. **Approach.** There is no stored ledger. Karma is derived on read from the match records themselves — counts, net total, and streaks are all recomputed from the same list every time the page loads. The score-sync step re-grades each finished match rather than mutating a total, so the only source of truth is the outcomes. **Artifact.** ```json "aggregate": { "counts": { "Perfect": 14, "Inspired": 39, "Missed": 16, "RedCard": 35 }, "netKarma": 25, "graded": 104, "ungraded": 0 } ``` **Result.** Net karma is just `14×1.5 + 39×1 + 16×0 + 35×(−1) = 25`. Nothing to reconcile, nothing to backfill: the aggregate is a pure function of 104 verdicts, so it cannot disagree with the rows it came from. ## Four graded matches with no prediction on file **Decision.** The prediction model was rebuilt mid-project — write-once locks were replaced by a regenerable drafts revision history so a pronostic could be revised right up to kickoff. Four already-played matches now carry a verdict but no prediction on file; they appear to have lost their originating prediction somewhere in that migration. They still had to count. **Approach.** Verdict and points are stored on each match and were preserved through the migration, so grading survives even where the source scoreline did not. The four affected records (M001, M002, M007, M019) carry `"predicted": null` but keep their verdict and are included in every aggregate. **Artifact.** ```json { "matchId": "M002", "predicted": null, "actual": "2-1", "verdict": "RedCard", "points": -1 } ``` **Result.** Two of the four are RedCards, one Inspired, one Missed. They are baked into the 104 count, the +25 net, and the streak math — which is exactly why the numbers on this page match the octopus's own karma page rather than some cleaner recomputed figure. Accountability includes owning the calls whose paperwork got lost. ## The gauge that can't lie about its own colors **Decision.** The karma page needed to show the full shape of the record at a glance, not just a headline number, and its earlier two-cell display (only Inspired and Red Cards) hid the Perfects and Misses. **Approach.** The home page's proportional verdict gauge was extended to render all four counts, each tinted from one shared `VERDICT_PALETTE` so the segment, the count, and the badge for a given verdict draw from the same color and can't drift apart. The gauge renders verdict share proportionally and is shown together with the running karma score. **Artifact.** | Verdict | Count | Share of 104 | | --- | --- | --- | | Perfect | 14 | 13% | | Inspired | 39 | 38% | | Missed | 16 | 15% | | RedCard | 35 | 34% | **Result.** The breakdown reads honestly: the octopus is right-ish (Perfect plus Inspired) 53 times out of 104, and dead wrong 35 times. The gauge shows the RedCard third instead of burying it, which is the point of an accountability page. ## Streaks and the analytics behind the swagger **Decision.** A net total flattens the story. A run of ten good calls and a run of four RedCards are both accountability facts worth surfacing. **Approach.** The derived aggregate also computes streaks and flags notable calls and misses, and the karma analytics page was extended with a cumulative trend line and a karma-by-tournament-experience histogram, each backed by its own derivation over the match list. **Artifact.** ```json "streaks": { "longestPositive": 10, "longestRedCard": 4 } ``` **Result.** A best run of ten straight positive verdicts against a worst run of four RedCards — the shape of a predictor that is genuinely streaky, not lucky. Every one of these figures traces back to the same 104 outcomes, which is the only promise the karma system actually makes: the score is whatever the results say it is.
  • date2026-07-24
  • descriptionThe accountability layer: four deliberately asymmetric verdicts, grading on the score actually played rather than the ninetieth minute, and a ledger derived on every read so the total can never drift from the 104 matches that produced it.
  • nameKarma & Accountability
  • typearticle
  • statepublished