Skip to content

fix(widget-dev): share the folder id helper, say the inode reuse limit, and ask to choose a remade folder again - #660

Merged
mrgoonie merged 2 commits into
mainfrom
fix/643-chosen-folder-identity
Oct 8, 2026
Merged

mrgoonie merged 2 commits into
mainfrom
fix/643-chosen-folder-identity

Conversation

@mrgoonie

@mrgoonie mrgoonie commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

The follow-ups to chosen-folder identity from the review of #641 (#628). Refs #643; official docs in digitopvn/clarkcant-web#143 (not merged), so this PR alone does not close the issue.

What changes, item by item

  1. Inode reuse: documented, no second signal. Evidence gathered on this machine:
    • Windows NTFS: deleting and making a folder again five times at one path gave five different ids (the MFT sequence number moves; the ids differ by 2^48).
    • Linux ext4 (WSL Ubuntu, Node 22): the same loop gave the same inode (1519) every time. Node's birthtimeNs was equal to ctimeNs, and two folders made within one clock tick had the same inode and the same birth time to the nanosecond.
    • libuv reports the change time as birth time when statx is not available, and the change time moves with every file added or removed.
      So birth time cannot tell a remade folder apart, and as a fallback it would break the common case. The limit is now stated in docs/open-interfaces(.vi).md, docs/widget-development(.vi).md, the core helper's comment and the official docs. They also say that a watched folder is held open on Linux and macOS (pinRoot), so the reuse cannot happen while a session watches the folder, and they advise forgetting a folder before deleting it.
  2. Restart re-check. A session Clark started in a chosen folder that was made again stops as root-refused at the next restart. The status line copy (shell.dev.stopReason.root-refused, EN+VI) now says why and to choose the folder again with /develop. The session's row on the develop card now notes that Develop again chooses it. Documented in open-interfaces (EN+VI), widget-development (EN+VI) and the widgetDevStopReasonSchema comment.
  3. One helper. devRootIdentityOf(root, { followLinks? }) is exported from @clarkcant/core: stat by default, as the engine uses it, and lstat with followLinks: false. The runtime's folderIdOf now only converts its result to the store's string form, so the lstat copy is gone. The runtime keeps lstat semantics: a link at the path gives no id. packages/core/test/dev-root-identity.spec.ts covers both modes: a folder, a file, a missing path, a link at the path, and a link above the path.
  4. Missing tests. Two tests are added: forgetting a folder drops chosenFolderId, and the person re-starting a live session after its folder was made again records the new folder's id.
  5. Card wording. The "not found now" note now says that a new folder at the path is chosen when the person starts developing it (EN+VI). It no longer claims that another folder made there can never count.

Verification

  • New and changed tests fail on origin/main sources (7 failures: 4 core helper tests, the not-found note test, the restart card test, and the status line test). They pass on the branch.
  • The two item-4 tests pass on main because the behaviour already exists. To show they catch a regression, I removed chosenFolderId from forget and from the live re-start: both tests then fail.
  • Focused vitest: 70/70 tests pass across the three specs. pnpm typecheck, pnpm invariants (the manifest was refreshed with --fix-manifest) and eslint on the changed files are clean.
  • pnpm verify: exit 0 (579 files passed, 1 skipped; 7937 tests passed).

Overlap

#656's flake fixes touch packages/core/test/widget-dev-engine.spec.ts and the "keeps the newest build's snapshot" test in apps/runtime/test/widget-dev-sessions.spec.ts. This PR does not edit the engine spec: the helper tests are in a new file. The runtime spec edits sit in the chosen-folder group (around lines 735-880), away from that test.

…t, and ask to choose a remade folder again

Export devRootIdentityOf from core with a followLinks option and use it for the chosen-folder id in the runtime, so the lstat copy goes away with the same semantics. A session Clark started in a chosen folder that was made again stops as root-refused at the next restart; the status line and the session's row on the develop card now tell the person to choose the folder again, and the not-found note says that starting a new folder there chooses it. Document that ext4 can give a folder deleted and made again at once the old file id, and why birth time is no second signal.

Refs #643
@mrgoonie

mrgoonie commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Review attestation: ready to merge at 2d4b5189d962b48e1a4240a0e4b034a8c2cfea5d, reviewed by agent:code-reviewer.

A push to this PR makes this attestation stale; the new head needs its own review.

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.

1 participant