sama-discipline-prefix.md
raw
· source
slug: sama-discipline-prefix
title: Move /sama/ → /sama/discipline/ — hypothesis test of cost-flattening
date: 2026-05-25
branch: sama-discipline-prefix
pr_number: 53
merge_sha: f806580
status: shipped
related_posts: [sama-v2-git-url-refactor-postmortem]
Goal: Execute the second URL refactor under the b32_
Done when:
- All four discipline URLs work under the new shape:
- /sama/discipline/sorted → 200, content as before
- /sama/discipline/architecture → 200
- /sama/discipline/modeled → 200
- /sama/discipline/atomic → 200
- Old URLs are permanent redirects:
- curl -I https://tdd.md/sama/sorted → HTTP/2 301, location: /sama/discipline/sorted, cache-control: public, max-age=86400
- Same for architecture, modeled, atomic
- Implemented as ONE regex in src/b32_sama_discipline_url_redirect.ts (mirroring b32_git_url_redirect.ts exactly): const OLD_PATTERN = /^/sama/(sorted|architecture|modeled|atomic)$/; export const rewriteOldSamaDisciplineUrl = (pathname: string): string | null => { ... } Fixed enumeration of the four slugs (S/A/M/A are spec-frozen). Sibling test src/b32_sama_discipline_url_redirect.test.ts covers: each of the four matches, the new URL form returns null, an unrelated /sama/v2 URL returns null, an unrelated /something path returns null, empty input returns null.
- Layer 3 wiring:
- src/d21_handlers_fallback.ts: import + 301-emit block placed BEFORE the existing rewriteOldGitUrl block (both are legacy-URL redirects; order by alphabetical prefix or by recency, but the new one must NOT match new-shape URLs)
- src/d21_app.ts Bun routes: change "/sama/:slug" → "/sama/discipline/:slug" (the explicit handler now matches the new shape; /sama/v2 + /sama/skill + /sama (landing) all keep working because Bun route precedence)
- All hard-coded /sama/sorted, /sama/architecture, /sama/modeled, /sama/atomic strings in content/ and src/ rewritten to use /sama/discipline/
: - content/sama/v2.md (the spec references the disciplines in §1.1)
- content/sama/sorted.md (cross-refs to the other three)
- content/sama/architecture.md
- content/sama/modeled.md
- content/sama/atomic.md
- content/home.md (if it links to disciplines)
- Any /blog post that references them via /sama/
- src/d21_handlers_sama.ts (the SAMA_LANDING_MD template that renders /sama; row links to /sama/
) After: grep -rE "/sama/(sorted|architecture|modeled|atomic)" content/ src/returns 0 lines (excluding the redirect helper + sibling test + this goal file itself).
- Sitemap auto-updates: src/d21_app.ts sitemap handler maps ALL_SAMA → /sama/
; this needs to change to /sama/discipline/ . STATIC_PATHS unchanged (/sama landing still lives at /sama). - All 409+ tests still pass; new helper test adds 6-8 cases for the redirect regex.
- /sama/v2/verify still reports 7/7 ✓ (anti-fudge).
- This goal file (goals/sama-discipline-prefix.md) flipped from status: pending → status: shipped in the final commit before deploy, with merge_sha filled.
- Deployed; live-verify with curl:
- /sama/discipline/sorted → 200, body contains "Sorted"
- /sama/sorted → 301 with Location /sama/discipline/sorted
- curl -sL of the old URL lands on 200 with content
- /sitemap.xml | grep -c "/sama/discipline/" → 4
- /sama/v2/verify → 7/7 ✓
- HYPOTHESIS TEST CLAIM: clock from "git checkout -b sama-discipline-prefix" to "deploy success + live-verify passes" is ≤ 90 minutes (the postmortem of PR #42 predicted "~1 hour"; a 50% buffer is fair given this is hypothesis-verification, not blind prediction). Wall-clock duration recorded in the postmortem post.
Constraints (anti-fudge):
- ONE regex in the redirect helper. If the regex grows into a hand-maintained list, anti-fudge is violated.
- Mirror b32_git_url_redirect.ts shape exactly — same export signature, same sibling-test structure, same Layer-3 wrapper in d21_handlers_fallback.ts. This is the WHOLE POINT of the hypothesis test; deviating defeats it.
- Don't change /sama/v2 or /sama/skill URLs. Only the four discipline pages move.
- Don't add a "discipline" segment to /sama (landing) or /sama/v2 (spec). Only to per-discipline detail pages.
- No alias mode. 301 forces consolidation.
- Site language English-only.
- 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.
- PR body MUST include this verbatim /goal under a "## /goal" heading per feedback_goal_authoring_workflow.md.
Load-bearing files to read FIRST:
- src/b32_git_url_redirect.ts (the template — copy its shape line-for-line)
- src/b32_git_url_redirect.test.ts (the sibling-test template)
- src/d21_handlers_fallback.ts (the rewriteOldGitUrl block — insert the new redirect adjacent)
- src/d21_app.ts (Bun route table — change /sama/:slug → /sama/discipline/:slug; sitemap handler ALL_SAMA mapping)
- src/d21_handlers_sama.ts (SAMA_LANDING_MD template — discipline row links)
- src/a31_sama.ts (ALL_SAMA — should remain unchanged; only URL emission changes downstream)
- content/sama/*.md (cross-discipline link rewrites)
- /blog/2026-05/sama-v2-git-url-refactor-postmortem (the hypothesis being tested — re-read so the postmortem's framing stays consistent)