Skip to content
Work

Rubric Playground

Re-weight a real investment screen and watch the shortlist re-rank, with every score traceable to its rubric anchor.

Role
Analysis, scoring engine and interface
Year
2026
Stack
Next.js, TypeScript, Motion, Python parity tests
Links
Source
Impact35.0%
Bottleneck35.0%
Fit30.0%
Hard filters
12 of 12 companies match the Python screener's output
  1. Oxyle

    Due Diligence
  2. Puraffinity

    Due Diligence
  3. Previsico

    Watchlist
  4. Hydraloop

    Watchlist
  5. Detektia

    Watchlist
  6. SolarDew

    Watchlist
  7. Fluves

    Screened & Declined
Why
I built a Python screener on Aurum Impact's published investment criteria. Does its ranking survive other priorities?
Cut
I left out generated explanations (every reason is a written rubric anchor), adding companies, and shareable score edits.
Limits
Scores are my judgement, not measurement; independent work, not affiliated with or endorsed by Aurum Impact, and not investment advice.
(long! unless you're a VC)

How it scores

Hard filters reject on mandate, never on quality: geography (Europe), stage (pre-seed to Series A) and scope (deferred segments, defence, non-equity legal forms). Survivors get twelve scores from 0 to 5, each against a written anchor, weighted Impact 35, Bottleneck 35, Fit 30. A source that is only self-reported costs 5%. Tiers start at 72, 60 and 48. Then check_consistency compares scores with structural priors, such as a municipal buyer with a fast sales cycle, and raises the question a committee would ask.

The port

Python in the browser means megabytes of WebAssembly, so I ported the engine line by line and test it against the screener's committed shortlist.csv. Same summation order, multiply before divide, haircut after the sum, and round() reproduced half-to-even on the exact float. Weights are stored as integers per mille, so Reset restores bit-identical weights.

scoring.py
composite = sum(cr.weight * _get(c, cr.key) / 5.0 for cr in ALL_CRITERIA) * 100.0

has_unverified = any(e.confidence == "unverified" for e in c.evidence)
if has_unverified or not c.evidence:
    composite *= UNVERIFIED_PENALTY

composite = round(composite, 1)
scoring.ts
let composite = pySum(ALL_CRITERIA.map((cr) => (weights[cr.key] * getScore(c, cr.key)) / 5.0)) * 100.0;
const haircutApplied = config.haircut && hasUnverifiedTraction(c);
if (haircutApplied) composite *= UNVERIFIED_PENALTY;

const rounded = pyRound(composite, 1);

What the numbers say

Oxyle leads Puraffinity by 0.1 points. Its composite is 75.0499999999999972 as a float. Python prints 75.0; Math.round(x * 10) / 10 prints 75.1, a number the screener never produced.

All 7 scored companies carry an unverified claim, so the haircut never reorders them. It does decide a tier: without it Previsico moves from 58.9 (Watchlist) to 62.0 (Closer Screening).

Two earlier claims did not survive the faithful port. The top two do change as Bottleneck sweeps from 0 to 80%: at 66%, 74%, 78% they tie at one decimal, and Python's last tie-break, file order, puts Puraffinity first. And ranks 3 to 7 swap at 11%, 22%, 28%, 44%, 45%, 69%, not 23% for the second.

Rank of each scored company as the Bottleneck weight sweeps from 0 to 80 percentAt 80 percent the order is Oxyle, Puraffinity, Previsico, Detektia, Fluves, Hydraloop, SolarDew. Puraffinity takes first place at 66%, 74%, 78% through a one-decimal tie.12345670%20%35% Aurum40%60%80%OxylePuraffinityPrevisicoDetektiaFluvesHydraloopSolarDew
Rank as Bottleneck sweeps from 0 to 80%, Impact and Fit sharing the rest 35 : 30. Red ticks: ties settled by file order.

The stability band redraws 400 weightings around yours, each criterion weight scaled by 0.5 to 1.5 from a seeded PRNG. At Aurum's weights Oxyle ranks first in 54% of them, Puraffinity in 46%.

Funnel: 12 screened, 5 out on mandate, 2 to due diligence, 4 to the watchlist, 1 declined on score. 8 of 9 segments have nothing above the watchlist.

A vitest suite ports the screener's tests (weight audit, filter integrity, determinism, a missing score throws) and pins every number here.

Limits

The universe is hand-built from public sources, so it favours companies with funding news; stealth companies are absent by construction. The band perturbs weights, never scores. Data as of 25 Aug 2026; claims marked unverified are self-reported. The committed CSV names two columns outcome_kpi, so the KPI text is overwritten by the score.

NextSettlement Desk