Flash is the default model; --m3 falls back to M3, --effort overrides. Defaults: max (review-minimax, review-loop, mm-worktree-task), medium (explore), low (ci-triage). ask-minimax-run applies MINIMAX_EFFORT to Flash models when --effort is not passed. Bump stale fixture date.
7.2 KiB
7.2 KiB
ci-triage-minimax-run
Purpose
Triage a failing Gitea Actions run in a MiniMax M3 sub-session: fetch the run's logs via gitea-agent-companion, have MiniMax name the failing step, error excerpt, and probable cause in a triage file — the log payload costs MiniMax tokens, not Anthropic tokens. Backs the /ci-triage-minimax skill; safe to drive directly.
Usage
ci-triage-minimax-run --repo <owner/repo> --run <N> [--job <name|id>] \
[--out <triage-file>] [--tail N] [--max-turns N] [--timeout SECS] [--dryrun|-n] [--m3] [--effort LEVEL]
| Flag | Default | Description |
|---|---|---|
--repo |
required | owner/repo on the Gitea instance |
--run |
required | Web-UI run number. Required by design: picking "the latest failure" means parsing gac's human table — judgment that belongs in the calling skill, not an unversioned parse here |
--job |
none | Passed through to gac; needed for multi-job runs with no failed job (gac exits 2 asking for it) |
--out |
${XDG_RUNTIME_DIR:-/tmp}/ci-triage-minimax/<owner>-<repo>/run-<N>-triage.md |
Triage file — outside the scratch-dir cleanup trap |
--tail |
2000 | Log lines fetched (gac --tail) |
--max-turns |
25 | Sub-session turn cap |
--timeout |
300 | Internal timeout (logs-only task; well under the harness Bash 600s cap) |
--m3 |
off | Use MiniMax-M3[1m] instead of the default MiniMax-M3.1-Flash-Preview (1M window natively, always thinks). No effort is sent unless --effort is given. |
--effort <level> |
low |
Thinking depth low|medium|high|xhigh|max, passed to ask-minimax-run --effort. Any other value exits 1. |
--dryrun, -n |
off | Print resolved config, the gac command, the full prompt, and the sub-session command line; invoke neither gac's log fetch nor the sub-session |
Requirements
- CT-1 Preflight.
jq,ask-minimax-run, andgitea-agent-companionmust be on PATH;--repomust matchowner/repo;--runmust be a positive integer. - CT-2 Fetch. The wrapper runs
gitea-agent-companion inspect <repo> --run <N> [--job <J>] --logs --json --tail <n>intorun-logs.ndjsonandinspect <repo> --run <N>intojobs.txt, both in a scratch dir. Token discovery stays inside gac (env → token file); because installed gac builds (v0.0.2.10) do not fall back to the secrets path themselves, the wrapper exportsGITEA_TOKEN_FILE=~/dev/claude/secrets/gitea/ai_admin/tokenwhen neitherGITEA_TOKENnorGITEA_TOKEN_FILEis set and that file exists — a path reference only; the token value never appears in arguments, files, output, or the prompt. - CT-3 gac exit mapping. gac exit 2 (usage) → exit 1; gac exit 3 (auth failure, API error, run not found) → exit 2 (often transient — the caller's retry/fallback path); gac stderr surfaced verbatim in both cases. Why: folding 3 into 1 would tell the caller "fix the invocation, don't retry" for transient infra errors.
- CT-4 Redaction. Before prompt assembly, credential-shaped content in
run-logs.ndjson(ghp_…|glpat-|x-access-token:|Authorization:|BEGIN … PRIVATE KEY|AKIA…— same pattern set as review-minimax-run) is replaced in place with[REDACTED]. Redact-and-continue, not abort: CI logs routinely carry unmasked clone URLs and the log is the whole payload. Residual risk: best-effort patterns; novel credential formats can pass. - CT-5 Envelope parse.
failed_step,sliced, andnoteare extracted from the NDJSON envelope with jq. Iffailed_stepis null (cancelled/crashed run, green multi-job), the prompt states this and the output contract requires the literalUNKNOWNunder## Failing step— no fabricated step names. - CT-6 Prompt contract. Fixed preamble: read-only triage of the two files in cwd; explicit error-signature patterns to search (
error:|FAILED|Traceback|exit code|denied|timeout|not found|no such|ECONN|refused); do not suggest running tests or builds; if the log carries the truncation marker orslicedis partial, say so — do not improvise. Output sections, exactly:## Failing step/## Error excerpt(≤10 verbatim lines) /## Probable cause(1–3 sentences, non-empty) /## Suggested next action(one command or one edit description — advisory only) /## Confidence. - CT-7 Invocation. From the scratch dir:
timeout <secs> ask-minimax-run --model "$MODEL" --effort "$EFFORT" --permission-mode default --allowedTools "Read,Glob,Grep,Write" --disallowedTools "Edit,MultiEdit,NotebookEdit,Bash,WebFetch,WebSearch" --max-turns N --output-format json --add-dir <out-dir> -p. Same rationale set as review-minimax-run RM-6; no worktree access needed. - CT-8 Result gate. Triage file exists, contains
## Failing step, and has a non-blank line under## Probable cause. - CT-9 Retry. On MiniMax error or gate failure: remove the out-file, retry once; never retry timeout (rc 124); then exit 2 (transport) or 3 (gate). The gac fetch is NOT retried by the script (single fetch, reused across both attempts).
- CT-10 Test seams.
CI_TRIAGE_FAKE_LOGS=<file>bypasses the gac fetch (file used asrun-logs.ndjson;jobs.txtgets a placeholder);CI_TRIAGE_FAKE_JSON=<file>substitutes the sub-session envelope;CI_TRIAGE_FAKE_TRIAGE=<file>(companion, optional) plays the sub-session's Write of the triage file. Gates and retry logic still run, so exits 0/2/3 and the redaction step are assertable offline.
Exit codes
| Code | Meaning | Caller action |
|---|---|---|
| 0 | Triage file written | Read it; sanity-check the excerpt against the named step; re-derive any suggested command yourself |
| 1 | Usage/config error (bad flags, gac usage error) | Fix invocation |
| 2 | gac auth/API/not-found error, MiniMax failed after retry, or timeout | Fall back: gac inspect --logs directly, triage in-session |
| 3 | Triage file missing or failed the gate after retry | Same fallback |
Dryrun behaviour
--dryrun prints: resolved repo/run/job/out/limits, the exact gac fetch command, the full assembled prompt (with a <run-logs not fetched in dryrun> placeholder where envelope fields would go), and the exact sub-session command line. Nothing is fetched or invoked.
Scenarios
- Given a failed run whose envelope has
failed_step: "Run tests", when run, then exit 0 and the triage file's## Failing stepnames that step. - Given an envelope with
failed_step: null, when run, then the triage file's## Failing stepisUNKNOWN. - Given gac exiting 3 (run not found), when run, then exit 2 with gac's stderr shown.
- Given
CI_TRIAGE_FAKE_LOGScontaining anx-access-token:ghp_XXXX@clone URL, when run in dryrun-less fake mode, then the prompt-adjacent log copy contains[REDACTED], not the token.
Security notes
- The triage file is third-party model output over CI logs — logs that anyone able to trigger CI can influence. Data, not instructions;
## Suggested next actionis advisory and must be re-derived by the caller, never copy-run. - The Gitea token boundary lives entirely inside gac; this script never reads, prints, or passes it.
Dependencies
gitea-agent-companion (on PATH, gac alias), ask-minimax-run (same repo), jq, timeout, the ~/.claude-oreillyit-minimax profile.