syntaxai/tdd.md · main · src / a31_sama.ts

a31_sama.ts 48 lines · 2165 bytes raw
// c31 — model: SAMA discipline registry. Drives /sama + /sama/:slug.
// Markdown bodies live in content/sama/<slug>.md. Each entry maps to
// one of the four SAMA properties (Sorted, Architecture, Modeled,
// Atomic) and surfaces its one-line rule on the index page.

export interface SamaDiscipline {
  slug: "sorted" | "architecture" | "modeled" | "atomic";
  letter: "S" | "A" | "M" | "A";
  title: string;
  rule: string;
  description: string;
}

export const ALL_SAMA: SamaDiscipline[] = [
  {
    slug: "sorted",
    letter: "S",
    title: "Sorted",
    rule: "Alphabetical sort = dependency direction. Lower-numbered layers never import from higher-numbered ones.",
    description:
      "The first letter of SAMA. `ls src/` is the architecture diagram: files sort by layer prefix, and the prefix tells the agent what may import from what. One grep verifies the rule.",
  },
  {
    slug: "architecture",
    letter: "A",
    title: "Architecture",
    rule: "The number is the layer; the layer is the contract. c11 = entry, c13 = SQL, c14 = HTTP I/O, c21 = handlers, c31 = models, c32 = pure logic, c51 = UI.",
    description:
      "The contract is in the prefix. A `c31_*` file holds models — no I/O. A `c21_*` file composes lower layers — no SQL of its own. Pick the layer first, then the name.",
  },
  {
    slug: "modeled",
    letter: "M",
    title: "Modeled",
    rule: "Tests live next to source. Types and parse-functions live in c31_*. The shape comes before the logic.",
    description:
      "Every behaviour has a test file as its sibling, every external input has a parser in `c31_*`. The model is the thing the impl has to satisfy — not a docstring, not a comment, the file next to it.",
  },
  {
    slug: "atomic",
    letter: "A",
    title: "Atomic",
    rule: "One responsibility per module. When a layer file passes ~700 lines, split per UI/data domain using the same prefix. No barrel re-exports.",
    description:
      "Atoms are small enough that an agent can hold one in its context with room to spare for the test. The split rule keeps them small as the codebase grows; the no-barrel rule keeps imports honest.",
  },
];