Skip to content

About

Records of architectural decisions made for zingolabs' repos

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Zingolabs decision records

zingo-adrs holds the architecture decision records for every zingolabs code repository. "Architecture" reads broadly: any decision that shapes how a repository is built, tested, or released belongs here, whether it concerns system structure, process, or infrastructure.

Scopes

A record's path says which repositories it binds.

  • An org-scoped record binds every code repository. It lives at the top level, numbered NNN.
  • A repo-scoped record binds exactly one code repository. It lives in that repository's subdirectory (zaino/ for zaino), numbered NNNN.

Each scope numbers its records in its own sequence. Take the next free number when proposing; concurrent proposals may collide, so renumber at merge, not before. A gap in a sequence means a proposal was abandoned or renumbered, nothing more.

Citing a record

Inside zingo-adrs, a bare ADR-NNNN cites a record in the citing record's own scope. A citation into another scope carries the path: zaino/0016 names the zaino record, and 003 names the org-scoped one.

A code repository chooses the form by medium. A source comment names the repository and the scope, as in zingo-adrs zingolib/0011, because its reader may see it outside a checkout. Rendered Markdown links the record's file on the dev branch of zingo-adrs, as in https://github.com/zingolabs/zingo-adrs/blob/dev/zaino/0016-changeset-derived-release-pipeline.md, but only for a merged record, whose number no longer changes. Markdown cites a record whose pull request is still open in the source-comment form, without a link. Neither medium cites a checkout path such as docs/adr/zingolib/0011-…, which resolves only after the submodule is initialised and which GitHub cannot follow.

The append-only rule

Records are append-only. Supersede, never delete or rewrite: a reversed decision gets a new record, and the old record's status names its successor. A record documents the decision as made and does not track the code, so "the code changed" is never a reason to remove one.

Record shape

A record is a Markdown file named NNN-kebab-title.md (or NNNN- in a repository scope) whose first line is a # title. The first line under its ## Status heading is exactly one of:

  • accepted, from the pull request that proposes the record onward. The merge is the acceptance, so the line is written once and not edited afterwards to say so;
  • proposed, for a record merged to put an idea on the record before it is final. It binds nothing. A later pull request moves it to accepted or supersedes it;
  • superseded by [<citation>](<relative path to the successor>).

Prose after that line may narrow a partial supersession, but the line itself is the whole record's standing. A record states one decision: context, decision, consequences. Keep it short; full governed behaviour belongs in a specification in the code repository, referenced from the record.

Proposing a record

Open a pull request against dev in this repository. Records are never proposed in a code repository: zingo-adrs is the sole write side, and code repositories carry read-only copies.

Pointing a code repository at zingo-adrs

docs/howto-code-repositories.md explains, for a reader arriving from a code repository, how its docs/adr/ relates to this repository.

A code repository holds zingo-adrs as a git submodule at docs/adr/. Only the pointer, one commit hash, is checked in there; the records never enter that repository's history. A code repository's scope directory here, such as zingolib/, therefore appears at docs/adr/zingolib/ in its checkout, and the org-scoped records sit directly under docs/adr/. To add the submodule:

git submodule add git@github.com:zingolabs/zingo-adrs.git docs/adr

To materialise the records after cloning:

git submodule update --init docs/adr

To advance the pointer to the current dev of zingo-adrs, then commit the change:

git submodule update --remote docs/adr

A stale pointer is not a defect, and no code repository gates on it. The records are read-only from the code repository's side: propose changes here.

Checking

tools/workbench holds check-records, which CI runs on every pull request. It verifies file names, the status vocabulary, that every superseded by link resolves, that numbers are unique within a scope, and that the index below matches the records. Regenerate the index with:

cargo run --manifest-path tools/workbench/Cargo.toml -- --write .

Index

Org-scoped records

Number Record Status
001 No upstream types in public APIs accepted
002 client_rpc_test_fixtures moves to its own repository accepted
003 ADR: Branching, Versioning, Documentation, Public Interfaces, and Release Strategy superseded by zaino/0016
004 Decision records live in zingo-adrs and are mirrored into code repositories by subtree superseded by 005
005 Code repositories point at zingo-adrs by submodule, and hold none of its content accepted

Repo-scoped records: zaino

Number Record Status
0001 zcashd_support feature gate superseded by zaino/0017
0002 Live tests rejoin the root workspace under a single lock accepted
0003 Live-test taxonomy and two-crate split accepted
0004 Rename the integration live-test partition to clientless; single makers test front door accepted
0005 zcashd_support is opt-in, not a default feature superseded by zaino/0017
0006 aws-lc-rs is the preferred CryptoProvider; classical key exchange is deprecating accepted
0007 Block persistence is a row-set boundary; the domain block is not a storage value accepted
0008 Validator access is a set of single-question ports over domain primitives accepted
0009 The served JSON schema lives in zaino-serve, beside its only consumer accepted
0010 ADR 0010: Mempool subsystem separated into zaino-mempool behind ports accepted
0011 The non-finalised chain head is a self-synchronising subsystem accepted
0012 The finalised state is a subsystem behind ports, and its database is one implementation of them accepted
0013 Domain quantity types carry invariants on results, not on operators accepted
0014 Validator readiness is owned by the runtime, not by its source consumers proposed
0015 Zaino Release Flow Design superseded by zaino/0016
0016 Releases derive from changesets through a four-branch gated pipeline accepted
0017 zcashd support is removed; Zebra is the only backing validator accepted
0018 The served block representation is a choice of index set superseded by zaino/0022
0019 Crate boundaries follow an independent-variation criterion proposed
0020 Errors keep their cause typed; a variant exists because a caller branches on it proposed
0021 zainod is the only consumer of zaino's library crates; in-process embedding is unsupported proposed
0022 The index set is a build-time choice proposed

