Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .claude/skills/t27f/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,52 @@ Measured at 355d44a39: each still has 9 to 14 flat colours, and the PNGs are 4 t
`foreign-budget` hook on master's own Rust lines (t27#10414). Merge the old branch into a
master-based branch instead. The result still fast-forwards the old branch.

## Application: idea factory, the OS particle design system (t27#10771)

The owner wants one factory that unpacks any idea in any style preset, with every element made
of particles, and runnable in the OS itself and on FPGA. Two specs do this:

- **`specs/t27f/particle_ds.t27` is the design system.** A preset is a column in integer tables:
`BG`, `COL_A/B/C`, `RADIUS`, `GAIN`, `SPRING`, `DAMP`, `LAW`, `FORCE`, `KICK`, `CARD`. The five
are noir, neon, trit, paper and rain. **Add a preset by adding a column, never a branch in code.**
- **`specs/t27f/idea_factory.t27` is the factory**, `(IDEA, PRESET) -> RGB24 frames`. It wraps
(at most 9 characters per line, 4 lines per scene, `|` cuts a scene), lays out in the 3x5 font,
assigns particles to glyph sub-slots and the card border, and closes on `CTA`.

**Keep it FPGA-shaped.** Use Q8 fixed point. The per-step and per-pixel paths use only add,
multiply, compare, table lookup (`kt` kernel ROM, `tt` tone ROM) and power-of-two division.
Divide by a variable at most once per scene cut, never per pixel. The seals then carry
`gen_hash_verilog`. That proves Verilog is emitted, not that it was synthesised. Say so.

**Render the preset sweep on the lab:**

1. For each preset, `sed` the `PRESET` constant. Also rename the module (for example
`idea_factory_p`), so the gen output does not overwrite the committed module's.
2. Run `t27c gen`, then `zig build-exe -O ReleaseFast`.
3. Run `./f 2>&1 1>fo.txt | ffmpeg -f rawvideo -pix_fmt rgb24 -s 1080x1920 -r 30 -i - ...`
(libx264, crf 19). The frames go to stderr. Send stdout to a file, **never to `/dev/null`**:
the lab replays `/dev/null` writes.
4. Concatenate the five, scale to 720 and make a tile sheet. Fetch them as `B64:...:END` and
check sha256 on both ends.

Measured: each preset takes 14 to 35 s for 216 frames, with 3072 particles.

**Check legibility by numbers, because the Mac cannot read images.** Crop the settled frame at
t = 2.2 s with ffmpeg and read `signalstats` YAVG for three regions: the text block, a gap row
between lines, and the empty bottom. On a dark preset you want block > gap > bottom (rain:
44.8 > 25.4 > 19.0). On paper the order flips (block 187 < gap 211). A flat triple means the
particles never settled into letters.

**Traps:**

- **Read the `test-report` tail, not a grep.** A grep for pass and fail counts miscounts the
summary lines (`tests N`, `pass N`, `FAIL 0`, `vacuous passes 0 of N`).
- **Rename loop variables by line range.** A rename that only changes the declaration leaves the
body pointing at the old name. Give each top-level loop in `main` its own name (`ia`, `ib`,
`ic`).
- **Base the branch on master's tip before the PR.** If the base PR (R3) merged first, reset the branch onto
`origin/master`. Untracked new specs survive the reset.

## Check the whole corpus for import cycles (t27#10693)

dependency-cruiser's `no-circular` and madge's `--circular` list every module on a cycle.
Expand Down
37 changes: 37 additions & 0 deletions .trinity/seals/t27f_idea_factory.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"built_by": "t27c-bootstrap@0.5.2+355d44a39",
"closure": [
{
"spec": "specs/t27f/particle_ds.t27",
"spec_hash": "sha256:00e84a7492536bf54ac69aa0cd852dea4727477acee12538f9c4b145c3d9c8f3"
},
{
"spec": "specs/t27f/scene_raster.t27",
"spec_hash": "sha256:7be7118d865aa65fd1ccb989ab160df2feb46c9ded0a15ca6510b747301ee4a6"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:49e275c87108c8621d521226b89afb5f6c6a39f74de8e8bba502fbd1e39ad843",
"gen_hash_rust": "sha256:7d03e6e99a15344a1c8272b7f96ffc8ddcbfdb1cf44ab7f70f7a0e37847529bc",
"gen_hash_verilog": "sha256:0f761cb6e48d10ac555e51b8e5722eb8b02074a87ca2055aaec9241754140c49",
"gen_hash_zig": "sha256:0730d911d7047dc707075d16c8ff04afe222f4422a24344eff10b90e72edfdf0",
"module": "idea_factory",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-19T02:25:39Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:34f59b06d780be9cbbae1b0577e7c96ed5b6b7d2451e61ada1b1dde2fd58b6b8",
"spec_path": "specs/t27f/idea_factory.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 8,
"total": 8,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10",
"zig": "0.16.0"
}
}
33 changes: 33 additions & 0 deletions .trinity/seals/t27f_particle_ds.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"built_by": "t27c-bootstrap@0.5.2+355d44a39",
"closure": [
{
"spec": "specs/t27f/scene_raster.t27",
"spec_hash": "sha256:7be7118d865aa65fd1ccb989ab160df2feb46c9ded0a15ca6510b747301ee4a6"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:03823e75050d119fede755d7e3b218cd924f47ad3d310bcc39f5a00ea315a715",
"gen_hash_rust": "sha256:33f633fdef8835e3d69e6e758e6bb180de9e103fca81005405999c391bec82f4",
"gen_hash_verilog": "sha256:c5ef23af6415734e2f11a6dd645de11cd86a4f040c331595fa3f11c4765a71db",
"gen_hash_zig": "sha256:262eb3241c84d2de64e67b59ea700299f8cf513d1d3a3e2ecf25279f5421f63f",
"module": "particle_ds",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-19T02:25:36Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:00e84a7492536bf54ac69aa0cd852dea4727477acee12538f9c4b145c3d9c8f3",
"spec_path": "specs/t27f/particle_ds.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 12,
"total": 12,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10",
"zig": "0.16.0"
}
}
Loading
Loading