No name and no account. The file holds weights and nothing that identifies anyone.
Weights run 0 to 5, and 3 is neutral. Ten shared value names (planet, people, openness, access, wellbeing, autonomy, animals, community, quality, joy) let one file work in every app.
An axis of value
One thing an option is measured on, and how it is known.
Apps that use the same key can share a values file. Two apps that both use environment can share a values file without translating it.
The tier says how the fact is known.measured is an open-data fact, shown exactly. certified is a third-party label. assessed is a researched judgement, which must cite a source and is shown as a band, never as a precise-looking number.
An option and its facts
Scores on the declared axes, each with where it came from.
{"code": "example-bank",
"name": "Example Bank",
"scores": { "environment":98 },1"provenance": { "environment": {
"note": "What the source says, in one line",
"source": "https://example.org/report",2"asof": "2026"
} }
}
A missing score means unknown, never zero. Leave the key out. Every key that is present must be an axis the lens declares, from 0 to 100.
Every judgement cites. A note, a source that resolves, and the date it was true, so anyone can check it or dispute it.
What the engine returns
A number, plus how much of it was known and what moved it.
Coverage comes with the score. This option was scored on 4 of the 7 things the reader cares about, and the score says so.
A dealbreaker cannot be averaged away. Here one heavily weighted axis scored 12, so the score is held at 49 whatever the others say.
Plate IIFig. 2. The scoring formula, running the reference engine.
The formula, worked
This runs the reference engine, the same engine.js file the app uses. One option, three axes. Change a weight, change a fact, or mark a fact as unknown, and see which of the three rules below applies.
AxisYour weight (0 to 5)The fact (0 to 100)
Climate
Fair pay
Price
Average of the known facts, by weight72.0
Coverage: weight on known facts / all weight5 / 8 = 0.625
72.0 × 0.625 + 50 × 0.37563.8
score64
050, neutral100
Fair pay is unknown, so 3 of the 8 weight points had no fact, and the score is pulled a little toward 50.
An unknown fact is left out. The score is pulled toward a neutral 50 by how much is unknown.
Exp. 2Too little known, no score
Below a quarter of what you care about, the engine returns nothing rather than a guess.
Exp. 3Dealbreakers hold
An axis you weight 4 or 5 that scores 20 or less caps the score at 49. A certification is the exception, because a 0 there means no label was found, which is missing paperwork, not harm.
What's happening. One option, three axes, and the reference engine itself, the same file the app runs. Each Try it button sets the inputs so that one rule applies.
Why it matters. An average is the obvious way to combine what someone cares about, and it misleads in two predictable ways: it treats a missing fact as a zero, and it lets a disaster on one axis hide behind good marks on the others. The first two rules answer the first; the cap answers the second.
Devil's advocate. The cap is crude on purpose. It is a flat 49, whatever the rest says. It used to fire on certifications too, where a 0 only means no label was found. On the open-data food comparisons that was 10,702 of 14,945 ethics scores in September 2026, so version 0.11 stopped treating missing paperwork as a verdict.
Rabbit hole. The engine is one plain file. Its score() function is 27 lines, six of them comments explaining the rules. Read it on GitHub.
What an app must keep to call itself compatible
An app can look and sound however it likes. These six stay the same, and five of them are checked by a validator anyone can run.
Rule
What it means
How it is checked
Fit to someone's values
A score says how well an option fits someone's stated values. It never says an option is good or bad for everyone.
Same facts with other weights must give another order
Every judgement cites
An assessed claim carries a note, a source and the date it was true.
Validator: provenance shape
Missing is not zero
Unknown facts are left out, pulled toward neutral, and withheld when too little is known.
Validator: score keys and 0 to 100 range
No pay-to-rank
Nothing in the files can encode sponsorship or paid placement.
Validator: no paid-placement fields
Values travel
A person's values file carries no identity and works in any compatible app.
Validator: values file shape
Any community's values
An app can bring its own value names and map them to the shared ten. The format favours none.
Validator: value-name mappings point at real axes
To check a lens you built: clone the source and run npm run audit:conformance, or add --passport=yourfile.json to check a values file.