Persist manual tuning findings

This commit is contained in:
Meta Vens 2026-04-28 17:25:22 +01:00
commit 2c656908e9
4 changed files with 90 additions and 5 deletions

View file

@ -132,3 +132,17 @@ After compaction, first rehydrate and reorient from the listed files and git
state. Do not continue implementation merely because the state names a next
move. Wait for the user's next instruction unless they explicitly say to
continue.
## Active Manual Tuning State
Manual tuning is in progress; see `state/scratch.md` for the full score ledger. Do not jump straight to editing `config/solver_params.json`.
Current evidence:
- Full validation, 38 cases x soft/crisp/ai, seed 23, steps 48: baseline score `0.7702`; `radius=0.60, blend=0.07` score `0.5790`, mean `0.2814`, worst `1.2734`, improved `97/114` rows.
- Regression guard on known bad rows says tighter radius may be safer: `radius=0.50, blend=0.07` scored `0.4075` with worst `0.6949` on the guard set, beating `radius=0.60, blend=0.07` at `0.6278` / worst `1.3589`.
Immediate re-entry for tuning:
- full-validate `radius=0.50, blend=0.07`
- full-validate `radius=0.55, blend=0.05`
- compare against the existing full-validation `radius=0.60, blend=0.07` results in `artifacts/tuning-validation-01`
- only then update `config/solver_params.json`

View file

@ -14,3 +14,6 @@
{"ts": "2026-04-26T22:40:02+00:00", "type": "design", "status": "accepted", "note": "Hosted mode now owns a distinct public front door in src/repixelizer/gui.py: / serves a landing page there, while local and self-host runs still redirect root straight to /app/. This keeps future auth and member-gating surgery in the hosted web layer instead of smearing it into the self-deploy path or the solver stack."}
{"ts": "2026-04-26T22:57:43+00:00", "type": "design", "status": "accepted", "note": "Repixelizer is now auth-ready at the hosted web boundary without landing real Heimdall auth. src/repixelizer/access.py owns the local access seam, src/repixelizer/gui.py binds request subjects and guards hosted routes, queued jobs now carry local owner metadata, and self-host remains permissive by default unless GC_ACCESS_* turns the seam on."}
{"ts": "2026-04-26T23:34:24+00:00", "type": "design", "status": "accepted", "note": "Repixelizer now consumes Heimdall entirely inside the hosted web layer. GC_ACCESS_MODE=heimdall creates local auth attempts, asks Heimdall to start provider OAuth, accepts the direct backend callback, verifies Heimdall Ed25519 access tokens locally, and adopts httpOnly cookie sessions without dragging provider tokens through browser URLs or solver code."}
{"ts": "2026-04-28T16:23:58+00:00", "type": "benchmark", "status": "ok", "note": "Manual tuning found the first robust improvement is reducing explicit solver local search movement, not increasing signal. On the 8-case soft+ai slice, baseline scored 0.6014; radius=0.60/blend=0.10 scored 0.2804; radius=0.60/blend=0.07 scored 0.2687. Stronger signal worsened the slice, and higher spring weight above 4.0 had no effect because the spring step is already clamped."}
{"ts": "2026-04-28T16:23:58+00:00", "type": "benchmark", "status": "ok", "note": "Full validation across 38 cases x soft/crisp/ai at seed 23 favored radius=0.60/blend=0.07 over baseline: score 0.5790 vs 0.7702, mean row score 0.2814 vs 0.4552, worst row 1.2734 vs 1.5050; 97/114 rows improved, 14 regressed."}
{"ts": "2026-04-28T16:23:59+00:00", "type": "benchmark", "status": "pending", "note": "Regression-guard validation on known bad rows found tighter radius may be better before shipping: r050-b007 scored 0.4075 with worst 0.6949 on the guard set, beating r060-b007 at 0.6278/worst 1.3589. Full-corpus validation is still required before updating config/solver_params.json."}

View file

