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