score.sh 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #!/bin/bash
  2. # Score iterate/SKILL.md on structural quality metrics.
  3. # Output: a single integer score (higher = better, max ~100).
  4. #
  5. # This scorer is deliberately hard to max out.
  6. # It rewards clarity, completeness, and economy of expression.
  7. FILE="${1:-skills/iterate/SKILL.md}"
  8. SCORE=0
  9. if [ ! -f "$FILE" ]; then
  10. echo "0"
  11. exit 0
  12. fi
  13. CONTENT=$(cat "$FILE")
  14. LINES=$(wc -l < "$FILE" | tr -d ' ')
  15. WORDS=$(wc -w < "$FILE" | tr -d ' ')
  16. # --- STRUCTURE (25 pts) ---
  17. # Frontmatter fields (10 pts)
  18. echo "$CONTENT" | head -1 | grep -q "^---" && {
  19. echo "$CONTENT" | grep -q "^name:" && SCORE=$((SCORE + 2))
  20. echo "$CONTENT" | grep -q "^description:" && SCORE=$((SCORE + 3))
  21. echo "$CONTENT" | grep -qi "triggers\? on:" && SCORE=$((SCORE + 2))
  22. echo "$CONTENT" | grep -q "^allowed-tools:" && SCORE=$((SCORE + 3))
  23. }
  24. # Required sections present (15 pts, 2.5 each - using 2+3 alternating)
  25. for section in "## Setup" "## The Loop" "## Rules" "## Results" "## Adapt" "## Guard"; do
  26. echo "$CONTENT" | grep -qi "$section" && SCORE=$((SCORE + 2))
  27. done
  28. # Bonus for usage examples section
  29. echo "$CONTENT" | grep -qi "## Usage\|## Example" && SCORE=$((SCORE + 3))
  30. # --- LOOP COMPLETENESS (20 pts) ---
  31. # All 8 steps of the loop referenced
  32. for step in "REVIEW\|Review\|review" "IDEATE\|Ideate\|ideate" "MODIFY\|Modify\|modify" \
  33. "COMMIT\|Commit\|commit" "VERIFY\|Verify\|verify" "DECIDE\|Decide\|decide" \
  34. "LOG\|Log\|log" "REPEAT\|Repeat\|repeat"; do
  35. echo "$CONTENT" | grep -q "$step" && SCORE=$((SCORE + 2))
  36. done
  37. # Rollback strategy mentioned (4 pts)
  38. echo "$CONTENT" | grep -q "git revert" && SCORE=$((SCORE + 2))
  39. echo "$CONTENT" | grep -q "git reset\|fallback\|fall back" && SCORE=$((SCORE + 2))
  40. # --- CLARITY (20 pts) ---
  41. # Results.tsv example with actual data rows (5 pts)
  42. tsv_rows=$(echo "$CONTENT" | grep -c "^[0-9].* .* .*keep\|^[0-9].* .* .*discard\|^[0-9].* .* .*baseline\|^[0-9].* .* .*crash")
  43. if [ "$tsv_rows" -ge 3 ]; then
  44. SCORE=$((SCORE + 5))
  45. elif [ "$tsv_rows" -ge 1 ]; then
  46. SCORE=$((SCORE + 2))
  47. fi
  48. # Domain adaptation table with 5+ examples (5 pts)
  49. domain_rows=$(echo "$CONTENT" | grep -c "^|.*|.*|.*higher\|^|.*|.*|.*lower")
  50. if [ "$domain_rows" -ge 5 ]; then
  51. SCORE=$((SCORE + 5))
  52. elif [ "$domain_rows" -ge 3 ]; then
  53. SCORE=$((SCORE + 3))
  54. fi
  55. # Progress output format shown (5 pts)
  56. echo "$CONTENT" | grep -q "Iteration [0-9]" && SCORE=$((SCORE + 3))
  57. echo "$CONTENT" | grep -q "=== Iterate Complete\|summary" && SCORE=$((SCORE + 2))
  58. # Inline config example with all 5 fields (5 pts)
  59. example_fields=0
  60. echo "$CONTENT" | grep -q "^Goal:" && example_fields=$((example_fields + 1))
  61. echo "$CONTENT" | grep -q "^Scope:" && example_fields=$((example_fields + 1))
  62. echo "$CONTENT" | grep -q "^Verify:" && example_fields=$((example_fields + 1))
  63. echo "$CONTENT" | grep -q "^Direction:" && example_fields=$((example_fields + 1))
  64. echo "$CONTENT" | grep -q "^Guard:" && example_fields=$((example_fields + 1))
  65. if [ "$example_fields" -ge 5 ]; then
  66. SCORE=$((SCORE + 5))
  67. elif [ "$example_fields" -ge 3 ]; then
  68. SCORE=$((SCORE + 2))
  69. fi
  70. # --- ECONOMY (20 pts) ---
  71. # Line count: sweet spot 150-250 (10 pts)
  72. if [ "$LINES" -ge 150 ] && [ "$LINES" -le 250 ]; then
  73. SCORE=$((SCORE + 10))
  74. elif [ "$LINES" -ge 120 ] && [ "$LINES" -le 300 ]; then
  75. SCORE=$((SCORE + 6))
  76. elif [ "$LINES" -ge 80 ] && [ "$LINES" -le 400 ]; then
  77. SCORE=$((SCORE + 3))
  78. fi
  79. # Word economy: under 2500 words (5 pts)
  80. if [ "$WORDS" -le 1800 ]; then
  81. SCORE=$((SCORE + 5))
  82. elif [ "$WORDS" -le 2500 ]; then
  83. SCORE=$((SCORE + 3))
  84. elif [ "$WORDS" -le 3500 ]; then
  85. SCORE=$((SCORE + 1))
  86. fi
  87. # No TODO/FIXME/HACK/XXX markers (5 pts)
  88. todo_count=$(echo "$CONTENT" | grep -ci "TODO\|FIXME\|HACK\|XXX")
  89. if [ "$todo_count" -eq 0 ]; then
  90. SCORE=$((SCORE + 5))
  91. fi
  92. # --- HYGIENE (15 pts) ---
  93. # Attribution to Karpathy (3 pts)
  94. echo "$CONTENT" | grep -qi "karpathy" && SCORE=$((SCORE + 3))
  95. # AskUserQuestion mentioned for missing config (3 pts)
  96. echo "$CONTENT" | grep -q "AskUserQuestion" && SCORE=$((SCORE + 3))
  97. # Bounded mode (Iterations: N) documented (3 pts)
  98. echo "$CONTENT" | grep -q "Iterations:" && SCORE=$((SCORE + 3))
  99. # "Never stop" / "never ask" principle (3 pts)
  100. echo "$CONTENT" | grep -qi "never stop\|never ask" && SCORE=$((SCORE + 3))
  101. # git add specific files warning (no -A) (3 pts)
  102. echo "$CONTENT" | grep -q "git add -A\|never.*git add" && SCORE=$((SCORE + 3))
  103. echo "$SCORE"