95847e3a31dfc4f9aeb5f7ff97354efb0227c802
NFR-COMPAT-2 asks for the v1 channels to be stated, and says why in its own second sentence: the channel decision and the storage design are coupled. There was nowhere that statement lived. packaging/ held a PKGBUILD and a desktop entry, which is a recipe rather than a decision, and the coupling the requirement points at was therefore invisible. docs/distribution.md states five channels and, more usefully, which two of them exist only as promises. It also records what every channel has to get right independently of format — the one identifier that appears in four places, the metainfo, Vulkan being a requirement rather than a preference while NFR-R8 is open, a secrets daemon being optional rather than required, and the LFS pointer check that stops a package shipping 130 bytes where an 11 MB model should be. §4 is the part worth reading. Preparing a Flatpak is what surfaced that FR-PLAT-LIN-3 is not satisfied and cannot be satisfied by packaging alone: a folder library is chosen by typing an absolute path into an EndpointOnly field that checks it with std::fs, and nothing in the tree calls the FileChooser portal. Inside a sandbox that path does not exist, so the launch screen refuses it. Import fails one step earlier, because a sandboxed process reads its own mount namespace and a card mounted on the host is not in it. That is written down rather than fixed with --filesystem=host, and the argument for not fixing it that way is §2: the Arch package and an AppImage both hand the application the same unrestricted process the developer runs it in, so Flatpak is the only Linux channel that tests whether a design assumed unrestricted access. Granting the permission removes the only reason to ship it. The reverse coupling on Android is recorded too. NFR-COMPAT-2 says Play distribution is what makes ARCH §6.9 binding; §6.9 is verified rather than assumed, so SAF is already unconditional and a sideloaded build would gain nothing by asking for more. Play is deferred over the GPLv3 question, which is a licence-reading exercise and blocks nothing in the storage design. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
DarkRoom
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.
Documentation
| Document | Contents |
|---|---|
| requirements.md | What the software must do — 122 numbered requirements |
| architecture.md | How it is built — crates, GPU pipeline, data model, sync |
| milestone-v0.1.md | The first buildable milestone |
| faces.md | Face detection and identity — the models, the licence problem, and what S14 measures |
Building
Desktop:
cargo run -p darkroom-desktop
Android (containerised toolchain, see docker/android):
./docker/android/build.sh cargo ndk -t arm64-v8a build --release
Current state
Working: workspace, GPU context and compute pass, adaptive Slint shell, Android cross-compilation of the core crates.
Not yet working: the zero-copy display path. The build currently uploads frames through the CPU, which is exactly what ARCH §6.1 forbids — measured at 96% of frame time at 4K. Replacing it is spike S1, the project's highest priority.
cargo run -p dr-gpu --example bench --features readback
reproduces that measurement.
Licence
GPL-3.0-or-later.
Releases
20
DarkRoom 0.24.0
Latest
Languages
Rust
86.1%
Slint
10.3%
Python
1.1%
Shell
1%
WGSL
0.9%
Other
0.6%