Skip to content

Report mtime and nlink from fs.stat, and mode, mtime and nlink from fs.list - #518

Open
mvanhorn wants to merge 1 commit into
Ephemeral-AI-Lab:mainfrom
mvanhorn:feat/fs-stat-mtime-nlink
Open

mvanhorn wants to merge 1 commit into
Ephemeral-AI-Lab:mainfrom
mvanhorn:feat/fs-stat-mtime-nlink

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Oct 30, 2026 •

Copy link
Copy Markdown

Closes #486.

fs.stat already reports mode. Readers that use only the Store still had to
call it once per directory entry for times and link counts, and it did not
report either. This adds those fields end to end.

What changes

  • fs.stat reports mtimeSeconds, mtimeNanoseconds and nlink beside
    type, inode, size and mode.
  • fs.list entries report mode, mtimeSeconds, mtimeNanoseconds and
    nlink beside name, path, type and inode.
  • nlink is the committed namespace link count: 0 for the root, 1 for any
    other directory or symlink, and the number of names for a regular file.
    Hard-linked names share inode.
  • mtimeSeconds / mtimeNanoseconds are the portable modification time
    (Unix epoch seconds and the fractional second). They are two integers so a
    JavaScript Number keeps them exactly. A single nanosecond timestamp is not a
    safe integer after 1970.
  • Inline portable metadata is still served from the inode value (no object
    read). Root-form metadata uses the listing's existing memo.
  • The listing reply budget per entry is 240 bytes to cover the extra fields.
  • CLI summaries for fs stat and fs list name the new fields.
  • Docs: api/docs/agent.md covers the fields and the listing.

No Store format change: every entry already stores mode, mtime and the
namespace link count. inode was already the hard-link group id.

Commits

  • feature, tests, docs and golden. Production LOC: 102831 -> 102851 (delta +20).

Tests

No test deleted or weakened. The sdk_methods golden adds the new fields to
its fs.stat and fs.list lines; mtime integers are masked as <varies>.

  • New engine/crates/layerfs-api/tests/fs_stat_metadata.rs: Init keeps a
    host mtime and hard link; fs.stat and fs.list agree; a content write's
    mtime reads back; main is untouched.
  • sdk_method_golden, sdk_list_entries, fs_mode, stat_symlink,
    write_refusals: pass.
  • rustfmt, and Clippy -D warnings on layerfs-store-service and
    layerfs-api: clean.
  • JS against the fake binding: api/agent/test/calls.mjs and
    api/cli/test/cli.test.mjs: pass.

Not run: the macOS/Windows worker routes. They forward the same SDK calls and
were not changed.

Author

  • I ran the checks listed above
  • Docs match the implemented fields

Demo

demo

fs.stat now includes mtimeSeconds, mtimeNanoseconds and nlink. Each fs.list
entry includes mode, the same mtime pair, and nlink, so a directory listing
does not need one fs.stat per name. Seconds and nanoseconds stay separate so
a JavaScript Number keeps them exactly. nlink is the committed namespace
link count; hard-linked names share inode.

Inline portable metadata still costs no object read. The listing memo serves
root-form metadata. No Store format change.

New fs_stat_metadata test covers Init mtime, hard links, list/stat agreement
and a content write. Golden, list-cost, mode, symlink and write-refusal tests
pass. Clippy -D warnings on layerfs-store-service and layerfs-api is clean.
Fake-binding SDK and CLI tests pass. Deleted tests: none.

Production LOC: 102831 -> 102851 (delta +20)
First-parent comparison: 35d3657.
Scopes: core 38395 -> 38395 (0), engine 61777 -> 61797 (+20),
api 2659 -> 2659 (0). Engine layerfs-store-service accounts for all +20.
Method: tools/production_loc.py blob 3341e4d,
--json on each snapshot. First-party production Rust, runtime SQL and
JavaScript; tests, docs, tooling, generated and third-party code excluded.
Reference absent (retired R9c; last counted 65,417 at tree 498dd19).
@Mola-maker

Mola-maker commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

感谢贡献,也感谢 AI 协作工具在 #486 的讨论中梳理接口面 🙏

真实评估(已读 diff):fs.stat 增加 mtimeSeconds/mtimeNanoseconds/nlink,fs.list 条目带上同组字段。两个设计决定都对:(1) 秒/纳秒拆成两个整数,避免 JS Number 的精度丢失(>2^53 纳秒时间戳会丢精度)——这正是 #486 讨论里的关键点;(2) nlink 取"已提交命名空间的硬链接名计数"(root 为 0、目录/symlink 为 1),语义写进了 api/docs/agent.md 与新增的 fs_stat_metadata.rs(156 行测试)。硬链接名共享 inode 的既有契约保持。没有发现缺陷。

对 AI agent 的使用价值:agent 遍历大目录(如 node_modules、数据集)时不再需要每个 entry 补一次 fs.stat,扫描类工具调用量直接下降。

建议:合入前在真实环境对含硬链接的树实测一次 fs.list 输出,确认 nlink 与 inode 配对正确。功能性调整等 LayerFS 2.0(#446)发布后再做。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JS SDK: mtime and nlink in fs.stat, and mode, mtime and nlink in fs.list entries

2 participants