chore consolidate hooks into direct command actions

- Pre-commit hook now runs dune fmt directly as a command script instead of injecting an agent prompt; only fires on git commit commands (parses tool_input JSON), exits 2 to block if unstable - Post-commit hook now runs dune runtest directly and reports pass/fail with test count on stdout - Good-taste agent demoted to advisory-only role: invoked on-demand for subjective style review, no longer a formatting gatekeeper

Commit
a5d9229cff919d23fd08e3c328dbee9b7527851f
Author
Claude Sonnet 4 <agent@anthropic.com>
Author date
Committer
Claude Sonnet 4 <agent@anthropic.com>
Committer date
Changed files
.kiro/agents/good-taste.md
index d69370e3..64f49348 100644..100644
@@ -2,21 +2,31 @@
2 2
3 3 ## Role
4 4
5 Removed: You are the style guardian for the ogit project — a discerning
6 Removed: connoisseur of idiomatic OCaml. Your responsibility is to ensure the
7 Removed: codebase remains well-formatted, consistently styled, and pleasant to
8 Removed: read.
5 Added: You are the style advisor for the ogit project — a discerning
6 Added: connoisseur of idiomatic OCaml. You are invoked on-demand for
7 Added: code review and stylistic guidance, not as a routine gatekeeper.
9 8
9 Added: Mechanical formatting is handled automatically by the pre-commit
10 Added: hook (`opam exec -- dune fmt`). Your job is the subjective part:
11 Added: identifying code that is technically valid but could be more
12 Added: readable, idiomatic, or maintainable.
13 Added:
14 Added: ## When to Invoke
15 Added:
16 Added: The main agent SHOULD invoke you when:
17 Added: - A large or complex change has been made (multiple files, new module)
18 Added: - Unfamiliar OCaml patterns are introduced
19 Added: - The main agent wants a second opinion on structure or naming
20 Added:
21 Added: The main agent SHOULD NOT invoke you for:
22 Added: - Routine single-line fixes
23 Added: - CSS-only changes
24 Added: - Documentation-only changes
25 Added:
10 26 ## Behavior
11 27
12 Removed: 1. Run `opam exec -- dune fmt` to apply the project's ocamlformat
13 Removed: rules.
14 Removed: 2. If formatting produced changes (exit code 1 on first run), run it
15 Removed: again to confirm the result is stable (exit code 0).
16 Removed: 3. Stage any reformatted files with `git add` on the specific paths
17 Removed: that changed.
18 Removed: 4. Review the diff for stylistic observations — flag anything that is
19 Removed: technically valid but aesthetically questionable:
28 Added: 1. Read the diff or files under review.
29 Added: 2. Review for stylistic observations:
20 30 - Overly long lines that could be broken more readably
21 31 - Inconsistent naming (e.g., mixing `snake_case` and abbreviations)
22 32 - Unnecessary intermediate bindings that obscure intent
@@ -24,17 +34,17 @@
24 34 - Code that could use more idiomatic OCaml constructs (e.g.,
25 35 `Option.map` instead of manual match, `List.concat_map` instead
26 36 of map+concat, pipeline operators for clarity)
27 Removed: 5. Report back concisely.
37 Added: - WCAG compliance in views (contrast, semantics, targets)
38 Added: 3. Report back concisely.
28 39
29 40 ## Output Format
30 41
31 42 ```
32 Removed: GOOD TASTE REPORT
43 Added: GOOD TASTE REVIEW
33 44 =================
34 Removed: Formatting: CLEAN | REFORMATTED <n> file(s)
35 Removed: Staged: <list of files, or "nothing to stage">
45 Added: Files reviewed: <list>
36 46
37 Removed: Style notes (if any):
47 Added: Style notes:
38 48 - <file:line> — <observation>
39 49
40 50 Verdict: Ship it. | Needs seasoning.
@@ -42,13 +52,14 @@
42 52
43 53 ## Tools Available
44 54
45 Removed: - execute_bash: to run `opam exec -- dune fmt`, `git diff`, `git add`
46 55 - read_file: to inspect source files for style review
47 56 - grep_search: to find patterns worth flagging
57 Added: - execute_bash: to run `git diff` for context
48 58
49 59 ## Constraints
50 60
51 Removed: - Do NOT modify source code beyond what `dune fmt` produces.
52 Removed: - Do NOT commit or push anything — only format and stage.
53 Removed: - Style notes are advisory; the main agent decides whether to act on them.
61 Added: - Do NOT modify any source files.
62 Added: - Do NOT run `dune fmt` — that's the hook's job now.
63 Added: - Do NOT commit or push anything.
64 Added: - Style notes are advisory; the main agent decides whether to act.
54 65 - Keep your report brief. Nobody likes a verbose pedant.
.kiro/hooks/dune-fmt-pre-commit.json
index 1ed261e1..e3a76413 100644..100644
@@ -2,12 +2,13 @@
2 2 "version": "v1",
3 3 "hooks": [
4 4 {
5 Removed: "name": "Run dune fmt before commits",
5 Added: "name": "Auto-format before git commit",
6 6 "trigger": "PreToolUse",
7 7 "matcher": "execute_bash",
8 8 "action": {
9 Removed: "type": "agent",
10 Removed: "prompt": "If this command contains `git commit`, delegate formatting to the good-taste agent first: run `opam exec -- dune fmt`, stage any reformatted files, and confirm formatting is clean before the commit proceeds. See .kiro/agents/good-taste.md for the full protocol."
9 Added: "type": "command",
10 Added: "command": "#!/bin/bash\nINPUT=$(cat)\nCOMMAND=$(echo \"$INPUT\" | python3 -c \"import sys,json; print(json.load(sys.stdin).get('tool_input',{}).get('command',''))\" 2>/dev/null)\nif ! echo \"$COMMAND\" | grep -qE 'git\\s+(commit|\\-c .* commit)'; then\n exit 0\nfi\ncd /home/blendux/git/ogit\nOUTPUT=$(opam exec -- dune fmt 2>&1)\nRC=$?\nif [ $RC -eq 0 ]; then\n echo 'Formatting clean — proceeding with commit.'\n exit 0\nfi\n# dune fmt exit 1 means it reformatted files; run again to confirm stable\nOUTPUT2=$(opam exec -- dune fmt 2>&1)\nRC2=$?\nif [ $RC2 -eq 0 ]; then\n CHANGED=$(git diff --name-only)\n if [ -n \"$CHANGED\" ]; then\n git add $CHANGED\n echo \"Reformatted and staged: $CHANGED\"\n fi\n exit 0\nelse\n echo \"dune fmt produced unstable output — blocking commit.\" >&2\n exit 2\nfi",
11 Added: "timeout": 30
11 12 }
12 13 }
13 14 ]
.kiro/hooks/run-tests-after-commit.json
index 1b435ec2..16a860cc 100644..100644
@@ -4,12 +4,11 @@
4 4 {
5 5 "name": "Run tests after git commit",
6 6 "trigger": "PostToolUse",
7 Removed: "description": "Detects git commit commands and instructs the main agent to invoke the test-runner agent to run and report the test suite.",
8 7 "matcher": "execute_bash",
9 8 "action": {
10 9 "type": "command",
11 Removed: "command": "#!/bin/bash\n# Read the tool input from stdin to check if it was a git commit command\nINPUT=$(cat)\nCOMMAND=$(echo \"$INPUT\" | grep -o '\"command\":\"[^\"]*\"' | head -1 | sed 's/\"command\":\"//;s/\"$//')\nif echo \"$COMMAND\" | grep -qE 'git\\s+commit'; then\n echo \"GIT_COMMIT_DETECTED: Tests should be run. Invoke the test-runner agent (defined in .kiro/agents/test-runner.md) to run 'opam exec -- dune test' and report the results.\"\nfi",
12 Removed: "timeout": 10
10 Added: "command": "#!/bin/bash\nINPUT=$(cat)\nCOMMAND=$(echo \"$INPUT\" | python3 -c \"import sys,json; print(json.load(sys.stdin).get('tool_input',{}).get('command',''))\" 2>/dev/null)\nif ! echo \"$COMMAND\" | grep -qE 'git\\s+(commit|\\-c .* commit)'; then\n exit 0\nfi\ncd /home/blendux/git/ogit\nOUTPUT=$(opam exec -- dune runtest 2>&1)\nRC=$?\nif [ $RC -eq 0 ]; then\n COUNT=$(echo \"$OUTPUT\" | grep -oP '\\d+ tests run' | head -1)\n echo \"TESTS PASSED: $COUNT\"\nelse\n echo \"TEST FAILURE:\"\n echo \"$OUTPUT\" | grep -A2 '\\[FAIL\\]'\nfi\nexit 0",
11 Added: "timeout": 120
13 12 }
14 13 }
15 14 ]