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
2 changes: 1 addition & 1 deletion PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ code-review platform. Production work includes:

## Non-goals

- Ranking humans on a public leaderboard
- Treating the evidence-linked `contributor × subsystem` leaderboard as a global ability, employment or performance ranking
- Automatically deciding whose fault an incident was
- Letting high-history contributors bypass baseline controls
- Treating vector similarity as causal evidence
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ PR ships → canary fails in production → operator confirms the causal linkage

The reviewer is deliberately disposable. Kill it mid-demo and its successor boots with **zero prior messages**, reads the contract from MongoDB, and blocks a PR that its predecessor would have waved through. That behavioral delta — not a longer prompt — is the whole claim.

**How it frames people.** The Elo is on the *change*, not the author. PR-Elo rates how much proven evidence a pull request must carry to enter a subsystem — a rating that moves when a canary proves something, never a rating of an engineer.
**How it frames people.** Enforcement stays on the *change*: no contributor score can waive a required check. The live demo also shows a transparent `contributor × subsystem` review-confidence score, computed from linked evidence events rather than inferred ability. It answers “how much proof has this contributor recently carried in this area?”, not “how good is this engineer?”

| Rule | What it means |
|---|---|
| 🎯 **The change is what's rated** | Output is a *review-depth requirement* on a PR entering a subsystem. Standing is scoped `contributor × subsystem`, read as history — never published as a global developer score. |
| 🎯 **The change is still gated** | Output is a *review-depth requirement* on a PR entering a subsystem. Contributor history can increase scrutiny but never remove baseline controls. |
| ❓ **Unknown by default** | States are `unknown · building · proven · proof-debt`. No evidence ≠ trusted, and ≠ suspect. |
| 🏛️ **Organizational, not personal** | A confirmed payments failure guards *every* future payments PR, regardless of author. |
| ↩️ **Recovery is always open** | Proof debt is paid down by executed evidence; contracts unlock. |
Expand Down Expand Up @@ -147,7 +147,7 @@ Embeddings run **locally** (`Xenova/all-MiniLM-L6-v2`, 384-dim) — no embedding
| Surface | Path | What it is |
|---|---|---|
| **Canonical demo** | `receipts/public/` | The operator console (numbered controls) and the live stage screen. Backed by real MongoDB writes and driven by change streams over SSE. **This is what runs on stage.** |
| **Live GitHub proof** | `receipts/public/live.html` | A PR targeting an authorized fork triggers a signed webhook, becomes an idempotent MongoDB receipt, is reviewed by the disposable worker and receives a GitHub commit status plus review comment. |
| **Live GitHub proof** | `receipts/public/live.html` | A PR targeting an authorized fork triggers a signed webhook, becomes an idempotent MongoDB receipt, is reviewed by the disposable worker and receives a GitHub commit status plus review comment. The same page recomputes an evidence-linked contributor leaderboard from MongoDB. |
| **Product vision** | `receipts/web/` | React 19 + TypeScript strict + Vite 8 + Tailwind v4. Routes: `/` Courtroom (live stream), `/contributor/:id` Dossier, `/review/:id` Case File, with a control-condition compare at `/review/rev-512`. Dark/light, WCAG AA tokens, `prefers-reduced-motion` parity. Design spec: [`receipts/web/DESIGN.md`](receipts/web/DESIGN.md) — *"a microfiche reader in a dark evidence room."* |

**Honest boundary:** the React UI runs on **fixture replay** and is not yet wired to the MongoDB API — it renders the product this becomes, not live data. The mechanics claims in this README are all proven by the `public/` demo and the source referenced above.
Expand Down Expand Up @@ -191,6 +191,8 @@ Forward events only to `POST /webhooks/github` through a one-way relay such as S

The webhook acknowledges only after its delivery ID is durably recorded. The worker fetches the real GitHub patch, maps changed paths to a subsystem, lets MongoDB contracts select scrutiny and posts the result as `PR-Elo / persistent review`. Replayed delivery IDs and repeated publications are deduplicated in MongoDB; startup recovery retries both interrupted deliveries and reviewed receipts whose GitHub publication did not finish.

