Repository navigation
Review objections must run: --review-executable - #28
solvyxtech wants to merge 3 commits into
Conversation
solvyxtech
left a comment
There was a problem hiding this comment.
Grok review: requesting changes (posted as a comment, since this account authored the PR and GitHub won't let it request changes on its own PR)
I reviewed the PR's own commit 3c1d9b6 against #27 (claude/hide-checks). The stacked #24–#27 commits are reviewed on their own PRs.
Pairing rules: these are clean. No subscription backends come back, and there are no competitor names in product copy. The "Grok worker" mention in the review.ts comment and the PR body is a measurement note about our own retained provider, so it's fine. Fine-tune is fine too: objections rides on index rows and journal entries, and finetune/extract.mjs already drops those whole rows when the worker or the judge is xAI or Grok.
Tests (run on my box): tsc --noEmit is clean, and review-executable.test.ts passes 11 of 11. The full test-run.mjs gave 1987 pass, 1 fail and 6 cancelled out of 1994. All of those are environmental and also happen on the #27 base:
- The 6 cancelled are in
local-ask.test.ts("Promise resolution is still pending"). The same 6 cancel onclaude/hide-checks. - The 1 fail is
hidden-checks-withheld.test.ts:242, "Committer identity unknown". That test is from #27 and assumes a global git identity. Please setuser.name/user.emailin the temp repo so it passes on clean CI and boxes.
Blocking
- Reviewer commands can run on the live tree.
runObjectiondoescwd: copy?.dir ?? this.cwd.copyTreereturnsnullfor a tree over the file or byte limit, for a.gitfile (worktrees and submodules), or whenmkdtempfails. In any of those cases a model-written command runs in the real project, and only the L15 denylist stands in the way. That's riskier than drafted checks: the reviewer reads the task text, which may be untrusted, and its commands exist to probe the work, not to protect it. Please fail closed. When there's no copy andMAAT_CHECK_COPYisn't explicitly0, recorddid-not-run("no throwaway copy of the tree") and don't run it. A test withmaxFilesforced low would cover it. - Merge conflicts with the base. Against current
claude/sync-local-work(4d94f37, "OpenCode: Zen models only"), there are conflicts insrc/acp.tsandsrc/opencode.ts. Those come from the stacked #24–#26 integration merges, not this commit, but the PR can't land until the stack is rebased on the updated base. No CI ran on this branch either, so please make surenpm run checkis green after the rebase.
Non-blocking
REVIEW_SYSTEM.split("\n").slice(0, -4)quietly depends on the last four lines ofREVIEW_SYSTEMbeing the JSON-format block. One edit there and the executable prompt ends up with two reply formats. I'd build both prompts from a sharedREVIEW_RULESarray, or add a test asserting the executable prompt has exactly oneReply with JSON only:.- Any non-zero exit counts as "demonstrated", so
falseorexit 1substantiates any objection. That's acceptable for now because this mode can only remove vetoes compared with before, never add one. Still, the PR body and CLI help shouldn't suggest the command is verified to be about the objection. One line saying this would help. - The
unsubstantiated objection ...info lines and the[shown by ...]evidence carry the reviewer's command and output, and those aren't run throughmaskWithheld. The journal and receipts are masked, and so is the nudge. Can aninfoevent reach the worker or an ACP client while hidden checks are withheld? If it can, mask those lines too. amendReviewrewritesindex.jsonlwith a plainwriteFileSync, asamendTierdoes. That's fine as precedent, but two amends per receipt now touch the index in the same turn. If there's an atomic-write helper (tmp file then rename), both should use it.- Cost: each distinct command gets a fresh
copyTree, run one after another. That's up to 12 copies and up to 12 × 30 s with no deadline. You could copy once per review and reuse it, since the commands are linted read-only, or bound the total time of a review. --review-executablehas no CHANGELOG or docs entry yet.
Nice design overall. Mechanically demoting false prose vetoes is exactly the "model finds, something mechanical judges" line, and the default-off path really is byte-identical in the tests. Fix the live-tree fallback and the rebase, and I'll approve.
|
Rebased onto the new base. It sits on #27 now, which is on #26. How each review item was handled. First review
Second review (bake-off)
|
3c1d9b6 to
1f82ebd
Compare
Measured 2026-10-07 (Grok worker, qwen3-coder-30b-a3b judge, 20 tasks): 18 runs passed the hidden grader but only 2 were verified, and in 5 of the 16 unverified passes the review's objection was false (a misread right-aligned column, an invented email rule, "tests were failing but now pass"). A weak reviewer's prose vetoed correct work. With MAAT_REVIEW_EXECUTABLE=1 or --review-executable, every objection must carry a read-only shell command that demonstrates it: the command exits non-zero, or prints the offending line it names in "shows". Maat lints it with L15 (a command that would change the work is never run), runs it on a throwaway copy of the tree, and counts the objection only when it ran and showed the failure. A missing command, a lint failure, a command that passes, cannot open its input, or times out is recorded as an unsubstantiated objection and vetoes nothing. The grounded-quote rule, vote counting and tier rules are unchanged: this can only remove a contradiction, never make a check assert a value. Objections with their command and result go to the journal's review entry, job_end, an info line each, and the receipt index row; the nudge to the worker is masked while hidden check commands are withheld. With the option off the prompt, the review and every record are as before.
copyTree returns null for a worktree's .git pointer, a tree over the copy limits, or no temp dir, and runObjection then ran the reviewer's command in the project itself. A reviewer's command is written by a model that read the task text, so it now fails closed: with no throwaway copy (or MAAT_CHECK_COPY=0) the command is not run and the objection is did-not-run, "could not be run safely", not counted. - Unsubstantiated-objection info lines are masked of hidden commands. - The help and CHANGELOG say a non-zero exit shows the command failed, not that it tested what the objection says. - A test pins one reply format in the executable review prompt.
…ay whether they were checked - runObjection ran the reviewer's command with Maat's whole environment, API keys included, and the worker can steer the reviewer through its claim. It now gets a credential-free environment (no *KEY/*TOKEN/ *SECRET/*PASSWORD names, no provider or Maat variables), Ctrl-C's signal, and is not run at all once the time budget is spent. - A bare false or exit 1 counted as demonstrated. A failure now counts only from a command that reads the work: names the project (.), a path in it or shaped like one, or runs its tests or build; otherwise the objection is off-the-work. A printed line that is in the command itself (echo) shows nothing either. - Each objection carries a standing: counted, refuted (the reviewer was wrong) or unchecked (it could not be run); the review counts the unchecked ones, and the info line says which it was.
1f82ebd to
6f2029e
Compare
Builds on #27 (claude/hide-checks), which builds on #24–#26. It uses #27's lint L15 (
checkMutates), its copy-on-run tree (copyTree) and its hidden-command masking.Why
On 2026-10-07 (Grok worker, NUC qwen3-coder-30b-a3b judge, 20 tasks), 18 runs passed the hidden grader but only 2 were verified. In 5 of the 16 unverified passes, the independent review's objection was false: a misread right-aligned column, an invented email rule, and "tests were failing but now pass". A weak reviewer's prose objections were vetoing correct work.
What
MAAT_REVIEW_EXECUTABLE=1/--review-executable(off by default):commandwith each violation. The command must be read-only. It demonstrates the violation by exiting non-zero, or by printing the offending line, which the reviewer names inshows(an exact whole-line match).reviewentry, injob_end.review.objections, as one info line per unsubstantiated objection, and on the receipt index row (amendReview). The nudge to the worker is masked while hidden check commands are withheld.Tests
test/review-executable.test.ts(11 tests):showsline-match is enforced.npm run check: 1994 tests pass, e2e PASS and self-check PASS, run with ~/.local/bin removed from PATH.