acceptance tests #
these are implementation requirements. run the real-nginx slice with:
NGINX_BINARY=/absolute/path/to/nginx scripts/acceptance-nginx.sh
that command fails if nginx is absent or replaced by a stub. the route oracle is
spec/acceptance-routes.json; it is independent of the generated manifest and checks HTTP status,
body, and content type for each spelling. all 43 machine-readable cases in spec/acceptance.json
are tracked in the handoff report; unimplemented cases remain not_run.
harness requirements #
construct a small deterministic fixture family: two repositories, multiple ref aliases, branches with shared tips, merges and same-tree commits, annotated tags, supported object formats, symlinks/submodules, binary/large files, and reserved/private objects. generate large-history fixtures separately for work counts and memory tests. pin commit metadata when reproducibility matters.
obtain intended wire behavior from the vendored handlers/schema/profile and explicitly reviewed bug fixes. enumerate expected routes independently from the new manifest. checking only what the compiler happened to emit cannot find omissions. use actual nginx for the nginx backend, plus real git clients for export tests. compare status/body/headers, not only parsed JSON values. add exact-byte checks only where bytes are part of the contract; don't accidentally require arbitrary JSON object key ordering.
concurrency tests use explicit barriers/failpoints around capture, installation, sealing, and activation. filesystem/process crash tests are distinct from power-loss durability guarantees; document the filesystem and failure model. injected fsync errors must be visible to publication.
cases #
locality #
A01 - targeted update preserves other repositories. create two repos, publish both, then push only repo a. assert: repo b release id and payload bytes remain unchanged; its routes still work; catalog remains complete.
A02 - healthy unchanged push. publish a repo then repeat with all complete inputs unchanged. assert: no staging, fact computation, export subprocess, materialization, data rehash/sync, or nginx reload; active identity stays the same.
A03 - unchanged source after failed publication. accept refs but fail compilation or activation; run again without ref changes. assert: repair is attempted; desired state is not confused with last successfully active state.
inputs #
A04 - symbolic HEAD changes at the same commit. main and other point to one commit; switch symbolic HEAD. assert: snapshot identity changes where observable; default branch and affected responses update.
A05 - non-commit inputs invalidate relevant output. change alias/name or relevant profile/limits/wire version without changing tips. assert: appropriate bindings/rendering are rebuilt; unrelated reusable facts remain valid; no erroneous no-op.
A06 - annotated tags and object formats. use lightweight and annotated tags, nested annotated tags where supported, and supported object formats. assert: raw tag identity, peeled targets, correct OID widths and unsupported non-commit target errors are preserved.
A07 - empty and unusual HEAD states. use unborn/empty repo and supported detached/default-branch edge cases. assert: snapshot/export/read responses follow explicit compatibility behavior without panics or invented branches.
wire #
A08 - alias body and header identity. request branch, full branch, tag, HEAD and explicit commit routes sharing facts/body bytes. assert: ref spelling stays correct and mutable versus immutable HTTP metadata does not bleed across routes.
A10 - combined raw and JSON blob semantics. test text, binary, invalid UTF-8 and sizes around each raw/JSON limit. assert: sharing bytes does not merge distinct eligibility, MIME, encoding, size, or error policies.
A11 - symlink and submodule handling. use symlink and submodule entries plus differing .gitmodules contents. assert: modes/path semantics and errors match supported behavior; no host filesystem symlink is followed as repo content.
A14 - path-dependent metadata for identical blobs. same bytes at paths with different extension/MIME/disposition context. assert: raw bytes may reuse but each path receives its correct response metadata.
A15 - case and escaping boundaries. case-distinct paths/refs and names with supported escaped characters; include traversal attempts. assert: case remains distinct; HTTP encoding and nginx escaping are correct; no filesystem/config injection or path escape.
A19 - compare and pagination restrictions. exercise supported ordered compare pairs/bounds and invalid revspec/page/prefix combinations. assert: preserve profile, merge semantics, error vocabulary, status and response limits; no silent feature expansion.
A35 - repository/ref listing completeness. multiple repos/refs and profiled pages, plus targeted push/name changes. assert: global listings follow actual dependencies; correct stable ordering/paging; no hidden dropped entries.
A41 - actual serving and independent route coverage. enumerate required routes independently, then issue actual HTTP requests through nginx or selected reader. assert: verify completeness, status, body, content type, cache/disposition headers, and applicable HEAD/range/conditional behavior.
work #
A09 - alias-independent language and diff computation. many supported aliases point to one captured semantic input. assert: language/diff executions do not scale with alias count; response envelopes may.
A12 - batched directory attribution. many files in a few directories at one commit. assert: one directory attribution result feeds tree and child blob metadata rather than repeated single-file walks.
A16 - single-pass full history with complete pages. long history with each profiled log page shape. assert: one walk per requested semantic tip and complete pages with correct order, total and cursor behavior.
A17 - warm history page-group reuse. change one ref while another tip stays cached. assert: all supported pages for the unchanged tip remain available, not only 50@0.
A18 - archive keys and bounded memory. same tree at two commits, differing prefixes/options, and large tar/zip outputs. assert: compatible archives reuse; differing observable options do not; completed archives leave memory promptly.
correctness #
A13 - history-sensitive attribution. create same-tree commits through different parents, merges, deletion/readdition and renames. assert: attribution matches the existing intended algorithm; tree-only reuse or first-parent shortcuts do not change answers.
lifecycle #
A20 - coherent input under overlapping ref edits. pause capture/build with explicit barriers and attempt managed ref updates. assert: candidate corresponds to a coherent captured state; producers never reread moving aliases.
A21 - object lifetime under maintenance. pause build after capture; attempt managed prune/repack after rewind or delete. assert: required source objects stay available under the documented coordination protocol; no reserved pin refs leak.
storage #
A22 - old-release immutability. reuse files, fail a candidate after export/control-file writes. assert: all previous release bytes remain unchanged, including smart artifacts, fingerprints and control metadata.
A23 - concurrent equal-key installation. synchronize writers installing the same new dependency key. assert: each observes a complete valid entry or structured failure; no shared tempfile collision or partial cache hit.
A24 - cache eviction after release sealing. remove repo-local cache entries used by a published release. assert: release-owned files still serve correctly; future cache misses safely recompute.
A25 - missing or corrupt cache/active metadata. remove/truncate cache entries, completion markers and separately active metadata. assert: invalid cache is ignored/rebuilt; invalid active state enters repair or explicit failure rather than a false healthy no-op.
A26 - durability failpoints. inject errors/crashes before and after file finalization, directory sync, sealing and publication. assert: restart finds a complete old/new state or a documented recoverable candidate; never a partially live release.
A27 - GC versus in-flight users. hold worker/request/transfer references while cleanup runs. assert: no still-required release/cache installation is deleted; retained-but-private data is not auto-exposed.
publication #
A28 - stale candidate and rollback ordering. finish an older build after a newer successful activation; then explicitly roll back. assert: older candidate cannot displace newer state; deliberate rollback uses a new revision under current policy.
A29 - concurrent different-repo activation. two repos prepare candidates, interleave backend publication. assert: both updates survive; publisher merges against current backend state without unrelated payload rewriting.
A30 - failed backend activation. fail nginx config test/reload or selected reader installation. assert: prior healthy active release stays available; desired, sealed and actually active states remain distinct.
A31 - crash across activation acknowledgement. crash after backend change but before active-state bookkeeping and vice versa. assert: restart reconciles actual backend state without falsely declaring unchanged or overwriting newer state.
resources #
A32 - cross-process admission limits. launch several SSH/admin CLI processes simultaneously. assert: active builds, CPU work, subprocesses and memory reservations obey installation-wide configured bounds.
A33 - child cleanup on error. make projection fail while git export/compression is running. assert: children are canceled or joined before staging/locks are dropped; no orphan build writes.
A34 - large-output memory bounds. large blobs, histories and archives under configured budgets. assert: peak buffers stay bounded; limits fail explicitly; no all-archives/all-pages unbounded accumulation.
export #
A36 - safe public fast-forward export. advance public tips without shrinking allowed reachability. assert: refs/HEAD match captured snapshot and clone/fetch succeed; reused packs stay immutable.
A37 - delete and rewind reconciliation. delete a public branch and force-rewind another. assert: stale refs disappear; permitted object set is enforced with a sanitizing fallback as needed.
A38 - private and reserved object isolation. source has reserved refs and packs mixing public/private or unreachable objects. assert: export and HTTP object access expose only allowed data; no public alternates into source/cache.
A39 - multi-request git operation during activation. pause real clone/fetch after advertisement, activate and attempt cleanup, then continue. assert: chosen compatibility/visibility policy is explicit and enforced; per-request pinning alone is not assumed sufficient.
A40 - transport capability honesty. run supported real-client clone/fetch plus shallow/filter or other unsupported requests. assert: supported modes remain compatible; unsupported modes fail intentionally; canned response is not claimed to be general negotiation.
migration #
A42 - legacy rollback and old-worker retention. shadow-build new layout, activate, retain old nginx workers, then roll back safely. assert: source state/credentials untouched; legacy CAS not deleted while referenced; rollback restores working supported routes.
A43 - remove obsolete global coupling. finish cutover and inspect new generation/storage call graph. assert: new release has no legacy/shared-CAS dependency; no duplicated old/new source of truth or global route collector remains.
completion criteria #
report each case as pass/fail/not-run with its command, fixture identity, backend, and evidence path. passing a body-only unit test is not a substitute for its corresponding serving/transport test. performance cases need observable work counters, not just a time threshold. no failure in visibility, old-release immutability, stale activation, or route completeness can be traded away for a lower latency.
for an unselected thin reader, its backend-specific cases remain not-run/not-applicable with a reason; the common architecture must still pass its nginx-path cases. old-worker GC and multi-request transport retention remain explicit release blockers until a safe policy is implemented or clearly bounded.