Skip to content

Commit 60df1ac

Browse files
authored
docs(test-classifier): update onboarding to the passthrough wrapper + complete --help (#63)
The LOCAL_TEST_CLASSIFIER.md onboarding doc still shipped the old 22-line three-branch zshrc function, which a developer would paste and get the stale wrapper that drifts on re-vendor. Update it to the 5-line passthrough that matches the dispatcher now owning all arg defaulting (#62), and describe the no-arg/bare-ref/flags behavior as the dispatcher's. Since the doc now points developers at `test-classifier --help`, make that help actually complete: add an AI_REVIEW_HELP_ADDENDUM hook to the shared lib's print_help (printed only if a dispatcher sets it — security dispatcher unaffected) and have the test-classifier dispatcher document its own flags (--pr/--post-comment/--submit/--gate/--json-only), the no-arg/bare-ref defaults, and AI_RUN_SUITE / metricsai env. Also fix the troubleshooting row for the dropped `[ -x ]` guard: a missing dispatcher now surfaces as the shell's own no-such-file/permission-denied.
1 parent d31da74 commit 60df1ac

3 files changed

Lines changed: 51 additions & 47 deletions

File tree

testing/classifier/.skills/_lib/ai-classifier-dispatch.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@ Exit codes:
218218
1 Unrecoverable runtime error (or --gate set and result is CLASSIFIED)
219219
2 Configuration error (AI_REVIEW_TOOL unset / invalid; bad flags)
220220
EOF
221+
# A dispatcher can document its own flags/defaults by setting AI_REVIEW_HELP_ADDENDUM
222+
# before calling this. Printed verbatim after the shared help above.
223+
if [[ -n "${AI_REVIEW_HELP_ADDENDUM:-}" ]]; then
224+
printf '\n%s\n' "${AI_REVIEW_HELP_ADDENDUM}"
225+
fi
221226
}
222227

223228
# ── AI_REVIEW_TOOL validation ───────────────────────────────────────────────

testing/classifier/.skills/test-classifier/scripts/test-classifier-dispatcher.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,29 @@ source "${LIB_PATH}"
377377

378378
# --help was requested during arg parsing above; the lib (which defines the help
379379
# text) is now loaded, so emit it and exit before any PR discovery / AI call.
380+
# Document the dispatcher's own flags + defaulting via the lib's addendum hook —
381+
# the shared --against/--unpushed/--dry-run/etc. are already covered by the lib.
380382
if (( WANT_HELP == 1 )); then
383+
read -r -d '' AI_REVIEW_HELP_ADDENDUM <<'HELP_ADDENDUM' || true
384+
test-classifier options (in addition to the shared options above):
385+
--pr <number> Explicit PR number for posting (overrides auto-discovery).
386+
--post-comment Post ONE PR comment with the verdicts + a 👍/👎 ask.
387+
Omit for a local report-only run (prints, posts nothing).
388+
--submit Implies --post-comment; then (interactive only) prompts
389+
"Was this helpful?" and appends one Testing Events row.
390+
--gate Exit 1 when the result is CLASSIFIED (CI-blocking mode).
391+
--json-only Print only the machine-readable JSON block.
392+
393+
Defaults when no diff-range/PR selector is given:
394+
(no arguments) → --unpushed (committed + staged; local, report-only).
395+
a bare ref → --against <ref>, e.g. test-classifier origin/main
396+
397+
Environment:
398+
AI_RUN_SUITE=1 Run the suite (OBSERVED) instead of inferring from the
399+
diff. Prefix it: AI_RUN_SUITE=1 test-classifier --pr 42
400+
METRICSAI_WEBHOOK_URL / METRICSAI_WEBHOOK_KEY
401+
Required only by --submit to append the Testing Events row.
402+
HELP_ADDENDUM
381403
ai_review::print_help
382404
exit 0
383405
fi

testing/classifier/docs/LOCAL_TEST_CLASSIFIER.md

Lines changed: 24 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -61,57 +61,34 @@ it's only needed for the PR-based modes (`--pr` / auto-discovery / `--post-comme
6161
Paste this block into `~/.zshrc`, then `source ~/.zshrc` (or open a new shell):
6262

6363
```zsh
64-
# AI test classifier.
65-
# <no arg> → classify everything not yet pushed (committed + staged); report-only
66-
# <ref> → classify the committed range <ref>..HEAD; report-only
67-
# <flags...> → passed straight to the dispatcher. This is how you post to a PR:
68-
# test-classifier --pr 42 --post-comment (or --post-comment to
69-
# auto-discover the current branch's PR). Needs gh authed.
70-
# Prefix with AI_RUN_SUITE=1 to run the suite locally (OBSERVED) instead of
71-
# inferring from the diff: AI_RUN_SUITE=1 test-classifier
64+
# AI test classifier. Run `test-classifier --help` for usage.
7265
test-classifier() {
73-
local root disp
74-
root="$(git rev-parse --show-toplevel 2>/dev/null)" \
66+
local root; root="$(git rev-parse --show-toplevel 2>/dev/null)" \
7567
|| { echo "✗ not inside a git repository"; return 1; }
76-
disp="$root/testing/classifier/.skills/test-classifier/scripts/test-classifier-dispatcher.sh"
77-
[ -x "$disp" ] \
78-
|| { echo "✗ test-classifier dispatcher not found/executable: $disp"; return 1; }
79-
if [ "$#" -eq 0 ]; then
80-
# No args → classify everything not yet pushed (committed + staged).
81-
echo "▶ test-classifier: all not-yet-pushed changes (committed + staged)"
82-
"$disp" --unpushed
83-
elif [ "${1#-}" != "$1" ]; then
84-
# First arg is a flag (starts with -) → pass everything straight through.
85-
# This is how you post to a PR: test-classifier --pr 42 --post-comment
86-
"$disp" "$@"
87-
else
88-
# First arg is a bare ref → --against <ref>; pass any remaining flags too.
89-
local ref="$1"; shift
90-
echo "▶ test-classifier: ${ref}..HEAD (committed range)"
91-
"$disp" --against "$ref" "$@"
92-
fi
68+
"$root/testing/classifier/.skills/test-classifier/scripts/test-classifier-dispatcher.sh" "$@"
9369
}
9470
```
9571

96-
What the function does:
97-
98-
1. **Confirms you're in a git repo**`git rev-parse --show-toplevel` doubles as
99-
the repo check (empty → not a repo) and gives the authoritative root, so the
100-
function works from any subdirectory.
101-
2. **Locates the dispatcher** under `testing/classifier/` and confirms it's
102-
executable.
103-
3. **Runs the classifier** by calling the dispatcher:
104-
- **no argument**`--unpushed`: everything not yet pushed (committed +
105-
staged). The base is your branch's upstream, falling back to the merge-base
106-
with the remote default branch. If neither can be determined (e.g. a
107-
brand-new branch with no remote), it errors and asks for an explicit ref
108-
rather than silently classifying less than you expect.
109-
- **a bare ref**`--against <ref>`: the committed range `<ref>..HEAD`.
110-
- **anything starting with `-`** → passed straight through to the dispatcher.
111-
This is how you post to a PR — `test-classifier --pr 42 --post-comment`
112-
(or just `--post-comment` to auto-discover the current branch's PR), plus
113-
any other dispatcher flag (`--dry-run`, `--json-only`, …). You can combine a
114-
ref with flags too: `test-classifier origin/main --post-comment`.
72+
The function is a thin passthrough: it finds the repo root and forwards every
73+
argument to the dispatcher. **All argument handling lives in the dispatcher**
74+
(versioned with the bundle), so the function never goes stale when you re-vendor.
75+
It forwards args verbatim, and the dispatcher applies these defaults:
76+
77+
- **no argument**`--unpushed`: everything not yet pushed (committed +
78+
staged). The base is your branch's upstream, falling back to the merge-base
79+
with the remote default branch. If neither can be determined (e.g. a
80+
brand-new branch with no remote), it errors and asks for an explicit ref
81+
rather than silently classifying less than you expect.
82+
- **a bare ref** (e.g. `test-classifier origin/main`) → `--against <ref>`: the
83+
committed range `<ref>..HEAD`.
84+
- **any flags** → used directly. This is how you post to a PR —
85+
`test-classifier --pr 42 --post-comment` (or just `--post-comment` to
86+
auto-discover the current branch's PR), plus any other dispatcher flag
87+
(`--dry-run`, `--json-only`, …). You can combine a ref with flags too:
88+
`test-classifier origin/main --post-comment`.
89+
90+
Prefix `AI_RUN_SUITE=1` to run the suite locally (OBSERVED) instead of inferring
91+
from the diff: `AI_RUN_SUITE=1 test-classifier`.
11592

11693
---
11794

@@ -232,7 +209,7 @@ run (Path B) is still the recorded, metrics-feeding pass; this is your preview.
232209
| Symptom | Cause / fix |
233210
|---|---|
234211
| `✗ not inside a git repository` | You're not in a git work tree. `cd` into the repo. |
235-
| `✗ test-classifier dispatcher not found/executable` | The bundle isn't installed under `testing/classifier/`, or the script lost its `+x` bit. Re-install / `chmod +x`. |
212+
| `no such file or directory` / `permission denied` on the dispatcher path | The bundle isn't installed under `testing/classifier/`, or the script lost its `+x` bit. Re-install / `chmod +x`. |
236213
| `--unpushed: couldn't determine what's been pushed` | No upstream and no remote default branch (e.g. brand-new branch, no remote). Pass an explicit base: `test-classifier origin/main`. |
237214
| `AI_REVIEW_TOOL … not set` | Export `AI_REVIEW_TOOL=claude` (or `codex`/`copilot`); see `README.md`. |
238215
| Classification seems to miss recent edits | `--unpushed` excludes *unstaged* changes. `git add` or commit them first. |

0 commit comments

Comments
 (0)