Skip to content

t27f: Russian ideas in the factory -- UTF-8 and a 5x7 Latin and Cyrillic font of particles (Closes #10788) - #10792

Merged
gHashTag merged 14 commits into
masterfrom
claude/t27f-cyrillic
Oct 19, 2026
Merged

gHashTag merged 14 commits into
masterfrom
claude/t27f-cyrillic

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Closes #10788. Part of epic #10560. Stacked on #10784 (the idea factory): the base is master, so until #10784 merges this diff also shows the factory's two commits. Only the last commit is new here.

What this does

The factory used to set text in scene_raster's 3x5 ASCII font. The owner's reels are Russian, and their text came from a TTF font through ffmpeg drawtext. That text was not made of particles and could not move to the FPGA path. Now Russian is drawn by particles too.

  • New: specs/t27f/glyph57.t27.
    • UTF-8: cp_len, cp_at and cp_count decode it. A malformed byte reads as one BAD character.
    • Case: fold maps Latin a..z, Cyrillic a..ya and yo to capitals.
    • The 5x7 font:
      • It stores ASCII 32..95 plus the 21 Cyrillic capitals that have no Latin twin: 85 glyphs, 595 rows.
      • The 11 look-alikes (A, Ve, Ie, Ka, Em, En, O, Er, Es, Te, Ha) and Yo reuse Latin glyphs through the 32-entry CYR_MAP.
      • An unknown code point draws as ?.
    • Integer only: table lookups and compares.
  • Changed: specs/t27f/idea_factory.t27.
    • It wraps by characters and keeps positions in bytes.
    • It sets text in the 5x7 font, with an advance of 6 and a line pitch of 9.
    • It adds RU_IDEA, a Russian sample of 80 bytes meaning "particles build the frame | one spec, many styles".
    • The English sample still gives 7 lines, 2 scenes and 216 frames.

A trap found on the way

t27c lowers only \n, \t, \\ and \" in a string. It keeps "\xD0" as four characters, so a test written with \xNN fails with no compile error. specs/tri/utils/terminal.t27 records the same trap for \x1b. Non-ASCII text is therefore a u8 array of its UTF-8 bytes, which also keeps L3: the sources stay ASCII. The t27f skill now records this.

Evidence (Railway lab)

  • Tests: t27c test-report passes 7 of 7 for glyph57 and 10 of 10 for idea_factory, with 0 vacuous tests. They pin:
    • Zhe decoding as D0 96, and yo folding to Yo;
    • no two stored glyphs sharing a bitmap, and a blank space;
    • every look-alike lighting exactly its Latin twin;
    • Russian lower case lighting the cells of its capitals;
    • a 7-letter, 14-byte word staying on one line;
    • every target staying inside the frame.
  • Seals: both saved, and --verify reports all hashes MATCH.
  • Duplicates: tools/dupe_scan.py reports no new duplicate body and no grown groups.
  • Preview: RU_IDEA rendered in all 5 presets at 1080x1920, 36 s in total, 18 to 23 s to render each preset.
    • Mean luma of the settled frame at t = 2.2 s:

      Preset Middle (text) Bottom (empty)
      0, noir-gold 62.2 22.9
      4, rain 38.0 18.9
    • No render output is committed.

Not claimed

  • Case: capitals only; lower case folds.
  • Yo: drawn as Ie, as small LCD fonts do.
  • Coverage: no glyphs beyond Latin, digits, ASCII punctuation and the Russian alphabet.
  • Hardware: the Verilog is emitted, not synthesised.
  • Compiler: the \xNN lexer gap is not fixed here; that would be a Rust change.

🤖 Generated with Claude Code

gHashTag and others added 3 commits October 19, 2026 09:26
…article (Closes #10771)

particle_ds.t27 is the particle design system: five presets (noir-gold,
neon-vortex, trit-charge, paper-ink, rain) as rows of integers -- palette,
blend, radius, gain, spring, dashpot, force law, kick, card -- and one
Q8 integer step, kernel, tone curve and finish. idea_factory.t27 is the
factory: (idea, preset) -> 1080x1920 RGB24 frames. It wraps the idea into
lines and scenes, sets each scene in the 3x5 font, gives every particle a
target cell or a card-border point at each cut, and closes on the address.

Lab: test-report 12/12 and 8/8 pass, 0 vacuous; seals saved and verified;
dupe_scan clean; 5-preset preview rendered at 1080x1920.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… on the lab, legibility by luma (Refs #10771)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lic font of particles (Closes #10788)

glyph57.t27 decodes UTF-8, folds lower case to capitals and stores a 5x7
font: ASCII 32..95 plus the 21 Cyrillic capitals with no Latin twin. The 11
look-alikes and Yo reuse Latin glyphs through a 32-entry map. idea_factory
now wraps by characters, keeps positions in bytes, and sets text in the 5x7
font (advance 6, line pitch 9).

t27c keeps "\xNN" in a string as four characters, so non-ASCII samples are
u8 arrays (RU_IDEA, 80 bytes). Lab: glyph57 7/7, idea_factory 10/10, 0
vacuous; seals verified; dupe_scan clean. The t27f skill records the trap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the ledger (Refs #10788)

#10784 merged with t27b-native-ratchet red: five specs that pass under t27b
had no row in docs/reports/t27b_expectations.json (UNLISTED). Rows added,
sorted by path, all "pass" as the ratchet reported them:

  specs/fpga/analog_cell_ax7203.t27
  specs/port/trios-railway/crates/trios-igla-race/src/bin/debug_queue.t27
  specs/port/trios-railway/crates/trios-igla-race/src/bin/smoke_agent.t27
  specs/t27f/idea_factory.t27
  specs/t27f/particle_ds.t27

max_not_pass stays 138. glyph57.t27's row waits for this branch's arm64
run: the lab is x86_64 and the t27b JIT runs only on arm64.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag and others added 3 commits October 19, 2026 09:54
…ep the PR a draft until then (Refs #10788)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On the x86_64 lab, the t27b front-end check (--check) prints every blocker
before it stops at "the t27b JIT runs only on arm64". glyph57.t27 and
petal_menu.t27 (new on master from #10786, also unlisted) reach that line with
no blocker. The control, frame_shard.t27, prints ExprCall(rejected fn). Both
rows are pass; this branch's arm64 run confirms them. max_not_pass stays 138.

The t27f skill's ratchet note said the lab cannot give a verdict. That was
wrong; it now gives the --check method and its control.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 03:02:37 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 41
PRs with All Checks Green 9
READY 2
FAILING 41
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 41 + 0 + 0 = 43, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=fad12492937a != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

…m master (Refs #10788)

Two of the three red checks on this PR came from master, not from the
glyph57 change. specs/analog/mos_psp103.t27 and mos_psp103_data.t27 landed
on master without t27b ledger rows, so the ratchet reported them UNLISTED.
They are added in sorted position as pass. The t27b front end on the lab
(--check) reports 0 unsupported constructs for both, matching the pass the
CI run measured. frontend.t27 does not import glyph57, but a module it uses
moved on master after its seal, so all four gen hashes were stale. It is
re-sealed on the lab against this branch's tree, and --verify reports all
hashes MATCH. The coverage gate failed on the same seal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag and others added 2 commits October 19, 2026 10:31
#10788)

specs/analog/sar_switch.t27 (analog M4c) reached master without a t27b
row, so this PR's ratchet reported it UNLISTED. The arm64 run on
7f33764 measured it as a t27b pass, so the row says pass. Master is
merged in first so the row names a file this branch contains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 04:36:04 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 43
PRs with All Checks Green 7
READY 2
FAILING 43
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 43 + 0 + 0 = 45, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=03f3de4a3582 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

…h merges clean (Refs #10609)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gHashTag

Copy link
Copy Markdown
Owner Author

Base #10784 has merged, so this PR leaves draft. The ledger now carries master's rows plus this lane's specs/t27f/glyph57.t27 row, and git merge-tree against master c05a288 returns rc 0. #10806, #10800, #10816, #10822 and #10830 got the same ledger fix. They stay drafts until their bases land.

@gHashTag

Copy link
Copy Markdown
Owner Author

t27b-native-ratchet is red here for the same reason master is red: UNLISTED specs/analog/sar_adc.t27, specs/tri/worktrees/reap.t27 and specs/ml/ngram_hslm.t27. #10862 auto-merged one push before its rows arrived. #10889 adds all three rows (not-pass 129 at cap 129). This PR's ledger change is only the glyph57 row, so the two PRs merge without conflict in either order. Not a required check, so no push here.

@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 06:12:20 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 41
PRs with All Checks Green 9
READY 2
FAILING 41
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 41 + 0 + 0 = 43, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=88b8cb73ceda != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit d0959ff into master Oct 19, 2026
34 of 38 checks passed
gHashTag added a commit that referenced this pull request Oct 19, 2026
…itle frame, byte for byte (Closes #10828) (#10830)

* t27f: idea factory -- any idea in any style preset, every element a particle (Closes #10771)

particle_ds.t27 is the particle design system: five presets (noir-gold,
neon-vortex, trit-charge, paper-ink, rain) as rows of integers -- palette,
blend, radius, gain, spring, dashpot, force law, kick, card -- and one
Q8 integer step, kernel, tone curve and finish. idea_factory.t27 is the
factory: (idea, preset) -> 1080x1920 RGB24 frames. It wraps the idea into
lines and scenes, sets each scene in the 3x5 font, gives every particle a
target cell or a card-border point at each cut, and closes on the address.

Lab: test-report 12/12 and 8/8 pass, 0 vacuous; seals saved and verified;
dupe_scan clean; 5-preset preview rendered at 1080x1920.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f skill: idea factory and the particle design system, preset sweep on the lab, legibility by luma (Refs #10771)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: Russian ideas in the factory -- UTF-8 and a 5x7 Latin and Cyrillic font of particles (Closes #10788)

glyph57.t27 decodes UTF-8, folds lower case to capitals and stores a 5x7
font: ASCII 32..95 plus the 21 Cyrillic capitals with no Latin twin. The 11
look-alikes and Yo reuse Latin glyphs through a 32-entry map. idea_factory
now wraps by characters, keeps positions in bytes, and sets text in the 5x7
font (advance 6, line pitch 9).

t27c keeps "\xNN" in a string as four characters, so non-ASCII samples are
u8 arrays (RU_IDEA, 80 bytes). Lab: glyph57 7/7, idea_factory 10/10, 0
vacuous; seals verified; dupe_scan clean. The t27f skill records the trap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f skill: a new spec's t27b ledger row comes from the arm64 run, keep the PR a draft until then (Refs #10788)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Ledger: glyph57 and petal_menu pass the t27b front end (Refs #10788)

On the x86_64 lab, the t27b front-end check (--check) prints every blocker
before it stops at "the t27b JIT runs only on arm64". glyph57.t27 and
petal_menu.t27 (new on master from #10786, also unlisted) reach that line with
no blocker. The control, frame_shard.t27, prints ExprCall(rejected fn). Both
rows are pass; this branch's arm64 run confirms them. max_not_pass stays 138.

The t27f skill's ratchet note said the lab cannot give a verdict. That was
wrong; it now gives the --check method and its control.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: idea factory picks its style preset from a hash of the idea, PRESET_AUTO (Closes #10803)

A batch of ideas rendered with the factory all came out in PRESET 0
unless someone edited the constant by hand. Now PRESET = PRESET_AUTO (255)
makes main run pick_preset(IDEA, PRESET). That uses preset_of(IDEA), which
is FNV-1a 32 over the idea's bytes (UTF-8 for Russian) mod PRESETS, so the
same idea always gets the same style and different ideas spread over the
five. Any other PRESET is kept as given, and PRESET stays 0, so today's
render is unchanged. This is Remotion's random(seed), applied to style.

Railway lab: t27c test-report 13/13 pass, 0 vacuous. The fnv1a32 test
checks the published FNV-1a 32 vectors ("", a, b, foobar). Across the
one-letter ideas A..Z every preset is picked. 5 of 5 mutants are killed:
basis, prime, FNV-1 order, AUTO -> 0, mod 4. t27b raises no blocker, so
the pass row stands. gen emits pick_preset. Seal re-saved, all hashes
MATCH.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Ledger rows for mos_psp103 and re-sealed frontend, both inherited from master (Refs #10788)

Two of the three red checks on this PR came from master, not from the
glyph57 change. specs/analog/mos_psp103.t27 and mos_psp103_data.t27 landed
on master without t27b ledger rows, so the ratchet reported them UNLISTED.
They are added in sorted position as pass. The t27b front end on the lab
(--check) reports 0 unsupported constructs for both, matching the pass the
CI run measured. frontend.t27 does not import glyph57, but a module it uses
moved on master after its seal, so all four gen hashes were stale. It is
re-sealed on the lab against this branch's tree, and --verify reports all
hashes MATCH. The coverage gate failed on the same seal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: idea factory batch -- five ideas cover all five presets, and the compiled binary agrees with the spec (Closes #10815)

PRESET_AUTO (#10806) was checked only in the t27c interpreter. A new
test pins a batch of five ideas whose AUTO presets are noir, neon,
trit, paper and rain. On the Railway lab each idea was built twice
from the generated Zig, once with PRESET = PRESET_AUTO and once with
the pinned preset written in, and the two frame streams have the same
md5 for 5 of 5 ideas. Idea 1 with preset 1 gives a different stream,
the control. So gen and the interpreter pick the same style.

Lab: t27c test-report 14/14 pass, 0 vacuous. Mutants killed: a pinned
preset swapped (paper -> rain) and one idea byte changed. The t27b
front end reports 0 unsupported constructs. Seal re-saved, all hashes
MATCH. The t27f skill records the recipe and the trap that cost one
run: five parallel libx264 encoders failed to open, the tee closed,
and md5 hashed truncated streams, so 3 of 5 read DIFF until md5 ran
on its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Ledger row for sar_switch, another master spec landed without one (Refs #10788)

specs/analog/sar_switch.t27 (analog M4c) reached master without a t27b
row, so this PR's ratchet reported it UNLISTED. The arm64 run on
7f33764 measured it as a t27b pass, so the row says pass. Master is
merged in first so the row names a file this branch contains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: idea factory pre-flight -- refuse an idea the font cannot draw before writing a frame (Closes #10820)

glyph57 draws a character it lacks as '?', so an idea with a phi, a
euro sign or a brace used to ship with the wrong letter on screen.
preflight(t) now returns PF_EMPTY (no scene), PF_GLYPH (missing_glyphs
> 0; first_missing gives the byte offset), PF_LONG (reel past MAX_S =
60 s) or PF_OK, in that order, and main writes no frame unless it is
PF_OK. A real '?', a '|' cut and a space do not count as missing; a
malformed UTF-8 byte does.

Railway lab, on top of 0a5dad1: 17/17 tests pass, 0 vacuous.
Mutants: 9 of 10 killed. The survivor, MAX_S = 61, is equivalent,
since reels grow in 72-frame steps and 60..62 s refuse the same ideas.
Generated binaries: A{B} and a 25-scene idea write 0 bytes; the same
A{B} with the guard removed writes 144 whole frames (the control);
the sample idea writes 216 whole frames. t27b front end: 0 unsupported
constructs. Seal re-saved, all hashes MATCH. The t27f skill records
the check and the equivalent-mutant note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Ledger: sar_switch sorts after sar_comparator (Refs #10788)

4f739c1 put the sar_switch row before sar_comparator, so the
loop-tools gate failed 'ledger: sorted, one entry per spec'. This
commit also carries the merge of master, which brings move_gate's row
and the cap of 139.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: idea factory cover still -- COVER=1 writes the reel's settled title frame, byte for byte (Closes #10828)

Reels, Shorts and TikTok show a cover before a reel plays. Until now
someone had to cut it out with ffmpeg and guess the frame. COVER = 1
makes main run the physics of every frame up to cover_frame(IDEA), the
first scene's last frame (71), and raster only that one. The still is
then frame 71 of the reel, with the same idea and preset, and cannot
drift from it. Remotion's renderStill is the model.

Railway lab, on top of e9b55d6: 18/18 tests pass, 0 vacuous. 4 of 4
mutants are killed. The t27b front end reports 0 unsupported constructs.
Generated binaries:
- COVER = 0 is md5-identical to the binary before this change.
- COVER = 1 writes 6220800 bytes, and cmp finds it equal to frame 71
  cut from the full 216-frame reel.
- The control, with the guard moved to frames - 2, differs from frame
  71 and equals frame 70.
- A refused idea (A{B}) still writes 0 bytes.
- The AUTO-preset idea SEALED|EVERY HASH writes one frame.
Seal re-saved; all hashes MATCH.

The t27f skill records the cover recipe. It also records the ledger
sort trap that turned #10792 red: a row was inserted out of order, and
`sort -c` catches it before the commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27b ledger: master's rows plus this lane's glyph57 row, so the branch merges clean (Refs #10609)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27b ledger: master's rows plus this lane's glyph57 row, so the branch merges clean (Refs #10609)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27b ledger: master's rows plus this lane's own rows, so the branch merges clean (Refs #10609)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: re-save the idea_factory seal on the lab after the master merge, 14/14 pass, MATCH (Refs #10815)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: re-save the idea_factory seal on the lab after the merge, 17/17 pass, MATCH (Refs #10820)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: re-save the idea_factory seal on the lab after the merge, MATCH (Refs #10828)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: re-seal idea_factory after the merge with master (Refs #10820)

Saved and verified on the Railway lab: test-report 0 FAIL, 17 tests, 0 vacuous; seal --verify MATCH.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: re-seal idea_factory after the merge with preflight and master (Refs #10828)

Saved and verified on the Railway lab: test-report 0 FAIL, 18 tests, 0 vacuous; seal --verify MATCH.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* t27f: re-seal idea_factory after the merge with master (Refs #10828)

Saved and verified on the Railway lab: test-report 0 FAIL, 18 tests, 0 vacuous; seal --verify MATCH.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

t27f: Cyrillic idea factory -- UTF-8 ideas set in a 5x7 particle font

1 participant