Skip to content

One data directory and one credentials directory for every package - #27

Merged
elsehow merged 6 commits into
forecastingresearch:mainfrom
fdrocha:worktree-runpod
Oct 28, 2026
Merged

elsehow merged 6 commits into
forecastingresearch:mainfrom
fdrocha:worktree-runpod

Conversation

@fdrocha

@fdrocha fdrocha commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

As I am preparing to do more runs of world generation and prompting I ran into inconsistencies about how the different world packages handle credentials and output data. I decided to re-organize it a bit before doing any of the runs and this PR does that.

Details from Claude:

Every package now writes its output to data/<package>/ and reads its keys from a single credentials/.env, both at the repository root and both normally symlinks to directories outside the checkout, so concurrent worktrees share one set of data and keys. New worktrees get the links automatically through a committed post-checkout hook. Also a FreeCiv v3 fleet bug fix found in the one-player pilot (400 replays on RunPod).

The commits are split by package, so each reviewer can read just theirs. The cross-package base is the second commit.

  • 450dd944 FreeCiv v3 fleet: start the worker's archive sync through start_sync.sh. The inline pgrep guard ran inside the ssh command, whose own command line contains the sync_loop path, so it always matched and the sync loop never started (found in the pilot, where it had to be started by hand).
  • 92e8d7f2 One data directory and one credentials directory, outside the checkout. fbsim_core.local (repo root, data_dir(package), load_env()); scripts/setup_worktree.sh and .githooks/post-checkout; root .gitignore, README section "Local data and credentials", CLAUDE.md. FBSIM_TEST_DATA_ROOT and FBSIM_TEST_ENV_FILE are test-only overrides. FBSIM_DATA_ROOT is deliberately not used, because in forecastbench-sim-paper it names the private data archive.
  • a2dd75d4 Micropolis: data root and keys from fbsim_core.local. The data root is <repo>/data whatever the working directory (it was ./data). credentials/.env is read only when a runner needs the engine or keys, never at import or for --help. The tests keep the checkout's credentials out, subprocesses included.
  • d4d44c8e Pandemic: cache and results under data/pandemic. scale_results.json, conditional_brier_gap.png and null_conditional_results.json leave git.
  • 74cda6d9 FreeCiv: output under data/freeciv, keys from credentials/.env. The engine's logging root (logs, recordings) moves to data/freeciv/logs through logging_config.logging_dir; game scores move too. About 140 paths in scripts/ that were relative to the working directory become absolute under data/freeciv (mechanical). The scripts still fetch provider keys from GCP Secret Manager; only GOOGLE_CLOUD_PROJECT now comes from credentials/.env. The agentic shell scripts' dead src.civrealm import is fixed.
  • cf9aed5c FreeCiv v3: fleet state and keys outside the checkout. fleet/paths.sh puts the run state in data/freeciv/fbsim_v3/fleet_state and the ssh keys in credentials/freeciv/. Paths are quoted and pods are reached through podsh, so checkout paths with spaces work. Pods record games under data/freeciv/logs. --env-file is removed from the run/ elicitation scripts. PROVENANCE.json records the adaptations.

Heads-up for coauthors

