feat(skill): add scripts, templates, and evals to backend-engineering and frontend-engineering (#256)

Thicken the two flagship engineering methodology skills with the artifact
set promised by issue #239: schema-v1 eval manifests (6 cases each), fillable
templates, and one small stdlib-only script per skill with tests.

backend-engineering:
- evals/evals.json: API implementation review, endpoint modeling, service
  structure, error handling, N+1 detection, integration retry/idempotency
- templates/service-design-record.md, templates/error-handling-taxonomy.md
- scripts/n1-query-spotter.py (+ test_n1_query_spotter.py): flags query-like
  calls inside loops with loop-variable confidence, --json output

frontend-engineering:
- evals/evals.json: component/state design, state management selection, API
  integration, data-fetching states, performance review, performance budgets
- templates/component-state-design-record.md, templates/performance-budget.md
- scripts/bundle-budget-checker.py (+ test_bundle_budget_checker.py): enforces
  total and per-chunk byte budgets on bundle reports, exit 1 on violation

Both SKILL.md files gain Templates and Scripts sections; both READMEs document
the scripts in Quick Start. All local validators pass (validate-skills.rb,
validate-evals.py, eval-coverage ratchet, make validate).

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
Magnus Hedemark
2026-08-03 15:08:28 -04:00
committed by GitHub
co-authored by factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
parent abe1ab3a00
commit 48c1a1e6f5
14 changed files with 1388 additions and 4 deletions
@@ -0,0 +1,192 @@
#!/usr/bin/env python3
"""Bundle budget checker for frontend-engineering.
Compares a JavaScript/CSS bundle size report against total and per-chunk byte
budgets and fails when a budget is exceeded, so a performance regression stops
the build instead of shipping silently.
Input: a JSON file describing bundle chunks, in either of two shapes:
{"chunks": [{"name": "main.js", "size": 180000}, ...]} # structured
{"main.js": 180000, "vendor.js": 90000} # name -> bytes
Budgets accept human units: 250KB, 1.5MB, 512000, 10 B (decimal KB/MB/GB or
binary KiB/MiB/GiB).
Exit codes:
0 all sizes within budget
1 one or more chunks or the total exceed budget
2 usage or input error (missing file, malformed JSON, bad budget value)
"""
import argparse
import json
import re
import sys
from pathlib import Path
_UNIT_RE = re.compile(r"^\s*(\d+(?:\.\d+)?)\s*(b|kb|kib|mb|mib|gb|gib)?\s*$", re.IGNORECASE)
_MULTIPLIERS = {
"b": 1,
"kb": 1000,
"kib": 1024,
"mb": 1000**2,
"mib": 1024**2,
"gb": 1000**3,
"gib": 1024**3,
}
def parse_size(text):
"""Parse '250KB', '1.5MB', or plain byte counts into an int, or None."""
match = _UNIT_RE.match(text)
if not match:
return None
value = float(match.group(1))
unit = (match.group(2) or "b").lower()
return int(value * _MULTIPLIERS[unit])
def human_size(size):
"""Render a byte count in a compact human unit (binary)."""
value = float(size)
for unit in ("B", "KiB", "MiB", "GiB"):
if value < 1024 or unit == "GiB":
if unit == "B":
return f"{int(value)} B"
return f"{value:.1f} {unit}"
value /= 1024
return f"{value:.1f} GiB"
def load_chunks(path):
"""Load a bundle report into [(name, bytes)]; raises ValueError on bad input."""
try:
raw = json.loads(Path(path).read_text(encoding="utf-8"))
except OSError as exc:
raise ValueError(f"cannot read {path}: {exc.strerror}") from exc
except json.JSONDecodeError as exc:
raise ValueError(f"{path}: invalid JSON: {exc.msg}") from exc
if isinstance(raw, dict):
if "chunks" in raw:
chunks = raw["chunks"]
if not isinstance(chunks, list):
raise ValueError(f"{path}: 'chunks' must be a list")
return [
(str(entry["name"]), int(entry["size"]))
for entry in chunks
if "name" in entry and "size" in entry
]
return [(str(name), int(size)) for name, size in raw.items()]
raise ValueError(f"{path}: report must be a JSON object of chunk names to sizes")
def build_parser():
parser = argparse.ArgumentParser(
prog="bundle-budget-checker.py",
description=(
"Check a bundle size report against total and per-chunk budgets. "
'Report format: {"chunks": [{"name": ..., "size": bytes}]} '
"or a plain {name: bytes} mapping."
),
epilog="Exit codes: 0 within budget, 1 over budget, 2 usage or input error.",
)
parser.add_argument("report", metavar="REPORT.json", help="bundle size report")
parser.add_argument(
"--total",
metavar="SIZE",
default=None,
help="total budget for all chunks, e.g. 500KB or 512000",
)
parser.add_argument(
"--chunk",
metavar="SIZE",
default=None,
help="per-chunk budget, e.g. 120KB; each chunk is checked individually",
)
parser.add_argument("--json", action="store_true", help="emit a machine-readable JSON report")
return parser
def main(argv=None):
parser = build_parser()
args = parser.parse_args(argv)
total_budget = parse_size(args.total) if args.total is not None else None
chunk_budget = parse_size(args.chunk) if args.chunk is not None else None
if args.total is not None and total_budget is None:
print(f"ERROR: cannot parse budget {args.total!r}", file=sys.stderr)
return 2
if args.chunk is not None and chunk_budget is None:
print(f"ERROR: cannot parse budget {args.chunk!r}", file=sys.stderr)
return 2
if total_budget is not None and total_budget < 0:
print("ERROR: --total must not be negative", file=sys.stderr)
return 2
if chunk_budget is not None and chunk_budget < 0:
print("ERROR: --chunk must not be negative", file=sys.stderr)
return 2
try:
chunks = load_chunks(args.report)
except ValueError as exc:
print(f"ERROR: {exc}", file=sys.stderr)
return 2
total = sum(size for _, size in chunks)
rows = []
over_budget = False
for name, size in chunks:
over = chunk_budget is not None and size > chunk_budget
over_budget = over_budget or over
rows.append(
{
"name": name,
"bytes": size,
"budget": chunk_budget,
"status": "over" if over else "ok",
}
)
total_over = total_budget is not None and total > total_budget
over_budget = over_budget or total_over
if args.json:
print(
json.dumps(
{
"total": {
"bytes": total,
"budget": total_budget,
"status": "over" if total_over else "ok",
},
"chunks": rows,
"over_budget": over_budget,
},
indent=2,
)
)
else:
print("Bundle budget report")
for row in rows:
status = "OVER" if row["status"] == "over" else "OK"
budget_text = human_size(row["budget"]) if row["budget"] is not None else "unset"
print(
f" {row['name']:<24} {human_size(row['bytes']):>10} "
f"budget {budget_text:>8} {status}"
)
total_budget_text = human_size(total_budget) if total_budget is not None else "unset"
total_status = "OVER" if total_over else "OK"
print(
f" {'total':<24} {human_size(total):>10} "
f"budget {total_budget_text:>8} {total_status}"
)
if over_budget:
print("Result: over budget", file=sys.stderr)
else:
print("Result: within budget")
return 1 if over_budget else 0
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,229 @@
"""Tests for bundle-budget-checker.py.
Covers: total and per-chunk budget enforcement, both input shapes (structured
chunks list and name->bytes mapping), human unit parsing (250KB, 1.5MB), --json
output, no-budget report mode, --help, and error paths (missing file, malformed
JSON, bad budget value).
Discoverable by both pytest and unittest (unittest.TestCase classes).
"""
import json
import os
import subprocess
import sys
import tempfile
import unittest
from contextlib import suppress
SCRIPTS_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)))
CHECKER = os.path.join(SCRIPTS_DIR, "bundle-budget-checker.py")
def run_checker(args):
cmd = [sys.executable, CHECKER, *args]
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
return proc.returncode, proc.stdout, proc.stderr
def write_report(data):
"""Write a JSON bundle report to a temp file; return its path."""
with tempfile.NamedTemporaryFile(
mode="w", suffix=".json", delete=False, encoding="utf-8"
) as handle:
json.dump(data, handle)
path = handle.name
return path
def cleanup(path):
with suppress(OSError):
os.unlink(path)
class TestBundleBudgetBudgets(unittest.TestCase):
def test_within_total_budget(self):
path = write_report({"chunks": [{"name": "main.js", "size": 100000}]})
try:
rc, _, _ = run_checker([path, "--total", "250KB"])
self.assertEqual(rc, 0)
finally:
cleanup(path)
def test_over_total_budget(self):
path = write_report({"chunks": [{"name": "main.js", "size": 300000}]})
try:
rc, _, stderr = run_checker([path, "--total", "250KB"])
self.assertEqual(rc, 1)
self.assertIn("over budget", stderr)
finally:
cleanup(path)
def test_over_chunk_budget(self):
path = write_report(
{"chunks": [{"name": "main.js", "size": 180000}, {"name": "vendor.js", "size": 90000}]}
)
try:
rc, stdout, _ = run_checker([path, "--chunk", "120KB"])
self.assertEqual(rc, 1)
self.assertIn("main.js", stdout)
self.assertIn("OVER", stdout)
finally:
cleanup(path)
def test_all_chunks_within_chunk_budget(self):
path = write_report({"chunks": [{"name": "main.js", "size": 100000}]})
try:
rc, stdout, _ = run_checker([path, "--chunk", "200KB"])
self.assertEqual(rc, 0)
self.assertIn("OK", stdout)
finally:
cleanup(path)
def test_total_and_chunk_combined(self):
path = write_report(
{"chunks": [{"name": "main.js", "size": 80000}, {"name": "vendor.js", "size": 80000}]}
)
try:
# Within both budgets: total 160 KB <= 200 KB, each chunk <= 100 KB.
rc_ok, _, _ = run_checker([path, "--total", "200KB", "--chunk", "100KB"])
self.assertEqual(rc_ok, 0)
# Over chunk budget but within total: one chunk over 100 KB.
rc_chunk, _, _ = run_checker([path, "--total", "300KB", "--chunk", "75KB"])
self.assertEqual(rc_chunk, 1)
# Over total but within chunk budget.
rc_total, _, _ = run_checker([path, "--total", "100KB", "--chunk", "100KB"])
self.assertEqual(rc_total, 1)
finally:
cleanup(path)
def test_no_budget_reports_only(self):
path = write_report({"chunks": [{"name": "main.js", "size": 180000}]})
try:
rc, stdout, _ = run_checker([path])
self.assertEqual(rc, 0)
self.assertIn("unset", stdout)
self.assertIn("within budget", stdout)
finally:
cleanup(path)
class TestBundleBudgetFormats(unittest.TestCase):
def test_mapping_input_shape(self):
path = write_report({"main.js": 180000, "vendor.js": 90000})
try:
rc, stdout, _ = run_checker([path, "--total", "300KB"])
self.assertEqual(rc, 0)
self.assertIn("main.js", stdout)
self.assertIn("vendor.js", stdout)
finally:
cleanup(path)
def test_empty_chunks_list(self):
path = write_report({"chunks": []})
try:
rc, stdout, _ = run_checker([path, "--total", "100KB"])
self.assertEqual(rc, 0)
self.assertIn("within budget", stdout)
finally:
cleanup(path)
class TestBundleBudgetParsing(unittest.TestCase):
def test_unit_parsing_variants(self):
path = write_report({"chunks": [{"name": "main.js", "size": 1024}]})
try:
rc_ok, _, _ = run_checker([path, "--total", "1.5KB"])
self.assertEqual(rc_ok, 0)
rc_bin, _, _ = run_checker([path, "--total", "1KiB"])
self.assertEqual(rc_bin, 0)
rc_over, _, _ = run_checker([path, "--total", "512B"])
self.assertEqual(rc_over, 1)
finally:
cleanup(path)
def test_plain_byte_budget(self):
path = write_report({"chunks": [{"name": "main.js", "size": 512000}]})
try:
rc, _, _ = run_checker([path, "--total", "512000"])
self.assertEqual(rc, 0)
finally:
cleanup(path)
def test_mib_budget(self):
path = write_report({"chunks": [{"name": "app.js", "size": 1500000}]})
try:
rc, _, _ = run_checker([path, "--total", "2MiB"])
self.assertEqual(rc, 0)
finally:
cleanup(path)
class TestBundleBudgetCli(unittest.TestCase):
def test_help_exits_zero(self):
rc, stdout, _ = run_checker(["--help"])
self.assertEqual(rc, 0)
self.assertIn("budget", stdout)
def test_json_output_parseable(self):
path = write_report({"chunks": [{"name": "main.js", "size": 300000}]})
try:
rc, stdout, _ = run_checker([path, "--total", "250KB", "--json"])
self.assertEqual(rc, 1)
report = json.loads(stdout)
self.assertTrue(report["over_budget"])
self.assertEqual(report["total"]["status"], "over")
self.assertEqual(report["chunks"][0]["name"], "main.js")
finally:
cleanup(path)
def test_json_within_budget(self):
path = write_report({"chunks": [{"name": "main.js", "size": 100000}]})
try:
rc, stdout, _ = run_checker([path, "--total", "250KB", "--json"])
self.assertEqual(rc, 0)
report = json.loads(stdout)
self.assertFalse(report["over_budget"])
self.assertEqual(report["chunks"][0]["status"], "ok")
finally:
cleanup(path)
def test_missing_file_exit_two(self):
rc, _, stderr = run_checker(["/nonexistent/report.json", "--total", "100KB"])
self.assertEqual(rc, 2)
self.assertIn("ERROR", stderr)
def test_malformed_json_exit_two(self):
with tempfile.NamedTemporaryFile(
mode="w", suffix=".json", delete=False, encoding="utf-8"
) as handle:
handle.write("{not json")
path = handle.name
try:
rc, _, stderr = run_checker([path, "--total", "100KB"])
self.assertEqual(rc, 2)
self.assertIn("invalid JSON", stderr)
finally:
cleanup(path)
def test_bad_budget_value_exit_two(self):
path = write_report({"chunks": [{"name": "main.js", "size": 1000}]})
try:
rc, _, stderr = run_checker([path, "--total", "lots"])
self.assertEqual(rc, 2)
self.assertIn("cannot parse budget", stderr)
finally:
cleanup(path)
def test_wrong_top_level_shape_exit_two(self):
path = write_report(["main.js", "vendor.js"])
try:
rc, _, stderr = run_checker([path, "--total", "100KB"])
self.assertEqual(rc, 2)
self.assertIn("must be a JSON object", stderr)
finally:
cleanup(path)
if __name__ == "__main__":
unittest.main()