syntaxai/tdd.md · main · goals / sama-discipline-prefix.md

sama-discipline-prefix.md 72 lines · 5968 bytes 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__url_redirect pattern established by PR #42 (git-url-drop-owner). Move the four /sama discipline pages from /sama/ to /sama/discipline/, creating a cleaner namespace for v1 content alongside /sama/v2/* for v2 content. Inbound links survive via ONE regex 301 redirect using exactly the same shape as b32_git_url_redirect.ts. Primary purpose: hypothesis test — the postmortem of PR #42 closed with a falsifiable claim that "if the second URL refactor lands in ~1 hour, the cost-flattening of pattern-as-redirect is confirmed". This /goal IS that test. The clock starts at the first commit on this branch and stops at deploy+live-verify.

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)