After this merges, once per clone:

  1. Create credentials/.env at the repository root (gitignored), with every variable from your old worlds/*/.env files in one file: ANTHROPIC_API_KEY, OPENROUTER_API_KEY, GOOGLE_CLOUD_PROJECT (FreeCiv still fetches its provider keys from GCP Secret Manager with it), RUNPOD_API_KEY (fleet only), MICROPOLIS_CORE_PATH, and DEEPINFRA_API_KEY (Pandemic scale_eval.py --eval). Variables exported in the shell still win.

  2. Move existing output:

    • worlds/freeciv/logs/ → data/freeciv/logs/;
    • FreeCiv's games/, questions/, conditional/, results/ and evaluations/ (from the root data/ or worlds/freeciv/data/) → data/freeciv/;
    • worlds/pandemic/.response_cache.json → data/pandemic/response_cache.json.

    data/micropolis* stays where it is.

  3. Optional: git config core.hooksPath .githooks, so new worktrees get the links automatically. It replaces .git/hooks; if you have hooks there, run scripts/setup_worktree.sh by hand instead.

data/ and credentials/ can stay real directories in your main checkout; the symlinks are only needed to keep them outside it.

Testing

  • Test suites: Micropolis 227, fbsim-core 16, Pandemic and FreeCiv 40, in the workspace venv. The same suites (227, and 77 for core and benchmark) also pass in the README's wheel-install venv, which exercises fbsim_core.local finding the checkout from the working directory. The two benchmark tests that assert a non-editable install fail in the workspace venv, as on main.
  • Static checks: py_compile on all 60 changed Python files; bash -n on all 28 changed shell scripts; ruff F821/F401 on the changed Python shows no new findings compared with main.
  • Fleet, local, read-only:
    • rp.sh list authenticates with the key from credentials/.env; rp.sh ledger, status.sh, launch_pending.sh and finish_all.sh --dry-run work against the moved state.
    • All of these were also run through a checkout path containing a space, with rsync -e and podsh checked to receive a spaced key path as one argument.
    • A built pod bundle contains no keys, .env files or symlinks.
  • Worktree hook: a new worktree created with git worktree add got both links from the post-checkout hook.
  • Paper build: forecastbench-sim-paper's build_paper.sh route (editable fbsim-core/fbsim-benchmark) was run against main and against this branch, into scratch copies of the manuscript. The outputs are byte-identical. The paper's default route uses the pinned 9e016b76, which this branch cannot affect.
  • Not tested:
    • Anything on RunPod after these changes. The pod-side recordings path (/workspace/civbench/data/freeciv/logs) and the fleet scripts' changes will first run with the next anchor pod. The earlier fleet commits ran the 400-replay pilot.
    • The legacy FreeCiv scripts: their path rewrite was only compiled and checked statically, not run.
    • Live Micropolis, Pandemic or FreeCiv model calls.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Tze4Twn5EYv7cQxwxUcBpP

fdrocha and others added 6 commits October 28, 2026 13:18
The inline pgrep guard ran inside the ssh command, whose own command line
contains the sync_loop path, so it always matched and the loop never started.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4Twn5EYv7cQxwxUcBpP
data/ and credentials/ at the repository root are gitignored symlinks to
directories outside the checkout, so every worktree shares one set of
output and keys; in the main checkout they may also be real directories.
scripts/setup_worktree.sh creates the links (a linked worktree points at
whatever the main checkout has), and .githooks/post-checkout runs it for
every new worktree once `git config core.hooksPath .githooks` is set
(the README notes that this replaces .git/hooks).

fbsim_core.local finds the repository root (from its own file in an
editable install, else from the working directory; with neither, it
warns and uses the working directory), gives
data_dir(package) = <repo>/data/<package>, and load_env() reads
credentials/.env, one sourceable file with every variable any package
needs; exported variables win. FBSIM_TEST_DATA_ROOT and
FBSIM_TEST_ENV_FILE redirect both, for tests only (FBSIM_DATA_ROOT is
deliberately not used: in forecastbench-sim-paper it names the private
data archive).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4Twn5EYv7cQxwxUcBpP
The data root is <repo>/data whatever the working directory (it was
./data); a config's data_dir still selects one folder in it, and the
example configs keep their own. credentials/.env is read only when a
runner needs the engine or provider keys (engine_app_path,
ensure_api_keys), never at import or for --help. The tests keep the
checkout's credentials out, subprocesses included, and point the data
root at a temporary directory with FBSIM_TEST_DATA_ROOT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4Twn5EYv7cQxwxUcBpP
scale_eval.py writes its response cache, scale_results.json and
conditional_brier_gap.png to data/pandemic/ and loads credentials/.env
before calling models. The three result files (with
null_conditional_results.json, which no code writes) leave git; copies
are in data/pandemic/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4Twn5EYv7cQxwxUcBpP
The logging root (logs and game recordings) is data/freeciv/logs, from
logging_config.logging_dir, the single source the engine and run_world.py
share; game scores and their plots go to data/freeciv too. The scripts'
paths relative to the working directory (data/games, data/questions,
data/conditional, data/results, data/evaluations, logs/recordings) are
now absolute under data/freeciv, quoted in the shell scripts. Scripts
load credentials/.env instead of worlds/freeciv/.env and still fetch
provider keys from GCP Secret Manager with its GOOGLE_CLOUD_PROJECT; the
agentic shell scripts' dead src.civrealm import is fixed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4Twn5EYv7cQxwxUcBpP
fleet/paths.sh, sourced by every fleet script, puts the run state (pod
ledger, queues, anchors, logs) in data/freeciv/fbsim_v3/fleet_state and
the ssh keys in credentials/freeciv/; rp.sh reads RUNPOD_API_KEY from
credentials/.env when it is not exported. Paths are quoted and pods are
reached through podsh (the key is quoted inside rsync -e strings), so a
checkout path with spaces works. Pods record games under
data/freeciv/logs, as in the checkout. The run/ elicitation scripts load
credentials/.env and drop --env-file, so they now run with uv run (they
import fbsim_core); make_queue.py defaults to the fleet state's queue;
the bundle excludes .env files. PROVENANCE.json records these
adaptations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tze4Twn5EYv7cQxwxUcBpP
@fdrocha
fdrocha marked this pull request as ready for review October 28, 2026 13:27
@fdrocha
fdrocha requested a review from elsehow October 28, 2026 13:27
@elsehow
elsehow merged commit 27776fc into forecastingresearch:main Oct 28, 2026
2 checks passed
@fdrocha
fdrocha deleted the worktree-runpod branch October 30, 2026 14:33
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.

2 participants