Problem
The src/structure/ module is responsible for managing verification structure files (frontmatter parsing, .md file I/O, certificates, config paths). However, it currently also owns the entire Docker/local command execution engine, which is an unrelated concern.
This coupling was introduced in commit 5100ccd ("feat(docker): add production-ready Docker execution support and CI"), which added executor.rs directly into structure/ and placed ExecutionMode / CommandConfig into structure/config.rs. Every subsequent PR (#11, #12, #14) built on top of that placement, deepening the coupling.
What lives in structure/ today that shouldn't
| File |
Docker/execution concerns |
executor.rs |
run_docker(), ensure_image_pulled(), Docker container orchestration (volume mounts, tmpfs, env vars, user mapping) |
config.rs |
ExecutionMode enum, CommandConfig struct, docker-image field, DEFAULT_DOCKER_IMAGE |
probe.rs |
Docker-vs-local branching in require_probe_installed() |
Why this is a problem
-
Semantic incoherence. Every command module (atomize, create, specify, verify, init) imports CommandConfig and ExecutionMode from crate::structure. A module about structure files is acting as the authority on how to run external processes.
-
Wrong dependency direction. If a future non-structure command needs to run something in Docker, it would have to import from structure/, which makes no sense. The execution layer should be independent and reusable.
-
Harder to reason about. When reading structure/mod.rs, you see re-exports for both frontmatter parsing and Docker container configuration side by side. New contributors have no way to guess that "structure" means "structure files + process execution."
-
Testing friction. Testing structure-file logic (frontmatter, certs) currently pulls in the execution types even though they're unrelated.
Proposed solution
Extract execution concerns into a dedicated src/execution/ module:
src/
execution/ # NEW
mod.rs # re-exports
executor.rs # run_command, run_local, run_docker, ensure_image_pulled
config.rs # CommandConfig, ExecutionMode
probe.rs # require_probe_installed, cleanup_intermediate_files
structure/ # EXISTING, now only about structure files
mod.rs
config.rs # StructureConfig, ConfigPaths (depends on execution::CommandConfig)
frontmatter.rs
certs.rs
utils.rs
This is a pure module extraction — no logic changes, just moving types and updating import paths. structure/config.rs would depend on execution::CommandConfig rather than owning it.
Files that need changes
src/structure/executor.rs → src/execution/executor.rs
src/structure/probe.rs → src/execution/probe.rs
ExecutionMode, CommandConfig out of src/structure/config.rs → src/execution/config.rs
src/structure/mod.rs — remove execution re-exports
src/execution/mod.rs — new, with re-exports
src/main.rs — add mod execution
src/commands/atomize.rs, create.rs, specify.rs, verify.rs, init.rs — update imports
src/structure/utils.rs — run_command delegates to executor, update import
Context
- Introduced by commit
5100ccd
Problem
The
src/structure/module is responsible for managing verification structure files (frontmatter parsing,.mdfile I/O, certificates, config paths). However, it currently also owns the entire Docker/local command execution engine, which is an unrelated concern.This coupling was introduced in commit
5100ccd("feat(docker): add production-ready Docker execution support and CI"), which addedexecutor.rsdirectly intostructure/and placedExecutionMode/CommandConfigintostructure/config.rs. Every subsequent PR (#11, #12, #14) built on top of that placement, deepening the coupling.What lives in
structure/today that shouldn'texecutor.rsrun_docker(),ensure_image_pulled(), Docker container orchestration (volume mounts, tmpfs, env vars, user mapping)config.rsExecutionModeenum,CommandConfigstruct,docker-imagefield,DEFAULT_DOCKER_IMAGEprobe.rsrequire_probe_installed()Why this is a problem
Semantic incoherence. Every command module (
atomize,create,specify,verify,init) importsCommandConfigandExecutionModefromcrate::structure. A module about structure files is acting as the authority on how to run external processes.Wrong dependency direction. If a future non-structure command needs to run something in Docker, it would have to import from
structure/, which makes no sense. The execution layer should be independent and reusable.Harder to reason about. When reading
structure/mod.rs, you see re-exports for both frontmatter parsing and Docker container configuration side by side. New contributors have no way to guess that "structure" means "structure files + process execution."Testing friction. Testing structure-file logic (frontmatter, certs) currently pulls in the execution types even though they're unrelated.
Proposed solution
Extract execution concerns into a dedicated
src/execution/module:This is a pure module extraction — no logic changes, just moving types and updating import paths.
structure/config.rswould depend onexecution::CommandConfigrather than owning it.Files that need changes
src/structure/executor.rs→src/execution/executor.rssrc/structure/probe.rs→src/execution/probe.rsExecutionMode,CommandConfigout ofsrc/structure/config.rs→src/execution/config.rssrc/structure/mod.rs— remove execution re-exportssrc/execution/mod.rs— new, with re-exportssrc/main.rs— addmod executionsrc/commands/atomize.rs,create.rs,specify.rs,verify.rs,init.rs— update importssrc/structure/utils.rs—run_commanddelegates to executor, update importContext
5100ccd