Advanced
Maintainer-facing documentation. If you want the main product path first, go back to Architecture.
Internal Architecture¶
This page is for maintainers and contributors who need the repository’s current implementation shape, not just the conceptual layer model. It explains what the codebase owns today and which dependency rules are expected to stay intact.
Product model first¶
envctl revolves around a small set of concepts:
- contract — the shared project declaration discovered from
.envctl.yamlfirst, then.envctl.schema.yamlas legacy fallback - profile values — local persisted values stored in the vault
- project context — the resolved project identity, binding source, and vault paths
- resolution — the deterministic runtime view built from contract and profile values
- inspection — human or JSON diagnostics over resolved state
- projection — safe export of resolved values to subprocesses or generated files
The implementation should reinforce that model instead of hiding it.
Layering¶
The repository is intentionally split into a small set of layers with directed dependencies:
flowchart TD
CLI["Layer 1 · Interaction<br/>CLI"]
SERVICES["Layer 2 · Orchestration<br/>Services"]
CORE["Layer 3 · Core semantics<br/>Domain"]
INFRA["Layer 3 · Infrastructure-facing modules<br/>Repository · Config · Adapters"]
UTILS["Layer 4 · Shared utilities<br/>Utils"]
CLI --> SERVICES
SERVICES --> CORE
SERVICES --> INFRA
CORE --> UTILS
INFRA --> UTILS
Dependency rules¶
Dependencies must always point inward or downward in the architecture. No layer may depend on a layer above it.
Allowed dependencies¶
| Layer | May depend on |
|---|---|
| CLI | services, domain, config, utils |
| services | domain, repository, adapters, config, utils |
| repository | domain, adapters, config, utils |
| adapters | domain, config, utils |
| domain | utils |
| config | utils |
| utils | standard library and external libraries only |
Forbidden dependencies¶
domainmust not import services, repository, adapters, CLI, or configadaptersmust not import services, repository, or CLIrepositorymust not import services or CLIservicesmust not import CLIutilsmust not import CLI, services, or repositoryconfigmust not import CLI, services, or repository
CLI shape¶
The CLI is being normalized around one command pattern:
- read Typer arguments and options
- normalize or validate CLI-only combinations
- call one service workflow
- choose JSON or terminal output
That boundary keeps interaction rules separate from orchestration and formatting.