project: name: Repixelizer status: active phase: hosted_shipping premise: > Recover fake pixel art by inferring a real lattice and moving one explicit source-position field under a simple local flatness signal plus lattice coherence. objective: primary: > Produce true grid-aligned output that preserves silhouette and internal structure better than resize baselines on icons, emblems, logos, and simple sprites. current: > Ship the hosted experiment with the current usable explicit phase-field solver so Repixelizer stops blocking Heimdall and StreamPixels, while preserving clean state for later signal tuning. constraints: - Prefer one chosen ruler, one live position field, one direct signal, and nearest-source final sampling. - Use visible structure and focused fixtures, not just lattice proxy metrics. - Keep compare mode, diagnostics, tuning, and GUI observer surfaces working. - Keep solver changes inside the one-ruler, one-position-field, one-signal model unless the design map changes first. - Treat hosted convenience as the product path; do not prioritize native desktop packaging unless it clearly beats hosted access on revenue, support burden, or strategy. invariants: - The map is canonical and slow-changing. - Scratch is temporary and disposable. - Evidence is durable and distilled; routine activity logs belong in git history, diagnostics, benchmark artifacts, or commit messages. - The live pipeline is `source -> lattice inference -> diagnostic edge preview -> fixed lattice centers -> hierarchical flatness signal -> explicit local search plus lattice relaxation -> nearest source sample -> cleanup -> optional palette fit -> diagnostics`. - `phase-field` is the only live reconstruction engine. - The final image is emitted by nearest-source sampling from final source positions, not by bilinear output sampling. - If a change cannot be explained cleanly against `docs/lean-optimizer-algorithm-map.md`, it should not land. - Failed benchmark or regression fixes should be reverted before the next hypothesis. - Persistent state cruft is the same failure class as code cruft. active_subgoals: - Ship the hosted experiment so Repixelizer unblocks Heimdall and StreamPixels. - Keep the current usable solver config stable unless launch exposes a blocking quality regression. - Keep inference, compare mode, diagnostics, tuning, and GUI observer events working after solver changes. - Preserve `source_structure` as an objective signal alongside lattice fidelity. - Keep Heimdall-backed hosted auth isolated to the web layer so future provider or session work does not contaminate self-host or solver code. accepted_design: - `phase-field` in `src/repixelizer/phase_field.py` is the only live reconstruction engine. - The working pipeline is `source image -> lattice inference -> diagnostic edge preview -> fixed lattice centers -> hierarchical flatness signal -> explicit local search plus lattice relaxation -> nearest source sample -> cleanup -> optional palette fitting -> diagnostics`. - `src/repixelizer/pipeline.py` owns orchestration and candidate rerank selection. - `src/repixelizer/analysis.py` provides the normalized diagnostic edge preview used by observer/GUI/diagnostic paths; it does not steer the solver. - `src/repixelizer/phase_field.py` owns the live source-position field: initialize from fixed centers, choose local preferred positions from a 5x5 candidate window, blend toward them, relax lattice springs, then nearest-sample the source. - Hosted demo inference uses autocorr lattice candidates, capped by the hosted output limit, with low-confidence preview rerank available. - Hosted mode owns the public front door in `src/repixelizer/gui.py`: `/` is a landing page there, while local/self-host runs keep root as a plain redirect to `/app/`. - `src/repixelizer/access.py` owns the hosted access seam: trusted-header ingress still works, `GC_ACCESS_MODE=heimdall` verifies Heimdall Ed25519 access tokens locally, and auth attempts are adopted into local httpOnly cookie sessions. - The solver starts from fixed lattice centers, adds tiny seeded noise, follows a direct hierarchical flatness signal, enforces local lattice coherence through spring relaxation, then rounds to real source pixels for final output. - Cleanup is local and secondary; it does not define the core reconstruction model. - `source_fidelity` and `source_structure` separate lattice agreement from visible structure. - Character glint/symbol cases, artificial focused cases, and the badge fixture remain useful reality checks for later solver tuning. - Keep the algorithm map, forward plan, scratch, and evidence separate. - The open-source distribution story is self-hosting; the paid offer is hosted convenience, not a desktop-app paywall. landed_baseline: - Lattice inference with fixed target dimensions or autocorr target candidates. - Hosted demo inference uses capped autocorr candidates and allows low-confidence preview rerank. - Diagnostic edge preview plus one explicit source-position solver with local search and lattice spring relaxation. - Compare mode, diagnostics writing, tuning, and GUI observer plumbing all working on the phase-field path. - `source_structure` reporting alongside `source_fidelity`. - Hosted landing page and Heimdall auth seam in the web layer. rejected_paths: - name: tray_optimizer_sprawl reason: persistent per-cell trays do not belong in the current one-field solver model - name: lattice_only_metric_selection reason: lattice fidelity alone does not cover visible structure - name: multi_stage_solver_stack reason: sequential solver stages do not match the current one-field model - name: projected_edge_spectrum_prior reason: projected edge-energy spectral sizing was unreliable on the dense landscape fixture - name: lattice_phase reason: the live solver starts from fixed centers and moves the position field directly current_status: summary: > The repo has one live reconstruction engine, `phase-field`, wired through lattice inference, diagnostic edge preview, explicit local-search reconstruction, cleanup, optional palette fitting, diagnostics, compare mode, tuning, and GUI observer events. Automatic lattice inference uses autocorr candidates; low-confidence autocorr candidates can be preview-reranked. Hosted web access is 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, 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 solver is shipping with a usable but not final tuned config: local search radius `0.215`, blend `0.24`, move weight `0.09`, grid alignment `4.75`, signal energy power `1.4`, and signal peak power `3.25`, aligned in `config/solver_params.json` and the docs. Diagnostic edge analysis remains an observer/GUI gauge. The tuning pass proved that wide local-search windows caused neighbor feature poaching and that tighter radius plus stronger blend is the current motion-geometry basin. It did not fully retune signal knobs around that basin. next_action: > Ship the hosted experiment with the current usable solver config so Repixelizer stops blocking Heimdall and StreamPixels. Later tuning should start from `docs/solver-tuning-lessons-2026-04-29.md`: sweep signal knobs around `radius=0.215, blend=0.24` first, then movement/coherence knobs, then combinations, and only then run final full-corpus validation.