aboutsummaryrefslogtreecommitdiffstats
path: root/docs/refactor-groups.md
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-07 00:58:37 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-07 00:58:37 +0200
commit2d3cbdec301c592daa2faff8e1ca1cab155ebb58 (patch)
treea4d543fa3f54d7bcb4c9147869e5a02cc58a0239 /docs/refactor-groups.md
parenta36080742287bad8f657f688d7fec0022dd696a1 (diff)
downloadmeshbay-2d3cbdec301c592daa2faff8e1ca1cab155ebb58.tar.gz
chore(node): finish Phase 3 — CLI deprecations, Windows shapes, docs
`member upload` reached the generic usage line for the other `member` verbs — "usage: meshbay-node member upload <username>" — which advertises a removed feature and sends the operator looking for a username it would then reject. It names `root set --writable` now, and the man page carries the same. Three lines between an operator finding the replacement and concluding the CLI is broken. `--upload-dir` still works, so an existing script keeps working, but its help and the man page say it is the old spelling and name what replaced it. The Windows pass (§4.4) is what can be checked from here, made checkable: drive letters and UNC through `as_posix()` into TOML, a drive root having no basename to derive a name from — sharing a whole drive is ordinary there — and a case-insensitive collision, which on NTFS and exFAT is one directory indexed as two roots. `PureWindowsPath` throughout, for the reason the backslash test earlier this branch got wrong. What it cannot check is written down rather than glossed: ReadDirectoryChangesW dropping events, MAX_PATH, and whether an eject actually lets a drive be removed. §7d says so, along with two things the plan never considered — the RO/RW asymmetry in `_do_dir_delete`, and `index_delta` carrying roots but not `dirs`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pvMdvLBG92jyhvD5pD6us
Diffstat (limited to 'docs/refactor-groups.md')
-rw-r--r--docs/refactor-groups.md71
1 files changed, 67 insertions, 4 deletions
diff --git a/docs/refactor-groups.md b/docs/refactor-groups.md
index f16f2f2..d63d858 100644
--- a/docs/refactor-groups.md
+++ b/docs/refactor-groups.md
@@ -1,14 +1,15 @@
# Groups Refactor — Per-Root Permissions & App Plugin Architecture
-> Status: **Phases 1 and 2 complete** (2026-09-06). Phase 3 not started.
+> Status: **Complete** (2026-09-07). All three phases built, reviewed and
+> tested against a running node.
>
> This is the most significant refactoring of the project. It changes how roots
> are permissioned, how group applications are configured, and how the Settings
> and Create Group pages are structured.
>
-> §7b records what the review of Phase 1 found and how the plan below was wrong
-> where it was wrong; §7c does the same for Phase 2. Read both before starting
-> Phase 3 — several entries are rules rather than one-off fixes.
+> §7b, §7c and §7d record what each phase's review found and where the plan
+> below was wrong. Several entries are rules rather than one-off fixes; §7d
+> also lists what a person still has to test by hand.
---
@@ -831,3 +832,65 @@ no syntax check at all before, which is how the file was committed.
- **What Phase 3 still owes:** the HelloWorld app (§4.1) — which is the actual
proof of the above, since every test here reads source rather than adding an
app and watching it work — plus the CLI polish and the Windows pass.
+
+---
+
+## 7d. Phase 3 as built (2026-09-07)
+
+### HelloWorld earned its place
+
+It was written last and immediately found two things no amount of source
+reading had: `group-settings.js` fell back to the *whole* registry when a group
+had no `enabled_apps` yet — which would have enabled a hidden app for everyone
+— and `group-page.js` wrote out `videoDirectories` / `musicDirectories` /
+`photoDirectories` by hand, so a fifth app would have needed that file edited.
+Both are fixed by making the code less app-specific, and the plugin claim is
+now true rather than nearly true.
+
+That is the argument for keeping it: every other test of the architecture reads
+source for the *absence* of app names, which proves nobody wrote a special case
+— not that a new app works. Deleting HelloWorld would leave the claim resting
+entirely on tests that read text.
+
+**It is hidden behind `?dev=1`**, not excluded from the build as §4.1 imagined.
+There is no build step to exclude it from, and an unregistered app proves
+nothing, since registration is exactly what is claimed to be sufficient. The
+flag is the same opt-in shape as `transport.js`'s `?trace=1`.
+
+### The CLI
+
+`member upload` reached the generic usage line for the other `member` verbs —
+"usage: meshbay-node member upload <username>" — which advertises a removed
+feature and sends the operator looking for a username it would then reject. It
+names `root set --writable` now. `--upload-dir` still works, so an existing
+script keeps working, but its help and the man page say it is the old spelling.
+
+### Windows
+
+`test_windows_root_shapes.py` covers what can be covered from here: drive
+letters and UNC through `as_posix()` into TOML, a drive root having no basename
+to derive a name from, and a case-insensitive collision — which on NTFS and
+exFAT is one directory indexed as two roots. All pass.
+
+**What still needs a person on Windows**, and cannot be faked:
+
+- `ReadDirectoryChangesW` dropping events under load — the reason periodic
+ reconciliation is mandatory, and the reason eject exists at all
+- `MAX_PATH` against a deep library, on download and on upload
+- whether an eject actually lets the drive be removed, and a plug picks it back
+ up — the eject/plug pair is the least-exercised thing in all three phases
+- the folder-tree picker against backslash paths in the UI
+- the Create Group wizard with a drive-letter root
+
+### What the whole refactor still owes
+
+Nothing in the plan. Two things it did not think of:
+
+- **`_do_dir_delete` was never checked against RO/RW.** `_do_file_upload` and
+ `_do_dir_create` both gained the `writable` check; deletion is operator-only
+ and so is not the same hole, but the asymmetry is worth a look.
+- **`index_delta` carries roots but not `dirs`.** A folder created by another
+ member does not reach a connected client's folder picker until a full
+ `index_sync`. Small, and the picker offers root names from the roots table
+ regardless, so nothing is unreachable — but it is the same class as the bug
+ §7d's roots fix closed.