Swarm runner: standalone run_swarm() lacks stack env scaffolding; YIELDOMEGA_SWARM_REFERRALS=0 verification deferred #102
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#102
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Verification of the local bot swarm path with referrals disabled (
YIELDOMEGA_SWARM_REFERRALS=0) was not completed in-session and is tracked here as deferred work.When attempting to invoke
swarm_runner.run_swarm()directly (outsidescripts/start-local-anvil-stack.sh), contributors hit swarm runner configuration failures attributable to missing environment scaffolding that the stack wrapper normally establishes implicitly. Until that scaffolding is repeatable for standalone runs and/or surfaced on the canonical wrapper path, the “no swarm referrals” behavior remains undertested in practice.Background
Intended behavior (
YIELDOMEGA_SWARM_REFERRALS)The TimeCurve bot swarm optionally bootstraps a shared referral code for deterministic local QA aligned with referrer flows and indexer ingestion (GitLab #94).
Implementation:
swarm_referrals_enabled()inbots/timecurve/src/timecurve_bot/referral_bootstrap.pyreturns false whenYIELDOMEGA_SWARM_REFERRALSis set to0(otherwise defaults to enabled).swarm_runner.pyfunds the registrar HD index (27), runsensure_swarm_referral_registered(...), and setsYIELDOMEGA_REFERRAL_CODEin worker subprocess env so buys usebuy(..., codeHash, ...).YIELDOMEGA_SWARM_REFERRALS=0), the swarm should skip registrar funding for referrals, skip registration bootstrap, and omitYIELDOMEGA_REFERRAL_CODEfrom workers so buys exercise the non-referral path.This is documented at a high level in
bots/timecurve/README.mdand cross-linked fromdocs/testing/invariants-and-business-logic.md.Canonical wrapper path
When
START_BOT_SWARM=1,start-local-anvil-stack.sh(tail of script):scripts/sync-bot-env-from-frontend.sh, which materializesbots/timecurve/.env.localfromfrontend/.env.local(RPC, chain id, TimeCurve / treasury / NFT addresses,acceptedAssetviacast, etc.).cd "${ROOT}"), exportsYIELDOMEGA_ALLOW_ANVIL_FUNDING=1, setsPYTHONPATH, and executes:run_swarm()callsload_config(env_file=None, send=True, allow_anvil_funding=False), which loads.envand, when the process cwd is the repo root,bots/timecurve/.env.local(bots/timecurve/src/timecurve_bot/config.py—load_dotenv_files).Thus the wrapper does two critical things beside setting
ALLOW_ANVIL_FUNDING:.env.local.Problem statement (what went wrong)
A contributor attempted to manually reproduce swarm behavior under
YIELDOMEGA_SWARM_REFERRALS=0by callingrun_swarm()outsidestart-local-anvil-stack.sh.That standalone invocation did not inherit the same effective environment as the wrapper:
sync-bot-env-from-frontend.shmay not have been run (no freshbots/timecurve/.env.local), producingload_config/ValueErrorfailures such as unsetYIELDOMEGA_RPC_URL/RPC_URLor unsetYIELDOMEGA_TIMECURVE_ADDRESS.YIELDOMEGA_ALLOW_ANVIL_FUNDING=1may be unset, causingSystemExit(2)with the swarm’s documented guardrail.load_dotenvresolution forbots/timecurve/.env.localis relative to cwd, not the package layout.PYTHONPATHtobots/timecurve/srcbreaks imports when not usingpython -mfrom an installed/env layout.Net effect: the failure mode observed was a runner configuration / env orchestration gap, not necessarily a defect in
swarm_referrals_enabled()logic itself. Because of that gap,YIELDOMEGA_SWARM_REFERRALS=0was not empirically exercised during the intended session (DEFERRED).Impact
=0end-to-end.swarm_runner,referral_bootstrap, or workerbuywiring could regress the opt-out path without CI catching it.Recommended fixes
Deliver one or more of the following (in order of leverage vs. scope):
A. Wrapper-visible opt-out (minimal, explicit)
Extend
START_BOT_SWARM=1UX onstart-local-anvil-stack.shto forward (or document and default-copy)YIELDOMEGA_SWARM_REFERRALS.YIELDOMEGA_SWARM_REFERRALS=0before starting the stack, the same subprocess that callsrun_swarm()inherits it—no Python code change strictly required, but today the script neither documents nor echoes this knob in the “Bot swarm” banner.YIELDOMEGA_SWARM_REFERRALS=0 (referral bootstrap disabled)vs default.This matches the contributor note: “follow up by setting the env on the wrapper script itself in a separate boot”—interpreted as making the wrapper path the place where this flag is first-class for local runs.
B. Document the standalone contract (docs / README)
Add a short “Run swarm without
start-local-anvil-stack.sh” checklist tobots/timecurve/README.md(and optionallydocs/testing/e2e-anvil.md):frontend/.env.local(or equivalent addresses).bash scripts/sync-bot-env-from-frontend.shexport YIELDOMEGA_ALLOW_ANVIL_FUNDING=1export YIELDOMEGA_SWARM_REFERRALS=0PYTHONPATH=bots/timecurve/src python3 -c "from timecurve_bot.swarm_runner import run_swarm; run_swarm()"or
timecurve-bot --allow-anvil-funding swarmwith the same env.C. Friendlier failure messages (optional code)
In
run_swarm(), whenload_configfails on missing RPC/TimeCurve, catchValueErroronce and append a hint pointing tosync-bot-env-from-frontend.shand repo-root cwd (keep messages short; avoid noisy stack traces for expected misconfig).D. Automated smoke (stretch)
A small scripted or pytest smoke that mocks/stubs RPC is likely overkill; prefer a documented one-liner plus optional CI job only if we can spin Anvil cheaply. Not required for closing this issue if manual acceptance below is satisfied.
Acceptance criteria
Documented path
There is repo-checked documentation (README and/or testing doc) that lists all prerequisites to run
run_swarm()withoutstart-local-anvil-stack.sh, includingsync-bot-env-from-frontend.sh,YIELDOMEGA_ALLOW_ANVIL_FUNDING=1, repo-root cwd, andYIELDOMEGA_SWARM_REFERRALS=0when testing the opt-out.Wrapper discoverability
When
START_BOT_SWARM=1, the stack script mentionsYIELDOMEGA_SWARM_REFERRALSin user-facing output (help text, comment block, or banner) so operators know they can set0without reading Python.Verified behavior (manual)
On a fresh local Anvil stack (or equivalent):
YIELDOMEGA_SWARM_REFERRALS=0, swarm starts successfully via the documented path (wrapper or standalone checklist).registerCodebootstrap for the swarm shared code (or N/A when registry zero), and worker env does not setYIELDOMEGA_REFERRAL_CODE(or workers buy without referral code—however the bot surfaces that).Cross-links
Update
docs/testing/invariants-and-business-logic.mdLocal stack bot swarm row or referrals subsection to reference this issue for theYIELDOMEGA_SWARM_REFERRALS=0verification note (one sentence).Related references
Labels / area
area:bots·type:tech-debtortype:documentation·priority::low-to-medium(suggest; adjust per project convention)marked this issue as related to #94
mentioned in commit
6b036a14adImplemented A + B + C from this issue and pushed to
main(6b036a1).What changed
scripts/start-local-anvil-stack.shdocumentsYIELDOMEGA_SWARM_REFERRALSin the header and prints a one-line summary whenSTART_BOT_SWARM=1(on vs off / opt-out).run_swarm()checklist inbots/timecurve/README.md; env table row + § Standalone bot swarm indocs/testing/e2e-anvil.md; invariants row + cross-links indocs/testing/invariants-and-business-logic.md,skills/README.md,bots/timecurve/SKILL.md,.cursor/skills/yieldomega-guardrails/SKILL.md.swarm_runner._load_config_for_swarm()catchesload_configValueError, prints a short hint (sync-bot-env-from-frontend.sh, repo-root cwd,YIELDOMEGA_ALLOW_ANVIL_FUNDING), exits 2 without a traceback. Unit test:bots/timecurve/tests/test_swarm_runner.py. Full botpytestrun: 17 passed./cc @brouie — please verify on your side (issue stays open per contributor request).
Verification checklist
export YIELDOMEGA_SWARM_REFERRALS=0thenSKIP_ANVIL_RICH_STATE=1 bash scripts/start-local-anvil-stack.sh— banner shows referrals off; swarm starts; workers buy without shared referral bootstrap (noYIELDOMEGA_REFERRAL_CODEin worker env; no registrar funding line for index 27).YIELDOMEGA_SWARM_REFERRALS=0— banner shows referrals on; prior behavior unchanged.frontend/.env.local,bash scripts/sync-bot-env-from-frontend.sh,export YIELDOMEGA_ALLOW_ANVIL_FUNDING=1, repo-root cwd,PYTHONPATH=bots/timecurve/src python3 - c "from timecurve_bot.swarm_runner import run_swarm; run_swarm()"— swarm runs (or fails only for chain reasons, not missing env).run_swarm()prints one error line + Hint mentioningsync-bot-env-from-frontend.shand repo-root cwd; exit code 2.Typo fix for checklist item 3: use a single line (no line break after
python3):PYTHONPATH=bots/timecurve/src python3 -c "from timecurve_bot.swarm_runner import run_swarm; run_swarm()"Items 1 + 2 PASS on
bf00d60(parent6b036a1). Wrapper boots verified clean from a torn-down stack.Item 2 — default referrals ON (regression check)
Banner:
Swarm referrals: ON — shared code for workers (export YIELDOMEGA_SWARM_REFERRALS=0 to opt out — GitLab #102)Bootstrap (3 lines,
/tmp/yo_stack_102_item2.log):swarm: funding referral registrar index 27 for code registrationregisterCode('swarmyo') tx=b0322ec45a90565a39dd423515e3d285c370d9c09ba88a4d40b3d7624c352f57 status=1swarm referrals: registered 'swarmyo' for 0x87BdCE72c06C21cd96219BD8521bDF1F42C78b5eIndexer ingestion (~3.5 min uptime): HD-27 rank 1,
referred_buy_count=28,total_referrer_charm_wad=6127198716742986130(~6.13 CHARM). Behavior matches #94 EOD baseline.Item 1 — opt-out
YIELDOMEGA_SWARM_REFERRALS=0Banner:
YIELDOMEGA_SWARM_REFERRALS=0 — referral bootstrap disabled (non-referral buy path)Stack log: zero matches for
registerCode|swarmyo|HD-?27|registrar|REFERRAL_CODE(no registrar funding, no registerCode tx, no swarmyo registration).Worker env (PID 1016283
timecurve_bot.cli seed-local,/proc/<pid>/environ):YIELDOMEGA_SWARM_REFERRALS=0present (passes through)YIELDOMEGA_REFERRAL_CODEABSENT — workers buy non-referral pathYIELDOMEGA_ALLOW_ANVIL_FUNDING=1,YIELDOMEGA_RPC_URL,YIELDOMEGA_CHAIN_IDall set (sync-bot-env baseline normal)Indexer leaderboard after 30s+ swarm activity:
{"items": [], ...}. NoReferralAppliedon-chain.Bot count = 18 (3× seed-local/defender/fun/shark/pvp/rando) — swarm spawning matches default-on, only referral bootstrap skipped.
Items 3 (standalone path) + 4 (misconfig hint + exit 2) — verifying next on this same Item 1 stack. Will post on completion.
Item 4 — misconfiguration (unset RPC)
Repro:
cd /tmp
env -i HOME=$HOME PATH=$PATH YIELDOMEGA_ALLOW_ANVIL_FUNDING=1
PYTHONPATH=/srv/qa/repos/yieldomega/bots/timecurve/src
python3 -c "from timecurve_bot.swarm_runner import run_swarm; run_swarm()"
Output (exact):
swarm: config error: Set YIELDOMEGA_RPC_URL or RPC_URL to an HTTP JSON-RPC endpoint.
Hint: from repository root run
bash scripts/sync-bot-env-from-frontend.sh(needsfrontend/.env.localor equivalent), export YIELDOMEGA_ALLOW_ANVIL_FUNDING=1, and use repo-root cwd sobots/timecurve/.env.localis loaded byload_config.EXIT_CODE: 2
Spec checks:
Notes:
PASS.
Item 3 — standalone path (happy path)
Repro (verbatim from dev's checklist):
cd /srv/qa/repos/yieldomega
bash scripts/sync-bot-env-from-frontend.sh # Wrote bots/timecurve/.env.local
export YIELDOMEGA_ALLOW_ANVIL_FUNDING=1
PYTHONPATH=bots/timecurve/src nohup python3 -c
"from timecurve_bot.swarm_runner import run_swarm; run_swarm()"
> /tmp/yo_item3_standalone.log 2>&1 &
Result: parent exited cleanly, 18 worker bots spawned and running.
Bootstrap output (key lines from /tmp/yo_item3_standalone.log):
swarm: funding referral registrar index 27 for code registration
swarm: one-shot Anvil dev funding (anvil_setBalance + mock mint)
[28x mint(CL8Y mock) tx=... status=1 lines]
swarm: anvil_setBalance 10000 ETH for 28 swarm addresses (gas).
swarm: minted 1000000000000000000000000000000000 wei mock reserve to 28 addresses.
approve tx=145c7bf97... status=1
registerCode('swarmyo') tx=6eec65660522a6922a987f5be9207d5692f9e857e2337257b903683015299e31 status=1
swarm referrals: registered 'swarmyo' for 0x87BdCE72c06C21cd96219BD8521bDF1F42C78b5e
[18x swarm: started -N pid=... log=/tmp/yieldomega_swarm_-N.log lines]
swarm: 18 processes; PIDs in /tmp/yieldomega_bot_swarm.pids
Pidfile (/tmp/yieldomega_bot_swarm.pids): 18 PIDs, all match
psoutput for active workers.ps confirms 18 timecurve_bot.cli workers running (3x each: seed-local, defender, fun, shark, pvp, rando).
Spec checks:
PASS.
All 4 acceptance items PASS on
bf00d60(parent fix6b036a1).Summary:
YIELDOMEGA_SWARM_REFERRALS=0): banner OFF, no registrar funding, noregisterCodetx, worker env has noYIELDOMEGA_REFERRAL_CODE, indexer leaderboard empty after 30s+ — note 3305970395registerCode('swarmyo') tx=b0322ec..., registered for0x87BdCE72...), HD-27 indexer ingestion confirmed (28 buys / 6.13 CHARM in 3.5min) — note 3305970395PYTHONPATH=... python3 -c "...run_swarm()"from repo root): full bootstrap clean (28x mints, anvil_setBalance 10000 ETH for 28 addrs, 1e33 wei mock reserve,registerCode tx=6eec656..., 18 workers spawned with PIDs logged), no missing-env failures — note 3305992211sync-bot-env-from-frontend.sh+ repo-root cwd +bots/timecurve/.env.local, exit code 2, no traceback — note 3305984353AC #1 (documented path), #2 (wrapper discoverability via banner + header comment line 19-20), #3 (verified behavior, all three sub-bullets PASS), #4 (cross-links in invariants doc) — all satisfied.
Closing.
mentioned in issue #104
mentioned in issue #162