Found 2026-11-13 while rewriting L8 for v4 (#189 Phase 7, Task 3). Introduced by #188 (c76a742f), my own work.
The defect
Since #188, L8's table cards are numbered 0..63, and card_bits() (v3/src/ssm_jacquard.c:235) turns a card number into its seven gate bits: ((card & 0x3F) << 1) | SSM_CFG_L7.
ssm_l8_tick_score_and_select() (v3/src/ssm_jacquard.c:292) takes the card cd_config_table_tick() chose. That function returns entries[best].config_bits, which is the card number. It then tests the SSM_CFG_L1..SSM_CFG_L7 bits against that number, not against card_bits(number). So after every tick each gate is one bit off:
L1 (0x40) is never on, because a card number is below 64;
L2 gets the card's L1 bit, L3 the card's L2 bit, and so on down;
L7 gets the card's L6 bit, though #188 made L7 always on.
ssm_apply_mode_from_table() (:447) uses card_bits() correctly. #188's tests (kernel/tests/test_ssm_jacquard.c) never check the gates after a tick.
Ruled (Captain Bob, 2026-11-13)
"v4 correct, v3 as is": v4's L8 applies the card through card_bits(), and v3 is left alone, since it is being retired (#156). v4's L8 therefore departs from v3's here on purpose. This issue records why.
If v3 is ever fixed
Fix the one site: card_bits(bits) in place of bits. Add a test that fails first: after a tick, the gates equal card_bits(table->current_config).
Found 2026-11-13 while rewriting L8 for v4 (#189 Phase 7, Task 3). Introduced by #188 (c76a742f), my own work.
## The defect
Since #188, L8's table cards are numbered 0..63, and `card_bits()` (`v3/src/ssm_jacquard.c:235`) turns a card number into its seven gate bits: `((card & 0x3F) << 1) | SSM_CFG_L7`.
`ssm_l8_tick_score_and_select()` (`v3/src/ssm_jacquard.c:292`) takes the card `cd_config_table_tick()` chose. That function returns `entries[best].config_bits`, which is the card number. It then tests the `SSM_CFG_L1`..`SSM_CFG_L7` bits against **that number**, not against `card_bits(number)`. So after every tick each gate is one bit off:
- L1 (`0x40`) is never on, because a card number is below 64;
- L2 gets the card's L1 bit, L3 the card's L2 bit, and so on down;
- L7 gets the card's L6 bit, though #188 made L7 always on.
`ssm_apply_mode_from_table()` (`:447`) uses `card_bits()` correctly. #188's tests (`kernel/tests/test_ssm_jacquard.c`) never check the gates after a tick.
## Ruled (Captain Bob, 2026-11-13)
"v4 correct, v3 as is": v4's L8 applies the card through `card_bits()`, and v3 is left alone, since it is being retired (#156). v4's L8 therefore departs from v3's here on purpose. This issue records why.
## If v3 is ever fixed
Fix the one site: `card_bits(bits)` in place of `bits`. Add a test that fails first: after a tick, the gates equal `card_bits(table->current_config)`.
rajames
added this to the Retire v3 milestone 2026-11-13 22:32:16 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found 2026-11-13 while rewriting L8 for v4 (#189 Phase 7, Task 3). Introduced by #188 (
c76a742f), my own work.The defect
Since #188, L8's table cards are numbered 0..63, and
card_bits()(v3/src/ssm_jacquard.c:235) turns a card number into its seven gate bits:((card & 0x3F) << 1) | SSM_CFG_L7.ssm_l8_tick_score_and_select()(v3/src/ssm_jacquard.c:292) takes the cardcd_config_table_tick()chose. That function returnsentries[best].config_bits, which is the card number. It then tests theSSM_CFG_L1..SSM_CFG_L7bits against that number, not againstcard_bits(number). So after every tick each gate is one bit off:0x40) is never on, because a card number is below 64;ssm_apply_mode_from_table()(:447) usescard_bits()correctly. #188's tests (kernel/tests/test_ssm_jacquard.c) never check the gates after a tick.Ruled (Captain Bob, 2026-11-13)
"v4 correct, v3 as is": v4's L8 applies the card through
card_bits(), and v3 is left alone, since it is being retired (#156). v4's L8 therefore departs from v3's here on purpose. This issue records why.If v3 is ever fixed
Fix the one site:
card_bits(bits)in place ofbits. Add a test that fails first: after a tick, the gates equalcard_bits(table->current_config).