Files
promptkit/docs/policy/architecture.md

119 lines
4.9 KiB
Markdown

# Architecture Policy
## Purpose
This document defines Promptkit's current high-level architecture and the
durable boundaries that implementation changes must preserve. The
[internal component overview](../internal/overview.md) inventories concrete
implemented packages without redefining these rules.
## System Shape
Promptkit is an importable Go library. It does not provide a runnable command,
an HTTP service, or another application process.
The module root contains package `promptkit`, which is the public facade and the
only implemented Go package in the current repository foundation. It declares
the module's public package boundary but does not yet provide migrated framework
behavior or exported APIs. No internal framework packages currently exist.
Future framework extraction must follow this dependency direction:
```text
downstream consumers, including Scriptorium
|
v
root promptkit public facade
|
v
internal framework components
|
v
narrow injected abstractions
```
The facade may coordinate internal components. Internal components must depend
on narrow abstractions for behavior supplied from outside the library; they
must not depend on consumers or on Scriptorium. This diagram constrains future
work and does not assert that the internal components already exist.
## Repository And Consumer Boundary
Scriptorium is a downstream application that will consume Promptkit through
the supported public facade. It is not a Promptkit package and must not become
an internal dependency.
Promptkit owns reusable, application-neutral library behavior. It does not own:
- binaries or executable packaging;
- CLI commands, parsing, streams, or exit codes;
- HTTP routes, servers, request DTOs, status mapping, or deployment policy;
- application configuration discovery or precedence;
- process lifecycle, operational state, or application logging; or
- consumer-specific filesystem or security policy.
Those concerns remain with Scriptorium or another consuming application.
## Package Ownership
The module root is the supported public facade. Framework implementation
packages belong under Go's `internal/` boundary unless a demonstrated, stable
consumer contract requires a public package.
Each package must have one cohesive responsibility and a clear dependency
direction. Internal packages must not expose their types merely to simplify
wiring, and the public facade must not leak internal representations through
exported signatures. New public packages require a durable consumer need that
cannot be served cleanly by the root facade.
The [internal component overview](../internal/overview.md) must be updated as
packages are implemented or their responsibilities change.
## Exported API Discipline
Export the smallest contract required by real consumers. Exported declarations
must have accurate GoDoc, stable semantics, and tests proportionate to their
compatibility risk. Avoid speculative extension points, aliases for internal
types, and public constructors that expose assembly details.
Once an exported API exists, its Go declaration and GoDoc own its exact public
contract. Architecture documentation owns boundary rules, not a duplicate API
reference.
## Error Boundaries
Internal failures must cross the public facade as errors meaningful to a Go
consumer without exposing private package types or transport-specific policy.
Wrapping should add useful context while preserving any public error identity
needed with `errors.Is` or `errors.As`.
Promptkit must not assign CLI exit codes or HTTP status codes. Consumers map
public library outcomes into their own transport behavior.
## Dependency Injection
External effects and consumer-selected policy must enter through narrow
interfaces or functions at the boundary that uses them. Dependencies should be
explicitly supplied during construction or invocation rather than read from
consumer configuration or hidden process-global state.
Interfaces should be owned by the code that consumes the behavior and should
contain only the operations that code requires. Provide defaults only for
application-neutral behavior; consumer-specific restrictions and adapters
remain injected from the consuming project.
## Repository Independence
Promptkit must build, test, and validate independently of Scriptorium. Do not
commit `go.work`, `go.work.sum`, or a local filesystem `replace` directive.
Temporary workspace or replacement configuration may support coordinated local
development, but it is not part of either repository's architecture or release
state.
## Current-State Maintenance
This policy distinguishes present implementation from constraints on future
framework extraction. Do not list planned packages as implemented components.
When extraction introduces a package, update the internal inventory and the
owning contract or subsystem document in the same change.