N/ NIFT LABS

EXPERIMENT 08 / FILESYSTEM AUTOMATION

Every file.
Every consequence.

A project tree under inspection.
Five runtimes. One verified filesystem.

Nift completes the work.
Bulk checksum and mirror throughput still lag.

Inspect the findings ↓
◉ project/READ · VERIFY · RECONCILE
▾ project/
▾ group00/ … group19/
▾ depth0/ … depth2/
▾ bucket000/

f000000.mdGENERATE

f000001.jsonINSPECT

f000004.datCOPY

↳ output/manifest.tsv ✓ VERIFIED
1,000→10,000→100,000 files
SCAN→INSPECT→SELECT→READ→HASH→TRANSFORM→WRITE

Nift 4.12.0 final candidate · Python 3.15.0 · Node 24.21.0 · Bun 1.4.3 · Go 1.27.2

Follow every path.

A directory walk becomes a runtime workload long before it becomes a bandwidth test.

Traversal scaling
Five runtimes enumerate the same three-level fixture and return a verified path inventory Logarithmic axis; equal vertical steps represent multiplicative changes. SVG ↗
Traversal scaling · booted isolated request, median · ms
WorkloadNiftPythonNodeBunGo
1k files22.8778.96612.03511.7265.619
10k files196.06173.19447.14331.96545.458
100k files2,029.268703.614356.774210.880451.046

Exact values above. On small screens, scroll the table independently →

Metadata has a cost.

Type-only checks acquire size metadata too. The explicit stat workload adds two queries per file.

Metadata scaling
Exists/type/size inspection, with checked metadata inventories Logarithmic axis; equal vertical steps represent multiplicative changes. SVG ↗
Metadata scaling · booted isolated request, median · ms
WorkloadNiftPythonNodeBunGo
1k files34.05613.06319.81316.2659.538
10k files309.684113.802104.88877.53190.535
100k files3,210.5831,177.859886.655670.540845.759

Exact values above. On small screens, scroll the table independently →

Historical 20261011 metadata trace

Logical files10,000
Walk: newfstatat21,373
Stat: newfstatat41,373

Historical20261011 traced requests, not final-candidate counts; linear zero-origin counts. Counts include directory/runtime work. Only four readlinks per trace. Syscall counts do not explain all wall time.

Inspect first. Select second.

Every filter stats every file before selection. Selection percentages describe results, not avoided metadata work.

Filtering / 10k files
Extension .md selects 20%; group00 prefix 5%; size ≥768 bytes 40%. Extension/group/size are correlated Logarithmic axis; equal vertical steps represent multiplicative changes. Bars start at the displayed positive minimum, not zero. SVG ↗
Filtering / 10k files · booted isolated request, median · ms
WorkloadNiftPythonNodeBunGo
Name 1%550.021132.821101.85077.67667.646
Name 10%543.735134.17899.37776.98671.627
Name 50%607.154138.870109.22180.26576.184
Extension378.766105.97192.15970.59270.459
Prefix365.017103.94092.26072.50167.436
Size324.383110.01196.16073.19378.562

Exact values above. On small screens, scroll the table independently →

Small files expose scalar work.

The checksum visits every byte in the language. Large-file reads load the full payload but aggregate endpoints only.

Small-file read + checksum
Portable h=(31h+byte)%1000000007 checksum; noncryptographic; output inventories included Logarithmic axis; equal vertical steps represent multiplicative changes. SVG ↗
Small-file read + checksum · booted isolated request, median · ms
WorkloadNiftPythonNodeBunGo
1k files1,019.024113.84857.19756.24026.617
10k files10,530.1121,127.583408.164421.197249.394
100k files102,441.25911,525.0073,627.6044,062.4302,472.142

Exact values above. On small screens, scroll the table independently →

100 MiB bulk-read contrast
These different contracts isolate a bulk-read contrast, not a subtraction-based estimate of checksum cost Logarithmic axis; equal vertical steps represent multiplicative changes. Bars start at the displayed positive minimum, not zero. SVG ↗
100 MiB bulk-read contrast · booted isolated request, median · ms
WorkloadNiftPythonNodeBunGo
10 × 10 MiB293.85854.38999.72571.54146.997
100 × 1 MiB220.74323.525106.17054.36934.573

Exact values above. On small screens, scroll the table independently →

A fingerprint is not a security digest.

Native SHA-256 is unavailable in this Nift snapshot. The portable checksum cannot substitute for a cryptographic release manifest.

Native SHA-256 / 10k files
— means unavailable; it is not zero or a failed observation Logarithmic axis; equal vertical steps represent multiplicative changes. Bars start at the displayed positive minimum, not zero. SVG ↗
Native SHA-256 / 10k files · booted isolated request, median · ms
WorkloadNiftPythonNodeBunGo
SHA-256—295.954290.092191.766237.422

Exact values above. On small screens, scroll the table independently →

