Does the target Termux private temporary filesystem accept the run-log open, append, file-flush, and
parent-directory-flush sequence required by PRODUCT.md?
Hypothesis
Opening a new log with O_APPEND | O_NOFOLLOW | O_CLOEXEC, writing intent and result records,
flushing each with fdatasync, and flushing the parent directory with fsync all succeed.
fdatasync(-1) fails with EBADF as a negative control.
Any failed positive operation or successful invalid-descriptor control falsifies the hypothesis.
An initial zig cc attempt failed before running the probe because this Termux Zig invocation did not
find asm/errno.h through its selected headers. Clang targets the installed Android API directly and
compiled the same source without warnings. This tooling failure does not bear on filesystem
capability.
All temporary source, binary, log, and trace files were removed after collecting the observations.
Conclusion
The required open and flush operations are supported on the tested Termux private temporary
filesystem. The result supports capable-platform testing of the specified run-log sequence.
A successful fdatasync or fsync reports kernel acceptance only. This experiment does not prove
survival across power loss, dishonest storage firmware, filesystem bugs, other filesystems, or every
supported Android version. Runtime failure must still block mutation admission or pause execution as
specified.
# Run-log flush capability experiment
## Question
Does the target Termux private temporary filesystem accept the run-log open, append, file-flush, and
parent-directory-flush sequence required by [`PRODUCT.md`](../PRODUCT.md#113-failure-behavior)?
## Hypothesis
Opening a new log with `O_APPEND | O_NOFOLLOW | O_CLOEXEC`, writing intent and result records,
flushing each with `fdatasync`, and flushing the parent directory with `fsync` all succeed.
`fdatasync(-1)` fails with `EBADF` as a negative control.
Any failed positive operation or successful invalid-descriptor control falsifies the hypothesis.
## Environment
- Date: 2026-09-14
- Kernel: Linux 6.1.176 Android 14, AArch64
- Compiler: Clang 21.1.8 targeting `aarch64-unknown-linux-android24`
- Tracer: strace 7.2
- Fixture: a fresh directory below Termux `$TMPDIR`, removed after the probe
## Method
A C17 probe performed this sequence:
1. Open the fixture directory with `O_DIRECTORY | O_CLOEXEC`.
2. Create `run.log` with `O_APPEND | O_NOFOLLOW | O_CLOEXEC` and mode `0600`.
3. Write `intent\n` and call `fdatasync` on the file.
4. Call `fsync` on the parent directory.
5. Write `result\n` and call `fdatasync` on the file.
6. Require `fdatasync(-1)` to fail with `EBADF`.
7. Reopen the file with `O_NOFOLLOW` and verify the exact contents.
The probe compiled with:
```text
clang -std=c17 -Wall -Wextra -Werror -O2 -o probe probe.c
```
The syscall trace used:
```text
strace -e trace=openat,write,fdatasync,fsync,close,read ./probe <fixture>
```
An initial `zig cc` attempt failed before running the probe because this Termux Zig invocation did not
find `asm/errno.h` through its selected headers. Clang targets the installed Android API directly and
compiled the same source without warnings. This tooling failure does not bear on filesystem
capability.
## Observations
The probe exited successfully and reported:
```text
open_no_follow_append=yes
intent_fdatasync=yes
parent_fsync=yes
result_fdatasync=yes
invalid_fd_control=EBADF
content=intent,result
```
The independent syscall trace recorded the required order:
```text
openat(3, "run.log", O_WRONLY|O_CREAT|O_APPEND|O_NOFOLLOW|O_CLOEXEC, 0600) = 4
write(4, "intent\n", 7) = 7
fdatasync(4) = 0
fsync(3) = 0
write(4, "result\n", 7) = 7
fdatasync(4) = 0
fdatasync(-1) = -1 EBADF (Bad file descriptor)
openat(3, "run.log", O_RDONLY|O_NOFOLLOW|O_CLOEXEC) = 4
```
All temporary source, binary, log, and trace files were removed after collecting the observations.
## Conclusion
**The required open and flush operations are supported on the tested Termux private temporary
filesystem.** The result supports capable-platform testing of the specified run-log sequence.
A successful `fdatasync` or `fsync` reports kernel acceptance only. This experiment does not prove
survival across power loss, dishonest storage firmware, filesystem bugs, other filesystems, or every
supported Android version. Runtime failure must still block mutation admission or pause execution as
specified.