Skip to content

Architecture decisions ​

Gin records its architecture decisions as ADRs. This page summarises each one. Most were written for the first milestone and are proposed until the milestone's discovery results are approved; the status of each is given below.

The agents-not-humans principle applies to every other decision.

Gin is built for agents, Git for humans ​

Status: accepted (2026-11-06). A product principle.

Gin is built for agents and machines; Git is built for humans. Gin does not copy Git's human-facing features and carries checkpoints, the DAG of dependent work, structured metadata, provenance, evidence and comments instead.

  • Git commits are not Gin nodes; Gin does not mirror or walk Git history.
  • Gin stores no commit messages, authors, committer dates or porcelain conventions.
  • A sync is one diff and one checkpoint in each direction; one sync record is the only link. Export refuses if the Git ref moved since the last sync.
  • Git parity means cost, not features: no extra work by default; extra guarantees are opt-in.
  • Work per sync is proportional to the change.
  • Older docs on authored Git imports and per-commit Git mappings are superseded. See Git interoperability.

Consistency of publication on one gin serve ​

Status: proposed.

How a worker's checkpoint reaches the daemon, how concurrent writers are kept apart, and how events are ordered.

  • One commit point per publication: exactly one SQLite transaction. No two-phase commit; atomicity comes from ordering and content addressing.
  • Objects before metadata, always. Metadata never references an object that is not durable and verified.
  • Every mutable pointer (channel heads, workspace epochs, write leases, Git export mappings) is updated by compare-and-swap. No blind writes.
  • Every server-side workspace mutation is fenced by the holder's write lease and epoch.
  • Every mutating request is idempotent; a retry returns the original outcome.
  • Events are written in the same transaction (transactional outbox), ordered per stream and replayed from a cursor. There is no global order or lock.

Durability of savepoints and publication ​

Status: proposed. The default policy was later changed to cached writes; full durability is opt-in.

  • The private workspace journal is an append-only journal: an edit is one unsynced append, a savepoint one append plus fsync.
  • Daemon metadata is SQLite in WAL mode; every publication is staged (objects durable and verified first, then one atomic metadata transition).
  • Any failed write or fsync poisons the store; a failed fsync is never retried and trusted.
  • Recovery never trusts cached bytes: it rewrites what it recovered before accepting work.
  • One open store per workspace, enforced by an exclusive lock that dies with its process.
  • Default cached mode keeps acknowledgements across a process kill but may lose recent work on an OS crash; full mode (GIN_DURABILITY=full) requires device barriers. See Getting started.

Evidence equivalence and strict exact-input reuse ​

Status: proposed.

What "the same inputs" means before a result may stand for a run that has not happened.

  • Strict mode is the only reuse mode for now.
  • A result is reusable only when its reuse key matches exactly, every component is known, and the test is cleared as hermetic. No partial match.
  • The source-input closure is the whole effective tree; reuse happens only across identical tree identities.
  • Declared, observed and verified inputs are separate records; none is treated as complete on its own word.
  • Reuse is advisory for now: Gin reports "would reuse" and skips nothing.
  • Reused evidence keeps its original trust and provenance and is labelled reused; a gate may demand a fresh run.

Integration and operations ​

Status: approved.

What runs where, who owns what, and how releases roll out and back.

  • One service: a single gin serve process on one Linux host, with SQLite metadata and the pack store embedded. Embedded-library mode runs the same core without a server.
  • One contract (gin.v1), several adapters: gRPC, local IPC, CLI and MCP. Within a major version changes are additive only.
  • Ownership stays put: the orchestrator owns tasks, reviews and landing decisions; Toki owns build and test execution; Gin owns source state and evidence; the forge keeps final landing authority.
  • Gin depends on no orchestrator schema and works with none present.
  • Git stays the external boundary: Gin holds no mirror or forge credential.
  • Rollback is switching the binary version and restarting; a binary refuses a store format newer than it understands. No persisted-format change lands without an upgrade path.

Threat boundaries and identity rules ​

Status: proposed.

  • Not a sandbox. Gin versions what lands in a workspace; containing processes belongs to the executor or harness.
  • Build scripts, shell commands, repository contents and compromised workers are untrusted to stated degrees. Gin never executes repository code, runs repository Git hooks or filters, or follows stored symlinks.
  • Hostile paths, collisions, oversized objects and crafted objects are refused at ingestion, never normalised.
  • Capabilities are scoped to repository, workspace and operation; a compromised worker can only do what its token allows, and its receipts never exceed executor-reported trust.
  • Identities are BLAKE3-256 over one canonical encoding in a per-kind domain; non-canonical input is refused. Git SHAs are never Gin identities.
  • An ID is a name, not a capability. Elapsed time alone never makes an object collectable.

Product hybrid directory manifests ​

Status: implementation decision.

How large directories are stored so that one edit stays cheap.

  • Directories up to 256 entries are sorted leaves; larger ones use compressed raw-byte prefix indexes.
  • This replaces an earlier hash-chunk layout that rewrote whole directories under crafted names.
  • Updates touch only changed groups; diff skips shared branches.
  • Exact source identity is kept for prefix-related and non-UTF-8 names.
  • No constant-time or depth-independent claim is made: long name prefixes can increase work.

Runtime resource ownership ​

Status: design record for the daemon runtime.

How the daemon bounds memory, descriptors and resident owners.

  • Bounded resident repositories and workspaces, evicted least-recently-used; active owners are never evicted.
  • Callers waiting for an owner queue in FIFO order and withdraw cleanly when cancelled.
  • One process-wide descriptor reservation pool; a request reserves its whole footprint before taking locks, so there are no partial-reservation deadlocks.
  • A request too large to ever fit gets a clear error rather than an endless wait.
  • No acknowledged state lives in disposable routing snapshots; missing or corrupt ones fall back to journal replay.

Last updated:

Part of the Tama toolchain.