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.
188 lines
9.4 KiB
Markdown
188 lines
9.4 KiB
Markdown
---
|
||
status: draft
|
||
last_updated: 2026-09-21
|
||
---
|
||
|
||
# Open Questions
|
||
|
||
All unresolved architecture questions, centrally tracked. Status values:
|
||
`open` (needs resolution now), `partially resolved` (decision made but a
|
||
narrower question remains — named in the entry), `resolved` (decision
|
||
made, ADR recorded), `deferred(scope)` (waiting on external information —
|
||
blocked-on condition stated), `deferred(unclear)` (pieces exist, shape
|
||
needs investigation). See `docs/sdd_process.md` for the deferral protocol
|
||
(blocker tasks in `tasks/architecture/`).
|
||
|
||
**Door type** classifies reversal cost: `one-way` decisions are
|
||
expensive/impossible to reverse once published (wire formats, public API
|
||
shapes); `two-way` decisions can be revisited while nothing is published.
|
||
Door type does not change urgency — all decisions here need resolution
|
||
when their impacts say so; it records how careful the resolution must be.
|
||
|
||
## Deferred / Blocked summary
|
||
|
||
| OQ | Status | Blocked on / investigation |
|
||
|---|---|---|
|
||
| OQ-04 | deferred(unclear) | receive-pack walkthrough (capabilities, shallow, thin-pack, CAS timing) + push POC |
|
||
| 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
|
||
|
||
### OQ-09: Slim-crate model — doors as family infrastructure, git as a payload service
|
||
|
||
- **Origin**: user session (2026-09-21); ADR-006, ADR-001, ssh.md
|
||
- **Status**: **resolved** — ADR-010 (pure protocol crate, the alktty/
|
||
alktunnels template): single `alkgit` crate, producer/consumer halves,
|
||
backend traits with feature-gated gix, no doors, no binary; ALPN
|
||
`alk/git`; http mounting → alkhttp `git` feature; git-over-ssh →
|
||
alkssh (russh scaffolding dropped); the monorepo/binary framing was an
|
||
init-agent artifact (vision amended).
|
||
- **Resolution**: [decisions/010-pure-protocol-crate.md]. All five
|
||
sub-decisions recorded there (ssh deletion, http home, crate
|
||
granularity, backend-trait surface, binary fate).
|
||
- **Cross-references**: ADR-001/006 (superseded), OQ-01, OQ-03, OQ-08,
|
||
doors.md, backend.md, overview.md
|
||
|
||
### OQ-01: HTTP adapter home and composability (alkhttp `git` feature vs alkgit-owned factory)
|
||
|
||
- **Origin**: user session question (OQ-01, resolved 2026-09-21)
|
||
- **Status**: **resolved** (subsumed by OQ-09/ADR-010) — the smart-http
|
||
stateless substrate stays in `alkgit` (IO-abstract); the http mounting
|
||
(routes, content types, `with_extra_routes` wiring) becomes an alkhttp
|
||
`git` feature published after alkgit's first publish. The ADR-006
|
||
router-factory shape is superseded; the alkhttp-side feature is the
|
||
outcome.
|
||
- **Cross-references**: ADR-006 (superseded), ADR-010, doors.md
|
||
|
||
### OQ-03: Downstream embedding surface (what "embeds alkgit" means concretely)
|
||
|
||
- **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`/`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.
|
||
- **Blocked on**: first-publish timing (a release decision, not an
|
||
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, ADR-012, backend.md, transport.md
|
||
|
||
## Theme: transport / protocol
|
||
|
||
### OQ-02: V2 multi-round negotiation (ack/NAK logic, `wait-for-done` retirement)
|
||
|
||
- **Origin**: [transport.md], poc2-findings §"does NOT settle"
|
||
- **Status**: open
|
||
- **Priority**: medium (full-closure-on-`done` works; multi-round is an
|
||
efficiency feature, not correctness)
|
||
- **Impacts**: fetch efficiency on repos with large shared history;
|
||
capability advertisement text (`fetch=` value).
|
||
- **Resolution path**: design the ack loop (rounds budget per ADR-009)
|
||
when transport implementation begins; POC-2's generator is
|
||
negotiation-agnostic already.
|
||
- **Cross-references**: ADR-003, ADR-004, ADR-009, transport.md §fetch
|
||
|
||
### OQ-04: receive-pack (push) — validation gap
|
||
|
||
- **Origin**: [transport.md], poc3-findings §"does NOT settle"
|
||
- **Status**: deferred(unclear)
|
||
- **Door type**: two-way
|
||
- **Priority**: high
|
||
- **Impacts**: blocks receive-pack implementation tasks; push is the
|
||
always-authenticated half of the wire surface.
|
||
- **Investigation**: the pieces are decided (POC-2: pack ingestion via
|
||
`gix-pack::data::input` with `streaming-input` (ADR-004); `gix-ref`
|
||
transaction CAS; fsck via `gix-fsck`; POC-3: request bodies stream). The shape to
|
||
work through: the full push state machine —
|
||
(a) the receive-pack **capability advertisement set**
|
||
(`report-status`/`report-status-v2`, `delete-refs`, `push-options`,
|
||
`atomic`, `side-band-64k`, `object-format`) under the honest-advertisement
|
||
invariant (ADR-003); (b) request-line parsing
|
||
(`<old> <new> <ref>` + shallow lines policy — expected resolution:
|
||
**reject shallow on push for v1**, mirroring fetch's decline-by-omission
|
||
in ADR-003, so depth semantics stay symmetric; confirm against real
|
||
`git push` behavior);
|
||
(c) thin-pack acceptance on push (client packs may be thin; accepting
|
||
implies base-object availability requirements); (d) pack ingestion
|
||
mid-stream; (e) CAS validation timing (before vs after pack index);
|
||
(f) status report (`unpack ok|ng` + per-ref lines); (g) the
|
||
receive-pack version/framing surface over http (which framing `git push`
|
||
uses against us; ADR-003's V2 decision covers fetch only). Method:
|
||
walkthrough against real `git push` captures, then a small POC if the
|
||
ingestion composition is not obvious from POC-2's findings. Tracker
|
||
task: `tasks/architecture/oq-04-receive-pack.md`.
|
||
- **Cross-references**: ADR-003, ADR-004, ADR-009, transport.md
|
||
§receive-pack, backend.md §"The trait family" (GitRefs), doors.md
|
||
|
||
### OQ-05: sha256 support policy
|
||
|
||
- **Origin**: [transport.md], git-protocol.md §"Open items"
|
||
- **Status**: deferred(scope)
|
||
- **Door type**: two-way
|
||
- **Priority**: low
|
||
- **Impacts**: none for v1 (sha1 pinned); feature-flag passthrough
|
||
compiles but is untested end-to-end.
|
||
- **Blocked on**: ecosystem need (a real client/repo requiring sha256) or
|
||
upstream gix sha256 maturity; POC-2 left the pipeline hash-generic but
|
||
untested. Tracker task: `tasks/architecture/oq-05-sha256.md`.
|
||
- **Cross-references**: ADR-003, ADR-004
|
||
|
||
## Theme: identity / auth
|
||
|
||
### OQ-08: Registry identity space + vault placement (narrowed)
|
||
|
||
- **Origin**: [overview.md], [doors.md], [backend.md]; originally "identity
|
||
sources per front door"
|
||
- **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**: **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**: **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" |