Create. Overwrite. Copy.

Stream writes include source reads; copies verify bytes and paths, not permissions or metadata.

Write and copy
Small stream writes, existing-file overwrite, 100 MiB streams, and a 100k-file copy are distinct contracts Logarithmic axis; equal vertical steps represent multiplicative changes. Bars start at the displayed positive minimum, not zero. SVG ↗
Write and copy · booted isolated request, median · ms
WorkloadNiftPythonNodeBunGo
Create 10k1,961.167927.347701.237747.142675.893
Overwrite 10k2,567.1171,459.3271,207.568464.2821,095.094
10 × 10 MiB407.801152.489218.158169.130155.823
100 × 1 MiB343.660142.333223.981170.532145.462
Copy 100k16,647.78111,739.10912,887.4227,814.1956,175.213

Exact values above. On small screens, scroll the table independently →

Unchanged still means inspected.

Both trees are fingerprinted. Identical destination files retain their timestamps.

source/

keep.md unchanged
~ edit.md new bytes
+ add.dat new path

destination/ → reconciled

keep.md preserve mtime
~ edit.md replace bytes
+ add.dat copy
- old.dat remove
Mirror / 10k files
Mixed =10% content +1% add/delete; add/delete-only =1% replacement paths. Diagram illustrates semantics, not a measured individual filename Logarithmic axis; equal vertical steps represent multiplicative changes. Bars start at the displayed positive minimum, not zero. SVG ↗
Mirror / 10k files · booted isolated request, median · ms
WorkloadNiftPythonNodeBunGo
Clean21,479.6442,640.587923.544936.652543.993
1% content21,048.0032,609.835876.791932.018572.536
10% content21,153.0512,662.650987.168940.122648.510
Mixed20,744.5352,756.055987.482967.749639.076
Add/delete20,726.1052,446.563839.236942.746560.993

Exact values above. On small screens, scroll the table independently →

What changed depends on the contract.

Modification-time access is unavailable in this Nift snapshot. Content and timestamp detection intentionally answer different questions.

Change detection / 10k files
Same 1% selected set: changed bytes/new time; same bytes/new time; changed bytes/restored time. Time-only detection misses restored-time edits; content ignores time-only edits Logarithmic axis; equal vertical steps represent multiplicative changes. Bars start at the displayed positive minimum, not zero. SVG ↗
Change detection / 10k files · booted isolated request, median · ms
WorkloadNiftPythonNodeBunGo
Time: bytes—213.947200.263169.598134.602
Time: time—210.445203.443167.721132.169
Time: restored—213.778197.703170.574135.238
Hash: bytes20,165.3582,151.856718.198791.047416.777
Hash: time21,031.6202,198.582691.207772.116421.593
Hash: restored20,065.5712,154.094713.792847.003417.963

Exact values above. On small screens, scroll the table independently →

The project, end to end.

Generate documents, copy selected assets and produce a sorted manifest. This is controlled project automation, not a website build.

Project workflows / 10k files
Manifest =path/size/portable fingerprint; generate prefixes inputs; mixed ignores group19, generates .md and copies .dat. Traversal still visits ignored paths Logarithmic axis; equal vertical steps represent multiplicative changes. Bars start at the displayed positive minimum, not zero. SVG ↗
Project workflows / 10k files · booted isolated request, median · ms
WorkloadNiftPythonNodeBunGo
Manifest11,105.6031,144.951437.788428.656283.115
Generate13,139.3762,095.6831,150.3731,154.427791.976
Mixed5,921.117940.791578.602513.347348.163

Exact values above. On small screens, scroll the table independently →

Measure the runtime after exec.

Fifteen final-candidate post-exec observations use the original verified walk protocol on a separate four-vCPU / 8 GiB Ubuntu 24.04 Linode of the same plan. Each runtime/size has one observation; these are checkpoints, not a distribution or significance claim.

Post-exec walk high-water mark
Linux /proc VmHWM after exec, exact full walk response and before exit; one verified request per runtime/size, zero warmups; separate final-candidate diagnostic Linear zero-origin axis. SVG ↗
Post-exec walk high-water mark · separate post-exec diagnostic, one verified request per cell · MiB
WorkloadNiftPythonNodeBunGo
1k files8.87520.03953.05527.6484.582
10k files25.72718.81667.12932.75010.180
100k files193.84845.871128.60979.87573.910

Exact values above. On small screens, scroll the table independently →

The separate final noop-child control rose from16.75 to80.75 MiB when its parent allocated64MiB; that confirms why launch-inclusive wait4 accounting is not substituted for these post-exec checkpoints. The fifteen new values use the frozen accepted protocol and pinned peers; no constant has been subtracted.

New final post-exec raw values and identities ↗

Where Nift spends the work.

Historical20261011 profiles and metadata traces below are retained analytical leads, not new final profiles; final exactly-once gates pass.

