// Transmissions — What We Shipped
The contract. Any training path — imitation, PPO, CFR distillation — is only useful if it produces something in exactly this shape, because this is what the serving process, the bots and the drivers already expect.
input 86 features (standardised: x' = (x - mu) / sd, from norm.npz)
|
tower Linear(86 -> 384) + LayerNorm(384) + activation
Linear(384 -> 384) + LayerNorm(384) + activation
Linear(384 -> 192)
|
+-- policy Linear(192 -> 6) action class logits
+-- betsize Linear(192 -> 8) pot-fraction bucket logits
+-- value Linear(192 -> 1) scalar state value
total parameters: 259,599
Deliberately small. It has to run on a CPU that is simultaneously doing computer vision for several handsets, inside a decision budget measured in milliseconds, so capacity is spent on the feature engineering rather than on depth.
The three questions — what to do, how much, and how good is this spot — share almost all of their evidence. One shared representation means the value head's learning signal also improves the policy head's features, and the value head is what PPO needs to compute advantage. Separate networks would triple the cost and learn the same thing three times.
| Head | Width | Classes |
|---|---|---|
| policy | 6 | fold · check · call · raise · allin · bet |
| betsize | 8 | 0.33 · 0.5 · 0.75 · 1.0 · 1.5 · 2.5 · 3.0 · 4.0 × pot |
| value | 1 | scalar |
For a long period the bet head learned from data in which a serve-time guardrail overwrote every bet the network chose. It was therefore fitting a size it had never actually played, and no metric said so. It only came right when the action space, the objective and the optimiser were fixed together; fixing any one alone did nothing measurable.
Note also that 3.0 and 4.0 were appended to the bucket
list rather than inserted, so older six-wide champions still decode correctly. Widening an ordinal
head in the middle silently relabels every historical model.
Grouped by what they describe. The order is the contract — norm.npz's
mu and sd are positional, so inserting a feature anywhere but the end
invalidates every existing checkpoint.
The f$ prefix marks features that come from the rule-engine's own vocabulary — the
same names its book uses — which is what lets a rule interpreter produce training labels that line
up with the network's inputs. The rest are computed directly from the table read. Note how much of
the vector is opponent model (17 features) and seat/steal context
(8): the hand itself is a minority of what the network sees, which is correct for poker.
Feature groups are switched on by the presence of a marker file beside the weights, so a champion records which capabilities it was actually trained with:
| Marker | Enables |
|---|---|
SIGHTED | multiway equity — the net can see it is not heads-up |
AGG_TRAINED | iamaggressor — who took the initiative |
TRAP_TRAINED | street memory — what I did earlier this street |
EXPLOIT_TRAINED | exploit / steal / players-behind reads |
Exploit features were built, deployed and measured — and were invisible to the policy: adding them changed nothing, because the learning path never credited them. Adaptation itself was worth +196 bb/100 when it worked, so the failure was in learning, not in the features. A marker file records that a group was present; it does not prove the net used it.
| Service | Port | Role |
|---|---|---|
hiss-nn-decide | 8088 | Champion — the live net |
hiss-nn-decide-chal | 8091 | Challenger — the A/B candidate |
hiss-nn-decide-cfr | — | CFR net, its own A/B slot |
hiss-decide | 8087 | Rule engine, headless — the teacher and baseline |
Artefacts live together and travel together:
model_champion/
model.pt raw weights
model_scripted.pt TorchScript — what is actually served
norm.npz mu, sd (86 each) — positional, order is the contract
profile.json the style this champion plays (vpip, pfr, af, wtsd, 3bet, …)
SIGHTED AGG_TRAINED TRAP_TRAINED EXPLOIT_TRAINED feature gates
Rules that override the network at serve time, each added because the net was reliably wrong in one specific place and could not be trained out of it:
The preflop rail overwrote the net on ~75% of preflop spots, so 87 of 114 PPO challengers scored exactly +0.00 against the champion. The gate was not being strict; it was being blind. Any guardrail that improves play also removes the evidence that would let you improve the policy underneath — so measure how often each one fires.
Next — rebuild it from an empty machine →
Hiss NN — the poker network, its training ladder and its serving contract. Written so the whole thing can be rebuilt from an empty machine. Figures are from the live system, not from the plan; where the two disagree the plan is annotated.