Files
DarkRoom/docs/traceability.md
T
dtourolle f8a718f42e Add Nextcloud connector; reject VFS as a transfer mechanism
Investigated using the Nextcloud desktop client's Virtual Files as a
cache instead of talking to the server directly. Measured on this
machine (client 4.0.7): the configured folder holds 121,785 placeholders
against 10,267 materialised files, including 7,037 CR2 and 9,411 DNG.

Three findings, each independently disqualifying:

  - Linux VFS is *suffix* mode. A dehydrated IMG.CR2 exists only as
    IMG.CR2.nextcloud holding one byte; the real name is absent.
  - Reading a placeholder does not hydrate it. dd of the first 256KB
    returned 1 byte, the stub was unchanged, and the real name never
    appeared. There is no FUSE layer — the stub is an inert marker.
  - Even with hydration the granularity is wrong: VFS has two states,
    1 byte or all bytes, and the preview tier needs a ~256KB prefix of
    a 27MB file. That is ~100x what FR-NC-3 requires.

Recorded as ARCH §9.0. Coexistence is still supported: dr-types now
recognises *.nextcloud stubs, and the viewer lists them as "not
downloaded" rather than as corrupt files or not at all.

So the connector talks to the server directly, as D7 specified.
Implemented: Login Flow v2, PROPFIND with oc:fileid and nc:has-preview,
ETag pruning via a Depth:0 probe, range GET with local slicing when the
server ignores the header, conditional PUT, and /core/preview with
forceIcon=false. delta() returns Unsupported and says why.

Chunked upload v2 is not implemented yet — put() rejects bodies over
5MB explicitly rather than silently truncating.

Two bugs found by testing: my hand-computed epoch in a date test was a
day out (the parser was right), and quick-xml reaches EOF on truncated
input without erroring, so unbalanced elements needed an explicit check
— a half-parsed multistatus must not look like an empty directory.

83 tests passing.
2026-08-09 09:09:27 +02:00

5.7 KiB

Requirements traceability matrix

Denominators are parsed from requirements.md at run time, never hardcoded. Coverage is the intersection of tagged and defined IDs over defined IDs, so it cannot exceed 100%.

Summary

Metric Value
Source files scanned 23
TRACES tags found 30
Requirements defined 143
Requirements covered 32
Coverage 22.4% (32/143)

By type

Type Covered Defined
FR 23 90
NFR 7 47
R 2 6

Orphan tags

A tag naming an ID requirements.md does not define — what renumbering produces, and what a typo produces.

None.

Tagged requirements

ID Tagged in
FR-CAT-1 tools/traceability/src/lib.rs:473, tools/traceability/src/lib.rs:505
FR-CAT-1a core/dr-types/src/lib.rs:23
FR-CAT-2 tools/traceability/src/lib.rs:473
FR-CAT-5 core/dr-decode/src/lib.rs:125
FR-CAT-9 core/dr-types/src/lib.rs:80
FR-CULL-1 core/dr-decode/src/preview.rs:96
FR-CULL-2 core/dr-decode/src/preview.rs:123
FR-DEV-4 core/dr-gpu/src/lib.rs:119
FR-DSP-1 ui/dr-ui/src/lib.rs:21
FR-EXP-9 core/dr-decode/src/lib.rs:151
FR-NC-1 core/dr-sync-nextcloud/src/auth.rs:132, core/dr-sync-nextcloud/src/auth.rs:44
FR-NC-12 core/dr-sync-nextcloud/src/lib.rs:30, core/dr-sync/src/lib.rs:128, core/dr-sync/src/lib.rs:34
FR-NC-3 core/dr-decode/src/preview.rs:123, core/dr-sync/src/capability.rs:41
FR-NC-4 core/dr-sync-nextcloud/src/propfind.rs:100, core/dr-sync-nextcloud/src/propfind.rs:51, core/dr-sync/src/capability.rs:6, core/dr-sync/src/lib.rs:128
FR-NC-5 core/dr-sync-nextcloud/src/propfind.rs:51
FR-NC-6c core/dr-types/src/lib.rs:131, core/dr-types/src/lib.rs:80
FR-PLAT-AND-1 core/dr-types/src/lib.rs:23
FR-RAW-1 core/dr-decode/src/lib.rs:83, core/dr-types/src/lib.rs:90
FR-RAW-3 core/dr-decode/src/lib.rs:151
FR-RAW-4 core/dr-decode/src/error.rs:1
FR-RAW-5 core/dr-decode/src/lib.rs:62
FR-UI-1 ui/dr-ui/src/lib.rs:29
FR-UI-2 ui/dr-ui/src/lib.rs:29
NFR-OPS-1 tools/traceability/src/lib.rs:266
NFR-P1 tools/traceability/src/lib.rs:473
NFR-P13 core/dr-decode/src/preview.rs:96
NFR-R7 core/dr-gpu/src/error.rs:1
NFR-R8 core/dr-gpu/src/error.rs:1
NFR-RES-1 ui/dr-ui/src/lib.rs:21
NFR-SEC-1 core/dr-decode/src/error.rs:1
R1 tools/traceability/src/lib.rs:489, tools/traceability/src/lib.rs:493
R4 core/dr-gpu/src/lib.rs:119