P0 · CORRECTNESS

One call must mean one call.

The historical reduction printed CALLED three times versus once for a bound result. Finalc14 inline and bound reductions both execute exactly once. The original diagnostic is retained; it is not a current defect.

P1 · METADATA

Reuse what the tree already knows.

The inspector queries status and file size even for type-only checks. Extra 20,000 stat calls accompany the 10k explicit-stat workload. Preserve races, symlinks and error contracts when consolidating.

P1 · ALLOCATION

5,578,191 allocations.

The separate 10k stat heaptrack diagnostic records 1,111,623 temporary allocations. String construction and condition trimming are concrete leads; instrumentation changes timing.

P1/P2 · SCALAR

Bytes become evaluator work.

Read profiles include AST evaluation, RuntimeValue lifetime, loop dispatch and variable lookup. Bulk reads are far less extreme. This motivates decomposition, not a claim that one function explains the gap.

Template Engines also profiled expression/string/allocation work; Concurrency profiled AST/value handling while demonstrating real multicore scaling. A shared value/execution mechanism is plausible, but their differing paths do not establish a single root cause.

Would I choose it?

Usable for bounded Nift-owned automation; large-tree throughput is weak in this snapshot.

Human + agent: Python for new standalone general automation, Go for bulk work, Nift for bounded existing-project operations. Agent-primary: the same conditional choices; explicit ownership/inputs/lifecycle help inspection but autonomous edit/recovery productivity was not measured. For new filesystem or release tooling today, I would choose Python for compact library-driven automation or Go for a maintained standalone utility. Traversal overhead, repeated metadata queries, allocation volume, slow per-byte interpreter work and copy/mirror costs are operational problems. Missing timestamps, native cryptographic hashing and clear recursive cleanup add real contract gaps. Final exactly-once gates pass; side-effect reliability remains essential.

What would change my preference?

Reusable metadata-bearing directory entries; fewer status/size queries; substantially less path/string/value allocation; faster scalar processing; native SHA-256 and timestamps; safe recursive helpers; continued exactly-once reliability; and competitive large-tree scaling. I would retain explicit roots, artifact ownership, lifecycle and independently checkable outputs.

Qualitative preference · present day versus a reliable, capable, competitive Nift
WorkflowTodayMature-Nift counterfactual
Nift-owned projectNift for bounded covered operationsNift: shared policy and lifecycle
Agent-authored automationPython/Go for a new filesystem toolNift: programmable explicit contracts, without another executor underneath
New release toolingPython/Go: hashes, timestamps, cleanupNift for project-attached release policy; Go for standalone delivery
Large tree scannerGo: throughput and typed metadata/errorsNift becomes viable if scaling and memory are genuinely competitive
Portable standalone utilityGo: compiled binary, no installed script runtimeStill often Go: build/distribute per-platform binaries with embedded dependencies

Existing Python or JS module requirements remain specific integration reasons to choose those runtimes. This Linux campaign does not certify Windows paths, symlinks or portability. Explicitness is useful only when the runtime reliably enforces it.

Frozen evidence. Open interpretation.

Official timing remains frozen. A separate fifteen-cell final-candidate diagnostic refreshes the original post-exec memory view without changing its protocol.

Fresh four-vCPU / 8 GiB Ubuntu 24.04 Linode; AMD EPYC 7542; affinity 0–3. Four-CPU affinity. 752 cells; 14,264 measured observations + 752 retained warmups; independent exact/reset/distribution audits passed.

Final candidate: c14d06835bca515a5281e41da0e40219c2d60ef0.

Fresh timing includes launch and exit; booted timing begins after readiness and ends at the complete response. Every observation uses a new runtime. Fixtures are restored, fully read and statted outside timing. Runtime order rotates; no outliers are removed. Full result sets/output SHA-256 checks and independent distribution/reset audits pass. Low-count stress tails are descriptive.

Warm Linux filesystem state, ASCII paths, fixed three-level corpus, no symlink/permission/glob or physical-bandwidth claim. Five file sizes (96–2,048 bytes) and extensions correlate with groups. No fsync or global cache dropping. Output serialization is inside timing; canonical oracle sorting is outside (Nift ls itself sorts).

Frozen identities / timing tails / implementation boundaries

Primary 75e77bb4bb6fb0b8c49920f641c77b394aec5985; supplement 1ab31488eb949eb8f8cd6d50b0eb9fd59e1ad78e; core c14d06835bca515a5281e41da0e40219c2d60ef0. Evidence commit 19e390183b9bcb039abe6aa553ad88a2305b49ee.

All 752 distributions, p95/min/max, commands, source, correctness and implementation boundaries remain in the evidence and full appendix. The launch/lifetime memory accounting limitation is preserved alongside the corrected diagnostic.

Canonical frozen evidence ↗ · Complete distributions ↗ · Core handover ↗