Deepen engine architecture + seed CONTEXT.md#243
Open
timopruesse wants to merge 1 commit into
Open
Conversation
Five deepening refactors that concentrate behavior behind smaller interfaces
and make the engine testable without touching disk, sudo, or the network:
1. Introduce engine::Mode {Install,Update,Uninstall}, distinct from the CLI
Command. Collapse CommandExecutor's three methods into one execute(ctx)
reading ctx.mode. Removes dead list/validate/completions match arms and the
double mode dispatch.
2. Add a FileOps privilege seam (DirectFs / SudoFs adapters) selected once per
command, replacing the per-call sudo fork and platform-specific symlink and
removal logic.
3. Extract a tree-materialization module shared by copy and symlink: dest
resolution (now a pure, table-tested function) plus the install/uninstall
walk, parameterized by a per-file operation.
4. Build a TaskGraph module owning topo order, layers, cycle and missing-edge
detection. Runner and validator now share one implementation.
5. Unify the parallel and sequential run_tasks branches into one layer loop
(sequential = one task per layer) with a single per-task lifecycle helper.
Hardening: new unit tests for Mode, FileOps adapters + a recording fake, dest
resolution, tree apply/remove, and TaskGraph; new integration tests for copy
and symlink uninstall, symlink force vs skip, parallel-respecting-dependency
layers, and single-file-into-directory copy.
Add CONTEXT.md documenting the domain and architecture vocabulary, resolving the
overloaded "command" into Command entry / Mode / CLI command.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Five architectural deepening refactors that concentrate behavior behind smaller interfaces and make the engine testable without touching disk, sudo, or the network — plus a
CONTEXT.mdthat names the resulting vocabulary. No user-facing behavior change (one cosmetic log line dropped, noted below).Net: +706 / −650 across 16 files, 4 new modules. Tests grew from ~50 lib + 31 integration to 78 lib + 37 integration.
What changed
1.
Mode, distinct from the CLICommand(src/engine/mode.rs)Mode {Install, Update, Uninstall}is mapped once from the CLI verb;list/validate/completionsnever reach the engine, so the dead match arms disappear fromrun_command,update_history, andcommands_for_mode. TheCommandExecutortrait collapsed from three methods to oneexecute(ctx)readingctx.mode, eliminating the double mode dispatch.2.
FileOpsprivilege seam (src/engine/commands/fs_ops.rs)A
FileOpstrait with two real adapters —DirectFs(std::fs) andSudoFs(sudo) — selected once per command. Theif use_sudo {…}fork and platform-specific symlink/removal logic move behind the interface. A test-onlyRecordingFslets executor tests assert which operations ran without disk I/O.3. Tree-materialization module (
src/engine/commands/tree.rs)resolve_single_file_dest(the file-vs-dir target rule, now a pure table-tested function) plusinstall_tree/uninstall_treeparameterized by a per-file op.copy/symlinkshrink to their genuine differences.4.
TaskGraph(src/config/graph.rs)One home for
topo_order,layers,find_cycle,missing_dependencies. The runner's two traversals and the validator's separate cycle DFS now share it.5. Unified runner execution (
src/engine/runner.rs, −190 lines)Parallel and sequential collapse into one layer loop (sequential = one task per layer) with a single
run_layerlifecycle helper.CONTEXT.mddocuments the domain + architecture vocabulary and resolves the overloaded "command" into Command entry / Mode / CLI command.Testing
make lint— clean (fmt + clippy-D warnings)make test— 78 lib + 37 integration tests passFileOpsadapters + recording fake, dest resolution, tree apply/remove,TaskGraph(diamond/cycle/missing/layers), and integration tests for copy & symlink uninstall, symlink force-vs-skip, parallel-respecting-dependency-layers, single-file-into-directory copy.Behavior note
copyin update mode no longer emits the cosmetic"Copy update: re-running install"log line; it still re-applies identically. Nothing else changes observably.🤖 Generated with Claude Code