Skip to main content

ADR-0006: Three-package Python structure in a2c-workflow

  • Status: Accepted
  • Date: 2026-06-12
  • Deciders: Michel Gillet

Context​

The a2c-workflow repository delivers multiple user-facing surfaces — a programmatic engine, a command-line tool, and a Textual TUI — in one repository (ADR-0005).

A single monolithic Python package would hide those surfaces. Multiple independently versioned packages would imply separate release cadences the product does not intend. A2C needs a layout that makes engine, CLI, and TUI responsibilities obvious while keeping one product version.

Repository: a2c-workflow Primary Python packages: a2c_core, a2c_cli, a2c_tui

Decision​

Inside the a2c-workflow repository, adopt three Python packages released in lockstep:

PackageSurfaceResponsibility
a2c_coreEngineDomain logic, metadata operations, schemas and repository-contract integration, AI workflow orchestration and evaluation
a2c_cliCLICommand-line entrypoints, command wiring, human-readable and JSON output surfaces
a2c_tuiTUITextual application — interactive bootstrap, configuration, diagnostics, maintenance UI

Layout (intended)​

src/
├── a2c_core/
├── a2c_cli/
└── a2c_tui/

Exact pyproject.toml / workspace tooling is an implementation detail; package names a2c_core, a2c_cli, a2c_tui are architectural and part of the public product story.

Dependency direction​

  • a2c_cli and a2c_tui depend on a2c_core
  • a2c_core does not depend on CLI or TUI presentation layers
  • Shared types and contracts live in a2c_core

Versioning​

  • One product semver (for example 1.2.3) covers all three packages
  • Git tag vX.Y.Z on a2c-workflow marks the combined release (ADR-0004)
  • The VS Code extension bundles CLI built from the same product version (ADR-0007)

Why three packages in one repo​

ReasonExplanation
ClarityContributors immediately see engine vs CLI vs TUI boundaries
Product signalingPackage names advertise the three tool surfaces without reading the whole tree
Import hygienePrevents IDE/UI code from leaking into domain modules
Not independent releasePackages version together — split is organizational, not a distribution boundary
Architecture storyPackage names alone signal engine, CLI, and TUI — contributors infer layout before reading the full tree

Alternatives considered​

AlternativeVerdictReason
Two packages: a2c_core + a2c_cli with TUI inside CLIRejectedCLI would carry two distinct interface identities; weakens immediate readability of the design
Four distributable packages including a separate AI packageRejectedAI workflow is not a separate product surface; it belongs in the a2c_core bounded context
Single monolithic Python packageRejectedHides engine vs CLI vs TUI surfaces (see Context)

Rationale​

  • Matches A2C principle: thin clients over a stable core (a2c_cli, a2c_tui over a2c_core)
  • Keeps AI workflow and schemas in the engine package where orchestration belongs
  • Avoids false independence — unlike a microservice split, these packages ship as one product
  • Makes testing structure obvious: domain tests in tests/a2c_core/, CLI contract tests in tests/a2c_cli/, etc.

Consequences​

Positive​

  • Each package has a simple story: engine, CLI, TUI
  • New contributors orient quickly — and can infer architecture from package names alone
  • Layout reinforces multiple deliberate user surfaces, not a single mixed tool blob
  • Internal dependency rules are easier to express and enforce because responsibilities are explicit
  • CLI binary packaging for the extension has a clear build target (a2c_cli)
  • TUI can grow without bloating library imports used by headless automation

Negative​

  • One more package boundary to document and maintain than a two-package layout
  • Build and packaging setup is slightly more explicit than with two packages
  • Refactors may touch multiple packages for cross-surface features
  • Naming (a2c_core package vs a2c-workflow repository) must be documented to avoid confusion

Still open (implementation)​

  • Monorepo tool choice (single pyproject.toml vs workspace)
  • Console script entrypoint names and distribution artifact layout
  • Whether a2c_tui is optional extra in packaging metadata

Relationship to other ADRs​

ADRRelationship
ADR-0005Parent — defines a2c-workflow as the owning repository
ADR-0007Bundled binary is built from a2c_cli at matching version

References​