PathSpec values inside the VFS; do not pass filesystem paths as raw strings.
File Structure
python/tests/ without creating __init__.py files in the test tree.
1. Config, Accessor, and Registry
Define a typed Pydantic config and keep secrets inSecretStr fields.
Accessor that owns the client or transport. Add the resource name to ResourceName, export the config/resource from resource/<name>/__init__.py, and add a lazy ResourceEntry to mirage/resource/registry.py. The registry entry is required for YAML, snapshots, and the daemon to construct the resource.
Keep every import at module scope. If that creates a cycle, change the dependency direction instead of adding a function-local import.
2. Core VFS Operations
Implement only the operations the backend supports. Read-only API resources usually start with:readdir(accessor, path, index)returning child names.read_bytes(accessor, path, index)returning bytes.stat(accessor, path, index)returningFileStat.resolve_glob(accessor, paths, index)returning resolvedPathSpecvalues.
3. Ops Layer
Ops are thin typed adapters from the workspace dispatcher to core functions. Declare dispatcher-injected arguments explicitly and keep**flags: object opaque.
write=True. Export the decorated functions as OPS from ops/<name>/__init__.py.
4. Commands
Build standard commands withCommandIO and make_generic_commands; the generic command owns flag interpretation. Backend wrappers should only connect glob resolution and I/O functions.
For a resource-specific command:
- Use the shared command spec.
- Mark every mutation with
write=TruesoMountMode.READremains a real boundary. - Declare injected parameters such as
stdin,index, andprefixexplicitly. - Use
FlagView(flags, spec=...)when the command itself must read a flag; never useflags.get(...). - Add a provision estimator when a useful estimate is possible. Otherwise the planner reports
precision=unknown.
COMMANDS from commands/builtin/<name>/__init__.py.
5. Resource Class
Import commands and ops at module scope, then register them in the constructor:caches_reads=True only for stable, read-mostly content. Implement get_state() with credentials redacted and close any network clients in close().
6. Snapshot Support
LeaveSUPPORTS_SNAPSHOT=False unless the complete drift contract is implemented:
stat()returns a stableFileStat.fingerprint.- Every read record includes the fingerprint that produced those bytes.
- If the backend supports immutable revisions, reads consult
revision_for(path.virtual)and record the resolved revision.
7. Verification
Add tests for config validation, path layout, every VFS op, command behavior, read-only enforcement, state redaction, and cleanup. For major features, add or update integration coverage underinteg/ and check Python/TypeScript parity before opening the PR.