G2/G4 complete: Gitea live, LFS landing in R2, four traps pinned

VERIFIED END TO END from outside the network:
  - create repo via API -> clone -> commit -> push -> read back over HTTPS
  - 3 MB LFS object pushed through the tunnel, landed in R2 at lfs/34/2d/...
  - NO local lfs/ directory on the host: I-3 confirmed by measurement
  - /health/full: db, gitea and r2 all green

Adds strand G4A recording four traps that each cost a crash loop, with tests:
  1. [lfs] STORAGE_TYPE creates a separate storage section that does not
     inherit [storage] — crash loop, error names the symptom not the cause
  2. storage backend != LFS enabled; LFS_START_SERVER is separate, and its
     absence reads as a permissions error
  3. Gitea env-to-ini SETS but never UNSETS — removing a compose var leaves the
     line in the persisted app.ini, so repo config and prod config silently
     disagree. Exactly the drift this cell exists to end.
  4. R2 rejects the default S3 checksum algorithm

And G4A.5, which is architecture rather than a bug: an 8 MB non-LFS push died
with HTTP 524 at Cloudflare's ~100s limit. This makes the LFS threshold
load-bearing and REQUIRES G10 to serve model weights via presigned R2 URLs
rather than proxying blobs through the tunnel — client straight to R2, which is
what Hugging Face does and which takes Grant's home upstream out of the path.

G2.4: Gitea's MIT text and a NOTICE now travel with the repo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Grant Whitmer
2026-08-11 15:13:58 -04:00
parent 647d414ec1
commit 82044933ed
4 changed files with 142 additions and 0 deletions

View File

@@ -234,3 +234,53 @@ def test_g05_no_secret_literals_committed():
text = path.read_text(encoding="utf-8", errors="ignore")
for pattern in patterns:
assert not pattern.search(text), f"credential literal in {path}"
# --------------------------------------------------------------------------
# G2.1 / G2.7 — the Gitea version is PINNED, and drift is a failure
# --------------------------------------------------------------------------
def test_g21_gitea_version_is_pinned_not_latest():
compose = (ROOT / "docker-compose.yml").read_text()
m = re.search(r"image:\s*\S*gitea/gitea:(\S+)", compose)
assert m, "no gitea image pin found"
assert m.group(1) != "latest", "G2.1: pin an exact Gitea version, never `latest`"
assert re.match(r"^\d+\.\d+\.\d+$", m.group(1)), f"not an exact version: {m.group(1)}"
def test_g24_gitea_license_travels_with_us():
"""MIT's one obligation. Cheap to honour, embarrassing to miss."""
assert (ROOT / "LICENSES" / "gitea-MIT.txt").exists()
assert "MIT" in (ROOT / "LICENSES" / "gitea-MIT.txt").read_text()
# --------------------------------------------------------------------------
# G4.3 — the two Gitea storage traps that cost a crash loop each
# --------------------------------------------------------------------------
def test_g43_no_lfs_storage_type_override():
"""Naming a storage type inside [lfs] creates a SEPARATE storage section
that does not inherit endpoint or credentials from [storage], and Gitea
crash-loops with an error that names the symptom and not the cause."""
# Check real settings only — the compose file deliberately NAMES this key in
# a warning comment so the next person does not re-add it.
active = [
ln for ln in (ROOT / "docker-compose.yml").read_text().splitlines()
if ln.strip() and not ln.strip().startswith("#")
]
assert not any("GITEA__lfs__STORAGE_TYPE" in ln for ln in active)
def test_g43_lfs_server_is_actually_enabled():
"""Setting the storage backend does NOT turn LFS on. Without this the batch
endpoint 404s and the client says 'Repository or object not found', which
reads like a permissions problem and is not one."""
active = [
ln for ln in (ROOT / "docker-compose.yml").read_text().splitlines()
if ln.strip() and not ln.strip().startswith("#")
]
assert any("GITEA__server__LFS_START_SERVER" in ln for ln in active)
def test_g43_r2_checksum_trap_is_pinned():
"""R2 rejects the checksum algorithm S3 clients send by default."""
compose = (ROOT / "docker-compose.yml").read_text()
assert "MINIO_CHECKSUM_ALGORITHM" in compose