Repo-scoped records: zingo-mobile

Number Record Status
0001 Shield and self-send change outputs prefer the Ironwood pool accepted
0002 Errors are types accepted
0003 Errors and data flow in separate channels accepted
0004 The mixnet shim's TLS verifies against Android's platform verifier superseded by zingo-mobile/0006
0005 The mobile proxy shim lives in this repository superseded by zingolib/0054
0006 The mixnet proxy's TLS verifies against the compiled-in Mozilla bundle accepted
0007 The biometric gate is a privacy shutter accepted
0008 Excise zcashd by removing the regchest test backend accepted
0009 Error channels carry ErrorKeys, never prose accepted
0010 Wallet files rely on OS protection, not app-layer encryption accepted
0011 Releases senesce by chain height instead of a remote kill switch proposed
0012 The price surface has no manual fetch accepted
0013 The proxy component is named for the mixnet accepted
0014 The mixnet's three legs are observed by capture and probe accepted
0015 zingo-mobile carries no product Rust proposed
0016 zingo-mobile pins zingolib by submodule accepted
0017 The controller machine is a discriminated union over the native runtime proposed
0019 Device tests read public chains through fixture wallets proposed
0020 zingo-mobile takes the Binding Layer from published Prebuilt Bundles proposed

Repo-scoped records: zingolib

Number Record Status
0001 LightClient starts offline by default accepted
0002 Regtest support is compiled out of production builds accepted
0003 Test-owned chain caches snapshot completed setup and record returned outputs accepted
0005 Retire the darkside-tests crate and the orphaned zingo-testutils crate accepted
0006 The pending proposal lives in the wallet; offline signing reads it accepted
0007 Library Birthday: a release-stamped floor for never-online wallet creation accepted
0008 Offline-signed transactions get their expiry by proposal retarget, not a builder override accepted
0009 Tests run Ironwood-era by default; Orchard-era behavior is opt-in accepted
0011 IP obfuscation for Transmission and price-fetch runs over the Nym mixnet accepted
0014 Pool Activation is derived once, in pepper-sync, from zcash_protocol parameters accepted
0015 ADR 0015: Landing in dev ships the wallet file format accepted
0016 Note-splitting execution is a stateless, send-shaped call accepted
0017 Phase 2 parts are due for the whole open window, and the random target is advisory accepted
0018 A part's anchor boundary is drawn at an age of one bucket or more, never at the window it broadcasts in accepted
0019 Immediate migration (Drain) is exposed as a send-shaped call accepted
0020 Migration logic delegates to zcash_pool_migration accepted
0021 The mixnet shim's TLS verifies against the compiled-in webpki bundle accepted
0022 A Broadcast Witness is never the sync indexer accepted
0023 Top-window sync rides the mixnet accepted
0024 24. Consumers converge on a zingolib-owned mixnet surface proposed
0025 25. Going online requires Connectivity Consent accepted
0026 26. Mixnet capability compiles by default; activation stays a runtime consent accepted
0028 28. The reference consumer lives in-repo in an excluded sub-workspace proposed
0029 29. A maintained mixnet indexer pool replaces server selection superseded by zingolib/0038
0030 The CLI crosses sync to async exactly once, dispatching from a static command table accepted
0031 CLI stdout carries only the result; failures and narration travel on stderr, and a failed one-shot exits nonzero accepted
0032 network off is zero-emission teardown, and --offline suppresses the network surface accepted
0033 Network access demands a consent-tiered Network Observer accepted
0034 Server selection is a mixnet liveness sweep proposed
0035 The acquisition race speaks the literature's vocabulary proposed
0036 A Destination, not a witness, receives a Transmission accepted
0037 Broadcast means many recipients proposed
0038 An Exit Node Reservation is unique to its holder proposed
0039 An Exit Node is Exclusive to one Destination or Shared across many proposed
0040 Send's escalation is a hedged race of full paths proposed
0041 A platform-typed Mixnet Session acquires every transport proposed
0042 A Destination Reservation levels concurrent Transmissions across operators proposed
0043 A survey proves its exit with a Sentinel, and restarts when the proof fails proposed
0044 A client proves its exit before its first role, and later clients trust fresh proof proposed
0045 Boot proves four exits and assigns them by role proposed
0046 The wallet asks for a mixnet conduit by role proposed
0047 Roles key conduits, and the wallet stops naming exits proposed
0048 A mobile session rotates one client rather than separating roles proposed
0049 Every transport comes from a long-lived host proposed
0050 Indexers are classified by role, trust, and location, and one broadcast rule draws from them accepted
0051 Continuous sync keeps the wallet current as new blocks are mined accepted
0052 Indexerless operations are pure functions; effects live at the edges superseded by zingolib/0006
0053 Destinations are drawn from the indexer registry per chain, on every transport superseded by zingolib/0050
0054 The Binding Layer lives beside the surface it wraps accepted
0055 zingolib admits Swift, Kotlin, and TypeScript with their native tooling proposed
0056 Block-count constants follow their semantics across the NU7 block-spacing change accepted

About

Records of architectural decisions made for zingolabs' repos

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages