Commit graph

1212 commits

Author SHA1 Message Date
johba
7fd1963480 fix: remove project .claude/settings.json — use global config (#1089)
## Problem

The project-level `.claude/settings.json` overrides the global `skipDangerousModePermissionPrompt` flag, causing Claude Code to show an interactive bypass-permissions confirmation dialog in worktrees. This blocks ALL non-interactive agent sessions on evolution.

## Root cause

Claude Code resolves settings per-project. When a `.claude/settings.json` exists in the repo, it takes precedence over `~/.claude/settings.json`. The harb repo has one (with supervisor hooks) but without `skipDangerousModePermissionPrompt: true`. Result: every agent tmux session shows a confirmation prompt and dies.

## Fix

Delete `.claude/settings.json` and `.claude/hooks/supervisor/` entirely:
- The supervisor hooks are legacy from claude-code-supervisor
- agent-session.sh injects its own hooks per worktree at runtime
- Disinto has no project-level `.claude/` and works fine
- Global `~/.claude/settings.json` has the correct flags

## Impact

**This unblocks all harb agents on evolution.** Currently zero PRs can be processed.

Reviewed-on: https://codeberg.org/johba/harb/pulls/1089
2026-03-21 20:23:46 +01:00
johba
46e928ea97 fix: Red-team schema should add candidate_commit field (#1066) (#1075)
Fixes #1066

## Changes
Done. Here's what was changed:

**`evidence/README.md`**
- Added `"candidate_commit": "abc1234"` to the red-team schema JSON example
- Added `candidate_commit | string | Git commit SHA of the optimizer under test` row to the field table

**`scripts/harb-evaluator/red-team.sh`**
- Captures `CANDIDATE_COMMIT` from `git rev-parse HEAD` at startup (alongside existing `CANDIDATE_NAME`/`OPTIMIZER_PROFILE`)
- Added a new step (9a-pre) that writes `evidence/red-team/YYYY-MM-DD.json` at the end of each run, including `candidate_commit` plus all other schema fields (`candidate`, `optimizer_profile`, `lm_eth_before`, `lm_eth_after`, `eth_extracted`, `floor_held`, `verdict`, `attacks`)

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/harb/pulls/1075
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-21 13:47:13 +01:00
johba
636ba989ee fix: Optimizer and OptimizerV3 lack _disableInitializers() in constructor (#1055) (#1080)
Fixes #1055

## Changes
That notification is for the earlier background task which already completed — I retrieved its output and used it to diagnose and fix the failing test. The work is done.

Reviewed-on: https://codeberg.org/johba/harb/pulls/1080
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-21 13:42:54 +01:00
johba
5e8d603ebd Merge pull request 'evidence: first red-team baseline — floor held' (#1065) from evidence/red-team-2026-03-20 into master 2026-03-21 07:48:26 +01:00
johba
fd80aec3be evidence: fix nits — strategies count, percentage calculation
- strategies_tested=7 (independent measurements only), strategies_total=9
- Fix attack 4 percentage: 374/2050 ≈ 18%, not 37%

Re: #1058

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 06:45:40 +00:00
johba
443593e66f evidence: fix review round 2 — slippage explanation, methodology note
Addresses re-review feedback:

1. Attack 4 (2050 ETH): delta_bps=3746 is from extreme slippage
   through thin liquidity beyond concentrated positions, not just
   1% fees. Insight corrected to explain the slippage mechanism.
2. Floor Ratchet: renamed to "initial phase only", insight explicitly
   notes the 2000-trade oscillation variant is NOT tested here and
   is tracked as follow-up issue #1082.
3. Added methodology field explaining snapshot-isolation semantics
   (why lm_eth_after == lm_eth_before).
4. Restored two dropped strategies (discovery WETH consumption,
   one-way sell) with notes that they are subsumed by other attacks.

Re: #1058

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 06:43:45 +00:00
johba
b883cde275 evidence: fix red-team baseline — accurate per-attack measurements
Addresses REQUEST_CHANGES review on PR #1065:

1. candidate: "Optimizer" (matches DeployLocal.sol deployment)
2. optimizer_profile: "default" (not push3-default — base Optimizer)
3. candidate_commit: master HEAD SHA for reproducibility
4. result/delta_bps: each attack independently measured with
   snapshot isolation — values now reflect actual LM ETH changes
5. Floor Ratchet attack tested: INCREASED +1179 bps. TWAP oracle
   blocks 9/10 recenters; massive floor liquidity absorbs sell.
6. lm_eth values as strings to avoid JS safe-integer truncation
7. lm_eth_before = lm_eth_after (attacks reverted between tests)

Re: #1058

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 06:31:33 +00:00
johba
abaeb9949d evidence: first red-team baseline — floor held, 8 strategies tested
All 8 adversarial strategies failed to extract ETH from LiquidityManager.
LM ETH actually increased from ~1000 to ~1050 ETH due to fee income.
Key defense: 1% pool fee + atomic recenter + massive floor liquidity.

Closes #1058

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 06:30:59 +00:00
johba
a1efa5942d Merge pull request 'fix: deploy-optimizer.sh reads LM_ADDR inside a guard that silently skips on missing broadcast JSON (#1051)' (#1081) from fix/issue-1051 into master 2026-03-21 03:47:02 +01:00
johba
daf0bac7d4 fix: deploy-optimizer.sh reads LM_ADDR inside a guard that silently skips on missing broadcast JSON (#1051) 2026-03-21 01:37:11 +00:00
johba
82ce7c3957 fix: deploy-optimizer.sh reads LM_ADDR inside a guard that silently skips on missing broadcast JSON (#1051)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 01:37:06 +00:00
johba
4f6b6cf586 Merge pull request 'fix: OptimizerV3Push3 as IOptimizer always returns bear defaults — integration risk (#1063)' (#1076) from fix/issue-1063 into master 2026-03-20 22:37:34 +01:00
johba
62fc7957b0 fix: OptimizerV3Push3 as IOptimizer always returns bear defaults — integration risk (#1063)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 20:52:29 +00:00
johba
45142e762a fix: OptimizerV3Push3 as IOptimizer always returns bear defaults — integration risk (#1063) 2026-03-20 20:14:19 +00:00
johba
6f7b6c4254 fix: OptimizerV3Push3 as IOptimizer always returns bear defaults — integration risk (#1063)
- getLiquidityParams() now reverts with "OptimizerV3Push3: not for production use" instead
  of silently returning zeroed bear-mode defaults; LiquidityManager.recenter() already has
  a try/catch fallback so backtesting is unaffected
- Added @custom:experimental NatSpec annotation to the contract marking it as a transpiler
  harness / backtesting stub only
- DeployBase.sol now validates any pre-existing optimizer address by calling getLiquidityParams()
  and reverting if it fails, blocking accidental wiring of OptimizerV3Push3 as a live optimizer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 20:13:18 +00:00
johba
351d4813e6 Merge pull request 'fix: Adoption milestone state ambiguity in MEMORY.md (#1068)' (#1073) from fix/issue-1068 into master 2026-03-20 20:40:08 +01:00
openhands
9327c0b5de fix: use 'disinto init' label for #1060 to match journal source
Review flagged inconsistency: line 8 said 'bootstrap init' while the
journal (2026-03-20.md:13) and Strategic direction (line 26) both use
'disinto init'.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:17:00 +00:00
johba
9feac90394 fix: Adoption milestone state ambiguity in MEMORY.md (#1068) 2026-03-20 19:07:07 +00:00
johba
98ca99d5eb fix: Adoption milestone state ambiguity in MEMORY.md (#1068) 2026-03-20 19:07:02 +00:00
johba
810f47cdd6 chore: planner run journal 2026-03-20 (#1064)
Planner journal entry from first cron-driven run.

Moved from disinto PR #390 — planner journals belong in the harb repo.

Reviewed-on: https://codeberg.org/johba/harb/pulls/1064
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-20 16:25:57 +01:00
johba
8583ec9119 Merge pull request 'fix: OptimizerV3Push3 — deeply-nested if-else vs flat if-else chain in OptimizerV3 (#599)' (#1057) from fix/issue-599 into master 2026-03-20 15:48:15 +01:00
openhands
05753054b9 fix: OptimizerV3Push3 — deeply-nested if-else vs flat if-else chain in OptimizerV3 (#599)
Extract transpiler output into OptimizerV3Push3Lib so both OptimizerV3
and OptimizerV3Push3 delegate to the same canonical copy.  Future
transpiler changes now require only one edit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:18:12 +00:00
johba
37f60850aa Merge pull request 'fix: fix: parallelize ci.yml steps with depends_on (#1052)' (#1056) from fix/issue-1052 into master 2026-03-20 14:54:53 +01:00
openhands
30cdd95ba0 fix: address review — fix race condition and dependency graph
- contracts-local-fork and node-quality now depend on foundry-suite
  (not just bootstrap-deps) to avoid concurrent writes to onchain/out/
  and onchain/cache/ from parallel forge invocations
- Remove duplicate forge build from node-quality (artifacts already
  exist from foundry-suite)
- evolution-tests changed to depends_on: [] — it only runs npm install
  in tools/ dirs, no submodule dependency
- Remove vestigial PATH=/root/.foundry/bin export from transpiler-tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:27:04 +00:00
openhands
d69310e5ff fix: node-quality needs forge build for kraiken-lib ABI imports
kraiken-lib/src/abis.ts imports from onchain/out/ which requires
forge build. Previously produced by the sequential foundry-suite step;
now that steps run in parallel, node-quality must build contracts itself.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:55:10 +00:00
openhands
82f1548856 fix: parallelize ci.yml steps with depends_on (#1052)
Add depends_on declarations so independent CI steps run in parallel.
Steps needing submodules (foundry-suite, contracts-local-fork,
evolution-tests, node-quality) wait for bootstrap-deps; lightweight
checks (single-package-manager, validate-evolution-patch,
optimizer-not-mutated, transpiler-tests) start immediately.

Critical path: bootstrap-deps (50s) + max(node-quality 400s) ≈ 450s
(was ~630s sequential).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:47:58 +00:00
johba
86e258f6e1 Merge pull request 'fix: Shift field silently ignored — dyadic rational inputs effectively unsupported (#606)' (#1053) from fix/issue-606 into master 2026-03-20 13:35:32 +01:00
openhands
abbf14854d fix: address review — add negative-mantissa guard to OptimizerV3, add OptimizerV3 test file
- Add require(mantissa >= 0) to OptimizerV3.calculateParams validation loop
  (was missing unlike Optimizer and OptimizerV3Push3)
- Create onchain/test/OptimizerV3.t.sol with shift, negative-mantissa, and
  basic bear/bull output tests
- Fix stale comment in Optimizer.sol: "shift=0 assumed" → "shift=0 enforced"
- Use implementation-neutral NatSpec phrasing in IOptimizer.sol

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:10:03 +00:00
openhands
42b4bf4149 fix: Shift field silently ignored — dyadic rational inputs effectively unsupported (#606)
Add require(shift == 0) guards to Optimizer.calculateParams and
OptimizerV3.calculateParams so non-zero shifts revert instead of being
silently discarded.  OptimizerV3Push3 already had this guard.

Update IOptimizer.sol NatSpec to document that shift is reserved for
future use and must be 0 in all current implementations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 11:42:50 +00:00
johba
26957dae88 Merge pull request 'fix: deployments-local.json committed to repo (#589)' (#1049) from fix/issue-589 into master 2026-03-20 12:26:04 +01:00
openhands
cee79eedb3 fix: web-app config.ts fails when deployments-local.json is absent
Use brace expansion in import.meta.glob pattern so Vite treats it as a
dynamic glob (returns {} when no files match) instead of compiling it
to a static import that errors when the gitignored file is absent in CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:45:13 +00:00
openhands
282ac72c14 fix: handle missing deployments-local.json in CI/production
Use import.meta.glob with eager loading instead of a static import so
config.ts degrades gracefully when the file is absent (gitignored).

Fixes the node-quality CI failure introduced when the file was removed
from the repo in this PR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 10:34:41 +00:00
openhands
de8cf65d06 fix: push3-evolution tsconfig rootDir too narrow for cross-project imports
Widen rootDir from "." to ".." and include push3-transpiler sources so
tsc can resolve the ../push3-transpiler/src imports that mutate.ts and
test files use.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:54:33 +00:00
openhands
79a2e2ee5e fix: deployments-local.json committed to repo (#589)
- Add onchain/deployments-local.json to .gitignore so it is no longer tracked
- Remove the stale committed file from git
- Update fitness.sh to read LM address from forge broadcast JSON
  (DeployLocal.sol's run-latest.json) instead of the potentially stale
  deployments-local.json, matching the approach deploy-optimizer.sh already uses

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:48:00 +00:00
johba
4c27351b27 Merge pull request 'fix: No --fork-url in deploy-optimizer.sh local Anvil start (#588)' (#1045) from fix/issue-588 into master 2026-03-20 10:05:48 +01:00
openhands
f361be30d2 fix: No --fork-url in deploy-optimizer.sh local Anvil start (#588)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 08:47:28 +00:00
johba
a0effe39d6 Merge pull request 'fix: No CI pipeline coverage for push3-evolution or push3-transpiler tests (#563)' (#1043) from fix/issue-563 into master 2026-03-20 09:36:02 +01:00
openhands
1f96e62fc8 fix: No CI pipeline coverage for push3-evolution or push3-transpiler tests (#563)
Add evolution-tests step to Woodpecker CI pipeline. The transpiler-tests
step already existed; the new step runs push3-evolution's vitest suite
and triggers on changes to either tools/push3-evolution or
tools/push3-transpiler (since evolution imports the transpiler's parser).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 07:57:46 +00:00
johba
0cb2e7ba07 fix: EXEC.IF branch reconciliation still injects synthetic zeros (#618) (#1033)
Fixes #618

## Changes
Add stack depth validation in processExecIf() so asymmetric EXEC.IF branches (where one branch pushes more values than the other) throw an explicit error instead of silently padding with '0'. Error messages identify both branch depths for DYADIC and BOOLEAN stacks. Removed dead-code '0'/'false' fallbacks in buildAssignments and reconstruction. Updated existing unbalanced-branch tests to expect errors; added regression tests for error message content and BOOLEAN mismatch. All existing seed files (optimizer_v3.push3, optimizer_seed.push3) continue to transpile.

Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/harb/pulls/1033
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-20 08:42:34 +01:00
johba
30abee68b8 Merge pull request 'fix: No tests for transpiler stack-depth validation (#619)' (#1032) from fix/issue-619 into master 2026-03-20 04:59:52 +01:00
openhands
793d875b4a fix: No tests for transpiler stack-depth validation (#619)
Add TypeScript unit test suite for the Push3 transpiler using Node's
built-in test runner (node:test) with tsx. 47 tests across 12 suites
covering parser, stack underflow/overflow, EXEC.IF balanced/unbalanced/
nested branching, arithmetic, boolean ops, name binding, and integration.

Update CI to run `npm test` (which now includes unit tests + existing
bash tests) and scope transpiler-tests step to only trigger on changes
to tools/push3-transpiler/**.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 03:29:45 +00:00
johba
df3389bdeb Merge pull request 'fix: getLiquidityParams: int256 overflow on large VWAP values (#622)' (#1030) from fix/issue-622 into master 2026-03-20 04:15:39 +01:00
openhands
e28e69c98a fix: guard int128 overflow in ThreePositionStrategy mirror tick (#622)
Move overflow guard to the actual vulnerable site:
ThreePositionStrategy._computeFloorTickWithSignal() line 262 where
vwapX96 >> 32 is cast to int128 for _tickAtPriceRatio. Values
exceeding int128.max now skip mirror tick (fallback to scarcity/clamp)
instead of reverting.

Remove incorrect require from Optimizer._buildInputs() which guarded
a non-existent int256 cast path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 02:46:30 +00:00
openhands
7007e593da fix: getLiquidityParams: int256 overflow on large VWAP values (#622)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 02:05:25 +00:00
johba
5deb1eab0c Merge pull request 'fix: _scrapePositions: unguarded safeTransfer to address(0) when feeDestination unset (#624)' (#1029) from fix/issue-624 into master 2026-03-20 02:53:02 +01:00
openhands
170cc839e6 fix: _scrapePositions: unguarded safeTransfer to address(0) when feeDestination unset (#624)
Add address(0) guard to fee transfer condition in _scrapePositions so
that when feeDestination is uninitialized, fees accrue as deployable
liquidity instead of reverting on safeTransfer to the zero address.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 01:05:05 +00:00
johba
84fae1a410 Merge pull request 'fix: mint_lp and burn_lp not soft-failing in attack execution (#630)' (#1028) from fix/issue-630 into master 2026-03-20 01:46:00 +01:00
openhands
37905a29b2 fix: mint_lp and burn_lp not soft-failing in attack execution (#630)
Wrap mint_lp and burn_lp ops in _executeOp with try/catch to match
the soft-fail pattern used by buy, sell, stake, and unstake. Replace
burn_lp's require() with a soft return for out-of-range index validation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:23:58 +00:00
johba
0446facb62 Merge pull request 'fix: No recovery path if VWAP bootstrap fails mid-sequence (#644)' (#1026) from fix/issue-644 into master 2026-03-20 01:03:57 +01:00
openhands
20f5ac68cd fix: add polling timeouts and safe fallback in recovery script (#644)
- Add max-iterations guard (60 polls × 5s = 5 min) to both cooldown
  polling loops with explicit error on timeout
- Use LAST_RECENTER (already validated) as fallback instead of "0" for
  post-seed-buy lastRecenterTime read, preventing silent cooldown skip
  on transient RPC failure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:45:31 +00:00