c35c5f7a47d2fdb0d9baad8df981720931b1c70e diff --git a/goals/sama-discipline-prefix.md b/goals/sama-discipline-prefix.md new file mode 100644 index 0000000000000000000000000000000000000000..0db28dcbe457ef7ac15b556f5988823f23653aab --- /dev/null +++ b/goals/sama-discipline-prefix.md @@ -0,0 +1,71 @@ +--- +slug: sama-discipline-prefix +title: Move /sama/ → /sama/discipline/ — hypothesis test of cost-flattening +date: 2026-05-25 +branch: sama-discipline-prefix +pr_number: null +merge_sha: null +status: pending +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/sama-v2-git-url-refactor-postmortem (the hypothesis being tested — re-read so the postmortem's framing stays consistent)