CLAUDE.md@ladder-foundry · git:20260701.cf4628b · 2026-07-01 · sha256 cb19a499490617d6

CLAUDE.md@ladder-foundry git:20260701.cf4628bA

Immutable. This exact content is served forever at /api/v1/blob/cb19a499490617d6.

# ladder-foundry — Working Notes for a Fresh Session

Orientation for whoever (human or CC) picks this up next. Local-only handoff
doc; the authoritative design lineage lives in the specs/plans referenced
below. **Read this first, then the STAGE-5 section, before touching anything.**

## What this is

ladder-foundry is the built form of the triple-CC pretrain generator
(design doc: `D:\YOGSOTH-AI\context\2026-06-06-20-18-triple-cc-architecture.md`).
Three nested Claude Code sessions act as a pseudo-NN training loop:

```
optimizer-cc  (long-running orchestrator; = the driving CC session itself)
  └─ sim-cc   (fresh per run; injected a PolicyCard persona)
       └─ exec-cc (fresh per run; the 773-skill DARE body doing the research)
```

Each run yields a labeled `(research_config, research_graph, research_result)`
triple. The **label = the generating PolicyCard** (the known supervision
condition), which sidesteps the no-ground-truth problem. A batch = 6 rungs ×
8 topics = 48 runs. Converged = 3 consecutive batches with pass_ratio ≥ 0.80.

## Status: STAGE 1–4 DELIVERED (all local), STAGE 5 = wire + run

Branch: `self-iteration/ladder-foundry` (NOT main; continuous iteration — do
NOT merge/push-to-main/finish). STAGE 1–4 built every part and verified it
**locally**: 8 leaf scripts (`scripts/`), 3 trainable weights + generator
(`generator/`), 7 skill artifacts (`skills/`), loss harness
(`skills/optimization-loop/scripts/run_codex_loss.py`), optimizer brain
(`skills/optimization-loop/SKILL.md`). Full suite: 117 passed. Final
whole-branch review: READY TO MERGE. **The blocks are all there.**

STAGE 5 does not author new components — it **wires the existing ones into
the real 3-layer nesting and runs them.** That is where a real machine and
real keys come in.

## Why STAGE 5 needs a dedicated machine (read carefully — two reasons, only one is real)

### Reason 1 (real): clean isolation + cost + long-run
This dev box is Windows / Git-Bash, has **no tmux**, and `D:\YOGSOTH-AI\.mcp.json`
carries **9 inline API keys** (SS_API_KEY, BRAVE_API_KEY, APIFY_TOKEN,
RUNPOD_API_KEY, 2× AWS pairs, …) plus `.env` (NPM_TOKEN, GITHUB_TOKEN). A
48-run × N-batch nested job wants a clean Linux box with strict role
isolation. **This reason justifies renting.**

### Reason 2 (NOT solved by renting): the transport-layer deadlock
The core action — **a parent CC launching a child `claude` in its own Bash
tool and holding a multi-turn conversation with it** — has NEVER been run,
and by pure reasoning it collides with the locked constraints:

- A Bash tool call is one-shot: run → wait for exit → collect stdout.
- Interactive `claude` (no print flag) is a TUI: it does not exit, it waits
  on a TTY. A one-shot Bash call cannot feed it multiple turns.
- The known ways to drive CC programmatically across turns are: (a) the print
  flag + resume/session-id continuation, (b) the SDK, (c) a persistent
  terminal via PTY/tmux.
- **All three are banned** (print/resume/session-id/PTY/tmux-for-children/
  driver-script are hard-forbidden — see constraints). That ban set closes
  *every* known path to a multi-turn sim↔exec conversation.

**This contradiction is OS-independent.** Renting a Linux box lets the cheap
scaffolding (Reason 1) go up smoothly, but the job will still stall at "parent
CC says the second sentence to the child." So:

> **Recommended order: do NOT rent yet.** First run a ~15-minute transport
> spike on ANY machine (this one is fine) inside `sandbox/`: can a parent CC
> `claude`-launch a child and receive one reply? Three outcomes —
> (1) it works some way I didn't foresee → transport confirmed, then rent &
> scaffold with confidence; (2) it needs exactly one ban relaxed (e.g. allow
> the print flag, fresh process per turn, no continuation) → bring the
> evidence back and let the user trade "fully-interactive-REPL aesthetics" for
> "it runs"; (3) it cannot work at all → save the rent money, redesign.

The spike is the ONE genuine unknown in STAGE 5. Everything else is
determinate labor.

## Decisions locked this session (2026-07-01)

