syntaxai/tdd.md · commit 2867c34

Add pending /goal: sama-cli-shell-verifier

Authored /goal on the user's request. Plants a pending goal at /goals/sama-cli-shell-verifier proposing a second independent SAMA v2 verifier in pure POSIX shell, parallel to the existing TS verifier.

Load-bearing claim the /goal lays cable for: 'two independent implementations of the spec produce identical verdicts'. Per /sama/v2 §6 evolution policy, two-verifier-agreement is empirical validation that the spec is reproducible from prose alone — not just one program's interpretation.

Explicitly corrects the cli.md email's broken prefix mapping (which had a*=Layer 3, c*=Layer 1 — backwards from the canonical a=Pure, b=Core, c=Adapter, d=Entry that this repo enforces).

Not yet fired. status: pending. merge_sha: null. Appears at /goals as the most recent entry.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
author
syntaxai <[email protected]>
date
2026-05-26 06:14:46 +01:00
parent
c02c4c0
commit
2867c3437d5b34c6bd0b9f2a614d31fb7f5d6ace

3 files changed · +610 −0

added cli.md +513 −0
@@ -0,0 +1,513 @@
1+Ja, hier is een concreet voorstel voor een sterkere Linux-native SAMA v2 verifier.
2+Doel van de Linux-first versie
3+
4+Een zo licht mogelijk, betrouwbaar en inspecteerbaar verificatiesysteem dat voornamelijk uit shell commands bestaat, met zo min mogelijk externe dependencies.
5+Voorgestelde structuur: `sama` CLI tool
6+
7+sama check # Alle checks draaien
8+sama check sorted
9+sama check law
10+sama check atomic
11+sama doctor # Systeem + project diagnose
12+sama graph # Toon import graph
13+
14+Implementatie per Conformance Check
15+
16+Hier is hoe elke check Linux-native kan worden geïmplementeerd:
17+Check Linux Commando’s / Tools Uitleg
18+1. Sorted find . -name "*.ts" -o -name "*.go" | sort + regex op prefix Check of alle bestanden een geldige prefix hebben en of de sortering klopt met laag-volgorde
19+2. Architecture `grep -E ’^(a0_ b1_
20+3. Modeled (tests) find . -name "*.ts" ! -name "*.test.ts" | while read f; do test "$f.test.ts" ... Sibling testfile check
21+4. Modeled (boundary) `grep -E ’JSON.parse new URL
22+5. Atomic find . -name "*.ts" -exec wc -l {} + | awk '$1 > 700' Lijntelling + waarschuwing
23+6. The Law (Imports) grep -E 'from ["'\''].*\.\.' + tsort of eigen graph script Bouw een directed graph en check op cycles + richting
24+7. Consistency Combineer prefix extractie + import analyse Check of verklaarde laag overeenkomt met geïmporteerde lagen
25+Voorbeeld: Basis `sama check` script
26+
27+#!/usr/bin/env bash
28+# sama-check.sh
29+
30+PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
31+cd "$PROJECT_ROOT"
32+
33+echo "=== SAMA v2 Linux Verifier ==="
34+
35+fail=0
36+
37+# Check 1: Sorted
38+echo -n "1. Sorted... "
39+if find src -name "*.ts" | grep -vE '^[a-d][0-3]_' > /dev/null; then
40+ echo "FAIL (ongeldige prefix)"
41+ fail=1
42+else
43+ echo "OK"
44+fi
45+
46+# Check 5: Atomic
47+echo -n "5. Atomic... "
48+if find src -name "*.ts" -exec wc -l {} + | awk '$1 > 700' | grep . > /dev/null; then
49+ echo "FAIL (te grote files)"
50+ fail=1
51+else
52+ echo "OK"
53+fi
54+
55+# Check 6: The Law (simpele versie)
56+echo -n "6. The Law... "
57+if grep -rE 'from ["'\''](\.\./)+[a-d][0-3]_' src | grep -E '^[a-d][0-1]_' > /dev/null; then
58+ echo "FAIL (import omhoog)"
59+ fail=1
60+else
61+ echo "OK"
62+fi
63+
64+if [ $fail -eq 0 ]; then
65+ echo "✅ Alle checks geslaagd"
66+else
67+ echo "❌ Er zijn fouten"
68+ exit 1
69+fi
70+
71+Aanbevolen tools (minimal dependencies)
72+
73+ Core: bash, grep, find, awk, sed, wc, sort
74+
75+ Performance: ripgrep (rg) als optie
76+
77+ Graph analyse: graphviz (dot) + eigen parser of tsort
78+
79+ Taal-specifiek: jq voor JSON-config, yq voor YAML
80+
81+Voordelen van deze aanpak
82+
83+ Zeer lichtgewicht (draait op bijna elke Linux server/CI)
84+
85+ Volledig inspecteerbaar (je kan elk commando los draaien)
86+
87+ AI-agents kunnen dit veel makkelijker genereren en debuggen
88+
89+ Sneller dan een zware TypeScript/Bun verifier
90+
91+ Past perfect bij Unix-filosofie
92+
93+Wil je dat ik een volledig uitgewerkt script maak voor alle 7 checks?
94+Of wil je een versie voor een specifieke taal (bijv. TypeScript, Go, Python)?
95+
96+Bas van Cuilenburg <[email protected]>
97+
98+Mon, May 25, 10:26 PM (7 hours ago)
99+
100+
101+to me
102+
103+✅ Hier is de nog verder uitgebreide versie met sama graph functionaliteit.
104+Volledige `sama` script (Linux-native + Graph support)
105+
106+#!/usr/bin/env bash
107+# =============================================
108+# SAMA v2 Linux Verifier + Graph Tool
109+# Unix-native • Verbeterde versie
110+# =============================================
111+
112+set -euo pipefail
113+
114+PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
115+cd "$PROJECT_ROOT"
116+
117+MAX_LINES=700
118+SUPPORTED_EXTENSIONS="\.ts$|\.js$|\.go$|\.py$"
119+
120+RED='\033[0;31m'
121+GREEN='\033[0;32m'
122+YELLOW='\033[1;33m'
123+BLUE='\033[0;34m'
124+NC='\033[0m'
125+
126+fail=0
127+
128+print_header() {
129+ echo "=== SAMA v2 Linux Verifier ==="
130+ echo "Project : $PROJECT_ROOT"
131+ echo "Max lines : $MAX_LINES"
132+ echo "====================================="
133+}
134+
135+# ==================== CHECKS ====================
136+
137+check_sorted() {
138+ local bad=$(find src -type f -regextype posix-extended -regex ".*($SUPPORTED_EXTENSIONS)" | grep -vE '^[a-d][0-3]_' | head -10)
139+ if [ -n "$bad" ]; then
140+ echo -e "${RED}Bestanden zonder prefix:${NC}"
141+ echo "$bad"
142+ return 1
143+ fi
144+ return 0
145+}
146+
147+check_modeled_tests() {
148+ local missing=()
149+ while IFS= read -r file; do
150+ local ext="${file##*.}"
151+ local testfile="${file%.*}.test.${ext}"
152+ [[ ! -f "$testfile" ]] && missing+=("$file")
153+ done < <(find src -regextype posix-extended -regex ".*($SUPPORTED_EXTENSIONS)" | grep -E '^[b-c][0-3]_')
154+
155+ if [ ${#missing[@]} -gt 0 ]; then
156+ echo -e "${RED}Missende tests:${NC}"
157+ printf ' %s\n' "${missing[@]}"
158+ return 1
159+ fi
160+ return 0
161+}
162+
163+check_boundary() {
164+ local bad=$(grep -rE 'JSON\.parse|new URL|URLSearchParams|qs\.parse' --include="*.ts" --include="*.js" src 2>/dev/null | grep -E '^[a-b][0-1]_' || true)
165+ if [ -n "$bad" ]; then
166+ echo -e "${RED}Boundary violations:${NC}"
167+ echo "$bad" | head -8
168+ return 1
169+ fi
170+ return 0
171+}
172+
173+check_atomic() {
174+ local big=$(find src -regextype posix-extended -regex ".*($SUPPORTED_EXTENSIONS)" -exec wc -l {} + 2>/dev/null | awk "\$1 > $MAX_LINES" || true)
175+ if [ -n "$big" ]; then
176+ echo -e "${RED}Te grote bestanden:${NC}"
177+ echo "$big"
178+ return 1
179+ fi
180+ return 0
181+}
182+
183+check_the_law() {
184+ local bad=$(grep -rE 'from ["'\''](\.\./)+[a-d][0-3]_' src 2>/dev/null | grep -E '^[a-d][0-1]_' || true)
185+ if [ -n "$bad" ]; then
186+ echo -e "${RED}The Law overtredingen:${NC}"
187+ echo "$bad" | head -6
188+ return 1
189+ fi
190+ return 0
191+}
192+
193+# ==================== GRAPH ====================
194+
195+sama_graph() {
196+ echo -e "${BLUE}Generating SAMA dependency graph...${NC}"
197+
198+ local graph_file="/tmp/sama_graph.dot"
199+
200+ cat > "$graph_file" << EOF
201+digraph SAMA {
202+ rankdir=TB;
203+ node [shape=box, fontname="monospace"];
204+ edge [arrowsize=0.6];
205+EOF
206+
207+ # Simpele import detectie
208+ grep -rE 'from ["'\''](\./|\.\./)' src 2>/dev/null | head -50 | while read -r line; do
209+ file=$(echo "$line" | cut -d: -f1)
210+ import=$(echo "$line" | grep -oE 'from ["'\''][^"'\'']+')
211+ if [[ -n "$file" && -n "$import" ]]; then
212+ echo " \"$file\" -> \"$import\";" >> "$graph_file"
213+ fi
214+ done
215+
216+ echo "}" >> "$graph_file"
217+
218+ if command -v dot >/dev/null 2>&1; then
219+ dot -Tpng "$graph_file" -o sama_graph.png
220+ echo -e "${GREEN}✅ Graph gegenereerd: sama_graph.png${NC}"
221+ else
222+ echo -e "${YELLOW}Waarschuwing: Graphviz (dot) niet geïnstalleerd.${NC}"
223+ echo "Installeer met: sudo apt install graphviz"
224+ fi
225+}
226+
227+# ==================== MAIN ====================
228+
229+print_header
230+
231+case "${1:-}" in
232+ graph)
233+ sama_graph
234+ ;;
235+ check)
236+ case "${2:-}" in
237+ sorted) check_sorted ;;
238+ tests) check_modeled_tests ;;
239+ boundary) check_boundary ;;
240+ atomic) check_atomic ;;
241+ law) check_the_law ;;
242+ *)
243+ echo "Beschikbare checks: sorted, tests, boundary, atomic, law"
244+ ;;
245+ esac
246+ ;;
247+ *)
248+ # Alle checks draaien
249+ echo "Running all checks..."
250+ check_sorted && echo -e "${GREEN}1. Sorted ...................... PASS${NC}" || { echo -e "${RED}1. Sorted ...................... FAIL${NC}"; fail=1; }
251+ check_modeled_tests && echo -e "${GREEN}3. Modeled (tests) ............. PASS${NC}" || { echo -e "${RED}3. Modeled (tests) ............. FAIL${NC}"; fail=1; }
252+ check_boundary && echo -e "${GREEN}4. Modeled (boundary) .......... PASS${NC}" || { echo -e "${RED}4. Modeled (boundary) .......... FAIL${NC}"; fail=1; }
253+ check_atomic && echo -e "${GREEN}5. Atomic ...................... PASS${NC}" || { echo -e "${RED}5. Atomic ...................... FAIL${NC}"; fail=1; }
254+ check_the_law && echo -e "${GREEN}6. The Law ..................... PASS${NC}" || { echo -e "${RED}6. The Law ..................... FAIL${NC}"; fail=1; }
255+ ;;
256+esac
257+
258+echo "====================================="
259+if [ $fail -eq 0 ]; then
260+ echo -e "${GREEN}✅ SAMA v2 Compliant${NC}"
261+else
262+ echo -e "${RED}❌ SAMA v2 issues found${NC}"
263+ exit 1
264+fi
265+
266+Gebruik:
267+
268+sama # Alle checks
269+sama check law # Alleen The Law
270+sama graph # Genereert dependency graph (sama_graph.png)
271+
272+Wil je nog verder gaan? Bijvoorbeeld:
273+
274+ Ondersteuning voor Go of Python verbeteren?
275+
276+ Een sama doctor commando toevoegen?
277+
278+ Het script nog simpeler/moderner maken met fd + rg?
279+
280+Laat het weten!
281+
282+
283+Met vriendelijke groet / Mit freundlichen Grüßen / Kind regards, ______________________________
284+
285+Bas van Cuilenburg
286+
287+
288+Bas van Cuilenburg <[email protected]>
289+
290+Mon, May 25, 10:30 PM (7 hours ago)
291+
292+
293+to me
294+
295+✅ Hier is de volledige, 100% SAMA v2 compliant versie van de Linux Verifier.
296+Projectstructuur (SAMA v2 compliant)
297+
298+sama-cli/
299+├── sama # Hoofd executable (wrapper)
300+├── src/
301+│ ├── a0_main.sh # Layer 3 - Entry
302+│ ├── b1_checks.sh # Layer 1 - Core
303+│ ├── b2_graph.sh # Layer 2 - Adapter
304+│ ├── c1_utils.sh # Layer 1 - Core
305+│ └── c2_constants.sh # Layer 0 - Pure
306+└── tests/
307+ ├── b1_checks.test.sh
308+ └── c1_utils.test.sh
309+
310+1. `src/c2_constants.sh` (Layer 0 - Pure)
311+
312+#!/usr/bin/env bash
313+# c2_constants.sh
314+
315+MAX_LINES=700
316+SUPPORTED_EXTENSIONS="\.ts$|\.js$|\.go$|\.py$|\.sh$"
317+
318+RED='\033[0;31m'
319+GREEN='\033[0;32m'
320+YELLOW='\033[1;33m'
321+BLUE='\033[0;34m'
322+NC='\033[0m'
323+
324+2. `src/c1_utils.sh` (Layer 1 - Core)
325+
326+#!/usr/bin/env bash
327+# c1_utils.sh
328+
329+print_header() {
330+ echo "=== SAMA v2 Linux Verifier ==="
331+ echo "Project : $(pwd)"
332+ echo "Max lines : $MAX_LINES"
333+ echo "====================================="
334+}
335+
336+run_check() {
337+ local name="$1"
338+ local func="$2"
339+ echo -n "$name "
340+ printf "%-28s" "........................"
341+ if $func; then
342+ echo -e "${GREEN}PASS${NC}"
343+ return 0
344+ else
345+ echo -e "${RED}FAIL${NC}"
346+ return 1
347+ fi
348+}
349+
350+3. `src/b1_checks.sh` (Layer 1 - Core)
351+
352+#!/usr/bin/env bash
353+# b1_checks.sh
354+
355+source "src/c2_constants.sh"
356+
357+check_sorted() {
358+ local bad=$(find src -type f -regextype posix-extended -regex ".*($SUPPORTED_EXTENSIONS)" | grep -vE '^[a-d][0-3]_' | head -10)
359+ if [ -n "$bad" ]; then
360+ echo -e "${RED}Bestanden zonder geldige prefix:${NC}"
361+ echo "$bad"
362+ return 1
363+ fi
364+ return 0
365+}
366+
367+check_modeled_tests() {
368+ local missing=()
369+ while IFS= read -r file; do
370+ local ext="${file##*.}"
371+ local testfile="${file%.*}.test.${ext}"
372+ [[ ! -f "$testfile" ]] && missing+=("$file")
373+ done < <(find src -regextype posix-extended -regex ".*($SUPPORTED_EXTENSIONS)" | grep -E '^[b-c][0-3]_')
374+
375+ if [ ${#missing[@]} -gt 0 ]; then
376+ echo -e "${RED}Missende testbestanden:${NC}"
377+ printf ' %s\n' "${missing[@]}"
378+ return 1
379+ fi
380+ return 0
381+}
382+
383+check_boundary() {
384+ local bad=$(grep -rE 'JSON\.parse|new URL|URLSearchParams|qs\.parse' --include="*.ts" --include="*.js" src 2>/dev/null | grep -E '^[a-b][0-1]_' || true)
385+ if [ -n "$bad" ]; then
386+ echo -e "${RED}Boundary violations (parsing buiten Layer 2):${NC}"
387+ echo "$bad" | head -8
388+ return 1
389+ fi
390+ return 0
391+}
392+
393+check_atomic() {
394+ local big=$(find src -regextype posix-extended -regex ".*($SUPPORTED_EXTENSIONS)" -exec wc -l {} + 2>/dev/null | awk "\$1 > $MAX_LINES" || true)
395+ if [ -n "$big" ]; then
396+ echo -e "${RED}Bestanden groter dan ${MAX_LINES} regels:${NC}"
397+ echo "$big"
398+ return 1
399+ fi
400+ return 0
401+}
402+
403+check_the_law() {
404+ local bad=$(grep -rE 'from ["'\''](\.\./)+[a-d][0-3]_' src 2>/dev/null | grep -E '^[a-d][0-1]_' || true)
405+ if [ -n "$bad" ]; then
406+ echo -e "${RED}The Law overtredingen (import omhoog):${NC}"
407+ echo "$bad" | head -6
408+ return 1
409+ fi
410+ return 0
411+}
412+
413+4. `src/b2_graph.sh` (Layer 2 - Adapter)
414+
415+#!/usr/bin/env bash
416+# b2_graph.sh
417+
418+sama_graph() {
419+ echo -e "${BLUE}Generating SAMA dependency graph...${NC}"
420+
421+ local graph_file="/tmp/sama_graph.dot"
422+
423+ cat > "$graph_file" << EOF
424+digraph SAMA {
425+ rankdir=TB;
426+ node [shape=box, fontname="monospace"];
427+ edge [arrowsize=0.6];
428+EOF
429+
430+ grep -rE 'source |from ["'\'']' src 2>/dev/null | head -40 | while read -r line; do
431+ file=$(echo "$line" | cut -d: -f1)
432+ import=$(echo "$line" | grep -oE '(source |from ["'\''])[^"'\'' ]+' | sed 's/.* //')
433+ if [[ -n "$file" && -n "$import" ]]; then
434+ echo " \"$file\" -> \"$import\";" >> "$graph_file"
435+ fi
436+ done
437+
438+ echo "}" >> "$graph_file"
439+
440+ if command -v dot >/dev/null 2>&1; then
441+ dot -Tpng "$graph_file" -o sama_graph.png
442+ echo -e "${GREEN}✅ Graph gegenereerd → sama_graph.png${NC}"
443+ else
444+ echo -e "${YELLOW}Graphviz niet gevonden. Installeer met: sudo apt install graphviz${NC}"
445+ fi
446+}
447+
448+5. `src/a0_main.sh` (Layer 3 - Entry)
449+
450+#!/usr/bin/env bash
451+# a0_main.sh
452+
453+source "src/c2_constants.sh"
454+source "src/c1_utils.sh"
455+source "src/b1_checks.sh"
456+source "src/b2_graph.sh"
457+
458+fail=0
459+
460+print_header
461+
462+case "${1:-}" in
463+ graph)
464+ sama_graph
465+ ;;
466+ check)
467+ case "${2:-}" in
468+ sorted) check_sorted ;;
469+ tests) check_modeled_tests ;;
470+ boundary) check_boundary ;;
471+ atomic) check_atomic ;;
472+ law) check_the_law ;;
473+ *) echo "Beschikbare checks: sorted, tests, boundary, atomic, law" ;;
474+ esac
475+ ;;
476+ *)
477+ run_check "1. Sorted" check_sorted || fail=1
478+ run_check "3. Modeled (tests)" check_modeled_tests || fail=1
479+ run_check "4. Modeled (boundary)" check_boundary || fail=1
480+ run_check "5. Atomic" check_atomic || fail=1
481+ run_check "6. The Law" check_the_law || fail=1
482+ ;;
483+esac
484+
485+echo "====================================="
486+if [ $fail -eq 0 ]; then
487+ echo -e "${GREEN}✅ SAMA v2 Compliant — Alles in orde!${NC}"
488+else
489+ echo -e "${RED}❌ SAMA v2 — Er zijn overtredingen${NC}"
490+ exit 1
491+fi
492+
493+6. Hoofd executable: `sama` (in root)
494+
495+#!/usr/bin/env bash
496+# sama
497+
498+cd "$(dirname "$0")"
499+exec bash src/a0_main.sh "$@"
500+
501+Installatie commando’s
502+
503+# Maak alle files executable
504+chmod +x sama src/*.sh
505+
506+# Test het
507+./sama
508+./sama graph
509+
510+Wil je dat ik ook de testbestanden (*.test.sh) toevoeg, of een sama doctor commando?
511+
512+
513+Met vriendelijke groet / Mit freundlichen Grüßen / Kind regards, ______________________________
added goals/sama-cli-shell-verifier.md +84 −0
@@ -0,0 +1,84 @@
1+---
2+slug: sama-cli-shell-verifier
3+title: Linux-native shell-based SAMA v2 verifier — second independent implementation
4+date: 2026-05-25
5+branch: sama-cli-shell-verifier
6+pr_number: null
7+merge_sha: null
8+status: pending
9+related_posts: [sama-v2-verifier-and-the-rename, sama-v2-metrics-emitter]
10+---
11+
12+Goal: Build a second, independent SAMA v2 §4 verifier implemented as Linux-native shell scripts (bash + find + grep + awk + wc + sed — no Bun, no Node, no language runtime beyond POSIX). Lives at `tools/sama-cli/` inside this repo. Acts as the cross-verifier reference per /sama/v2 §6 evolution policy: two independent implementations of the spec produce the same verdict against the same codebase. The load-bearing claim that follows is *"the spec is reproducible from prose alone — two teams could implement it, and both implementations agree."* The cli.md email at the repo root sketches the design; this /goal corrects its broken prefix mapping and binds the implementation to actually pass the existing /sama/v2/verify.
13+
14+**Why this matters empirically.** Today, /sama/v2/verify is one program, written in TypeScript, run on Bun. If that program is wrong, the site's claim *"this codebase scores 7/7 ✓"* is unaudited — there's no independent oracle. A second implementation in a fundamentally different language (shell, not TS) running on different primitives (POSIX find/grep, not Bun's filesystem APIs) creates the oracle. If both agree on 7/7 ✓ across every commit, the verdict is empirical, not just compiled.
15+
16+The cli.md proposal at the repo root has a critical layer-mapping bug — it maps `a*_` to Layer 3, `c*_` to Layer 1, etc., which is backwards from this codebase's canonical mapping (a=Pure, b=Core, c=Adapter, d=Entry). Under the cli.md mapping the proposal's own files would FAIL §4.1 Sorted. This /goal explicitly corrects that and uses the canonical SAMA v2 prefix scheme throughout.
17+
18+Done when:
19+- `tools/sama-cli/` directory exists with this exact structure (canonical layer mapping applied):
20+ ```
21+ tools/sama-cli/
22+ ├── sama # entry wrapper, calls src/d*_main.sh
23+ ├── sama.profile.toml # SAMA v2 profile for THIS sub-project
24+ └── src/
25+ ├── a31_constants.sh # Layer 0 — Pure: MAX_LINES, color codes, supported exts
26+ ├── b32_checks.sh # Layer 1 — Core: the 7 §4 checks as pure functions
27+ ├── b32_checks.test.sh # Sibling test for b32_checks.sh
28+ ├── b32_utils.sh # Layer 1 — Core: print_header, run_check, status helpers
29+ ├── b32_utils.test.sh # Sibling test for b32_utils.sh
30+ ├── c14_graph.sh # Layer 2 — Adapter: calls graphviz dot (filesystem write)
31+ ├── c14_graph.test.sh # Sibling test for c14_graph.sh
32+ └── d21_main.sh # Layer 3 — Entry: dispatcher for `sama check`, `sama graph`, etc.
33+ ```
34+- `tools/sama-cli/sama --help` prints usage covering: `sama check [check-name]`, `sama graph`, `sama doctor` (diagnostic: which tools are installed).
35+- Each of the 7 §4 checks implemented:
36+ * `check_sorted` — verify every file in `src/` matches `^[a-d][0-9]_` and the lex-order matches layer order
37+ * `check_architecture` — verify imports respect the prefix-to-layer contract (a=Pure imports nothing local; d=Entry can import any lower; b/c follow the Law)
38+ * `check_modeled_tests` — every `b*_<name>.{ts,sh}` and `c*_<name>.{ts,sh}` source file has a sibling `<name>.test.{ts,sh}`
39+ * `check_modeled_boundary` — `JSON.parse|new URL|URLSearchParams|qs.parse` only appears in `c*_` files
40+ * `check_atomic` — no source file exceeds 700 LOC (configurable via `sama.profile.toml`)
41+ * `check_the_law` — no `import from "../<higher-prefix>"` violations; graph is acyclic
42+ * `check_consistency` — declared layer (file prefix) matches actual imported layers (no `a31_` importing from `b32_`)
43+- Cross-verifier agreement test: `tools/sama-cli/sama check` run against THIS repo's `src/` produces 7/7 ✓ — same verdict as `bun src/b32_sama_v2_verify.ts` (the existing TS verifier). A small bash script `tools/sama-cli/cross-verify.sh` runs both and asserts the verdicts are identical (exit 0 if they agree, exit 1 if they don't).
44+- Self-conformance: `tools/sama-cli/sama check` pointed at its OWN `tools/sama-cli/src/` returns 7/7 ✓. The shell verifier verifies itself under the same rules.
45+- `tools/sama-cli/sama graph` generates a `.dot` file and (if graphviz `dot` is installed) renders a PNG showing the import/source-relationship graph for the target src/ tree.
46+- `tools/sama-cli/sama doctor` lists every tool the verifier uses (`bash`, `find`, `grep`, `awk`, `wc`, `sed`, `sort`, optionally `dot`) and reports which are present + which version.
47+- A new blog post planned (NOT in this /goal — a follow-up plan-post) describes the two-verifier-agreement empirical claim. This /goal just builds the second implementation; the empirical-chain blog post is the next iteration.
48+- All existing `bun test` runs still pass (no regression — this /goal adds files in `tools/sama-cli/` and doesn't modify any existing src/).
49+- /sama/v2/verify (the TS verifier exposed on the live site) still reports 7/7 ✓.
50+- Optional but recommended: a CI hook (or a simple `make verify` Makefile target) that runs BOTH verifiers and fails if they disagree. Forces ongoing agreement, not just one-time agreement.
51+- Deployed; live-verify with curl:
52+ * /sama/v2/verify → 7/7 ✓ (the TS verifier, unchanged)
53+ * /GIT/tdd.md/blob/main/tools/sama-cli/sama → 200 (the shell entry is browseable on-site)
54+ * /GIT/tdd.md/tree/main/tools/sama-cli → 200 (the directory listing is reachable)
55+ * /goals/sama-cli-shell-verifier → 200 with status: shipped (this very goal file flipped post-merge)
56+
57+Constraints (anti-fudge):
58+- **Layer mapping is `a*_` = Layer 0 Pure, `b*_` = Layer 1 Core, `c*_` = Layer 2 Adapter, `d*_` = Layer 3 Entry.** This matches the canonical spec at /sama/v2 §1.1 and this repo's existing src/. The cli.md proposal's mapping is wrong; do not copy it.
59+- **Two-verifier agreement is load-bearing.** If the shell verifier produces a different verdict than the TS verifier on this codebase, the shell verifier is wrong by default. Only after both have been stress-tested against external repos (the §5 cross-repo measurements) can a disagreement be resolved by spec-reading rather than by deferring to one.
60+- **No Bun, no Node, no language runtime.** Pure POSIX shell + standard Linux utilities. `awk`, `sed`, `find`, `grep`, `wc`, `sort`, `bash`. `dot` (graphviz) is optional and only for the `graph` command.
61+- **Self-conformance is non-negotiable.** The verifier must score 7/7 ✓ against its own source tree. If it doesn't, the design is broken before it ships.
62+- **Sibling tests for every b*_ and c*_ file.** Per /sama/v2 §4.3. Use a minimal test runner — a bash function that asserts expected exit codes / output, or `bats` if it's available. Document the choice in `tools/sama-cli/README.md`.
63+- **`tools/sama-cli/` is a sub-project, not a sub-directory.** It has its own `sama.profile.toml`. The existing repo's profile is unchanged. The two profiles let the existing TS verifier ignore `tools/sama-cli/` files (since they're outside src/) and vice versa.
64+- **No symlinks. No git submodules. No external repo dependency.** Everything lands in this repo, in `tools/sama-cli/`. The /GIT/ browser surfaces it automatically.
65+- **Containerfile**: add `COPY tools ./tools` if shell verifier should run from the deployed container; otherwise the directory stays repo-only and isn't shipped to production. Decide based on whether `sama doctor` or `sama graph` should be runnable on the live server. Default: ship it (per the PR #46 lessons-learned that new top-level dirs need explicit COPY).
66+- Site language English-only in all shell comments + output strings.
67+- GitHub flow via flatpak-spawn (branch → PR → merge → push p620 → deploy via flatpak-spawn --host scripts/p620/deploy-tdd-md.sh).
68+- Do NOT change /sama/v2/verify or src/b32_sama_v2_verify.ts. The TS verifier is canonical for now.
69+- PR body MUST embed this verbatim /goal under `## /goal` per feedback_goal_authoring_workflow.md.
70+
71+Load-bearing files to read FIRST:
72+- `cli.md` at the repo root (the email proposal — read it, then ignore its prefix mapping; use the section structure but rebind the layer prefixes correctly)
73+- `src/b32_sama_v2_verify.ts` (the canonical TS verifier — the shell version must produce the same 7/7 ✓ on this repo)
74+- `src/a31_sama_v2.ts` (the spec constants: MAX_LINES = 700, WORKING_SET_MIN_LOC = 50, WORKING_SET_MAX_LOC = 500, layer prefix scheme — replicate as constants in `tools/sama-cli/src/a31_constants.sh`)
75+- `sama.profile.toml` at the repo root (the profile shape — `tools/sama-cli/sama.profile.toml` should mirror it for its own src/)
76+- /sama/v2 (the canonical spec — §4 checks, §1.2 the Law)
77+- /blog/2026-05/sama-v2-verifier-and-the-rename (the original verifier-and-renaming story — context for why the shell version exists)
78+- /blog/2026-05/sama-v2-metrics-emitter (the §5 emitter — same shape of building a second pure helper that agrees with an existing one structurally)
79+
80+**Falsifiable claim this /goal lays cable for** (the next iteration tests it):
81+
82+> *"Two independent implementations of the SAMA v2 §4 spec, written in different languages on different runtimes, will produce identical verdicts against any given codebase that conforms to the spec. If they disagree on this repo at 7/7 ✓, one of them is wrong — and per /sama/v2 §0 the disagreement is auditable from the spec prose alone."*
83+
84+The next blog post after this /goal merges will document: which checks the two verifiers agreed on byte-for-byte vs. which required the SAMA v2 spec to disambiguate. That's the §6 evolution-policy mechanism in action — disagreements between independent implementations are the spec's empirical-validation pressure-points.
modified src/a31_goals.ts +13 −0
@@ -38,6 +38,19 @@ export interface GoalEntry {
3838 }
3939
4040 export const ALL_GOALS: GoalEntry[] = [
41+ {
42+ slug: "sama-cli-shell-verifier",
43+ title: "Linux-native shell-based SAMA v2 verifier — second independent implementation",
44+ date: "2026-05-25",
45+ branch: "sama-cli-shell-verifier",
46+ prNumber: null,
47+ mergeSha: null,
48+ status: "pending",
49+ relatedPosts: [
50+ "sama-v2-verifier-and-the-rename",
51+ "sama-v2-metrics-emitter",
52+ ],
53+ },
4154 {
4255 slug: "blog-date-prefix",
4356 title: "Move /blog/<slug> → /blog/<yyyy-mm>/<slug> — data-driven portability test",