Dependency Management (West + Submodule)
Context
autograph needs to manage two categories of dependencies:
- The engine itself (integrated into projects)
- Packages (core and third-party) that extend capabilities
The solution must support: local development (file:// resolution), remote distribution (git/https), versioning, and the recursive case (engine has its own dependencies).
Options considered
Option A - Git submodules only
Engine and all packages as Git submodules.
- Advantage: Native Git, no extra tooling
- Disadvantage: Submodules are notoriously painful (detached HEAD, nested updates). No metadata mechanism. No dependency graph. Doesn't scale for many packages.
Option B - West for everything
Engine and packages all managed by West.
- Advantage: Uniform tooling, single manifest
- Disadvantage: The engine needs special treatment (it must exist before West can run). West doesn't distinguish between "the thing that provides West" and "things resolved by West". Circular dependency risk.
Option C - Submodule for engine, West for packages (chosen)
The engine is a Git submodule (fixed SHA pointer). Packages are managed by West. The engine itself uses West recursively for its own core packages.
- Advantage: Clear separation. The engine bootstrap is simple (git submodule update). Packages get the full power of West (manifest, metadata, resolution). No circular dependency.
- Disadvantage: Two mechanisms to understand. The recursive case (engine uses West for its own deps) adds complexity to the bootstrap sequence.
Decision
Option C - Submodule for engine, West for packages.
The engine is special - it's the thing that makes everything else work. It deserves a simpler, more reliable integration mechanism (submodule = fixed SHA, always available after clone). Packages are the composable parts and benefit from West's features.
Consequences
Architecture
project/
├── engine/ # Git submodule → autograph repo
│ └── deps/
│ ├── manifest/west.yml # Core packages (pkg.agent, pkg.delivery)
│ └── modules/ # Resolved by West
│
└── deps/ # Project-level West workspace
├── manifest/west.yml # Third-party packages
└── modules/ # Resolved by West
Bootstrap sequence
1. git submodule update --init → engine/ populated
2. west init + update (engine) → engine/deps/modules/ populated (core packages)
3. west init + update (project) → deps/modules/ populated (third-party packages)
West specifics
- West runs in a Docker container (Python + west + git)
- Manifest uses
userdata.augrfor autograph metadata (imposed by West spec) - Local resolution via
file://for lab development, remotehttps://for production - Reset is simple:
rm -rf deps/.west deps/modulesthen re-run
Trade-offs
- Two dependency mechanisms to learn (submodule + West)
- Bootstrap is sequential (engine first, then engine deps, then project deps)
- West container must be built before any package resolution
- The engine's West container is the only "hard-coded" infrastructure element