Files
TORCH/docs/ARCHITECTURE_DECISIONS.md
T

123 lines
5.4 KiB
Markdown

# TORCH architecture decisions
Status date: 2026-09-27
This ledger resolves the implementation decisions identified by
`PORTABLE_AGENT_FLEET_SPEC.md` section 31. A decision marked **accepted** is
the current portable-core contract. A decision marked **gated** identifies a
feature boundary TORCH must not cross until a follow-up decision and acceptance
evidence exist.
## ADR-001: SQLite state and retention
**Status:** accepted.
Machine-local structured state uses one SQLite database per installed project,
with WAL, foreign keys, and a bounded busy timeout. Messages, acknowledgements,
audit records, presence, leases, check receipts, integration requests, context
samples, schedule runs, and Fleet changes share the project identity but remain
separate tables. TORCH performs no automatic history deletion. Retention or
compaction must be an explicit, owner-authorized operation added with recovery
tests; until then, durable records are append-preserving.
## ADR-002: Control-plane transport
**Status:** accepted.
The service layer is an in-process API. The agent-facing transport is MCP over
stdio and the non-MCP fallback is the structured CLI. The Fleet Console exposes
a read-only loopback HTTP projection of the same services. There is no required
daemon, Unix socket, network message queue, or hosted database. A future socket
transport must preserve identity binding and cannot become the data model.
## ADR-003: Project identity and repository moves
**Status:** accepted for the first release; moves are gated.
Installation creates an opaque project UUID stored in tracked configuration,
the ownership manifest, and machine-local metadata. All three must agree.
Machine-local state also records the canonical absolute repository root, and a
different root fails closed. Moving a managed repository therefore requires a
future explicit migration command that verifies identity and rewrites only the
local root binding; TORCH must not infer a move from a matching directory name.
## ADR-004: Runtime process supervision
**Status:** accepted.
Runtime adapters own process-specific creation, resume, status, capture, and
stop behavior and declare every capability. TORCH persists stable Fleet
identity and runtime session IDs but does not require a resident supervisor.
Unsupported controls fail explicitly and durable messages remain available.
The optional system-schedule launcher uses user systemd on Linux; macOS and
Windows launchers are separate adapters and are not claimed by this release.
## ADR-005: Configuration and generated files
**Status:** accepted.
`.torch/torch.yaml`, approved decisions, and tracked backlog records are
authoritative. `roster.yaml` and prompts are reviewable materializations of an
approved organization. The ownership manifest records their exact hashes;
doctor reports drift, and generated prose never overrides configuration.
Changing organization requires the Fleet-change workflow rather than editing a
generated prompt and treating it as policy.
## ADR-006: Runtime capability negotiation
**Status:** accepted.
Every adapter implements the common operation surface and declares support for
each operation. Startup validates the declaration before planning a launch.
The minimum useful adapter can create or resume a session and exchange durable
messages through CLI/MCP; live steering, hooks, listing, and stopping may be
reported unsupported. TORCH never substitutes an unsupported native feature
silently.
## ADR-007: Check invalidation
**Status:** accepted for the first release.
A check pass is reusable only for the exact Git commit and the exact hash of its
configured definition. A dirty or changing worktree produces no transferable
pass. Additional non-Git inputs require a future declared input-fingerprint
schema; until then projects must encode them in the check definition or rerun
the check. Branch names alone never validate a receipt.
## ADR-008: Local canonical remote naming
**Status:** accepted.
The local bare canonical remote is named `torch-canonical`, never `origin`, and
lives under machine-local project state as `remote.git`. Creation refuses an
existing path, remote-name collision, or dirty checkout. The configured remote
and path are recorded in tracked configuration and the ownership manifest.
## ADR-009: Multi-machine security
**Status:** gated.
The first release is single-machine and exposes no network control-plane write
surface. Multi-machine transport is prohibited until a separate decision
defines mutual authentication, encryption, project isolation, replay defense,
revocation, and recovery, with adversarial acceptance tests. A forge remote is
not a substitute for control-plane authentication.
## ADR-010: Distribution and update signing
**Status:** gated.
Local candidate builds use exact tree hashing, versioned compatibility
metadata, isolated state, and atomic activation/rollback. They are not signed.
Publishing a package or enabling unattended remote updates is blocked until a
follow-up decision selects artifact signing, trusted-key rotation, provenance,
and offline rollback verification. Local `npm pack` qualification does not
claim supply-chain authenticity.
## Consequences
These decisions keep the first usable release local-first and provider-
independent. They also make current boundaries explicit: repository moves,
multi-machine control, non-Linux persistent launchers, and published update
channels are unavailable rather than silently approximated.