affterms — Sourced Affiliate Terms for Dev and SaaS Tools
Affiliate programme terms for developer and SaaS tools, every figure sourced and dated. Jev, a calibrated model, picks which pages a person re-reads.
Overview
In plain terms: if you promote developer tools, the headline commission is the least useful number in the deal. Whether it recurs, how long the cookie lasts and how much you must earn before a payout decide what you get paid. Most lists give you a name and a percentage, with no date and no source.
affterms is a directory of those terms — commission, recurring or one-time, cookie window, minimum payout, payout method and network — for 471 programmes (as of 24 Sept 2026). Every figure was read off the vendor's own page, links back to it, and carries the date it was checked. Where a vendor doesn't publish something, the site says not stated rather than guessing. 50 programmes are free on the site; the full directory is a paid CSV + PDF.
Visit affiliateprogramterms.com
The one rule
No figure goes in that wasn't read off the vendor's own page. One invented number destroys a directory whose only claim is that its numbers were checked. So the question for every piece of automation here is not "is it good?" but "can it put a figure in a record?" — and the answer is built to be no.
How the model is used, and fenced
Jev (TypeSafe's System One model) is a second reader. It gets a page code has already fetched and answers yes/no questions about it: is this the vendor's affiliate page? does it still say the cookie lasts 30 days? That's all. It never fetches, converts units, compares dates, writes a note or supplies a value.
It decides whether a person looks, never what the record says. The refresh re-reads every source, runs a free deterministic check that each published figure is still on the page, and asks Jev one yes/no per stated field — the question string matching can't ask. A person reads only what gets flagged. The one thing the tool may write is the checkedOn date, and only on a record where every check passed.
Why not let it extract? It was measured doing exactly that. Picking values from candidate spans, it beat the regex extractor — right on 49% of records against 42% — and was still wrong on 7% of what it asserted at ≥0.9 confidence. The rule is no unsourced facts, and 7% is not zero.
Recurrence is asked in pairs. A single "does commission repeat?" flagged 6 of 48 true records. Asking the claim and its opposite together, and flagging only when the opposite is affirmed: 0 of 48 true records flagged, 41–42 of 48 planted flips caught.
Calibrated, not trusted
Every threshold was measured against 68 pages a person had already read, plus 16 vendor homepages as negatives, with planted false claims to catch a reader that just says yes. The model is pinned to jev-1.13.0, because an alias that moves would move every threshold silently. calibrate_jev.py re-runs the whole battery and exits non-zero if a gate fails — so a reworded question can't slip through.
Some of what that measurement caught:
- "Commission rate" was read literally, so a flat "$100 per referral" came back "not stated".
- Adding "including saying it never expires" to the cookie question dropped agreement from 29/29 to 3/29.
- A drop line of 0.2 would have thrown out a real referral page (Jobber, 0.19). It sits at 0.1.
A full re-check costs about four cents — ~947k input tokens for 417 records, around five minutes, and the wall time is the fetches, not the model.
The pipeline
harvest → triage → intake → refresh.
- harvest sweeps candidate domains for programme pages. 79% of its 23,166 requests were 404 path probes, so there was no page for a model to judge — Jev can't make the sweep faster, and doesn't pretend to.
- triage asks two questions of each page that did come back — is it a programme page? does it state a term? — and routes it
drop,unsure,extractorno-terms, so a page that never was one doesn't reach a browser read. - intake is the only way in, for a sweep and a public submission alike. A submitted figure that isn't on the page is rejected automatically, and every figure a record carries is matched against the stored page text before it can merge — whoever wrote it, agent included.
- refresh re-reads everything and sends a person to what changed. On 24 Sept it re-read 413 records: 373 passed, 23 were read by hand, 6 were corrected.
In production
- Site: static, zero-dependency Node build on Cloudflare Pages. The build aborts and deletes its output if a paid record's figure reaches a page, or if a count was typed in rather than computed from the data.
- Payments: Dodo, live since 22 Sept 2026. A webhook grants the download; a claim endpoint verifies the payment against Dodo's own API, so a late or lost webhook leaves nobody charged and empty-handed.
- Delivery: files published once per edition to Cloudflare KV, served instantly and emailed through Resend.
- Tooling: the authoring tools are Python and the build never imports them. Without a Jev key everything still runs — it just does less.
Where it fits
Same idea as tally-aiagent and doceval: a model's answer is not evidence. Here it is allowed to point a person at a page, and nothing more.