docs(architecture): resolve OQ-06/07/08 — per-repo authz, registry backing, CRUD ops

ADR-011 (resolves OQ-08): per-repo authorization — grants live in repo
records keyed on the stable logical identity id (alkcall ADR-025,
referenced); policy is alkgit-core's authorize() function (public+read
anonymous-first-class, write always authenticated+granted); alkgit
stores no identity records; vault placement resolved as nothing to
place in v1.

ADR-012 (resolves OQ-06/OQ-07): registry backing + write surface —
GitRegistryStore write supertrait (alknet ADR-035 read/write split
shape); registry-file default (per-repo record files + in-memory
index, config-seeded, op-mutable, no gitoxide); git/repo/* CRUD ops
shipped External with scope+ownership ACL (create mints ownership and
seeds creator grants; ownership never implies git access); the
two-op-kind classification recorded (open op + call ops from one
crate, per alkcall ADR-047); recorded split trigger for a downstream
platform crate.

Doc sync: backend.md (five-trait family, feature model split,
two-op-kinds), doors.md + overview.md (authorize policy, dual-kind
crate map), open-questions.md (OQ-06/07/08 resolved), README (ADR
table, current state), oq-06 tracker task closed (resolved early).

Verification: cargo test (default + --no-default-features), clippy
-D warnings, fmt --check.
This commit is contained in:
glm-5.3-flash committed 2026-09-21 16:26:59 +00:00
1 parent 86bf5a0cf0
commit addc874667
8 files changed
+492 -104

No files matched your search

+43 -47
View File
@@ -24,8 +24,8 @@ when their impacts say so; it records how careful the resolution must be.
| OQ | Status | Blocked on / investigation |
|---|---|---|
| OQ-04 | deferred(unclear) | receive-pack walkthrough (capabilities, shallow, thin-pack, CAS timing) + push POC |
| OQ-06 | deferred(scope) | concrete metadata-scale requirements (feeders: OQ-07, OQ-08 outputs) |
| OQ-05 | deferred(scope) | ecosystem need for sha256 |
| OQ-03 | partially resolved | first-publish timing (release decision; the freeze inventory lives in backend.md/transport.md) |
## Theme: composition / crate shapes
@@ -60,9 +60,11 @@ when their impacts say so; it records how careful the resolution must be.
- **Origin**: [overview.md], [transport.md], vision §"ALPN as a service"
- **Status**: **partially resolved** — the shape is settled (ADR-010):
embedding = one crate + backend traits (own storage via
`default-features = false`, or the gix feature) + optional door
features. What remains deferred is the publish-time API freeze itself:
which type/feature names are pinned at first crates.io publish.
`default-features = false`, or the `gix`/`registry-file` features) +
optional door features. What remains deferred is the publish-time API
freeze itself: which type/feature/op names are pinned at first
crates.io publish. ADR-012 added the `git/repo/*` op set (names +
schemas) to the freeze inventory.
- **Door type**: one-way (API freeze is registry-visible to dependents)
- **Priority**: medium
- **Impacts**: blocks the first publish only, not implementation.
@@ -70,7 +72,7 @@ when their impacts say so; it records how careful the resolution must be.
architecture question). The API surface inventory lives in
[backend.md](backend.md) §public API and [transport.md](transport.md)
§public API.
- **Cross-references**: ADR-010, ADR-002, backend.md, transport.md
- **Cross-references**: ADR-010, ADR-002, ADR-012, backend.md, transport.md
## Theme: transport / protocol
@@ -138,55 +140,49 @@ when their impacts say so; it records how careful the resolution must be.
- **Origin**: [overview.md], [doors.md], [backend.md]; originally "identity
sources per front door"
- **Status**: open — narrowed by ADR-010. Door auth mechanics (http token
handling, ssh keys) belong to the door crates; what remains for alkgit
is: the identity model the `GitRegistry` knows (what an identity is,
what identity records exist, whether they live in the same metadata
store as repo records — OQ-06's field list may grow), and where
credential material lives (alkvault; metadata holds references only).
- **Door type**: two-way
- **Priority**: high
- **Impacts**: blocks backend.md's registry trait field list finalizing;
blocks the admin-ops shapes (OQ-07).
- **Resolution path**: one focused session on the registry identity model
+ alkvault placement.
- **Cross-references**: ADR-007, ADR-010, OQ-06, OQ-07, backend.md
§GitRegistry, doors.md
- **Status**: **resolved** — ADR-011 (per-repo authorization): the
identity model is alkcall's resolved `Identity` keyed on its stable
logical id (alkcall ADR-025 property, referenced); alkgit stores no
identity records; grants live in repo records; the public+read /
always-authenticated-write policy is alkgit-core's `authorize`
function (the clause ADR-007 pinned but the static ACL engine could
not express); vault placement resolved as **nothing to place in v1**
(no credential-shaped material in metadata).
- **Resolution**: [decisions/011-per-repo-authorization.md]
- **Cross-references**: ADR-007, ADR-008, ADR-011, ADR-012, OQ-06, OQ-07,
backend.md §GitRegistry, doors.md
## Theme: storage / metadata
### OQ-06: Registry/metadata backing store (gix feature)
- **Origin**: [backend.md] (was storage.md), ADR-008
- **Status**: deferred(scope)
- **Door type**: two-way (backing choice is swappable behind the
`GitRegistry` trait)
- **Priority**: high for the gix feature's default story, but choice
deferrable because the trait boundary is what matters
- **Impacts**: blocks backend.md's gix-feature registry impl finalizing;
does NOT block the wire layer (it codes against the trait).
- **Blocked on**: concrete metadata-scale requirements (how many repos,
what metadata fields beyond id/root/visibility/ACL scope, whether
identity records join — OQ-08's output, whether hub integration lands
in v1). A config-file or embedded-store decision without those inputs
would be a guess. Tracker task:
`tasks/architecture/oq-06-metadata-backing.md`.
- **Cross-references**: ADR-008, ADR-010, backend.md §"The trait family" (GitRegistry), OQ-08
(whose identity-records question may extend this store's field list)
- **Status**: **resolved** — ADR-012 (registry backing + write surface):
the alknet repo/adapter pattern applied — `GitRegistry` read trait +
`GitRegistryStore` write supertrait; default backing is the
`registry-file` feature (per-repo record files + in-memory index,
config-seeded, op-mutable, atomic writes — no gitoxide); persistence
adapters (SQLite et al.) are future, separate, additive, gated by a
real deployment need — the deferred "scale requirements" never gated
the default, only that future adapter.
- **Resolution**: [decisions/012-registry-backing-and-ops.md] §1–2, §4
- **Cross-references**: ADR-008, ADR-010 (feature story amended), ADR-011,
backend.md §feature model
### OQ-07: Admin API operation set (v1 scope)
- **Origin**: [overview.md], alk-stack.md §"The gitea lesson"
- **Status**: open — rescope note (ADR-010): there is no alkgit binary, so
there is no alkgit-owned admin surface. The question narrows to whether
the gix feature's `GitRegistry` implementation ships with any management
ops (repo create/delete, visibility, ACL grant) as reusable alkcall ops,
or whether registry mutation is entirely downstream assembly work. If
shipped, they are `Visibility::Internal` alkcall ops over the
assembler's admin listener — never the git traffic surface.
- **Priority**: medium
- **Impacts**: blocks the gix feature's registry impl scope; OQ-08's
identity model determines the op shapes.
- **Resolution path**: decide alongside OQ-08 (one session can settle
both).
- **Cross-references**: ADR-007, ADR-010, OQ-08, backend.md §"The trait family" (GitRegistry)
- **Status**: **resolved** — ADR-012 (§3, §5): the crate ships a minimal
CRUD op set (`git/repo/{create,delete,update,get}`) as thin call ops
over `GitRegistryStore`, `Visibility::External`, always-on, gated by
scopes (global tier, e.g. `git:admin` / `git:repo:create`) + ownership
(self-owned tier; create mints ownership per alkcall ADR-011 and
seeds the creator's grants — ownership never implies git access,
ADR-011). The old "Internal ops over an admin listener" framing is
superseded (right mechanism, wrong axis — visible-surface =
authorized-surface is served by the ACL). Ops stay record-scoped;
anything beyond repo records (users, orgs) is a downstream platform
crate (the recorded split trigger, ADR-012 §5).
- **Resolution**: [decisions/012-registry-backing-and-ops.md] §3, §5
- **Cross-references**: ADR-007, ADR-011, ADR-012, alkcall ADR-017/011,
backend.md §"The two op kinds"