You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Deliver milestone M1 — parity of the NFT tracker decided in ADR-0001: a detection-only NftTracker in packages/nft-tracker that does exactly what the stateless webcam demo does today, plus the .wnft target format (spec) readable by two independent codecs.
M1 adds no new tracking behaviour. Its job is to give every later milestone (M2 patch tracker, M3 IPPE + One Euro, M4 target compiler) a tested baseline to be measured against.
Why this issue exists
Accepted ADRs are not edited (see AGENTS.md, "Design records"), so ADR-0001's action items record the plan at acceptance time. Progress is tracked here instead. The M1 items of the ADR are 4, 5 and 6; item 7 (M2–M4) is out of scope.
Decide Q10 (I-JSON): require the manifest to be I-JSON (RFC 7493), rejecting duplicate keys? Must be settled before 3A, since the TS codec is where duplicates would be detected.
3A — TS codec and fixtures.encode / decode in packages/nft-tracker/src/target/format/, validation order of §6.1, error and warning codes of §6.2, canonical writer of §7.3. Fixtures in fixtures/nft-target/0.1/ (valid/, invalid/, warnings/, noncanonical/) from a committed deterministic generator. Tests of §8.2–§8.4, including truncation and property-based fuzzing.
3B — NftTracker, parity. Move buildLevelIndex / matchPerLevel from examples/js/pinball-shared.mjs into the package (zero-copy per-level views); buildFromImage; detection-only NftTracker; parity test against the static demo pipeline with a seeded RNG; demos import from the package. Can run in parallel with 3A.
3C — Rust codec crates/wnft-format. Written from the spec, not ported from TS; no_std + alloc, no unsafe, no panic on untrusted input. Consumes the 3A fixtures, never generates its own. Adds a Cargo workspace and a Rust CI job. Starts after 3A is merged.
4 — Integration and first real target. End-to-end round-trip test (image → buildFromImage → encode → decode → NftTracker); compile-target script; commit examples/targets/pinball.wnft; static demo can load it. If 3C is merged, a Rust test decodes pinball.wnft too. Needs 3A and 3B.
Goal
Deliver milestone M1 — parity of the NFT tracker decided in ADR-0001: a detection-only
NftTrackerinpackages/nft-trackerthat does exactly what the stateless webcam demo does today, plus the.wnfttarget format (spec) readable by two independent codecs.M1 adds no new tracking behaviour. Its job is to give every later milestone (M2 patch tracker, M3 IPPE + One Euro, M4 target compiler) a tested baseline to be measured against.
Why this issue exists
Accepted ADRs are not edited (see AGENTS.md, "Design records"), so ADR-0001's action items record the plan at acceptance time. Progress is tracked here instead. The M1 items of the ADR are 4, 5 and 6; item 7 (M2–M4) is out of scope.
Checklist
Done
packages/nft-trackerand the in-memory target types; spec 0.1 rev 2 — feat(nft-tracker): scaffold the package and the in-memory target types #21Spec
Implementation
encode/decodeinpackages/nft-tracker/src/target/format/, validation order of §6.1, error and warning codes of §6.2, canonical writer of §7.3. Fixtures infixtures/nft-target/0.1/(valid/,invalid/,warnings/,noncanonical/) from a committed deterministic generator. Tests of §8.2–§8.4, including truncation and property-based fuzzing.NftTracker, parity. MovebuildLevelIndex/matchPerLevelfromexamples/js/pinball-shared.mjsinto the package (zero-copy per-level views);buildFromImage; detection-onlyNftTracker; parity test against the static demo pipeline with a seeded RNG; demos import from the package. Can run in parallel with 3A.crates/wnft-format. Written from the spec, not ported from TS;no_std+alloc, nounsafe, no panic on untrusted input. Consumes the 3A fixtures, never generates its own. Adds a Cargo workspace and a Rust CI job. Starts after 3A is merged.buildFromImage→encode→decode→NftTracker);compile-targetscript; commitexamples/targets/pinball.wnft; static demo can load it. If 3C is merged, a Rust test decodespinball.wnfttoo. Needs 3A and 3B.Measurement
examples/bench-nft.html: per-stage timings (frame acquisition, grey conversion, detect, describe, match, homography, pose), p50 / p95 / max, JSON export; stateless andNftTrackermodes.Contract
cv-backend-specissues listed under "Contract gaps" in ADR-0001, one each:Keypoint.levelis ambiguous across backends)DescriptorKind, different bits")WKNF_multiview)DetectOptions; estimator selector inRansacOptionsposeFromHomographyreturns a single pose)detectis not a pure function of (image, options) — uninitialisedbuffer reads in jsfeatNext's FAST — cv-backend-jsfeatnext: detect is not stateless — FAST corner rows read uninitialised cache memory (off-by-one) #27
Dependencies
Definition of done
NftTrackerin detection-only mode produces the same result as the stateless pipeline on the static demo images, with a seeded RNG.pinball.wnftis produced bycompile-target, and decoded identically by the TS codec and bycrates/wnft-format.