WIP: microservice rearchitecture #35

Draft
omarz wants to merge 40 commits from new-arch into development
Member

Splits the monolithic myfs-lib binary into a JSON-RPC microservice topology and follows up with bug fixes identified by full end-to-end testing of every scenario in docs/PROJECT_OVERVIEW.md.

Architecture (feat)

  • myfs-server — canonical JSON-RPC 2.0 daemon over a Unix socket; the only process that touches stores, FUSE, and fungi metadata.
  • myfs-sdk — typed client + #[rpc] trait (health, version, pack/unpack, mount/umount, clone, merge, sync, container, upload/download, exists, flist_tree/inspect/preview,
    block_get/exists, upload_dir, website_publish). Everything routes through this.
  • myfs-hub — REST API + JWT auth + website serving, using the SDK (no in-process fungi).
  • myfs-hub-api — shared wire types extracted from the hub.
  • myfs-ui — Axum+Askama dashboard split out of the old hub.
  • myfs-cli (new) and myfs-tool (rewritten) — both pure SDK consumers.
  • hero_proc lifecycle — myfs --start/--stop registers server+hub+ui as supervised actions with health checks and auto-generated hub.toml
┌──────────────────────────────────────────────────────────────────────┐
 │                          USER / OPERATOR                             │
 │   browser │ HTTP client │ terminal │ Rhai script │ other service     │
 └──────┬──────────┬──────────────┬──────────────┬──────────────────────┘
        │ HTML     │ HTTPS/JWT    │ exec         │ exec
        ▼          ▼              ▼              ▼
 ┌──────────────────────────┐ ┌──────────┐ ┌────────────┐
 │         myfs-hub         │ │   myfs   │ │ myfs-tool  │
 │  /api/v1/* + JWT + REST  │ │  (CLI)   │ │ (adv. CLI) │
 │  + Askama web UI +       │ │ pack,    │ │ clone,     │
 │    website serving       │ │ unpack,  │ │ merge,     │
 │                          │ │ mount,   │ │ sync,      │
 │                          │ │ upload,  │ │ container, │
 │                          │ │ flist    │ │ run(Rhai)  │
 └────────────┬─────────────┘ └────┬─────┘ └─────┬──────┘
              │                    │             │
              └────────────┬───────┴─────────────┘
                           │  JSON-RPC 2.0 over Unix socket
                           │  (all callers depend on myfs-sdk)
                           ▼
                    ┌─────────────────────┐
                    │    myfs-server      │  ← canonical API
                    │  (JSON-RPC daemon)  │     owns all storage ops
                    │   rpc.sock          │
                    └──────────┬──────────┘
                               │ uses
                               ▼
                    ┌─────────────────────┐
                    │      myfs-lib       │  pack / unpack / mount (FUSE)
                    │  (operations lib)   │  clone / merge / sync / container
                    └──────────┬──────────┘
                               │ uses
                               ▼
                    ┌─────────────────────┐
                    │     myfs-core       │  stores, fungi metadata,
                    │  (foundation lib)   │  cache, block enc/compress
                    └──────────┬──────────┘
                               │
             ┌─────────────────┼───────────────────┐
             ▼                 ▼                   ▼
        ┌────────┐       ┌──────────┐       ┌──────────┐
        │  dir://│       │  zdb://  │       │  s3://   │ ... http:// server://
        │ local  │       │ 0-DB     │       │ S3       │     (pluggable stores)
        └────────┘       └──────────┘       └──────────┘


Splits the monolithic myfs-lib binary into a JSON-RPC microservice topology and follows up with bug fixes identified by full end-to-end testing of every scenario in docs/PROJECT_OVERVIEW.md. Architecture (feat) - `myfs-server` — canonical JSON-RPC 2.0 daemon over a Unix socket; the only process that touches stores, FUSE, and fungi metadata. - `myfs-sdk` — typed client + #[rpc] trait (health, version, pack/unpack, mount/umount, clone, merge, sync, container, upload/download, exists, flist_tree/inspect/preview, block_get/exists, upload_dir, website_publish). Everything routes through this. - `myfs-hub` — REST API + JWT auth + website serving, using the SDK (no in-process fungi). - `myfs-hub-api` — shared wire types extracted from the hub. - `myfs-ui` — Axum+Askama dashboard split out of the old hub. - `myfs-cli` (new) and `myfs-tool` (rewritten) — both pure SDK consumers. - `hero_proc` lifecycle — myfs --start/--stop registers server+hub+ui as supervised actions with health checks and auto-generated hub.toml ``` ┌──────────────────────────────────────────────────────────────────────┐ │ USER / OPERATOR │ │ browser │ HTTP client │ terminal │ Rhai script │ other service │ └──────┬──────────┬──────────────┬──────────────┬──────────────────────┘ │ HTML │ HTTPS/JWT │ exec │ exec ▼ ▼ ▼ ▼ ┌──────────────────────────┐ ┌──────────┐ ┌────────────┐ │ myfs-hub │ │ myfs │ │ myfs-tool │ │ /api/v1/* + JWT + REST │ │ (CLI) │ │ (adv. CLI) │ │ + Askama web UI + │ │ pack, │ │ clone, │ │ website serving │ │ unpack, │ │ merge, │ │ │ │ mount, │ │ sync, │ │ │ │ upload, │ │ container, │ │ │ │ flist │ │ run(Rhai) │ └────────────┬─────────────┘ └────┬─────┘ └─────┬──────┘ │ │ │ └────────────┬───────┴─────────────┘ │ JSON-RPC 2.0 over Unix socket │ (all callers depend on myfs-sdk) ▼ ┌─────────────────────┐ │ myfs-server │ ← canonical API │ (JSON-RPC daemon) │ owns all storage ops │ rpc.sock │ └──────────┬──────────┘ │ uses ▼ ┌─────────────────────┐ │ myfs-lib │ pack / unpack / mount (FUSE) │ (operations lib) │ clone / merge / sync / container └──────────┬──────────┘ │ uses ▼ ┌─────────────────────┐ │ myfs-core │ stores, fungi metadata, │ (foundation lib) │ cache, block enc/compress └──────────┬──────────┘ │ ┌─────────────────┼───────────────────┐ ▼ ▼ ▼ ┌────────┐ ┌──────────┐ ┌──────────┐ │ dir://│ │ zdb:// │ │ s3:// │ ... http:// server:// │ local │ │ 0-DB │ │ S3 │ (pluggable stores) └────────┘ └──────────┘ └──────────┘ ```
- PRD 0000: platform overview of what MyFS is today
- PRD 0001: microservice rearchitecture proposal (hero_rpc2, hero_proc)
- ADR-006: accepted — myfs-server OpenRPC daemon on hero_rpc2
- ADR-009: split myfs-hub into REST gateway + new myfs-ui binary
- ADR-010: CLIs become SDK consumers + hero_proc --start/--stop
- docs/plans/: migration map + 5 phase execution plans
Introduces the JSON-RPC 2.0 foundation for MyFS:

- myfs-sdk: #[rpc(server, client)] trait with 15 methods covering every
  myfs-lib operation (pack, unpack, mount, clone, merge, sync, container,
  upload, download, exists, flist_tree, flist_inspect, health, version).
  Built on hero_rpc2 (trait-first jsonrpsee framework).
- myfs-server: daemon binding to \$HERO_SOCKET_DIR/myfs/rpc.sock via
  serve_http. Holds per-mount state in DashMap<String, MountHandle>.
  All 13 non-trivial methods dispatch into myfs-lib.
- myfs-test-utils: start_test_server() helper + ServerGuard RAII that
  spawns an ephemeral server on a temp socket for integration tests.

Workspace gains hero_rpc2, dashmap, tokio-util dependencies. No existing
crate is modified. Release binary: 14.2 MB.

Related: ADR-006, PRD 0001 phases 1-3.
Both CLIs now call myfs-server via myfs-sdk over Unix socket rather
than linking myfs-lib in-process. Includes ephemeral-server fallback
so 'myfs pack' still works with no running daemon.

Changes:
- myfs-lib/src/main.rs: every subcommand dispatches through
  myfs_sdk::MyFsClient; removes direct myfs-lib function calls
- myfs-lib/src/sdk_client.rs: connect_or_ephemeral() — resolves socket
  path, falls back to auto-spawning a myfs-server --ephemeral on a
  temp socket with RAII cleanup via EphemeralGuard
- myfs-lib/src/rhai_bindings.rs: Rhai bindings now call SDK methods
- myfs-tool/: same SDK-consumer rewrite; rhai bindings moved here from
  myfs-lib (container/pack/unpack/convert/execute scripts all route
  through the SDK)
- myfs-tool/Cargo.toml: drops myfs-core, myfs-lib path deps

Config subcommand (tag/store CRUD) dropped — no SDK equivalent; will
be reintroduced in a later PRD.

Binary sizes: myfs 2.5 MB (-83%), myfs-tool 5.3 MB (-83%). Neither
binary links polyfuse, rust-s3, sqlx, bb8-redis, or aes-gcm.

Related: ADR-010, PRD 0001 phase 4.
Follows hero_embedder's server/ui pattern: REST API and web dashboard
live in separate binaries with separate sockets, both consuming the
SDK.

- myfs-hub (trimmed): REST/OpenAPI gateway only (17 /api/v1/* routes,
  JWT auth, swagger, /website/:hash/*). Binds \$HERO_SOCKET_DIR/myfs/
  hub.sock. Drops askama, workers, snap, aes-gcm, tempfile, walkdir,
  which; gains myfs-sdk, hyper-util.
- myfs-ui (new): Axum + Askama web dashboard. Binds ui.sock. Adds a
  /health HTTP endpoint for hero_proc health checks. Website block
  fetches currently proxy through hub's HTTP /api/v1/block/:hash
  endpoint — tracked as an open question in ADR-009.
- Templates (base.html, index.html, error.html) copied from hub.
- /health routes added on both hub and ui.

Dep-tree check: askama not in hub; utoipa and myfs-lib not in ui.

Known gap (tracked): myfs-lib + myfs-core still linked in hub because
POST /api/v1/fl (container conversion) and GET /api/v1/fl/preview use
library functions with no SDK equivalent. Hub stuck at ~27 MB until
flist_preview / block_get / block_exists SDK methods land (v0.5).

Binary sizes: myfs-ui 7.7 MB.

Related: ADR-009, PRD 0001 phase 5.
feat(lifecycle): add myfs --start/--stop hero_proc integration (Phase 6)
Some checks failed
Build and Test / build (push) Failing after 2m2s
0693329b87
Adds one-command service orchestration: 'myfs --start' registers a
'myfs' service with hero_proc containing three supervised actions
(myfs-server, myfs-hub, myfs-ui), each with retry policy, SIGTERM
stop signal, and socket-based health checks. 'myfs --stop' tears
everything down.

- myfs-lib/src/lifecycle.rs: self_start() builds the ServiceSpec via
  hero_proc_sdk::ActionBuilder + ServiceBuilder; restart_service on
  the factory. self_stop() stops the service. Socket paths resolve
  from \$HERO_SOCKET_DIR/myfs/{rpc,hub,ui}.sock with \$HOME fallback.
- myfs-lib/src/main.rs: adds exclusive --start / --stop top-level
  flags; wraps command: Option<Commands> so lifecycle can run without
  a subcommand.
- myfs-lib/Cargo.toml: adds hero_proc_sdk.workspace dep.
- Cargo.toml: hero_proc_sdk workspace dependency (git, development
  branch).
- Makefile: 'make run' = install + myfs --start; 'make stop' =
  myfs --stop.

Health checks: myfs-server uses openrpc_socket (JSON-RPC health
method); myfs-hub and myfs-ui use http_url (/health GET endpoint)
combined with their respective socket paths for HTTP-over-UDS probes.

myfs binary size: 5.2 MB (up from 2.5 MB after adding hero_proc_sdk).

Related: ADR-010, PRD 0001 phase 6.
- Workspace version bump 0.3.0 → 0.4.0
- CHANGELOG.md: full v0.4.0 entry covering the microservice rearchitecture
  (added / changed / breaking / known gaps / compatibility)
- README.md: rewrite for the 5-binary architecture, new quickstart,
  environment table, REST API overview, roadmap
- Release workflow: BINARIES now includes myfs-server and myfs-ui
  alongside myfs, myfs-hub, myfs-tool

Live hero_proc verification, the ADR/PRD status flips, and the tag
itself are deferred until after PR review — see
docs/plans/0001-release-checklist.md.
Five surgical fixes from the parallel-subagent test run; Rhai runtime
panic (#1) is intentionally deferred per user direction.

- #2 myfs-server::impls::mount now validates the mountpoint exists and
  is a directory before spawning the FUSE worker. Previously the RPC
  returned success immediately and the background FUSE task failed
  silently, leaving the caller believing a bad mount had succeeded.
- #3 sdk_client::connect_or_ephemeral no longer auto-spawns an
  ephemeral server when the user passes --socket explicitly.  An
  explicit override path that's unreachable now errors cleanly; env
  and default paths keep their autospawn behaviour.
- #4 cli_tests::test_mount_help no longer asserts on the --daemon flag
  that Phase 4 intentionally dropped (FUSE lives in myfs-server; CLI
  daemonising is redundant).
- #5 rhai_bindings.rs module doctest compiles — the stale `client`
  reference is wrapped in a hidden fn stub that matches the real
  register_myfs_module signature (takes InnerClient by value).
- #6 warning cleanup: unused `mut` on axum service handles in
  myfs-hub/server/mod.rs and myfs-ui/src/main.rs; dead-code allow on
  ResponseResult::Res (retained for utoipa schema) and
  AppState::flist_dir (v0.5 UI usage planned); unused_imports allow
  on myfs-lib/tests/common.rs re-export.

cargo test --workspace --release: 89 pass, 0 fail, 11 ignored
(environmental skips: S3 creds, container runtime, FUSE-test user).
docs: record E2E verification pass (11/11 green)
Some checks failed
Build and Test / build (push) Failing after 2m4s
98f2140e19
omarz changed title from new-arch to wip: new-arch 2026-04-17 23:00:08 +00:00
- myfs-core: auto-fixes in error.rs, fungi/meta.rs, store/router.rs
- myfs-core/fungi/meta.rs: decimal `0754` → octal `0o754` in Mode perms test
- myfs-core/server_api.rs: move `mod tests` after all pub fns
- myfs-hub tests: drop needless borrows on `hex::encode`
- myfs-lib tests: 6× `while let Some(_)` → `.is_some()`

`cargo clippy --workspace --all-targets` now reports zero warnings.
chore: remove stale root docs and unused daemonize dep
Some checks failed
Build and Test / build (push) Failing after 2m2s
743fd96b3a
- Delete ACCEPTANCE_MATRIX.md + FEATURE_VERIFICATION.md (pre-rearchitecture
  status docs, superseded by docs/plans/0001-release-checklist.md and
  CHANGELOG.md).
- Drop `daemonize` workspace dep; only referenced in "DROPPED" comments
  since Phase 4 moved the FUSE worker into myfs-server.
style: apply cargo fmt to fix CI fmt-check failure
All checks were successful
Build and Test / build (push) Successful in 4m31s
206c6d062d
Both myfs-lib and myfs-tool shipped near-identical 320-LOC sdk_client
modules; tool's copy had silently dropped the `explicit` branch that
makes an explicit --socket disable ephemeral auto-spawn.

Promote the canonical (lib) version to myfs-sdk::connect so every SDK
consumer gets the same connect_or_ephemeral + MyFsConnection helpers.

- myfs-sdk: add connect module; pull in anyhow/log/tempfile/which deps.
- myfs-lib, myfs-tool: drop local sdk_client.rs, import from myfs_sdk.
myfs-lib was producing both a library and the `myfs` binary. After
the Phase-4 rewrite the binary no longer calls library operations —
it only talks to myfs-sdk. ADR-010 explicitly left "carve out a
dedicated cli crate" as an open question; this does that.

- new myfs-cli/ crate owns src/main.rs, src/lifecycle.rs, build.rs
  (git-version).
- myfs-lib/Cargo.toml drops [[bin]], build.rs, and CLI-only deps
  (clap, env_logger, simple_logger, hero_proc_sdk, git-version
  build-dep).
- Makefile dev target retargeted to `cargo run -p myfs-cli`.
- Root workspace picks up the new member.

Binary name `myfs` is unchanged, so CI (BINARIES env) and install
targets work without edits.
Closes the v0.5 SDK gap called out in the release checklist: three
endpoints previously reachable only by linking myfs-core/myfs-lib
in-process (hub's flist preview + website block fetch; ui's block
proxy) now have proper SDK coverage.

- flist_preview walks the flist collecting visible paths and returns
  them along with the flist's sha256. Matches the existing hub preview
  response shape so T2.3 can drop the in-process implementation.
- block_get and block_exists resolve through the store router embedded
  in the referenced flist, so the caller does not need to know store
  URLs up front. block_get returns Vec<u8>; blocks are ≤512 KiB in
  practice and JSON-RPC base64-inflates ~1.4× — OK per call, not for
  streaming.

Unblocks T2.3 (hub slim) and T3.2 (ui direct path).
Captures the full scope of T2.3 from the structural cleanup plan —
three ordered phases (handler rewrites, hub-native error type, CLI
subcommand split), each a stand-alone shippable change, with the
coupling analysis that makes this a milestone rather than a single
commit.

SDK groundwork already landed in 211176f (flist_preview / block_get /
block_exists); this ADR captures what the rest of the work looks like.
myfs-core/server_api.rs (HTTP client) and myfs-hub/src/server/*
(HTTP server) each hand-defined the same ten DTOs used on the hub
REST boundary (BlockInfo, BlocksResponse, ListBlocksResponse,
SigninResponse, UserBlockInfo, UserBlocksResponse, BlockDownloadsResponse,
VerifyBlock, VerifyBlocksRequest, VerifyBlocksResponse). Small drift
already crept in — some core fields were non-public where hub's were
public.

myfs-hub-api is a tiny new crate that owns those types. `schema`
feature gates the utoipa::ToSchema derives so slim consumers (core)
don't pull utoipa. Hub enables the feature for its OpenAPI generation.

Both sides replace their local definitions with `pub use` re-exports,
so no call-site changes were needed.

RPC DTOs in myfs-sdk/src/types.rs stay untouched — they were already
the single source of truth for the SDK boundary.
refactor: share one reqwest::Client across myfs-core HTTP paths
Some checks failed
Build and Test / build (push) Failing after 1m39s
89f839875a
myfs-core was building a fresh reqwest::Client in every entry point —
six call sites in server_api.rs, two in store/server.rs, one in
store/http.rs — each with its own connection pool. reqwest::Client is
internally Arc-backed and explicitly designed to be cloned and shared,
so per-call construction is pure waste.

Add server_api::http_client() backed by a OnceLock<Client>. Every
Client::new() in myfs-core now routes through it. ServerStore drops its
Arc<Client> field (the shared handle already is Arc-backed). Eight
connection pools collapse to one.
ci: fix apt MergeList corruption and fmt on new-arch
Some checks failed
Build and Test / build (push) Failing after 1m58s
b095ec1223
Run #132 failed at step "Install system dependencies" with an apt MergeList
parse error on a stale package (lib32stdc++6-13-dbg) cached in the builder
image. Clearing /var/lib/apt/lists before apt-get update works around the
corrupted list.

Also apply cargo fmt on myfs-server/src/impls.rs import ordering that would
have failed the subsequent fmt-check step.
ci: set RUST_MIN_STACK to avoid rustc SIGSEGV in LLVM codegen
Some checks failed
Build and Test / build (push) Failing after 1m42s
47b31ab78b
Run #133 hit a SIGSEGV in rustc while compiling myfs-lib (LLVM
ELFObjectWriter::writeObject on a codegen thread). rustc's own error
message suggests RUST_MIN_STACK=16777216 as the fix.
fix: extend request timeout for long operations in myfs-sdk connection
Some checks failed
Build and Test / build (push) Failing after 2m52s
7beef45e12
`TempDir::new("myfs-container").path().with_extension("fl")` produced
the fixed `/tmp/myfs-container.fl` for every call, ignoring `--store`
and overwriting on the next run. Sanitize the image name, drop the
registry-host prefix, and write into the first `dir://` entry of
`--store` when available; otherwise use a uniquely-named tempfile that
survives the working tempdir.
`myfs-tool merge` previously required `--token` and a reachable hub,
contradicting the documented local-operation semantics. Add
`myfs_lib::merge_local` — a metadata-only merge that aggregates routes
from the input flists and copies inode + block records into the
output. The server dispatches to `merge_local` when `server` or `token`
is empty, keeping the legacy remote path for existing callers.
Bindings use `Handle::current().block_on()`, which panics with
"Cannot start a runtime from within a runtime" when the Rhai engine
runs inline on a tokio worker. Execute the engine via
`spawn_blocking` with `handle.enter()` so the binding-side
`block_on` is invoked from outside the runtime pool.
The hub action was registered with just the binary path, so
`myfs-hub` always printed its help and exited. Pass `serve
--config-path <hub.toml>` as part of the exec script, and on first
start generate a default `hub.toml` under `$HERO_CFG_DIR/myfs/`
(with data dirs under `$HERO_DATA_DIR/myfs/hub/`) populated from
`$MYFS_JWT_SECRET` or a freshly rolled 32-byte random secret.
The preview route used Axum's single-segment `:flist_path`, so
`admin/foo.fl` — the format emitted by `GET /api/v1/fl` — could
never match. Switch to the wildcard `*flist_path`, resolve the
captured value against `config.flist_dir`, and reject any path
containing `..` with 400.
feat(sdk,cli,hub): upload_dir/website_publish RPCs, CLI path canon, SDK-compatible file hash
Some checks failed
Build and Test / build (push) Failing after 2m8s
c73c2bce42
- Add `upload_dir` and `website_publish` methods to the SDK trait and
  types; wire the server handlers to `myfs_lib::upload_dir_with_parallel`
  and `publish_website_with_parallel`. The CLI's `upload-dir`,
  `flist-create`, and `website-publish` subcommands now use these
  instead of falling into the single-file `upload` path (which failed
  with EISDIR on a directory).
- Canonicalize path arguments (`meta`, `target`, `store` for `dir://`,
  `cache`, `output`, `path`) in the CLI before sending them over RPC,
  so relative paths from the caller's cwd resolve correctly against
  the server's (different) cwd.
- Compute `file_hash` in the hub's `POST /api/v1/file` using the same
  block-based scheme as `myfs-sdk::upload` — sha256 over concatenated
  blake2b-32 block hashes — so the two upload paths are interchangeable.
- Refresh `docs/PROJECT_OVERVIEW.md` to match reality (health body,
  block upload message, path_uri format, job poll auth, merge example)
  and add the test report documenting the nine issues found.
The preview handler was passing the joined {flist_dir}{captured}
string through validate_flist_path, which assumes a relative
flist_dir and rejects absolute paths. Since the captured portion is
already guaranteed relative and .. -free by the wildcard guard, skip
the legacy validator and check component count directly.
The `run_myfs` helper invoked `cargo run -p myfs-lib --bin myfs`, but
the `myfs` binary lives in `myfs-cli` (moved in the Phase 4 split).
CI surfaced this as six failing cli_tests panics; error_tests accidentally
passed because their assertion is on non-zero exit which cargo satisfies
when the bin target is missing.
style: cargo fmt
All checks were successful
Build and Test / build (push) Successful in 4m22s
9c6a537c42
omarz changed title from wip: new-arch to WIP: wip: new-arch 2026-04-20 14:46:03 +00:00
omarz changed title from WIP: wip: new-arch to microservice rearchitecture 2026-04-20 14:48:11 +00:00
Owner

don't merge this, talk to me first please

don't merge this, talk to me first please
omarz changed title from microservice rearchitecture to WIP: microservice rearchitecture 2026-04-20 17:47:09 +00:00
The UI lived in its own crate but called the hub over reqwest for every
block and flist fetch — a localhost HTTP round-trip for data both halves
already shared. Merged the UI into myfs-hub as server::ui; website
handlers now read state.db directly. Drops the ui.sock listener, the
myfs-ui crate, and the reqwest hop.

Also removes orphan hub files (serve_flists.rs, website_handlers.rs)
that weren't declared in mod.rs and wouldn't compile, plus the unused
validate_flist_path helper.

ADR-009 rewritten as "Split, then Merged Back" (2026-04-21 revision);
ADR-011 is unaffected. Doc/Makefile/CI references to myfs-ui removed.
myfs-cli/src/main.rs grew to ~600 lines with mixed concerns. Split into:
  cli.rs       clap structs, with a shared ServerOpts flattened into
               upload-dir / flist-create / website-publish
  util.rs      abs_path / abs_store / default_parallel / emit (+ 4 tests)
  lifecycle.rs three near-identical ActionBuilder blocks collapsed into
               one build_action(ActionPlan) helper; the four HERO_*_DIR
               fallbacks share one hero_subdir helper
  main.rs      thin dispatcher (223 lines)

Correctness fixes:
- Remove `download-dir` subcommand. The SDK has no download_dir method;
  it was silently aliased to download and never worked end-to-end.
- Rename MyFS_TOKEN → MYFS_TOKEN everywhere (cli / hub / tool / lib /
  docs / tests). Linux env vars are case-sensitive and every other var
  in the project is all-caps; this was a long-standing drift.
- Delete stale `// NOTE: ... SDK gap` comments whose referenced fields
  are already plumbed through.

Docs / tests:
- Drop download-dir from user-facing docs and architecture overview.
- Rewrite the syncing-files tutorial verification step and the two e2e
  test functions (directory download, parallel download perf) to use the
  `download <flist-hash>` + `unpack --meta` flow — the actual supported
  path.
- docs/plans/* left alone (historical intent).

Breaking:
- MyFS_TOKEN env var must be renamed to MYFS_TOKEN.
- `myfs download-dir` is gone; use `myfs download <flist-hash> -o f.fl &&
  myfs unpack --meta f.fl --target dir/`.
Covers the RPC surface, socket transport, usage from Rust/CLI/curl,
and relevant env vars.
- flist_inspect/flist_tree: collect walk results into the RPC response
  instead of printing to server stdout and returning a placeholder.
- Download remote flists via tempfile::NamedTempFile (RAII cleanup,
  unique path) to replace /tmp/flist_*_{target}.fl which was both
  injectable via caller input and leaked on error paths.
- shutdown_all_mounts: cancel in parallel via JoinSet, bounded by a
  10s timeout with abort_all() for stragglers so a stuck FUSE task
  cannot hang process exit.
test(e2e): add ADR-012 layered pyramid — SDK types, RPC surface, REST, full-stack
Some checks failed
Build and Test / build (push) Failing after 4m24s
cb307a6c48
Implements docs/adr/012-e2e-test-strategy.md end-to-end: one `make test-all`
gate that covers cargo unit + integration, hub REST surface (17 curl
assertions), and a sandboxed full-stack walk (build → spawn server+hub →
REST round-trip → CLI via hub → direct RPC → Rhai round-trip → PID-scoped
teardown). Release smoke for the UI bits lives in docs/tests/agent_smoke.md.

Drive-by: removed the dead myfs-ui hero_proc action from myfs-cli lifecycle
(the crate was merged back into myfs-hub in 942f037 but the action
registration lingered, making `myfs --start` reference a binary that
can't be rebuilt). Now registers 2 actions instead of 3.

Also drops 4 placeholder `#[ignore]` hub tests that just probed an external
localhost:8080 — superseded by tests/api_hub.sh which boots its own hub.
fix(tests): improve binary build check and ensure cargo is in PATH
All checks were successful
Build and Test / build (push) Successful in 4m32s
bf4cb15b11
restore deleted files
All checks were successful
Build and Test / build (push) Successful in 6m11s
f3592f8ab3
merge: sync development into new-arch
Some checks failed
Build and Test / build (push) Failing after 7s
b50e434530
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Member

Classification: not-a-bug

This issue describes a planned microservice rearchitecture splitting myfs-lib into a JSON-RPC microservice topology. It is a design proposal and feature architecture change, not a report of incorrect behavior in the current codebase. Issues like this are better tracked as feature requests or ADR discussion threads rather than bug reports.

> Classification: not-a-bug This issue describes a planned microservice rearchitecture splitting myfs-lib into a JSON-RPC microservice topology. It is a design proposal and feature architecture change, not a report of incorrect behavior in the current codebase. Issues like this are better tracked as feature requests or ADR discussion threads rather than bug reports.
Some checks failed
Build and Test / build (push) Failing after 7s
This pull request has changes conflicting with the target branch.
  • .forgejo/workflows/build.yaml
  • Cargo.toml
  • Makefile
  • README.md
  • myfs-core/src/server_api.rs
  • myfs-hub/src/server/mod.rs
  • myfs-hub/src/server/response.rs
  • myfs-hub/src/server/serve_flists.rs
  • myfs-hub/src/server/website_handlers.rs
  • myfs-lib/src/main.rs
  • myfs-lib/src/rhai_bindings.rs
  • myfs-lib/src/sync.rs
  • myfs-lib/src/upload.rs
  • myfs-tool/src/main.rs
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin new-arch:new-arch
git switch new-arch

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch development
git merge --no-ff new-arch
git switch new-arch
git rebase development
git switch development
git merge --ff-only new-arch
git switch new-arch
git rebase development
git switch development
git merge --no-ff new-arch
git switch development
git merge --squash new-arch
git switch development
git merge --ff-only new-arch
git switch development
git merge new-arch
git push origin development
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
geomind_code/my_fs!35
No description provided.