Not yet tagged

111 of 143 requirements have no implementation tag. Expected while the codebase is young; each should gain one as it is built.

Show untagged requirements
  • FR-CAT-10
  • FR-CAT-11
  • FR-CAT-12
  • FR-CAT-13
  • FR-CAT-14
  • FR-CAT-3
  • FR-CAT-4
  • FR-CAT-6
  • FR-CAT-7
  • FR-CAT-8
  • FR-CULL-3
  • FR-CULL-4
  • FR-CULL-5
  • FR-CULL-6
  • FR-CULL-7
  • FR-DEV-1
  • FR-DEV-2
  • FR-DEV-3
  • FR-DEV-3a
  • FR-DEV-3b
  • FR-DEV-3c
  • FR-DEV-3d
  • FR-DEV-3e
  • FR-DEV-3f
  • FR-DEV-3g
  • FR-DEV-5
  • FR-DEV-6
  • FR-DEV-7
  • FR-DEV-8
  • FR-DSP-2
  • FR-DSP-3
  • FR-DSP-4
  • FR-DSP-5
  • FR-DSP-6
  • FR-DSP-7
  • FR-DSP-8
  • FR-EXP-1
  • FR-EXP-2
  • FR-EXP-3
  • FR-EXP-4
  • FR-EXP-5
  • FR-EXP-6
  • FR-EXP-7
  • FR-EXP-8
  • FR-NC-10
  • FR-NC-11
  • FR-NC-2
  • FR-NC-6
  • FR-NC-6a
  • FR-NC-6b
  • FR-NC-7
  • FR-NC-8
  • FR-NC-9
  • FR-PLAT-AND-2
  • FR-PLAT-AND-3
  • FR-PLAT-AND-4
  • FR-PLAT-AND-5
  • FR-PLAT-AND-6
  • FR-PLAT-LIN-1
  • FR-PLAT-LIN-2
  • FR-PLAT-LIN-3
  • FR-RAW-2
  • FR-UI-3
  • FR-UI-4
  • FR-UI-5
  • FR-UI-6
  • FR-UI-7
  • NFR-A11Y-1
  • NFR-A11Y-2
  • NFR-A11Y-3
  • NFR-ARCH-1
  • NFR-ARCH-2
  • NFR-ARCH-3
  • NFR-ARCH-4
  • NFR-COMPAT-1
  • NFR-COMPAT-2
  • NFR-OPS-2
  • NFR-OPS-3
  • NFR-OPS-4
  • NFR-P10
  • NFR-P11
  • NFR-P12
  • NFR-P14
  • NFR-P15
  • NFR-P2
  • NFR-P3
  • NFR-P4
  • NFR-P5
  • NFR-P6
  • NFR-P7
  • NFR-P8
  • NFR-P9
  • NFR-PORT-1
  • NFR-PORT-2
  • NFR-PORT-3
  • NFR-R1
  • NFR-R2
  • NFR-R3
  • NFR-R4
  • NFR-R5
  • NFR-R6
  • NFR-RES-2
  • NFR-RES-3
  • NFR-RES-4
  • NFR-SEC-2
  • NFR-SEC-3
  • NFR-SEC-4
  • R2
  • R3
  • R5
  • R6