Files
SirRoboGarage/common_libs/tests/test_lead_gain_legacy.nim
T
SirStone 5e32ec16df j142 retire the ADE+SBC gun (rack id 17): the owner watched it, it does not learn, throw it away
Remove guns/bitbrain_net.nim (+README), test_bitbrain_net.nim,
measure_bitbrain_scaling.nim, rack id 17 and all of its plumbing in
selector.nim / ModularBot.nim / env_report.nim, the TR_BITBRAIN_NET switch
and the NEW-NETWORK TR_BITBRAIN_* knobs, and the BitBrainNet arm of
run_prediction_quality.nim.

With id 17 gone there is nothing to disambiguate, so the legacy namespace
becomes the ONLY one: TR_RACK_BITBRAIN always selects id 16 LEADGAIN and
every TR_BITBRAIN_<X> in the frozen 14-suffix alias set always means
TR_LEADGAIN_<X>. The alias layer and its [depr] line stay.

KEPT: the common_libs/bitbrain/ SBC library (learned_surfer imports
bitbrain/sbc), lead_gain at id 16 with env TR_LEADGAIN_* and log tag [lg],
and the c9b6753 crash fix (NumRackGuns widths + test_rack_stat_width).

Tombstone: docs/bitbrain_campaign.md ## RETIRED and one cross-reference line
in docs/gun_campaign.md. Shipped defaults unchanged: clean env -> rack
active 1v1 = PATTERN, movement default strafe.
2026-09-26 19:20:23 +02:00

185 lines
8.1 KiB
Nim

