fullseye

Session 2026-08-14 — Data-format expansion + Studio UI review

Goal (user, 2026-08-14): grow Fullseye toward an HDevelop/HALCON-class practical environment — concretely (1) handle more data formats, especially 3-D objects a robot (evis/onocollo/hillco) can import and grasp; (2) add more operators that differentiate from HALCON, leaning on Python’s affinity with CNN/RL/ML; (3) review the Studio UI with external AI. Worked autonomously (user at work). All changes local; not pushed (human gate).

What shipped (verified, full suite 2771 passed / 0 failed)

Starting point (audited): Fullseye could import zero object formats; only float64 [0,1] grayscale/RGB survived end-to-end; 16-bit/float/complex/>3-channel were lost; save_ply was write-only; the volume sort had no loader. Four new numpy-native modules close most of that gap, each wired into the api facade + fullseye package.

Honest notes: mesh.voxelize is surface (cells a triangle crosses) and render3d.voxelize_solid is centre-inside on the same grid — different, both-correct criteria, so solid is not a superset of surface (a naive solid ⊇ surface check is wrong). render’s default view is head-on (flat depth); SDF sign needs a watertight mesh; PLY/OBJ custom attributes beyond position/rgb are dropped; 16-bit PNG through imgio.load is still demoted (use raster.read_raster for bit-depth-sensitive reads).

Second wave — grasp / mesh-repair / volume analysis (shipped + verified, full suite 2834 / 0 fail)

Three more zero-dependency numpy modules turn imported geometry/volumes into robot-usable results — all wired into the facade, each independently smoke-verified:

Session total: 7 new numpy-native modules (mesh, volio, raster, render3d, grasp, meshrepair, volops) + the imgio fix + the Studio UI fixes. Full suite 2834 passed / 0 failed, all local, not pushed.

Third wave — complex + hyperspectral modalities (shipped + verified)

Two more data modalities, both HALCON differentiators (verified against the corpus), zero-dep plain modules wired into the facade:

Plus examples/import_and_grasp.py — the evis story end to end (import → sim-ready with exact inertia → grasp → render; verified: box mass 0.28 kg, grasp width = the box’s thin dimension). Session total: 9 new numpy-native modules + the imgio fix + the Studio UI fixes + the capstone example. Full suite 2881 passed / 0 failed, all local, not pushed.

Studio UI review (external AI)

Reviewed studio.py with Codex + Copilot (read-only) plus a visual (offscreen) pass. Verdict after verifying each finding against real code: 13 confirmed, 2 partial, 1 false-positive (the “drag-reorder is race-prone” claim — exercised all 30 single-row moves, 0 mismatches; multi-select is impossible, so not a bug). Fixed the confirmed, non-architectural ones (focus rings, disabled-slider styling, file-I/O error handling, dirty-state + confirm, enabled-state sync, command-palette single-run, shortcut scoping, malformed-pipeline validation, accessibility, knob debounce 8→1 eval, render dedup 2→1), each with a regression test (test_studio.py 30→50). Full report: docs/STUDIO_REVIEW_2026_08_14.md. Deferred (needs user sign-off, architectural): async execution on a QThreadPool (heavy op still freezes the UI), a QAbstractListModel rewrite. Bonus bug filed: imgio.save ignores cv2.imwrite’s False return (a failed save can still flash “saved”).

Differentiation direction — DEFERRED to user (touches the sacred evolution core)

Two design workflows (a 12-phase format roadmap + a 26-item TRIZ CNN/RL/ML differentiation track, both paper-grounded and honesty-filtered) produced a clear identity: Fullseye is a numpy-native perception library that designs its own pipelines, with classical and learned ops interchangeable behind one op interface, one algebra across 2D/3D/hyperspectral/point-cloud/time. The highest-leverage differentiators require Wave-0 changes to the evolution engine, which I did not make autonomously because they alter the north-star (evolution + honest holdout). Verified against real code, for the user to decide:

  1. Op selection is by list index, not name (ops.py:652: cands[int(t*len(cands))]). Registering optional/learned ops changes len(cands) and remaps every genome for that sort — a champion is only reproducible under the same installed backends. Fix = stable op slots + champions pinned by name (pipeline_str already emits names).
  2. Honest gate is a 2-way split (evolve.py: n_train=14, n_holdout=8, holdout = same synthetic generator at seed+10000, read every generation but never selected on). Structurally thin: no calibration split, no locked-once holdout. Fix = 3-way split.
  3. All problems are synthetic — needed Problem.from_pairs + real-frame problem sets before any learned/ML claim is meaningful.

Only after Wave-0 do the learned-op layer (host + descriptor/vector sorts + classify_head closing the documented classification gap + anomaly inspector) and the optional learned perception ops (SAM/RAFT/MiDaS/RTMPose — all permissive; never SuperPoint/SuperGlue = non-commercial) become honest. These are the user’s call.

Next (autonomous, safe = plain numpy modules, evolution core untouched)

Source of truth: memory project_imgevolve / reference_imgevolve_usage / project_imgevolve_goal_knowledge_layer_2026_08_13.