Repair the references that point at sections that moved
Eight citations named §5.1, §5.2 and a §5 selector language that requirements.md's §5 has not contained since it became a pointer at architecture.md; two named §9 for the golden images and the benchmark suite, which are §8; and the three pointers into architecture.md were each one section off. All now name the section that holds the thing. architecture.md §12's subsections are numbered 6.1–6.13, colliding with its real §6. That numbering is what every ARCH §6.n citation in the tree uses, so it stays, and a note at the head of §12 says so instead of leaving the next reader to work it out. FR-DEV-3f's open question about persisting the film stock was answered in sidecar.rs; the clause now says so.
This commit is contained in:
@@ -1099,6 +1099,13 @@ architecture; everything else assumes they pass.
|
|||||||
|
|
||||||
Decisions treated as fixed because reversing them is expensive. Each is evidence-backed.
|
Decisions treated as fixed because reversing them is expensive. Each is evidence-backed.
|
||||||
|
|
||||||
|
> **On the numbering.** The subsections below are numbered **6.1–6.13**, not 12.x. They were §6
|
||||||
|
> when this document was first written, and every `ARCH §6.n` citation in `requirements.md`, in
|
||||||
|
> `docs/*.md` and in source comments names them by those numbers. Renumbering would break several
|
||||||
|
> hundred citations for no gain, so the numbers stay: `ARCH §6.1` means the first constraint here,
|
||||||
|
> and never §6.1 of the data architecture above, which is cited as *§6 Data architecture* or by
|
||||||
|
> its title.
|
||||||
|
|
||||||
### 6.1 GPU results never round-trip through the CPU
|
### 6.1 GPU results never round-trip through the CPU
|
||||||
|
|
||||||
darktable identifies this as their single biggest bottleneck: OpenCL output returns to the GTK
|
darktable identifies this as their single biggest bottleneck: OpenCL output returns to the GTK
|
||||||
|
|||||||
+20
-19
@@ -77,7 +77,7 @@ R1 is therefore stated as a bounded tolerance — a defined maximum per-pixel de
|
|||||||
ΔE2000 for colour or ULPs at the working precision. **The threshold must be fixed before spike S9**,
|
ΔE2000 for colour or ULPs at the working precision. **The threshold must be fixed before spike S9**,
|
||||||
because S9 both validates R1 and calibrates what the achievable tolerance actually is.
|
because S9 both validates R1 and calibrates what the achievable tolerance actually is.
|
||||||
|
|
||||||
Where genuine bit-identity is required — cache keys, edit-graph hashing (§5.2 invariant 3) — it
|
Where genuine bit-identity is required — cache keys, edit-graph hashing (ARCH §3.4, ARCH §6.13) — it
|
||||||
applies to *integer* operations on CPU-side state, which are deterministic, never to GPU float
|
applies to *integer* operations on CPU-side state, which are deterministic, never to GPU float
|
||||||
results.
|
results.
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ in the catalog when it was trashed and the path it came from; restore moves it b
|
|||||||
Permanent delete removes the file first and the catalog row second, and a delete of something
|
Permanent delete removes the file first and the catalog row second, and a delete of something
|
||||||
already gone counts as success.
|
already gone counts as success.
|
||||||
|
|
||||||
A flag alone would not survive invariant 5.2.4: the catalog is rebuildable from sources, so a
|
A flag alone would not survive ARCH §6.12 (the catalog is a rebuildable index): the catalog is rebuildable from sources, so a
|
||||||
rescan would find every "deleted" file still in the library and re-index it. The folder is the
|
rescan would find every "deleted" file still in the library and re-index it. The folder is the
|
||||||
durable fact and the row is the convenience — which also means the scanner shall exclude the trash
|
durable fact and the row is the convenience — which also means the scanner shall exclude the trash
|
||||||
folder, and that a user can recover by hand without DarkRoom. Derived data keyed on the file
|
folder, and that a user can recover by hand without DarkRoom. Derived data keyed on the file
|
||||||
@@ -310,7 +310,7 @@ pub trait Operation: Send + Sync {
|
|||||||
/// Parameter values → GPU work. No UI types cross this boundary.
|
/// Parameter values → GPU work. No UI types cross this boundary.
|
||||||
fn encode(&self, enc: &mut ComputeEncoder, ctx: &TileContext);
|
fn encode(&self, enc: &mut ComputeEncoder, ctx: &TileContext);
|
||||||
|
|
||||||
/// Identity for cache invalidation (see §5.2 invariant 3).
|
/// Identity for cache invalidation (see ARCH §3.4, ARCH §6.13).
|
||||||
fn params_hash(&self) -> u64;
|
fn params_hash(&self) -> u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ pub enum WidgetKind {
|
|||||||
```
|
```
|
||||||
|
|
||||||
**The pipeline crate shall not depend on the UI toolkit.** Descriptors carry data, never widgets.
|
**The pipeline crate shall not depend on the UI toolkit.** Descriptors carry data, never widgets.
|
||||||
This keeps the edit chain testable headless (see §9's golden-image tests, which must link no UI)
|
This keeps the edit chain testable headless (see §8's golden-image tests, which must link no UI)
|
||||||
and is what allows one operation to render differently on touch and desktop.
|
and is what allows one operation to render differently on touch and desktop.
|
||||||
|
|
||||||
**FR-DEV-3b — Frontend presentation mapping.** The frontend maps `ParamKind` to a concrete control
|
**FR-DEV-3b — Frontend presentation mapping.** The frontend maps `ParamKind` to a concrete control
|
||||||
@@ -413,8 +413,9 @@ within 0.06 in linear sRGB; the baked lookup's interpolation error stays under o
|
|||||||
value; and the shader agrees with the CPU model, which agrees in turn with an independent
|
value; and the shader agrees with the CPU model, which agrees in turn with an independent
|
||||||
reference implementation.
|
reference implementation.
|
||||||
|
|
||||||
**Open:** how the chosen stock persists. Sidecar parameters are `f32` and the stock list is
|
*Resolved 2026-09-19:* the chosen stock persists **by id** in its own sidecar field, not as a
|
||||||
data-driven, so neither an index nor a name fits the existing shape.
|
parameter — `core/dr-pipeline/src/sidecar.rs` records why an index was rejected (installing a
|
||||||
|
profile would silently change which film every existing photograph was developed on).
|
||||||
|
|
||||||
**FR-DEV-3g — AI denoise.** Learned denoising operating in the raw domain, ideally jointly with
|
**FR-DEV-3g — AI denoise.** Learned denoising operating in the raw domain, ideally jointly with
|
||||||
demosaic.
|
demosaic.
|
||||||
@@ -1155,7 +1156,7 @@ mandatory.
|
|||||||
- **Evidence beside the frame** (added 2026-09-19) — FR-CULL-13's signals, readable at a glance
|
- **Evidence beside the frame** (added 2026-09-19) — FR-CULL-13's signals, readable at a glance
|
||||||
without leaving the mode or opening the frame
|
without leaving the mode or opening the frame
|
||||||
- **The last import as a scope** (added 2026-09-19) — the set a culling session most often starts
|
- **The last import as a scope** (added 2026-09-19) — the set a culling session most often starts
|
||||||
from, reachable in one step and counted, expressed as a term of the §5 selector language rather
|
from, reachable in one step and counted, expressed as a term of the selector language (ARCH §9.2) rather
|
||||||
than as a special collection
|
than as a special collection
|
||||||
|
|
||||||
**FR-CULL-5 — Burst and near-duplicate grouping.** Group frames by capture-time proximity and image
|
**FR-CULL-5 — Burst and near-duplicate grouping.** Group frames by capture-time proximity and image
|
||||||
@@ -1177,7 +1178,7 @@ mobile. Gesture and rating targets must not overlap.
|
|||||||
|
|
||||||
**FR-CULL-13 — Evidence, never verdicts.** Added 2026-09-19; numbered after the people clauses
|
**FR-CULL-13 — Evidence, never verdicts.** Added 2026-09-19; numbered after the people clauses
|
||||||
because it governs them too. Everything the app computes about a frame in aid of culling is
|
because it governs them too. Everything the app computes about a frame in aid of culling is
|
||||||
**evidence**: shown beside the frame, filterable and sortable through the §5 selector language,
|
**evidence**: shown beside the frame, filterable and sortable through the selector language (ARCH §9.2),
|
||||||
and — within a burst — permitted to *propose* which frame represents the group. The signals are
|
and — within a burst — permitted to *propose* which frame represents the group. The signals are
|
||||||
the raw histogram, clipping and focus (FR-CULL-3), burst membership (FR-CULL-5), and per-face eye
|
the raw histogram, clipping and focus (FR-CULL-3), burst membership (FR-CULL-5), and per-face eye
|
||||||
state and head pose (FR-CULL-8a). The list grows by adding to it, never by adding a second kind of
|
state and head pose (FR-CULL-8a). The list grows by adding to it, never by adding a second kind of
|
||||||
@@ -1291,7 +1292,7 @@ as derived data under FR-CULL-12:
|
|||||||
matters, groups and children and events, a turned head is the decision and averted eyes are
|
matters, groups and children and events, a turned head is the decision and averted eyes are
|
||||||
often the better frame.
|
often the better frame.
|
||||||
|
|
||||||
Both are terms in the §5 selector language (FR-CULL-11) — "everyone's eyes open", "facing the
|
Both are terms in the selector language (ARCH §9.2, FR-CULL-11) — "everyone's eyes open", "facing the
|
||||||
camera" — composable with a person and with every other term. Both feed FR-CULL-13's evidence and
|
camera" — composable with a person and with every other term. Both feed FR-CULL-13's evidence and
|
||||||
may propose a burst representative (FR-CULL-5); neither may set a rating or a flag.
|
may propose a burst representative (FR-CULL-5); neither may set a rating or a flag.
|
||||||
|
|
||||||
@@ -1347,7 +1348,7 @@ Confirmation is explicit. A face is either **suggested** (the system's inference
|
|||||||
(the user's judgement), and the two are never conflated in storage or in display. Suggestions may be
|
(the user's judgement), and the two are never conflated in storage or in display. Suggestions may be
|
||||||
recomputed freely; confirmations are user data and are never overwritten by a later inference pass.
|
recomputed freely; confirmations are user data and are never overwritten by a later inference pass.
|
||||||
|
|
||||||
**FR-CULL-11 — People as a selector term.** A person shall be a term in the §5 selector language,
|
**FR-CULL-11 — People as a selector term.** A person shall be a term in the selector language (ARCH §9.2),
|
||||||
composable with every other term.
|
composable with every other term.
|
||||||
|
|
||||||
This is the requirement that pays for the subsystem, and it is nearly free once FR-CULL-10 exists:
|
This is the requirement that pays for the subsystem, and it is nearly free once FR-CULL-10 exists:
|
||||||
@@ -1704,7 +1705,7 @@ the class where it was expressed.
|
|||||||
Everything the photographer produced or navigated to is a different matter, and none of it may be
|
Everything the photographer produced or navigated to is a different matter, and none of it may be
|
||||||
touched by a resize. That is the list in the criterion, and it is the testable half.
|
touched by a resize. That is the list in the criterion, and it is the testable half.
|
||||||
|
|
||||||
**Performance regressions fail the build.** §9's benchmark suite runs per-commit; a regression
|
**Performance regressions fail the build.** §8's benchmark suite runs per-commit; a regression
|
||||||
beyond a stated tolerance is a build failure, not a notification. Performance work rots otherwise.
|
beyond a stated tolerance is a build failure, not a notification. Performance work rots otherwise.
|
||||||
|
|
||||||
### 4.2 Reliability
|
### 4.2 Reliability
|
||||||
@@ -1729,7 +1730,7 @@ ARCH §6.6 already anticipates one migration (folder ETags); there will be other
|
|||||||
exist before the first one.
|
exist before the first one.
|
||||||
|
|
||||||
**NFR-R6 — Corruption recovery.** On failing an integrity check at startup, the app offers restore
|
**NFR-R6 — Corruption recovery.** On failing an integrity check at startup, the app offers restore
|
||||||
from the NFR-R2 backup, and failing that, rebuild from sources plus sidecars per invariant 5.2.4.
|
from the NFR-R2 backup, and failing that, rebuild from sources plus sidecars per ARCH §6.12.
|
||||||
FR-CAT-8 is what makes that second path real for local-only users.
|
FR-CAT-8 is what makes that second path real for local-only users.
|
||||||
|
|
||||||
**NFR-R7 — GPU device loss.** The GPU layer treats device loss as an expected event (ARCH §6.10): detect
|
**NFR-R7 — GPU device loss.** The GPU layer treats device loss as an expected event (ARCH §6.10): detect
|
||||||
@@ -1953,7 +1954,7 @@ more in a colour-grading application than in most software.
|
|||||||
|
|
||||||
Entity definitions, invariants, and all architectural constraints are specified in
|
Entity definitions, invariants, and all architectural constraints are specified in
|
||||||
[architecture.md](architecture.md) — §3 (core abstractions), §6 (data architecture), and
|
[architecture.md](architecture.md) — §3 (core abstractions), §6 (data architecture), and
|
||||||
§11 (architectural constraints).
|
§12 (architectural constraints — whose subsections keep their original 6.x numbers, so `ARCH §6.1` in this document means §12's first constraint, not §6.1 of the data architecture).
|
||||||
|
|
||||||
Requirements in this document that depend on an architectural guarantee cite it inline. The
|
Requirements in this document that depend on an architectural guarantee cite it inline. The
|
||||||
constraints most load-bearing for testability are:
|
constraints most load-bearing for testability are:
|
||||||
@@ -1970,7 +1971,7 @@ constraints most load-bearing for testability are:
|
|||||||
## 6. Decisions
|
## 6. Decisions
|
||||||
|
|
||||||
Rationale, evidence, and the eliminated alternatives are recorded in
|
Rationale, evidence, and the eliminated alternatives are recorded in
|
||||||
[architecture.md §12](architecture.md). Outcomes only:
|
[architecture.md §13](architecture.md). Outcomes only:
|
||||||
|
|
||||||
| # | Decision | Outcome |
|
| # | Decision | Outcome |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
@@ -2173,12 +2174,12 @@ collides with four things this document says.
|
|||||||
aligned by the similarity the face subsystem already fits between two landmark sets and blended
|
aligned by the similarity the face subsystem already fits between two landmark sets and blended
|
||||||
by the membrane heal already shipped. It reopens `spot-removal.md`'s non-goal that the source is
|
by the membrane heal already shipped. It reopens `spot-removal.md`'s non-goal that the source is
|
||||||
"a patch from the same photograph", which would be revised deliberately, not quietly.
|
"a patch from the same photograph", which would be revised deliberately, not quietly.
|
||||||
2. **§5.1, single-source `Image`.** The real one. §7 defers panorama, HDR and focus stacking on the
|
2. **ARCH §6.3, single-source `Image`.** The real one. §7 defers panorama, HDR and focus stacking on the
|
||||||
grounds that the schema cannot express an image derived from several sources. This is that case
|
grounds that the schema cannot express an image derived from several sources. This is that case
|
||||||
in a milder form — the output is still frame A, but A's sidecar now names B — and it brings the
|
in a milder form — the output is still frame A, but A's sidecar now names B — and it brings the
|
||||||
rules the tiers already have: B's original must be present to render A (FR-NC-6c: visible and
|
rules the tiers already have: B's original must be present to render A (FR-NC-6c: visible and
|
||||||
priced before starting), trashing B must know A depends on it (FR-CAT-15), and `Version::merge`
|
priced before starting), trashing B must know A depends on it (FR-CAT-15), and `Version::merge`
|
||||||
has never seen a cross-reference. Reopening §5.1 for this reopens it for the three deferred
|
has never seen a cross-reference. Reopening ARCH §6.3 for this reopens it for the three deferred
|
||||||
rows at once, which is the argument for doing it once and properly rather than for this alone.
|
rows at once, which is the argument for doing it once and properly rather than for this alone.
|
||||||
3. **Tone.** The source patch goes through A's chain, not B's — B demosaiced and run through A's
|
3. **Tone.** The source patch goes through A's chain, not B's — B demosaiced and run through A's
|
||||||
parameters to the head of the detail chain, then sampled. A second small pipeline at proxy
|
parameters to the head of the detail chain, then sampled. A second small pipeline at proxy
|
||||||
@@ -2233,7 +2234,7 @@ note where deferring now constrains the design later.
|
|||||||
| Deferred | Note |
|
| Deferred | Note |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Tethered shooting | — |
|
| Tethered shooting | — |
|
||||||
| Panorama and HDR merge | **Keep the schema open** — these produce images derived from multiple sources, which §5.1's single-source `Image` cannot express. |
|
| Panorama and HDR merge | **Keep the schema open** — these produce images derived from multiple sources, which ARCH §6.3's single-source `Image` cannot express. |
|
||||||
| Focus stacking | Same provenance consideration. |
|
| Focus stacking | Same provenance consideration. |
|
||||||
| Cross-frame face repair ("best take") | A face from a neighbouring frame of the same burst, aligned by its landmarks and blended by FR-DEV-8's heal. Mechanically a spot whose source is another photograph; **the same multi-source schema question as the two rows above, arriving early** — D17. Deferred rather than refused, with its non-goals fixed now: never automatic, geometry not corrected, source frame declared in sidecar, history and export. |
|
| Cross-frame face repair ("best take") | A face from a neighbouring frame of the same burst, aligned by its landmarks and blended by FR-DEV-8's heal. Mechanically a spot whose source is another photograph; **the same multi-source schema question as the two rows above, arriving early** — D17. Deferred rather than refused, with its non-goals fixed now: never automatic, geometry not corrected, source frame declared in sidecar, history and export. |
|
||||||
| Gaze and eye-contact estimation | Every open gaze model read on 2026-09-19 is trained on Gaze360, MPIIGaze or ETH-XGaze, all research-only, and Gaze360's licence restricts *models trained on it* by name — the InsightFace situation again (D13). Head pose from the five landmarks is the proxy (FR-CULL-8a). Revisit when weights with a clean data chain exist; iris offset within the eye crop is the licence-free fallback if the proxy proves too weak. |
|
| Gaze and eye-contact estimation | Every open gaze model read on 2026-09-19 is trained on Gaze360, MPIIGaze or ETH-XGaze, all research-only, and Gaze360's licence restricts *models trained on it* by name — the InsightFace situation again (D13). Head pose from the five landmarks is the proxy (FR-CULL-8a). Revisit when weights with a clean data chain exist; iris offset within the eye crop is the licence-free fallback if the proxy proves too weak. |
|
||||||
@@ -2271,7 +2272,7 @@ note where deferring now constrains the design later.
|
|||||||
| Cancellation (NFR-ARCH-3) | Assert every long-running operation observes cancellation within the stated bound, including in-flight GPU work. |
|
| Cancellation (NFR-ARCH-3) | Assert every long-running operation observes cancellation within the stated bound, including in-flight GPU work. |
|
||||||
| Layer separation (ARCH §6.5a) | CI dependency-tree assertion: no `core/*` crate may transitively depend on a UI toolkit. |
|
| Layer separation (ARCH §6.5a) | CI dependency-tree assertion: no `core/*` crate may transitively depend on a UI toolkit. |
|
||||||
| Operation self-description (FR-DEV-3c) | A test operation added to the registry appears in a generated panel with no frontend change. |
|
| Operation self-description (FR-DEV-3c) | A test operation added to the registry appears in a generated panel with no frontend change. |
|
||||||
| Adaptive layout (§3.5) | Snapshot tests at each breakpoint, and a resize test asserting no state loss across a layout-class transition. |
|
| Adaptive layout (§3.5) | Snapshot tests at each breakpoint, and a resize test asserting no loss of *photographic* state across a layout-class transition — NFR-P11's list, with panel disclosure exempt as that clause says. |
|
||||||
| Touch targets (FR-UI-3) | Automated check that interactive elements meet the 44pt minimum in touch modality. |
|
| Touch targets (FR-UI-3) | Automated check that interactive elements meet the 44pt minimum in touch modality. |
|
||||||
| Export sizing (FR-EXP-3) | Per-mode dimension assertions, including aspect preservation, fill-crop centring, and the upscale-disabled fallback. |
|
| Export sizing (FR-EXP-3) | Per-mode dimension assertions, including aspect preservation, fill-crop centring, and the upscale-disabled fallback. |
|
||||||
| Identity calibration (FR-CULL-9) | Reliability diagram over a hand-labelled corpus: stated probability against observed match rate, asserted within tolerance across the range — not a single accuracy figure, which would hide exactly the miscalibration this tests for. Plus a static assertion that no comparison thresholds a raw similarity. |
|
| Identity calibration (FR-CULL-9) | Reliability diagram over a hand-labelled corpus: stated probability against observed match rate, asserted within tolerance across the range — not a single accuracy figure, which would hide exactly the miscalibration this tests for. Plus a static assertion that no comparison thresholds a raw similarity. |
|
||||||
@@ -2321,7 +2322,7 @@ this revision it was unstated.
|
|||||||
this app category before designing around it is far cheaper than discovering it at submission.
|
this app category before designing around it is far cheaper than discovering it at submission.
|
||||||
|
|
||||||
**S9 moved to Tier 1** because it does not merely test R1 — it *calibrates* it. R1's tolerance
|
**S9 moved to Tier 1** because it does not merely test R1 — it *calibrates* it. R1's tolerance
|
||||||
threshold cannot be fixed sensibly without knowing the real cross-vendor deviation, and the §9
|
threshold cannot be fixed sensibly without knowing the real cross-vendor deviation, and the §8
|
||||||
golden-image strategy depends on that number.
|
golden-image strategy depends on that number.
|
||||||
|
|
||||||
Test S1 on Mesa/AMD, Intel, and NVIDIA proprietary drivers, under both X11 and Wayland. FD-based
|
Test S1 on Mesa/AMD, Intel, and NVIDIA proprietary drivers, under both X11 and Wayland. FD-based
|
||||||
|
|||||||
Reference in New Issue
Block a user