repixelizer/state/map.yaml
2026-04-29 11:43:17 +01:00

107 lines
7.7 KiB
YAML

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.