Skip to content

Adding CLI Surface

Atlas has two command domains. bijux atlas and the bijux-atlas binary expose product behavior. bijux dev atlas and bijux-atlas-dev expose repository, release, operations, and evidence control. Choose the domain before choosing a command name; putting maintainer authority in the product CLI creates an unsupported operational side entrance.

CLI Addition Flow

flowchart TD
    Need[User or maintainer capability] --> Domain{Product or control plane?}
    Domain --> Family[Choose owned command family]
    Family --> Parse[Arguments and validation]
    Parse --> Execute[Application or domain operation]
    Execute --> Output[Text and machine result]
    Output --> Contract[Exit, schema, and artifact contract]
    Contract --> Evidence[Help, behavior, and failure evidence]

A parser entry is only the beginning of the surface. A complete command has an authority boundary, deterministic inputs, observable mutation policy, stable failure behavior, and evidence that both direct and umbrella routing reach the same implementation.

Placement Model

flowchart LR
    CLIIntent[CLI intent] --> Args[Inbound argument model]
    Args --> Dispatch[Command dispatch]
    Dispatch --> App[Application use case or orchestration]
    App --> Domain[Domain and outbound ports]
    Dispatch --> Presentation[Text or JSON presentation]
    Presentation --> Consumer[Human or automation consumer]

Clap types, shell wording, and process exit conversion stop at the inbound boundary. Application and domain code must remain callable without constructing CLI types. Presentation converts a typed result into the selected format; it must not silently change the operation's verdict.

Command Contract

Concern Required decision
Ownership product CLI or repository control plane, then one durable command family
Inputs precedence, defaults, path resolution, network access, and validation
Mutation read-only, planned, or write-authorized behavior with an explicit boundary
Output human text, JSON shape, artifact paths, and stdout/stderr separation
Failure usage, validation, dependency, or internal exit class plus machine code
Idempotency whether rerunning is safe and how partial state is detected
Evidence tests and reports proving success, failure, help, and routing behavior

Do not create a generic root family to avoid an ownership decision. Extend the domain that owns the state or operation. If no family fits, document the new boundary and its relationship to adjacent commands before adding it.

Machine and Human Output

JSON is an automation contract, not decorated console text. Use stable field names, explicit status, governed report schemas when results persist, and deterministic ordering where consumers compare output. Send diagnostics to stderr so stdout remains parseable. Human output may add explanation but must preserve the same verdict and identities.

Use the shared exit classes consistently: 0 success, 2 usage, 3 validation, 4 dependency failure, and 10 internal failure. A newly created report does not justify exit 0 when its governing check failed.

Acceptance Evidence

  • Help exposes the command in the intended family with meaningful option text.
  • Direct binary and umbrella routes resolve to equivalent behavior where both are supported.
  • Missing, invalid, and conflicting inputs return the correct stable exit class.
  • JSON output parses and matches its declared schema or field contract.
  • Mutating behavior requires the repository's established write authorization and leaves no unexplained partial state.
  • Tests exercise a successful result, representative rejection, and dependency failure without relying only on snapshots of prose.
  • Reader documentation states prerequisites, effects, completion evidence, and what the command does not prove.

Review the broader Automation Command Surface and Command Routing before establishing a new family.