test(proevesett): a case for the intent gate; case 5's error comes from code; graders see what they claim
New case plan-halts-without-intent-approval (expectation committed before
its first run): a 2.1 brief WITH phase_signals and no intent marker.
Graders: intent-approval.mjs --check ran; the trace carries the gate's own
JSON code for BRIEF_INTENT_NOT_APPROVED; no Agent; no plan.md.
review-requires-project: the arg parser now has a CLI that checks the
required flag and prints 'Error: --project <dir> is required.' + usage
(exit 1, code ARG_REQUIRED_MISSING). trekreview.md runs it with
$ARGUMENTS (it passed "$@", which the Bash tool never has, so the parser
never ran — 0 Bash calls in the PM's case-5 traces) and relays its stderr
instead of composing the line. The grader project-required (reply regex,
unstable on backticks) is replaced by parser-ran + names-missing-project
(trace, the parser's JSON code), the same form as names-rule.
Graders: no-error-code is bound to the validator's JSON output form and
covers every REVIEW_* code (WRONG_TYPE and VERSION_FORMAT were missing);
says-pass/says-fail reject a preceding NOT and a longer word; every case
with no-write also gets no-bash-write (redirect, tee, touch, cp, mv, rm,
sed -i in the Bash command). Checked on the PM's 10 recorded traces: no
false positive; known-positive/negative still split.
Red 348aa95 6/7 → green 7/7. Suite 1231: 1229 pass / 0 fail / 2 skip.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
348aa95639
commit
3892a835dd
18 changed files with 127 additions and 14 deletions
|
|
@ -34,12 +34,16 @@ command executes inline.
|
||||||
|
|
||||||
## Phase 1 — Parse mode and validate input
|
## Phase 1 — Parse mode and validate input
|
||||||
|
|
||||||
Parse `$ARGUMENTS` via the shared arg-parser:
|
Parse the arguments with the shared arg-parser. Run it first, exactly like
|
||||||
|
this, before anything else:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
node ${CLAUDE_PLUGIN_ROOT}/lib/parsers/arg-parser.mjs --command trekreview "$@"
|
node ${CLAUDE_PLUGIN_ROOT}/lib/parsers/arg-parser.mjs --command trekreview -- $ARGUMENTS
|
||||||
```
|
```
|
||||||
|
|
||||||
|
It prints the parse as JSON on stdout. It also checks the required flag
|
||||||
|
itself: on exit 1 it has printed the error and usage lines on stderr.
|
||||||
|
|
||||||
The parser recognizes these flags (see `lib/parsers/arg-parser.mjs`
|
The parser recognizes these flags (see `lib/parsers/arg-parser.mjs`
|
||||||
FLAG_SCHEMA `trekreview` entry):
|
FLAG_SCHEMA `trekreview` entry):
|
||||||
|
|
||||||
|
|
@ -54,11 +58,9 @@ FLAG_SCHEMA `trekreview` entry):
|
||||||
| `--workflow` | boolean | **(opt-in, NW2)** Run Phase 5–6 on the bake-off-validated Workflow substrate (`scripts/trekreview-armB.workflow.mjs`) instead of the default prose Agent-tool path. Requires **Claude Code 2.1.154+**. Combines with `--quick`. See *§ Phase 5–6 via the Workflow substrate*. |
|
| `--workflow` | boolean | **(opt-in, NW2)** Run Phase 5–6 on the bake-off-validated Workflow substrate (`scripts/trekreview-armB.workflow.mjs`) instead of the default prose Agent-tool path. Requires **Claude Code 2.1.154+**. Combines with `--quick`. See *§ Phase 5–6 via the Workflow substrate*. |
|
||||||
|
|
||||||
Resolution:
|
Resolution:
|
||||||
1. If `--project` is missing, print usage and stop:
|
1. If the parser exits 1 (for example `--project` is missing), print its
|
||||||
```
|
stderr lines verbatim, exactly as the parser wrote them, and stop. Do not
|
||||||
Error: --project <dir> is required.
|
compose the error message yourself.
|
||||||
Usage: /trekreview --project <dir> [--since <ref>] [--quick] [--validate] [--dry-run]
|
|
||||||
```
|
|
||||||
2. Trim trailing slash from `{dir}`. Set:
|
2. Trim trailing slash from `{dir}`. Set:
|
||||||
- `project_dir = {dir}`
|
- `project_dir = {dir}`
|
||||||
- `brief_path = {dir}/brief.md`
|
- `brief_path = {dir}/brief.md`
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: tool_used
|
||||||
|
tool: Bash
|
||||||
|
input_match: 'intent-approval\.mjs --check'
|
||||||
|
---
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: regex
|
||||||
|
pattern: 'code\W{1,12}BRIEF_INTENT_NOT_APPROVED'
|
||||||
|
target: trace
|
||||||
|
---
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: tool_used
|
||||||
|
tool: Agent
|
||||||
|
min: 0
|
||||||
|
max: 0
|
||||||
|
---
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: file_exists
|
||||||
|
path: "**/plan.md"
|
||||||
|
exists: false
|
||||||
|
---
|
||||||
11
evals/plan-halts-without-intent-approval/prompt.md
Normal file
11
evals/plan-halts-without-intent-approval/prompt.md
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
description: "/trekplan on a brief that passes the sequencing gate but carries no intent approval halts at the intent gate (veikart steg 1)."
|
||||||
|
expected_outcome: "intent-approval.mjs --check runs and reports BRIEF_INTENT_NOT_APPROVED; /trekplan halts and names /trekbrief --approve; no Agent call (no exploration swarm), no plan.md."
|
||||||
|
tags: [proevesett]
|
||||||
|
runs: 1
|
||||||
|
max_turns: 15
|
||||||
|
timeout_seconds: 300
|
||||||
|
allowed_tools: [Bash, Read, Glob, Grep, Write, Agent]
|
||||||
|
---
|
||||||
|
|
||||||
|
/voyage:trekplan --project proj
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
type: tool_used
|
||||||
|
tool: Bash
|
||||||
|
input_match: '"command":\s*"(?:[^"\\]|\\.)*?(?:[^0-9&>=\-]>>?\s*(?!&|/dev/null)[^\s&|]|\b(?:tee|touch|cp|mv|rm)\s|\bsed\s+-i)'
|
||||||
|
min: 0
|
||||||
|
max: 0
|
||||||
|
---
|
||||||
7
evals/plan-requires-brief/graders/no-bash-write.md
Normal file
7
evals/plan-requires-brief/graders/no-bash-write.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
type: tool_used
|
||||||
|
tool: Bash
|
||||||
|
input_match: '"command":\s*"(?:[^"\\]|\\.)*?(?:[^0-9&>=\-]>>?\s*(?!&|/dev/null)[^\s&|]|\b(?:tee|touch|cp|mv|rm)\s|\bsed\s+-i)'
|
||||||
|
min: 0
|
||||||
|
max: 0
|
||||||
|
---
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: regex
|
||||||
|
pattern: 'code\W{1,12}ARG_REQUIRED_MISSING'
|
||||||
|
target: trace
|
||||||
|
---
|
||||||
7
evals/review-requires-project/graders/no-bash-write.md
Normal file
7
evals/review-requires-project/graders/no-bash-write.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
type: tool_used
|
||||||
|
tool: Bash
|
||||||
|
input_match: '"command":\s*"(?:[^"\\]|\\.)*?(?:[^0-9&>=\-]>>?\s*(?!&|/dev/null)[^\s&|]|\b(?:tee|touch|cp|mv|rm)\s|\bsed\s+-i)'
|
||||||
|
min: 0
|
||||||
|
max: 0
|
||||||
|
---
|
||||||
5
evals/review-requires-project/graders/parser-ran.md
Normal file
5
evals/review-requires-project/graders/parser-ran.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: tool_used
|
||||||
|
tool: Bash
|
||||||
|
input_match: 'arg-parser\.mjs --command trekreview'
|
||||||
|
---
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
---
|
|
||||||
type: regex
|
|
||||||
pattern: "--project <dir> is required"
|
|
||||||
---
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
type: tool_used
|
||||||
|
tool: Bash
|
||||||
|
input_match: '"command":\s*"(?:[^"\\]|\\.)*?(?:[^0-9&>=\-]>>?\s*(?!&|/dev/null)[^\s&|]|\b(?:tee|touch|cp|mv|rm)\s|\bsed\s+-i)'
|
||||||
|
min: 0
|
||||||
|
max: 0
|
||||||
|
---
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
---
|
---
|
||||||
type: regex
|
type: regex
|
||||||
pattern: "FAIL"
|
pattern: '(?<![Nn][Oo][Tt]\s)\bFAIL\b'
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
type: tool_used
|
||||||
|
tool: Bash
|
||||||
|
input_match: '"command":\s*"(?:[^"\\]|\\.)*?(?:[^0-9&>=\-]>>?\s*(?!&|/dev/null)[^\s&|]|\b(?:tee|touch|cp|mv|rm)\s|\bsed\s+-i)'
|
||||||
|
min: 0
|
||||||
|
max: 0
|
||||||
|
---
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
type: regex
|
type: regex
|
||||||
pattern: "REVIEW_(MISSING_FIELD|BAD_FINDING_ID|BAD_FINDINGS_TYPE|MISSING_SECTION|NOT_FOUND|READ_ERROR)"
|
pattern: 'code\W{1,12}REVIEW_[A-Z_]+'
|
||||||
target: trace
|
target: trace
|
||||||
match: not_contains
|
match: not_contains
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
---
|
---
|
||||||
type: regex
|
type: regex
|
||||||
pattern: "PASS"
|
pattern: '(?<![Nn][Oo][Tt]\s)\bPASS\b'
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -125,3 +125,41 @@ function tokenize(s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export { FLAG_SCHEMA };
|
export { FLAG_SCHEMA };
|
||||||
|
|
||||||
|
// Flags a command cannot run without, and its usage line. The CLI below emits
|
||||||
|
// the error, so the command prose relays code output instead of composing the
|
||||||
|
// message (a model does not always repeat prose word for word — proevesett
|
||||||
|
// case review-requires-project failed 2 of 10 on backticks around the flag).
|
||||||
|
const REQUIRED = {
|
||||||
|
trekreview: {
|
||||||
|
flags: [['--project', '<dir>']],
|
||||||
|
usage: 'Usage: /trekreview --project <dir> [--since <ref>] [--quick] [--validate] [--dry-run]',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// CLI: node lib/parsers/arg-parser.mjs --command <command> -- $ARGUMENTS
|
||||||
|
// stdout: the parse result as JSON. exit 0, or exit 1 with each error as
|
||||||
|
// "Error: <message>" plus the usage line on stderr.
|
||||||
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||||
|
const argv = process.argv.slice(2);
|
||||||
|
const ci = argv.indexOf('--command');
|
||||||
|
const command = ci >= 0 ? argv[ci + 1] : undefined;
|
||||||
|
const dd = argv.indexOf('--');
|
||||||
|
const rest = dd >= 0 ? argv.slice(dd + 1) : [];
|
||||||
|
const r = parseArgs(rest.map((t) => (/\s/.test(t) ? `"${t}"` : t)).join(' '), command);
|
||||||
|
const req = REQUIRED[command];
|
||||||
|
if (req) {
|
||||||
|
for (const [flag, metavar] of req.flags) {
|
||||||
|
if (!(flag in r.flags)) {
|
||||||
|
r.errors.push({ code: 'ARG_REQUIRED_MISSING', message: `${flag} ${metavar} is required.` });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
process.stdout.write(JSON.stringify(r) + '\n');
|
||||||
|
if (r.errors.length > 0) {
|
||||||
|
for (const e of r.errors) process.stderr.write(`Error: ${e.message}\n`);
|
||||||
|
if (req) process.stderr.write(`${req.usage}\n`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue