Work
Live · closed testing · 2026

Antumbra

A voice with rules, and a checker for every rule — so the model can't drift into jargon, flattery, or claims nobody can check.

antumbra.space ↗︎
Antumbra — the cover screen
The map
The cover
The archive

Four systems, one straight answer.

Western astrology, bazi, zi wei dou shu, and six questions about this particular relationship. When they disagree, the questions win. Black, white, and nothing in between — the whole product sits inside one CRT.

Role
Product, interface, AI behaviour, code — one person
Status
Live · closed testing
Built in
7 days · 72 commits
Model's job
Writes the sentence. Decides nothing.
Checks
22 scripts, one per rule
Stack
Next.js 16 · Neon Postgres · Claude
Code · decides
Western chart · bazi · zi wei dou shu · your six answers
score
78
phase
0.71
flag
initiating is one-sided
direction
holds
Deterministic. Same input, same numbers, every time.
Model · writes

You do the reaching, and you aren't tired afterwards — which is the part that matters.

Gets the conclusion as a brief. Cannot change a number, a flag, or a direction.
Code · checks
  • jargon
  • model tells
  • echo of one answer
  • contradicts the numbers
  • unfalsifiable
  • repetition
Any hit → rewrite → check again. Loops until clean, then ships.

The code decides what. The model only writes it.

Score, position, flag, direction — computed, none of it passes through a language model. The model gets a finished conclusion and makes it read like a person wrote it.

Antumbra · review layerInteractive · press Write itWaiting
COMPUTED · FIXED
initiator me
you reach out first, almost always
frequency daily
in touch most days
candor honest
you can say the hard thing
after same
not drained afterwards
score 78
phase 0.71 · gives back more than it takes
flag the initiating is one-sided
direction holds

None of this passed through a model. The model gets it as a brief and writes.

Checkers

A working model of the review layer. The checks are the product's real rules — the jargon table, the model-tell patterns, “built from one answer is an echo” — running here in the browser; the model's drafts and rewrites are scripted. Switch a checker off and run it again to see what ships.

A rule without a checker isn’t a rule. It’s a hope.

Press Write it. The checks are the product’s real ones, running in your browser. Switch one off and see what ships.

the voice
check:voicecheck:echocheck:judgecheck:talkcheck:askcheck:traitscheck:self
the numbers
check:hardcheck:scorecheck:paircheck:daycheck:luckcheck:standingcheck:forks
the page
check:flowcheck:structurecheck:mapcheck:worldcheck:footercheck:startcheck:logocheck:emit
22 scripts · npm run check:*package.json · 4 Sep 2026

One script per rule.

If a rule matters, there is a command that fails when it’s broken. Voice, numbers, page — twenty-two of them.

ROOTSREFUGEALONGSIDEPULLXiyu WangXiyu WangHaminHaminGuoGuoRachelYayaMomMomTanoXuxiAnnieRosannaNannan Le

The map, centred on you. Positions are computed, not draggable. Phase is how much a relationship gives back; size is how often you're in touch; a flat orbit swings close and distant. Redrawn from the demo account's real geometry.

The map, centred on you.

Phase is how much a relationship gives back. Size is how often you’re in touch. A flat orbit swings close and far. Positions are computed, not draggable.

  • Change 01

    “My best friend and I scored so low, I want to retake it.”

    Wrong · The score came almost entirely from two birth charts. Not one of her answers about the relationship went in.
    Now · Driven by the answers, chart as a correction. 0 and 100 are both reachable.
  • Change 02

    Every reading found a flaw — even the ones that scored 90.

    Wrong · “What to watch” was a required field in the output shape. A flaw was decided before any data was read.
    Now · Follows a computed list. Empty list → it writes the boundary and invents nothing.
  • Change 03

    You answer that you always reach out first. It tells you that you always reach out first.

    Wrong · A conclusion built from a single answer reads like a finding and carries no information.
    Now · Hard rule: one input can't become a line. It has to cross two, or come from the computed layer.

The ruler changed three times.

Every change is written down in public under What changed, and each entry has to say what the previous version got wrong.

Commits per day · 29 Aug – 4 Sep 2026 · git log72 commits · 7 days · one person
1Aug 2911Aug 3010Aug 3113Sep 0113Sep 0217Sep 037Sep 0412345
  1. 1Aug 29 · First commit: cover, forms, charts, verdict, map. Called Verdict.
  2. 2Aug 30 · Renamed Antumbra. Privacy and terms. Gazetteer rebuilt.
  3. 3Sep 02 · Review layer for the voice. Score redefined: 0 and 100 reachable.
  4. 4Sep 03 · Echo rule: one answer can't become a finding. Cover opened to everyone.
  5. 5Sep 04 · Repetition checker. About, How it works, Pricing. Closed testing.

Seven days from first commit to closed testing.

Next.js 16, Drizzle on Neon, next-auth. The hard layer is deterministic — astronomia, lunar-javascript, iztro, a gazetteer. The soft layer is Claude, given a fixed conclusion and asked only to write it.

What I'd do next

  1. 01
    Open the closed test
    Fifty readers, and the first ‘What changed’ entry written from someone else’s complaint rather than mine.
  2. 02
    A regression set for the voice
    Every rewrite the review layer has ever made, kept as a test — so a prompt change can’t quietly bring the jargon back.
  3. 03
    Make the map say why
    Tap a person, see the three numbers that put them there. The position is already computed; it should be able to explain itself.
← WorkMYLIFE