ADR-047: FAL tools
- Status
-
Accepted
- Date
-
2026-07-09
- Deciders
-
nr_llm maintainers
Context
The tool family covered records, schema, configuration and code — but not
the File Abstraction Layer. The recurring questions "which storages exist?",
"what is in this folder?", "find that PDF", "where is this image used?" and
"why is this image broken?" had a single narrow answer
(read_fal_asset_meta, one file by uid) and no navigation around it.
FAL output egresses to the external LLM provider, so the family needs one shared containment: storage scoping. A single allow-list in one place beats five copies of the same intersection logic.
Decision
Five read-only built-in tools in the NEW group files — the first group
added since the initial taxonomy (ADR-043); third-party extensions remain
advised to use their extension key as group:
list_fal_storages- The effective storages with uid, name, driver and status flags. The server-side base path is never part of the output.
browse_fal_folder- One folder's subfolders (with file count) and files (size, MIME type), resolved exclusively through the storage API. Identifiers are storage-relative; entries are capped.
search_fal_files- Substring search over file name and default-language metadata
title/alternative. The model-chosen query is LIKE-escaped (literal
%/_), missing files are excluded, results are capped. get_fal_referencessys_file_referenceusages of one file astable:uid (field)— hidden references marked, deleted ones invisible. The output states explicitly that soft references (RTE links, plain URLs) are not tracked, so "no references" is never read as "safe to delete".find_missing_filessys_filerows withmissing = 1in the effective storages, with the total count always reported alongside the capped listing.
Access model
All five share Fal: the configured storage allow-list
(default [1]), intersected for non-admins with the storages reachable
through their file mounts
(Backend, verified identical on
13.4 and 14). Fail-closed: no backend user or an empty intersection yields
the neutral denial. A file or folder outside the gate is indistinguishable
from a missing one — the same neutrality contract as
read_fal_asset_meta. get_fal_references additionally drops rows
whose referencing table fails Table for non-admins.
browse_fal_folder enforces FOLDER-level file-mount boundaries on top:
for non-admins it sets Resource, so
the core mount checks apply to every folder read. The mounts themselves are
attached by the core StoragePermissionsAspect only inside a backend
request — in any other context (CLI, scheduler) non-admin folder access
therefore fails CLOSED (denied) rather than mount-blind.
Server paths never egress: listings use storage-relative identifiers, and
list_fal_storages omits the base path by design.
Consequences
- The FAL gap in the tool taxonomy is closed with navigation (storages → folders → files), search, usage and integrity tools.
- The new
filesgroup can be disabled centrally, per configuration and per run like every other group (ADR-043). get_fal_referencesreadssys_file_referenceonly; soft-reference tracking (sys_refindex) is a possible later extension if "is this file really unused?" needs a stronger answer.