Repository navigation
Description
Problem
discover_apps (pkgs/id/src/app_manifest.rs:152-200, main @ df3f836) follows symlinks when scanning the apps root, so an "app folder" that is actually a symlink to a directory outside the apps root is registered as a local app:
- candidate folders are filtered with
path.is_dir()(app_manifest.rs:182), which follows symlinks; - the manifest is loaded via
folder.join("app.toml")+is_file()(:186-190), also following symlinks; - the folder name used for the id-match check is the symlink's name (:187-190), so an external folder registers whenever its manifest
idmatches the symlink's name.
Verified this run with a probe crate on the laptop compiling a sha256-identical copy of app_manifest.rs from main df3f836 (probe: ~/git/fleet/probe-appmanifest-20261101 on the laptop; result confirmed in two independent runs): apps root containing two real folders plus linked-app → symlink to a directory outside the root holding a valid app.toml with id = "linked-app" → discover_apps returns apps=["app-one", "app-two", "linked-app"], errors=0.
Why it matters
The app-folder model (design doc/2026-10-29T12-50-36Z_design_id_app_packaging §2/§3) treats the folder as the unit of trust: everything is relative to it, its name must equal the app id, and discovery "registers the app". A symlink hop silently breaks that unit — the registered app's program.source, [resources].files, and templates all resolve in a directory the operator never placed under the apps root, and a later folder-copy/backup of the root captures a dangling or different app than the one registered. The fleet hit this exact shape in pm-dispatch and fixed it as #3999 (symlink confinement, merged today); discovery has no equivalent stance — it does not even record that a folder was a symlink.
Acceptance criteria
- Discovery takes an explicit stance on symlinked app folders: either skip them with a named per-app error in
AppDiscovery.errors, or resolve and register them only when the resolved target stays inside the apps root — the chosen rule is documented in the module docs. - A unit test builds an apps root with a symlinked folder pointing outside it and asserts the chosen behavior (not silently registered as a plain local app).
- Real (non-symlink) app folders, including the checked-in tic-tac-toe app, discover exactly as today.
- Symlinks inside a real app folder (e.g. a linked
program/entry) are either covered by the same rule or explicitly called out as out of scope in the module docs.
Activity
dezren39 commentedon Nov 1, 2026
🤖 Agent note · filed
dezren39 commentedon Nov 2, 2026
🤖 Agent note · adopted as Phase 1 of design #4202
app_manifest.rsmodule doc. Symlinks INSIDE a folder are dispositioned by the Phase 4 audit Phase 4 (audit) of #4202 — closing field-by-field disposition for pkgs/id app_manifest #4203, not this phase.source/design-architect. Existing queued triage packet stands.dezren39 commentedon Nov 2, 2026
🤖 Agent note · picked up
11 remaining items
dezren39 commentedon Nov 2, 2026
🤖 Agent note · picked up
fix(id): resolve and contain symlinked app folders in discover_apps (#…
dezren39 commentedon Nov 2, 2026
🤖 Agent note · done
link, integration tests) filed separately as issue id(chain): integration tests do not compile — ChainExt initializers missing new link field #4522.