Skip to content

Eighteen tajweed rules, two instruments for one displacement, and a register that knows the difference - #87

Merged
omars-lab merged 2 commits into
mainfrom
mark-registration-by-hand
Aug 12, 2026
Merged

Eighteen tajweed rules, two instruments for one displacement, and a register that knows the difference#87
omars-lab merged 2 commits into
mainfrom
mark-registration-by-hand

Conversation

@omars-lab

Copy link
Copy Markdown
Owner

What is here

Two commits, code then docs, over three threads that share a subject: what a mark is, and where it sits.

The tajweed shards widen from seven families to eighteen rules

The source names eighteen rules; the first pass through it collapsed them to seven families, and a reader who wants madd_2 coloured differently from madd_246 cannot say so through a vocabulary that already threw the distinction away. The shards are rebuilt at rule granularity, @hifth/core reads the wider vocabulary, and gate:tajweed holds the two in step.

The colour decision itself is opendocs/decisions/tajweed-colours.md, with its options page — and nothing reader-facing ships until it is answered.

Two instruments for one displacement

probe-mark-ink finds a per-page displacement between the rectangle we draw for a diacritic and the ink the print drew for it. The correction is a number nobody had looked at. Two ways to look, and they are deliberately two:

asks returns
pnpm adjudicate:marks which of these two rectangles is on the mark? a preference
pnpm nudge:marks put this rectangle where it belongs a magnitude

Neither page knows the answer while it is being worked: the plan is a pure function of the seed, so no key exists on disk until the scorer rebuilds it afterwards. The forced choice carries its own controls (catch trials, identical pairs, same-magnitude decoys in other directions). The placing session measures the reader's own precision from marks shown twice, in the same sitting, and refuses to call a residual smaller than that hand a finding.

Why not one page with a drag handle. Adjusting a rectangle inside a two-panel trial and then scoring the landing against the two starting positions is the answer key; adjusting after answering teaches the direction of the correction, which points the same way on nearly every page. The two sessions are scored separately, never summed, and should not be worked back to back by the same person.

The registers learn that a preference is not a distance

A forced choice yields one bit per trial, so it can confirm direction and is structurally incapable of confirming distance — and every threshold in mark-registration.md §⑦ is a claim about distance. So there are now two ledger checks, two issue rows, and a §⑩ ⑦ that states the gap. The older issue row is scoped rather than rewritten, so nobody later reads a preference as a distance.

Also along for the ride, from the same stretch: make session (a manual check opened as a sitting, with a transcript written while the walkthrough happens rather than after it), the decisions register and its gate, and CLAUDE.md.

Verification

  • make ci green (118.3 KB gz / 150 KB budget).
  • pnpm --filter @hifth/etl exec vitest run scripts/lib/adjudication.test.mjs — 16/16, including that no trial can be answered by leaving the rectangle where it appeared, that the starting directions cancel, and that a repeated mark's two showings are far enough apart to be a fresh judgement.
  • Both scorers exercised against three synthetic sessions (a real residual, an agreeing reader, and a lazy one) and each verdict sentence checked against the numbers that produced it.
  • grep over the built page confirms the proposed correction reaches no markup, no data attribute and no comment.
  • gate:validation, gate:issues, gate:map, gate:decisions, gate:tajweed, lint — all green.

What this does not do

It does not bank a verdict. Both sessions are owner: user and both block mark-C; the hour is a person's and cannot be spent by an agent.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EuhvbUKjGesE3uMhjCzBGt

omars-lab and others added 2 commits August 12, 2026 11:31
…x belongs

The tajweed shards carried seven families because that is what the first
reader of the source collapsed them to. The source names eighteen rules, and
a reader who wants to colour madd differently from madd cannot say so through
a vocabulary that has already thrown the distinction away. So the shards are
rebuilt at rule granularity, core reads the wider vocabulary, and gate:tajweed
holds the two in step.

Beside that, the marks. probe-mark-ink measures whether the rectangle we draw
for a diacritic sits on the ink the print drew for it, and finds a per-page
displacement worth correcting. That correction is a number nobody has looked
at, and this commit adds the two instruments that let somebody look:

  - a forced choice. Two rectangles, one panel each, nothing on screen saying
    which is ours, and no key written to disk until the scorer rebuilds it
    from the seed. It carries its own controls: obviously wrong rectangles to
    catch a session worked while distracted, identical pairs to catch a person
    who always picks something, and same-size displacements in other
    directions to measure whether an eye can resolve a shift this small at
    all. What it returns is a preference.

  - a placing session. One rectangle, started a fixed distance out in a
    direction that changes every trial, and the reader puts it where it
    belongs. Subtracting what we proposed from where it landed leaves a
    magnitude, reported against the reader's own precision, measured in the
    same sitting from the marks shown twice. A residual smaller than the hand
    that produced it is not a finding, and the scorer says so.

They are two sessions and not one page with a drag handle, for a reason worth
writing down: adjusting a rectangle inside a two-panel trial and then scoring
the landing against the two starting positions IS the answer key, and
adjusting after answering teaches the direction of the correction, which
points the same way on nearly every page.

Also here: make session, which opens a manual check as a sitting and writes a
transcript while the walkthrough happens rather than after it, and the
decisions register with its gate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EuhvbUKjGesE3uMhjCzBGt
Two rows where there was one. placement-correction-by-eye was carrying both
halves of a question it can only answer half of: a forced choice returns one
bit per trial, so it can confirm that our correction points the right way and
is structurally incapable of confirming that it goes far enough. Every
threshold in mark-registration.md's section 7 is a claim about distance.

So placement-residual-by-hand joins it in the ledger, section 10 item 7
states the gap in the design doc, and the issue that was open on the first
question is scoped rather than rewritten -- it now says what it can never
deliver, so that nobody six months from now reads a preference as a distance.
The two verdicts are scored separately and never summed, and the sessions
should not be worked back to back by the same person.

The other registers follow: four pointers in the code map, two rules in the
extend skill about instruments and about measuring the hand in the same
sitting as the thing the hand measured, and a transcripts README saying why
a sitting is written down as it happens.

Also here, from the same stretch of work: the decisions register and its
rendered face, the tajweed-colours record and its options page, the mark
granularity options page, mark-labels.md, and CLAUDE.md -- which says the
thing all of this is in service of, that a decision is explained in plain
language or it is not explained.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EuhvbUKjGesE3uMhjCzBGt
@omars-lab
omars-lab merged commit b674459 into main Aug 12, 2026
6 checks passed
@omars-lab
omars-lab deleted the mark-registration-by-hand branch August 12, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant