git-url-drop-owner.md
raw
· source
slug: git-url-drop-owner title: Drop redundant :owner segment from /GIT/ URLs date: 2026-05-25 branch: git-url-drop-owner pr_number: 42 merge_sha: 684f257 status: shipped related_posts: [sama-v2-git-url-refactor-plan, sama-v2-git-url-refactor-postmortem]
Goal: Execute the URL refactor described in https://tdd.md/blog/2026-05/sama-v2-git-url-refactor-plan — drop the redundant :owner segment from /GIT/:owner/:repo/ URLs so /GIT/syntaxai/tdd.md/blob/main/src/b32_sama_v2_verify.ts becomes /GIT/tdd.md/blob/main/src/b32_sama_v2_verify.ts. The blog post is the design spec; this /goal is the execution checklist. Single-tenant is already enforced by isAllowedRepo() in src/d21_handlers_repo_browse.ts:26-30 (404s anything that isn't syntaxai/tdd.md), so the owner segment is policy overhead, not data. Inbound links survive via ONE regex 301 redirect in the fallback handler — no hand-maintained URL map.
Done when:
- The four /GIT/ URL kinds work under the new shape:
- /GIT/tdd.md/tree/:ref/
→ 200, directory listing - /GIT/tdd.md/blob/:ref/
→ 200, file viewer HTML - /GIT/tdd.md/raw/:ref/
→ 200, text/plain raw - /GIT/tdd.md/commit/
→ 200, commit detail
- /GIT/tdd.md/tree/:ref/
- Old URL form is a permanent redirect:
- curl -I https://tdd.md/GIT/syntaxai/tdd.md/blob/main/src/b32_sama_v2_verify.ts → HTTP/2 301 → location: /GIT/tdd.md/blob/main/src/b32_sama_v2_verify.ts → cache-control: public, max-age=86400
- Implemented as ONE regex in src/d21_handlers_fallback.ts: /^/GIT/syntaxai/tdd.md/(.+)$/ → 301 to /GIT/tdd.md/$1 The regex must sit BEFORE the gitBrowseMatch block at line ~102 so the old URL never reaches the browse handler.
- parseRepoBrowsePath in src/d21_handlers_repo_browse.ts keeps its shape (returns {kind, ref, path}) — only its callers drop the owner argument.
- isAllowedRepo collapses to isAllowedRepo(repo: string): boolean — owner is implicit, dropped from signature and from the gitBrowseMatch regex (the new regex captures only
:repo+ suffix). - repoBrowseHandler and commitViewHandler drop the
ownerparameter from their signatures. All call sites updated. - The explicit Bun route in src/d21_app.ts:486 changes from "/GIT/:owner/:repo/commit/:sha" → "/GIT/:repo/commit/:sha".
- Every link builder emits the new shape:
- src/b51_render_repo.ts — 8 call sites (breadcrumbs, parent-dir, raw link, source-view link)
- src/b51_render_commit.ts — 2 call sites (commit-parent, raw .diff)
- src/b51_render_edit.ts:27 — hard-coded /GIT/syntaxai/tdd.md/commit/... string
- All hard-coded "/GIT/syntaxai/tdd.md/" strings in content/ and src/ rewritten to "/GIT/tdd.md/":
- content/home.md
- content/sama/v2.md
- content/blog/sama-v2-rust-project-ripgrep.md
- content/blog/sama-v2-workingset-cross-repo-baseline.md
- content/blog/sama-v2-metrics-emitter.md
- content/blog/sama-v2-go-project-dive.md
- content/blog/sama-v2-sitemap-implementation-plan.md
- content/blog/sama-v2-git-url-refactor-plan.md (the plan post itself uses old-form examples — those become AFTER-references in postmortem style)
- src/d21_handlers_sama.ts:137 (markdown embedded in /sama/v2/verify page body)
After:
grep -rn '/GIT/syntaxai/tdd.md/' content/ src/returns 0 lines.
- Test expectations updated in src/b51_render_repo.test.ts and src/b51_render_commit.test.ts to match the new URL strings.
- All 379+ tests pass; no test count regression. New helper test (~3 cases) covers the redirect regex: matches a tree/blob/raw/commit URL and produces the expected Location; non-matching URLs (e.g. /GIT/otherorg/repo/...) fall through and don't redirect.
- /sama/v2/verify still reports 7/7 ✓ (anti-fudge).
- Sitemap unchanged — /GIT/ URLs aren't listed there.
- Deployed; live-verify with curl:
- /GIT/tdd.md/blob/main/src/b32_sama_v2_verify.ts → 200, body contains "export"
- /GIT/tdd.md/tree/main → 200, body contains "src" and "content"
- /GIT/tdd.md/raw/main/sama.profile.toml → 200, text/plain
- /GIT/syntaxai/tdd.md/blob/main/README.md → 301 with Location /GIT/tdd.md/blob/main/README.md
- curl -sL of the old URL lands on the new one and returns the file content
- Visit https://tdd.md/blog/2026-05/sama-v2-git-url-refactor-plan and click any /GIT/ link in the rendered HTML → lands on a 200 (no broken navigation after rewrite).
Constraints (anti-fudge):
- One regex for the redirect — no per-URL hand-maintained mapping. If the regex grows into "a list" the anti-fudge clause is violated.
- Do NOT remove LIVE_REPO_OWNER from src/a31_site_config.ts; it's still the truthful owner constant used by c14_git operations + Forgejo proxy. It just stops appearing in user-facing URLs.
- OUT OF SCOPE: the bare git protocol endpoint /syntaxai/tdd.md.git and the two-segment bare-repo view at /
/ . Those go through isGitProtocol + repoMatch — git-client-facing, copy-pasted into clone commands, breakage risk for cosmetics. Touch only the /GIT/ prefix. - No alias mode — both URL forms working forever lets the old one quietly remain canonical. The 301 forces consolidation; the old URL is a redirect, not a working endpoint.
- Site language English-only — any new comments or response strings in English.
- GitHub flow via flatpak-spawn (branch → PR → merge → push p620 → deploy via flatpak-spawn --host scripts/p620/deploy-tdd-md.sh).
- Do NOT change any §4 verifier logic.
Load-bearing files to read FIRST:
- The plan post: https://tdd.md/blog/2026-05/sama-v2-git-url-refactor-plan (the design spec — read this before any code; the SAMA-layer mapping and design rationale are there, not duplicated in this /goal)
- src/d21_handlers_fallback.ts (lines 89-117 — bareGitUrl block + gitBrowseMatch regex; the new 301 redirect goes BEFORE gitBrowseMatch)
- src/d21_handlers_repo_browse.ts (parseRepoBrowsePath at line 56, isAllowedRepo at line 26, repoBrowseHandler signature at line 69)
- src/d21_handlers_commit_view.ts (commitViewHandler signature — drop owner arg)
- src/d21_app.ts (line 484-486 — the explicit commit route + import wiring)
- src/b51_render_repo.ts (8 link-emit sites — breadcrumbs, parent-dir, raw/source/dir links)
- src/b51_render_commit.ts (2 link-emit sites — commit-parent, raw .diff)
- src/b51_render_edit.ts (1 hard-coded edit→commit URL at line 27)
- src/a31_site_config.ts (LIVE_REPO_OWNER stays exported — confirm callers before touching)
- src/b51_render_repo.test.ts + src/b51_render_commit.test.ts (test strings to update mechanically with the link-builder changes)