@ -96,4 +96,4 @@ rejected_paths:
current_status:
summary: The repo has one live reconstruction engine, `phase-field`, wired through the main pipeline with lattice inference, edge analysis, projected displacement optimization, cleanup, optional palette fitting, diagnostics, compare mode, tuning, and GUI observer events. The searched lattice path now trusts autocorrelation only; it keeps a tiny near-best lag plateau and uses cross-axis consensus before collapsing to one lattice family. The hosted demo path now skips multi-size lattice search and candidate rerank entirely, taking one direct autocorr-consensus size and respecting the hosted output cap instead of silently pinning unspecified jobs to that cap. Hosted web access is now auth-landed without smearing into the solver: `src/repixelizer/access.py` verifies Heimdall Ed25519 access tokens locally, tracks auth attempts, and adopts local cookie sessions, while `src/repixelizer/gui.py` owns provider-start routes, direct backend callback receipt, the hosted landing-page login buttons, route guards, and queue/job ownership checks. Self-host remains permissive by default unless `GC_ACCESS_*` turns the seam on. The spectral prior experiment was removed after it floor-hugged to 2px / 626-family aliases on the dense landscape fixture, and the old change-interval / pixel-walk sizing path was cut after it kept pruning the badge away from the `126` family. The solver now has a wider displacement budget so moderate starting-grid error can be recovered by the field instead of requiring as much candidate-rerank ceremony. `source_structure` now rides alongside `source_fidelity` because lattice-only scoring was lying about visible quality. The tracked weakness is still the widened dark contour near the badge sword tip on tapered shapes.
next_action: After rehydrate, if the user wants more hosted auth work, keep it inside `src/repixelizer/access.py` and `src/repixelizer/gui.py` with bounded polish such as provider expansion, session UX, or persistence hardening. Otherwise resume one bounded solver hypothesis for along-stroke versus across-stroke behavior in `src/repixelizer/phase_field.py` against the pinned badge case and `tests/fixtures/real/ai-badge-tip-focus.json`, and revert immediately if the visual result or `source_structure` does not clearly improve.
next_action: Resume manual tuning from `state/scratch.md`. Do not edit `config/solver_params.json` yet. Full-corpus validation picked `phase_field_local_search_radius_ratio=0.60` and `phase_field_local_search_blend=0.07`, but the regression guard found `0.50/0.07` and `0.55/0.05` may reduce known crisp-case regressions. Next run should full-validate those tighter/slower candidates against baseline before shipping params.

View file

