# Architecture Policy **Base Policy Version:** 1.3 **Last Updated**: 2026-09-28 **Upstream Source:** [Standard Repository Policies architecture](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/architecture.md) ## Purpose And Ownership The adopted policy defines the application's purpose and the architectural constraints contributors must follow. It owns system boundaries, responsibility and dependency rules, established invariants, and explicit non-goals. Describe the concrete package inventory and implementation mechanics in internal documentation. Link to canonical public contracts for their exact behavior and to ADRs for decision rationale. ## Architectural Approach Hexagonal architecture is strongly recommended, including encapsulating external integrations and APIs within internal adapters. Keep domain and application logic independent of external integration details, and make dependency direction clear in the adopted policy. Implement that separation with proportionate, idiomatic code. Choose interfaces and package layout to serve the application's actual boundaries. Use adapters for collaborators with external integration responsibilities. ## Adopted Constraints And Implemented Structure Architectural constraints govern current and future development. Record implemented structure accurately, proposals and implementation status in the roadmap, and significant decisions and rationale in ADRs. Describe a target structure as implemented when its changes land. Constraints must reflect deliberately selected requirements and decisions. Do not promote incidental implementation choices into architectural invariants. ## Application-Specific Topics Audita is a single-process Go CLI for transcript polishing. Its architecture separates deterministic transcript processing from external LLM effects through narrow contracts and adapters. Correction modules and validators remain explicit, composable components in an ordered processing pipeline. This policy owns architectural requirements. The [internal overview](../internal/overview.md) owns the implemented component inventory and links to runtime mechanics. [CLI](../cli.md), [configuration](../config.md), [operations](../operations.md), and [integration documentation](../integrations/subprocess.md) own external contracts. ## Ownership and Dependency Direction - **Core:** owns domain data handling and reusable configuration, schema, normalization, chunking, output, diagnostics, and reporting contracts. Domain behavior must not require CLI or provider-transport knowledge. - **Framework:** owns orchestration contracts and shared runtime mechanics for modules, validators, proposals, LLM adapters, and report assembly. It composes domain operations through explicit inputs and outputs. - **Modules:** own narrowly scoped correction behavior and module-specific prompt choices. Keep module packages separate rather than collapsing their distinct responsibilities into a broad generic stage abstraction. - **Validators:** own validation behavior and composition. Deterministic and LLM-backed validators remain explicit, independently composable elements. - **Prompts:** own embedded prompt assets and metadata used by the runtime. - **CLI and adapters:** own command parsing, streams, filesystem wiring, and transport. Keep these concerns outside module, validator, and schema logic. LLM transport belongs behind `StructuredLLMClient` and framework adapter boundaries. Prefer small shared helpers over broad rewrites. Keep module and validator inputs, outputs, and configuration dependencies explicit, without hidden global state. ## Correction and Concurrency Invariants - Treat LLM responses as nondeterministic inputs. Preserve deterministic proposal indexing, validator ordering, transcript mutation, reports, and serialization. - Validate corrections before final mutation, including local proposal checks, decision cardinality, and apply-time safety. Provider-side schema enforcement does not replace these checks. - Keep LLM concurrency bounded and context-aware through PromptKit's engine-local per-backend admission. Proposal and validation calls selecting the same backend share that capacity, including retries and repairs. Preserve deterministic collection order. Recoverable model-operation failures stay local to their proposal response or validation batch; fatal invariant/application failure and parent cancellation stop peers and join them. - Keep module and validator identities, reason codes, and execution-class distinctions stable where exposed as contracts. The [pipeline](../internal/pipeline.md), [modules](../internal/modules.md), [validators](../internal/validators.md), and [LLM runtime](../internal/llm-runtime.md) describe how these requirements are implemented. ## State and Compatibility Keep transcript mutation and output handling deterministic around external calls. Reports and correction ledgers are derived from processing results. Preserve the separation between transient processing state and filesystem adapters; physical report placement and optional debug retention belong to [operations](../operations.md). Public CLI, configuration, output-schema, diagnostics, report, prompt, module, and validator contracts should remain stable unless a change is deliberate and tested. The resilience work intentionally replaced the earlier JSON process report with versioned errors/recoveries YAML and a fixed Markdown overview; future changes should treat those current contracts deliberately. Current implementation limits are documented in the [internal overview](../internal/overview.md#current-scope); they are not additional prohibitions on future development. ## Trust Boundaries And Threat Scope Errors should identify the failed processing phase sufficiently for users and subprocess callers. Preserve the stream and exit behavior defined by the [CLI contract](../cli.md) and the artifact handling defined by [operations](../operations.md). Diagnostics, reports, and surfaced errors must not leak configured LLM secrets. Configuration redaction and LLM payload/error redaction have separate responsibilities and should remain separate. Implementation details belong in [diagnostics and reporting](../internal/diagnostics-reporting.md). ## Dependencies Keep Audita dependency-light and prefer the Go standard library for CLI parsing, filesystems, synchronization, and tests. ConfigKit owns configuration loading, presence, provenance, and secret resolution; PromptKit owns prompt/profile loading, OpenAI-compatible transport, retries, repairs, and backend admission. Audita owns domain meaning, role selection, and deterministic processing. Do not introduce broad CLI, dependency-injection, workflow, logging, or plugin frameworks without a concrete implemented need and focused tests. ## Testing and Documentation Follow the [testing policy](testing.md) for risk-based sufficiency and stable test boundaries. Keep tests close to the behavior they protect; shared helpers should remove duplication without obscuring component-specific behavior. Relevant internal docs identify component tests and change recipes; the [contributor guide](../development.md) provides baseline validation commands. Follow the [documentation policy](documentation.md) for ownership, current versus future behavior, and the ADR lifecycle. Keep architecture concise and normative; use the roadmap for implementation plans rather than maintaining a changelog or future-feature specification here.