1. **Sandbox location:** build the runtime sandbox under a directory inside
   `D:\YOGSOTH-AI\` (build-on-site), NOT the design doc's POSIX `/workspace`.
   All four role config-dirs move inside it. **Hard boundary: all reads/writes
   stay within that sandbox + standard config locations — never touch anything
   else.**
2. **Drop codex; loss also runs on CC.** Chosen form: keep ALL of
   `run_codex_loss.py`'s harness logic unchanged (shuffle / Copeland / Kendall
   τ / K-vote / schema validation / all thresholds), and swap only the
   innermost `codex_fn` from calling `codex exec` to calling `claude` in a
   clean config-dir carrying just the two loss skills. The independent,
   check-blind 4th judge role is PRESERVED (no-fake-stub red line intact) —
   it just runs on `claude` instead of `codex`.
3. **Cost knob (deferred switch):** to save money, either point the loss/exec
   CCs at a third-party API base-url, or run everything on haiku. Implement as
   a fillable knob per config-dir; do not let it block sandbox bring-up.

## Isolation red line (STAGE-5 scaffolding MUST honor)

The four role config-dirs (`home/optim`, `home/sim`, `home/exec`, `home/loss`)
must be **clean** — they must NOT inherit `D:\YOGSOTH-AI\.mcp.json` (9 keys)
or `.env` (2 tokens). Each role carries only what it needs:
- optim: this project's optimization-loop skill + superpowers
- sim: superpowers only (persona is injected, no skills)
- exec: the 773 DARE skills + formated-specs/formated-results + superpowers
- loss: injection-fidelity + ladder-quality-order only (check-blind)

## Environment facts (this box, verified 2026-07-01, read-only)

- `claude` 2.1.197 on PATH; global config `C:\Users\Strix\.claude`.
- `codex` 0.120.0 on PATH (`~/.codex` has auth) — present, but we drop it.
- Shell: Git Bash / MSYS2 (`MINGW64`), NOT WSL. `$HOME=/c/Users/Strix`.
- **tmux: NOT installed.** No terminal multiplexer available.
- `ladder-foundry/sandbox/` already has a prototype (`.claude/`,
  `settings.local.json.template`, `read_session.py`, `smoke_test.py`) but NO
  runtime `home/{optim,sim,exec,loss}/`, `work/`, or `runs/` yet — those are
  what STAGE-5 scaffolding creates.

## STAGE-5 scaffolding checklist (the cheap, determinate "A-class" work)

Do this ONLY after the transport spike passes:
- Create clean role config-dirs `home/{optim,sim,exec,loss}/.claude` (each with
  `settings.local.json` = `{"permissions":{"defaultMode":"bypassPermissions"}}`),
  `work/{sim,exec,loss}` cwds, `runs/` skeleton.
- Apply the `codex_fn → claude` swap in `run_codex_loss.py`.
- Fix **M1**: `gen_configs.py` names configs `config_{rung}.json` (rung only) →
  collides across 8 topics at 48-run scale. Rename to
  `config_{topic}_{rung}` BEFORE the optimizer chains gen_configs into the loop.

## Standing hard constraints (carry every session — do NOT violate)

- **Privacy red line:** the CC log path (`C:\Users\...\.claude\projects\...`,
  its POSIX form, and any derived cwd-slug) MUST NEVER appear in any committed
  artifact. Log-reading scripts take `--logs-dir` as a REQUIRED arg, no
  default. Committed outputs are de-identified/aggregate only. Key VALUES
  never committed.
- **Banned CC flags EVERYWHERE (incl. design text):** the print flag,
  resume, session-id, allowed-tools, PTY/pexpect, tmux-for-children, and any
  driver script. All CC layers are normal interactive REPLs. (This ban is the
  source of the transport deadlock above — relaxing it is a user decision.)
- **Between-run independence:** sim/exec are freshly spawned each run; only
  the optimizer is continuous.
- **W5 leak boundary:** generation + loss skills are check-blind — they never
  see the 32 checks / 6 primitives / detection signatures. The probe is the
  only check-seeing session.
- **4-layer DARE architecture INVARIANT** (campaign→strategy→tactic→sop).
- **D1–D5 evaluation standard ONLY.** Academic criteria
  (novelty/baseline/rigor/citations/publishability) are FORBIDDEN as judging
  criteria.
- **Data-oriented weights:** training edits weights JSON only; `.py` never
  moves. `frozen_label` LOCKED; `collision_offset_axis ∈ {B1, expression}`;
  ONE weight changed per batch (先归因再动手).
- **no-fake-stub:** the loss codex/CC edge is NEVER stubbed to a green gate
  outcome; no local test asserts a gate result from canned output.
- Write/Edit calls stay UNDER 13000 chars; build large files in parts.
- Commit trailer: `Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>`.

## Known debts to carry into STAGE 5

- M1 gen_configs naming collision (fix as noted above).
- `run_codex_loss.py` tempfile leak (`delete=False` never unlinked).
- `validate()` is one-level (nested `per_axis_evidence` unenforced).
- `copeland_order` lacks a `winner ∈ {0..n-1}` guard (an out-of-range judge
  winner would KeyError rather than exit-2 gracefully).

## Next action

Run the transport spike (see STAGE-5 section). Do not rent a machine, build
the sandbox, or start the 48-run loop before that single unknown is resolved
and the user has ruled on any ban relaxation it surfaces.