repixelizer/state/map.yaml
2026-06-16 18:19:23 +01:00

137 lines
11 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/spritesheet.py` owns spritesheet region identity, explicit grid slicing, shared texel density sizing, optional individual sprite export, and output packing; each detected crop still runs through the canonical `run_pipeline_rgba` solver path.
- `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.
- In Heimdall mode, Repixelizer keeps a separate httpOnly refresh cookie and asks Heimdall to reissue a short-lived access claim before forcing the user back through provider OAuth.
- `src/repixelizer/witness.py` owns the read-only first-cut Odin provider advertisement export. It names Repixelizer job, queue, event, runtime, and auth witness schemas plus the reserved `state/repixelizer.witness.cc` path, but it does not own queue truth or write CultCache.
- `src/repixelizer/eve_surface.py` owns the read-only Eve surface projection for Repixelizer's front page, single-page workflow, runtime/auth/queue status, retro style tokens, command descriptors, and Periwinkle lowering comparison; `/eve/surface` serves the live projection from `gui.py` without owning queue truth.
- 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.
- Spritesheet CLI mode detects separated foreground regions or selects the largest requested sprite count, then repixelizes each crop independently through `phase-field`.
- `source_structure` reporting alongside `source_fidelity`.
- Hosted landing page and Heimdall auth seam in the web layer.
- Read-only `gamecult.eve.provider_advertisement.v1` fixture/export for Odin discovery and future CultCache/Eve witness work.
- Read-only `gamecult.eve.surface.v1` fixture/export plus hosted `/eve/surface` projection, preserving Repixelizer's retro CSS identity as Eve style tokens and documenting Android/Periwinkle style-control parity gaps.
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, spritesheet
CLI 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, adopts local cookie sessions, and refreshes
expired/missing access cookies through Heimdall's signed session-refresh
endpoint before falling back to provider OAuth, 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. `src/repixelizer/witness.py` now emits a read-only
`gamecult.eve.provider_advertisement.v1` export and checked-in fixture that
names the Repixelizer job/queue/event/runtime/auth witness schemas and
reserved `state/repixelizer.witness.cc` path for Odin/Huginn discovery,
and `src/repixelizer/eve_surface.py` emits a read-only
`gamecult.eve.surface.v1` projection served at `/eve/surface` and checked in
as `docs/fixtures/repixelizer.eve-surface.json`. The Eve surface keeps the
browser app as the lossless retro lowering, publishes Press Start 2P/VT323
and pixel-shell style tokens, routes commands back to existing GUI routes,
and records that Periwinkle's Kotlin renderer can traverse the surface tree
but does not yet honor provider style tokens, pixel fonts, image assets, or
native upload/canvas controls. These exports do not move queue ownership out
of `gui.py`. 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: >
Repixelizer is now the next Idunn transport cut on Yggdrasil. Keep the
current solver config stable, but move daemon truth out of
`repixelizer-gui.service` plus `/api/health` / `/api/config` compatibility
checks by wiring the existing Python CultLib lane
(`E:\Projects\CultLib\packages\cultcache-py`) into the live GUI runtime.
The next implementation pass should add a daemon-owned `.cc` witness export
from `GuiJobManager`, publish Repixelizer daemon health to Idunn over
CultNet/RUDP, publish runtime-owned command-boundary and transport-profile
state, and teach the Yggdrasil deploy lane to ship the CultLib Python
snapshot alongside the app artifact. 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.