## Backward-compatibility guard for the LEADGAIN rename (gun id 16).
##
## The owner's live `.env` predates the rename and carries `TR_RACK_BITBRAIN`,
## `TR_BITBRAIN_GAINS`, `TR_BITBRAIN_MEM`, `TR_BITBRAIN_LOG`. Those names used to
## address the corrector that is now called LEADGAIN, and they MUST keep working.
##
## The ADE+SBC gun that briefly owned the `TR_BITBRAIN_*` prefix (rack id 17,
## `guns/bitbrain_net.nim`) was RETIRED and removed, so there is nothing left to
## disambiguate: this gun is the SOLE owner of that namespace and
##
## * every `TR_BITBRAIN_<X>` in the frozen `LegacyKnobEnvNames` set is an
## alias for `TR_LEADGAIN_<X>`, unconditionally;
## * `TR_RACK_BITBRAIN` selects rack id 16, unconditionally;
## * a stale `TR_BITBRAIN_NET=1` left in a `.env` is an unrecognised
## variable — the boot report warns about it and nothing reads it.
##
## Run: nim c -r common_libs/tests/test_lead_gain_legacy.nim
import std/[os, strutils]
import gun_harness/virtual_bullets
import gun_harness/selector
import guns/lead_gain
const LeadGainId = 16
var failures = 0
proc check(name: string, ok: bool) =
if ok: echo "PASS: ", name
else: echo "FAIL: ", name; inc failures
proc clearEnv() =
for suffix in LegacyKnobEnvNames:
delEnv(LegacyPrefix & suffix)
delEnv(NewPrefix & suffix)
delEnv(LegacyRackEnvName)
delEnv("TR_RACK_" & RackGunNames[LeadGainId])
delEnv("TR_BITBRAIN_NET")
# ── the alias table itself ───────────────────────────────────────────────────
proc testAliasTableIsDisjoint() =
## Every legacy name must be a `TR_BITBRAIN_<X>` whose `X` is in the frozen
## set, and the new name must be the `TR_LEADGAIN_<X>` of the same suffix.
var ok = LegacyKnobEnvNames.len == 14
var suffixes: seq[string]
for s in LegacyKnobEnvNames:
if s.len == 0 or s in suffixes: ok = false
suffixes.add s
check "table: 14 unique legacy suffixes", ok
check "table: the legacy prefix is TR_BITBRAIN_", LegacyPrefix == "TR_BITBRAIN_"
check "table: the new prefix is TR_LEADGAIN_", NewPrefix == "TR_LEADGAIN_"
# The corrector's own live knobs must all be in the alias set, otherwise the
# owner's `.env` silently stops working.
for knob in [LG_MEM_ENV, LG_GAINS_ENV, LG_LOG_ENV, LG_MIN_OBS_ENV, LG_DECAY_ENV,
LG_DECAY_FRAC_ENV, LG_RESET_ON_TARGET_ENV, LG_N_ENV, LG_NADE_ENV,
LG_RANGE_ENV, LG_WARMUP_ENV, LG_ADAPT_ENV, LG_CALIB_ENV, LG_SEED_ENV]:
let suffix = knob[NewPrefix.len .. ^1]
if suffix notin LegacyKnobEnvNames: ok = false
check "table: every corrector knob has a legacy alias", ok
# ── the switch ───────────────────────────────────────────────────────────────
proc testNamespaceIsUnconditional() =
## There is no namespace switch any more. The ADE+SBC gun is gone, so a stale
## `TR_BITBRAIN_NET` left in an old `.env` is inert: it must neither disown
## the legacy knob aliases, nor the legacy rack knob, nor the deprecation line.
clearEnv()
putEnv("TR_BITBRAIN_MEM", "decay")
putEnv("TR_BITBRAIN_LOG", "1")
putEnv(LegacyRackEnvName, "both")
var g = initLeadGainGun()
check "ns: the legacy prefix is unconditional (no switch set at all)",
g.memMode == lgDecay and g.logEnabled
putEnv("TR_BITBRAIN_NET", "1")
var g1 = initLeadGainGun()
check "ns: a stale TR_BITBRAIN_NET=1 does not disown the legacy knob names",
g1.memMode == lgDecay and g1.logEnabled
putEnv("TR_BITBRAIN_NET", "0")
var g2 = initLeadGainGun()
check "ns: a stale TR_BITBRAIN_NET=0 is equally inert", g2.memMode == lgDecay
putEnv("TR_BITBRAIN_NET", "1")
check "ns: a stale TR_BITBRAIN_NET=1 does not disown the legacy rack knob",
loadRackMembership()[LeadGainId] == rmBoth
check "ns: a stale TR_BITBRAIN_NET=1 does not suppress the deprecation line",
lgDeprecationLine().len > 0
clearEnv()
# ── knob aliasing ────────────────────────────────────────────────────────────
proc testKnobAlias() =
clearEnv()
# the owner's exact .env
putEnv("TR_BITBRAIN_GAINS", "1.0,0.5,0.25")
putEnv("TR_BITBRAIN_MEM", "decay")
putEnv("TR_BITBRAIN_LOG", "1")
var g = initLeadGainGun()
check "alias: TR_BITBRAIN_GAINS feeds the candidate set",
g.cands == @[0.25, 0.5, 1.0]
check "alias: TR_BITBRAIN_MEM=decay is honoured", g.memMode == lgDecay
check "alias: TR_BITBRAIN_LOG=1 turns the log on", g.logEnabled
# the new name always wins over the legacy alias
putEnv("TR_LEADGAIN_GAINS", "0.5,0.75")
var g2 = initLeadGainGun()
check "alias: the NEW name wins when both are set", g2.cands == @[0.5, 0.75]
# the legacy namespace is unconditional, even next to a stale NET switch
putEnv("TR_BITBRAIN_NET", "1")
delEnv("TR_LEADGAIN_GAINS")
var g3 = initLeadGainGun()
check "alias: a stale TR_BITBRAIN_NET=1 does NOT make the legacy names inert",
g3.memMode == lgDecay and g3.logEnabled and
g3.cands == @[0.25, 0.5, 1.0]
# ... and then the NEW names still work
putEnv("TR_LEADGAIN_MEM", "retained")
var g4 = initLeadGainGun()
check "alias: TR_LEADGAIN_* is always read, in both modes",
g4.memMode == lgRetained
clearEnv()
# ── rack alias ───────────────────────────────────────────────────────────────
proc testRackAlias() =
clearEnv()
putEnv(LegacyRackEnvName, "both")
let m = loadRackMembership()
check "rack: TR_RACK_BITBRAIN=both still selects LEADGAIN (id 16)",
m[LeadGainId] == rmBoth and
vBulletAdmitted(LeadGainId, rm1v1, m, true)
putEnv("TR_BITBRAIN_NET", "1")
let m2 = loadRackMembership()
check "rack: a stale TR_BITBRAIN_NET=1 no longer disowns the name — LEADGAIN (id 16) stays selected",
m2[LeadGainId] == rmBoth and m2.len == NumRackGuns
clearEnv()
putEnv("TR_RACK_LEADGAIN", "both")
putEnv(LegacyRackEnvName, "off")
let m3 = loadRackMembership()
check "rack: the new name wins over the legacy alias",
m3[LeadGainId] == rmBoth
clearEnv()
# ── the deprecation line ─────────────────────────────────────────────────────
proc testDeprecationLine() =
clearEnv()
check "depr: no legacy knobs => no deprecation line",
lgDeprecationLine().len == 0
putEnv("TR_BITBRAIN_GAINS", "1.0")
let line = lgDeprecationLine()
check "depr: a legacy knob produces exactly one line naming the new name",
line.startsWith("[depr]") and
line.contains("TR_BITBRAIN_GAINS -> TR_LEADGAIN_GAINS") and
line.contains(NewPrefix)
putEnv("TR_BITBRAIN_NET", "1")
check "depr: the line still fires with a stale TR_BITBRAIN_NET=1 present",
lgDeprecationLine().len > 0
clearEnv()
# ── shipped-default parity ───────────────────────────────────────────────────
proc testDefaultParity() =
clearEnv()
let m = loadRackMembership()
var onlyPattern = true
for i in 0..<RackGunNames.len:
let want = if i == 5: rmBoth else: rmOff
if m[i] != want: onlyPattern = false
check "parity: a clean env still loads the shipped onlyPattern rack", onlyPattern
check "parity: the rack is still 17 guns at id 16 = LEADGAIN",
RackGunNames.len == 17 and RackGunNames[LeadGainId] == "LEADGAIN"
var g = initLeadGainGun()
check "parity: a clean env resolves the shipped candidate set",
g.cands == @[0.0, 0.25, 0.5, 0.75, 1.0] and g.memMode == lgPerRound
clearEnv()
testAliasTableIsDisjoint()
testNamespaceIsUnconditional()
testKnobAlias()
testRackAlias()
testDeprecationLine()
testDefaultParity()
if failures > 0:
echo "\n", failures, " check(s) FAILED"
quit(1)
echo "\nAll LEADGAIN legacy-alias checks passed."