@ -1,7 +1,75 @@
# Scratch
This file is disposable working memory for the current bounded subgoal.
# Scratch: manual solver tuning in progress
## Current Subgoal
Manual solver tuning is in progress; full-validate tighter/slower local search candidates before shipping params.
No active scratch subgoal.
## Current bounded subgoal
Find a shippable `config/solver_params.json` update for the simplified explicit phase-field solver. Do not resume random tuner blindly. Continue deliberate parameter nudging with benchmark evidence.
## Baseline
Current committed config before tuning:
- `phase_field_local_search_radius_ratio`: `0.80`
- `phase_field_local_search_blend`: `0.18`
- `phase_field_signal_weight`: `0.25`
- `phase_field_local_search_grid_weight`: `0.0`
## Timing / benchmark setup
Manual batches use `run_roundtrip_benchmark(...)`, CPU, `steps=48`, `variants=1`, usually pinned ground-truth size (`infer_size=False`).
Progress/log artifacts are under `artifacts/manual-tuning-*`, `artifacts/tuning-validation-01`, and `artifacts/tuning-regression-guard-01`.
## Key findings so far
1. Blindly increasing signal made results worse.
- `more-signal`: score `0.7339` vs baseline `0.6014` on 8-case soft+ai slice.
- `signal-and-spring`: score `0.7090`.
- Stronger attraction causes feature crowding / artifacts; do not chase bigger signal.
2. Increasing spring weight above current `4.0` did nothing on the slice.
- `more-spring`: exactly same score as baseline.
- Reason found in source: `_relax_lattice_springs_np` clamps spring step at `0.22`, and current `4.0` is already above the clamp threshold.
3. Smaller local search radius is the first real improvement.
- 8-case soft+ai slice baseline: score `0.6014`, mean `0.3570`, worst `1.1717`.
- `radius=0.60`: score `0.3746`, mean `0.2104`, worst `0.7575`.
- Biggest wins were soft enemy cases that baseline lost to naive.
4. Slower local search blend improves further.
- `radius=0.60, blend=0.10`: score `0.2804`, mean `0.1643`, worst `0.5513` on same slice.
- Blend bracket showed `0.06`, `0.07`, `0.08` are basically a plateau.
- Best small-slice objective: `radius=0.60, blend=0.07`, score `0.2687356`, mean `0.1616738`, worst `0.5185465`.
- `radius=0.60, blend=0.08` is almost tied: score `0.2687747`.
5. Full-corpus validation across all 38 cases x soft/crisp/ai chose `radius=0.60, blend=0.07` over baseline and `blend=0.08`.
- Baseline: score `0.7701765`, mean `0.4552439`, worst `1.5050192`.
- `r060-b007`: score `0.5790363`, mean `0.2814493`, worst `1.2734060`.
- `r060-b008`: score `0.5938681`, mean `0.2864235`, worst `1.3112390`.
- `r060-b007` improved 97 / 114 rows, regressed 14 / 114, tied 3 / 114.
- Mean deltas by profile: ai `-0.1981`, crisp `-0.1836`, soft `-0.1396`.
6. Known regression guard says `radius=0.60` still hurts specific crisp cases, especially `disciple` crisp.
Full validation worst regression for `r060-b007`:
- `disciple` crisp: row score `0.6688 -> 1.2734`, delta `+0.6046`.
Other notable regressions:
- `dagrons5-08` crisp: `1.1013 -> 1.2413`, delta `+0.1400`.
- `dagrons5-10` ai: `0.8494 -> 0.9664`, delta `+0.1170`.
7. Regression-guard batch on the known bad cases prefers tighter radius.
Cases: `disciple`, `dagrons5-08`, `dagrons5-10`, `dagrons5-11`, `9rpgenemies-02`, `9rpgenemies-06`, `minion`, `more-rpg-enemies-06`; profiles soft/crisp/ai; seed 23.
- Guard baseline: score `0.8112430`, mean `0.5648541`, worst `1.3861505`.
- `r060-b007`: score `0.6277928`, mean `0.3144768`, worst `1.3588636`.
- `r055-b007`: score `0.5313045`, mean `0.3039784`, worst `1.0617322`.
- `r050-b007`: score `0.4075140`, mean `0.2843421`, worst `0.6949151`.
- `r055-b005`: score `0.4298573`, mean `0.2982637`, worst `0.7369090`.
- `r060-b007-grid004`: score `0.6339122`, mean `0.3133518`, worst `1.3818866`.
This means `r050-b007` or `r055-b005` need full-corpus validation before shipping. `r060-b007` is no longer automatically safe despite winning full validation, because the guard set exposes known bruises.
## Recommended next action after compaction
Run full-corpus validation for:
- baseline
- `radius=0.60, blend=0.07` if not already using existing results for comparison
- `radius=0.50, blend=0.07`
- `radius=0.55, blend=0.05`
- optionally `radius=0.55, blend=0.07`
Use all 38 cases, profiles `soft/crisp/ai`, seed `23`, steps `48`, CPU, pinned size. If `r050-b007` generalizes, it is the leading ship candidate. If it overfits the guard set, compare `r055-b005` and `r060-b007` on mean/worst/regression count.
Do not edit `config/solver_params.json` yet. The current best full-corpus validated params are `r060-b007`, but the regression guard has created a better hypothesis that still needs full validation.