Skip to content

spec(maxpool2d_layer): a lowerable out_side(kernel, stride) for the nn-maxpool widget (Closes #10664) - #10665

Merged
gHashTag merged 1 commit into
masterfrom
feat/maxpool-out-side
Oct 18, 2026
Merged

gHashTag merged 1 commit into
masterfrom
feat/maxpool-out-side

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Closes #10664. Part of EPIC #9063.

Why

This unblocks gHashTag/trinity#1696 (course 10, neural networks). Its review (5565039954) found one defect: the widget nn-maxpool hand-holds K_OUT_SIDES = [2, 2, 3, 1]. Those numbers are out_size(4, cfg(k, s)) from this spec. out_size takes a MaxPool2DConfig struct, so it does not lower to WASM, and the widget had no compiled way to get the output side.

What it adds

specs/ml/layers/maxpool2d_layer.t27:

fn out_side(kernel: u32, stride: u32) -> u32 {
    return out_size(4, cfg(kernel, stride));
}

It is non-pub like the file's other fns, and its integer types are the ones out_size and cfg take. Two tests come with it:

  • out_side_of_each_widget_config: the widget's four configs (K_KERNELS = [2, 3, 2, 4], K_STRIDES = [2, 1, 1, 1] on trinity's feat/course-neural-networks) give (2,2)->2, (3,1)->2, (2,1)->3 and (4,1)->1.
  • out_side_identity_and_floor: edge cases. (1,1)->4 keeps the side. A stride that does not divide rounds down: (3,2)->1 and (1,3)->2.

The seal is re-saved (.trinity/seals/Maxpool2d.json, layers_Maxpool2d.json), and the NOW entry is docs/now/2026-10-18-maxpool-out-side.md.

Evidence

t27c is the one from 239b4b0 (bootstrap/ has not changed since). Zig is 0.16.0.

tests 7, pass 7, FAIL 0, invariants 1 proved, vacuous passes 0 of 7
  • Negative controls. I made 4 mutants of the fn body: side 5, stride forced to 1, stride dropped, and ceiling division. All 4 were killed. Only the edge test kills the ceiling mutant, so neither test is redundant.
  • Lowering. scripts/t27-logic.mjs (999-multibots-telegraf) wrote maxpool2d_layer.logic.ts: 3 fns lowered, 4 not. It exports outSide, and __NOT_LOWERED__ is ["out_size","forward","backward","cfg"]. In node, the compiled WASM returns 2, 2, 3, 1, 4, 1, 2 for the seven pairs above.
  • Local gates.
    • tools/dupe_scan.py: no new group.
    • check_specs_still_parse.py: 0 newly unparseable.
    • own-language (check_all and check_budget): exit 0.
    • check_json_parses.py: OK.
    • check_now_entry_shape.py: OK.

Not here

The re-vendor into trinity, calling outSide(k, st) in nn-maxpool/tool.js, and dropping K_OUT_SIDES and its hand-derived formula test. Those are a later step on trinity#1696.


Generated by Claude Code

…n-maxpool widget (Closes #10664)

gHashTag/trinity#1696 (course 10) was refused because the nn-maxpool
widget hand-holds K_OUT_SIDES = [2, 2, 3, 1]. Those are
out_size(4, cfg(k, s)), but out_size takes a MaxPool2DConfig struct and
does not lower to WASM.

- out_side(kernel: u32, stride: u32) -> u32 returns
  out_size(4, cfg(kernel, stride)); t27-logic.mjs lowers it as outSide.
- Tests: the widget's four configs (2,2)->2, (3,1)->2, (2,1)->3,
  (4,1)->1, and the edges (1,1)->4, (3,2)->1, (1,3)->2.
- test-report 7 of 7 pass, 0 vacuous; 4 mutants of the fn, 4 killed.
- Seal saved; NOW entry in docs/now/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-18 21:29:32 UTC

Summary

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

These columns do not partition: 2 + 47 + 0 + 0 = 49, 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).

