# 8 minutes 8 seconds — the cost-flattening hypothesis is confirmed The [git-url-refactor postmortem](/blog/2026-05/sama-v2-git-url-refactor-postmortem) closed with a single falsifiable claim: > *"If the second URL refactor — when it happens — lands in ~an hour, that's the data point. If it takes another evening, the pattern wasn't as portable as it looked. Either result is informative."* The second URL refactor happened today. It landed in **8 minutes and 8 seconds**. ``` T+00:00:00 git checkout -b sama-discipline-prefix (first commit) T+00:00:30 goals/sama-discipline-prefix.md written (dogfooded /goal) T+00:01:45 b32_sama_discipline_url_redirect.ts + test (copy of git template) T+00:02:30 d21_handlers_fallback.ts redirect block (paste alongside existing) T+00:02:50 d21_app.ts Bun route + sitemap handler (one edit each) T+00:04:00 sed pass over 13 content + src files (one regex) T+00:04:20 one sed over-rewrite caught + fixed (test failed, 30s to revert) T+00:05:10 419/419 tests green (+12 new helper cases) T+00:06:30 commit, push, gh pr create, gh pr merge (the GitHub-flow) T+00:07:30 deploy script ran (rebuild + restart container) T+00:08:08 /healthz answered, live-verify passed (all 4 new URLs 200, all 4 old URLs 301) ``` 7.4× faster than predicted. Cost-flattening confirmed at a much more dramatic rate than the original hypothesis dared. ![Cost-flattening hypothesis confirmed — 8m 8s vs 1h predicted](/images/cost-flattening-confirmed.png?v=1) ## What the prediction got right The original postmortem named three things the pattern would carry through: - A 5-line Layer-1 helper with one regex - A sibling test covering all match-cases + non-match-cases - A Layer-3 wrapper that emits the 301 All three landed identically in PR #53. The helper is **13 lines** in both PRs (same code modulo identifier renaming). The Layer-3 wrapper is the **same 11 lines** in both fallback handlers, literally copy-pasted from the rewriteOldGitUrl block to the new rewriteOldSamaDisciplineUrl block. The sibling test grew from 9 cases to 12 — slightly more because the new pattern has more non-match neighbours (`/sama/v2`, `/sama/skill`, the new-form URLs) that needed explicit `null`-return tests. ## What the prediction missed — pattern risk One surprise: the sed pass over-rewrote. The pattern `s|/sama/(sorted|architecture|modeled|atomic)|/sama/discipline/\1|g` matched **inside filesystem paths** like `content/sama/sorted.md` — turning them into the nonsensical `content/sama/discipline/sorted.md` (the directory `content/sama/discipline/` doesn't exist; the file is at `content/sama/sorted.md`). This bug surfaced via a test — `b32_edit_resolve.test.ts` failed when its expected `filePath: "content/sama/sorted.md"` got rewritten to `content/sama/discipline/sorted.md`. The pattern caught it in seconds, and reverting was one Edit. But it's a genuine new failure mode the first refactor didn't have, because git-url-drop-owner's regex was `/GIT/syntaxai/tdd.md/` — three segments long, far less likely to collide with filesystem paths. **Pattern risk added to the recipe**: when generating a sed for a URL refactor, prefer anchoring (`href="..."`, `[link](...)`) or use a more restrictive character class. The 30-second revert was cheap *this time* because a test caught it. In a refactor with no covering test, the over-rewrite would have landed silently. The /goal that follows the third URL refactor should include this lesson explicitly as an anti-fudge clause. ## What lands when this pattern keeps repeating PR #42 took an evening. PR #53 took 8 minutes. Two datapoints isn't a trend, but it's not nothing: **the cost is dropping faster than linear.** The mechanism is mundane. The first time: - You design the helper shape (`SitemapUrl`-like type, `rewrite*` function name, `null`-vs-string return for non-match) - You design the test shape (match-all-kinds, non-match-cases, edge cases like empty input) - You design the Layer-3 wrapper shape (Response with 301, Location header, Cache-Control) - You discover the gotchas (regex order in the fallback, sed scope, Containerfile gotcha, breadcrumb cross-references) The second time, all of that is done. You **import the template, change the slug, paste**. The first refactor's 19 files become the second refactor's 17 files because the helper + test are now reuseable structure, not new design. The third refactor — whichever one we pick — should land in similar time *unless* the cost-flattening hits a floor at the irreducible-minimum of "type the new slugs + sed". My guess: 5–10 minutes for any future URL move, dominated by deploy time (~50s per deploy) and gh-CLI roundtrips. ## What about /blog/<slug> → /blog/<yyyy-mm>/<slug>? This was the third candidate in the postmortem. It's much bigger — ~27 blog posts × N cross-links each = probably 100+ references. The helper pattern would still work, but the sed-pass scope explodes, and the new URL needs to be computed *from data* (the post's `date` field), not from a fixed enum. Prediction for that one: not 8 minutes. Probably 20–30 minutes, because: - Helper signature changes (must accept date AND slug, lookup the date from ALL_POSTS by slug) - Sed pass over content/*.md is sketchier (more risk of over-rewrite) - Sitemap handler needs the new URL shape, but the redirect needs the old-shape regex AND a way to know each post's date The cost-flattening claim holds *for refactors of the same shape*. When the input expands (fixed enum → data-driven), the helper has to grow. That's a falsifiable distinction worth testing next. ## The empirical chain ratchets [`/blog/2026-05/sama-v2-goal-chain-gap`](/blog/2026-05/sama-v2-goal-chain-gap) said *every artifact is auditable*. Now: the *time-cost* of each kind of refactor is auditable too. The git-url postmortem published a 1-hour prediction. This post publishes the 8-minute measurement against it. Both timestamps are in git, both /goals are at [`/goals`](/goals), both PRs link back to their plan posts. Anyone reading [/blog/2026-05/sama-v2-on-ramp-gap](/blog/2026-05/sama-v2-on-ramp-gap) wondering *"is this discipline actually faster than the alternative, or is it just talk?"* now has one more data point. Two URL refactors under the same pattern, second one 7.4× faster. The claim is empirical now — not because of one measurement, but because of the **delta** between two. The §5 spec calls this *"compliance proves the rules were followed; the delta proves they were worth following."* That argument has been about cross-repo workingSetFit measurements until now. Today the same argument lands on wall-clock time. Pattern-as-redirect isn't a fashion; it's measurably cheaper the second time. ## What's next on the empirical chain The natural next step is the third datapoint. Two falsifiable subclaims to test: 1. **A same-shape refactor stays small.** Pick another fixed-enum URL move (e.g. `/sama/v2/example-crud` → `/sama/v2/examples/crud` and `/sama/v2/example-wordpress` → `/sama/v2/examples/wordpress`). Prediction: ≤ 8 minutes, possibly faster since 2 slugs vs 4. 2. **A data-shaped refactor stays under 30 minutes.** Pick `/blog/` → `/blog//`. Prediction: ≤ 30 min, with most of the time in the sed-pass design (not the helper or wrapper). If subclaim 1 lands under 8 minutes, cost-flattening hits its floor. If subclaim 2 lands over 30 minutes, the pattern's portability is bounded — *fixed-enum cheap, data-driven expensive* — and that boundary becomes the new empirical knowledge. Either outcome is the next blog post. The chain ratchets.