7bd481f96213d45cac751b3f1b1af4f9efc612b8 diff --git a/content/blog/sama-v2-on-ramp-gap.md b/content/blog/sama-v2-on-ramp-gap.md new file mode 100644 index 0000000000000000000000000000000000000000..3569cf8c934f08da90a49918214d905df8122900 --- /dev/null +++ b/content/blog/sama-v2-on-ramp-gap.md @@ -0,0 +1,97 @@ +# Every artifact has a URL. The on-ramp doesn't. + +Open `https://tdd.md` in a fresh browser. Count the entry points: + +- [/sama/v2](/sama/v2) — the spec +- [/sama/v2/verify](/sama/v2/verify) — the live verifier +- [/blog](/blog) — the narrative +- [/goals](/goals) — the contracts that drove every PR +- [/GIT/tdd.md/tree/main](/GIT/tdd.md/tree/main) — the source +- [/sitemap.xml](/sitemap.xml) — every URL on the site + +Six entry points. Each one is its own auditable artifact. Each one has been the subject of at least one blog post. Each one is what the empirical-chain argument rests on. + +Now ask the question the entire site exists to answer for a reader: **"How do I contribute?"** + +There is no answer. There is no front door. There is no document at `/contributing` or `CONTRIBUTING.md` or anywhere else that says *"here is how you add a feature to this codebase."* You are expected to read 5+ blog posts, browse the goals registry, skim PR bodies for patterns, and reverse-engineer the file-naming convention from the source tree. The site that has been preaching auditability for forty PRs has been failing the most basic on-ramp test the entire time. + +![Every artifact has a URL — the path to authoring them doesn't](/images/contributing-onramp-gap.png?v=1) + +## The artifacts vs the path + +The table above splits cleanly into two halves. Above the line: every *output* the codebase produces is in git, on the site, and grep-able. Below the line, in amber and red: the *authoring path* — how those outputs come into being — is scattered or missing entirely. + +Specifically: + +- **The `/goal` workflow rule** lives at `/var/home/scri/.claude/projects/-var-home-scri-Documents-tdd-md/memory/feedback_goal_authoring_workflow.md` — an agent-private memory file. A human contributor literally cannot read it. The rule that determines how every PR on this site is authored is preserved for the agent and invisible to everyone else. + +- **The layer-prefix convention** (`a31_*` = Layer 0, `b32_*` = Layer 1, `c14_*` = Layer 2, `d21_*` = Layer 3) is partially documented in [/sama/v2 §1.1](/sama/v2#11-layers), partially in the `/sama/sorted` discipline page, and partially encoded in the source code itself. A new contributor has to triangulate. + +- **The branch-PR-deploy flow** (branch → `gh pr create` → merge → push p620 → `flatpak-spawn --host scripts/p620/deploy-tdd-md.sh` → live-verify) is in *zero* blog posts as a standalone procedure. It's mentioned as a constraint inside individual `/goal` bodies, embedded in PR commit messages, scattered across the recent /goals archive. Never collected. + +- **The test discipline** (sibling `.test.ts`, 402+ stays green, /sama/v2/verify must stay 7/7 ✓) is the load-bearing anti-fudge rule for the entire codebase. It appears in §4.3 of the spec, in every PR body, in every /goal's anti-fudge constraints. Never in one document. + +- **The image convention** (live under `public/images/`, `https://tdd.md` watermark, served via `/images/.` wildcard) was added in [PR #44](/GIT/tdd.md/commit/db83746) and lives only in memory + scattered references. There is no public document a contributor can read to learn it. + +- **The Containerfile gotcha** (every new top-level directory needs a `COPY ./` line, surfaced by PR #46 when `/goals/` returned 404 in production) is captured in *one PR's commit message* and the postmortem section of the goals registry implementation. A new contributor who adds a top-level directory will hit the same 404 in production and have to discover the rule themselves. + +Each of these rules is real, enforced, and load-bearing. None of them is in a canonical-doc-shaped place. + +## What a new contributor actually sees + +Pretend you've just landed on tdd.md and want to add a blog post. The literal steps required to know how: + +1. Open `/sama/v2` to learn the layer convention. Realize blog posts aren't a layer-thing — they're content. +2. Open `/blog` and click around — notice the URL pattern `/blog/`. +3. Browse `/GIT/tdd.md/tree/main/content/blog` — find that posts are markdown files. +4. Open `/GIT/tdd.md/blob/main/src/a31_blog.ts` — discover `ALL_POSTS` and realize new posts need to be registered. +5. Look at `/blog/sama-v2-sitemap-implementation-plan` to see the pattern for *how* posts are authored — but that's about sitemap.xml, not about the blog post itself. +6. Hunt for a recent merged PR — find `gh pr view 44` — see the branch-merge-deploy flow in *the commit messages*, not in any document. +7. Try to figure out images. Read `/blog/sama-v2-goal-chain-gap` looking for image conventions. Find a passing mention. Open a recent PR with images. Reverse-engineer. +8. Realize you don't know whether your blog post needs sibling tests. Read `/sama/v2 §4.3`. Determine: no — only source files need siblings. Content files don't. +9. Realize you might break `/sama/v2/verify`. Run it locally? There's no instruction. Push to `main` and pray? That breaks the workflow. Fork the repo? The verifier doesn't run on forks. +10. Give up. Open an issue saying "how do I contribute?" + +This is the experience the site currently delivers. The empirical chain is intact for every artifact *except* the one that brings new contributors in. + +## Why this is a SAMA v2 self-violation + +The [chain-gap drama post](/blog/sama-v2-goal-chain-gap) argued that the `/goal` command was a SAMA v2 self-violation because the contract driving every PR wasn't in the chain. The fix shipped — `/goals/.md` files are in git, the workflow memory is locked in, every future `/goal` lands in the registry by construction. + +This post argues the same shape, one level up: **the workflow itself is the next missing artifact**. The `/goal` is now in git; the rule for how to *write* a `/goal` is not. The branch flow is encoded in memory; the rule for how to *run* the branch flow is not on the site. The image convention is enforced by code; the rule that a contributor needs to know about the convention is nowhere a contributor would think to look. + +It's the same structural failure as before, applied to procedure instead of contract. The empirical chain has always had this hole; we just shipped the patch one level too shallow. + +The SAMA v2 §0 auditability clause says *"the verifier is a deterministic program; that claim is only auditable if a human can reproduce it from the data."* By the same logic: *the authoring process is a discipline; that claim is only auditable if a human can reproduce it from the published material.* They can't. Not because we hid anything — because we never wrote the on-ramp down in one place. + +## The fix + +![CONTRIBUTING.md — synthesis, not duplication](/images/contributing-onramp-fix.png?v=1) + +One markdown file. Two surfaces: + +- **`./CONTRIBUTING.md` at repo root** — GitHub auto-detects this and surfaces it in the contribute UI. A reader on `github.com/syntaxai/tdd.md` gets pointed at it immediately. +- **`/contributing` on tdd.md** — the canonical permalink, served from the same markdown body. Sitemap entry, nav link, navigable like every other page. + +One file, two URLs. Same pattern as the sitemap (one source, two delivery mechanisms — registry + URL endpoint). + +**Three load-bearing properties** the document must satisfy to be 100% SAMA v2: + +1. **Single source of truth.** Every rule is owned by exactly one canonical artifact. `CONTRIBUTING.md` **links**, doesn't restate. The layer convention lives at `/sama/v2 §1.1`; CONTRIBUTING.md says "see §1.1" and never copies the table. If a future PR changes the spec, CONTRIBUTING.md doesn't drift because there's nothing in it to drift. + +2. **Dogfooded.** Its own creation is `/goal`-driven. `goals/contributing-md.md` lands as the first commit of the PR per the [workflow memory](https://tdd.md/blog/sama-v2-goal-chain-gap); the merge SHA flips to shipped at deploy time. The artifact that documents the workflow is itself produced by the workflow. + +3. **Drift-detectable.** A test grep-checks that `CONTRIBUTING.md` only contains *references* to canonical sources — no rule restatements. If someone adds "the SAMA layers are a31/b32/c14/d21" as a paragraph instead of a link, the test fails. This is the same anti-fudge shape the verifier uses for source files. + +## What lands when this ships + +After the `/goal` that fires next: + +- A reader on `github.com/syntaxai/tdd.md` lands on `CONTRIBUTING.md` and can produce their first PR in a single read. +- A reader on `tdd.md/contributing` gets the same content, navigable from the main nav. +- An agent context-loaded with this site no longer has to assemble the workflow from scattered sources — one document is the entry point, with links out to the canonical artifacts for the details. +- The empirical chain gains its final missing link: the procedural one. Every artifact has a URL. The path to authoring them now also has a URL. + +The `/goal` that drives this work follows immediately after this post — same pattern as every other plan-then-execute cycle on this site. After merge, the postmortem post compares the plan to what landed. + +The drama ends quietly. The chain closes. A new contributor lands on tdd.md and finds the front door right where they expected it. diff --git a/public/images/contributing-onramp-fix.png b/public/images/contributing-onramp-fix.png new file mode 100644 index 0000000000000000000000000000000000000000..0c923899c0602fd1a5cb47c6742b0a6f1303aa02 Binary files /dev/null and b/public/images/contributing-onramp-fix.png differ diff --git a/public/images/contributing-onramp-fix.svg b/public/images/contributing-onramp-fix.svg new file mode 100644 index 0000000000000000000000000000000000000000..dcaeec789353a5893ce433f0a05d98476dfb8533 --- /dev/null +++ b/public/images/contributing-onramp-fix.svg @@ -0,0 +1,75 @@ + + + + + + The fix — CONTRIBUTING.md synthesizes existing artifacts, no new abstractions + Each section links to its canonical source. No duplication. + Two surfaces: ./CONTRIBUTING.md at repo root (GitHub-native) + /contributing on the site. One file, two URLs. + + + + + CONTRIBUTING.md SECTION + CANONICAL SOURCE (linked) + SYNTHESIS + + + + + + + Before you start + /sama/v2 · /blog/sama-v2-goal-chain-gap + 3 links + + The /goal workflow + /goals/migrate-historical-goals + 7-line summary + + SAMA layer convention + /sama/v2 §1.1 + /sama/sorted + aXX/bXX/cXX/dXX table + + How to add a blog post + content/blog/<slug>.md + ALL_POSTS + recipe + + How to add a /goal + workflow memory + /goals registry + recipe + + How to add an image + public/images/ + watermark convention + recipe + + How to add a Layer-1 helper + b32_<name>.ts + b32_<name>.test.ts + recipe + + How to add a top-level directory + Containerfile COPY line (gotcha PR #46) + recipe + warning + + Anti-fudge defaults + /sama/v2/verify (must stay 7/7 ✓) + 5-bullet checklist + + Branch / deploy flow + scripts/p620/deploy-tdd-md.sh + gh CLI + 5-step sequence + + + + + + Three load-bearing properties: + 1. SINGLE SOURCE OF TRUTH — every rule is owned by exactly one canonical artifact; CONTRIBUTING.md links, doesn't restate. + 2. TWO SURFACES — ./CONTRIBUTING.md (GitHub auto-detects it) + /contributing (site canonical) read from ONE markdown file. + 3. DOGFOODED — its own creation is a /goal-driven artifact at /goals/contributing-md, with merge_sha in frontmatter. + Drift detection follow-up: a test grep-checks that CONTRIBUTING.md only contains references to canonical sources (no rule restatements). + + + + https://tdd.md + diff --git a/public/images/contributing-onramp-gap.png b/public/images/contributing-onramp-gap.png new file mode 100644 index 0000000000000000000000000000000000000000..c8cdc9ebbe70cd658db6cfd4a39836703acb9372 Binary files /dev/null and b/public/images/contributing-onramp-gap.png differ diff --git a/public/images/contributing-onramp-gap.svg b/public/images/contributing-onramp-gap.svg new file mode 100644 index 0000000000000000000000000000000000000000..07ac41526354df612f78c8c785178e79adafa368 --- /dev/null +++ b/public/images/contributing-onramp-gap.svg @@ -0,0 +1,76 @@ + + + + + + The empirical chain — every output has a URL, the on-ramp doesn't + Every artifact has a URL. The path to authoring them doesn't. + A new contributor must read 5+ blog posts + the spec + agent-private memory files to assemble "how to add a feature". + + + + + ARTIFACT + WHERE IT LIVES + CANONICAL DOC? + + + + + + + SAMA spec (rules + profile + verifier) + /sama/v2 + ✓ on-site + + §4 verifier verdict (live proof) + /sama/v2/verify + ✓ live · auditable + + §5 metric definitions + measurements + /sama/v2 §5 · /blog + ✓ on-site + + /goal contracts (post PR #47) + /goals · /goals/<slug> + ✓ archived + + Source code (every file) + /GIT/tdd.md/tree/main + ✓ browseable + + Discoverability (every URL) + /sitemap.xml + ✓ generated + + Blog narrative (every decision) + /blog + ✓ indexed + + Authoring workflow (the /goal rule) + agent-private memory file + ~ not on site + + Layer / test / branch / deploy patterns + scattered across PRs + posts + ~ no canonical doc + + + + "How do I contribute?" — the on-ramp + nowhere — assemble from 11+ sources + ✗ MISSING + + + + + + The self-violation: + "Every artifact is auditable" — yes, every OUTPUT is. The path to producing the outputs requires reverse-engineering + across blog posts + memory files (which humans can't even read) + commit history. A new contributor lands on tdd.md + with six entry points and no front door. The chain has all its links — except the one that brings a contributor in. + + + + https://tdd.md + diff --git a/src/a31_blog.ts b/src/a31_blog.ts index 33f27e1d03f2a6cb8a07dc7cd878ad3a39252a49..4266e6b62c73c7883003ff961ee77e57ae244d0c 100644 --- a/src/a31_blog.ts +++ b/src/a31_blog.ts @@ -12,6 +12,12 @@ export interface BlogEntry { } export const ALL_POSTS: BlogEntry[] = [ + { + slug: "sama-v2-on-ramp-gap", + title: "Every artifact has a URL. The on-ramp doesn't.", + description: "Open tdd.md in a fresh browser. Count the entry points — /sama/v2 (spec), /sama/v2/verify (live), /blog (narrative), /goals (contracts), /GIT/tdd.md (source), /sitemap.xml (every URL). Six artifacts, each auditable, each its own blog post subject. Now ask the question the site exists to answer for a reader: 'how do I contribute?' There is no answer. No CONTRIBUTING.md, no /contributing URL, no canonical on-ramp anywhere. Forty PRs of preaching auditability — and the most basic on-ramp test failing the entire time. This post is the drama. Walks the artifact-vs-path table: every OUTPUT lives in a canonical place (✓), every authoring rule lives somewhere a contributor wouldn't think to look (the /goal workflow rule is in an agent-private memory file that humans literally cannot read; the layer convention is in /sama/v2 §1.1 + /sama/sorted + the source tree; the branch-PR-deploy flow is scattered across PR commit messages and individual /goal bodies; the image convention lives in memory only; the Containerfile gotcha lives in one PR's commit message). Concrete 10-step thought experiment of what a new contributor adding their first blog post would actually have to do — ends in 'give up, open an issue saying how do I contribute'. Frames this as a SAMA v2 self-violation parallel to /blog/sama-v2-goal-chain-gap one level up: that post fixed the /goal in the chain; this post argues the workflow itself is the next missing artifact, same structural failure applied to procedure instead of contract. Sketches the fix: one CONTRIBUTING.md, two surfaces (./CONTRIBUTING.md at repo root + /contributing on the site, same markdown source), with three load-bearing properties — single source of truth (links don't restate), dogfooded (its own creation is /goal-driven at /goals/contributing-md), drift-detectable (a test that grep-checks CONTRIBUTING.md contains only references not restatements). The /goal that drives the implementation follows this post per the plan-execute-postmortem pattern.", + date: "2026-05-25", + }, { slug: "sama-v2-goal-chain-gap", title: "Every chain artifact lives in git — except the /goal",