Clamp anchorWidth output with `% (2**24)` before the uint24 cast so that
large literal values (e.g. 1e18 from evolved constants) produce valid
Solidity instead of a compile-time overflow error.
Add test_transpiler_clamping.sh (Test 5) verifying that a Push3 program
outputting 1e18 for anchorWidth generates `uint24(... % (2**24))` and not
the raw overflowing literal. Update package.json to run both test suites.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add skip_candidate() helper that emits fitness=0 JSON to stdout and
tracks the failed score for the output-dir file, satisfying the
downstream scorer's expectation of one JSON line per candidate.
- Unify all failure paths (transpile, forge build, bytecode extract,
empty bytecode) through skip_candidate() with a distinct error key.
- Log message now reads "WARNING: <id> compile failed — scoring as 0"
as required by the acceptance criteria.
- Output-dir scores.jsonl now merges successful + failed scores so the
file is complete even when some candidates fail to compile.
- All-candidates-fail path (COMPILED_COUNT=0) still exits 2 (no viable
population); true infra errors (missing tool, bad RPC) unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move CROSS_PATTERNS_FILE from /tmp/red-team-cross-patterns.jsonl to
tools/red-team/cross-patterns.jsonl (repo-tracked path)
- Remove the reset (> file) at sweep start so patterns accumulate across runs
- Generate a SWEEP_ID (sweep-YYYYMMDD-HHMMSS) at sweep start and stamp
each new entry with sweep_id for traceability
- Deduplicate on (pattern, candidate, result): entries already present in
the file are skipped; intra-batch duplicates are also suppressed
- Create tools/red-team/ directory with .gitkeep
- Add mkdir -p guards in both scripts so the directory is created on first run
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extend the patch to also replace the NatSpec comments above MAX_ANCHOR_WIDTH,
which became misleading after switching to type(uint24).max. The old comments
claimed overflow-safety ("fits in int24"); the new comments document that the
production cap is 1233, that values above 123358 overflow int24 and revert,
and that this is tolerable in the evolution context where reverts score zero
fitness. The patch now correctly updates both the constant and its documentation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Regenerate evolution.patch from the current ThreePositionStrategy.sol.
The old patch had a corrupt hunk header (@@ -33,7 +33,7 @@ claiming 7 lines
but only supplying 4) and placeholder index hashes (0000000..0000000),
causing `git apply` to reject it with "corrupt patch". MAX_ANCHOR_WIDTH
still exists in the file at value 1233; the patch correctly overrides it
to type(uint24).max for unbounded evolution runs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update tsconfig.json to use NodeNext module system (fixes CJS/ESM conflict),
enable ts-node ESM mode, and add .js extensions to relative imports so the
built output and ts-node dev script both work correctly with "type":"module".
Replace the }` heuristic in inject.sh with a brace-depth counter:
start at depth=1 after the opening {, increment on {, decrement on },
stop when depth reaches 0. This correctly handles nested if/else blocks,
loops, and structs that close at 4-space indent inside calculateParams.
Also emit a non-zero exit with a descriptive message if EOF is reached
without finding the matching closing brace.
Add test_inject_extraction.sh covering simple bodies, nested if/else,
multi-level nesting, and the EOF-without-match error case.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dpop/bpop silently returned '0'/'false' on stack underflow instead of
throwing, so isValid() never returned false for underflowing programs.
Make dpop and bpop throw an Error on underflow so the transpiler's
existing try/catch in isValid() correctly classifies such programs as
invalid. The output-extraction phase uses state.dStack.pop() directly
(not dpop) and is unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Null out the stale fitness score (7116531284966772550194) for
evo_run007_champion.push3, which was recorded against the buggy
processExecIf interpreter (pre-#655 fix). Setting fitness to null
marks the entry for re-scoring by evaluate-seeds.sh once a valid
ANVIL_FORK_URL is available. Updated the note field to document why
the fitness was cleared.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
## What
- `tools/push3-transpiler/inject.sh` — shared transpile+inject logic used by both batch-eval and red-team-sweep
- `batch-eval.sh` — replaced inline 60-line Python block with `inject.sh` call
- `scripts/harb-evaluator/red-team-sweep.sh` — red-teams each kindergarten seed using existing `red-team.sh`, with random smoke test gate
## Why
Sweep script kept breaking because I rewrote the injection logic instead of reusing batch-eval's proven Python. Now there's one copy.
## Testing
- inject.sh tested manually on DO box with optimizer_v3 seed
- Smoke test picks random seed, injects + compiles before starting sweep
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/harb/pulls/806
Reviewed-by: review_bot <review_bot@noreply.codeberg.org>
- Change WARNING to explicitly state "legacy CID format ... migration not supported, skipping"
- Expand comment near the startswith('candidate_') guard to document the CID format
contract and explain why re-admission is intentionally out of scope (no surviving
generation_N.jsonl files from runs 1-6 exist in the repo)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Pass seed basename into the admission Python block as argv[7]
- Add \`note\` field to every new evolved entry: "Evolved from <seed> (run<N> gen<G>)"
- Add migration comment noting entries admitted before this fix may have note: null
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace unquoted heredoc (shell-injection path) with a temp file: the
shell loop now appends tab-separated filename/score lines to a temp
file, which is passed as a plain path argument to the Python manifest-
rewrite block. Python reads only file contents, never executes shell-
expanded strings.
- Add early abort on fitness.sh exit code 2 (infra error: Anvil down,
missing tool). Iterating past an infra failure produces no useful
results; aborting immediately surfaces the real problem.
- Remove unused `os` import from the manifest-rewrite Python block.
- Fix inaccurate comment in evolve.sh --diverse-seeds sampling: the pool
sampler does a flat random shuffle with no fitness weighting; null-
fitness seeds are not "treated as 0" — they are sampled with equal
probability to any other seed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add evaluate-seeds.sh: standalone script that reads manifest.jsonl,
finds every entry with fitness: null, runs fitness.sh against each
seed file, and atomically writes results back to manifest.jsonl.
Supports --dry-run to preview without evaluating.
- Add comment to --diverse-seeds sampling in evolve.sh documenting that
null-fitness seeds are included with effective_fitness=0 and that
evaluate-seeds.sh should be run to score them.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Define ZERO_RATED_FLAGS set near effective_fitness and check each flag
with any(...in flags...) instead of a single hard-coded substring test.
token_value_inflation behaviour is preserved; new flags can be added to
the set without touching the dispatch logic.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace AW=250 (VERY AGGRESSIVE) with 100 and AW=150 (AGGRESSIVE) with 80
so neither value is silently clamped by LiquidityManager.MAX_ANCHOR_WIDTH=100.
Update header comment block to match the corrected values.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Stream evolve.sh output directly to stderr instead of buffering in a
command substitution; long runs (tens of minutes) are now visible live.
- Use an array (EVOLVE_ARGS) for evolve.sh arguments instead of an
unquoted DIVERSE_FLAG string variable.
- Abort the current run (continue to next loop iteration) when the patch
fails to apply, rather than silently running with wrong evaluation semantics.
- Fix notify() to pass the message via stdin to avoid SSH single-quote
interpolation breakage on messages containing special characters.
- Fix step comment/counter mismatch: "Step 7" comment now reads "Step 6"
to match the [6/7] log label for the summary-write step.
- Clarify in evolution.conf that GAS_LIMIT and ANCHOR_WIDTH_UNBOUNDED are
documentation-only (they document what evolution.patch does); editing
them has no runtime effect.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace `mktemp -d` with a fixed working directory `evolved/.work/` that
is wiped at startup. Stale `/tmp/tmp.*` directories from killed runs can
no longer interfere with batch-eval.sh path resolution. Run outputs are
already preserved in `evolved/run_NNN/` before the work dir is cleaned.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
evo_run007_champion: fitness 7.117e21, anchorWidth=153 (unbounded),
discoveryDepth=0. Simplified to single percentageStaked>88% threshold.
Evolved under IL crystallization attack pressure.
Recovered from reflog after rebase accident destroyed PRs #692, #699.
Balanced Adaptive (#688) was garbage collected — will be regenerated.
Kindergarten (#683) needs fresh implementation due to evolve.sh conflicts.
Closes#672, #675.
- Fix run_NNN scan regex: r'run(\d+)' → r'run_(\d+)' so it correctly
matches the underscore-separated directory names the script creates
(previously always resolved to 001, overwriting the same dir each run)
- Remove [in-progress] tag from STATE.md entry for #752
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- --output now accepts a base dir (default: evolved/) instead of requiring
an explicit path each run
- On each invocation, scan base dir for existing run_NNN/ subdirectories,
find the highest N, and create run_(N+1)/ for this run's outputs
- All generation JSONL files, best.push3, diff.txt, and evolution.log are
written to the new run dir — previous runs are never overwritten
- Log header now shows both Base dir and Output (run dir) for clarity
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add fitness_flags="token_value_inflation" to evo_run004_champion in
manifest.jsonl so callers can detect the inflated value without
discarding the entry entirely.
- Add effective_fitness() helper in evolve.sh pool admission (step 5)
that returns 0 for any entry with a token_value_inflation flag,
preventing inflated scores from biasing the top-100 evolved pool
ranking or eviction decisions.
- Document in evolve.sh that raw fitness values are only comparable
within the same evaluation run.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes#667
## Changes
## Summary
Implemented persistent top-100 candidate pool in `tools/push3-evolution/evolve.sh`:
### Changes
**`--run-id <N>` flag** (line 96)
- Optional integer; auto-increments from highest `run` field in `manifest.jsonl` when omitted
- Zero-padded to 3 digits (`001`, `002`, …)
**Seeds pool constants** (after path canonicalization)
- `SEEDS_DIR` → `$SCRIPT_DIR/seeds/`
- `POOL_MANIFEST` → `seeds/manifest.jsonl`
- `ADMISSION_THRESHOLD` → `6000000000000000000000` (6e21 wei)
**`--diverse-seeds` mode** now has two paths:
1. **Pool mode** (pool non-empty): random-shuffles the pool and takes up to `POPULATION` candidates — real evolved diversity, not parametric clones
2. **Fallback** (pool empty): original `seed-gen-cli` parametric variant behavior
- Both paths fall back to mutating `--seed` to fill any shortfall
**Step 5 — End-of-run admission** (after the diff step):
1. Scans all `generation_*.jsonl` in `OUTPUT_DIR` for candidates with `fitness ≥ 6e21`
2. Maps `candidate_id` (e.g. `gen2_c005`) back to `.push3` files in `WORK_DIR` (still exists since cleanup fires on EXIT)
3. Deduplicates by SHA-256 content hash against existing pool
4. Names new files `run{RUN_ID}_gen{N}_c{MMM}.push3`
5. Merges with existing pool, sorts by fitness descending, keeps top 100
6. Copies admitted files to `seeds/`, removes evicted evolved files (never hand-written), rewrites `manifest.jsonl`
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/harb/pulls/683
Reviewed-by: review_bot <review_bot@noreply.codeberg.org>