chore: replace AI skill library with 16 verified mvp-* skills
Deploy to Staging / Build Images (push) Successful in 5m32s
Deploy to Staging / Deploy to Staging (push) Successful in 44s
Deploy to Staging / Verify Staging (push) Successful in 5s
Deploy to Staging / Notify Staging Ready (push) Successful in 4s
Deploy to Staging / Notify Staging Failure (push) Has been skipped

Removes the old planner/decision-critic/role-agents/domain-agents system
(step-injector scripts, stale scopes, sprint-era workflow) and replaces it
with 16 ground-truth-verified skills under .claude/skills/: change control,
debugging playbook, failure archaeology, architecture contract, domain
reference, OCR/Gemini pipeline, config and secrets, build and env, run and
operate, diagnostics (with tested scripts), validation and QA, docs and
writing, launch readiness, deploy-safety campaign, proof and analysis
toolkit, and research frontier. RULE 0/1/2, the temporal-contamination rule,
and the decision stress-test protocol are carried forward into the new
skills; the retired content remains in git history.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Eric Gullickson
2026-07-09 20:21:42 -05:00
co-authored by Claude Fable 5
parent e729d425fd
commit c239bb9347
71 changed files with 4087 additions and 10221 deletions
@@ -0,0 +1,77 @@
#!/bin/bash
# check-numeric-coercion.sh - Find NUMERIC/DECIMAL columns returned from
# repositories without Number()/parseFloat() coercion.
#
# Why: node-postgres returns NUMERIC/DECIMAL (OID 1700) as *strings*.
# backend/src/core/config/database.ts overrides only the DATE parser, so
# every repository mapper must coerce manually. Missed coercion is this
# project's #1 recurring bug class (issues #239, #241, #244).
#
# Usage: ./check-numeric-coercion.sh (read-only; run from anywhere in repo)
# Exit: 0 = no suspects, 1 = suspects found, 2 = setup error
set -u
ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
[ -z "$ROOT" ] && { echo "ERROR: not inside a git repo" >&2; exit 2; }
SRC="$ROOT/backend/src"
[ -d "$SRC" ] && cd "$ROOT" || { echo "ERROR: $SRC missing" >&2; exit 2; }
# 1. Collect numeric/decimal column names from all migration SQL.
# Three shapes: column definition lines, ADD COLUMN, ALTER COLUMN ... TYPE.
COLS=$(
{
grep -rhiE '^[[:space:]]*"?[a-z_]+"?[[:space:]]+(numeric|decimal)[[:space:](]' \
--include='*.sql' "$SRC" | awk '{gsub(/"/,""); print tolower($1)}'
grep -rhioE 'add column (if not exists )?"?[a-z_]+"? +(numeric|decimal)' \
--include='*.sql' "$SRC" | awk '{gsub(/"/,""); print tolower($(NF-1))}'
grep -rhioE 'alter column "?[a-z_]+"? type +(numeric|decimal)' \
--include='*.sql' "$SRC" | awk '{gsub(/"/,""); print tolower($(NF-2))}'
} | sort -u
)
[ -z "$COLS" ] && { echo "ERROR: no numeric columns found (wrong dir?)" >&2; exit 2; }
echo "Numeric/decimal columns found in migrations:"
echo "$COLS" | tr '\n' ' '; echo; echo
# 2. In every repository file, flag lines that read row.<col> without
# Number( or parseFloat( on the same line.
SUSPECTS=0
for col in $COLS; do
HITS=$(find "$SRC" -name '*.repository.ts' -exec \
grep -nE "row\.${col}([^a-zA-Z0-9_]|\$)" {} + 2>/dev/null |
grep -v 'parseFloat(' | grep -v 'Number(')
if [ -n "$HITS" ]; then
echo "SUSPECT column '$col' (string from pg, no coercion on line):"
echo "$HITS" | sed "s|$ROOT/||; s/^/ /"
SUSPECTS=$((SUSPECTS + $(echo "$HITS" | wc -l | tr -d ' ')))
fi
done
# 3. Flag raw-row returns (the actual shape of bug #244: "return res.rows[0]"
# bypasses the mapper entirely) in features whose migrations define
# numeric columns. Scalar returns (.count/.exists/.length) are filtered.
for repo in $(find "$SRC/features" -name '*.repository.ts'); do
feat=$(echo "$repo" | sed "s|$SRC/features/||; s|/.*||")
featcols=$(grep -rhiE "(numeric|decimal)" --include='*.sql' \
"$SRC/features/$feat/migrations" 2>/dev/null | head -1)
[ -z "$featcols" ] && continue
RAW=$(grep -nE 'return (res|result)\.rows' "$repo" |
grep -vE 'map[A-Za-z]*\(|\.map\(|\?\.|\.length|\.count|\.exists')
if [ -n "$RAW" ]; then
echo "SUSPECT raw-row return in numeric-bearing feature '$feat':"
echo "$RAW" | sed "s|^| ${repo#"$ROOT"/}:|"
SUSPECTS=$((SUSPECTS + $(echo "$RAW" | wc -l | tr -d ' ')))
fi
done
echo
if [ "$SUSPECTS" -eq 0 ]; then
echo "PASS: no uncoerced numeric column reads or raw-row returns found."
exit 0
else
echo "FAIL: $SUSPECTS suspect line(s). Each must wrap the value in Number()"
echo "or parseFloat() (nullable: 'row.x != null ? parseFloat(row.x) : null')."
echo "Limitations: same-line heuristic; coercion done on a different line or"
echo "in the service layer will still be flagged - verify before fixing."
exit 1
fi