docs(architecture): N-4 + N-5 — push-options trait param, unborn-HEAD rider

- N-4: GitPackIngest's prepare binding carries push_options:
  Option<&PushOptions> (parsed (key, value) pairs, verbatim and
  un-interpreted; None until the config gate opens) — pinned in
  ADR-013 §11 and backend.md's trait description so opening the
  config gate later is value-additive, not a trait redesign
- N-5: ls-refs=unborn verification recorded as a rider in
  transport.md §ls-refs + tracker task tasks/architecture/
  n5-unborn-head-rider.md (unborn fixture, real client, both
  substrates; drop the token if it cannot be served — ADR-003)
- review 001: N-4, N-5 marked resolved

verification: cargo test, clippy -D warnings, fmt --check, doc — clean
This commit is contained in:
glm-5.3-flash committed 2026-09-30 04:19:37 +00:00
1 parent 82653c31b6
commit 11ceead6fd
5 files changed
+80 -4

No files matched your search

+6 -1
View File
@@ -51,7 +51,12 @@ gix types:
`.keep` guard; missing objects → `unpack ng`. It *prepares* the
validated ref updates; the transaction itself is applied by `GitRefs`
(single CAS home — ingest validates, refs commits; one transaction per
push is what makes `atomic` correct — ADR-013 §7). Budgeted (ADR-009
push is what makes `atomic` correct — ADR-013 §7). The prepare binding
carries `push_options: Option<&PushOptions>` (ADR-013 §11, review 001
N-4): the parsed per-push metadata, present only when `push-options`
was negotiated — `None` until the config gate opens; alkgit parses and
forwards the option pairs verbatim, never interprets them (their
meaning is the caller's policy domain). Budgeted (ADR-009
max pack size); the impl runs its blocking work off the async
executor (concurrency model below).
@@ -186,7 +186,12 @@ verification of the ingestion composition. Captures are recorded in
11. **Push-options**: negotiated (`push-options` advertised only when the
assembler enables it; default off in v1), request section parsed
(bare pkt-lines between the command flush and the pack) and surfaced
to the ingest/refs seam as per-push metadata. Rejection of specific
to the ingest/refs seam as per-push metadata: the prepared binding
carries `push_options: Option<&PushOptions>` — the parsed
`(key, value)` pair list, verbatim and un-interpreted — present only
when `push-options` was negotiated (`None` until the config gate
opens; review 001 N-4's additive-signature pin, so opening the gate
later is a value change, not a trait redesign). Rejection of specific
options is `ng <ref> <reason>`; the section's absence when not
negotiated must not be parsed as commands (the flush boundary is
authoritative).
+8
View File
@@ -68,6 +68,14 @@ substrate property (per-request state), not a protocol fork.
- Parse `command=ls-refs` (peel, symrefs, ref-prefix), stream ref lines
from the backend's listing, flush. `ref-prefix` filtering is
client-driven.
- **Unborn-HEAD rider** (review 001 N-5): `ls-refs=unborn` is advertised
(POC-1 validated the *capability token* was accepted, but serving an
unborn HEAD's symref line was never exercised against real git — the
only advertised promise without capture evidence). Implementation-phase
verification: an ls-refs round against an unborn repo, real client,
both substrates (the unborn repo fixture in the POC set has refs —
a new one without any). If it cannot be served correctly, the honest
move per ADR-003 is dropping the token.
### fetch
@@ -770,8 +770,8 @@ criticals are ADR-writing work, not code):
| N-1 | ref-cap breach behavior | one fail-closed clause in transport.md | trivial | none | **resolved** — ref cap fail-closed clause in transport.md §Limits (breach is an error, never truncation) |
| N-2 | unknown ≡ unauthorized at wire mapping | one sentence in transport.md error taxonomy | trivial | none | **resolved** — collapse rule stated at the variant→wire mapping in transport.md §error taxonomy |
| N-3 | schemas unpinned | backend.md types/schemas section | small | freeze inventory | open |
| N-4 | push-options seam | pin additive parameter shape | trivial | none | open |
| N-5 | `ls-refs=unborn` unverified | implementation-phase test rider (record in transport.md or a task) | trivial | none | open |
| N-4 | push-options seam | pin additive parameter shape | trivial | none | **resolved** — `GitPackIngest`'s prepare binding carries `push_options: Option<&PushOptions>` (parsed `(key, value)` pairs, verbatim and un-interpreted; `None` until the config gate opens) — pinned in ADR-013 §11 + backend.md trait description, so opening the gate is value-additive, not a trait redesign |
| N-5 | `ls-refs=unborn` unverified | implementation-phase test rider (record in transport.md or a task) | trivial | none | **resolved (rider)** — unborn-HEAD verification recorded in transport.md §ls-refs and tracker task `tasks/architecture/n5-unborn-head-rider.md` (unborn fixture, real client, both substrates; drop the token if it cannot be served — ADR-003) |
Suggested sequencing: (1) **A-2 + A-6** together (one trait-surface
amendment set + manifest change — they are the same signature surface);
@@ -0,0 +1,58 @@
---
id: architecture/n5-unborn-head-rider
name: Verify ls-refs=unborn serving (unborn-HEAD fixture, both substrates)
status: pending
depends_on: []
scope: narrow
risk: low
impact: wire-claim
level: implementation
tags: [verification-rider, advertisement-honesty]
---
## Description
Review 001 N-5: `ls-refs=unborn` is advertised (transport.md §advertisement,
ADR-003), and POC-1 validated real git accepting the capability *token* —
but serving an unborn HEAD's symref line was never exercised against a
real client (every POC fixture had refs). This is the only advertised
promise in the corpus without capture evidence. The rider is the
verification that closes it.
## Work
Implementation-phase test (lands with the ls-refs workstream):
1. Fixture: an unborn repo — registry record exists, `git init`-equivalent
storage with no refs (the POC set's unborn repo has refs; a new one
without any is needed).
2. V2 ls-refs against it over the duplex substrate with a real git client
(`git -c protocol.version=2 ls-remote`), asserting the unborn HEAD
symref line appears per the ls-refs grammar
(`<zero-oid> HEAD symref-target:refs/heads/<default>` unpeeled).
3. Same over the stateless (smart-http-shape) substrate.
4. Backend seam: the refs listing must expose the unborn symref for an
empty repo — verify the `GitRefs` trait shape carries it (a
`symref-target` with no oid); adjust the trait surface if the gix
listing cannot produce it.
If it cannot be served correctly: drop the `ls-refs=unborn` token from
the advertisement (the honest move per ADR-003 — decline by omission)
and record the drop in transport.md §advertisement.
## Verification
- Real `git ls-remote` (V2) against an unborn repo lists the unborn HEAD
symref line, both substrates.
- The full advertisement suite still passes against repos with refs
(the token must not change the served behavior there).
## Out of scope
- Unborn-HEAD push (an unborn repo's first push is ordinary ref creation
— ADR-013; not this rider).
- Any capability beyond the token's existing grammar.
## Summary
> Filled on completion.