Skip to content

fs-safe 0.18.0

Choose a tag to compare

@github-actions github-actions released this 21 Sep 18:02
· 434 commits to main since this release
v0.18.0
3ba5c95

Highlights

  • Security hardening for Root arguments: explicit paths, payloads, and copy sources take precedence over matching properties in wider options objects. A supplied source Root retains its admission and read policy; directory creation and writable opens keep their internal controls. (#577)
  • More reliable cancellation and failure reporting: tree-copy workers receive cancellation even when caller abort handlers stop event propagation. Secret reads and asynchronous atomic operations preserve their selected failures when best-effort descriptor cleanup also fails. (#561, #566, #545, #554)
  • Reliable Windows publication and ownership checks: keep missing buffered-write destinations absent until complete content is published, including across process interruption, and preserve write-only access when admitting a destination that appears during staging. Permission-query results must explicitly verify owner locality. (#573, #547)
  • Less repeated work in targeted workloads: reduce metadata observations and Promise scheduling in secret reads, Root path resolution, and durable queues; reuse bounded, cleared scratch storage for fallback SHA-256. Measurements show gains in selected Linux read workloads, with workload-specific costs retained in the linked PRs. (#535, #536, #549, #550)
  • Smaller npm installs with intact TypeScript declarations: stop shipping declaration maps that point to unpublished source files. Public declarations and exports remain available. Thanks @vincentkoc. (#570)

Compatibility and upgrade notes

  • Explicit Root arguments remain authoritative even when JavaScript callers or structurally wider TypeScript options include relativePath, data, or source. Enumerable option getters still run and can throw; supported defaults and policy options keep their precedence. This fixes argument selection within the existing filesystem capability contract. (#577, Root contract)
  • Injected Windows permission executors must return valid owner/current-user SIDs, an explicit boolean remote, and complete DACL facts. Missing or nonboolean locality leaves both inspectors unverified; remote: true retains the ACL report but does not grant trusted ownership. (#547, permission-query contract)
  • Descriptor-close behavior remains operation-specific. Synchronous secret readers report a lone close failure before trimming or empty-content validation, while an earlier read or identity failure retains precedence. Atomic best-effort cleanup now treats synchronous adapter throws like rejected close promises; synchronous successful admission, parent-mode admission, and retained descriptor-owner closes keep their existing failure reporting. (#566, #545, #554, atomic cleanup contract)
  • Root path properties are readonly metadata. Each Root retains its originally admitted canonical directory and identity; create another Root to select a different directory. Values in the supplied defaults object remain live for later operations. (#546)

Security hardening and correctness

  • Preserve positional paths and payloads across Root reads, writable opens, writes, creates, appends, removals, and copies, including JSON and streamed wrappers. Keep Root-scoped copy sources authoritative instead of allowing an options property to substitute a raw path. mkdir() and ensureRoot() retain their distinct root-directory rules, and internal removal or writable-open fields cannot replace their caller-owned controls. (#577)
  • Keep missing destinations absent until buffered Windows Root.write() publishes complete content; existing destinations retain their previous bytes during staging. Re-admit raced destinations before replacement, preserving write-only access, link rejection, final authority checks, and cleanup. (#573)
  • Isolate tree-copy cancellation from caller event handlers across native cloning and portable byte-copy fallback. Preserve caller handlers, first-failure selection, and per-file cancellation; join admitted work before releasing descriptors and native signal handlers. Dispatched APFS/Btrfs bulk operations remain uninterruptible, and failed or cancelled copies can leave caller-owned output. (#561, copy cancellation contract)
  • Preserve synchronous secret-read and identity-validation errors, including their causes, when closing the descriptor also fails. Make one close attempt and retain the existing lone-close failure behavior. (#566)
  • Preserve asynchronous copy-source results and destination-admission failures when custom filesystem adapters throw synchronously during best-effort close. Apply the same handling to atomic admission pins, best-effort parent synchronization, and replacement pins that were not adopted, without changing filesystem identity checks or retained-owner close policy. (#545, #554)
  • Reject unverified Windows owner locality while retaining valid local/remote classification, SID-validation precedence, bounded diagnostics, and exact rejected values. Share permission-report metadata across native and command inspection without sharing mutable public results or changing ACL policy. (#547, #567)

Performance and package size

  • Reduce redundant metadata observations and scheduling in secret reads, regular-file admission, and staged publication. An isolated Linux comparison measured readSecretFileSync() about 11% faster; five other measured calls were roughly unchanged. Exact identity and mutation checks remain. (#535)
  • Share Root metadata traversal and reuse normalized missing-path suffixes instead of rebuilding per-component arrays. An isolated Linux/native-off comparison measured roughly 3–4% lower resolver medians, with a slightly higher maximum synchronous sample average. Preserve async/sync canonicalization routes, Windows alias rejection, dangling-link behavior, and observation receipts. (#536, #562)
  • Consolidate durable-queue directory and metadata ownership while retaining asynchronous file I/O, path admission, exact identities, and recovery synchronization. Small and 64 KiB reads measured 8.68% and 13.78% faster in a balanced Linux comparison; durable medians stayed within −1.09% to +1.21%, with isolated higher maxima documented. (#549)
  • Reuse scratch storage between fallback SHA-256 operations, retaining at most four idle buffers of up to 256 KiB each. Clear used contents before retention and keep each pending read's storage exclusive until settlement, including cancellation; preserve byte limits and borrowed descriptor cursors. (#550)
  • Share Windows drive and namespace syntax checks without rewriting whole inputs during network classification. Predicate measurements showed gains for normal Windows paths under Linux with explicit Windows rules and a small rooted-alias cost; they do not establish end-to-end Windows throughput. (#539)
  • Omit .d.ts.map output and package entries whose targets are unpublished TypeScript sources, and make package validation reject those maps. The PR's baseline/candidate comparison measured a 5.8% smaller compressed package and 7.8% smaller unpacked package; declarations and public exports remain intact. Thanks @vincentkoc. (#570)

Maintenance and platform validation

  • Consolidate archive staging, directory admission, temporary ownership, synchronous store receipt chains, lock registration and acquisition, and ordered mutation-denial policy. Preserve authority boundaries, exact identity checks, callback ordering, stale recovery, and publication/cleanup ownership. These are maintenance changes; measured raw-lock overhead and other control tradeoffs remain documented in their PRs. (#535, #537, #538, #542)
  • Specialize private lock, store, JSON retry, filename, rename, and move-cleanup helpers to their existing callers; remove unused descriptor projections and native lock-handle methods. Preserve public defaults, shared validators, Windows device-name protection, root replacement checks, and trash fallback behavior. Share write-policy callback types without changing emitted JavaScript or public type semantics. (#551, #552, #556, #558, #546, #543)
  • Share guest Python operand admission and descriptor cleanup, retain native POSIX beneath-open descriptors until handoff, and use the shared Windows handle owner for process tokens. Simplify native task settlement, SHA-256 worker state, and Unix cleanup forwarding while preserving containment, positioned reads, cancellation checks, handle ownership, and error precedence. (#540, #541, #535, #555, #565)
  • Use existing Windows SDK declarations for native syscalls and verify the built addon's imports in installed npm and pnpm consumers. Share native link/rename admission and the archive entry schema; simplify Windows relative-open policy while preserving source-before-target errors, manifest snapshots, reparse checks, exact created-directory ownership, and hardlink access. (#563, #560, #564, #559)
  • Keep filesystem fixtures and backend settings alive until timed-out operations settle, make the in-flight archive deadline regression deterministic, and exercise queue recovery where directory synchronization is unsupported. Send guest-test stdin only to operations that consume it and give the durable copy-restoration regression its instrumented Windows budget. Expand public mutation proof selection to shared policy/path owners without weakening runtime deadlines or settlement assertions. (#553, #556, #549, #543, #540, #538)

Published packages

Package Registry tarball Verified integrity Provenance
@openclaw/fs-safe-linux-x64-gnu@0.18.0 tgz sha512-nghyt4YhNI7Dep8zXVyG3ITttpkOhwQUC+TGBahfpGeVnRlT6+nsz8lyJwNSeR5j3KasD8hEeBi/a2mYT++yBA== verified attestation
@openclaw/fs-safe-linux-x64-musl@0.18.0 tgz sha512-JLKdDlSLn0FzcUk24fHtXp/FL7Di6FVq9xAtuHdf5BuLHrj7xjGQwuWvUJVfYLSfXQdKXUeUSVb4z+keAa+O3Q== verified attestation
@openclaw/fs-safe-linux-arm64-gnu@0.18.0 tgz sha512-uBJwBv3HZM8OsGIzVU7IVpk5wREpriMfTwLYJ/ZlL2RWcBUAKVdzjgNGm3GiiUnuqdSeQDToEFXF7Xa+JQDrGw== verified attestation
@openclaw/fs-safe-linux-arm64-musl@0.18.0 tgz sha512-6MSz4W1/tdFt9osKKEOi8GazCVNO21Kp9gZkRltRz6EaIkLMY9lzWs7pihygdUkhk4cJ7EJKN4epBu7y6E46JA== verified attestation
@openclaw/fs-safe-darwin-x64@0.18.0 tgz sha512-nQySFyOc4UcLjG3gi7FATR2Nm827v85kZODFQNYVl/77mgwy0JgWGdEhSKOb1K8VcezRqPeo2ZRcJobQ7XjGJg== verified attestation
@openclaw/fs-safe-darwin-arm64@0.18.0 tgz sha512-51CreZp7bBKVBNj4pw3xojnMqIrFgWxplH5F5eHReEVYkIS8hH+c096hOZRS1y5qBcQmxqtnHUbfjtbJNevoZQ== verified attestation
@openclaw/fs-safe-win32-x64-msvc@0.18.0 tgz sha512-V09PsSgniYnk85Omqq01eo1h2drTHBEUJ6pIgOJ9Bj1F/L57qEN+sisditCV9fHDC8YulwHQe9ZT8HyLSu3Fjw== verified attestation
@openclaw/fs-safe@0.18.0 tgz sha512-eSPdJUUIHSPMc0iHwgvONxEtFQ8AwtDGBwWLjOau7THlnL173QArWE9xlsxsOOacAcjG6awVo25IU4D6Dxfzng== verified attestation

Release proof: GitHub Actions run.