4.3 KiB
Flow Architecture
This document describes the current action-runtime architecture.
Runtime Shape
Flow is organized around a canonical action plan:
cli -> app -> domain -> actions -> adapters
The important boundary is ActionPlan -> ActionExecutor -> ActionResult.
cli: Typer command declarations and argument parsing insrc/flow/cli.py.app: command use-cases insrc/flow/app/. These load config/state, compose domain planners, and submit action plans.domain: pure models, parsers, resolvers, and planners insrc/flow/domain/.actions: canonical action models, expansion, execution, dry-run rendering, JSONL audit logging, and rollback insrc/flow/actions/.adapters: filesystem, process, git, package-manager, download, archive, container, and tmux implementations insrc/flow/adapters/.
The filesystem is not the core abstraction. It is one adapter used by the executor. The core abstraction is the action plan.
Actions
DomainAction captures user intent:
kind:dotfiles,package,project,repo,container,remote,setup, orcompletionaction:link,unlink,install,remove,update,pull,push,create,stop, and related verbspayload: typed-by-domain data or already expanded primitive actionsrollback_policy:rollbackable,barrier, ornone
PrimitiveAction is the executor-owned operation set:
- filesystem: create/remove symlink, write, write JSON, copy, copy tree, remove, chmod
- git: clone, pull, push, fetch, checkout, status
- process: argv command or explicit user shell hook
- packages/assets: download and archive extraction
- containers: run, start, stop, kill, remove, exec
- tmux: new session, set option, respawn pane
Domain actions are expanded before execution. Dry-run output and audit logging come from the same primitive list that real execution uses.
Rollback
Rollback is explicit and best effort.
Supported file/state primitives record reverse actions before mutation. On failure, the executor rolls back in reverse order until it reaches a barrier. External boundaries such as package-manager commands, user shell hooks, git pushes, container lifecycle operations, and interactive command handoffs are not guaranteed to roll back.
Command Surface
Implemented commands:
flow dotfiles init|link|unlink|status|edit
flow dotfiles repos list|status|pull|push
flow packages install|remove|list
flow setup run|show|list
flow remote enter|list
flow enter
flow dev create|attach|connect|exec|enter|stop|remove|rm|respawn|list
flow projects check|fetch|summary
flow sync
flow completion zsh|install-zsh
Global flags:
flow --version
flow --quiet
flow --no-color
Mutating non-interactive commands expose --dry-run where a preview is useful:
dotfiles link/unlink, dotfiles repo pull/push, package install/remove, setup
run, remote enter, and dev create.
Dotfiles And Modules
The dotfiles repo and _module.yaml repos share one abstraction: managed repos.
flow dotfiles repos operates on both. Modules are regular git clones cached
under the flow data directory; they are not git submodules.
Link planning treats conflicts and missing modules as pre-execution failures. State is written through actions, and broken tracked symlinks are repaired by the same link reconciliation path.
Packages
Package manifests are parsed into typed dataclasses. Package-manager commands are built as argv lists by the package adapter. Binary and AppImage installs expand into download, archive, copy/chmod, cleanup, post-install barrier, and state-write primitives.
packages remove is strict: it refuses unknown packages, removes tracked files,
and writes updated state through the executor.
Tests And Guards
The test suite covers:
- action executor dry-run, audit logs, rollback, barriers, domain expansion, and primitive dispatch
- dotfiles discovery, module handling, conflict behavior, rollback, and repo operations
- package manifest parsing, package-manager argv, binary installs, archive safety, strict removal, and post-install barriers
- Typer CLI invocation, help output, completion, and error reporting
- Docker/Podman e2e for the example dotfiles repo when
FLOW_RUN_E2E=1
Static guard tests reject direct mutating filesystem and command APIs outside
actions, adapters, and tests.