Files
packfs/CHANGELOG.md
T
retoorandClaude Sonnet 5 21bcb4640f
CI / build-and-test (push) Failing after 23s
Move CI to Gitea Actions; this project is hosted on Gitea, not GitHub
Per explicit direction: this repository is not going on GitHub. Moved
.github/workflows/ci.yml to .gitea/workflows/ci.yml (Gitea Actions'
convention) and updated every doc that referenced the old path or assumed
GitHub-specific features:

- .gitea/workflows/ci.yml: added a header comment on the two things that
  are genuinely Gitea-specific and instance-dependent, not just a renamed
  file -- `runs-on: ubuntu-latest` must match a label the actual
  registered Gitea runner advertises (there is no GitHub-hosted-runner
  equivalent, this is self-hosted), and `actions/checkout@v4` resolves
  against whatever action source that runner is configured with.
- CONTRIBUTING.md: corrected a claim that no longer holds -- it previously
  said CI "runs on a normal, unrestricted GitHub Actions VM where TSan is
  expected to work"; since this is actually a self-hosted Gitea runner
  whose environment isn't controlled by this repo, that assumption isn't
  something this repo can vouch for, so the text now says so rather than
  carrying the old (GitHub-shaped) assumption forward silently.
- SECURITY.md: removed a claim this project can't back up (that "private
  security advisories" are available once hosted -- that's a GitHub
  feature this repo never had access to); reporting is by direct email to
  the maintainer only.
- README.md: fixed a real gap while in here -- the "Security" section
  never actually linked to SECURITY.md despite it existing since the
  previous commit.
- CLAUDE.md, CHANGELOG.md: updated path references; CLAUDE.md's
  self-evaluation section (a historical record of an audit finding) keeps
  the old .github path where it describes what was literally true at that
  time, with a note explaining the rename, rather than rewriting history.

Verified: clean make all + make test, all 6 binaries pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UqJpkdJ6Njnt1pw3CbghzB
2026-09-14 11:03:20 +00:00

4.3 KiB

Changelog

All notable changes to this project are documented in this file, in the style of Keep a Changelog. This project follows Semantic Versioning; see PACKFS_VERSION_STRING in include/packfs.h for the authoritative current version (packfs.pc, generated by make install, is derived from it, not maintained separately).

This project is pre-release (0.x, an initial, partial implementation of concept.md, not a completed one; see README.md's "Status"). v0.1.0 is tagged locally in this repository's own git history but has not been pushed to any remote — there is no public release yet, only a local one.

[0.1.0] - 2026-09-14

Added

  • Initial implementation of concept.md: vfs_* core, mem/dir/pack backends, the copy-on-write overlay (copy-up, whiteouts, compaction, an append journal), path containment (openat2/Landlock on Linux 5.6+/5.13+, a documented weaker fallback elsewhere), and pack integrity validation.
  • tests/test_*.c covering each backend, concurrency, and randomized structural-index stress testing against an independent reference model.
  • bench/bench.c (make bench) and BENCH.md, comparing PackFS against the host filesystem across metadata operations, large sequential I/O, random-access pack reads, mount-table scaling, and concurrent workloads.
  • PACKFS_VERSION_MAJOR/MINOR/PATCH/STRING and pfs_version() for compile-time and runtime version/ABI checks.
  • packfs.pc (pkg-config), generated by make install from packfs.pc.in, version always derived from include/packfs.h.
  • SPDX-License-Identifier: MIT on every file under src/ and include/.

Fixed

  • Bulk sequential create/unlink/mkdir on mem/dir was O(n²) in file count. The index (UpperSnapshot) was a flat sorted array copied in full on every structural write; rewritten as a persistent treap (src/upper.c), reducing a structural write to the O(log n) nodes on the path to the change. See BENCH.md's "Resolution" for the full before/after measurement and complexity-class confirmation.
  • pack_write's compaction-time exact-duplicate elimination (Section 9.2) was O(n²) in entry count, and trusted a hash match without comparing actual bytes (a latent correctness bug: FNV-1a64 is explicitly not collision-resistant). Rewritten as an open-addressing hash table with a memcmp verification before ever reusing a data_off, fixing both at once. See BENCH.md's "Resolution #2".
  • backend_pack_new was declared in include/packfs.h but never implemented — any program calling it failed at link time. Implemented as a standalone, read-only pack Backend.
  • The CI config's (.gitea/workflows/ci.yml) sanitizer-build steps never passed -D_GNU_SOURCE when compiling test files (only the library object files got it), which was harmless until a test included internal.h (needed for pthread_rwlock_t) and became a link failure.

Changed

  • CI moved from a GitHub-Actions-convention config (.github/workflows/) to Gitea Actions (.gitea/workflows/) — this project is hosted on Gitea, not GitHub, and was never actually hosted on GitHub; only the scaffolding's starting convention changed. SECURITY.md, CLAUDE.md, CONTRIBUTING.md, and README.md updated to match.

Documented

  • vfs.c's mount table (MountSnapshot) is O(n²) in mount count, the same pattern the file index used to have — confirmed, and deliberately left unfixed. Mount counts are bounded by a program's own source code, not workload-driven, so they do not reach the scale that made the file index's O(n²) a real problem. See BENCH.md's "Finding: mount table scaling" for the numbers and reasoning.
  • A ThreadSanitizer environment limitation (some sandboxes block the personality(ADDR_NO_RANDOMIZE) syscall TSan needs) and a related ASan/UBSan sandbox startup flake (AddressSanitizer:DEADLYSIGNAL), both in CONTRIBUTING.md and CLAUDE.md, with the confirming tests and the required mitigation (timeout-wrapped sanitizer runs).