@gHashTag
gHashTag enabled auto-merge (squash) October 18, 2026 21:29
@gHashTag
gHashTag merged commit 2e53089 into master Oct 18, 2026
35 checks passed
gHashTag pushed a commit to gHashTag/trinity that referenced this pull request Oct 18, 2026
The widget held the output sides as K_OUT_SIDES = [2, 2, 3, 1], which are
results of the spec fn out_size. A widget-spec test re-derived out_size's
formula by hand to hold them. Both broke the mirror law (review 5565039954).

- Vendor specs/ml/layers/maxpool2d_layer.t27 from t27 master 2e53089d5,
  byte-identical, into public/t27/files and nn-maxpool/logic.t27. That
  commit (gHashTag/t27#10665) added the lowerable fn out_side(kernel, stride).
- Lower it again with t27-logic.mjs and import it with widget-logic.mjs.
  logic.js now exports outSide.
- tool.js gets the output grid's shape and the "output n x n" tile from
  outSide(k, st).
- Drop K_OUT_SIDES and the test every_output_side_follows_from_kernel_and_stride.
  A new test, the_four_configs_are_the_spec_window_stride_pairs, holds the
  K_KERNELS/K_STRIDES inputs.
- The course spec says the max-pool spec is vendored from 2e53089d5. Widget
  pages and both max-pooling lesson pages are regenerated.

Course 10, #1695. Spec: gHashTag/t27#10665.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k
gHashTag added a commit to gHashTag/trinity that referenced this pull request Oct 18, 2026
…dgets running compiled specs/ml (#1696)

* specs reader: a float with an exponent is a number; the gallery counts past 255

t27 specs/ml writes its epsilons as 1e-8, 1.0e-5 and -1.0e30. literalValue
refused that form, so constsOf threw on adam, attention_mechanism,
batchnorm_layer, binary_crossentropy_loss and lamb, and widget-logic could
not compare a widget's K_ numbers with them. The decimal pattern now takes
an optional exponent; hex and expressions are still refused, and a new test
says both.

WIDGET_COUNT becomes u16 in the gallery schema: the 27 widgets of course 10
take the gallery from 252 to 279, past what a u8 holds.

Refs #1695

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k

* widgets: 27 neural-network widgets, logic compiled from gHashTag/t27 specs/ml

Twenty-seven tool widgets, three per module of the neural-networks course:
activations (ReLU, sigmoid, tanh, GELU, Swish, ELU), softmax, embeddings and
dropout, pooling and batch norm, MSE, cross-entropy and Huber, SGD, RMSProp
and Adam, backpropagation, XOR and LAMB, a recurrent cell, LSTM gates and
attention, positional encoding, an encoder block and PPO. Each widget opens
with the question its lesson asks and computes nothing itself: its logic.js
is the fn bodies of one specs/ml spec of t27 master 239b4b059, compiled to
wasm by 999 scripts/t27-logic.mjs (usize lowered since 999#4017) and
imported with widget-logic.mjs --import. Words are SAY_ and numbers K_
constants of specs/widgets/<id>.t27; the widget specs hold integers only, so
a K_ name ending in _C is in hundredths.

nn-kit.js builds on dsp-kit.js (controls, presets, URL hash, tiles, plot
axes) and adds curves you drag along, bar charts, heat-maps, diverging and
heat colour scales and a node-link diagram. nn-conv is average pooling over
2 x 2 windows (pool4_at): the sliding conv2d spec, t27#10612, is not merged,
and the widget says so. nn-xor trains the spec's 2-8-1 network in the page
and shows the four inputs the spec exposes, not a decision region.

The gallery grows from 252 to 279 widgets; the new shelf sits before the
wars pin (index 244 to 270) and the pins after it move by 27. The 27 lesson
specs are vendored under public/t27/files/specs/ml byte for byte as t27
master; 24 of them replace older copies, read by no course or widget before.

Refs #1695

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k

* course: neural-networks, from one neuron to a transformer block

Course 10: nine modules and 27 lessons. It opens the parts the project's
agents think with, as the gHashTag/t27 specs/ml specs they are written in:
one neuron (ReLU, sigmoid, tanh), new bends (GELU, Swish, ELU), a layer
(softmax, embeddings, dropout), pictures (pooling, max pooling, batch
norm), the error (MSE, cross-entropy, Huber), downhill (SGD, RMSProp,
Adam), learning (backpropagation, XOR, LAMB), memory and attention (a
recurrent cell, LSTM gates, attention) and the transformer and the reward
(positional encoding, an encoder block, PPO). Each lesson asks a question,
opens one nn-* widget that answers it, and names the spec that computes it.
Lesson 10 says plainly that it is average pooling until t27#10612 merges.

The course is added last in courses.t27 (COURSE_COUNT 10, with a test that
it closes the catalogue), with the Russian contract neural-networks-ru.t27
and the bundle i18n/neural-networks.ru.json; the negative control of
course-from-spec.test.mjs moves from 10 to 11. Also regenerated: the learn
pages (EN and RU), cards, sitemap, the course and route tables, and the menu
entry.

Refs #1695

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k

* blog: neural networks in t27, a widget per lesson

The post (EN and RU) walks through the nine modules of course 10 and the
widget each lesson opens, explains how a specs/ml spec reaches the browser
(t27-logic.mjs, then widget-logic.mjs), and says what the course does not
show. Its figure is the XOR training loss of the 2-8-1 network and its four
outputs after 2000 epochs (0.8896 to 1.8e-13), drawn by the same compiled
mlp.t27 logic the nn-xor widget runs.

Refs #1695

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k

* widgets(nn-maxpool): the output side comes from the spec's out_side

The widget held the output sides as K_OUT_SIDES = [2, 2, 3, 1], which are
results of the spec fn out_size. A widget-spec test re-derived out_size's
formula by hand to hold them. Both broke the mirror law (review 5565039954).

- Vendor specs/ml/layers/maxpool2d_layer.t27 from t27 master 2e53089d5,
  byte-identical, into public/t27/files and nn-maxpool/logic.t27. That
  commit (gHashTag/t27#10665) added the lowerable fn out_side(kernel, stride).
- Lower it again with t27-logic.mjs and import it with widget-logic.mjs.
  logic.js now exports outSide.
- tool.js gets the output grid's shape and the "output n x n" tile from
  outSide(k, st).
- Drop K_OUT_SIDES and the test every_output_side_follows_from_kernel_and_stride.
  A new test, the_four_configs_are_the_spec_window_stride_pairs, holds the
  K_KERNELS/K_STRIDES inputs.
- The course spec says the max-pool spec is vendored from 2e53089d5. Widget
  pages and both max-pooling lesson pages are regenerated.

Course 10, #1695. Spec: gHashTag/t27#10665.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k

---------

Co-authored-by: Claude <noreply@anthropic.com>
github-actions Bot added a commit to gHashTag/trinity that referenced this pull request Oct 18, 2026
feat(website): course 10, Neural networks in t27 -- 27 lessons, 27 widgets running compiled specs/ml (#1696)

* specs reader: a float with an exponent is a number; the gallery counts past 255

t27 specs/ml writes its epsilons as 1e-8, 1.0e-5 and -1.0e30. literalValue
refused that form, so constsOf threw on adam, attention_mechanism,
batchnorm_layer, binary_crossentropy_loss and lamb, and widget-logic could
not compare a widget's K_ numbers with them. The decimal pattern now takes
an optional exponent; hex and expressions are still refused, and a new test
says both.

WIDGET_COUNT becomes u16 in the gallery schema: the 27 widgets of course 10
take the gallery from 252 to 279, past what a u8 holds.

Refs #1695

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k

* widgets: 27 neural-network widgets, logic compiled from gHashTag/t27 specs/ml

Twenty-seven tool widgets, three per module of the neural-networks course:
activations (ReLU, sigmoid, tanh, GELU, Swish, ELU), softmax, embeddings and
dropout, pooling and batch norm, MSE, cross-entropy and Huber, SGD, RMSProp
and Adam, backpropagation, XOR and LAMB, a recurrent cell, LSTM gates and
attention, positional encoding, an encoder block and PPO. Each widget opens
with the question its lesson asks and computes nothing itself: its logic.js
is the fn bodies of one specs/ml spec of t27 master 239b4b059, compiled to
wasm by 999 scripts/t27-logic.mjs (usize lowered since 999#4017) and
imported with widget-logic.mjs --import. Words are SAY_ and numbers K_
constants of specs/widgets/<id>.t27; the widget specs hold integers only, so
a K_ name ending in _C is in hundredths.

nn-kit.js builds on dsp-kit.js (controls, presets, URL hash, tiles, plot
axes) and adds curves you drag along, bar charts, heat-maps, diverging and
heat colour scales and a node-link diagram. nn-conv is average pooling over
2 x 2 windows (pool4_at): the sliding conv2d spec, t27#10612, is not merged,
and the widget says so. nn-xor trains the spec's 2-8-1 network in the page
and shows the four inputs the spec exposes, not a decision region.

The gallery grows from 252 to 279 widgets; the new shelf sits before the
wars pin (index 244 to 270) and the pins after it move by 27. The 27 lesson
specs are vendored under public/t27/files/specs/ml byte for byte as t27
master; 24 of them replace older copies, read by no course or widget before.

Refs #1695

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k

* course: neural-networks, from one neuron to a transformer block

Course 10: nine modules and 27 lessons. It opens the parts the project's
agents think with, as the gHashTag/t27 specs/ml specs they are written in:
one neuron (ReLU, sigmoid, tanh), new bends (GELU, Swish, ELU), a layer
(softmax, embeddings, dropout), pictures (pooling, max pooling, batch
norm), the error (MSE, cross-entropy, Huber), downhill (SGD, RMSProp,
Adam), learning (backpropagation, XOR, LAMB), memory and attention (a
recurrent cell, LSTM gates, attention) and the transformer and the reward
(positional encoding, an encoder block, PPO). Each lesson asks a question,
opens one nn-* widget that answers it, and names the spec that computes it.
Lesson 10 says plainly that it is average pooling until t27#10612 merges.

The course is added last in courses.t27 (COURSE_COUNT 10, with a test that
it closes the catalogue), with the Russian contract neural-networks-ru.t27
and the bundle i18n/neural-networks.ru.json; the negative control of
course-from-spec.test.mjs moves from 10 to 11. Also regenerated: the learn
pages (EN and RU), cards, sitemap, the course and route tables, and the menu
entry.

Refs #1695

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k

* blog: neural networks in t27, a widget per lesson

The post (EN and RU) walks through the nine modules of course 10 and the
widget each lesson opens, explains how a specs/ml spec reaches the browser
(t27-logic.mjs, then widget-logic.mjs), and says what the course does not
show. Its figure is the XOR training loss of the 2-8-1 network and its four
outputs after 2000 epochs (0.8896 to 1.8e-13), drawn by the same compiled
mlp.t27 logic the nn-xor widget runs.

Refs #1695

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k

* widgets(nn-maxpool): the output side comes from the spec's out_side

The widget held the output sides as K_OUT_SIDES = [2, 2, 3, 1], which are
results of the spec fn out_size. A widget-spec test re-derived out_size's
formula by hand to hold them. Both broke the mirror law (review 5565039954).

- Vendor specs/ml/layers/maxpool2d_layer.t27 from t27 master 2e53089d5,
  byte-identical, into public/t27/files and nn-maxpool/logic.t27. That
  commit (gHashTag/t27#10665) added the lowerable fn out_side(kernel, stride).
- Lower it again with t27-logic.mjs and import it with widget-logic.mjs.
  logic.js now exports outSide.
- tool.js gets the output grid's shape and the "output n x n" tile from
  outSide(k, st).
- Drop K_OUT_SIDES and the test every_output_side_follows_from_kernel_and_stride.
  A new test, the_four_configs_are_the_spec_window_stride_pairs, holds the
  K_KERNELS/K_STRIDES inputs.
- The course spec says the max-pool spec is vendored from 2e53089d5. Widget
  pages and both max-pooling lesson pages are regenerated.

Course 10, #1695. Spec: gHashTag/t27#10665.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScHVrGSr6zZUdwkdC8DR9k

---------

Co-authored-by: Claude <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.

spec(maxpool2d_layer): a lowerable out_side(kernel, stride) for the nn-maxpool widget

2 participants