Implements the core design: a mount table published as an atomically- swapped snapshot; mem/dir/pack/overlay backends; copy-on-write overlay with copy-up and whiteout deletion; a checksummed append journal; compaction with exact-duplicate elimination; single-writer/wait-free- reader concurrency with a structural/content write split; openat2/ Landlock path containment for dir mounts; and load-time pack integrity validation. Zero required third-party dependencies. Sanitizer testing (ASan/UBSan) caught and led to fixing a genuine heap-use-after-free in the snapshot-reclamation path: the textbook "load pointer, then increment its refcount" pattern left a gap a concurrent writer could free through. Closed with a small reclaim_gate rwlock, documented in internal.h and CLAUDE.md since it's a pattern every refcounted structure in the codebase now follows. zip/tar import/export backends, recommended in concept.md Section 11, will not be built — a permanent project decision recorded in CLAUDE.md since concept.md itself is frozen and cannot be edited to reflect it. Includes a runnable demo (examples/demo.c, `make demo`) exercising the library end to end and proving cross-run persistence through the pack file, plus open-source scaffolding: MIT license, README, CONTRIBUTING, and a CI workflow running the test suite under ASan/UBSan/TSan. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UqJpkdJ6Njnt1pw3CbghzB
62 lines
2.9 KiB
Markdown
62 lines
2.9 KiB
Markdown
# Contributing to PackFS
|
|
|
|
## Before changing anything
|
|
|
|
Read [`concept.md`](concept.md) in full. It is the project's specification,
|
|
not background reading — every backend, lock, and on-disk field in `src/`
|
|
exists because a section of `concept.md` requires it, and most functions'
|
|
comments cite the section they implement rather than re-explaining it.
|
|
`concept.md` is frozen (see [`CLAUDE.md`](CLAUDE.md)): if you believe the
|
|
design itself needs to change, that belongs in a new document that amends
|
|
or supersedes it, not in an edit to `concept.md`.
|
|
|
|
Then read [`CLAUDE.md`](CLAUDE.md), which states the load-bearing constraints
|
|
a change must respect (static linking, the write model, the concurrency
|
|
model, path containment, pack integrity) and the documentation register this
|
|
project is written in.
|
|
|
|
## Workflow
|
|
|
|
```sh
|
|
make test # must pass before any PR
|
|
cc ... -fsanitize=address,undefined # ASan/UBSan: see .github/workflows/ci.yml for exact flags
|
|
cc ... -fsanitize=thread # TSan, for anything touching src/upper.c, src/overlay.c, or src/vfs.c
|
|
```
|
|
|
|
Any change to the concurrency-sensitive files (`upper.c`, `overlay.c`,
|
|
`vfs.c`) must be run under ThreadSanitizer, not just the plain test suite —
|
|
a data race there is exactly the class of bug Section 5 of `concept.md`
|
|
exists to prevent, and the plain build will not surface it.
|
|
|
|
## Scope
|
|
|
|
Changes that add functionality `concept.md` Section 10 lists as explicitly
|
|
out of scope for v0 (full POSIX semantics, enforced permissions/symlinks/hard
|
|
links, cross-process concurrency, content-defined chunking/delta
|
|
compression) should discuss the tradeoff with a maintainer first — those
|
|
exclusions were deliberate design decisions, not gaps waiting to be filled.
|
|
|
|
**`zip` and `tar` import/export backends will not be accepted, full stop —
|
|
not discussed, not behind a flag.** `concept.md` Section 11 recommends them,
|
|
but that recommendation is permanently superseded; see `CLAUDE.md`, "Project
|
|
decisions that supersede concept.md." This is a harder line than the v0
|
|
exclusions above, which are open to future discussion — this one is not.
|
|
|
|
## Static-linking constraint
|
|
|
|
`concept.md` Section 11.1 is a hard constraint: the core must build with
|
|
zero required third-party libraries and zero dynamic loading. In practice
|
|
this project has no optional-dependency boundary at all: `concept.md`
|
|
described one at the `zip`/`tar` backend for `miniz`/`libarchive`, but per
|
|
the decision above, that backend will never exist, so there is no path by
|
|
which a third-party dependency enters this codebase — a change proposing
|
|
one, for any backend, will not be accepted.
|
|
|
|
## Style
|
|
|
|
Match the register already in the file you're editing — precise,
|
|
constraint-labeled comments citing the `concept.md` section they implement,
|
|
no filler. See the "Documentation standard" section of `CLAUDE.md` for the
|
|
full rule; it applies to code comments and commit messages, not only to
|
|
`.md` files.
|