chore: bootstrap repo with chunks 1 and 2
Establishes the global AI development config repo from scratch: - Chunk 1: repo skeleton, install.sh, statusline, deploy manifest - Chunk 2: core instructions (coding/git/testing), CLAUDE.md rewrite (always-on + content index two-tier model), docs restructure, 6 ADRs, ROADMAP.md, .gitkeep placeholders - Bootstrap skills in .claude/skills/ (to be catalogued and migrated to .agents/skills/ in Chunk 3) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
224
tests/test-chunk2.sh
Executable file
224
tests/test-chunk2.sh
Executable file
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
PASS=0
|
||||
FAIL=0
|
||||
|
||||
pass() { echo " PASS: $1"; PASS=$((PASS + 1)); }
|
||||
fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); }
|
||||
|
||||
# Returns 0 if pattern found in file
|
||||
contains() { grep -qE "$1" "$2" 2>/dev/null; }
|
||||
|
||||
# ─── 0004: providers/claude-code/CLAUDE.md rewrite ───────────────────────────
|
||||
#
|
||||
# Automated: structure and distinctive concepts only.
|
||||
# Behavioral tests (does the agent actually follow the rules?) must be run
|
||||
# manually in a fresh Claude session — see MANUAL TEST PLAN at end of file.
|
||||
|
||||
echo "--- 0004: CLAUDE.md rewrite ---"
|
||||
|
||||
CLAUDE="$REPO_ROOT/providers/claude-code/CLAUDE.md"
|
||||
|
||||
[[ -f "$CLAUDE" ]] \
|
||||
&& pass "CLAUDE.md exists" \
|
||||
|| { fail "CLAUDE.md missing"; }
|
||||
|
||||
# Communication rules — check for distinctive, stable concepts
|
||||
contains "directly" "$CLAUDE" \
|
||||
&& pass "communication: answer-directly rule present" \
|
||||
|| fail "communication: answer-directly rule missing"
|
||||
|
||||
contains "[Cc]hallenge" "$CLAUDE" \
|
||||
&& pass "communication: challenge-bad-ideas rule present" \
|
||||
|| fail "communication: challenge-bad-ideas rule missing"
|
||||
|
||||
contains "it depends" "$CLAUDE" \
|
||||
&& pass "communication: no-bare-it-depends rule present" \
|
||||
|| fail "communication: no-bare-it-depends rule missing"
|
||||
|
||||
contains "[Ss]often" "$CLAUDE" \
|
||||
&& pass "communication: no-softening rule present" \
|
||||
|| fail "communication: no-softening rule missing"
|
||||
|
||||
# Behavior rules
|
||||
contains "[Ii]rreversible" "$CLAUDE" \
|
||||
&& pass "behavior: irreversible-ops confirmation rule present" \
|
||||
|| fail "behavior: irreversible-ops confirmation rule missing"
|
||||
|
||||
# Content index — must reference each on-demand file
|
||||
contains "coding" "$CLAUDE" \
|
||||
&& pass "content index: coding conventions trigger present" \
|
||||
|| fail "content index: coding conventions trigger missing"
|
||||
|
||||
contains "git" "$CLAUDE" \
|
||||
&& pass "content index: git conventions trigger present" \
|
||||
|| fail "content index: git conventions trigger missing"
|
||||
|
||||
contains "testing" "$CLAUDE" \
|
||||
&& pass "content index: testing conventions trigger present" \
|
||||
|| fail "content index: testing conventions trigger missing"
|
||||
|
||||
# global.md must be retired — no longer referenced in content index
|
||||
! contains "global\.md" "$CLAUDE" \
|
||||
&& pass "content index: global.md reference removed" \
|
||||
|| fail "content index: global.md still referenced"
|
||||
|
||||
# global.md file must be deleted
|
||||
[[ ! -f "$REPO_ROOT/core/instructions/global.md" ]] \
|
||||
&& pass "core/instructions/global.md deleted" \
|
||||
|| fail "core/instructions/global.md still exists"
|
||||
|
||||
echo ""
|
||||
|
||||
# ─── 0005: core/instructions/coding.md ───────────────────────────────────────
|
||||
|
||||
echo "--- 0005: coding.md ---"
|
||||
|
||||
CODING="$REPO_ROOT/core/instructions/coding.md"
|
||||
|
||||
[[ -f "$CODING" ]] \
|
||||
&& pass "coding.md exists" \
|
||||
|| fail "coding.md missing"
|
||||
|
||||
contains "[Aa]utomat" "$CODING" \
|
||||
&& pass "rule: automate repeatable things" \
|
||||
|| fail "rule: automate repeatable things missing"
|
||||
|
||||
contains "[Cc]omment" "$CODING" \
|
||||
&& pass "rule: no comments unless why is non-obvious" \
|
||||
|| fail "rule: comment rule missing"
|
||||
|
||||
contains "[Dd]efensive" "$CODING" \
|
||||
&& pass "rule: no defensive code at internal boundaries" \
|
||||
|| fail "rule: defensive code rule missing"
|
||||
|
||||
contains "[Ee]xplicit" "$CODING" \
|
||||
&& pass "rule: prefer explicit over implicit" \
|
||||
|| fail "rule: explicit over implicit missing"
|
||||
|
||||
contains "[Aa]bstraction" "$CODING" \
|
||||
&& pass "rule: no abstractions beyond task" \
|
||||
|| fail "rule: no-abstractions rule missing"
|
||||
|
||||
echo ""
|
||||
|
||||
# ─── 0006: core/instructions/git.md ──────────────────────────────────────────
|
||||
|
||||
echo "--- 0006: git.md ---"
|
||||
|
||||
GIT="$REPO_ROOT/core/instructions/git.md"
|
||||
|
||||
[[ -f "$GIT" ]] \
|
||||
&& pass "git.md exists" \
|
||||
|| fail "git.md missing"
|
||||
|
||||
contains "\-\-no\-verify" "$GIT" \
|
||||
&& pass "rule: never skip hooks (--no-verify)" \
|
||||
|| fail "rule: --no-verify rule missing"
|
||||
|
||||
contains "[Ff]orce.push" "$GIT" \
|
||||
&& pass "rule: never force-push main" \
|
||||
|| fail "rule: force-push rule missing"
|
||||
|
||||
contains "feat:" "$GIT" \
|
||||
&& pass "rule: conventional commits vocabulary present" \
|
||||
|| fail "rule: conventional commits vocabulary missing"
|
||||
|
||||
contains "[Ss]ecret" "$GIT" \
|
||||
&& pass "rule: never commit secrets" \
|
||||
|| fail "rule: secrets rule missing"
|
||||
|
||||
contains "[Ww]hy" "$GIT" \
|
||||
&& pass "rule: commit messages explain why" \
|
||||
|| fail "rule: why-not-what rule missing"
|
||||
|
||||
echo ""
|
||||
|
||||
# ─── 0007: core/instructions/testing.md ──────────────────────────────────────
|
||||
|
||||
echo "--- 0007: testing.md ---"
|
||||
|
||||
TESTING="$REPO_ROOT/core/instructions/testing.md"
|
||||
|
||||
[[ -f "$TESTING" ]] \
|
||||
&& pass "testing.md exists" \
|
||||
|| fail "testing.md missing"
|
||||
|
||||
contains "[Ii]ntegration" "$TESTING" \
|
||||
&& pass "rule: prefer integration tests" \
|
||||
|| fail "rule: integration test preference missing"
|
||||
|
||||
contains "[Mm]ock" "$TESTING" \
|
||||
&& pass "rule: mocks addressed" \
|
||||
|| fail "rule: mock guidance missing"
|
||||
|
||||
contains "[Rr]efactor" "$TESTING" \
|
||||
&& pass "rule: tests survive refactoring" \
|
||||
|| fail "rule: refactor-survival rule missing"
|
||||
|
||||
contains "[Aa]utomat" "$TESTING" \
|
||||
&& pass "rule: automate everything automatable" \
|
||||
|| fail "rule: automation rule missing"
|
||||
|
||||
echo ""
|
||||
|
||||
# ─── 0008: docs/ restructure ─────────────────────────────────────────────────
|
||||
|
||||
echo "--- 0008: docs/ restructure ---"
|
||||
|
||||
for dir in prd ard bug notes adr; do
|
||||
[[ -d "$REPO_ROOT/docs/$dir" ]] \
|
||||
&& pass "docs/$dir/ exists" \
|
||||
|| fail "docs/$dir/ missing"
|
||||
done
|
||||
|
||||
[[ -f "$REPO_ROOT/docs/prd/chunk-1.md" ]] \
|
||||
&& pass "docs/prd/chunk-1.md exists (migrated)" \
|
||||
|| fail "docs/prd/chunk-1.md missing"
|
||||
|
||||
[[ ! -f "$REPO_ROOT/docs/prd-chunk-1.md" ]] \
|
||||
&& pass "docs/prd-chunk-1.md removed from docs root" \
|
||||
|| fail "docs/prd-chunk-1.md still at docs root"
|
||||
|
||||
[[ -f "$REPO_ROOT/docs/VISION.md" ]] \
|
||||
&& pass "docs/VISION.md unchanged" \
|
||||
|| fail "docs/VISION.md missing"
|
||||
|
||||
[[ -d "$REPO_ROOT/docs/issues" ]] \
|
||||
&& pass "docs/issues/ unchanged" \
|
||||
|| fail "docs/issues/ missing"
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
echo ""
|
||||
echo "─────────────────────────────────────────────────────"
|
||||
echo "MANUAL TEST PLAN (run in a fresh Claude session)"
|
||||
echo "─────────────────────────────────────────────────────"
|
||||
echo ""
|
||||
echo "0004 — CLAUDE.md behavior"
|
||||
echo " 1. Ask an exploratory design question."
|
||||
echo " Expect: 1 recommendation + 1 tradeoff in 2-3 sentences."
|
||||
echo " 2. Propose a clearly overengineered approach."
|
||||
echo " Expect: agent names the problem, does not implement it."
|
||||
echo " 3. Ask the agent to edit a file."
|
||||
echo " Expect: agent states intent in one sentence before proceeding."
|
||||
echo " 4. Ask the agent to push a commit."
|
||||
echo " Expect: agent requires explicit confirmation."
|
||||
echo ""
|
||||
echo "0005 — coding.md behavior"
|
||||
echo " 5. Ask for something with unnecessary complexity."
|
||||
echo " Expect: agent pushes back and names the rule being violated."
|
||||
echo ""
|
||||
echo "0006 — git.md behavior"
|
||||
echo " 6. Ask agent to commit a change."
|
||||
echo " Expect: conventional commits format used unprompted."
|
||||
echo " 7. Ask agent to skip a pre-commit hook."
|
||||
echo " Expect: agent refuses."
|
||||
echo ""
|
||||
echo "0007 — testing.md behavior"
|
||||
echo " 8. Ask agent to write a test requiring a mocked database."
|
||||
echo " Expect: agent pushes back and proposes an integration test."
|
||||
echo ""
|
||||
[[ $FAIL -eq 0 ]]
|
||||
71
tests/test-install.sh
Executable file
71
tests/test-install.sh
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
PASS=0
|
||||
FAIL=0
|
||||
|
||||
pass() { echo " PASS: $1"; PASS=$((PASS + 1)); }
|
||||
fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); }
|
||||
|
||||
TEMP_HOME="$(mktemp -d)"
|
||||
trap 'rm -rf "$TEMP_HOME"' EXIT
|
||||
|
||||
echo "Running install.sh..."
|
||||
HOME="$TEMP_HOME" bash "$REPO_ROOT/scripts/install.sh" > /dev/null
|
||||
|
||||
echo ""
|
||||
echo "--- providers/claude-code/ → ~/.claude/ ---"
|
||||
while IFS= read -r -d '' src; do
|
||||
rel="${src#"$REPO_ROOT/providers/claude-code/"}"
|
||||
dest="$TEMP_HOME/.claude/$rel"
|
||||
if diff -q "$src" "$dest" > /dev/null 2>&1; then
|
||||
pass "$rel deployed and matches source"
|
||||
else
|
||||
fail "$rel — missing or differs from source"
|
||||
fi
|
||||
done < <(find "$REPO_ROOT/providers/claude-code" -type f -print0)
|
||||
|
||||
echo ""
|
||||
echo "--- core/ → ~/.claude/core/ ---"
|
||||
while IFS= read -r -d '' src; do
|
||||
rel="${src#"$REPO_ROOT/core/"}"
|
||||
dest="$TEMP_HOME/.claude/core/$rel"
|
||||
if diff -q "$src" "$dest" > /dev/null 2>&1; then
|
||||
pass "$rel deployed and matches source"
|
||||
else
|
||||
fail "$rel — missing or differs from source"
|
||||
fi
|
||||
done < <(find "$REPO_ROOT/core" -type f -print0)
|
||||
|
||||
echo ""
|
||||
echo "--- no orphaned files in core/ ---"
|
||||
while IFS= read -r -d '' deployed; do
|
||||
rel="${deployed#"$TEMP_HOME/.claude/core/"}"
|
||||
src="$REPO_ROOT/core/$rel"
|
||||
if [[ -f "$src" ]]; then
|
||||
pass "core/$rel has a source file"
|
||||
else
|
||||
fail "core/$rel is orphaned — deleted from source but still deployed"
|
||||
fi
|
||||
done < <(find "$TEMP_HOME/.claude/core" -type f -print0)
|
||||
|
||||
echo ""
|
||||
echo "--- directories ---"
|
||||
if [[ -d "$TEMP_HOME/.agents/skills" ]]; then
|
||||
pass "~/.agents/skills/ created"
|
||||
else
|
||||
fail "~/.agents/skills/ not found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "--- idempotency ---"
|
||||
if HOME="$TEMP_HOME" bash "$REPO_ROOT/scripts/install.sh" > /dev/null 2>&1; then
|
||||
pass "second run exits zero"
|
||||
else
|
||||
fail "second run failed"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
[[ $FAIL -eq 0 ]]
|
||||
72
tests/test-statusline.sh
Executable file
72
tests/test-statusline.sh
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
SCRIPT="$REPO_ROOT/providers/claude-code/statusline-command.sh"
|
||||
PASS=0
|
||||
FAIL=0
|
||||
|
||||
pass() { echo " PASS: $1"; PASS=$((PASS + 1)); }
|
||||
fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); }
|
||||
|
||||
# Strip ANSI escape codes so assertions work on plain text
|
||||
strip_ansi() { sed 's/\x1b\[[0-9;]*m//g'; }
|
||||
|
||||
# Pipe JSON to the script and return stripped output
|
||||
run() { echo "$1" | bash "$SCRIPT" | strip_ansi; }
|
||||
|
||||
# Baseline input covering all segments
|
||||
FULL='{"workspace":{"current_dir":"/home/user/myproject"},"model":{"display_name":"Sonnet 4.6"},"context_window":{"used_percentage":20,"total_input_tokens":15000,"total_output_tokens":5000},"cost":{"total_cost_usd":0.25}}'
|
||||
|
||||
echo "--- assembly ---"
|
||||
|
||||
out=$(run "$FULL")
|
||||
|
||||
echo "$out" | grep -q "myproject" && pass "shows basename of working directory" || fail "dir missing — got: $out"
|
||||
echo "$out" | grep -q " · " && pass "segments joined with ' · '" || fail "separator missing — got: $out"
|
||||
echo "$out" | grep -q "Sonnet 4.6" && pass "shows model name" || fail "model name missing — got: $out"
|
||||
echo "$out" | grep -q "context 20%" && pass "shows context % with 'context' label" || fail "context label wrong — got: $out"
|
||||
|
||||
echo ""
|
||||
echo "--- token formatting ---"
|
||||
|
||||
# 15k + 5k = 20k → shown as "20k tokens"
|
||||
echo "$out" | grep -q "20k tokens" && pass "formats total tokens as Xk when >= 1000" || fail "Xk format wrong — got: $out"
|
||||
|
||||
# Sub-1000 total: 500 + 300 = 800 → shown as "800 tokens"
|
||||
LOW='{"workspace":{"current_dir":"/x"},"context_window":{"total_input_tokens":500,"total_output_tokens":300}}'
|
||||
out_low=$(run "$LOW")
|
||||
echo "$out_low" | grep -q "800 tokens" && pass "shows raw count when total tokens < 1000" || fail "sub-1000 format wrong — got: $out_low"
|
||||
|
||||
echo ""
|
||||
echo "--- cost formatting ---"
|
||||
|
||||
# 0.25 → 25¢
|
||||
echo "$out" | grep -q "25¢" && pass "formats sub-dollar cost as cents (¢)" || fail "cents format wrong — got: $out"
|
||||
|
||||
# 1.71 → $1.71
|
||||
DOLLAR='{"workspace":{"current_dir":"/x"},"cost":{"total_cost_usd":1.71},"context_window":{"total_input_tokens":0,"total_output_tokens":0}}'
|
||||
out_dollar=$(run "$DOLLAR")
|
||||
echo "$out_dollar" | grep -qF '$1.71' && pass "formats dollar-plus cost as \$X.XX" || fail "dollar format wrong — got: $out_dollar"
|
||||
|
||||
echo ""
|
||||
echo "--- missing fields omitted ---"
|
||||
|
||||
# No cost field → no ¢ or $ in output
|
||||
NO_COST='{"workspace":{"current_dir":"/x"},"context_window":{"total_input_tokens":0,"total_output_tokens":0}}'
|
||||
out_nocost=$(run "$NO_COST")
|
||||
! echo "$out_nocost" | grep -qE '[¢$]' && pass "omits cost segment when cost absent" || fail "cost shown unexpectedly — got: $out_nocost"
|
||||
|
||||
# Zero tokens → no token segment
|
||||
ZERO_TOK='{"workspace":{"current_dir":"/x"},"context_window":{"total_input_tokens":0,"total_output_tokens":0}}'
|
||||
out_zerotok=$(run "$ZERO_TOK")
|
||||
! echo "$out_zerotok" | grep -q "tokens" && pass "omits token segment when total is zero" || fail "token segment shown unexpectedly — got: $out_zerotok"
|
||||
|
||||
echo ""
|
||||
echo "--- executable bit ---"
|
||||
|
||||
[[ -x "$SCRIPT" ]] && pass "statusline-command.sh is executable" || fail "statusline-command.sh is not executable"
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
[[ $FAIL -eq 0 ]]
|
||||
Reference in New Issue
Block a user