From 954246b9692c03225677506c2155606149bd1299 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sun, 20 Sep 2026 20:32:49 +0200 Subject: [PATCH] Register the inference requirements, and format the fill test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two CI gates have failed on every push since 0.13.4 and both are fixed here. The traceability gate rejected `FR-INF-1` as an orphan: settings.slint and dr-ui tag it, but the four register entries inference.md §12 wrote were never carried into requirements.md, which is the only file the extractor reads. §3.12 and §4.10 now hold FR-INF-1..3 and NFR-INF-1 verbatim, with the acceptance milestones pointed back at inference.md. The matrix is regenerated (188 defined, 155 covered) and the README's "where it stands" line, which the 0.13.6 release commit skipped, says 0.13.6 and the new figures. `cargo fmt --check` failed on the `fill_border` call in dr-pano's padding test, which is the first thing the Desktop job runs after installing the toolchain and why it failed within a minute. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 4 ++-- core/dr-pano/src/fill.rs | 12 ++++++++++-- docs/requirements.md | 29 +++++++++++++++++++++++++++++ docs/traceability.md | 18 +++++++++++------- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 15d9175..d90c3cc 100644 --- a/README.md +++ b/README.md @@ -76,8 +76,8 @@ controls, its place in the chain and its tests. ## Where it stands -**0.13.5**, nineteen tagged releases in. 184 numbered requirements in -scope, 84% of them claimed by code and [traced to it](docs/traceability.md); +**0.13.6**, twenty tagged releases in. 188 numbered requirements in +scope, 82% of them claimed by code and [traced to it](docs/traceability.md); the rest are written down rather than merely absent. **Not built:** plugins (post-v1, [D12](docs/requirements.md)), compare and diff --git a/core/dr-pano/src/fill.rs b/core/dr-pano/src/fill.rs index d7aacc1..f755b4f 100644 --- a/core/dr-pano/src/fill.rs +++ b/core/dr-pano/src/fill.rs @@ -745,8 +745,16 @@ mod tests { tile: 64, seen: Vec::new(), }; - let tiles = fill_border(&mut rgb, 300, 40, &known, &mut model, test_params(0), &mut |_, _| {}) - .unwrap(); + let tiles = fill_border( + &mut rgb, + 300, + 40, + &known, + &mut model, + test_params(0), + &mut |_, _| {}, + ) + .unwrap(); assert!(tiles > 0, "no tile fitted a picture shorter than the tile"); for i in 0..300 * 40 { if !known[i] { diff --git a/docs/requirements.md b/docs/requirements.md index 8075812..8160fc1 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -1814,6 +1814,28 @@ tool for a hand-held set, and a photograph with real parallax is not a panorama. in one operation until HDR merge exists on its own. No live re-stitch: a different projection or crop after the fact is a new file, not an edit. No video. +### 3.12 Inference runtime + +The face, segmentation and border-fill models run under an inference engine the application +selects per device. [inference.md](inference.md) is the design: its §3 sets the dependency policy +the runtime may reopen, its §10 the milestones (M1–M7) the clauses below cite as acceptance. The +clauses are the register entries inference.md §12 promised; they are stated here so the +traceability gate can count them. + +**FR-INF-1 — Runtime selection.** On launch the application shall determine, per device and +without blocking the first frame, the fastest inference backend that can build and run a session +for the shipped models, by attempting it; shall record and reuse that determination until the +runtime, driver, hardware or models change; and shall display the backend in use in Settings and +on the about screen. *Acceptance:* inference.md §10 M1 and M5. + +**FR-INF-2 — Derived engines.** Backends that require device-specific compilation shall compile in +the background after selection, shall serve requests from the next lower backend until each engine +is ready, and shall not change the backend of a job in progress. *Acceptance:* M5. + +**FR-INF-3 — Model forms.** Quantised model forms are produced at release time from real +calibration data and are shipped only when they meet inference.md §10's accuracy gates against the +canonical form; the application never quantises on the device. *Acceptance:* M2, M7. + --- ## 4. Non-functional requirements @@ -2111,6 +2133,13 @@ it is far cheaper to discover now than after the UI is built. clipping indicators (FR-DSP-7), and the HSL mixer carry a shape or text affordance. This matters more in a colour-grading application than in most software. +### 4.10 Inference + +**NFR-INF-1 — Embedding comparability.** Face embeddings shall be computed at a precision whose +deviation from the f32 reference is within [inference.md](inference.md) §7's gate, on every +backend, so that embeddings from any device are comparable — FR-CULL-9's calibration depends on +it. *Acceptance:* inference.md §10 M3. + --- ## 5. Data model and architecture diff --git a/docs/traceability.md b/docs/traceability.md index b845f17..c4f1487 100644 --- a/docs/traceability.md +++ b/docs/traceability.md @@ -11,24 +11,24 @@ Denominators are parsed from [`requirements.md`](requirements.md) at run time, n |---|---| | Source files scanned | 394 | | TRACES tags found | 1573 | -| Requirements defined | 184 | +| Requirements defined | 188 | | Requirements deferred (post-v1) | 24 | -| Requirements covered | 154 | -| **Coverage** | **83.7%** (154/184) | +| Requirements covered | 155 | +| **Coverage** | **82.4%** (155/188) | ### By type | Type | Covered | Defined | |---|---|---| -| FR | 116 | 127 | -| NFR | 34 | 50 | +| FR | 117 | 130 | +| NFR | 34 | 51 | | R | 4 | 7 | ## Orphan tags A tag naming an ID `requirements.md` does not define — what renumbering produces, and what a typo produces. -- `FR-INF-1` +_None._ ## Tagged requirements @@ -100,6 +100,7 @@ A tag naming an ID `requirements.md` does not define — what renumbering produc | FR-EXP-7 | [`ui/dr-ui/src/activity.rs:83`](../ui/dr-ui/src/activity.rs#L83), [`ui/dr-ui/src/export.rs:1005`](../ui/dr-ui/src/export.rs#L1005), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:268`](../ui/dr-ui/src/lib.rs#L268), [`ui/dr-ui/src/lib.rs:2813`](../ui/dr-ui/src/lib.rs#L2813), [`ui/dr-ui/src/lib.rs:607`](../ui/dr-ui/src/lib.rs#L607), [`ui/dr-ui/src/lib.rs:653`](../ui/dr-ui/src/lib.rs#L653), [`ui/dr-ui/src/lib.rs:680`](../ui/dr-ui/src/lib.rs#L680), [`ui/dr-ui/src/library_ui.rs:4249`](../ui/dr-ui/src/library_ui.rs#L4249), [`ui/dr-ui/src/library_ui.rs:721`](../ui/dr-ui/src/library_ui.rs#L721), [`ui/dr-ui/src/library_ui.rs:8149`](../ui/dr-ui/src/library_ui.rs#L8149), [`ui/dr-ui/src/library_ui.rs:821`](../ui/dr-ui/src/library_ui.rs#L821), [`ui/dr-ui/src/library_ui.rs:8226`](../ui/dr-ui/src/library_ui.rs#L8226), [`ui/dr-ui/src/library_ui.rs:8238`](../ui/dr-ui/src/library_ui.rs#L8238), [`ui/dr-ui/src/library_ui.rs:878`](../ui/dr-ui/src/library_ui.rs#L878), [`ui/dr-ui/ui/app.slint:1139`](../ui/dr-ui/ui/app.slint#L1139), [`ui/dr-ui/ui/app.slint:1716`](../ui/dr-ui/ui/app.slint#L1716), [`ui/dr-ui/ui/library.slint:1588`](../ui/dr-ui/ui/library.slint#L1588), [`ui/dr-ui/ui/library.slint:4339`](../ui/dr-ui/ui/library.slint#L4339) | | FR-EXP-8 | [`core/dr-decode/src/lib.rs:366`](../core/dr-decode/src/lib.rs#L366), [`core/dr-decode/src/lib.rs:390`](../core/dr-decode/src/lib.rs#L390), [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-decode/src/lib.rs:71`](../core/dr-decode/src/lib.rs#L71), [`core/dr-decode/src/lib.rs:79`](../core/dr-decode/src/lib.rs#L79), [`core/dr-decode/src/lib.rs:82`](../core/dr-decode/src/lib.rs#L82), [`core/dr-decode/src/locate.rs:1233`](../core/dr-decode/src/locate.rs#L1233), [`core/dr-decode/src/locate.rs:1292`](../core/dr-decode/src/locate.rs#L1292), [`core/dr-decode/src/locate.rs:359`](../core/dr-decode/src/locate.rs#L359), [`core/dr-decode/src/locate.rs:556`](../core/dr-decode/src/locate.rs#L556), [`core/dr-decode/src/locate.rs:640`](../core/dr-decode/src/locate.rs#L640), [`core/dr-decode/src/locate.rs:653`](../core/dr-decode/src/locate.rs#L653), [`core/dr-decode/src/locate.rs:736`](../core/dr-decode/src/locate.rs#L736), [`core/dr-export/examples/export.rs:99`](../core/dr-export/examples/export.rs#L99), [`core/dr-export/src/encode.rs:117`](../core/dr-export/src/encode.rs#L117), [`core/dr-export/src/encode.rs:161`](../core/dr-export/src/encode.rs#L161), [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/encode.rs:206`](../core/dr-export/src/encode.rs#L206), [`core/dr-export/src/encode.rs:235`](../core/dr-export/src/encode.rs#L235), [`core/dr-export/src/encode.rs:311`](../core/dr-export/src/encode.rs#L311), [`core/dr-export/src/encode.rs:325`](../core/dr-export/src/encode.rs#L325), [`core/dr-export/src/encode.rs:408`](../core/dr-export/src/encode.rs#L408), [`core/dr-export/src/encode.rs:456`](../core/dr-export/src/encode.rs#L456), [`core/dr-export/src/encode.rs:70`](../core/dr-export/src/encode.rs#L70), [`core/dr-export/src/encode.rs:795`](../core/dr-export/src/encode.rs#L795), [`core/dr-export/src/encode.rs:809`](../core/dr-export/src/encode.rs#L809), [`core/dr-export/src/encode.rs:850`](../core/dr-export/src/encode.rs#L850), [`core/dr-export/src/encode.rs:898`](../core/dr-export/src/encode.rs#L898), [`core/dr-export/src/exif.rs:1`](../core/dr-export/src/exif.rs#L1), [`core/dr-export/src/lib.rs:140`](../core/dr-export/src/lib.rs#L140), [`core/dr-export/src/metadata.rs:1`](../core/dr-export/src/metadata.rs#L1), [`core/dr-export/src/metadata.rs:41`](../core/dr-export/src/metadata.rs#L41), [`core/dr-export/src/metadata.rs:74`](../core/dr-export/src/metadata.rs#L74), [`core/dr-types/src/lib.rs:655`](../core/dr-types/src/lib.rs#L655), [`core/dr-types/src/settings.rs:671`](../core/dr-types/src/settings.rs#L671), [`ui/dr-ui/src/develop.rs:4581`](../ui/dr-ui/src/develop.rs#L4581), [`ui/dr-ui/src/develop.rs:4693`](../ui/dr-ui/src/develop.rs#L4693), [`ui/dr-ui/src/develop.rs:729`](../ui/dr-ui/src/develop.rs#L729), [`ui/dr-ui/src/export.rs:474`](../ui/dr-ui/src/export.rs#L474), [`ui/dr-ui/src/export.rs:641`](../ui/dr-ui/src/export.rs#L641), [`ui/dr-ui/src/export.rs:687`](../ui/dr-ui/src/export.rs#L687), [`ui/dr-ui/src/export.rs:715`](../ui/dr-ui/src/export.rs#L715), [`ui/dr-ui/src/export.rs:839`](../ui/dr-ui/src/export.rs#L839), [`ui/dr-ui/src/export.rs:857`](../ui/dr-ui/src/export.rs#L857), [`ui/dr-ui/src/lib.rs:268`](../ui/dr-ui/src/lib.rs#L268), [`ui/dr-ui/src/lib.rs:291`](../ui/dr-ui/src/lib.rs#L291), [`ui/dr-ui/src/lib.rs:639`](../ui/dr-ui/src/lib.rs#L639), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | | FR-EXP-9 | [`core/dr-decode/src/lib.rs:546`](../core/dr-decode/src/lib.rs#L546), [`core/dr-export/src/lib.rs:132`](../core/dr-export/src/lib.rs#L132), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-gpu/src/adjust.rs:1134`](../core/dr-gpu/src/adjust.rs#L1134), [`ui/dr-ui/examples/face_native.rs:1`](../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/develop.rs:4714`](../ui/dr-ui/src/develop.rs#L4714), [`ui/dr-ui/src/develop.rs:4752`](../ui/dr-ui/src/develop.rs#L4752), [`ui/dr-ui/src/develop.rs:7111`](../ui/dr-ui/src/develop.rs#L7111), [`ui/dr-ui/src/lib.rs:607`](../ui/dr-ui/src/lib.rs#L607), [`ui/dr-ui/src/library.rs:3889`](../ui/dr-ui/src/library.rs#L3889), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../ui/dr-ui/tests/export_ignores_the_viewport.rs#L1) | +| FR-INF-1 | [`ui/dr-ui/src/lib.rs:1215`](../ui/dr-ui/src/lib.rs#L1215), [`ui/dr-ui/ui/settings.slint:928`](../ui/dr-ui/ui/settings.slint#L928) | | FR-MRG-1 | [`core/dr-pano/src/align.rs:1`](../core/dr-pano/src/align.rs#L1), [`core/dr-pano/src/lib.rs:1`](../core/dr-pano/src/lib.rs#L1), [`ui/dr-ui/src/lib.rs:1576`](../ui/dr-ui/src/lib.rs#L1576), [`ui/dr-ui/src/merge.rs:1`](../ui/dr-ui/src/merge.rs#L1), [`ui/dr-ui/src/merge_ui.rs:1`](../ui/dr-ui/src/merge_ui.rs#L1), [`ui/dr-ui/ui/app.slint:1721`](../ui/dr-ui/ui/app.slint#L1721), [`ui/dr-ui/ui/app.slint:829`](../ui/dr-ui/ui/app.slint#L829), [`ui/dr-ui/ui/library.slint:1596`](../ui/dr-ui/ui/library.slint#L1596), [`ui/dr-ui/ui/library.slint:4284`](../ui/dr-ui/ui/library.slint#L4284), [`ui/dr-ui/ui/merge.slint:1`](../ui/dr-ui/ui/merge.slint#L1) | | FR-MRG-10 | [`core/dr-gpu/src/merge.rs:1`](../core/dr-gpu/src/merge.rs#L1), [`core/dr-gpu/src/shaders/merge.wgsl:1`](../core/dr-gpu/src/shaders/merge.wgsl#L1), [`core/dr-pano/src/lib.rs:1`](../core/dr-pano/src/lib.rs#L1) | | FR-MRG-11 | [`core/dr-gpu/src/merge.rs:1`](../core/dr-gpu/src/merge.rs#L1), [`core/dr-gpu/src/shaders/merge.wgsl:1`](../core/dr-gpu/src/shaders/merge.wgsl#L1) | @@ -220,7 +221,7 @@ Defined in `requirements.md` and marked `(post-v1)` on the defining line. Not in ## Not yet tagged -30 of 184 requirements have no implementation tag. Expected while the codebase is young; each should gain one as it is built. +33 of 188 requirements have no implementation tag. Expected while the codebase is young; each should gain one as it is built.
Show untagged requirements @@ -230,6 +231,8 @@ Defined in `requirements.md` and marked `(post-v1)` on the defining line. Not in - FR-DEV-3g - FR-DSP-2 - FR-DSP-4 +- FR-INF-2 +- FR-INF-3 - FR-MRG-9 - FR-NC-11 - FR-PLAT-AND-1 @@ -238,6 +241,7 @@ Defined in `requirements.md` and marked `(post-v1)` on the defining line. Not in - NFR-A11Y-1 - NFR-ARCH-1 - NFR-COMPAT-2 +- NFR-INF-1 - NFR-MRG-1 - NFR-MRG-2 - NFR-OPS-4