The live leaderboard starts each `contributor × subsystem` scope at 100. Missing required evidence is −5, review concerns are −3, a public auto-revert is −6, a corrective re-land is +4 and verified evidence is +3. The MongoDB contributor rows are a disclosed Aug 6–13 public sample; the `gorajing` row is calculated from append-only verdict events on actual signed-webhook receipts in the demo fork. A repaired PR keeps its earlier failure event before adding its recovery event. Every movement links to its public PR or commit. This is a demo review-readiness signal, not an employment or performance metric.

<details>
<summary><b>Optional checks & the product-vision UI</b></summary>

Expand Down
46 changes: 45 additions & 1 deletion receipts/public/live.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
.memory{margin-top:16px;padding:17px;border:1px dashed #625c48;background:#1c1912}.memory h3{margin:8px 0 7px;font:600 20px Georgia,serif}.memory p{color:#c9c4b4;margin:0;line-height:1.5}.memory .source{margin-top:11px;font:11px/1.5 ui-monospace,monospace;color:var(--muted)}
.timeline{list-style:none;padding:0;margin:14px 0 0}.timeline li{display:grid;grid-template-columns:12px 1fr;gap:12px;padding:0 0 19px;color:var(--muted);line-height:1.4}.timeline li:before{content:"";width:9px;height:9px;border-radius:50%;background:var(--line);margin-top:5px;box-shadow:0 0 0 5px #ffffff05}.timeline li.done:before{background:var(--green)}.timeline b{color:var(--ink);display:block;font-size:13px}.timeline span{font:11px ui-monospace,monospace}
.empty{color:var(--muted);padding:46px 0;text-align:center;font:15px/1.6 Georgia,serif}.foot{margin-top:16px;display:flex;justify-content:space-between;gap:16px;color:var(--muted);font:11px ui-monospace,monospace}.btn{display:inline-flex;margin-top:16px;padding:10px 13px;border:1px solid var(--line);text-decoration:none;font:700 11px ui-monospace,monospace;text-transform:uppercase;letter-spacing:.1em}
.board{margin-top:16px}.board-head{display:flex;align-items:end;justify-content:space-between;gap:24px}.board-head h2{font-size:clamp(26px,3vw,38px)}.board-copy{max-width:570px;margin:8px 0 0;color:var(--muted);font:13px/1.5 ui-monospace,monospace}.legend{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:7px}.legend span,.band{border:1px solid var(--line);padding:6px 8px;color:var(--muted);font:700 10px/1 ui-monospace,monospace;text-transform:uppercase;letter-spacing:.06em}.legend .negative{color:var(--red)}.legend .positive{color:var(--green)}
.leaderboard{list-style:none;padding:0;margin:20px 0 0;border-top:1px solid var(--line)}.leader-row{display:grid;grid-template-columns:40px minmax(180px,1.1fr) minmax(160px,.9fr) 110px minmax(210px,1.2fr);gap:14px;align-items:center;min-height:78px;border-bottom:1px solid var(--line)}.leader-row.current{background:linear-gradient(90deg,#f0a92f13,transparent);box-shadow:inset 3px 0 var(--amber)}.rank{color:#6f6b60;font:600 22px Georgia,serif;text-align:center}.who a{font:700 15px ui-monospace,monospace;text-decoration:none}.who small,.scope small,.event small{display:block;margin-top:6px;color:var(--muted);font:10px/1.35 ui-monospace,monospace}.you{display:inline-block;margin-left:7px;padding:3px 5px;background:var(--amber);color:#18130b;font:900 9px/1 ui-monospace,monospace;letter-spacing:.08em;vertical-align:2px}.scope{font:13px/1.3 Georgia,serif}.score{text-align:right}.score strong{display:block;font:600 33px/1 Georgia,serif}.movement{font:800 11px ui-monospace,monospace}.movement.down{color:var(--red)}.movement.up{color:var(--green)}.band{display:inline-block;margin-top:5px;padding:4px 6px}.band.elevated{color:var(--amber)}.band.maximum{color:var(--red)}.event{font:12px/1.35 Georgia,serif}.event a{text-decoration-color:#706b5d;text-underline-offset:3px}.transition{color:var(--muted);font:10px ui-monospace,monospace}.board-empty{padding:25px 0;color:var(--muted);font:13px ui-monospace,monospace}
@media(max-width:900px){.leader-row{grid-template-columns:32px 1fr 100px}.scope{grid-column:2}.event{grid-column:2/4;padding-bottom:14px}.board-head{align-items:start;flex-direction:column}.legend{justify-content:flex-start}}
@media(max-width:800px){.pipeline{grid-template-columns:1fr 1fr}.grid{grid-template-columns:1fr}header{display:block}.live{margin-top:16px}}
</style>
</head>
Expand All @@ -32,13 +35,53 @@
<section class="card" id="case"><div class="empty">Open a pull request against <b>gorajing/mongo</b>.<br>The live case will appear here without pressing a button.</div></section>
<aside class="card"><div class="label">Evidence chain</div><ol class="timeline" id="timeline"></ol><div class="memory" id="memory"><div class="label">Persistent memory</div><h3>Loading organizational contract…</h3></div></aside>
</div>
<section class="card board" aria-labelledby="leaderboard-title">
<div class="board-head"><div><div class="label">Evidence ledger · Aug 6–13 + live fork</div><h2 id="leaderboard-title">Contributor review confidence</h2><p class="board-copy">Evidence-readiness within one subsystem, not an employee-performance rating. Every movement links to the PR, revert or corrective re-land that caused it.</p></div><div class="legend" id="score-legend"></div></div>
<ol class="leaderboard" id="leaderboard"><li class="board-empty">Loading evidence-linked scores…</li></ol>
</section>
<div class="foot"><span id="updated">Not updated yet</span><span>The reviewer can die. The lesson remains.</span></div>
</main>
<script>
const byId = (id) => document.getElementById(id)
const esc = (value) => String(value ?? '').replace(/[&<>"']/g, (ch) => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[ch]))
const time = (value) => value ? new Date(value).toLocaleTimeString([], {hour:'2-digit',minute:'2-digit',second:'2-digit'}) : 'pending'
const setStep = (id, on, text) => { byId(id).classList.toggle('on', Boolean(on)); byId(id.replace('step-','') + '-state').textContent = text }
const githubUrl = (value) => /^https:\/\/github\.com\//.test(value || '') ? value : null

function renderLeaderboard(leaderboard) {
const rows = leaderboard?.rows || []
const scoring = leaderboard?.scoring
if (scoring) {
const signed = (value) => value > 0 ? '+' + value : String(value)
byId('score-legend').innerHTML = [
['baseline ' + scoring.baseline, ''],
['missing evidence ' + signed(scoring.deltas['missing-evidence']), 'negative'],
['auto-revert ' + signed(scoring.deltas['auto-revert']), 'negative'],
['corrective re-land ' + signed(scoring.deltas['corrective-reland']), 'positive'],
].map(([label, tone]) => '<span class="' + tone + '">' + esc(label) + '</span>').join('')
}
if (!rows.length) {
byId('leaderboard').innerHTML = '<li class="board-empty">Seed the bounded public evidence sample to load contributor scores.</li>'
return
}
byId('leaderboard').innerHTML = rows.map((row, index) => {
const latest = row.events?.[row.events.length - 1]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Render links for every event included in the score

For any row with multiple scored events, selecting only latest hides all earlier evidence links and transitions even though those events still contribute to the displayed total. For example, the documented two-blocked-PR row shows a −10 movement but exposes only the second PR's 95→90 transition, preventing users from auditing the first −5; render the full event list or otherwise provide access to every contributing event.

Useful? React with 👍 / 👎.

const movement = row.movement > 0 ? '+' + row.movement : String(row.movement)
const movementTone = row.movement > 0 ? 'up' : (row.movement < 0 ? 'down' : '')
const profileUrl = githubUrl(row.profileUrl)
const eventUrl = githubUrl(latest?.url)
const handle = profileUrl ? '<a href="' + esc(profileUrl) + '" target="_blank" rel="noreferrer">@' + esc(row.handle) + '</a>' : '@' + esc(row.handle)
const eventLabel = latest?.label || 'No scored failure in the bounded sample'
const event = eventUrl ? '<a href="' + esc(eventUrl) + '" target="_blank" rel="noreferrer">' + esc(eventLabel) + ' ↗</a>' : esc(eventLabel)
const transition = latest ? latest.from + ' → ' + latest.to + ' · ' + (latest.delta > 0 ? '+' : '') + latest.delta : 'baseline retained'
return '<li class="leader-row ' + (row.isCurrentUser ? 'current' : '') + '">' +
'<div class="rank">' + (index + 1) + '</div>' +
'<div class="who">' + handle + (row.isCurrentUser ? '<span class="you">YOU · LIVE</span>' : '') + '<small>' + esc(row.repo) + '</small></div>' +
'<div class="scope">' + esc(row.subsystem) + '<small>' + esc(row.basis) + '</small></div>' +
'<div class="score"><strong>' + esc(row.score) + '</strong><span class="movement ' + movementTone + '">' + esc(movement) + '</span><br><span class="band ' + esc(row.band?.key) + '">' + esc(row.band?.label) + '</span></div>' +
'<div class="event">' + event + '<small class="transition">' + esc(transition) + '</small></div></li>'
}).join('')
}

function render(data) {
const delivery = data.delivery, receipt = data.receipt, publication = data.publication
Expand Down Expand Up @@ -77,6 +120,7 @@
[publication?.status === 'published', 'Verdict posted back to GitHub', publication && publication.verdict + ' · ' + time(publication.publishedAt)]
]
byId('timeline').innerHTML = events.map((item) => '<li class="' + (item[0] ? 'done' : '') + '"><div><b>' + esc(item[1]) + '</b><span>' + esc(item[2] || 'pending') + '</span></div></li>').join('')
renderLeaderboard(data.leaderboard)
byId('updated').textContent = 'last read ' + time(data.now)
}

Expand All @@ -87,7 +131,7 @@
const source = new EventSource('/events')
source.onopen = () => { byId('connection').textContent = 'live MongoDB stream' }
source.onerror = () => { byId('connection').textContent = 'reconnecting' }
for (const name of ['github_delivery','receipt','reviewer','publication','contract']) source.addEventListener(name, refresh)
for (const name of ['github_delivery','receipt','reviewer','publication','contract','leaderboard']) source.addEventListener(name, refresh)
refresh()
setInterval(refresh, 2500)
</script>
Expand Down
2 changes: 1 addition & 1 deletion receipts/src/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ function reviewComment(receipt, result, key, targetUrl) {
`**Why this scrutiny:** ${memory}`,
...(unmet ? ['', unmet] : []),
'',
`Reviewer: \`${receipt.review.by}\` · Mongo receipt: \`#${receipt.prNum}\` · Contributor credibility unchanged`,
`Reviewer: \`${receipt.review.by}\` · Mongo receipt: \`#${receipt.prNum}\` · Subsystem review-readiness event recorded`,
...(targetUrl ? [`[Open the live review receipt](${targetUrl})`] : []),
].join('\n');
}
Expand Down
113 changes: 113 additions & 0 deletions receipts/src/leaderboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
const BASELINE = 100;

const DELTAS = Object.freeze({
'missing-evidence': -5,
'review-concerns': -3,
'auto-revert': -6,
'corrective-reland': 4,
'verified-evidence': 3,
});

function dateValue(value) {
const time = new Date(value).getTime();
return Number.isFinite(time) ? time : 0;
}

export function scoreEvents(events, baseline = BASELINE) {
let score = baseline;
const scored = [...events]
.sort((left, right) => dateValue(left.at) - dateValue(right.at))
.map((event) => {
const delta = DELTAS[event.kind] ?? 0;
const from = score;
score += delta;
return { ...event, delta, from, to: score };
});
return { score, trend: [baseline, ...scored.map((event) => event.to)], events: scored };
}

function eventKind(status) {
if (status === 'blocked') return 'missing-evidence';
if (status === 'concerns') return 'review-concerns';
if (status === 'approved') return 'verified-evidence';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restrict verified-evidence credit to actual evidence

When a PR has no active contract, the standard review path can approve it without checking any evidence, yet this status-only mapping records a verified-evidence event and adds +3. Consequently, ordinary approved GitHub PRs inflate the public evidence-readiness score even when receipt.evidence is empty; create this event only when the reviewer has actually validated the required evidence, and leave ordinary approvals unscored.

Useful? React with 👍 / 👎.

return null;
}

export function reviewEventForReceipt(receipt, status = receipt.status, at = null) {
const kind = eventKind(status);
if (!kind) return null;
const number = receipt.github?.number ?? receipt.prNum;
return {
kind,
status,
at: at ?? receipt.github?.publication?.publishedAt ?? receipt.ts,
label: `PR #${number} ${status}`,
url: receipt.github?.htmlUrl ?? null,
source: receipt.github?.repository ?? 'MongoDB receipt',
};
}

function receiptEvents(receipt) {
if (!receipt.reviewEvents?.length) {
const current = reviewEventForReceipt(receipt);
return current ? [current] : [];
}
return receipt.reviewEvents
.map((event) => {
const generated = reviewEventForReceipt(receipt, event.status, event.at);
return generated ? { ...generated, ...event } : null;
})
.filter(Boolean);
}

function reviewBand(score) {
if (score >= 100) return { key: 'normal', label: 'normal review' };
if (score >= 90) return { key: 'elevated', label: 'elevated review' };
return { key: 'maximum', label: 'maximum review' };
}

export function buildContributorLeaderboard({ profiles, receipts }) {
const byScope = new Map(
profiles.map((profile) => [`${profile.handle}\u0000${profile.subsystem}`, { ...profile }]),
);

for (const receipt of receipts) {
if (!receipt.author || !receipt.subsystem || !receipt.github) continue;
const key = `${receipt.author}\u0000${receipt.subsystem}`;
if (!byScope.has(key)) {
byScope.set(key, {
handle: receipt.author,
repo: receipt.github.repository,
subsystem: receipt.subsystem,
isCurrentUser: receipt.author === 'gorajing',
events: [],
});
}
}

const rows = [];
for (const profile of byScope.values()) {
const liveEvents = receipts
.filter((receipt) => receipt.author === profile.handle && receipt.subsystem === profile.subsystem)
.flatMap(receiptEvents);
const scored = scoreEvents([...(profile.events ?? []), ...liveEvents]);
rows.push({
handle: profile.handle,
repo: profile.repo,
subsystem: profile.subsystem,
isCurrentUser: Boolean(profile.isCurrentUser),
profileUrl: profile.profileUrl ?? `https://github.com/${profile.handle}`,
basis: profile.basis ?? 'Live PR-Elo receipts',
...scored,
movement: scored.score - BASELINE,
band: reviewBand(scored.score),
});
}

return rows.sort((left, right) => right.score - left.score || left.handle.localeCompare(right.handle));
}

export const leaderboardScoring = {
baseline: BASELINE,
deltas: DELTAS,
};
29 changes: 28 additions & 1 deletion receipts/src/ops.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import { client } from './db.js';
import { embed } from './embed.js';
import {
contributors, receipts, incidents, contracts, nextSeq, VECTOR_INDEX,
contributors, receipts, incidents, contracts, leaderboardProfiles, nextSeq, VECTOR_INDEX,
} from './schema.js';
import { buildContributorLeaderboard, leaderboardScoring } from './leaderboard.js';

export async function submitPR({
author, subsystem, changeType = 'feature', title, code, fnName = null,
Expand Down Expand Up @@ -203,3 +204,29 @@ export async function standing() {
}
return rows;
}

/**
* Public, evidence-linked review readiness beside the live fork contributor.
* Profiles provide bounded public history; live GitHub receipts provide the
* score movements that judges can watch happen in this session.
*/
export async function contributorLeaderboard() {
const [profiles, githubReceipts] = await Promise.all([
leaderboardProfiles().find({ active: true }).toArray(),
receipts().find(
{ 'github.repository': { $type: 'string' } },
{
projection: {
prNum: 1, author: 1, subsystem: 1, status: 1, ts: 1,
reviewEvents: 1,
'github.number': 1, 'github.repository': 1, 'github.htmlUrl': 1,
'github.publication.publishedAt': 1,
},
},
).toArray(),
]);
return {
rows: buildContributorLeaderboard({ profiles, receipts: githubReceipts }),
scoring: leaderboardScoring,
};
}
Loading