From ab0ef6a26d98e58fb74190772c3b618bd13da62c Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 29 Aug 2026 20:23:07 +0200 Subject: [PATCH 1/5] Say which requirements the code was already satisfying MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thirteen requirements were surveyed as built but untagged. Eight of them were: R3, R6, FR-DEV-1, FR-UI-6, FR-NC-6d, NFR-OPS-3, NFR-PORT-2 and NFR-SEC-3. Each was read against its full text in requirements.md and against the code before the tag was added, because a tag that is wrong is worse than an absent one — it turns a visible gap into an invisible one. The five that were refused, and why, because the reasoning is the part worth keeping: R2 carries "(figure TBD)" in its own acceptance criterion and asks for a stated prefetch margin and cache-hit rate; neither figure exists anywhere in the tree and neither quantity is measured, while TD-2 and TD-3 both describe the thumbnail path falling short of it. R5 asks for three things and the code does one. The display pipeline does run at viewport resolution, but "only visible tiles are computed" and "panning recomputes only newly exposed tiles" need a tile scheduler that does not exist — and frame_budget.rs currently argues for striking tiled computation from the interactive path rather than building it. FR-RAW-2 asks for a trait taking a SourceRef, so that a second decoder can be added without changing callers. What exists is free functions over &[u8]. That meets the requirement's stated *purpose* — the same decoder serves a local file, a SAF document and a byte range, which is exactly why it takes bytes — but there is no trait and no second implementation seam, so the requirement should probably be amended rather than tagged. NFR-ARCH-1 asks for named executors with stated thread counts. architecture.md §7.1 states the table; nothing implements it. Workers are twenty-odd ad-hoc std::thread::spawn sites, each building its own one-worker tokio runtime, with no decode pool, no GPU-submit executor and no I/O pool. The requirement's own text says R4 and NFR-P9 "assert an outcome with no stated means", and that is still true. NFR-SEC-4 is satisfied by absence — there is no telemetry — and absence has no module to tag. A tag would point at nothing. NFR-OPS-3 was the closest call of the eight taken. The store is single, separate from the catalog, survives a catalog rebuild and does not sync between devices; it has no version *field*, deliberately, and settings.rs argues why and names the condition that would need one. The substance is met and the reasoning is recorded where it belongs. Co-Authored-By: Claude Opus 5 (1M context) --- core/dr-export/src/lib.rs | 2 +- core/dr-gpu/src/lib.rs | 1 + core/dr-pipeline/src/graph.rs | 1 + core/dr-pipeline/src/lib.rs | 1 + core/dr-pipeline/src/sidecar.rs | 1 + core/dr-sync-folder/src/borrow.rs | 2 +- core/dr-sync-folder/src/lib.rs | 2 +- core/dr-sync-folder/src/vfs.rs | 2 +- core/dr-sync-nextcloud/src/lib.rs | 1 + core/dr-sync-nextcloud/src/provider.rs | 2 +- core/dr-types/src/settings.rs | 2 +- ui/dr-ui/src/settings_store.rs | 2 +- ui/dr-ui/ui/widgets.slint | 1 + 13 files changed, 13 insertions(+), 7 deletions(-) diff --git a/core/dr-export/src/lib.rs b/core/dr-export/src/lib.rs index cc9699d..a406101 100644 --- a/core/dr-export/src/lib.rs +++ b/core/dr-export/src/lib.rs @@ -1,4 +1,4 @@ -//! TRACES: FR-EXP-1 | FR-EXP-2 | FR-EXP-3 | FR-EXP-4 | FR-EXP-6 | FR-EXP-9 +//! TRACES: FR-EXP-1 | FR-EXP-2 | FR-EXP-3 | FR-EXP-4 | FR-EXP-6 | FR-EXP-9 | R3 //! Turning a rendered frame into a file's worth of bytes. //! //! # What this crate is, and is not diff --git a/core/dr-gpu/src/lib.rs b/core/dr-gpu/src/lib.rs index 705ceb1..b644b01 100644 --- a/core/dr-gpu/src/lib.rs +++ b/core/dr-gpu/src/lib.rs @@ -1,3 +1,4 @@ +//! TRACES: NFR-PORT-2 //! GPU device and compute for DarkRoom. //! //! In v0.1 this exists to prove one thing: a compute shader can write a diff --git a/core/dr-pipeline/src/graph.rs b/core/dr-pipeline/src/graph.rs index 209bbd3..20c2225 100644 --- a/core/dr-pipeline/src/graph.rs +++ b/core/dr-pipeline/src/graph.rs @@ -1,3 +1,4 @@ +//! TRACES: FR-DEV-1 //! The edit graph — an ordered set of operations (ARCH §3.4). //! //! CPU-side state, deliberately. The GPU device can be lost and rebuilt at any diff --git a/core/dr-pipeline/src/lib.rs b/core/dr-pipeline/src/lib.rs index c8ffbf8..fb7faab 100644 --- a/core/dr-pipeline/src/lib.rs +++ b/core/dr-pipeline/src/lib.rs @@ -1,3 +1,4 @@ +//! TRACES: R3 //! The develop pipeline — operations, descriptors, and shader composition. //! //! # What this crate is diff --git a/core/dr-pipeline/src/sidecar.rs b/core/dr-pipeline/src/sidecar.rs index 93e2372..f70d91c 100644 --- a/core/dr-pipeline/src/sidecar.rs +++ b/core/dr-pipeline/src/sidecar.rs @@ -1,3 +1,4 @@ +//! TRACES: FR-DEV-1 //! Sidecar serialisation — the edit graph as durable, mergeable data. //! //! # Generic, for the same reason the UI is generic diff --git a/core/dr-sync-folder/src/borrow.rs b/core/dr-sync-folder/src/borrow.rs index f48526a..490a938 100644 --- a/core/dr-sync-folder/src/borrow.rs +++ b/core/dr-sync-folder/src/borrow.rs @@ -1,4 +1,4 @@ -// TRACES: FR-NC-6c | FR-NC-6a +// TRACES: FR-NC-6c | FR-NC-6a | FR-NC-6d //! Hydrating a file for as long as it is needed, and no longer. //! //! A pass over a library — thumbnails, face indexing — needs each photograph's diff --git a/core/dr-sync-folder/src/lib.rs b/core/dr-sync-folder/src/lib.rs index 69f0d22..24b84cd 100644 --- a/core/dr-sync-folder/src/lib.rs +++ b/core/dr-sync-folder/src/lib.rs @@ -1,4 +1,4 @@ -// TRACES: FR-NC-13 | FR-NC-12 +// TRACES: FR-NC-13 | FR-NC-12 | FR-NC-6d //! A library that is just a directory. //! //! The second [`RemoteBackend`], and the one that exists to prove the first diff --git a/core/dr-sync-folder/src/vfs.rs b/core/dr-sync-folder/src/vfs.rs index 3e05e4d..a49e0d9 100644 --- a/core/dr-sync-folder/src/vfs.rs +++ b/core/dr-sync-folder/src/vfs.rs @@ -1,4 +1,4 @@ -// TRACES: FR-NC-6c +// TRACES: FR-NC-6c | FR-NC-6d //! Virtual-filesystem conventions layered over a directory. //! //! A sync client in virtual-files mode leaves a *placeholder* where a file is diff --git a/core/dr-sync-nextcloud/src/lib.rs b/core/dr-sync-nextcloud/src/lib.rs index bfc30f7..ad93db0 100644 --- a/core/dr-sync-nextcloud/src/lib.rs +++ b/core/dr-sync-nextcloud/src/lib.rs @@ -1,3 +1,4 @@ +//! TRACES: R6 | NFR-SEC-3 //! Nextcloud connector. //! //! One of two [`RemoteBackend`] implementations, registered through diff --git a/core/dr-sync-nextcloud/src/provider.rs b/core/dr-sync-nextcloud/src/provider.rs index c182935..7b1a503 100644 --- a/core/dr-sync-nextcloud/src/provider.rs +++ b/core/dr-sync-nextcloud/src/provider.rs @@ -1,4 +1,4 @@ -// TRACES: FR-NC-12 | FR-NC-1 +// TRACES: FR-NC-12 | FR-NC-1 | NFR-SEC-3 //! Registering Nextcloud as a storage backend. //! //! The account model this connector used to own now lives in diff --git a/core/dr-types/src/settings.rs b/core/dr-types/src/settings.rs index 8bc950d..a6b596c 100644 --- a/core/dr-types/src/settings.rs +++ b/core/dr-types/src/settings.rs @@ -1,4 +1,4 @@ -//! TRACES: FR-NC-6a | FR-EXP-1 | FR-EXP-2 | FR-EXP-3 | FR-EXP-6 | FR-PLAT-LIN-1 +//! TRACES: FR-NC-6a | FR-EXP-1 | FR-EXP-2 | FR-EXP-3 | FR-EXP-6 | FR-PLAT-LIN-1 | NFR-OPS-3 //! Device preferences: how much disk to spend, and what an export defaults to. //! //! # Why these live beside the session and not in the catalog diff --git a/ui/dr-ui/src/settings_store.rs b/ui/dr-ui/src/settings_store.rs index 755772d..d8b9c54 100644 --- a/ui/dr-ui/src/settings_store.rs +++ b/ui/dr-ui/src/settings_store.rs @@ -1,4 +1,4 @@ -//! TRACES: FR-PLAT-LIN-1 | FR-NC-6a | FR-EXP-5 +//! TRACES: FR-PLAT-LIN-1 | FR-NC-6a | FR-EXP-5 | NFR-OPS-3 //! Reads and writes `settings.json` beside the session config. //! //! Deliberately a near-twin of [`SessionStore`](dr_sync_nextcloud::SessionStore) diff --git a/ui/dr-ui/ui/widgets.slint b/ui/dr-ui/ui/widgets.slint index 5a9db2f..793439e 100644 --- a/ui/dr-ui/ui/widgets.slint +++ b/ui/dr-ui/ui/widgets.slint @@ -1,3 +1,4 @@ +// TRACES: FR-UI-6 // Shared chrome primitives and the style layer. // // Before this file every button was a Rectangle + TouchArea written out where From 8165619065524caa8fc3cbfdbe45b68fd539d4e3 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 29 Aug 2026 20:23:28 +0200 Subject: [PATCH 2/5] Describe the project the README is actually in front of MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It said the status was "early", that v0.1 is a remote library viewer, and that the zero-copy display path was "not yet working" and its replacement was the highest priority. All three were true when they were written and none of them has been true for eight releases. The zero-copy line was the damaging one, because it is the project's central architectural constraint and the README stated the opposite of what happened. Desktop keeps the zero-copy path — the compute pass writes a texture Slint composites directly — and the readback survives in exactly one place, the Android develop view, because wgpu's Vulkan swapchain tears a portrait window on a tablet whose panel is mounted landscape. That is TD-1, with the on-device measurements and the three things any one of which would remove it. A reader who took the old text at face value would have gone looking for a bug that was fixed, and missed a compromise that was chosen. "Current state" now says what runs, checked item by item against the tree rather than from memory: the first draft claimed AVIF and JPEG XL export, which the settings page offers and dr-export refuses on purpose, and sixteen declared operations where there are fifteen. Both are the kind of error this commit exists to remove. The requirement count moves from 122 to 179, the documentation table gains the five documents somebody would actually want next, and the "Not built" paragraph points at docs/outstanding.md rather than leaving the reader to infer the gap from silence. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 61 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 0125092..8656899 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,25 @@ A cross-platform, non-destructive RAW photo editor for Linux and Android. -**Status:** early. v0.1 is a remote library viewer — see -[docs/milestone-v0.1.md](docs/milestone-v0.1.md). +**Status:** 0.9.0, and no longer a spike. A library opens, culls, develops and +exports on both platforms, across eight tagged releases. What is *not* +built is written down rather than merely absent — see +[docs/outstanding.md](docs/outstanding.md) for the requirements that have no +implementation and why, and [docs/technical-debt.md](docs/technical-debt.md) +for the compromises that were chosen. ## Documentation | Document | Contents | |---|---| -| [requirements.md](docs/requirements.md) | What the software must do — 122 numbered requirements | +| [CONTRIBUTING.md](CONTRIBUTING.md) | How to land a first change without reading the rest | +| [requirements.md](docs/requirements.md) | What the software must do — 179 numbered requirements | | [architecture.md](docs/architecture.md) | How it is built — crates, GPU pipeline, data model, sync | -| [milestone-v0.1.md](docs/milestone-v0.1.md) | The first buildable milestone | -| [faces.md](docs/faces.md) | Face detection and identity — the models, the licence problem, and what S14 measures | +| [technical-debt.md](docs/technical-debt.md) | Compromises taken deliberately, each with the condition that retires it | +| [outstanding.md](docs/outstanding.md) | What is not built, and whether that is a decision or a gap | +| [code-health.md](docs/code-health.md) | What a contribution costs, per seam, measured | +| [traceability.md](docs/traceability.md) | Generated: which requirement is claimed by which file | +| [faces.md](docs/faces.md) | Face detection and identity — the models, the licence problem, and what S14 measured | ## Building @@ -28,21 +36,48 @@ Android (containerised toolchain, see [docker/android](docker/android/README.md) ./docker/android/build.sh cargo ndk -t arm64-v8a build --release ``` +Git LFS is required for the model weights, and the toolchain pins itself. +[CONTRIBUTING.md](CONTRIBUTING.md) has the details and the four commands CI +will run against what you send. + ## Current state -Working: workspace, GPU context and compute pass, adaptive Slint shell, Android -cross-compilation of the core crates. +**Working.** A catalog over a local folder, a Nextcloud account, or a folder a +sync client keeps in virtual-files mode — where a placeholder is treated as the +photograph rather than as a one-byte file. A virtualised library grid with a +capture-time timeline, ratings, labels, keywords, collections and a trash that +survives a crash mid-operation. Card ingest. Face detection and identity, with +the index syncing between devices. A develop pipeline of fifteen declared +operations fused into a single compute dispatch, plus the neighbourhood +operations that cannot be — clarity, texture, capture sharpening, noise +reduction, lens correction, spectral film simulation. Crop, straighten, spot +removal, gradient and subject-segmentation masks, named presets, and a +generated panel that no operation in `ui/` is allowed to name. Export to JPEG, +PNG and 8- or 16-bit TIFF with resize and output sharpening. -**Not yet working:** the zero-copy display path. The build currently uploads -frames through the CPU, which is exactly what -[ARCH §6.1](docs/architecture.md) forbids — measured at 96% of frame time at -4K. Replacing it is spike S1, the project's highest priority. +**The zero-copy display path works on desktop.** The compute pass writes a +texture that Slint composites directly, which is what +[ARCH §6.1](docs/architecture.md) requires; the readback it forbids costs 96% +of frame time at 4K, and -``` +```bash cargo run -p dr-gpu --example bench --features readback ``` -reproduces that measurement. +still reproduces that measurement. **The one exception is the Android develop +view**, which reads the frame back through the CPU because zero-copy there +needs wgpu's Vulkan swapchain, and that tears a portrait window on a tablet +whose panel is mounted landscape. It is debt, not a revision of the rule: the +reasoning, the on-device measurements that forced it, and the three separate +things any one of which would remove it are in +[technical-debt.md TD-1](docs/technical-debt.md). + +**Not built.** Plugins, compare and survey culling, focus peaking, burst +grouping, AI denoise, tiled and progressive rendering, and most of the Android +platform integration beyond running. The performance targets in §4.1 are +unverified rather than unmet — the per-commit benchmark suite §8 requires does +not exist, so nothing fails a build on a regression. +[docs/outstanding.md](docs/outstanding.md) is the list, with the reasoning. ## Licence From 88ef7148d6f03730b5644dac48105b3be818507e Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 29 Aug 2026 20:23:52 +0200 Subject: [PATCH 3/5] Write down what is not built, so the gap reads as a decision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The traceability matrix reports one number and cannot say what it means. An untagged requirement is either one nobody built or one somebody built and did not label, and both look identical in the summary table. Eight of the second kind were tagged in the previous commit. This is the first kind, written out with the reasoning, so that the distance between the register and the binary is something a reader can see rather than reconstruct from a percentage. Eleven clusters, each verified against the tree rather than inherited from a survey. Several turned out to be more interesting than "not done": Plugins are 21 untagged requirements — nearly a third of the shortfall — and §7 already lists the Plugin API as out of scope for v1 while §3.10 spends 280 lines specifying it. The two that *are* built, FR-PLG-2 and FR-PLG-2d, are the declarative operation format, which is a plugin system that resolves at build time. The fix here is an edit to requirements.md, not code, and D16 has to be answered before any format is called stable. FR-DSP-2 is not merely unbuilt; it is under challenge. frame_budget.rs and TD-4 independently argue that tiling costs more than it saves on the interactive path, so the open question is whether the requirement should survive, not when it will be met — and the spike that would settle it, S6, has not run. NFR-A11Y-1's hard half is done and its easy half is not. LocalizedKey already keeps display strings out of core/ and labels::resolve is a single resolution point; what that point does is a hardcoded English match, so a translation needs a recompile, which is the one thing the requirement forbids. The §4.1 performance targets are unverified rather than unmet. §8 requires a per-commit benchmark suite whose regressions fail the build; there is no benches/ directory, no criterion, and no benchmark step in any of the three CI workflows. The one guard that does live in CI skips itself without a GPU adapter and asserts its CPU half only in release, while CI tests in dev. Nothing says the targets are missed. It says nobody would find out. And three requirements are reported as covered while not being met: R1 and NFR-OPS-1 are tagged only by string literals inside the traceability tool's own tests, which it scans along with everything else, and FR-CAT-13's single tag sits on keyword storage while no XMP is parsed or written anywhere. CONTRIBUTING already warns that a tag proves a tag exists; these are the specific ones. Focus peaking, burst grouping, Flatpak packaging and the Android platform integration are being built in parallel and are marked in progress rather than listed as absent, so those lines can be struck as they land. Co-Authored-By: Claude Opus 5 (1M context) --- docs/outstanding.md | 351 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) create mode 100644 docs/outstanding.md diff --git a/docs/outstanding.md b/docs/outstanding.md new file mode 100644 index 0000000..45c6a8f --- /dev/null +++ b/docs/outstanding.md @@ -0,0 +1,351 @@ +# DarkRoom — Outstanding work + +**Status:** Living document · first written 2026-08-29 +**Companion to:** [requirements.md §7](requirements.md), [technical-debt.md](technical-debt.md), +[traceability.md](traceability.md) + +What is specified and not built, and for each cluster whether that is a decision, a dependency, or a +gap nobody has looked at. + +This document exists because [traceability.md](traceability.md) cannot tell those apart. It reports +one number — the share of requirements carrying a `TRACES` tag — and a missing tag means either +"nobody has built this" or "somebody built it and did not say so". Both read the same way in the +summary table, which makes that figure pessimistic *and* uninformative at once: it understates what +works while hiding which of the remainder matters. Eight requirements gained a tag on this branch +because the code already satisfied them and nobody had said so. Everything below is the other kind. + +It is also not a plan. [requirements.md §7](requirements.md) records what was deferred deliberately +and needs no argument; this records what is still nominally in scope, so that the distance between +the register and the binary is visible rather than something a reader has to reconstruct from a +percentage. Where the honest answer is "this requirement should be amended rather than met", it says +so — an unbuilt requirement that nobody intends to build is worse than a deferred one, because it +keeps costing attention. + +**Four of these are being built right now**, in parallel worktrees, and are marked **⟳ in +progress** where they appear: focus peaking (part of FR-CULL-3), burst grouping (FR-CULL-5), +Flatpak packaging (FR-PLAT-LIN-3), and Android platform integration (FR-PLAT-AND-2/4/5/6). Strike +those lines as they land rather than rewriting around them. + +--- + +## 1. Plugins — 21 requirements, and a contradiction to resolve before any of them + +**Untagged:** FR-PLG-1, -1a, -2a, -2b, -2c, -3, -3a, -4, -4a, -5, -5a, -5b, -5c, -6, -6a, -7, -8, +-9, -10, -11, -12. + +No plugin host exists. No crate loads anything at runtime: there is no manifest reader, no WASM or +Lua engine, no registry, no signature check, no install path, no capability grant, no per-plugin +failure ledger. `declared/mod.rs` says as much in its own documentation — the operation format is +"not a plugin directory read at startup". + +**Two of §3.10's requirements are met, and they are the interesting two.** FR-PLG-2 and FR-PLG-2d — +the declarative node format — are built and tagged: `core/dr-pipeline/ops/*.yaml` compiled by +`build.rs`, with the restricted expression grammar in `declared/expr.rs` and a parity test asserting +a declared operation and a hand-written one produce identical output. +[code-health.md §3](code-health.md) calls it "a working plugin system that happens to resolve at +build time", and that is exactly right. What is missing is not the format; it is everything that +would let somebody who is not in this repository use it. + +**The contradiction.** [requirements.md §7](requirements.md) lists `| Plugin API | — |` among the +things deferred for v1 — a bare row, where most deferrals carry a justifying note. §3.10 then spends +roughly 280 lines and 23 requirement IDs specifying that same Plugin API in detail. Both statements +are in the register of record, and the traceability denominator counts the second one: 21 IDs, 12% +of all 179 defined requirements, worth about twelve points of coverage on their own — and nearly a +third of everything the matrix reports as uncovered. A reader looking at the coverage figure has no +way to know that, or that the subsystem behind it is one the same document says is not in this +version. + +**And D16 is open.** [Decision D16](requirements.md) — plugin licensing — records that GPLv3 +answers the derivative-work question differently for each of §3.10's three plugin forms, and that +this "must be answered *before* an ecosystem exists, not after", because a term introduced later +cannot be applied to plugins already written. D16 explicitly does not block FR-PLG-2; it blocks +publishing a third-party format as stable. + +**What would resolve this:** an edit to `requirements.md`, not code. Either §7 drops the row, or +§3.10 is marked deferred with the two built requirements carved out. Until one of those happens the +coverage figure is measuring a decision that has already been taken, and taking it again every time +somebody reads the matrix. + +--- + +## 2. Culling — the stated differentiator, half built + +[D11](requirements.md) names culling "the core differentiator". FR-CULL-1, -2, -4 and -8 through -12 +are built. Four are not. + +**FR-CULL-3 — Raw-truth overlays.** Focus peaking does not exist anywhere; the string appears zero +times in the tree. A histogram and clipping indicators *do* exist, but they are not the ones this +requirement asks for: they live in the develop view under FR-DSP-7, they are threshold readouts +rather than per-pixel overlays on the image, and `develop.rs` says plainly that what they count is +"the levels the display will show" — the pipeline result, not the sensor data. FR-CULL-3 exists +because a culling decision made against a rendered preview is a decision made against the wrong +image. **⟳ in progress** (focus peaking). + +**FR-CULL-5 — Burst and near-duplicate grouping.** Absent. Worth knowing before it is built: +`core/dr-face/src/calibrate.rs` already *assumes* it exists — "since FR-CULL-5 already groups +bursts, positives are bootstrapped from bursts" — and in fact bootstraps from confirmed labels +instead. That comment is a forward reference to this requirement and will need correcting either +way. `core/dr-catalog/src/dedup.rs` is not this: it is re-import detection under FR-CAT-11, matching +a file against one already catalogued, not two photographs against each other. **⟳ in progress**. + +**FR-CULL-6 — Compare and survey.** Absent. No side-by-side view, no synchronised zoom or pan. +This is the one of the four with no adjacent machinery at all, and it is also the one that most +directly distinguishes culling from browsing. + +**FR-CULL-7 — Culling on tablet.** Absent, and blocked by the three above rather than independent +of them: there is no separate tablet culling surface to build until there is something to put on it. + +--- + +## 3. FR-DEV-3g — AI denoise + +Promoted into v1 by [D11](requirements.md), and named there as the precondition for deferring AI +masking — the argument being that one learned stage earns the runtime that a second could then +reuse. Only classical noise reduction exists: `ops/noise_reduction.rs`, a bilateral filter in two +arrangements, exact for luminance and separable for chroma. It is good, and it is not this. + +`models/` holds two face models and nothing else; `core/dr-segment/models/` holds a YOLO +segmentation model for subject masks. There is no denoise model, no learned demosaic, and no +inference path that is not face or segmentation. + +The obstacle is not the pipeline. It is that [D13](requirements.md) — model licensing — is still +open for the models that already ship, and adding a third learned stage adds a third licence to +answer for. Building the runtime before that is settled means owning the same problem in one more +place. + +--- + +## 4. The render path — FR-DSP-2, FR-DSP-4, NFR-RES-2 + +**FR-DSP-2 — Tiled computation. Unbuilt, and under challenge.** [architecture.md §6.2](architecture.md) +calls for tiling "from day one" on the grounds that retrofitting it is a rewrite. It was not built, +and the evidence has since moved. `core/dr-gpu/tests/frame_budget.rs` carries the argument in its +own header: one fused dispatch over a viewport-sized target is comfortably inside the frame budget, +and "if that stops being true, the recommendation to strike tiled computation from the interactive +path stops being supported, and this test is what says so." +[technical-debt.md TD-4](technical-debt.md) reaches the same place from the other direction — a +tiled convolution at clarity's radius reads nearly twice the taps that an untiled one does, so the +stage that looks most like it wants a tile cache is the stage that would be hurt most by one. + +What exists is the declaration and not the mechanism: `DetailPass::radius` is documented as the halo +a tile would have to be grown by, with a test that pins it, and there is no scheduler to read it. +That is deliberate plumbing, not an oversight. + +**So the open question here is not "when is tiling built" but "is FR-DSP-2 still a requirement".** +Two measurements say it costs more than it saves on the interactive path. Neither says anything +about the export path or about a device under memory pressure, which is where the case for it +actually lives — and that is spike S6, which has not run. + +**FR-DSP-4 — Progressive refinement.** Unbuilt. FR-DSP-1's proxy rendering and TD-4's +quarter-resolution base are adjacent and are not it: both are fixed choices about what resolution to +compute at, where FR-DSP-4 asks for a first frame that is deliberately cheap and a second that +replaces it. Nothing tracks a "this frame is provisional" state. + +**NFR-RES-2 — Images larger than GPU memory.** No answer, and §4.3 knows it: the requirement text +itself asks the reader to "decide explicitly" how ARCH §6.4 and NFR-RES-2 are reconciled. There is +no headroom budget, no allocation-failure fallback, and no spill. Spike S6 — a tiled pipeline on a +mid-range Android device with an image larger than available GPU memory — is the one that would +settle both this and FR-DSP-2, and there is no evidence it has run. + +--- + +## 5. Android beyond running, and Flatpak + +The Android app is not a stub — it builds an APK, runs the whole application, unpacks bundled face +models, and has been measured on a tablet ([faces.md §12.1](faces.md), +[technical-debt.md TD-1](technical-debt.md)). What is missing is the platform contract around it. + +**FR-PLAT-AND-1 is tagged and should not be relied on.** The requirement demands that library access +be obtained *exclusively* through the Storage Access Framework. There is no SAF code: no +`ACTION_OPEN_DOCUMENT_TREE`, no `takePersistableUriPermission`, no `DocumentsContract`. The two tags +rest on a `SourceRef::Document` variant that nothing constructs and a volumes helper, which is the +"plumbing a future feature would use" case [CONTRIBUTING.md](../CONTRIBUTING.md) and +[code-health.md CH-4](code-health.md) both warn about. Android reaches a library through a Nextcloud +account or a folder, over paths, like the desktop. + +That has a consequence for the rest of the cluster: **FR-PLAT-AND-2** — detecting the loss of a +granted tree permission and marking images offline rather than deleting rows — cannot be built until +there is a permission to lose. It is listed here as unbuilt, but it is blocked, not skipped. + +**FR-PLAT-AND-4** (managed background execution, foreground service for exports, stated Doze +behaviour): the manifest declares one activity, no service, and neither `FOREGROUND_SERVICE` nor +`POST_NOTIFICATIONS`. **FR-PLAT-AND-5** (`onTrimMemory` with a stated eviction order): no callback +is registered, though the eviction order it is supposed to drive is specified in FR-NC-6's text. +**FR-PLAT-AND-6** (view and share intents, `FileProvider`): the only intent filter is +`MAIN`/`LAUNCHER`. **⟳ in progress** for this group. + +**FR-PLAT-LIN-3 — Flatpak.** `packaging/` holds an Arch `PKGBUILD` and a `.desktop` entry. There is +no Flatpak manifest, nothing goes through a portal, and `platform/dr-plat/src/secrets.rs` talks to +the Secret Service directly rather than through the portal the requirement names. **⟳ in progress**. + +**NFR-COMPAT-2 — distribution channels.** Unstated, and this is the requirement that makes the +others binding: §4.8 observes that the decision to publish on Play is what turns SAF from a +preference into a constraint. Spike S11, the Play permissions dry-run that would settle it, has not +run. Related, NFR-COMPAT-1's baseline is real but scattered — API 28/36 live in the Android +Dockerfile and are checked in CI against the built ELF, which is good — while the items the +requirement singles out are missing: whether `shaderFloat16` and 16-bit storage are required (the +one it flags as jeopardising R1), minimum RAM, minimum desktop Mesa, and a named reference device +from a second GPU vendor. + +**NFR-OPS-2 and NFR-OPS-4.** Crash reporting is a `log::error!` panic hook on Android and nothing at +all on desktop: no local crash record, no backtrace capture, no upload path and therefore no opt-in +gate to guard it. Update and first run are undefined; the concrete reason NFR-OPS-4 gives — that D2 +pins rawler at a non-SemVer alpha whose camera-support fixes users will need — is unaddressed, and +there is no update mechanism of any kind. + +--- + +## 6. Accessibility and internationalisation — the hard half is done and the easy half is not + +**NFR-A11Y-1 — Localisation.** `@tr(` appears **zero** times across 14,482 lines of Slint. That +number overstates the problem, because the part that is genuinely architectural was got right: +`LocalizedKey` keeps display strings out of `core/` entirely, every operation publishes a key rather +than a label, and `labels::resolve` is the single point where a key becomes text. What that single +point does, however, is a hardcoded English `match` in Rust source — so changing a translation +requires a recompile, which is the one thing the requirement explicitly forbids. There is no message +catalogue in any format, no locale-resolution rule, and no decision recorded about RTL. + +The work left is therefore smaller than it looks and entirely mechanical: a catalogue format, a load +path behind `resolve`, and `@tr(` around the Slint literals. The design it needs already exists. + +**NFR-A11Y-2 — Accessibility.** `accessible-*` appears five times in the whole interface, all five +on one control — the parameter slider in `adjust.slint` — and nothing is set from the Rust side at +all. Everything else in eighteen Slint files is unnamed to AT-SPI and TalkBack. The requirement's own +caveat, that Slint's Android accessibility needs verifying, is spike S13, which has not run. + +**NFR-A11Y-3 — Colour-independent status.** No compliance work found. This is cheap to satisfy while +a control is being written and expensive to retrofit across forty of them, which is an argument for +doing it as part of the NFR-A11Y-2 pass rather than after it. + +--- + +## 7. Catalog and sync + +**FR-CAT-14 — Migration import.** Reading ratings, labels, keywords and collections out of a +Lightroom `.lrcat` or a darktable `library.db`. Unbuilt. The destination is not: keywords, +collections, ratings and the cross-device merge rules are all built and tested, and +`keywords.rs` already anticipates the arrival ("an import from Lightroom can bring in…"). What is +missing is only the two source adapters — which is a comparatively contained piece of work for a +requirement that decides whether somebody can try this software on a library they already have. + +**FR-NC-11 — Initial catalog build.** Using WebDAV `SEARCH` (RFC 5323) against `/remote.php/dav/`, +filtered by mimetype and paginated, in preference to walking folders with PROPFIND. Unbuilt: no +`SEARCH` request is issued anywhere. The PROPFIND walk this exists to replace is fully built and +well optimised — ETag pruning under FR-NC-4 turns an unchanged 50k library into one request — so the +gap is narrower than it reads. It is the *first* build against a large remote library that pays, and +that is the moment a new user meets. + +**FR-CAT-13 — XMP interoperability, tagged and not met.** Read and write standard XMP sidecars. The +single tag sits on `keywords.rs`, which stores keywords; no XMP is parsed or written anywhere in the +tree, and `dr-export`'s metadata module says so about its own half ("neither is read by `dr-decode` +today"). Listed here rather than silently, because a tag makes a gap invisible and this one is +load-bearing for interoperating with the editors FR-CAT-14 imports from. + +--- + +## 8. The performance targets are unverified, not unmet + +Eleven of the fifteen §4.1 targets carry no tag: NFR-P2, -P3, -P4, -P6, -P7, -P8, -P10, -P11, -P12, +-P14, -P15. That is the uninteresting part of this section. + +The interesting part is that §8 and §4.1 both require the same thing, in the same words, and it does +not exist: an automated benchmark suite against a synthetic 50k catalog, run per commit, where **"a +regression beyond a stated tolerance is a build failure, not a notification."** There is no +`benches/` directory in the workspace, no criterion dependency, and no synthetic catalog. The three +CI workflows run `cargo fmt --check`, clippy, `cargo test --workspace`, a release build, an Android +cross-build and a layering check. None of them measures anything, so there is no baseline to +regress against and no tolerance to exceed. + +What does exist is narrower and genuinely good: `dr-gpu/examples/frame_budget` is a real instrument, +its results are committed in [frame-budget.md](frame-budget.md) with the machine and profile named, +and TD-4's before-and-after was measured with it. But it is run by hand — frame-budget.md's own +instruction is "rerun and diff this file" — and the guard version that does live in CI skips itself +where there is no GPU adapter, which the workflow notes is the normal case on a runner, while +asserting its CPU half only when `debug_assertions` is off, which a dev-profile `cargo test` is not. +In CI it therefore asserts approximately nothing. + +**The claim to take from this is precise.** Nothing here says the performance targets are missed. +Several are plausibly met. It says that if one were broken tomorrow, nobody would find out — which +is the failure mode §8 was written to prevent, and the reason it belongs in this document rather +than in a backlog. + +--- + +## 9. Two core requirements that cannot be closed as written + +**R1 — Cross-platform output within a bounded tolerance.** §2 states that the threshold "must be +fixed before spike S9", because S9 both validates R1 and calibrates what tolerance is achievable. +The threshold was never fixed and S9 has not run, so R1 currently has no acceptance criterion at +all — there is nothing a test could assert. + +Worse, the matrix reports R1 as *covered*. Both of its tags are string literals inside the +traceability tool's own unit tests (`tools/traceability/src/lib.rs`), which the tool scans along with +everything else, because a fixture demonstrating tag extraction is indistinguishable from a tag. +NFR-OPS-1 is covered the same way, from a tag on `compute_coverage` — and no rotating, size-capped +on-disk log exists; logging goes to stderr and logcat. These are two of the cases +[CONTRIBUTING.md](../CONTRIBUTING.md) already warns about, now named. + +**R2 — Efficient display of huge RAW libraries.** Its acceptance criterion contains "*(figure +TBD)*" — the scroll velocity below which no cell may render as a placeholder — and asks for a stated +prefetch margin and cache-hit rate. No figure is stated anywhere in the tree, neither quantity is +measured, and [TD-2](technical-debt.md) and [TD-3](technical-debt.md) both describe the thumbnail +path falling short of it in ways that were measured. R2 was deliberately left untagged on this branch +for that reason: the machinery is substantial and the criterion is unmet and partly undefined. + +Both belong with §8 above. A requirement whose threshold was never chosen and a target nothing +measures fail in the same way — not by being wrong, but by being unfalsifiable. + +--- + +## 10. Spikes + +§9 defines fourteen validation spikes and says of three of them: "S1, S2 and S10 are the three that +can invalidate the architecture." + +Only **S1** (Slint + wgpu zero-copy on Linux) and **S14** (the face pipeline on a real library) have +recorded results. S14's are the best evidence of any spike — a dedicated document, a measured pass +over an 18,143-face library, a named device and a reproducible command — though D13's licensing half +remains open. + +**S6, S9, S10, S11 and S13 show no evidence of having run at all.** Each is referenced only from the +requirement text that asks for it: + +| Spike | Would settle | Blocked on | +|---|---|---| +| S6 | FR-DSP-2, NFR-RES-2 — tiling and images larger than GPU memory | Nothing; needs a device and a large image | +| S9 | R1's tolerance threshold, and therefore R1 | Nothing; the threshold is defined *by* running it | +| S10 | Whether SAF at 10k files meets NFR-P1/P3 | §5 — there is no SAF code to measure | +| S11 | NFR-COMPAT-2, and whether Play makes SAF binding | Nothing | +| S13 | NFR-A11Y-2 on Android | §6 — there is almost nothing to test with | + +S2, S3, S4, S5, S7, S8 and S12 are also unrun, several with acknowledgements in the code that say +so (`dr-sync/src/upload.rs` on S8, `dr-sync-nextcloud/src/lib.rs` on S3). S2 is one of the three +architecture-invalidating spikes and needs Adreno and Mali hardware, which the manifest notes no +emulator represents. + +The pattern is worth stating rather than leaving to be inferred: the spikes that ran are the ones +whose subject was being built anyway. The ones that did not are the ones that would have said +whether something *should* be built — which is the opposite of the order §9 asks for. + +--- + +## 11. D12, which governs all of the above + +[Decision D12 — scope versus pace](requirements.md) is still **OPEN**, and says: + +> The calibration selected an ambitious feature set — full tablet editing, full ingest, culling as a +> differentiator, complete GPU masking, AI denoise, Fuji-first colour, deep sync, sidecar durability +> — against a stated pace of evenings and weekends, indefinitely. +> +> **Those are not compatible as stated.** + +Sections 1 through 10 are what that incompatibility looks like eleven versions later, and they land +almost exactly where D12 predicted: tablet editing carries SAF at unproven scale, background +execution limits and two GPU vendors to validate (§5), and every one of those is unbuilt or unrun. +The parts that *were* built — the develop pipeline, sync, faces, the catalog — are the parts that +did not need a decision first. + +D12 is not resolved by choosing to work faster. It is resolved by moving requirements across the +line into §7, which costs nothing but the admission, and which this document is intended to make +easy: every cluster above is a candidate, and each says what it would take to build and what it +would cost to drop. Resolving D12 sets D3 and [architecture.md §10](architecture.md)'s Phase 2. From 0d9f802f88a0fb8fa30053cdecdbcea105b88907 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 29 Aug 2026 20:26:07 +0200 Subject: [PATCH 4/5] Regenerate the matrix that this branch is about MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eight requirements gained a tag in this branch's first commit, so the generated matrix is stale until it is rerun. Coverage moves from 59.8% (107/179) to 64.2% (115/179), and the untagged list drops from 72 entries to 64. Regenerating here rather than leaving it to the pre-commit hook, because this branch's subject *is* the matrix: a reader comparing the two commits should see the number move for a stated reason. The eight are R3, R6, FR-DEV-1, FR-UI-6, FR-NC-6d, NFR-OPS-3, NFR-PORT-2 and NFR-SEC-3, and none of them is new work — every one was already satisfied by code that had simply never said so. Six of the thirteen tag sites were new `TRACES:` lines rather than additions to existing ones, so the tag count moves 896 → 902 while the covered count moves by eight. Orphan tags remain at zero. Run from source with `cargo run -p traceability -- report`, never from a prebuilt binary, and note that the tool tracks line numbers — the six prepended module tags shift every subsequent line in their own files, which accounts for the churn in this diff that is not a coverage change. Co-Authored-By: Claude Opus 5 (1M context) --- docs/traceability.md | 76 ++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/docs/traceability.md b/docs/traceability.md index c8ddc26..9fcc95d 100644 --- a/docs/traceability.md +++ b/docs/traceability.md @@ -10,18 +10,18 @@ Denominators are parsed from [`requirements.md`](requirements.md) at run time, n | Metric | Value | |---|---| | Source files scanned | 292 | -| TRACES tags found | 896 | +| TRACES tags found | 902 | | Requirements defined | 179 | -| Requirements covered | 107 | -| **Coverage** | **59.8%** (107/179) | +| Requirements covered | 115 | +| **Coverage** | **64.2%** (115/179) | ### By type | Type | Covered | Defined | |---|---|---| -| FR | 85 | 124 | -| NFR | 20 | 49 | -| R | 2 | 6 | +| FR | 88 | 124 | +| NFR | 23 | 49 | +| R | 4 | 6 | ## Orphan tags @@ -36,48 +36,49 @@ _None._ | FR-CAT-1 | [`core/dr-catalog/src/scan.rs:1`](../core/dr-catalog/src/scan.rs#L1), [`core/dr-catalog/src/walk.rs:109`](../core/dr-catalog/src/walk.rs#L109), [`core/dr-catalog/src/walk.rs:162`](../core/dr-catalog/src/walk.rs#L162), [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-sync/src/scan.rs:93`](../core/dr-sync/src/scan.rs#L93), [`core/dr-types/src/lib.rs:201`](../core/dr-types/src/lib.rs#L201), [`core/dr-types/src/lib.rs:270`](../core/dr-types/src/lib.rs#L270), [`core/dr-types/src/lib.rs:303`](../core/dr-types/src/lib.rs#L303), [`platform/dr-plat/src/storage.rs:1`](../platform/dr-plat/src/storage.rs#L1), [`platform/dr-plat/src/storage.rs:216`](../platform/dr-plat/src/storage.rs#L216), [`tools/traceability/src/lib.rs:479`](../tools/traceability/src/lib.rs#L479), [`tools/traceability/src/lib.rs:511`](../tools/traceability/src/lib.rs#L511), [`ui/dr-ui/src/activity.rs:1`](../ui/dr-ui/src/activity.rs#L1), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1) | | FR-CAT-10 | [`core/dr-ingest/src/layout.rs:1`](../core/dr-ingest/src/layout.rs#L1), [`core/dr-ingest/src/lib.rs:1`](../core/dr-ingest/src/lib.rs#L1), [`core/dr-ingest/src/lib.rs:733`](../core/dr-ingest/src/lib.rs#L733), [`core/dr-types/src/settings.rs:116`](../core/dr-types/src/settings.rs#L116), [`platform/dr-plat/src/storage.rs:287`](../platform/dr-plat/src/storage.rs#L287), [`platform/dr-plat/src/storage.rs:586`](../platform/dr-plat/src/storage.rs#L586), [`platform/dr-plat/src/volumes.rs:1`](../platform/dr-plat/src/volumes.rs#L1), [`platform/dr-plat/src/volumes.rs:62`](../platform/dr-plat/src/volumes.rs#L62), [`ui/dr-ui/src/import.rs:1`](../ui/dr-ui/src/import.rs#L1), [`ui/dr-ui/src/import.rs:336`](../ui/dr-ui/src/import.rs#L336), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1176`](../ui/dr-ui/src/lib.rs#L1176), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5), [`ui/dr-ui/ui/library.slint:1031`](../ui/dr-ui/ui/library.slint#L1031), [`ui/dr-ui/ui/library.slint:1193`](../ui/dr-ui/ui/library.slint#L1193), [`ui/dr-ui/ui/library.slint:866`](../ui/dr-ui/ui/library.slint#L866) | | FR-CAT-11 | [`core/dr-catalog/src/dedup.rs:1`](../core/dr-catalog/src/dedup.rs#L1), [`core/dr-ingest/src/lib.rs:1`](../core/dr-ingest/src/lib.rs#L1), [`core/dr-ingest/src/lib.rs:392`](../core/dr-ingest/src/lib.rs#L392), [`core/dr-sync/src/upload.rs:40`](../core/dr-sync/src/upload.rs#L40), [`ui/dr-ui/src/import.rs:1`](../ui/dr-ui/src/import.rs#L1), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1176`](../ui/dr-ui/src/lib.rs#L1176), [`ui/dr-ui/src/library.rs:162`](../ui/dr-ui/src/library.rs#L162), [`ui/dr-ui/src/library.rs:2375`](../ui/dr-ui/src/library.rs#L2375), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | -| FR-CAT-12 | [`core/dr-pipeline/src/sidecar.rs:118`](../core/dr-pipeline/src/sidecar.rs#L118) | +| FR-CAT-12 | [`core/dr-pipeline/src/sidecar.rs:119`](../core/dr-pipeline/src/sidecar.rs#L119) | | FR-CAT-13 | [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1) | -| FR-CAT-15 | [`core/dr-catalog/src/schema.rs:641`](../core/dr-catalog/src/schema.rs#L641), [`core/dr-catalog/src/trash.rs:1`](../core/dr-catalog/src/trash.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:456`](../core/dr-sync-nextcloud/src/lib.rs#L456), [`core/dr-sync/src/lib.rs:135`](../core/dr-sync/src/lib.rs#L135), [`core/dr-sync/src/scan.rs:429`](../core/dr-sync/src/scan.rs#L429), [`core/dr-sync/src/scan.rs:57`](../core/dr-sync/src/scan.rs#L57), [`core/dr-thumbs/src/lib.rs:376`](../core/dr-thumbs/src/lib.rs#L376), [`ui/dr-ui/src/collections_ui.rs:1219`](../ui/dr-ui/src/collections_ui.rs#L1219), [`ui/dr-ui/src/collections_ui.rs:1975`](../ui/dr-ui/src/collections_ui.rs#L1975), [`ui/dr-ui/src/library.rs:162`](../ui/dr-ui/src/library.rs#L162), [`ui/dr-ui/src/library.rs:179`](../ui/dr-ui/src/library.rs#L179), [`ui/dr-ui/src/library.rs:208`](../ui/dr-ui/src/library.rs#L208), [`ui/dr-ui/src/library.rs:3869`](../ui/dr-ui/src/library.rs#L3869), [`ui/dr-ui/src/library.rs:3903`](../ui/dr-ui/src/library.rs#L3903), [`ui/dr-ui/src/library_ui.rs:190`](../ui/dr-ui/src/library_ui.rs#L190), [`ui/dr-ui/src/library_ui.rs:756`](../ui/dr-ui/src/library_ui.rs#L756), [`ui/dr-ui/src/trash.rs:1`](../ui/dr-ui/src/trash.rs#L1), [`ui/dr-ui/ui/collections.slint:572`](../ui/dr-ui/ui/collections.slint#L572) | +| FR-CAT-15 | [`core/dr-catalog/src/schema.rs:641`](../core/dr-catalog/src/schema.rs#L641), [`core/dr-catalog/src/trash.rs:1`](../core/dr-catalog/src/trash.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:457`](../core/dr-sync-nextcloud/src/lib.rs#L457), [`core/dr-sync/src/lib.rs:135`](../core/dr-sync/src/lib.rs#L135), [`core/dr-sync/src/scan.rs:429`](../core/dr-sync/src/scan.rs#L429), [`core/dr-sync/src/scan.rs:57`](../core/dr-sync/src/scan.rs#L57), [`core/dr-thumbs/src/lib.rs:376`](../core/dr-thumbs/src/lib.rs#L376), [`ui/dr-ui/src/collections_ui.rs:1219`](../ui/dr-ui/src/collections_ui.rs#L1219), [`ui/dr-ui/src/collections_ui.rs:1975`](../ui/dr-ui/src/collections_ui.rs#L1975), [`ui/dr-ui/src/library.rs:162`](../ui/dr-ui/src/library.rs#L162), [`ui/dr-ui/src/library.rs:179`](../ui/dr-ui/src/library.rs#L179), [`ui/dr-ui/src/library.rs:208`](../ui/dr-ui/src/library.rs#L208), [`ui/dr-ui/src/library.rs:3869`](../ui/dr-ui/src/library.rs#L3869), [`ui/dr-ui/src/library.rs:3903`](../ui/dr-ui/src/library.rs#L3903), [`ui/dr-ui/src/library_ui.rs:190`](../ui/dr-ui/src/library_ui.rs#L190), [`ui/dr-ui/src/library_ui.rs:756`](../ui/dr-ui/src/library_ui.rs#L756), [`ui/dr-ui/src/trash.rs:1`](../ui/dr-ui/src/trash.rs#L1), [`ui/dr-ui/ui/collections.slint:572`](../ui/dr-ui/ui/collections.slint#L572) | | FR-CAT-1a | [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-types/src/lib.rs:54`](../core/dr-types/src/lib.rs#L54), [`platform/dr-plat/src/storage.rs:1`](../platform/dr-plat/src/storage.rs#L1), [`platform/dr-plat/src/storage.rs:216`](../platform/dr-plat/src/storage.rs#L216), [`platform/dr-plat/src/storage.rs:46`](../platform/dr-plat/src/storage.rs#L46) | | FR-CAT-2 | [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/schema.rs:1`](../core/dr-catalog/src/schema.rs#L1), [`tools/traceability/src/lib.rs:479`](../tools/traceability/src/lib.rs#L479) | | FR-CAT-3 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`core/dr-catalog/src/walk.rs:66`](../core/dr-catalog/src/walk.rs#L66), [`core/dr-sync/src/scan.rs:69`](../core/dr-sync/src/scan.rs#L69), [`core/dr-thumbs/src/codec.rs:1`](../core/dr-thumbs/src/codec.rs#L1), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/import.rs:463`](../ui/dr-ui/src/import.rs#L463), [`ui/dr-ui/src/import.rs:488`](../ui/dr-ui/src/import.rs#L488), [`ui/dr-ui/src/library.rs:2848`](../ui/dr-ui/src/library.rs#L2848), [`ui/dr-ui/src/library.rs:3356`](../ui/dr-ui/src/library.rs#L3356), [`ui/dr-ui/src/library_ui.rs:172`](../ui/dr-ui/src/library_ui.rs#L172), [`ui/dr-ui/src/library_ui.rs:3627`](../ui/dr-ui/src/library_ui.rs#L3627), [`ui/dr-ui/src/library_ui.rs:4592`](../ui/dr-ui/src/library_ui.rs#L4592), [`ui/dr-ui/ui/app.slint:348`](../ui/dr-ui/ui/app.slint#L348), [`ui/dr-ui/ui/settings.slint:384`](../ui/dr-ui/ui/settings.slint#L384), [`ui/dr-ui/ui/settings.slint:72`](../ui/dr-ui/ui/settings.slint#L72) | | FR-CAT-4 | [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/query.rs:1`](../core/dr-catalog/src/query.rs#L1), [`core/dr-catalog/src/schema.rs:318`](../core/dr-catalog/src/schema.rs#L318), [`ui/dr-ui/src/library.rs:189`](../ui/dr-ui/src/library.rs#L189), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1) | -| FR-CAT-5 | [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1), [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-catalog/src/schema.rs:1059`](../core/dr-catalog/src/schema.rs#L1059), [`core/dr-catalog/src/schema.rs:556`](../core/dr-catalog/src/schema.rs#L556), [`core/dr-decode/src/lib.rs:285`](../core/dr-decode/src/lib.rs#L285), [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-pipeline/src/sidecar.rs:135`](../core/dr-pipeline/src/sidecar.rs#L135), [`ui/dr-ui/src/collections_ui.rs:1558`](../ui/dr-ui/src/collections_ui.rs#L1558), [`ui/dr-ui/src/collections_ui.rs:1577`](../ui/dr-ui/src/collections_ui.rs#L1577), [`ui/dr-ui/src/collections_ui.rs:243`](../ui/dr-ui/src/collections_ui.rs#L243), [`ui/dr-ui/src/collections_ui.rs:340`](../ui/dr-ui/src/collections_ui.rs#L340), [`ui/dr-ui/src/collections_ui.rs:89`](../ui/dr-ui/src/collections_ui.rs#L89), [`ui/dr-ui/src/library.rs:3917`](../ui/dr-ui/src/library.rs#L3917), [`ui/dr-ui/src/library_ui.rs:631`](../ui/dr-ui/src/library_ui.rs#L631), [`ui/dr-ui/src/library_ui.rs:6389`](../ui/dr-ui/src/library_ui.rs#L6389), [`ui/dr-ui/src/library_ui.rs:6400`](../ui/dr-ui/src/library_ui.rs#L6400), [`ui/dr-ui/src/library_ui.rs:6413`](../ui/dr-ui/src/library_ui.rs#L6413), [`ui/dr-ui/src/library_ui.rs:6428`](../ui/dr-ui/src/library_ui.rs#L6428), [`ui/dr-ui/src/library_ui.rs:6437`](../ui/dr-ui/src/library_ui.rs#L6437), [`ui/dr-ui/ui/app.slint:293`](../ui/dr-ui/ui/app.slint#L293), [`ui/dr-ui/ui/app.slint:474`](../ui/dr-ui/ui/app.slint#L474), [`ui/dr-ui/ui/library.slint:1242`](../ui/dr-ui/ui/library.slint#L1242), [`ui/dr-ui/ui/library.slint:1245`](../ui/dr-ui/ui/library.slint#L1245), [`ui/dr-ui/ui/library.slint:18`](../ui/dr-ui/ui/library.slint#L18), [`ui/dr-ui/ui/library.slint:859`](../ui/dr-ui/ui/library.slint#L859), [`ui/dr-ui/ui/library.slint:911`](../ui/dr-ui/ui/library.slint#L911) | +| FR-CAT-5 | [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1), [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-catalog/src/schema.rs:1059`](../core/dr-catalog/src/schema.rs#L1059), [`core/dr-catalog/src/schema.rs:556`](../core/dr-catalog/src/schema.rs#L556), [`core/dr-decode/src/lib.rs:285`](../core/dr-decode/src/lib.rs#L285), [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-pipeline/src/sidecar.rs:136`](../core/dr-pipeline/src/sidecar.rs#L136), [`ui/dr-ui/src/collections_ui.rs:1558`](../ui/dr-ui/src/collections_ui.rs#L1558), [`ui/dr-ui/src/collections_ui.rs:1577`](../ui/dr-ui/src/collections_ui.rs#L1577), [`ui/dr-ui/src/collections_ui.rs:243`](../ui/dr-ui/src/collections_ui.rs#L243), [`ui/dr-ui/src/collections_ui.rs:340`](../ui/dr-ui/src/collections_ui.rs#L340), [`ui/dr-ui/src/collections_ui.rs:89`](../ui/dr-ui/src/collections_ui.rs#L89), [`ui/dr-ui/src/library.rs:3917`](../ui/dr-ui/src/library.rs#L3917), [`ui/dr-ui/src/library_ui.rs:631`](../ui/dr-ui/src/library_ui.rs#L631), [`ui/dr-ui/src/library_ui.rs:6389`](../ui/dr-ui/src/library_ui.rs#L6389), [`ui/dr-ui/src/library_ui.rs:6400`](../ui/dr-ui/src/library_ui.rs#L6400), [`ui/dr-ui/src/library_ui.rs:6413`](../ui/dr-ui/src/library_ui.rs#L6413), [`ui/dr-ui/src/library_ui.rs:6428`](../ui/dr-ui/src/library_ui.rs#L6428), [`ui/dr-ui/src/library_ui.rs:6437`](../ui/dr-ui/src/library_ui.rs#L6437), [`ui/dr-ui/ui/app.slint:293`](../ui/dr-ui/ui/app.slint#L293), [`ui/dr-ui/ui/app.slint:474`](../ui/dr-ui/ui/app.slint#L474), [`ui/dr-ui/ui/library.slint:1242`](../ui/dr-ui/ui/library.slint#L1242), [`ui/dr-ui/ui/library.slint:1245`](../ui/dr-ui/ui/library.slint#L1245), [`ui/dr-ui/ui/library.slint:18`](../ui/dr-ui/ui/library.slint#L18), [`ui/dr-ui/ui/library.slint:859`](../ui/dr-ui/ui/library.slint#L859), [`ui/dr-ui/ui/library.slint:911`](../ui/dr-ui/ui/library.slint#L911) | | FR-CAT-6 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.rs#L1), [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1), [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/query.rs:1`](../core/dr-catalog/src/query.rs#L1), [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-catalog/src/schema.rs:556`](../core/dr-catalog/src/schema.rs#L556), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`core/dr-types/src/settings.rs:63`](../core/dr-types/src/settings.rs#L63), [`core/dr-types/src/time.rs:67`](../core/dr-types/src/time.rs#L67), [`core/dr-types/src/time.rs:90`](../core/dr-types/src/time.rs#L90), [`ui/dr-ui/src/library.rs:213`](../ui/dr-ui/src/library.rs#L213), [`ui/dr-ui/src/library.rs:4163`](../ui/dr-ui/src/library.rs#L4163), [`ui/dr-ui/src/library_ui.rs:321`](../ui/dr-ui/src/library_ui.rs#L321), [`ui/dr-ui/src/library_ui.rs:393`](../ui/dr-ui/src/library_ui.rs#L393), [`ui/dr-ui/src/library_ui.rs:5203`](../ui/dr-ui/src/library_ui.rs#L5203), [`ui/dr-ui/src/library_ui.rs:5256`](../ui/dr-ui/src/library_ui.rs#L5256), [`ui/dr-ui/src/library_ui.rs:6529`](../ui/dr-ui/src/library_ui.rs#L6529), [`ui/dr-ui/ui/app.slint:296`](../ui/dr-ui/ui/app.slint#L296), [`ui/dr-ui/ui/app.slint:474`](../ui/dr-ui/ui/app.slint#L474), [`ui/dr-ui/ui/app.slint:748`](../ui/dr-ui/ui/app.slint#L748), [`ui/dr-ui/ui/library.slint:109`](../ui/dr-ui/ui/library.slint#L109), [`ui/dr-ui/ui/library.slint:1318`](../ui/dr-ui/ui/library.slint#L1318), [`ui/dr-ui/ui/library.slint:911`](../ui/dr-ui/ui/library.slint#L911), [`ui/dr-ui/ui/settings.slint:147`](../ui/dr-ui/ui/settings.slint#L147) | | FR-CAT-7 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.rs#L1), [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/sync.rs:1`](../core/dr-catalog/src/sync.rs#L1), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`ui/dr-ui/src/collections_ui.rs:1673`](../ui/dr-ui/src/collections_ui.rs#L1673), [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/library_ui.rs:3489`](../ui/dr-ui/src/library_ui.rs#L3489), [`ui/dr-ui/src/library_ui.rs:4182`](../ui/dr-ui/src/library_ui.rs#L4182), [`ui/dr-ui/ui/app.slint:469`](../ui/dr-ui/ui/app.slint#L469), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/library.slint:2585`](../ui/dr-ui/ui/library.slint#L2585), [`ui/dr-ui/ui/library.slint:882`](../ui/dr-ui/ui/library.slint#L882), [`ui/dr-ui/ui/library.slint:901`](../ui/dr-ui/ui/library.slint#L901) | -| FR-CAT-8 | [`core/dr-pipeline/src/graph.rs:345`](../core/dr-pipeline/src/graph.rs#L345), [`core/dr-pipeline/src/graph.rs:384`](../core/dr-pipeline/src/graph.rs#L384), [`core/dr-pipeline/src/ops/curve.rs:137`](../core/dr-pipeline/src/ops/curve.rs#L137), [`core/dr-pipeline/src/ops/curve.rs:656`](../core/dr-pipeline/src/ops/curve.rs#L656), [`core/dr-pipeline/src/sidecar.rs:1636`](../core/dr-pipeline/src/sidecar.rs#L1636), [`core/dr-pipeline/src/sidecar.rs:92`](../core/dr-pipeline/src/sidecar.rs#L92), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`core/dr-pipeline/tests/tone_curve.rs:34`](../core/dr-pipeline/tests/tone_curve.rs#L34), [`ui/dr-ui/src/develop.rs:3570`](../ui/dr-ui/src/develop.rs#L3570), [`ui/dr-ui/src/develop.rs:3599`](../ui/dr-ui/src/develop.rs#L3599), [`ui/dr-ui/src/export.rs:750`](../ui/dr-ui/src/export.rs#L750), [`ui/dr-ui/src/lib.rs:1429`](../ui/dr-ui/src/lib.rs#L1429), [`ui/dr-ui/src/lib.rs:1830`](../ui/dr-ui/src/lib.rs#L1830), [`ui/dr-ui/src/lib.rs:1965`](../ui/dr-ui/src/lib.rs#L1965), [`ui/dr-ui/src/lib.rs:554`](../ui/dr-ui/src/lib.rs#L554), [`ui/dr-ui/src/lib.rs:979`](../ui/dr-ui/src/lib.rs#L979), [`ui/dr-ui/src/library.rs:1787`](../ui/dr-ui/src/library.rs#L1787), [`ui/dr-ui/src/library.rs:459`](../ui/dr-ui/src/library.rs#L459), [`ui/dr-ui/src/library.rs:506`](../ui/dr-ui/src/library.rs#L506), [`ui/dr-ui/src/library.rs:543`](../ui/dr-ui/src/library.rs#L543), [`ui/dr-ui/src/library.rs:790`](../ui/dr-ui/src/library.rs#L790), [`ui/dr-ui/src/library_ui.rs:4884`](../ui/dr-ui/src/library_ui.rs#L4884), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | +| FR-CAT-8 | [`core/dr-pipeline/src/graph.rs:346`](../core/dr-pipeline/src/graph.rs#L346), [`core/dr-pipeline/src/graph.rs:385`](../core/dr-pipeline/src/graph.rs#L385), [`core/dr-pipeline/src/ops/curve.rs:137`](../core/dr-pipeline/src/ops/curve.rs#L137), [`core/dr-pipeline/src/ops/curve.rs:656`](../core/dr-pipeline/src/ops/curve.rs#L656), [`core/dr-pipeline/src/sidecar.rs:1637`](../core/dr-pipeline/src/sidecar.rs#L1637), [`core/dr-pipeline/src/sidecar.rs:93`](../core/dr-pipeline/src/sidecar.rs#L93), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`core/dr-pipeline/tests/tone_curve.rs:34`](../core/dr-pipeline/tests/tone_curve.rs#L34), [`ui/dr-ui/src/develop.rs:3570`](../ui/dr-ui/src/develop.rs#L3570), [`ui/dr-ui/src/develop.rs:3599`](../ui/dr-ui/src/develop.rs#L3599), [`ui/dr-ui/src/export.rs:750`](../ui/dr-ui/src/export.rs#L750), [`ui/dr-ui/src/lib.rs:1429`](../ui/dr-ui/src/lib.rs#L1429), [`ui/dr-ui/src/lib.rs:1830`](../ui/dr-ui/src/lib.rs#L1830), [`ui/dr-ui/src/lib.rs:1965`](../ui/dr-ui/src/lib.rs#L1965), [`ui/dr-ui/src/lib.rs:554`](../ui/dr-ui/src/lib.rs#L554), [`ui/dr-ui/src/lib.rs:979`](../ui/dr-ui/src/lib.rs#L979), [`ui/dr-ui/src/library.rs:1787`](../ui/dr-ui/src/library.rs#L1787), [`ui/dr-ui/src/library.rs:459`](../ui/dr-ui/src/library.rs#L459), [`ui/dr-ui/src/library.rs:506`](../ui/dr-ui/src/library.rs#L506), [`ui/dr-ui/src/library.rs:543`](../ui/dr-ui/src/library.rs#L543), [`ui/dr-ui/src/library.rs:790`](../ui/dr-ui/src/library.rs#L790), [`ui/dr-ui/src/library_ui.rs:4884`](../ui/dr-ui/src/library_ui.rs#L4884), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | | FR-CAT-9 | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/scan.rs:1`](../core/dr-catalog/src/scan.rs#L1), [`core/dr-catalog/src/schema.rs:613`](../core/dr-catalog/src/schema.rs#L613), [`core/dr-catalog/src/walk.rs:162`](../core/dr-catalog/src/walk.rs#L162), [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-catalog/src/walk.rs:435`](../core/dr-catalog/src/walk.rs#L435), [`core/dr-catalog/src/walk.rs:704`](../core/dr-catalog/src/walk.rs#L704), [`core/dr-sync-nextcloud/src/desktop_client.rs:30`](../core/dr-sync-nextcloud/src/desktop_client.rs#L30), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`core/dr-types/src/lib.rs:120`](../core/dr-types/src/lib.rs#L120), [`ui/dr-ui/src/develop.rs:2997`](../ui/dr-ui/src/develop.rs#L2997), [`ui/dr-ui/src/library.rs:148`](../ui/dr-ui/src/library.rs#L148), [`ui/dr-ui/src/library.rs:1747`](../ui/dr-ui/src/library.rs#L1747), [`ui/dr-ui/src/library.rs:1823`](../ui/dr-ui/src/library.rs#L1823), [`ui/dr-ui/src/library.rs:233`](../ui/dr-ui/src/library.rs#L233), [`ui/dr-ui/src/library.rs:4270`](../ui/dr-ui/src/library.rs#L4270), [`ui/dr-ui/src/library.rs:543`](../ui/dr-ui/src/library.rs#L543), [`ui/dr-ui/src/library.rs:774`](../ui/dr-ui/src/library.rs#L774), [`ui/dr-ui/src/library.rs:790`](../ui/dr-ui/src/library.rs#L790), [`ui/dr-ui/src/library.rs:844`](../ui/dr-ui/src/library.rs#L844), [`ui/dr-ui/src/library_ui.rs:1580`](../ui/dr-ui/src/library_ui.rs#L1580), [`ui/dr-ui/src/library_ui.rs:1606`](../ui/dr-ui/src/library_ui.rs#L1606), [`ui/dr-ui/src/library_ui.rs:1622`](../ui/dr-ui/src/library_ui.rs#L1622), [`ui/dr-ui/src/library_ui.rs:1716`](../ui/dr-ui/src/library_ui.rs#L1716), [`ui/dr-ui/src/library_ui.rs:232`](../ui/dr-ui/src/library_ui.rs#L232), [`ui/dr-ui/src/library_ui.rs:2332`](../ui/dr-ui/src/library_ui.rs#L2332), [`ui/dr-ui/src/library_ui.rs:265`](../ui/dr-ui/src/library_ui.rs#L265), [`ui/dr-ui/src/library_ui.rs:2770`](../ui/dr-ui/src/library_ui.rs#L2770), [`ui/dr-ui/src/library_ui.rs:2992`](../ui/dr-ui/src/library_ui.rs#L2992), [`ui/dr-ui/src/library_ui.rs:3270`](../ui/dr-ui/src/library_ui.rs#L3270), [`ui/dr-ui/src/library_ui.rs:3358`](../ui/dr-ui/src/library_ui.rs#L3358), [`ui/dr-ui/src/library_ui.rs:3540`](../ui/dr-ui/src/library_ui.rs#L3540), [`ui/dr-ui/src/library_ui.rs:3654`](../ui/dr-ui/src/library_ui.rs#L3654), [`ui/dr-ui/src/library_ui.rs:446`](../ui/dr-ui/src/library_ui.rs#L446), [`ui/dr-ui/src/library_ui.rs:504`](../ui/dr-ui/src/library_ui.rs#L504), [`ui/dr-ui/src/library_ui.rs:5301`](../ui/dr-ui/src/library_ui.rs#L5301), [`ui/dr-ui/src/library_ui.rs:5416`](../ui/dr-ui/src/library_ui.rs#L5416), [`ui/dr-ui/src/presets.rs:337`](../ui/dr-ui/src/presets.rs#L337), [`ui/dr-ui/src/presets.rs:349`](../ui/dr-ui/src/presets.rs#L349), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | | FR-CULL-1 | [`core/dr-decode/src/preview.rs:121`](../core/dr-decode/src/preview.rs#L121) | | FR-CULL-10 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:357`](../core/dr-catalog/src/schema.rs#L357), [`core/dr-catalog/src/schema.rs:442`](../core/dr-catalog/src/schema.rs#L442), [`core/dr-face/src/assign.rs:1`](../core/dr-face/src/assign.rs#L1), [`core/dr-face/src/neighbours.rs:1`](../core/dr-face/src/neighbours.rs#L1), [`ui/dr-ui/src/develop.rs:119`](../ui/dr-ui/src/develop.rs#L119), [`ui/dr-ui/src/develop.rs:128`](../ui/dr-ui/src/develop.rs#L128), [`ui/dr-ui/src/develop.rs:1920`](../ui/dr-ui/src/develop.rs#L1920), [`ui/dr-ui/src/develop.rs:194`](../ui/dr-ui/src/develop.rs#L194), [`ui/dr-ui/src/develop.rs:687`](../ui/dr-ui/src/develop.rs#L687), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1937`](../ui/dr-ui/src/lib.rs#L1937), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-11 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:442`](../core/dr-catalog/src/schema.rs#L442), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/library.rs:254`](../ui/dr-ui/src/library.rs#L254), [`ui/dr-ui/src/library.rs:284`](../ui/dr-ui/src/library.rs#L284), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-12 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:357`](../core/dr-catalog/src/schema.rs#L357), [`core/dr-catalog/src/schema.rs:442`](../core/dr-catalog/src/schema.rs#L442), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-2 | [`core/dr-decode/src/locate.rs:1`](../core/dr-decode/src/locate.rs#L1), [`core/dr-decode/src/preview.rs:148`](../core/dr-decode/src/preview.rs#L148), [`ui/dr-ui/src/import.rs:463`](../ui/dr-ui/src/import.rs#L463) | -| FR-CULL-4 | [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-pipeline/src/sidecar.rs:135`](../core/dr-pipeline/src/sidecar.rs#L135), [`ui/dr-ui/src/library.rs:213`](../ui/dr-ui/src/library.rs#L213), [`ui/dr-ui/src/library.rs:459`](../ui/dr-ui/src/library.rs#L459) | +| FR-CULL-4 | [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-pipeline/src/sidecar.rs:136`](../core/dr-pipeline/src/sidecar.rs#L136), [`ui/dr-ui/src/library.rs:213`](../ui/dr-ui/src/library.rs#L213), [`ui/dr-ui/src/library.rs:459`](../ui/dr-ui/src/library.rs#L459) | | FR-CULL-8 | [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:401`](../core/dr-catalog/src/schema.rs#L401), [`core/dr-catalog/src/schema.rs:442`](../core/dr-catalog/src/schema.rs#L442), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/library.rs:2849`](../ui/dr-ui/src/library.rs#L2849), [`ui/dr-ui/src/library.rs:2953`](../ui/dr-ui/src/library.rs#L2953), [`ui/dr-ui/ui/settings.slint:416`](../ui/dr-ui/ui/settings.slint#L416), [`ui/dr-ui/ui/settings.slint:81`](../ui/dr-ui/ui/settings.slint#L81) | | FR-CULL-9 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:442`](../core/dr-catalog/src/schema.rs#L442), [`core/dr-face/src/assign.rs:1`](../core/dr-face/src/assign.rs#L1), [`core/dr-face/src/neighbours.rs:1`](../core/dr-face/src/neighbours.rs#L1), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1) | +| FR-DEV-1 | [`core/dr-pipeline/src/graph.rs:1`](../core/dr-pipeline/src/graph.rs#L1), [`core/dr-pipeline/src/sidecar.rs:1`](../core/dr-pipeline/src/sidecar.rs#L1) | | FR-DEV-2 | [`core/dr-pipeline/src/operation.rs:389`](../core/dr-pipeline/src/operation.rs#L389) | -| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2165`](../core/dr-gpu/src/adjust.rs#L2165), [`core/dr-gpu/src/adjust.rs:651`](../core/dr-gpu/src/adjust.rs#L651), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/tests/tone_curve.rs:1`](../core/dr-gpu/tests/tone_curve.rs#L1), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/framing.rs:177`](../core/dr-pipeline/src/framing.rs#L177), [`core/dr-pipeline/src/framing.rs:234`](../core/dr-pipeline/src/framing.rs#L234), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-pipeline/src/framing.rs:743`](../core/dr-pipeline/src/framing.rs#L743), [`core/dr-pipeline/src/graph.rs:169`](../core/dr-pipeline/src/graph.rs#L169), [`core/dr-pipeline/src/graph.rs:577`](../core/dr-pipeline/src/graph.rs#L577), [`core/dr-pipeline/src/mask.rs:121`](../core/dr-pipeline/src/mask.rs#L121), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:516`](../core/dr-pipeline/src/operation.rs#L516), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:210`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L210), [`core/dr-pipeline/src/ops/curve.rs:100`](../core/dr-pipeline/src/ops/curve.rs#L100), [`core/dr-pipeline/src/ops/curve.rs:1`](../core/dr-pipeline/src/ops/curve.rs#L1), [`core/dr-pipeline/src/ops/curve.rs:219`](../core/dr-pipeline/src/ops/curve.rs#L219), [`core/dr-pipeline/src/ops/curve.rs:635`](../core/dr-pipeline/src/ops/curve.rs#L635), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:1`](../core/dr-pipeline/src/ops/noise_reduction.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:273`](../core/dr-pipeline/src/ops/noise_reduction.rs#L273), [`core/dr-pipeline/src/sidecar.rs:156`](../core/dr-pipeline/src/sidecar.rs#L156), [`core/dr-pipeline/src/sidecar.rs:1636`](../core/dr-pipeline/src/sidecar.rs#L1636), [`core/dr-pipeline/src/sidecar.rs:1696`](../core/dr-pipeline/src/sidecar.rs#L1696), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`ui/dr-ui/src/develop.rs:101`](../ui/dr-ui/src/develop.rs#L101), [`ui/dr-ui/src/develop.rs:1424`](../ui/dr-ui/src/develop.rs#L1424), [`ui/dr-ui/src/develop.rs:163`](../ui/dr-ui/src/develop.rs#L163), [`ui/dr-ui/src/develop.rs:1902`](../ui/dr-ui/src/develop.rs#L1902), [`ui/dr-ui/src/develop.rs:1920`](../ui/dr-ui/src/develop.rs#L1920), [`ui/dr-ui/src/develop.rs:1934`](../ui/dr-ui/src/develop.rs#L1934), [`ui/dr-ui/src/develop.rs:1956`](../ui/dr-ui/src/develop.rs#L1956), [`ui/dr-ui/src/develop.rs:2102`](../ui/dr-ui/src/develop.rs#L2102), [`ui/dr-ui/src/develop.rs:2200`](../ui/dr-ui/src/develop.rs#L2200), [`ui/dr-ui/src/develop.rs:3268`](../ui/dr-ui/src/develop.rs#L3268), [`ui/dr-ui/src/develop.rs:326`](../ui/dr-ui/src/develop.rs#L326), [`ui/dr-ui/src/develop.rs:3298`](../ui/dr-ui/src/develop.rs#L3298), [`ui/dr-ui/src/develop.rs:3364`](../ui/dr-ui/src/develop.rs#L3364), [`ui/dr-ui/src/develop.rs:3378`](../ui/dr-ui/src/develop.rs#L3378), [`ui/dr-ui/src/develop.rs:3570`](../ui/dr-ui/src/develop.rs#L3570), [`ui/dr-ui/src/develop.rs:363`](../ui/dr-ui/src/develop.rs#L363), [`ui/dr-ui/src/develop.rs:4230`](../ui/dr-ui/src/develop.rs#L4230), [`ui/dr-ui/src/develop.rs:4284`](../ui/dr-ui/src/develop.rs#L4284), [`ui/dr-ui/src/develop.rs:4328`](../ui/dr-ui/src/develop.rs#L4328), [`ui/dr-ui/src/develop.rs:4378`](../ui/dr-ui/src/develop.rs#L4378), [`ui/dr-ui/src/develop.rs:586`](../ui/dr-ui/src/develop.rs#L586), [`ui/dr-ui/src/develop.rs:647`](../ui/dr-ui/src/develop.rs#L647), [`ui/dr-ui/src/develop.rs:726`](../ui/dr-ui/src/develop.rs#L726), [`ui/dr-ui/src/develop.rs:773`](../ui/dr-ui/src/develop.rs#L773), [`ui/dr-ui/src/develop.rs:802`](../ui/dr-ui/src/develop.rs#L802), [`ui/dr-ui/src/lib.rs:1514`](../ui/dr-ui/src/lib.rs#L1514), [`ui/dr-ui/src/lib.rs:2233`](../ui/dr-ui/src/lib.rs#L2233), [`ui/dr-ui/src/lib.rs:2429`](../ui/dr-ui/src/lib.rs#L2429), [`ui/dr-ui/src/lib.rs:2601`](../ui/dr-ui/src/lib.rs#L2601), [`ui/dr-ui/src/lib.rs:2665`](../ui/dr-ui/src/lib.rs#L2665), [`ui/dr-ui/src/lib.rs:2719`](../ui/dr-ui/src/lib.rs#L2719), [`ui/dr-ui/src/lib.rs:320`](../ui/dr-ui/src/lib.rs#L320), [`ui/dr-ui/src/lib.rs:363`](../ui/dr-ui/src/lib.rs#L363), [`ui/dr-ui/src/lib.rs:386`](../ui/dr-ui/src/lib.rs#L386), [`ui/dr-ui/src/library.rs:506`](../ui/dr-ui/src/library.rs#L506), [`ui/dr-ui/src/masks_ui.rs:218`](../ui/dr-ui/src/masks_ui.rs#L218), [`ui/dr-ui/src/masks_ui.rs:41`](../ui/dr-ui/src/masks_ui.rs#L41), [`ui/dr-ui/src/masks_ui.rs:816`](../ui/dr-ui/src/masks_ui.rs#L816), [`ui/dr-ui/src/masks_ui.rs:930`](../ui/dr-ui/src/masks_ui.rs#L930), [`ui/dr-ui/src/segmentation.rs:219`](../ui/dr-ui/src/segmentation.rs#L219), [`ui/dr-ui/src/segmentation.rs:322`](../ui/dr-ui/src/segmentation.rs#L322), [`ui/dr-ui/src/segmentation.rs:350`](../ui/dr-ui/src/segmentation.rs#L350), [`ui/dr-ui/ui/adjust.slint:517`](../ui/dr-ui/ui/adjust.slint#L517), [`ui/dr-ui/ui/adjust.slint:635`](../ui/dr-ui/ui/adjust.slint#L635), [`ui/dr-ui/ui/app.slint:119`](../ui/dr-ui/ui/app.slint#L119), [`ui/dr-ui/ui/app.slint:165`](../ui/dr-ui/ui/app.slint#L165), [`ui/dr-ui/ui/app.slint:1849`](../ui/dr-ui/ui/app.slint#L1849), [`ui/dr-ui/ui/app.slint:858`](../ui/dr-ui/ui/app.slint#L858), [`ui/dr-ui/ui/masks.slint:490`](../ui/dr-ui/ui/masks.slint#L490) | -| FR-DEV-3a | [`core/dr-pipeline/build.rs:756`](../core/dr-pipeline/build.rs#L756), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/descriptor.rs:194`](../core/dr-pipeline/src/descriptor.rs#L194), [`core/dr-pipeline/src/descriptor.rs:234`](../core/dr-pipeline/src/descriptor.rs#L234), [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/descriptor.rs:313`](../core/dr-pipeline/src/descriptor.rs#L313), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:23`](../core/dr-pipeline/src/graph.rs#L23), [`core/dr-pipeline/src/graph.rs:250`](../core/dr-pipeline/src/graph.rs#L250), [`core/dr-pipeline/src/graph.rs:45`](../core/dr-pipeline/src/graph.rs#L45), [`core/dr-pipeline/src/graph.rs:58`](../core/dr-pipeline/src/graph.rs#L58), [`core/dr-pipeline/src/mask.rs:955`](../core/dr-pipeline/src/mask.rs#L955), [`core/dr-pipeline/src/operation.rs:232`](../core/dr-pipeline/src/operation.rs#L232), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365), [`core/dr-pipeline/src/ops/curve.rs:319`](../core/dr-pipeline/src/ops/curve.rs#L319), [`ui/dr-ui/src/develop.rs:1321`](../ui/dr-ui/src/develop.rs#L1321), [`ui/dr-ui/src/lib.rs:669`](../ui/dr-ui/src/lib.rs#L669), [`ui/dr-ui/tests/ui_names_no_operation.rs:1`](../ui/dr-ui/tests/ui_names_no_operation.rs#L1) | -| FR-DEV-3b | [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:58`](../core/dr-pipeline/src/graph.rs#L58), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365) | -| FR-DEV-3c | [`core/dr-pipeline/build.rs:756`](../core/dr-pipeline/build.rs#L756), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:250`](../core/dr-pipeline/src/graph.rs#L250), [`core/dr-pipeline/src/graph.rs:45`](../core/dr-pipeline/src/graph.rs#L45), [`core/dr-pipeline/src/mask.rs:955`](../core/dr-pipeline/src/mask.rs#L955), [`ui/dr-ui/src/develop.rs:4957`](../ui/dr-ui/src/develop.rs#L4957) | -| FR-DEV-3d | [`core/dr-gpu/src/adjust.rs:1041`](../core/dr-gpu/src/adjust.rs#L1041), [`core/dr-gpu/src/adjust.rs:104`](../core/dr-gpu/src/adjust.rs#L104), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/src/adjust.rs:986`](../core/dr-gpu/src/adjust.rs#L986), [`core/dr-gpu/tests/capture_sharpen.rs:434`](../core/dr-gpu/tests/capture_sharpen.rs#L434), [`core/dr-gpu/tests/detail_stage.rs:242`](../core/dr-gpu/tests/detail_stage.rs#L242), [`core/dr-gpu/tests/local_contrast.rs:558`](../core/dr-gpu/tests/local_contrast.rs#L558), [`core/dr-gpu/tests/noise_reduction.rs:556`](../core/dr-gpu/tests/noise_reduction.rs#L556), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/graph.rs:616`](../core/dr-pipeline/src/graph.rs#L616), [`core/dr-pipeline/src/operation.rs:32`](../core/dr-pipeline/src/operation.rs#L32), [`core/dr-pipeline/src/operation.rs:389`](../core/dr-pipeline/src/operation.rs#L389), [`core/dr-pipeline/src/operation.rs:53`](../core/dr-pipeline/src/operation.rs#L53), [`core/dr-pipeline/src/operation.rs:71`](../core/dr-pipeline/src/operation.rs#L71) | +| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2165`](../core/dr-gpu/src/adjust.rs#L2165), [`core/dr-gpu/src/adjust.rs:651`](../core/dr-gpu/src/adjust.rs#L651), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/tests/tone_curve.rs:1`](../core/dr-gpu/tests/tone_curve.rs#L1), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/framing.rs:177`](../core/dr-pipeline/src/framing.rs#L177), [`core/dr-pipeline/src/framing.rs:234`](../core/dr-pipeline/src/framing.rs#L234), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-pipeline/src/framing.rs:743`](../core/dr-pipeline/src/framing.rs#L743), [`core/dr-pipeline/src/graph.rs:170`](../core/dr-pipeline/src/graph.rs#L170), [`core/dr-pipeline/src/graph.rs:578`](../core/dr-pipeline/src/graph.rs#L578), [`core/dr-pipeline/src/mask.rs:121`](../core/dr-pipeline/src/mask.rs#L121), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:516`](../core/dr-pipeline/src/operation.rs#L516), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:210`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L210), [`core/dr-pipeline/src/ops/curve.rs:100`](../core/dr-pipeline/src/ops/curve.rs#L100), [`core/dr-pipeline/src/ops/curve.rs:1`](../core/dr-pipeline/src/ops/curve.rs#L1), [`core/dr-pipeline/src/ops/curve.rs:219`](../core/dr-pipeline/src/ops/curve.rs#L219), [`core/dr-pipeline/src/ops/curve.rs:635`](../core/dr-pipeline/src/ops/curve.rs#L635), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:1`](../core/dr-pipeline/src/ops/noise_reduction.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:273`](../core/dr-pipeline/src/ops/noise_reduction.rs#L273), [`core/dr-pipeline/src/sidecar.rs:157`](../core/dr-pipeline/src/sidecar.rs#L157), [`core/dr-pipeline/src/sidecar.rs:1637`](../core/dr-pipeline/src/sidecar.rs#L1637), [`core/dr-pipeline/src/sidecar.rs:1697`](../core/dr-pipeline/src/sidecar.rs#L1697), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`ui/dr-ui/src/develop.rs:101`](../ui/dr-ui/src/develop.rs#L101), [`ui/dr-ui/src/develop.rs:1424`](../ui/dr-ui/src/develop.rs#L1424), [`ui/dr-ui/src/develop.rs:163`](../ui/dr-ui/src/develop.rs#L163), [`ui/dr-ui/src/develop.rs:1902`](../ui/dr-ui/src/develop.rs#L1902), [`ui/dr-ui/src/develop.rs:1920`](../ui/dr-ui/src/develop.rs#L1920), [`ui/dr-ui/src/develop.rs:1934`](../ui/dr-ui/src/develop.rs#L1934), [`ui/dr-ui/src/develop.rs:1956`](../ui/dr-ui/src/develop.rs#L1956), [`ui/dr-ui/src/develop.rs:2102`](../ui/dr-ui/src/develop.rs#L2102), [`ui/dr-ui/src/develop.rs:2200`](../ui/dr-ui/src/develop.rs#L2200), [`ui/dr-ui/src/develop.rs:3268`](../ui/dr-ui/src/develop.rs#L3268), [`ui/dr-ui/src/develop.rs:326`](../ui/dr-ui/src/develop.rs#L326), [`ui/dr-ui/src/develop.rs:3298`](../ui/dr-ui/src/develop.rs#L3298), [`ui/dr-ui/src/develop.rs:3364`](../ui/dr-ui/src/develop.rs#L3364), [`ui/dr-ui/src/develop.rs:3378`](../ui/dr-ui/src/develop.rs#L3378), [`ui/dr-ui/src/develop.rs:3570`](../ui/dr-ui/src/develop.rs#L3570), [`ui/dr-ui/src/develop.rs:363`](../ui/dr-ui/src/develop.rs#L363), [`ui/dr-ui/src/develop.rs:4230`](../ui/dr-ui/src/develop.rs#L4230), [`ui/dr-ui/src/develop.rs:4284`](../ui/dr-ui/src/develop.rs#L4284), [`ui/dr-ui/src/develop.rs:4328`](../ui/dr-ui/src/develop.rs#L4328), [`ui/dr-ui/src/develop.rs:4378`](../ui/dr-ui/src/develop.rs#L4378), [`ui/dr-ui/src/develop.rs:586`](../ui/dr-ui/src/develop.rs#L586), [`ui/dr-ui/src/develop.rs:647`](../ui/dr-ui/src/develop.rs#L647), [`ui/dr-ui/src/develop.rs:726`](../ui/dr-ui/src/develop.rs#L726), [`ui/dr-ui/src/develop.rs:773`](../ui/dr-ui/src/develop.rs#L773), [`ui/dr-ui/src/develop.rs:802`](../ui/dr-ui/src/develop.rs#L802), [`ui/dr-ui/src/lib.rs:1514`](../ui/dr-ui/src/lib.rs#L1514), [`ui/dr-ui/src/lib.rs:2233`](../ui/dr-ui/src/lib.rs#L2233), [`ui/dr-ui/src/lib.rs:2429`](../ui/dr-ui/src/lib.rs#L2429), [`ui/dr-ui/src/lib.rs:2601`](../ui/dr-ui/src/lib.rs#L2601), [`ui/dr-ui/src/lib.rs:2665`](../ui/dr-ui/src/lib.rs#L2665), [`ui/dr-ui/src/lib.rs:2719`](../ui/dr-ui/src/lib.rs#L2719), [`ui/dr-ui/src/lib.rs:320`](../ui/dr-ui/src/lib.rs#L320), [`ui/dr-ui/src/lib.rs:363`](../ui/dr-ui/src/lib.rs#L363), [`ui/dr-ui/src/lib.rs:386`](../ui/dr-ui/src/lib.rs#L386), [`ui/dr-ui/src/library.rs:506`](../ui/dr-ui/src/library.rs#L506), [`ui/dr-ui/src/masks_ui.rs:218`](../ui/dr-ui/src/masks_ui.rs#L218), [`ui/dr-ui/src/masks_ui.rs:41`](../ui/dr-ui/src/masks_ui.rs#L41), [`ui/dr-ui/src/masks_ui.rs:816`](../ui/dr-ui/src/masks_ui.rs#L816), [`ui/dr-ui/src/masks_ui.rs:930`](../ui/dr-ui/src/masks_ui.rs#L930), [`ui/dr-ui/src/segmentation.rs:219`](../ui/dr-ui/src/segmentation.rs#L219), [`ui/dr-ui/src/segmentation.rs:322`](../ui/dr-ui/src/segmentation.rs#L322), [`ui/dr-ui/src/segmentation.rs:350`](../ui/dr-ui/src/segmentation.rs#L350), [`ui/dr-ui/ui/adjust.slint:517`](../ui/dr-ui/ui/adjust.slint#L517), [`ui/dr-ui/ui/adjust.slint:635`](../ui/dr-ui/ui/adjust.slint#L635), [`ui/dr-ui/ui/app.slint:119`](../ui/dr-ui/ui/app.slint#L119), [`ui/dr-ui/ui/app.slint:165`](../ui/dr-ui/ui/app.slint#L165), [`ui/dr-ui/ui/app.slint:1849`](../ui/dr-ui/ui/app.slint#L1849), [`ui/dr-ui/ui/app.slint:858`](../ui/dr-ui/ui/app.slint#L858), [`ui/dr-ui/ui/masks.slint:490`](../ui/dr-ui/ui/masks.slint#L490) | +| FR-DEV-3a | [`core/dr-pipeline/build.rs:756`](../core/dr-pipeline/build.rs#L756), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/descriptor.rs:194`](../core/dr-pipeline/src/descriptor.rs#L194), [`core/dr-pipeline/src/descriptor.rs:234`](../core/dr-pipeline/src/descriptor.rs#L234), [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/descriptor.rs:313`](../core/dr-pipeline/src/descriptor.rs#L313), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:24`](../core/dr-pipeline/src/graph.rs#L24), [`core/dr-pipeline/src/graph.rs:251`](../core/dr-pipeline/src/graph.rs#L251), [`core/dr-pipeline/src/graph.rs:46`](../core/dr-pipeline/src/graph.rs#L46), [`core/dr-pipeline/src/graph.rs:59`](../core/dr-pipeline/src/graph.rs#L59), [`core/dr-pipeline/src/mask.rs:955`](../core/dr-pipeline/src/mask.rs#L955), [`core/dr-pipeline/src/operation.rs:232`](../core/dr-pipeline/src/operation.rs#L232), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365), [`core/dr-pipeline/src/ops/curve.rs:319`](../core/dr-pipeline/src/ops/curve.rs#L319), [`ui/dr-ui/src/develop.rs:1321`](../ui/dr-ui/src/develop.rs#L1321), [`ui/dr-ui/src/lib.rs:669`](../ui/dr-ui/src/lib.rs#L669), [`ui/dr-ui/tests/ui_names_no_operation.rs:1`](../ui/dr-ui/tests/ui_names_no_operation.rs#L1) | +| FR-DEV-3b | [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:59`](../core/dr-pipeline/src/graph.rs#L59), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365) | +| FR-DEV-3c | [`core/dr-pipeline/build.rs:756`](../core/dr-pipeline/build.rs#L756), [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:251`](../core/dr-pipeline/src/graph.rs#L251), [`core/dr-pipeline/src/graph.rs:46`](../core/dr-pipeline/src/graph.rs#L46), [`core/dr-pipeline/src/mask.rs:955`](../core/dr-pipeline/src/mask.rs#L955), [`ui/dr-ui/src/develop.rs:4957`](../ui/dr-ui/src/develop.rs#L4957) | +| FR-DEV-3d | [`core/dr-gpu/src/adjust.rs:1041`](../core/dr-gpu/src/adjust.rs#L1041), [`core/dr-gpu/src/adjust.rs:104`](../core/dr-gpu/src/adjust.rs#L104), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/src/adjust.rs:986`](../core/dr-gpu/src/adjust.rs#L986), [`core/dr-gpu/tests/capture_sharpen.rs:434`](../core/dr-gpu/tests/capture_sharpen.rs#L434), [`core/dr-gpu/tests/detail_stage.rs:242`](../core/dr-gpu/tests/detail_stage.rs#L242), [`core/dr-gpu/tests/local_contrast.rs:558`](../core/dr-gpu/tests/local_contrast.rs#L558), [`core/dr-gpu/tests/noise_reduction.rs:556`](../core/dr-gpu/tests/noise_reduction.rs#L556), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/graph.rs:617`](../core/dr-pipeline/src/graph.rs#L617), [`core/dr-pipeline/src/operation.rs:32`](../core/dr-pipeline/src/operation.rs#L32), [`core/dr-pipeline/src/operation.rs:389`](../core/dr-pipeline/src/operation.rs#L389), [`core/dr-pipeline/src/operation.rs:53`](../core/dr-pipeline/src/operation.rs#L53), [`core/dr-pipeline/src/operation.rs:71`](../core/dr-pipeline/src/operation.rs#L71) | | FR-DEV-3e | [`core/dr-decode/src/base_curve.rs:145`](../core/dr-decode/src/base_curve.rs#L145), [`core/dr-decode/src/base_curve.rs:158`](../core/dr-decode/src/base_curve.rs#L158), [`core/dr-decode/src/base_curve.rs:1`](../core/dr-decode/src/base_curve.rs#L1), [`core/dr-decode/src/base_curve.rs:267`](../core/dr-decode/src/base_curve.rs#L267), [`core/dr-decode/src/base_curve.rs:347`](../core/dr-decode/src/base_curve.rs#L347), [`core/dr-decode/src/base_curve.rs:55`](../core/dr-decode/src/base_curve.rs#L55), [`core/dr-decode/src/lib.rs:121`](../core/dr-decode/src/lib.rs#L121), [`core/dr-decode/src/lib.rs:708`](../core/dr-decode/src/lib.rs#L708), [`core/dr-decode/src/lib.rs:748`](../core/dr-decode/src/lib.rs#L748), [`core/dr-decode/src/profile.rs:102`](../core/dr-decode/src/profile.rs#L102), [`core/dr-decode/src/profile.rs:151`](../core/dr-decode/src/profile.rs#L151), [`core/dr-decode/src/profile.rs:1`](../core/dr-decode/src/profile.rs#L1), [`core/dr-decode/src/profile.rs:235`](../core/dr-decode/src/profile.rs#L235), [`core/dr-decode/src/profile.rs:286`](../core/dr-decode/src/profile.rs#L286), [`core/dr-decode/src/profile.rs:343`](../core/dr-decode/src/profile.rs#L343), [`core/dr-decode/src/profile.rs:458`](../core/dr-decode/src/profile.rs#L458), [`core/dr-decode/src/profile.rs:492`](../core/dr-decode/src/profile.rs#L492), [`core/dr-decode/src/profile.rs:630`](../core/dr-decode/src/profile.rs#L630), [`core/dr-gpu/src/adjust.rs:37`](../core/dr-gpu/src/adjust.rs#L37), [`core/dr-gpu/src/adjust.rs:967`](../core/dr-gpu/src/adjust.rs#L967), [`core/dr-gpu/src/demosaic.rs:121`](../core/dr-gpu/src/demosaic.rs#L121), [`core/dr-gpu/src/demosaic.rs:86`](../core/dr-gpu/src/demosaic.rs#L86), [`core/dr-gpu/tests/base_curve.rs:1`](../core/dr-gpu/tests/base_curve.rs#L1), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:1576`](../core/dr-pipeline/src/operation.rs#L1576), [`core/dr-pipeline/src/operation.rs:1601`](../core/dr-pipeline/src/operation.rs#L1601), [`core/dr-pipeline/src/operation.rs:1616`](../core/dr-pipeline/src/operation.rs#L1616), [`core/dr-pipeline/src/operation.rs:1640`](../core/dr-pipeline/src/operation.rs#L1640), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/operation.rs:440`](../core/dr-pipeline/src/operation.rs#L440), [`core/dr-pipeline/src/operation.rs:450`](../core/dr-pipeline/src/operation.rs#L450), [`core/dr-pipeline/src/operation.rs:600`](../core/dr-pipeline/src/operation.rs#L600) | -| FR-DEV-3f | [`core/dr-film/src/bake.rs:271`](../core/dr-film/src/bake.rs#L271), [`core/dr-film/src/bake.rs:62`](../core/dr-film/src/bake.rs#L62), [`core/dr-film/src/boolean_grain.rs:1`](../core/dr-film/src/boolean_grain.rs#L1), [`core/dr-film/src/boolean_grain.rs:78`](../core/dr-film/src/boolean_grain.rs#L78), [`core/dr-film/src/grain.rs:140`](../core/dr-film/src/grain.rs#L140), [`core/dr-film/src/grain.rs:1`](../core/dr-film/src/grain.rs#L1), [`core/dr-film/src/grain.rs:302`](../core/dr-film/src/grain.rs#L302), [`core/dr-film/src/grain.rs:79`](../core/dr-film/src/grain.rs#L79), [`core/dr-film/src/lib.rs:160`](../core/dr-film/src/lib.rs#L160), [`core/dr-film/src/lib.rs:1`](../core/dr-film/src/lib.rs#L1), [`core/dr-film/src/profile.rs:100`](../core/dr-film/src/profile.rs#L100), [`core/dr-film/src/profile.rs:142`](../core/dr-film/src/profile.rs#L142), [`core/dr-film/src/profile.rs:182`](../core/dr-film/src/profile.rs#L182), [`core/dr-film/src/profile.rs:259`](../core/dr-film/src/profile.rs#L259), [`core/dr-film/src/profile.rs:502`](../core/dr-film/src/profile.rs#L502), [`core/dr-film/src/profile.rs:73`](../core/dr-film/src/profile.rs#L73), [`core/dr-gpu/src/adjust.rs:139`](../core/dr-gpu/src/adjust.rs#L139), [`core/dr-gpu/src/adjust.rs:196`](../core/dr-gpu/src/adjust.rs#L196), [`core/dr-gpu/src/adjust.rs:357`](../core/dr-gpu/src/adjust.rs#L357), [`core/dr-gpu/src/adjust.rs:483`](../core/dr-gpu/src/adjust.rs#L483), [`core/dr-gpu/src/adjust.rs:77`](../core/dr-gpu/src/adjust.rs#L77), [`core/dr-gpu/tests/film_sim.rs:191`](../core/dr-gpu/tests/film_sim.rs#L191), [`core/dr-gpu/tests/film_sim.rs:1`](../core/dr-gpu/tests/film_sim.rs#L1), [`core/dr-pipeline/src/graph.rs:101`](../core/dr-pipeline/src/graph.rs#L101), [`core/dr-pipeline/src/graph.rs:124`](../core/dr-pipeline/src/graph.rs#L124), [`core/dr-pipeline/src/graph.rs:324`](../core/dr-pipeline/src/graph.rs#L324), [`core/dr-pipeline/src/operation.rs:1065`](../core/dr-pipeline/src/operation.rs#L1065), [`core/dr-pipeline/src/operation.rs:1094`](../core/dr-pipeline/src/operation.rs#L1094), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:296`](../core/dr-pipeline/src/operation.rs#L296), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/ops/film_sim.rs:129`](../core/dr-pipeline/src/ops/film_sim.rs#L129), [`core/dr-pipeline/src/ops/film_sim.rs:153`](../core/dr-pipeline/src/ops/film_sim.rs#L153), [`core/dr-pipeline/src/ops/film_sim.rs:1`](../core/dr-pipeline/src/ops/film_sim.rs#L1), [`core/dr-pipeline/src/ops/film_sim.rs:331`](../core/dr-pipeline/src/ops/film_sim.rs#L331), [`core/dr-pipeline/src/ops/film_sim.rs:43`](../core/dr-pipeline/src/ops/film_sim.rs#L43), [`core/dr-pipeline/src/ops/film_sim.rs:87`](../core/dr-pipeline/src/ops/film_sim.rs#L87), [`core/dr-pipeline/src/ops/film_sim.rs:92`](../core/dr-pipeline/src/ops/film_sim.rs#L92), [`core/dr-pipeline/src/sidecar.rs:111`](../core/dr-pipeline/src/sidecar.rs#L111), [`core/dr-pipeline/src/sidecar.rs:167`](../core/dr-pipeline/src/sidecar.rs#L167), [`core/dr-pipeline/src/sidecar.rs:1957`](../core/dr-pipeline/src/sidecar.rs#L1957), [`core/dr-pipeline/src/sidecar.rs:2033`](../core/dr-pipeline/src/sidecar.rs#L2033), [`core/dr-pipeline/src/sidecar.rs:533`](../core/dr-pipeline/src/sidecar.rs#L533), [`core/dr-pipeline/src/sidecar.rs:660`](../core/dr-pipeline/src/sidecar.rs#L660), [`core/dr-pipeline/src/sidecar.rs:792`](../core/dr-pipeline/src/sidecar.rs#L792), [`core/dr-pipeline/src/state.rs:100`](../core/dr-pipeline/src/state.rs#L100), [`core/dr-pipeline/src/state.rs:115`](../core/dr-pipeline/src/state.rs#L115), [`core/dr-pipeline/src/state.rs:60`](../core/dr-pipeline/src/state.rs#L60), [`ui/dr-ui/src/develop.rs:3012`](../ui/dr-ui/src/develop.rs#L3012), [`ui/dr-ui/src/develop.rs:3029`](../ui/dr-ui/src/develop.rs#L3029), [`ui/dr-ui/src/develop.rs:3041`](../ui/dr-ui/src/develop.rs#L3041), [`ui/dr-ui/src/develop.rs:3079`](../ui/dr-ui/src/develop.rs#L3079), [`ui/dr-ui/src/develop.rs:3088`](../ui/dr-ui/src/develop.rs#L3088), [`ui/dr-ui/src/develop.rs:3191`](../ui/dr-ui/src/develop.rs#L3191), [`ui/dr-ui/src/develop.rs:3607`](../ui/dr-ui/src/develop.rs#L3607), [`ui/dr-ui/src/develop.rs:3622`](../ui/dr-ui/src/develop.rs#L3622), [`ui/dr-ui/src/lib.rs:2207`](../ui/dr-ui/src/lib.rs#L2207), [`ui/dr-ui/src/lib.rs:602`](../ui/dr-ui/src/lib.rs#L602), [`ui/dr-ui/src/lib.rs:660`](../ui/dr-ui/src/lib.rs#L660), [`ui/dr-ui/src/library.rs:497`](../ui/dr-ui/src/library.rs#L497), [`ui/dr-ui/src/library.rs:745`](../ui/dr-ui/src/library.rs#L745), [`ui/dr-ui/src/presets.rs:286`](../ui/dr-ui/src/presets.rs#L286), [`ui/dr-ui/ui/adjust.slint:1034`](../ui/dr-ui/ui/adjust.slint#L1034), [`ui/dr-ui/ui/adjust.slint:1116`](../ui/dr-ui/ui/adjust.slint#L1116), [`ui/dr-ui/ui/app.slint:2364`](../ui/dr-ui/ui/app.slint#L2364), [`ui/dr-ui/ui/app.slint:600`](../ui/dr-ui/ui/app.slint#L600) | +| FR-DEV-3f | [`core/dr-film/src/bake.rs:271`](../core/dr-film/src/bake.rs#L271), [`core/dr-film/src/bake.rs:62`](../core/dr-film/src/bake.rs#L62), [`core/dr-film/src/boolean_grain.rs:1`](../core/dr-film/src/boolean_grain.rs#L1), [`core/dr-film/src/boolean_grain.rs:78`](../core/dr-film/src/boolean_grain.rs#L78), [`core/dr-film/src/grain.rs:140`](../core/dr-film/src/grain.rs#L140), [`core/dr-film/src/grain.rs:1`](../core/dr-film/src/grain.rs#L1), [`core/dr-film/src/grain.rs:302`](../core/dr-film/src/grain.rs#L302), [`core/dr-film/src/grain.rs:79`](../core/dr-film/src/grain.rs#L79), [`core/dr-film/src/lib.rs:160`](../core/dr-film/src/lib.rs#L160), [`core/dr-film/src/lib.rs:1`](../core/dr-film/src/lib.rs#L1), [`core/dr-film/src/profile.rs:100`](../core/dr-film/src/profile.rs#L100), [`core/dr-film/src/profile.rs:142`](../core/dr-film/src/profile.rs#L142), [`core/dr-film/src/profile.rs:182`](../core/dr-film/src/profile.rs#L182), [`core/dr-film/src/profile.rs:259`](../core/dr-film/src/profile.rs#L259), [`core/dr-film/src/profile.rs:502`](../core/dr-film/src/profile.rs#L502), [`core/dr-film/src/profile.rs:73`](../core/dr-film/src/profile.rs#L73), [`core/dr-gpu/src/adjust.rs:139`](../core/dr-gpu/src/adjust.rs#L139), [`core/dr-gpu/src/adjust.rs:196`](../core/dr-gpu/src/adjust.rs#L196), [`core/dr-gpu/src/adjust.rs:357`](../core/dr-gpu/src/adjust.rs#L357), [`core/dr-gpu/src/adjust.rs:483`](../core/dr-gpu/src/adjust.rs#L483), [`core/dr-gpu/src/adjust.rs:77`](../core/dr-gpu/src/adjust.rs#L77), [`core/dr-gpu/tests/film_sim.rs:191`](../core/dr-gpu/tests/film_sim.rs#L191), [`core/dr-gpu/tests/film_sim.rs:1`](../core/dr-gpu/tests/film_sim.rs#L1), [`core/dr-pipeline/src/graph.rs:102`](../core/dr-pipeline/src/graph.rs#L102), [`core/dr-pipeline/src/graph.rs:125`](../core/dr-pipeline/src/graph.rs#L125), [`core/dr-pipeline/src/graph.rs:325`](../core/dr-pipeline/src/graph.rs#L325), [`core/dr-pipeline/src/operation.rs:1065`](../core/dr-pipeline/src/operation.rs#L1065), [`core/dr-pipeline/src/operation.rs:1094`](../core/dr-pipeline/src/operation.rs#L1094), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:296`](../core/dr-pipeline/src/operation.rs#L296), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/ops/film_sim.rs:129`](../core/dr-pipeline/src/ops/film_sim.rs#L129), [`core/dr-pipeline/src/ops/film_sim.rs:153`](../core/dr-pipeline/src/ops/film_sim.rs#L153), [`core/dr-pipeline/src/ops/film_sim.rs:1`](../core/dr-pipeline/src/ops/film_sim.rs#L1), [`core/dr-pipeline/src/ops/film_sim.rs:331`](../core/dr-pipeline/src/ops/film_sim.rs#L331), [`core/dr-pipeline/src/ops/film_sim.rs:43`](../core/dr-pipeline/src/ops/film_sim.rs#L43), [`core/dr-pipeline/src/ops/film_sim.rs:87`](../core/dr-pipeline/src/ops/film_sim.rs#L87), [`core/dr-pipeline/src/ops/film_sim.rs:92`](../core/dr-pipeline/src/ops/film_sim.rs#L92), [`core/dr-pipeline/src/sidecar.rs:112`](../core/dr-pipeline/src/sidecar.rs#L112), [`core/dr-pipeline/src/sidecar.rs:168`](../core/dr-pipeline/src/sidecar.rs#L168), [`core/dr-pipeline/src/sidecar.rs:1958`](../core/dr-pipeline/src/sidecar.rs#L1958), [`core/dr-pipeline/src/sidecar.rs:2034`](../core/dr-pipeline/src/sidecar.rs#L2034), [`core/dr-pipeline/src/sidecar.rs:534`](../core/dr-pipeline/src/sidecar.rs#L534), [`core/dr-pipeline/src/sidecar.rs:661`](../core/dr-pipeline/src/sidecar.rs#L661), [`core/dr-pipeline/src/sidecar.rs:793`](../core/dr-pipeline/src/sidecar.rs#L793), [`core/dr-pipeline/src/state.rs:100`](../core/dr-pipeline/src/state.rs#L100), [`core/dr-pipeline/src/state.rs:115`](../core/dr-pipeline/src/state.rs#L115), [`core/dr-pipeline/src/state.rs:60`](../core/dr-pipeline/src/state.rs#L60), [`ui/dr-ui/src/develop.rs:3012`](../ui/dr-ui/src/develop.rs#L3012), [`ui/dr-ui/src/develop.rs:3029`](../ui/dr-ui/src/develop.rs#L3029), [`ui/dr-ui/src/develop.rs:3041`](../ui/dr-ui/src/develop.rs#L3041), [`ui/dr-ui/src/develop.rs:3079`](../ui/dr-ui/src/develop.rs#L3079), [`ui/dr-ui/src/develop.rs:3088`](../ui/dr-ui/src/develop.rs#L3088), [`ui/dr-ui/src/develop.rs:3191`](../ui/dr-ui/src/develop.rs#L3191), [`ui/dr-ui/src/develop.rs:3607`](../ui/dr-ui/src/develop.rs#L3607), [`ui/dr-ui/src/develop.rs:3622`](../ui/dr-ui/src/develop.rs#L3622), [`ui/dr-ui/src/lib.rs:2207`](../ui/dr-ui/src/lib.rs#L2207), [`ui/dr-ui/src/lib.rs:602`](../ui/dr-ui/src/lib.rs#L602), [`ui/dr-ui/src/lib.rs:660`](../ui/dr-ui/src/lib.rs#L660), [`ui/dr-ui/src/library.rs:497`](../ui/dr-ui/src/library.rs#L497), [`ui/dr-ui/src/library.rs:745`](../ui/dr-ui/src/library.rs#L745), [`ui/dr-ui/src/presets.rs:286`](../ui/dr-ui/src/presets.rs#L286), [`ui/dr-ui/ui/adjust.slint:1034`](../ui/dr-ui/ui/adjust.slint#L1034), [`ui/dr-ui/ui/adjust.slint:1116`](../ui/dr-ui/ui/adjust.slint#L1116), [`ui/dr-ui/ui/app.slint:2364`](../ui/dr-ui/ui/app.slint#L2364), [`ui/dr-ui/ui/app.slint:600`](../ui/dr-ui/ui/app.slint#L600) | | FR-DEV-3h | [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-decode/src/preview.rs:29`](../core/dr-decode/src/preview.rs#L29), [`core/dr-pipeline/src/framing.rs:1050`](../core/dr-pipeline/src/framing.rs#L1050), [`core/dr-pipeline/src/framing.rs:328`](../core/dr-pipeline/src/framing.rs#L328), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-types/src/lib.rs:337`](../core/dr-types/src/lib.rs#L337), [`core/dr-types/src/lib.rs:445`](../core/dr-types/src/lib.rs#L445), [`core/dr-types/src/lib.rs:457`](../core/dr-types/src/lib.rs#L457), [`core/dr-types/src/lib.rs:473`](../core/dr-types/src/lib.rs#L473), [`ui/dr-ui/src/develop.rs:138`](../ui/dr-ui/src/develop.rs#L138), [`ui/dr-ui/src/develop.rs:2119`](../ui/dr-ui/src/develop.rs#L2119), [`ui/dr-ui/src/segmentation.rs:322`](../ui/dr-ui/src/segmentation.rs#L322) | -| FR-DEV-4 | [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:335`](../core/dr-gpu/src/lib.rs#L335), [`ui/dr-ui/ui/crop.slint:1`](../ui/dr-ui/ui/crop.slint#L1) | -| FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:345`](../core/dr-pipeline/src/graph.rs#L345), [`core/dr-pipeline/src/graph.rs:384`](../core/dr-pipeline/src/graph.rs#L384), [`core/dr-pipeline/src/history.rs:102`](../core/dr-pipeline/src/history.rs#L102), [`core/dr-pipeline/src/history.rs:110`](../core/dr-pipeline/src/history.rs#L110), [`core/dr-pipeline/src/history.rs:127`](../core/dr-pipeline/src/history.rs#L127), [`core/dr-pipeline/src/history.rs:184`](../core/dr-pipeline/src/history.rs#L184), [`core/dr-pipeline/src/history.rs:1`](../core/dr-pipeline/src/history.rs#L1), [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:234`](../core/dr-pipeline/src/history.rs#L234), [`core/dr-pipeline/src/history.rs:293`](../core/dr-pipeline/src/history.rs#L293), [`core/dr-pipeline/src/history.rs:479`](../core/dr-pipeline/src/history.rs#L479), [`core/dr-pipeline/src/history.rs:489`](../core/dr-pipeline/src/history.rs#L489), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`ui/dr-ui/src/develop.rs:3041`](../ui/dr-ui/src/develop.rs#L3041), [`ui/dr-ui/src/develop.rs:3622`](../ui/dr-ui/src/develop.rs#L3622), [`ui/dr-ui/src/develop.rs:3652`](../ui/dr-ui/src/develop.rs#L3652), [`ui/dr-ui/src/develop.rs:3665`](../ui/dr-ui/src/develop.rs#L3665), [`ui/dr-ui/src/develop.rs:3677`](../ui/dr-ui/src/develop.rs#L3677), [`ui/dr-ui/src/develop.rs:3693`](../ui/dr-ui/src/develop.rs#L3693), [`ui/dr-ui/src/develop.rs:3725`](../ui/dr-ui/src/develop.rs#L3725), [`ui/dr-ui/src/develop.rs:3729`](../ui/dr-ui/src/develop.rs#L3729), [`ui/dr-ui/src/develop.rs:3748`](../ui/dr-ui/src/develop.rs#L3748), [`ui/dr-ui/src/develop.rs:3764`](../ui/dr-ui/src/develop.rs#L3764), [`ui/dr-ui/src/develop.rs:708`](../ui/dr-ui/src/develop.rs#L708), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:215`](../ui/dr-ui/src/labels.rs#L215), [`ui/dr-ui/src/lib.rs:1462`](../ui/dr-ui/src/lib.rs#L1462), [`ui/dr-ui/src/lib.rs:1492`](../ui/dr-ui/src/lib.rs#L1492), [`ui/dr-ui/src/lib.rs:1500`](../ui/dr-ui/src/lib.rs#L1500), [`ui/dr-ui/src/lib.rs:2403`](../ui/dr-ui/src/lib.rs#L2403), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | +| FR-DEV-4 | [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:336`](../core/dr-gpu/src/lib.rs#L336), [`ui/dr-ui/ui/crop.slint:1`](../ui/dr-ui/ui/crop.slint#L1) | +| FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:346`](../core/dr-pipeline/src/graph.rs#L346), [`core/dr-pipeline/src/graph.rs:385`](../core/dr-pipeline/src/graph.rs#L385), [`core/dr-pipeline/src/history.rs:102`](../core/dr-pipeline/src/history.rs#L102), [`core/dr-pipeline/src/history.rs:110`](../core/dr-pipeline/src/history.rs#L110), [`core/dr-pipeline/src/history.rs:127`](../core/dr-pipeline/src/history.rs#L127), [`core/dr-pipeline/src/history.rs:184`](../core/dr-pipeline/src/history.rs#L184), [`core/dr-pipeline/src/history.rs:1`](../core/dr-pipeline/src/history.rs#L1), [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:234`](../core/dr-pipeline/src/history.rs#L234), [`core/dr-pipeline/src/history.rs:293`](../core/dr-pipeline/src/history.rs#L293), [`core/dr-pipeline/src/history.rs:479`](../core/dr-pipeline/src/history.rs#L479), [`core/dr-pipeline/src/history.rs:489`](../core/dr-pipeline/src/history.rs#L489), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`ui/dr-ui/src/develop.rs:3041`](../ui/dr-ui/src/develop.rs#L3041), [`ui/dr-ui/src/develop.rs:3622`](../ui/dr-ui/src/develop.rs#L3622), [`ui/dr-ui/src/develop.rs:3652`](../ui/dr-ui/src/develop.rs#L3652), [`ui/dr-ui/src/develop.rs:3665`](../ui/dr-ui/src/develop.rs#L3665), [`ui/dr-ui/src/develop.rs:3677`](../ui/dr-ui/src/develop.rs#L3677), [`ui/dr-ui/src/develop.rs:3693`](../ui/dr-ui/src/develop.rs#L3693), [`ui/dr-ui/src/develop.rs:3725`](../ui/dr-ui/src/develop.rs#L3725), [`ui/dr-ui/src/develop.rs:3729`](../ui/dr-ui/src/develop.rs#L3729), [`ui/dr-ui/src/develop.rs:3748`](../ui/dr-ui/src/develop.rs#L3748), [`ui/dr-ui/src/develop.rs:3764`](../ui/dr-ui/src/develop.rs#L3764), [`ui/dr-ui/src/develop.rs:708`](../ui/dr-ui/src/develop.rs#L708), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:215`](../ui/dr-ui/src/labels.rs#L215), [`ui/dr-ui/src/lib.rs:1462`](../ui/dr-ui/src/lib.rs#L1462), [`ui/dr-ui/src/lib.rs:1492`](../ui/dr-ui/src/lib.rs#L1492), [`ui/dr-ui/src/lib.rs:1500`](../ui/dr-ui/src/lib.rs#L1500), [`ui/dr-ui/src/lib.rs:2403`](../ui/dr-ui/src/lib.rs#L2403), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | | FR-DEV-6 | [`core/dr-pipeline/src/preset.rs:1`](../core/dr-pipeline/src/preset.rs#L1), [`core/dr-pipeline/src/preset.rs:249`](../core/dr-pipeline/src/preset.rs#L249), [`core/dr-pipeline/src/preset.rs:282`](../core/dr-pipeline/src/preset.rs#L282), [`core/dr-types/src/settings.rs:182`](../core/dr-types/src/settings.rs#L182), [`ui/dr-ui/src/develop.rs:3564`](../ui/dr-ui/src/develop.rs#L3564), [`ui/dr-ui/src/develop.rs:3585`](../ui/dr-ui/src/develop.rs#L3585), [`ui/dr-ui/src/lib.rs:1429`](../ui/dr-ui/src/lib.rs#L1429), [`ui/dr-ui/src/lib.rs:2025`](../ui/dr-ui/src/lib.rs#L2025), [`ui/dr-ui/src/library.rs:1787`](../ui/dr-ui/src/library.rs#L1787), [`ui/dr-ui/src/library.rs:459`](../ui/dr-ui/src/library.rs#L459), [`ui/dr-ui/src/library.rs:487`](../ui/dr-ui/src/library.rs#L487), [`ui/dr-ui/src/library_ui.rs:2592`](../ui/dr-ui/src/library_ui.rs#L2592), [`ui/dr-ui/src/library_ui.rs:2992`](../ui/dr-ui/src/library_ui.rs#L2992), [`ui/dr-ui/src/library_ui.rs:472`](../ui/dr-ui/src/library_ui.rs#L472), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/presets.rs:1`](../ui/dr-ui/src/presets.rs#L1), [`ui/dr-ui/src/presets.rs:546`](../ui/dr-ui/src/presets.rs#L546), [`ui/dr-ui/src/settings_ui.rs:630`](../ui/dr-ui/src/settings_ui.rs#L630), [`ui/dr-ui/ui/adjust.slint:709`](../ui/dr-ui/ui/adjust.slint#L709), [`ui/dr-ui/ui/adjust.slint:736`](../ui/dr-ui/ui/adjust.slint#L736), [`ui/dr-ui/ui/adjust.slint:779`](../ui/dr-ui/ui/adjust.slint#L779), [`ui/dr-ui/ui/app.slint:1443`](../ui/dr-ui/ui/app.slint#L1443), [`ui/dr-ui/ui/app.slint:2453`](../ui/dr-ui/ui/app.slint#L2453), [`ui/dr-ui/ui/library.slint:1345`](../ui/dr-ui/ui/library.slint#L1345), [`ui/dr-ui/ui/library.slint:1352`](../ui/dr-ui/ui/library.slint#L1352), [`ui/dr-ui/ui/library.slint:837`](../ui/dr-ui/ui/library.slint#L837), [`ui/dr-ui/ui/library.slint:853`](../ui/dr-ui/ui/library.slint#L853), [`ui/dr-ui/ui/library.slint:922`](../ui/dr-ui/ui/library.slint#L922), [`ui/dr-ui/ui/library.slint:937`](../ui/dr-ui/ui/library.slint#L937), [`ui/dr-ui/ui/presets.slint:4`](../ui/dr-ui/ui/presets.slint#L4), [`ui/dr-ui/ui/settings.slint:100`](../ui/dr-ui/ui/settings.slint#L100) | | FR-DEV-7 | [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`ui/dr-ui/src/develop.rs:3693`](../ui/dr-ui/src/develop.rs#L3693), [`ui/dr-ui/src/develop.rs:3725`](../ui/dr-ui/src/develop.rs#L3725), [`ui/dr-ui/src/lib.rs:1500`](../ui/dr-ui/src/lib.rs#L1500), [`ui/dr-ui/src/lib.rs:2403`](../ui/dr-ui/src/lib.rs#L2403), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | -| FR-DEV-8 | [`core/dr-gpu/src/detail.rs:387`](../core/dr-gpu/src/detail.rs#L387), [`core/dr-gpu/src/detail.rs:592`](../core/dr-gpu/src/detail.rs#L592), [`core/dr-gpu/tests/detail_instances.rs:1`](../core/dr-gpu/tests/detail_instances.rs#L1), [`core/dr-gpu/tests/spot_removal.rs:1`](../core/dr-gpu/tests/spot_removal.rs#L1), [`core/dr-pipeline/src/detail.rs:410`](../core/dr-pipeline/src/detail.rs#L410), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:469`](../core/dr-pipeline/src/detail.rs#L469), [`core/dr-pipeline/src/detail.rs:555`](../core/dr-pipeline/src/detail.rs#L555), [`core/dr-pipeline/src/graph.rs:113`](../core/dr-pipeline/src/graph.rs#L113), [`core/dr-pipeline/src/graph.rs:191`](../core/dr-pipeline/src/graph.rs#L191), [`core/dr-pipeline/src/graph.rs:685`](../core/dr-pipeline/src/graph.rs#L685), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:554`](../core/dr-pipeline/src/operation.rs#L554), [`core/dr-pipeline/src/sidecar.rs:183`](../core/dr-pipeline/src/sidecar.rs#L183), [`core/dr-pipeline/src/sidecar.rs:352`](../core/dr-pipeline/src/sidecar.rs#L352), [`core/dr-pipeline/src/sidecar.rs:672`](../core/dr-pipeline/src/sidecar.rs#L672), [`core/dr-pipeline/src/sidecar.rs:808`](../core/dr-pipeline/src/sidecar.rs#L808), [`core/dr-pipeline/src/sidecar.rs:862`](../core/dr-pipeline/src/sidecar.rs#L862), [`core/dr-pipeline/src/sidecar.rs:892`](../core/dr-pipeline/src/sidecar.rs#L892), [`core/dr-pipeline/src/spot.rs:115`](../core/dr-pipeline/src/spot.rs#L115), [`core/dr-pipeline/src/spot.rs:151`](../core/dr-pipeline/src/spot.rs#L151), [`core/dr-pipeline/src/spot.rs:1`](../core/dr-pipeline/src/spot.rs#L1), [`core/dr-pipeline/src/spot.rs:207`](../core/dr-pipeline/src/spot.rs#L207), [`core/dr-pipeline/src/spot.rs:387`](../core/dr-pipeline/src/spot.rs#L387), [`core/dr-pipeline/src/spot.rs:472`](../core/dr-pipeline/src/spot.rs#L472), [`core/dr-pipeline/src/spot.rs:582`](../core/dr-pipeline/src/spot.rs#L582), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`core/dr-pipeline/src/state.rs:103`](../core/dr-pipeline/src/state.rs#L103), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`core/dr-pipeline/tests/spots.rs:1`](../core/dr-pipeline/tests/spots.rs#L1), [`ui/dr-ui/src/develop.rs:2271`](../ui/dr-ui/src/develop.rs#L2271), [`ui/dr-ui/src/develop.rs:2309`](../ui/dr-ui/src/develop.rs#L2309), [`ui/dr-ui/src/develop.rs:2374`](../ui/dr-ui/src/develop.rs#L2374), [`ui/dr-ui/src/develop.rs:2457`](../ui/dr-ui/src/develop.rs#L2457), [`ui/dr-ui/src/develop.rs:2471`](../ui/dr-ui/src/develop.rs#L2471), [`ui/dr-ui/src/develop.rs:756`](../ui/dr-ui/src/develop.rs#L756), [`ui/dr-ui/src/labels.rs:52`](../ui/dr-ui/src/labels.rs#L52), [`ui/dr-ui/src/lib.rs:1521`](../ui/dr-ui/src/lib.rs#L1521), [`ui/dr-ui/src/lib.rs:2521`](../ui/dr-ui/src/lib.rs#L2521), [`ui/dr-ui/src/lib.rs:325`](../ui/dr-ui/src/lib.rs#L325), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/src/spots_ui.rs:1`](../ui/dr-ui/src/spots_ui.rs#L1), [`ui/dr-ui/src/spots_ui.rs:265`](../ui/dr-ui/src/spots_ui.rs#L265), [`ui/dr-ui/ui/adjust.slint:810`](../ui/dr-ui/ui/adjust.slint#L810), [`ui/dr-ui/ui/app.slint:109`](../ui/dr-ui/ui/app.slint#L109), [`ui/dr-ui/ui/app.slint:1752`](../ui/dr-ui/ui/app.slint#L1752), [`ui/dr-ui/ui/app.slint:1927`](../ui/dr-ui/ui/app.slint#L1927), [`ui/dr-ui/ui/app.slint:2270`](../ui/dr-ui/ui/app.slint#L2270), [`ui/dr-ui/ui/spots.slint:180`](../ui/dr-ui/ui/spots.slint#L180), [`ui/dr-ui/ui/spots.slint:48`](../ui/dr-ui/ui/spots.slint#L48), [`ui/dr-ui/ui/spots.slint:5`](../ui/dr-ui/ui/spots.slint#L5) | -| FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2088`](../core/dr-gpu/src/adjust.rs#L2088), [`core/dr-gpu/src/adjust.rs:2165`](../core/dr-gpu/src/adjust.rs#L2165), [`core/dr-gpu/src/adjust.rs:2250`](../core/dr-gpu/src/adjust.rs#L2250), [`core/dr-gpu/src/adjust.rs:54`](../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:156`](../core/dr-gpu/src/lib.rs#L156), [`core/dr-gpu/src/lib.rs:176`](../core/dr-gpu/src/lib.rs#L176), [`core/dr-gpu/src/lib.rs:54`](../core/dr-gpu/src/lib.rs#L54), [`core/dr-gpu/src/lib.rs:77`](../core/dr-gpu/src/lib.rs#L77), [`core/dr-gpu/tests/capture_sharpen.rs:200`](../core/dr-gpu/tests/capture_sharpen.rs#L200), [`core/dr-gpu/tests/detail_stage.rs:328`](../core/dr-gpu/tests/detail_stage.rs#L328), [`core/dr-gpu/tests/local_contrast.rs:264`](../core/dr-gpu/tests/local_contrast.rs#L264), [`core/dr-gpu/tests/noise_reduction.rs:378`](../core/dr-gpu/tests/noise_reduction.rs#L378), [`core/dr-pipeline/src/detail.rs:136`](../core/dr-pipeline/src/detail.rs#L136), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/graph.rs:547`](../core/dr-pipeline/src/graph.rs#L547), [`core/dr-pipeline/src/graph.rs:577`](../core/dr-pipeline/src/graph.rs#L577), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:659`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L659), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/local_contrast.rs:971`](../core/dr-pipeline/src/ops/local_contrast.rs#L971), [`core/dr-pipeline/src/ops/noise_reduction.rs:700`](../core/dr-pipeline/src/ops/noise_reduction.rs#L700), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`ui/dr-ui/src/develop.rs:2795`](../ui/dr-ui/src/develop.rs#L2795), [`ui/dr-ui/src/develop.rs:4019`](../ui/dr-ui/src/develop.rs#L4019), [`ui/dr-ui/src/develop.rs:4502`](../ui/dr-ui/src/develop.rs#L4502), [`ui/dr-ui/src/develop.rs:4536`](../ui/dr-ui/src/develop.rs#L4536), [`ui/dr-ui/src/lib.rs:73`](../ui/dr-ui/src/lib.rs#L73), [`ui/dr-ui/src/lib.rs:810`](../ui/dr-ui/src/lib.rs#L810), [`ui/dr-ui/src/lib.rs:869`](../ui/dr-ui/src/lib.rs#L869) | +| FR-DEV-8 | [`core/dr-gpu/src/detail.rs:387`](../core/dr-gpu/src/detail.rs#L387), [`core/dr-gpu/src/detail.rs:592`](../core/dr-gpu/src/detail.rs#L592), [`core/dr-gpu/tests/detail_instances.rs:1`](../core/dr-gpu/tests/detail_instances.rs#L1), [`core/dr-gpu/tests/spot_removal.rs:1`](../core/dr-gpu/tests/spot_removal.rs#L1), [`core/dr-pipeline/src/detail.rs:410`](../core/dr-pipeline/src/detail.rs#L410), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:469`](../core/dr-pipeline/src/detail.rs#L469), [`core/dr-pipeline/src/detail.rs:555`](../core/dr-pipeline/src/detail.rs#L555), [`core/dr-pipeline/src/graph.rs:114`](../core/dr-pipeline/src/graph.rs#L114), [`core/dr-pipeline/src/graph.rs:192`](../core/dr-pipeline/src/graph.rs#L192), [`core/dr-pipeline/src/graph.rs:686`](../core/dr-pipeline/src/graph.rs#L686), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:554`](../core/dr-pipeline/src/operation.rs#L554), [`core/dr-pipeline/src/sidecar.rs:184`](../core/dr-pipeline/src/sidecar.rs#L184), [`core/dr-pipeline/src/sidecar.rs:353`](../core/dr-pipeline/src/sidecar.rs#L353), [`core/dr-pipeline/src/sidecar.rs:673`](../core/dr-pipeline/src/sidecar.rs#L673), [`core/dr-pipeline/src/sidecar.rs:809`](../core/dr-pipeline/src/sidecar.rs#L809), [`core/dr-pipeline/src/sidecar.rs:863`](../core/dr-pipeline/src/sidecar.rs#L863), [`core/dr-pipeline/src/sidecar.rs:893`](../core/dr-pipeline/src/sidecar.rs#L893), [`core/dr-pipeline/src/spot.rs:115`](../core/dr-pipeline/src/spot.rs#L115), [`core/dr-pipeline/src/spot.rs:151`](../core/dr-pipeline/src/spot.rs#L151), [`core/dr-pipeline/src/spot.rs:1`](../core/dr-pipeline/src/spot.rs#L1), [`core/dr-pipeline/src/spot.rs:207`](../core/dr-pipeline/src/spot.rs#L207), [`core/dr-pipeline/src/spot.rs:387`](../core/dr-pipeline/src/spot.rs#L387), [`core/dr-pipeline/src/spot.rs:472`](../core/dr-pipeline/src/spot.rs#L472), [`core/dr-pipeline/src/spot.rs:582`](../core/dr-pipeline/src/spot.rs#L582), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`core/dr-pipeline/src/state.rs:103`](../core/dr-pipeline/src/state.rs#L103), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`core/dr-pipeline/tests/spots.rs:1`](../core/dr-pipeline/tests/spots.rs#L1), [`ui/dr-ui/src/develop.rs:2271`](../ui/dr-ui/src/develop.rs#L2271), [`ui/dr-ui/src/develop.rs:2309`](../ui/dr-ui/src/develop.rs#L2309), [`ui/dr-ui/src/develop.rs:2374`](../ui/dr-ui/src/develop.rs#L2374), [`ui/dr-ui/src/develop.rs:2457`](../ui/dr-ui/src/develop.rs#L2457), [`ui/dr-ui/src/develop.rs:2471`](../ui/dr-ui/src/develop.rs#L2471), [`ui/dr-ui/src/develop.rs:756`](../ui/dr-ui/src/develop.rs#L756), [`ui/dr-ui/src/labels.rs:52`](../ui/dr-ui/src/labels.rs#L52), [`ui/dr-ui/src/lib.rs:1521`](../ui/dr-ui/src/lib.rs#L1521), [`ui/dr-ui/src/lib.rs:2521`](../ui/dr-ui/src/lib.rs#L2521), [`ui/dr-ui/src/lib.rs:325`](../ui/dr-ui/src/lib.rs#L325), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/src/spots_ui.rs:1`](../ui/dr-ui/src/spots_ui.rs#L1), [`ui/dr-ui/src/spots_ui.rs:265`](../ui/dr-ui/src/spots_ui.rs#L265), [`ui/dr-ui/ui/adjust.slint:810`](../ui/dr-ui/ui/adjust.slint#L810), [`ui/dr-ui/ui/app.slint:109`](../ui/dr-ui/ui/app.slint#L109), [`ui/dr-ui/ui/app.slint:1752`](../ui/dr-ui/ui/app.slint#L1752), [`ui/dr-ui/ui/app.slint:1927`](../ui/dr-ui/ui/app.slint#L1927), [`ui/dr-ui/ui/app.slint:2270`](../ui/dr-ui/ui/app.slint#L2270), [`ui/dr-ui/ui/spots.slint:180`](../ui/dr-ui/ui/spots.slint#L180), [`ui/dr-ui/ui/spots.slint:48`](../ui/dr-ui/ui/spots.slint#L48), [`ui/dr-ui/ui/spots.slint:5`](../ui/dr-ui/ui/spots.slint#L5) | +| FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2088`](../core/dr-gpu/src/adjust.rs#L2088), [`core/dr-gpu/src/adjust.rs:2165`](../core/dr-gpu/src/adjust.rs#L2165), [`core/dr-gpu/src/adjust.rs:2250`](../core/dr-gpu/src/adjust.rs#L2250), [`core/dr-gpu/src/adjust.rs:54`](../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:157`](../core/dr-gpu/src/lib.rs#L157), [`core/dr-gpu/src/lib.rs:177`](../core/dr-gpu/src/lib.rs#L177), [`core/dr-gpu/src/lib.rs:55`](../core/dr-gpu/src/lib.rs#L55), [`core/dr-gpu/src/lib.rs:78`](../core/dr-gpu/src/lib.rs#L78), [`core/dr-gpu/tests/capture_sharpen.rs:200`](../core/dr-gpu/tests/capture_sharpen.rs#L200), [`core/dr-gpu/tests/detail_stage.rs:328`](../core/dr-gpu/tests/detail_stage.rs#L328), [`core/dr-gpu/tests/local_contrast.rs:264`](../core/dr-gpu/tests/local_contrast.rs#L264), [`core/dr-gpu/tests/noise_reduction.rs:378`](../core/dr-gpu/tests/noise_reduction.rs#L378), [`core/dr-pipeline/src/detail.rs:136`](../core/dr-pipeline/src/detail.rs#L136), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/graph.rs:548`](../core/dr-pipeline/src/graph.rs#L548), [`core/dr-pipeline/src/graph.rs:578`](../core/dr-pipeline/src/graph.rs#L578), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:659`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L659), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/local_contrast.rs:971`](../core/dr-pipeline/src/ops/local_contrast.rs#L971), [`core/dr-pipeline/src/ops/noise_reduction.rs:700`](../core/dr-pipeline/src/ops/noise_reduction.rs#L700), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`ui/dr-ui/src/develop.rs:2795`](../ui/dr-ui/src/develop.rs#L2795), [`ui/dr-ui/src/develop.rs:4019`](../ui/dr-ui/src/develop.rs#L4019), [`ui/dr-ui/src/develop.rs:4502`](../ui/dr-ui/src/develop.rs#L4502), [`ui/dr-ui/src/develop.rs:4536`](../ui/dr-ui/src/develop.rs#L4536), [`ui/dr-ui/src/lib.rs:73`](../ui/dr-ui/src/lib.rs#L73), [`ui/dr-ui/src/lib.rs:810`](../ui/dr-ui/src/lib.rs#L810), [`ui/dr-ui/src/lib.rs:869`](../ui/dr-ui/src/lib.rs#L869) | | FR-DSP-3 | [`core/dr-gpu/tests/frame_budget.rs:101`](../core/dr-gpu/tests/frame_budget.rs#L101), [`core/dr-gpu/tests/local_contrast.rs:329`](../core/dr-gpu/tests/local_contrast.rs#L329), [`core/dr-pipeline/src/ops/local_contrast.rs:447`](../core/dr-pipeline/src/ops/local_contrast.rs#L447) | | FR-DSP-5 | [`core/dr-gpu/tests/frame_budget.rs:101`](../core/dr-gpu/tests/frame_budget.rs#L101), [`core/dr-gpu/tests/zoom_resolution.rs:135`](../core/dr-gpu/tests/zoom_resolution.rs#L135), [`core/dr-gpu/tests/zoom_resolution.rs:166`](../core/dr-gpu/tests/zoom_resolution.rs#L166), [`core/dr-gpu/tests/zoom_resolution.rs:1`](../core/dr-gpu/tests/zoom_resolution.rs#L1), [`core/dr-gpu/tests/zoom_resolution.rs:216`](../core/dr-gpu/tests/zoom_resolution.rs#L216) | | FR-DSP-6 | [`core/dr-pipeline/src/operation.rs:483`](../core/dr-pipeline/src/operation.rs#L483), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop.rs:2825`](../ui/dr-ui/src/develop.rs#L2825), [`ui/dr-ui/src/develop.rs:5794`](../ui/dr-ui/src/develop.rs#L5794), [`ui/dr-ui/src/lib.rs:1477`](../ui/dr-ui/src/lib.rs#L1477), [`ui/dr-ui/src/lib.rs:2840`](../ui/dr-ui/src/lib.rs#L2840) | | FR-DSP-7 | [`core/dr-gpu/src/histogram.rs:147`](../core/dr-gpu/src/histogram.rs#L147), [`core/dr-gpu/src/histogram.rs:1`](../core/dr-gpu/src/histogram.rs#L1), [`core/dr-gpu/src/histogram.rs:281`](../core/dr-gpu/src/histogram.rs#L281), [`core/dr-gpu/src/histogram.rs:50`](../core/dr-gpu/src/histogram.rs#L50), [`core/dr-gpu/src/shaders/histogram.wgsl:1`](../core/dr-gpu/src/shaders/histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:2874`](../ui/dr-ui/src/develop.rs#L2874), [`ui/dr-ui/src/develop.rs:5604`](../ui/dr-ui/src/develop.rs#L5604), [`ui/dr-ui/src/develop.rs:5636`](../ui/dr-ui/src/develop.rs#L5636), [`ui/dr-ui/src/develop.rs:719`](../ui/dr-ui/src/develop.rs#L719), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/lib.rs:1577`](../ui/dr-ui/src/lib.rs#L1577), [`ui/dr-ui/src/lib.rs:315`](../ui/dr-ui/src/lib.rs#L315), [`ui/dr-ui/ui/app.slint:69`](../ui/dr-ui/ui/app.slint#L69), [`ui/dr-ui/ui/histogram.slint:122`](../ui/dr-ui/ui/histogram.slint#L122), [`ui/dr-ui/ui/histogram.slint:1`](../ui/dr-ui/ui/histogram.slint#L1) | | FR-DSP-8 | [`platform/dr-plat/src/display.rs:1`](../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/display/icc.rs:1`](../platform/dr-plat/src/display/icc.rs#L1), [`platform/dr-plat/src/display/wayland.rs:1`](../platform/dr-plat/src/display/wayland.rs#L1), [`platform/dr-plat/src/display/x11.rs:1`](../platform/dr-plat/src/display/x11.rs#L1), [`ui/dr-ui/src/develop.rs:2771`](../ui/dr-ui/src/develop.rs#L2771), [`ui/dr-ui/src/develop.rs:2825`](../ui/dr-ui/src/develop.rs#L2825), [`ui/dr-ui/src/develop.rs:5794`](../ui/dr-ui/src/develop.rs#L5794), [`ui/dr-ui/src/develop.rs:5840`](../ui/dr-ui/src/develop.rs#L5840), [`ui/dr-ui/src/develop.rs:5859`](../ui/dr-ui/src/develop.rs#L5859), [`ui/dr-ui/src/develop.rs:787`](../ui/dr-ui/src/develop.rs#L787), [`ui/dr-ui/src/display_ui.rs:192`](../ui/dr-ui/src/display_ui.rs#L192), [`ui/dr-ui/src/display_ui.rs:1`](../ui/dr-ui/src/display_ui.rs#L1), [`ui/dr-ui/src/display_ui.rs:325`](../ui/dr-ui/src/display_ui.rs#L325), [`ui/dr-ui/src/display_ui.rs:346`](../ui/dr-ui/src/display_ui.rs#L346), [`ui/dr-ui/src/display_ui.rs:379`](../ui/dr-ui/src/display_ui.rs#L379), [`ui/dr-ui/src/lib.rs:1451`](../ui/dr-ui/src/lib.rs#L1451), [`ui/dr-ui/src/lib.rs:1477`](../ui/dr-ui/src/lib.rs#L1477), [`ui/dr-ui/src/lib.rs:2817`](../ui/dr-ui/src/lib.rs#L2817), [`ui/dr-ui/src/lib.rs:2840`](../ui/dr-ui/src/lib.rs#L2840), [`ui/dr-ui/ui/app.slint:1612`](../ui/dr-ui/ui/app.slint#L1612), [`ui/dr-ui/ui/app.slint:48`](../ui/dr-ui/ui/app.slint#L48), [`ui/dr-ui/ui/settings.slint:120`](../ui/dr-ui/ui/settings.slint#L120), [`ui/dr-ui/ui/settings.slint:772`](../ui/dr-ui/ui/settings.slint#L772) | | FR-EXP-1 | [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | -| FR-EXP-2 | [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/error.rs:26`](../core/dr-export/src/error.rs#L26), [`core/dr-export/src/icc.rs:1`](../core/dr-export/src/icc.rs#L1), [`core/dr-export/src/lib.rs:153`](../core/dr-export/src/lib.rs#L153), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/lib.rs:53`](../core/dr-export/src/lib.rs#L53), [`core/dr-gpu/src/adjust.rs:2398`](../core/dr-gpu/src/adjust.rs#L2398), [`core/dr-pipeline/src/graph.rs:537`](../core/dr-pipeline/src/graph.rs#L537), [`core/dr-pipeline/src/graph.rs:591`](../core/dr-pipeline/src/graph.rs#L591), [`core/dr-pipeline/src/operation.rs:483`](../core/dr-pipeline/src/operation.rs#L483), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`core/dr-types/src/settings.rs:600`](../core/dr-types/src/settings.rs#L600), [`ui/dr-ui/src/develop.rs:5859`](../ui/dr-ui/src/develop.rs#L5859), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | +| FR-EXP-2 | [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/error.rs:26`](../core/dr-export/src/error.rs#L26), [`core/dr-export/src/icc.rs:1`](../core/dr-export/src/icc.rs#L1), [`core/dr-export/src/lib.rs:153`](../core/dr-export/src/lib.rs#L153), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/lib.rs:53`](../core/dr-export/src/lib.rs#L53), [`core/dr-gpu/src/adjust.rs:2398`](../core/dr-gpu/src/adjust.rs#L2398), [`core/dr-pipeline/src/graph.rs:538`](../core/dr-pipeline/src/graph.rs#L538), [`core/dr-pipeline/src/graph.rs:592`](../core/dr-pipeline/src/graph.rs#L592), [`core/dr-pipeline/src/operation.rs:483`](../core/dr-pipeline/src/operation.rs#L483), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`core/dr-types/src/settings.rs:600`](../core/dr-types/src/settings.rs#L600), [`ui/dr-ui/src/develop.rs:5859`](../ui/dr-ui/src/develop.rs#L5859), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | | FR-EXP-3 | [`core/dr-export/src/lib.rs:182`](../core/dr-export/src/lib.rs#L182), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/size.rs:136`](../core/dr-export/src/size.rs#L136), [`core/dr-export/src/size.rs:1`](../core/dr-export/src/size.rs#L1), [`core/dr-export/src/size.rs:25`](../core/dr-export/src/size.rs#L25), [`core/dr-export/src/size.rs:84`](../core/dr-export/src/size.rs#L84), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`core/dr-types/src/settings.rs:645`](../core/dr-types/src/settings.rs#L645), [`core/dr-types/src/settings.rs:653`](../core/dr-types/src/settings.rs#L653), [`core/dr-types/src/settings.rs:669`](../core/dr-types/src/settings.rs#L669), [`core/dr-types/src/settings.rs:738`](../core/dr-types/src/settings.rs#L738), [`core/dr-types/src/settings.rs:766`](../core/dr-types/src/settings.rs#L766), [`core/dr-types/src/settings.rs:777`](../core/dr-types/src/settings.rs#L777), [`core/dr-types/src/settings.rs:783`](../core/dr-types/src/settings.rs#L783), [`ui/dr-ui/src/settings_ui.rs:199`](../ui/dr-ui/src/settings_ui.rs#L199), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/src/settings_ui.rs:212`](../ui/dr-ui/src/settings_ui.rs#L212), [`ui/dr-ui/src/settings_ui.rs:227`](../ui/dr-ui/src/settings_ui.rs#L227), [`ui/dr-ui/src/settings_ui.rs:557`](../ui/dr-ui/src/settings_ui.rs#L557), [`ui/dr-ui/ui/settings.slint:675`](../ui/dr-ui/ui/settings.slint#L675), [`ui/dr-ui/ui/settings.slint:685`](../ui/dr-ui/ui/settings.slint#L685) | | FR-EXP-4 | [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/sharpen.rs:1`](../core/dr-export/src/sharpen.rs#L1), [`core/dr-export/src/size.rs:1`](../core/dr-export/src/size.rs#L1), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | | FR-EXP-5 | [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | @@ -87,7 +88,7 @@ _None._ | FR-EXP-9 | [`core/dr-decode/src/lib.rs:506`](../core/dr-decode/src/lib.rs#L506), [`core/dr-export/src/lib.rs:128`](../core/dr-export/src/lib.rs#L128), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-gpu/src/adjust.rs:1068`](../core/dr-gpu/src/adjust.rs#L1068), [`ui/dr-ui/src/develop.rs:2956`](../ui/dr-ui/src/develop.rs#L2956), [`ui/dr-ui/src/lib.rs:415`](../ui/dr-ui/src/lib.rs#L415) | | FR-NC-1 | [`core/dr-sync-nextcloud/src/auth.rs:132`](../core/dr-sync-nextcloud/src/auth.rs#L132), [`core/dr-sync-nextcloud/src/auth.rs:44`](../core/dr-sync-nextcloud/src/auth.rs#L44), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1), [`core/dr-sync/src/account.rs:355`](../core/dr-sync/src/account.rs#L355), [`ui/dr-ui/src/launch.rs:277`](../ui/dr-ui/src/launch.rs#L277), [`ui/dr-ui/src/launch.rs:61`](../ui/dr-ui/src/launch.rs#L61), [`ui/dr-ui/src/launch_ui.rs:417`](../ui/dr-ui/src/launch_ui.rs#L417) | | FR-NC-10 | [`core/dr-sync/src/account.rs:220`](../core/dr-sync/src/account.rs#L220), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:477`](../ui/dr-ui/src/lib.rs#L477), [`ui/dr-ui/src/library.rs:1068`](../ui/dr-ui/src/library.rs#L1068), [`ui/dr-ui/src/library.rs:1823`](../ui/dr-ui/src/library.rs#L1823), [`ui/dr-ui/src/library.rs:543`](../ui/dr-ui/src/library.rs#L543), [`ui/dr-ui/src/library.rs:844`](../ui/dr-ui/src/library.rs#L844), [`ui/dr-ui/src/library_ui.rs:1622`](../ui/dr-ui/src/library_ui.rs#L1622), [`ui/dr-ui/src/library_ui.rs:3375`](../ui/dr-ui/src/library_ui.rs#L3375), [`ui/dr-ui/src/library_ui.rs:504`](../ui/dr-ui/src/library_ui.rs#L504), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | -| FR-NC-12 | [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:39`](../core/dr-sync-nextcloud/src/lib.rs#L39), [`core/dr-sync-nextcloud/src/lib.rs:913`](../core/dr-sync-nextcloud/src/lib.rs#L913), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1), [`core/dr-sync/src/account.rs:1`](../core/dr-sync/src/account.rs#L1), [`core/dr-sync/src/account.rs:81`](../core/dr-sync/src/account.rs#L81), [`core/dr-sync/src/lib.rs:218`](../core/dr-sync/src/lib.rs#L218), [`core/dr-sync/src/lib.rs:51`](../core/dr-sync/src/lib.rs#L51), [`core/dr-sync/src/provider.rs:106`](../core/dr-sync/src/provider.rs#L106), [`core/dr-sync/src/provider.rs:1`](../core/dr-sync/src/provider.rs#L1), [`core/dr-sync/src/provider.rs:53`](../core/dr-sync/src/provider.rs#L53), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`ui/dr-ui/src/remote.rs:1`](../ui/dr-ui/src/remote.rs#L1) | +| FR-NC-12 | [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:40`](../core/dr-sync-nextcloud/src/lib.rs#L40), [`core/dr-sync-nextcloud/src/lib.rs:914`](../core/dr-sync-nextcloud/src/lib.rs#L914), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1), [`core/dr-sync/src/account.rs:1`](../core/dr-sync/src/account.rs#L1), [`core/dr-sync/src/account.rs:81`](../core/dr-sync/src/account.rs#L81), [`core/dr-sync/src/lib.rs:218`](../core/dr-sync/src/lib.rs#L218), [`core/dr-sync/src/lib.rs:51`](../core/dr-sync/src/lib.rs#L51), [`core/dr-sync/src/provider.rs:106`](../core/dr-sync/src/provider.rs#L106), [`core/dr-sync/src/provider.rs:1`](../core/dr-sync/src/provider.rs#L1), [`core/dr-sync/src/provider.rs:53`](../core/dr-sync/src/provider.rs#L53), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`ui/dr-ui/src/remote.rs:1`](../ui/dr-ui/src/remote.rs#L1) | | FR-NC-13 | [`core/dr-sync-folder/src/lib.rs:197`](../core/dr-sync-folder/src/lib.rs#L197), [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-folder/src/lib.rs:73`](../core/dr-sync-folder/src/lib.rs#L73), [`core/dr-sync/src/provider.rs:106`](../core/dr-sync/src/provider.rs#L106), [`ui/dr-ui/src/launch_ui.rs:316`](../ui/dr-ui/src/launch_ui.rs#L316), [`ui/dr-ui/src/remote.rs:1`](../ui/dr-ui/src/remote.rs#L1) | | FR-NC-2 | [`core/dr-sync/src/account.rs:1`](../core/dr-sync/src/account.rs#L1), [`core/dr-sync/src/account.rs:298`](../core/dr-sync/src/account.rs#L298), [`core/dr-sync/src/account.rs:355`](../core/dr-sync/src/account.rs#L355), [`core/dr-sync/src/account.rs:59`](../core/dr-sync/src/account.rs#L59), [`platform/dr-plat/src/secrets.rs:82`](../platform/dr-plat/src/secrets.rs#L82) | | FR-NC-3 | [`core/dr-decode/src/locate.rs:1`](../core/dr-decode/src/locate.rs#L1), [`core/dr-decode/src/preview.rs:148`](../core/dr-decode/src/preview.rs#L148), [`core/dr-sync/src/capability.rs:85`](../core/dr-sync/src/capability.rs#L85), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library.rs:2848`](../ui/dr-ui/src/library.rs#L2848), [`ui/dr-ui/src/library.rs:3356`](../ui/dr-ui/src/library.rs#L3356), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1), [`ui/dr-ui/src/library_ui.rs:3627`](../ui/dr-ui/src/library_ui.rs#L3627), [`ui/dr-ui/src/library_ui.rs:4592`](../ui/dr-ui/src/library_ui.rs#L4592), [`ui/dr-ui/ui/app.slint:348`](../ui/dr-ui/ui/app.slint#L348), [`ui/dr-ui/ui/settings.slint:384`](../ui/dr-ui/ui/settings.slint#L384), [`ui/dr-ui/ui/settings.slint:72`](../ui/dr-ui/ui/settings.slint#L72) | @@ -97,11 +98,12 @@ _None._ | FR-NC-6a | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/cache.rs:225`](../core/dr-catalog/src/cache.rs#L225), [`core/dr-catalog/src/schema.rs:1014`](../core/dr-catalog/src/schema.rs#L1014), [`core/dr-catalog/src/schema.rs:613`](../core/dr-catalog/src/schema.rs#L613), [`core/dr-sync-folder/src/borrow.rs:1`](../core/dr-sync-folder/src/borrow.rs#L1), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/collections_ui.rs:3174`](../ui/dr-ui/src/collections_ui.rs#L3174), [`ui/dr-ui/src/collections_ui.rs:621`](../ui/dr-ui/src/collections_ui.rs#L621), [`ui/dr-ui/src/collections_ui.rs:683`](../ui/dr-ui/src/collections_ui.rs#L683), [`ui/dr-ui/src/lib.rs:1860`](../ui/dr-ui/src/lib.rs#L1860), [`ui/dr-ui/src/lib.rs:2903`](../ui/dr-ui/src/lib.rs#L2903), [`ui/dr-ui/src/library.rs:1449`](../ui/dr-ui/src/library.rs#L1449), [`ui/dr-ui/src/library.rs:1472`](../ui/dr-ui/src/library.rs#L1472), [`ui/dr-ui/src/library.rs:1747`](../ui/dr-ui/src/library.rs#L1747), [`ui/dr-ui/src/library_ui.rs:1065`](../ui/dr-ui/src/library_ui.rs#L1065), [`ui/dr-ui/src/library_ui.rs:1138`](../ui/dr-ui/src/library_ui.rs#L1138), [`ui/dr-ui/src/library_ui.rs:1239`](../ui/dr-ui/src/library_ui.rs#L1239), [`ui/dr-ui/src/library_ui.rs:1294`](../ui/dr-ui/src/library_ui.rs#L1294), [`ui/dr-ui/src/library_ui.rs:1429`](../ui/dr-ui/src/library_ui.rs#L1429), [`ui/dr-ui/src/library_ui.rs:1547`](../ui/dr-ui/src/library_ui.rs#L1547), [`ui/dr-ui/src/library_ui.rs:2074`](../ui/dr-ui/src/library_ui.rs#L2074), [`ui/dr-ui/src/library_ui.rs:273`](../ui/dr-ui/src/library_ui.rs#L273), [`ui/dr-ui/src/library_ui.rs:284`](../ui/dr-ui/src/library_ui.rs#L284), [`ui/dr-ui/src/library_ui.rs:292`](../ui/dr-ui/src/library_ui.rs#L292), [`ui/dr-ui/src/library_ui.rs:304`](../ui/dr-ui/src/library_ui.rs#L304), [`ui/dr-ui/src/library_ui.rs:313`](../ui/dr-ui/src/library_ui.rs#L313), [`ui/dr-ui/src/library_ui.rs:405`](../ui/dr-ui/src/library_ui.rs#L405), [`ui/dr-ui/src/library_ui.rs:415`](../ui/dr-ui/src/library_ui.rs#L415), [`ui/dr-ui/src/library_ui.rs:457`](../ui/dr-ui/src/library_ui.rs#L457), [`ui/dr-ui/src/library_ui.rs:520`](../ui/dr-ui/src/library_ui.rs#L520), [`ui/dr-ui/src/library_ui.rs:5318`](../ui/dr-ui/src/library_ui.rs#L5318), [`ui/dr-ui/src/library_ui.rs:5336`](../ui/dr-ui/src/library_ui.rs#L5336), [`ui/dr-ui/src/library_ui.rs:5348`](../ui/dr-ui/src/library_ui.rs#L5348), [`ui/dr-ui/src/library_ui.rs:551`](../ui/dr-ui/src/library_ui.rs#L551), [`ui/dr-ui/src/library_ui.rs:563`](../ui/dr-ui/src/library_ui.rs#L563), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/ui/app.slint:2443`](../ui/dr-ui/ui/app.slint#L2443), [`ui/dr-ui/ui/app.slint:463`](../ui/dr-ui/ui/app.slint#L463), [`ui/dr-ui/ui/collections.slint:249`](../ui/dr-ui/ui/collections.slint#L249), [`ui/dr-ui/ui/collections.slint:369`](../ui/dr-ui/ui/collections.slint#L369), [`ui/dr-ui/ui/collections.slint:52`](../ui/dr-ui/ui/collections.slint#L52), [`ui/dr-ui/ui/collections.slint:682`](../ui/dr-ui/ui/collections.slint#L682), [`ui/dr-ui/ui/collections.slint:84`](../ui/dr-ui/ui/collections.slint#L84), [`ui/dr-ui/ui/icons.slint:260`](../ui/dr-ui/ui/icons.slint#L260), [`ui/dr-ui/ui/library.slint:997`](../ui/dr-ui/ui/library.slint#L997) | | FR-NC-6b | [`ui/dr-ui/src/library_ui.rs:1294`](../ui/dr-ui/src/library_ui.rs#L1294) | | FR-NC-6c | [`core/dr-catalog/src/cache.rs:225`](../core/dr-catalog/src/cache.rs#L225), [`core/dr-sync-folder/src/borrow.rs:1`](../core/dr-sync-folder/src/borrow.rs#L1), [`core/dr-sync-folder/src/lib.rs:197`](../core/dr-sync-folder/src/lib.rs#L197), [`core/dr-sync-folder/src/lib.rs:73`](../core/dr-sync-folder/src/lib.rs#L73), [`core/dr-sync-folder/src/lib.rs:803`](../core/dr-sync-folder/src/lib.rs#L803), [`core/dr-sync-folder/src/lib.rs:842`](../core/dr-sync-folder/src/lib.rs#L842), [`core/dr-sync-folder/src/vfs.rs:1`](../core/dr-sync-folder/src/vfs.rs#L1), [`core/dr-sync-nextcloud/src/desktop_client.rs:167`](../core/dr-sync-nextcloud/src/desktop_client.rs#L167), [`core/dr-sync-nextcloud/src/desktop_client.rs:30`](../core/dr-sync-nextcloud/src/desktop_client.rs#L30), [`core/dr-sync/src/capability.rs:41`](../core/dr-sync/src/capability.rs#L41), [`core/dr-sync/src/error.rs:39`](../core/dr-sync/src/error.rs#L39), [`core/dr-sync/src/lib.rs:158`](../core/dr-sync/src/lib.rs#L158), [`core/dr-sync/src/types.rs:101`](../core/dr-sync/src/types.rs#L101), [`core/dr-types/src/lib.rs:120`](../core/dr-types/src/lib.rs#L120), [`core/dr-types/src/lib.rs:202`](../core/dr-types/src/lib.rs#L202), [`ui/dr-ui/src/activity.rs:1`](../ui/dr-ui/src/activity.rs#L1), [`ui/dr-ui/src/collections_ui.rs:3174`](../ui/dr-ui/src/collections_ui.rs#L3174), [`ui/dr-ui/src/collections_ui.rs:621`](../ui/dr-ui/src/collections_ui.rs#L621), [`ui/dr-ui/src/collections_ui.rs:683`](../ui/dr-ui/src/collections_ui.rs#L683), [`ui/dr-ui/src/derived_sync.rs:555`](../ui/dr-ui/src/derived_sync.rs#L555), [`ui/dr-ui/src/derived_sync.rs:627`](../ui/dr-ui/src/derived_sync.rs#L627), [`ui/dr-ui/src/library.rs:1569`](../ui/dr-ui/src/library.rs#L1569), [`ui/dr-ui/src/library.rs:1659`](../ui/dr-ui/src/library.rs#L1659), [`ui/dr-ui/src/library.rs:3138`](../ui/dr-ui/src/library.rs#L3138), [`ui/dr-ui/src/library.rs:3476`](../ui/dr-ui/src/library.rs#L3476), [`ui/dr-ui/src/library.rs:948`](../ui/dr-ui/src/library.rs#L948), [`ui/dr-ui/src/library_ui.rs:1065`](../ui/dr-ui/src/library_ui.rs#L1065), [`ui/dr-ui/src/library_ui.rs:1138`](../ui/dr-ui/src/library_ui.rs#L1138), [`ui/dr-ui/src/library_ui.rs:1337`](../ui/dr-ui/src/library_ui.rs#L1337), [`ui/dr-ui/src/remote.rs:40`](../ui/dr-ui/src/remote.rs#L40), [`ui/dr-ui/ui/collections.slint:249`](../ui/dr-ui/ui/collections.slint#L249), [`ui/dr-ui/ui/collections.slint:682`](../ui/dr-ui/ui/collections.slint#L682), [`ui/dr-ui/ui/icons.slint:260`](../ui/dr-ui/ui/icons.slint#L260) | -| FR-NC-7 | [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:104`](../core/dr-sync-nextcloud/src/lib.rs#L104), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/library.rs:3356`](../ui/dr-ui/src/library.rs#L3356), [`ui/dr-ui/src/library_ui.rs:3627`](../ui/dr-ui/src/library_ui.rs#L3627), [`ui/dr-ui/ui/settings.slint:384`](../ui/dr-ui/ui/settings.slint#L384) | +| FR-NC-6d | [`core/dr-sync-folder/src/borrow.rs:1`](../core/dr-sync-folder/src/borrow.rs#L1), [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-folder/src/vfs.rs:1`](../core/dr-sync-folder/src/vfs.rs#L1) | +| FR-NC-7 | [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:105`](../core/dr-sync-nextcloud/src/lib.rs#L105), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/library.rs:3356`](../ui/dr-ui/src/library.rs#L3356), [`ui/dr-ui/src/library_ui.rs:3627`](../ui/dr-ui/src/library_ui.rs#L3627), [`ui/dr-ui/ui/settings.slint:384`](../ui/dr-ui/ui/settings.slint#L384) | | FR-NC-7a | [`core/dr-ingest/src/layout.rs:1`](../core/dr-ingest/src/layout.rs#L1), [`core/dr-sync/src/upload.rs:1`](../core/dr-sync/src/upload.rs#L1), [`core/dr-sync/src/upload.rs:40`](../core/dr-sync/src/upload.rs#L40), [`core/dr-types/src/settings.rs:116`](../core/dr-types/src/settings.rs#L116), [`ui/dr-ui/src/import.rs:1`](../ui/dr-ui/src/import.rs#L1), [`ui/dr-ui/src/import.rs:97`](../ui/dr-ui/src/import.rs#L97), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1176`](../ui/dr-ui/src/lib.rs#L1176), [`ui/dr-ui/ui/import.slint:5`](../ui/dr-ui/ui/import.slint#L5) | | FR-NC-7b | [`core/dr-ingest/src/lib.rs:733`](../core/dr-ingest/src/lib.rs#L733), [`core/dr-sync/src/upload.rs:1`](../core/dr-sync/src/upload.rs#L1), [`ui/dr-ui/src/import.rs:122`](../ui/dr-ui/src/import.rs#L122), [`ui/dr-ui/src/import.rs:336`](../ui/dr-ui/src/import.rs#L336), [`ui/dr-ui/src/import.rs:584`](../ui/dr-ui/src/import.rs#L584), [`ui/dr-ui/src/import.rs:97`](../ui/dr-ui/src/import.rs#L97), [`ui/dr-ui/src/import_ui.rs:1`](../ui/dr-ui/src/import_ui.rs#L1), [`ui/dr-ui/src/lib.rs:1176`](../ui/dr-ui/src/lib.rs#L1176) | -| FR-NC-8 | [`core/dr-pipeline/src/sidecar.rs:118`](../core/dr-pipeline/src/sidecar.rs#L118), [`core/dr-pipeline/src/sidecar.rs:92`](../core/dr-pipeline/src/sidecar.rs#L92), [`ui/dr-ui/src/lib.rs:1830`](../ui/dr-ui/src/lib.rs#L1830), [`ui/dr-ui/src/library.rs:459`](../ui/dr-ui/src/library.rs#L459), [`ui/dr-ui/src/library_ui.rs:472`](../ui/dr-ui/src/library_ui.rs#L472) | -| FR-NC-9 | [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/schema.rs:556`](../core/dr-catalog/src/schema.rs#L556), [`core/dr-catalog/src/sync.rs:1`](../core/dr-catalog/src/sync.rs#L1), [`core/dr-pipeline/src/sidecar.rs:156`](../core/dr-pipeline/src/sidecar.rs#L156), [`core/dr-pipeline/src/sidecar.rs:183`](../core/dr-pipeline/src/sidecar.rs#L183), [`core/dr-pipeline/src/sidecar.rs:2033`](../core/dr-pipeline/src/sidecar.rs#L2033), [`core/dr-pipeline/src/sidecar.rs:352`](../core/dr-pipeline/src/sidecar.rs#L352), [`core/dr-pipeline/src/sidecar.rs:450`](../core/dr-pipeline/src/sidecar.rs#L450), [`core/dr-pipeline/src/spot.rs:245`](../core/dr-pipeline/src/spot.rs#L245), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`ui/dr-ui/src/derived_sync.rs:555`](../ui/dr-ui/src/derived_sync.rs#L555), [`ui/dr-ui/src/library.rs:844`](../ui/dr-ui/src/library.rs#L844), [`ui/dr-ui/src/library.rs:998`](../ui/dr-ui/src/library.rs#L998) | +| FR-NC-8 | [`core/dr-pipeline/src/sidecar.rs:119`](../core/dr-pipeline/src/sidecar.rs#L119), [`core/dr-pipeline/src/sidecar.rs:93`](../core/dr-pipeline/src/sidecar.rs#L93), [`ui/dr-ui/src/lib.rs:1830`](../ui/dr-ui/src/lib.rs#L1830), [`ui/dr-ui/src/library.rs:459`](../ui/dr-ui/src/library.rs#L459), [`ui/dr-ui/src/library_ui.rs:472`](../ui/dr-ui/src/library_ui.rs#L472) | +| FR-NC-9 | [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/schema.rs:556`](../core/dr-catalog/src/schema.rs#L556), [`core/dr-catalog/src/sync.rs:1`](../core/dr-catalog/src/sync.rs#L1), [`core/dr-pipeline/src/sidecar.rs:157`](../core/dr-pipeline/src/sidecar.rs#L157), [`core/dr-pipeline/src/sidecar.rs:184`](../core/dr-pipeline/src/sidecar.rs#L184), [`core/dr-pipeline/src/sidecar.rs:2034`](../core/dr-pipeline/src/sidecar.rs#L2034), [`core/dr-pipeline/src/sidecar.rs:353`](../core/dr-pipeline/src/sidecar.rs#L353), [`core/dr-pipeline/src/sidecar.rs:451`](../core/dr-pipeline/src/sidecar.rs#L451), [`core/dr-pipeline/src/spot.rs:245`](../core/dr-pipeline/src/spot.rs#L245), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`ui/dr-ui/src/derived_sync.rs:555`](../ui/dr-ui/src/derived_sync.rs#L555), [`ui/dr-ui/src/library.rs:844`](../ui/dr-ui/src/library.rs#L844), [`ui/dr-ui/src/library.rs:998`](../ui/dr-ui/src/library.rs#L998) | | FR-PLAT-AND-1 | [`core/dr-types/src/lib.rs:54`](../core/dr-types/src/lib.rs#L54), [`platform/dr-plat/src/volumes.rs:62`](../platform/dr-plat/src/volumes.rs#L62) | | FR-PLAT-AND-3 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1) | | FR-PLAT-LIN-1 | [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`platform/dr-plat/src/storage.rs:344`](../platform/dr-plat/src/storage.rs#L344), [`ui/dr-ui/src/lib.rs:919`](../ui/dr-ui/src/lib.rs#L919), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | @@ -117,33 +119,39 @@ _None._ | FR-UI-3 | [`ui/dr-ui/src/develop.rs:2200`](../ui/dr-ui/src/develop.rs#L2200), [`ui/dr-ui/src/develop.rs:2309`](../ui/dr-ui/src/develop.rs#L2309), [`ui/dr-ui/src/library_ui.rs:4387`](../ui/dr-ui/src/library_ui.rs#L4387), [`ui/dr-ui/src/masks_ui.rs:218`](../ui/dr-ui/src/masks_ui.rs#L218), [`ui/dr-ui/src/masks_ui.rs:908`](../ui/dr-ui/src/masks_ui.rs#L908), [`ui/dr-ui/src/masks_ui.rs:930`](../ui/dr-ui/src/masks_ui.rs#L930), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/ui/app.slint:1849`](../ui/dr-ui/ui/app.slint#L1849), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/collections.slint:682`](../ui/dr-ui/ui/collections.slint#L682), [`ui/dr-ui/ui/masks.slint:490`](../ui/dr-ui/ui/masks.slint#L490) | | FR-UI-4 | [`ui/dr-ui/src/collections_ui.rs:1005`](../ui/dr-ui/src/collections_ui.rs#L1005), [`ui/dr-ui/src/collections_ui.rs:118`](../ui/dr-ui/src/collections_ui.rs#L118), [`ui/dr-ui/src/collections_ui.rs:131`](../ui/dr-ui/src/collections_ui.rs#L131), [`ui/dr-ui/src/collections_ui.rs:1488`](../ui/dr-ui/src/collections_ui.rs#L1488), [`ui/dr-ui/src/collections_ui.rs:1502`](../ui/dr-ui/src/collections_ui.rs#L1502), [`ui/dr-ui/src/collections_ui.rs:1548`](../ui/dr-ui/src/collections_ui.rs#L1548), [`ui/dr-ui/src/collections_ui.rs:159`](../ui/dr-ui/src/collections_ui.rs#L159), [`ui/dr-ui/src/collections_ui.rs:1646`](../ui/dr-ui/src/collections_ui.rs#L1646), [`ui/dr-ui/src/collections_ui.rs:1673`](../ui/dr-ui/src/collections_ui.rs#L1673), [`ui/dr-ui/src/collections_ui.rs:485`](../ui/dr-ui/src/collections_ui.rs#L485), [`ui/dr-ui/src/collections_ui.rs:514`](../ui/dr-ui/src/collections_ui.rs#L514), [`ui/dr-ui/src/collections_ui.rs:582`](../ui/dr-ui/src/collections_ui.rs#L582), [`ui/dr-ui/src/collections_ui.rs:995`](../ui/dr-ui/src/collections_ui.rs#L995), [`ui/dr-ui/src/library_ui.rs:4387`](../ui/dr-ui/src/library_ui.rs#L4387), [`ui/dr-ui/src/library_ui.rs:4432`](../ui/dr-ui/src/library_ui.rs#L4432), [`ui/dr-ui/src/library_ui.rs:4535`](../ui/dr-ui/src/library_ui.rs#L4535), [`ui/dr-ui/src/library_ui.rs:4563`](../ui/dr-ui/src/library_ui.rs#L4563), [`ui/dr-ui/src/library_ui.rs:5336`](../ui/dr-ui/src/library_ui.rs#L5336), [`ui/dr-ui/src/library_ui.rs:5348`](../ui/dr-ui/src/library_ui.rs#L5348), [`ui/dr-ui/ui/app.slint:1689`](../ui/dr-ui/ui/app.slint#L1689), [`ui/dr-ui/ui/app.slint:469`](../ui/dr-ui/ui/app.slint#L469), [`ui/dr-ui/ui/app.slint:500`](../ui/dr-ui/ui/app.slint#L500), [`ui/dr-ui/ui/library.slint:1219`](../ui/dr-ui/ui/library.slint#L1219), [`ui/dr-ui/ui/library.slint:1226`](../ui/dr-ui/ui/library.slint#L1226), [`ui/dr-ui/ui/library.slint:1232`](../ui/dr-ui/ui/library.slint#L1232), [`ui/dr-ui/ui/library.slint:2335`](../ui/dr-ui/ui/library.slint#L2335), [`ui/dr-ui/ui/library.slint:829`](../ui/dr-ui/ui/library.slint#L829), [`ui/dr-ui/ui/library.slint:882`](../ui/dr-ui/ui/library.slint#L882), [`ui/dr-ui/ui/library.slint:901`](../ui/dr-ui/ui/library.slint#L901) | | FR-UI-5 | [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/lib.rs:2486`](../ui/dr-ui/src/lib.rs#L2486), [`ui/dr-ui/src/lib.rs:3024`](../ui/dr-ui/src/lib.rs#L3024), [`ui/dr-ui/src/lib.rs:3209`](../ui/dr-ui/src/lib.rs#L3209), [`ui/dr-ui/src/masks_ui.rs:863`](../ui/dr-ui/src/masks_ui.rs#L863), [`ui/dr-ui/ui/app.slint:90`](../ui/dr-ui/ui/app.slint#L90), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4) | +| FR-UI-6 | [`ui/dr-ui/ui/widgets.slint:1`](../ui/dr-ui/ui/widgets.slint#L1) | | FR-UI-7 | [`core/dr-pipeline/src/descriptor.rs:177`](../core/dr-pipeline/src/descriptor.rs#L177), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385) | | NFR-ARCH-2 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/library.rs:2953`](../ui/dr-ui/src/library.rs#L2953) | | NFR-ARCH-3 | [`ui/dr-ui/src/export.rs:1553`](../ui/dr-ui/src/export.rs#L1553), [`ui/dr-ui/src/export.rs:1579`](../ui/dr-ui/src/export.rs#L1579), [`ui/dr-ui/src/export.rs:409`](../ui/dr-ui/src/export.rs#L409), [`ui/dr-ui/src/export.rs:435`](../ui/dr-ui/src/export.rs#L435), [`ui/dr-ui/src/lib.rs:2183`](../ui/dr-ui/src/lib.rs#L2183), [`ui/dr-ui/ui/app.slint:1005`](../ui/dr-ui/ui/app.slint#L1005), [`ui/dr-ui/ui/library.slint:951`](../ui/dr-ui/ui/library.slint#L951) | | NFR-ARCH-4 | [`core/dr-catalog/src/error.rs:1`](../core/dr-catalog/src/error.rs#L1), [`core/dr-export/src/error.rs:1`](../core/dr-export/src/error.rs#L1), [`core/dr-thumbs/src/error.rs:1`](../core/dr-thumbs/src/error.rs#L1), [`platform/dr-plat/src/storage.rs:148`](../platform/dr-plat/src/storage.rs#L148), [`ui/dr-ui/src/export.rs:499`](../ui/dr-ui/src/export.rs#L499) | | NFR-OPS-1 | [`tools/traceability/src/lib.rs:266`](../tools/traceability/src/lib.rs#L266) | +| NFR-OPS-3 | [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | | NFR-P1 | [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/scan.rs:1`](../core/dr-catalog/src/scan.rs#L1), [`core/dr-catalog/src/walk.rs:162`](../core/dr-catalog/src/walk.rs#L162), [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`tools/traceability/src/lib.rs:479`](../tools/traceability/src/lib.rs#L479) | | NFR-P13 | [`core/dr-decode/src/preview.rs:121`](../core/dr-decode/src/preview.rs#L121) | | NFR-P5 | [`core/dr-catalog/src/schema.rs:318`](../core/dr-catalog/src/schema.rs#L318), [`ui/dr-ui/src/library.rs:4003`](../ui/dr-ui/src/library.rs#L4003), [`ui/dr-ui/src/library.rs:4795`](../ui/dr-ui/src/library.rs#L4795), [`ui/dr-ui/src/library_ui.rs:4072`](../ui/dr-ui/src/library_ui.rs#L4072), [`ui/dr-ui/src/library_ui.rs:64`](../ui/dr-ui/src/library_ui.rs#L64) | | NFR-P9 | [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/export.rs:942`](../ui/dr-ui/src/export.rs#L942), [`ui/dr-ui/src/library.rs:1`](../ui/dr-ui/src/library.rs#L1), [`ui/dr-ui/src/library_ui.rs:1`](../ui/dr-ui/src/library_ui.rs#L1), [`ui/dr-ui/src/trash.rs:1`](../ui/dr-ui/src/trash.rs#L1) | | NFR-PORT-1 | [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-types/src/lib.rs:270`](../core/dr-types/src/lib.rs#L270), [`core/dr-types/src/lib.rs:303`](../core/dr-types/src/lib.rs#L303), [`platform/dr-plat/src/display.rs:1`](../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/storage.rs:1`](../platform/dr-plat/src/storage.rs#L1), [`platform/dr-plat/src/storage.rs:216`](../platform/dr-plat/src/storage.rs#L216), [`platform/dr-plat/src/storage.rs:287`](../platform/dr-plat/src/storage.rs#L287), [`platform/dr-plat/src/storage.rs:344`](../platform/dr-plat/src/storage.rs#L344), [`platform/dr-plat/src/volumes.rs:1`](../platform/dr-plat/src/volumes.rs#L1), [`platform/dr-plat/src/volumes.rs:62`](../platform/dr-plat/src/volumes.rs#L62) | +| NFR-PORT-2 | [`core/dr-gpu/src/lib.rs:1`](../core/dr-gpu/src/lib.rs#L1) | | NFR-PORT-3 | [`platform/dr-plat/src/storage.rs:1`](../platform/dr-plat/src/storage.rs#L1) | -| NFR-R1 | [`core/dr-catalog/src/sync.rs:1`](../core/dr-catalog/src/sync.rs#L1), [`core/dr-gpu/src/lib.rs:176`](../core/dr-gpu/src/lib.rs#L176), [`core/dr-sync/src/account.rs:220`](../core/dr-sync/src/account.rs#L220), [`ui/dr-ui/src/library.rs:1068`](../ui/dr-ui/src/library.rs#L1068) | +| NFR-R1 | [`core/dr-catalog/src/sync.rs:1`](../core/dr-catalog/src/sync.rs#L1), [`core/dr-gpu/src/lib.rs:177`](../core/dr-gpu/src/lib.rs#L177), [`core/dr-sync/src/account.rs:220`](../core/dr-sync/src/account.rs#L220), [`ui/dr-ui/src/library.rs:1068`](../ui/dr-ui/src/library.rs#L1068) | | NFR-R2 | [`core/dr-catalog/src/trash.rs:1`](../core/dr-catalog/src/trash.rs#L1) | | NFR-R5 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.rs#L1), [`core/dr-catalog/src/error.rs:1`](../core/dr-catalog/src/error.rs#L1), [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1), [`core/dr-catalog/src/schema.rs:1`](../core/dr-catalog/src/schema.rs#L1) | | NFR-R7 | [`core/dr-gpu/src/error.rs:1`](../core/dr-gpu/src/error.rs#L1) | | NFR-R8 | [`core/dr-gpu/src/error.rs:1`](../core/dr-gpu/src/error.rs#L1) | | NFR-RES-1 | [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`ui/dr-ui/src/lib.rs:73`](../ui/dr-ui/src/lib.rs#L73) | -| NFR-RES-4 | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-catalog/src/schema.rs:613`](../core/dr-catalog/src/schema.rs#L613), [`core/dr-gpu/src/lib.rs:77`](../core/dr-gpu/src/lib.rs#L77), [`core/dr-thumbs/src/codec.rs:1`](../core/dr-thumbs/src/codec.rs#L1), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`core/dr-thumbs/src/lib.rs:376`](../core/dr-thumbs/src/lib.rs#L376), [`ui/dr-ui/src/library.rs:2848`](../ui/dr-ui/src/library.rs#L2848) | +| NFR-RES-4 | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-catalog/src/schema.rs:613`](../core/dr-catalog/src/schema.rs#L613), [`core/dr-gpu/src/lib.rs:78`](../core/dr-gpu/src/lib.rs#L78), [`core/dr-thumbs/src/codec.rs:1`](../core/dr-thumbs/src/codec.rs#L1), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`core/dr-thumbs/src/lib.rs:376`](../core/dr-thumbs/src/lib.rs#L376), [`ui/dr-ui/src/library.rs:2848`](../ui/dr-ui/src/library.rs#L2848) | | NFR-SEC-1 | [`core/dr-decode/src/error.rs:1`](../core/dr-decode/src/error.rs#L1) | | NFR-SEC-2 | [`core/dr-sync/src/account.rs:298`](../core/dr-sync/src/account.rs#L298), [`platform/dr-plat/src/secrets.rs:82`](../platform/dr-plat/src/secrets.rs#L82) | +| NFR-SEC-3 | [`core/dr-sync-nextcloud/src/lib.rs:1`](../core/dr-sync-nextcloud/src/lib.rs#L1), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1) | | NFR-SEC-5 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:442`](../core/dr-catalog/src/schema.rs#L442), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | R1 | [`tools/traceability/src/lib.rs:495`](../tools/traceability/src/lib.rs#L495), [`tools/traceability/src/lib.rs:499`](../tools/traceability/src/lib.rs#L499) | -| R4 | [`core/dr-gpu/src/lib.rs:335`](../core/dr-gpu/src/lib.rs#L335) | +| R3 | [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-pipeline/src/lib.rs:1`](../core/dr-pipeline/src/lib.rs#L1) | +| R4 | [`core/dr-gpu/src/lib.rs:336`](../core/dr-gpu/src/lib.rs#L336) | +| R6 | [`core/dr-sync-nextcloud/src/lib.rs:1`](../core/dr-sync-nextcloud/src/lib.rs#L1) | ## Not yet tagged -72 of 179 requirements have no implementation tag. Expected while the codebase is young; each should gain one as it is built. +64 of 179 requirements have no implementation tag. Expected while the codebase is young; each should gain one as it is built.
Show untagged requirements @@ -152,12 +160,10 @@ _None._ - FR-CULL-5 - FR-CULL-6 - FR-CULL-7 -- FR-DEV-1 - FR-DEV-3g - FR-DSP-2 - FR-DSP-4 - FR-NC-11 -- FR-NC-6d - FR-PLAT-AND-2 - FR-PLAT-AND-4 - FR-PLAT-AND-5 @@ -185,7 +191,6 @@ _None._ - FR-PLG-8 - FR-PLG-9 - FR-RAW-2 -- FR-UI-6 - NFR-A11Y-1 - NFR-A11Y-2 - NFR-A11Y-3 @@ -193,7 +198,6 @@ _None._ - NFR-COMPAT-1 - NFR-COMPAT-2 - NFR-OPS-2 -- NFR-OPS-3 - NFR-OPS-4 - NFR-P10 - NFR-P11 @@ -206,18 +210,14 @@ _None._ - NFR-P6 - NFR-P7 - NFR-P8 -- NFR-PORT-2 - NFR-R3 - NFR-R4 - NFR-R6 - NFR-RES-2 - NFR-RES-3 -- NFR-SEC-3 - NFR-SEC-4 - NFR-SEC-6 - R2 -- R3 - R5 -- R6
From 8d5dc423eafa61fb9b28f5640e0212f51a9b6ea4 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 29 Aug 2026 20:36:51 +0200 Subject: [PATCH 5/5] Say that all three of FR-CULL-3's bullets are unbuilt, not one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first draft got this half right and half wrong. It correctly said the existing histogram and clipping indicators are not FR-CULL-3's, but it described them as adjacent — as though the work left were mostly focus peaking and a relocation. They are not adjacent. The histogram reads AdjustPass's 8-bit output and counts clipping as r == 255, so it describes the frame the display is about to show, after the entire develop chain. FR-CULL-3 asks for the histogram of the sensor data, and gives its reason in the requirement itself: a rendered image "systematically lies about what is recoverable in the raw". A readout taken from the render cannot answer that question however it is presented, which means two of the three bullets need a new measurement rather than a new placement. Found by the agent building focus peaking, who had to go looking at the counters to find out. Co-Authored-By: Claude Opus 5 (1M context) --- docs/outstanding.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/outstanding.md b/docs/outstanding.md index 45c6a8f..3e6011e 100644 --- a/docs/outstanding.md +++ b/docs/outstanding.md @@ -73,13 +73,20 @@ somebody reads the matrix. [D11](requirements.md) names culling "the core differentiator". FR-CULL-1, -2, -4 and -8 through -12 are built. Four are not. -**FR-CULL-3 — Raw-truth overlays.** Focus peaking does not exist anywhere; the string appears zero -times in the tree. A histogram and clipping indicators *do* exist, but they are not the ones this -requirement asks for: they live in the develop view under FR-DSP-7, they are threshold readouts -rather than per-pixel overlays on the image, and `develop.rs` says plainly that what they count is -"the levels the display will show" — the pipeline result, not the sensor data. FR-CULL-3 exists -because a culling decision made against a rendered preview is a decision made against the wrong -image. **⟳ in progress** (focus peaking). +**FR-CULL-3 — Raw-truth overlays. All three bullets, unbuilt.** Focus peaking does not exist +anywhere; the string appears zero times in the tree. + +The other two are easy to mistake for present, and are not. A histogram and clipping indicators do +exist — `dr-gpu/src/histogram.rs`, `ui/dr-ui/src/histogram.rs`, the panel in `histogram.slint` — +but they are tagged FR-DSP-7 and they answer the opposite question. They read `AdjustPass`'s 8-bit +output and count clipping as `r == 255`, which is to say they describe **the frame the display is +about to show**, after the whole develop chain has run. FR-CULL-3 asks for the histogram of the +*sensor data*, on the explicit grounds that a rendered image "systematically lies about what is +recoverable in the raw". A readout that measures the render cannot answer that however it is +presented, so this is not a matter of moving an existing widget into the culling view. + +The requirement exists because a culling decision made against a rendered preview is a decision made +against the wrong image, and the whole of it is still to build. **⟳ in progress** (focus peaking). **FR-CULL-5 — Burst and near-duplicate grouping.** Absent. Worth knowing before it is built: `core/dr-face/src/calibrate.rs` already *assumes* it exists — "since FR-CULL-5 already groups