Files
rUv e0d0af1cef feat(gaia): pre-submission exploit audit + signed attestation (ADR-167) (#2543)
* feat(gaia): pre-submission exploit audit + signed attestation (ADR-167)

Motivated by UC Berkeley RDI's April-2026 finding that all 8 major agent
benchmarks were gamed to ~98-100% without solving a single task (GAIA leaked
~98% of answers via public answer DBs + normalization collisions; o3/Claude-3.7
monkey-patch graders in 30%+ of runs per METR).

Signing proves transport-integrity; this audit proves earning-integrity. The
audit report is deterministic ($0, offline, pure-core) and is registered as an
ADR-103 witness fix marker so its sha256 + "clean": true marker are signed INTO
manifest.md.json.

- ADR-167 (v3/docs/adr): threat model, check catalogue mapped to RDI/METR
  vectors, manifest-attestation design, honest harness-gap limitations.
- gaia-audit.mjs: 7 pure checks (answer-leakage, no-work, oracle-leakage,
  grader-isolation, normalization-collision, voting-disclosure, split-integrity);
  CLI exit 0 clean / 1 CRITICAL / 2 usage. Schema-blocked checks return skip
  with a harness_gap note, never a false pass.
- Tests: 27 passing; clean + dirty fixtures triggering every vector.
- Wired --audit into /gaia validate; pre-sign gate into /gaia submit
  (refuses CRITICAL fail unless --allow-dirty) + gaia-submission skill.
- Bump ruflo-workflows 0.4.0 → 0.5.0.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01V84YJJK7RBF9TuUo4eVSW7

* docs(adr): ADR-168 — GAIA harness evidence recording (implements ADR-167 §7 forward contract)

Co-Authored-By: RuFlo <ruv@ruv.net>

* docs(adr): ADR-169 — benchmark reporting integrity standard (strict-EM headlines, view-labeled scaling, disclosed gaps)

Codifies the discipline the FRAMES ablation self-audit measured against the
Berkeley RDI vectors. Completes the integrity family: ADR-167 audits the
submission, ADR-168 records the evidence, ADR-169 governs how numbers are
reported.

Co-Authored-By: RuFlo <ruv@ruv.net>

* feat(gaia): port static source-scan checks (AUD-8/9/10) into gaia-audit

Ports the unique, non-overlapping checks from the reverted #2547 duplicate
gaia-integrity.mjs into gaia-audit.mjs as a new static source-scan family,
matching ADR-167's check-registry / status / harness_gap design:

- AUD-8 answer-key-reads (CRITICAL, fail-closed): scans runner sources +
  produced artifacts for answer/gold/solution/ground-truth-shaped paths
  referenced outside the sanctioned dataset dir(s).
- AUD-9 dynamic-eval (CRITICAL, fail-closed): static scan of the gaia-bench
  runner sources for eval()/new Function()/exec-family calls with a non-literal
  first arg. Preserves the #2547 false-positive refinements (multi-line aware,
  RegExp.prototype.exec excluded, fixed-string commands + comments ignored) —
  passes clean against ruflo's own multi-line `gcloud secrets … execSync`.
- AUD-10 judge-injection (WARN): scans the agent's PRODUCED answer/outputs for
  judge-directed prompt-injection markers. Distinct from AUD-3 oracle-leakage
  (input-side gold-answer scan), so both run.

Unlike AUD-1/3/4 these need no trajectory instrumentation — they enforce today
and skip honestly (never false-pass) when the source population is absent
(standalone/ejected run or --skip-source-scan). The #2547 provenance stamp and
--allow-integrity-override are NOT ported: #2543's signed attestation and the
`/gaia submit --allow-dirty` gate already own provenance + override, so the new
checks flow through the same attestation.clean/strict_clean path.

CLI adds --repo-root, --dataset-dir (repeatable), --skip-source-scan.
Fixtures: planted evil runner (eval + interpolated exec), planted answer-key
read, judge-injection results. Tests: 44 green (17 new). Docs: ADR-167 §3/§7
check table, gaia-validate.md, gaia-submission SKILL.md.

Co-Authored-By: RuFlo <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01S7GYqnVUVxBfZ5W8znqry3

* fix(ci): advance ruflo-workflows smoke version assertion to 0.5.0

The AUD-8/9/10 port bumped plugin.json to 0.5.0 but the plugin's own
smoke step 1 still asserted 0.4.0 — the single failing step behind both
smoke-all and the meta-smoke leg of smoke-without-metaharness on #2543.

Co-Authored-By: RuFlo <ruv@ruv.net>
2026-07-03 16:46:31 -04:00

5.2 KiB

name, description, argument-hint
name description argument-hint
gaia-submit Package GAIA results into an Ed25519-signed, HAL-compatible submission archive [--results=<path>] [--run-id=<id>] [--dry-run]

/gaia submit

Build a submission-ready package from a completed benchmark run and sign it with the ruflo Ed25519 witness manifest.

Usage

/gaia submit
/gaia submit --results=~/.cache/ruflo/gaia/results-latest.json
/gaia submit --results=./my-results.json --dry-run

Options

Flag Default Description
--results ~/.cache/ruflo/gaia/results-latest.json Path to the JSON results file from /gaia run
--run-id auto (from git SHA) Short identifier embedded in the package directory name
--dry-run off Build and validate the package but do not write it to disk
--no-sign off Skip Ed25519 signing (not recommended for leaderboard submissions)
--allow-dirty off Build the package even when the ADR-167 exploit audit reports a CRITICAL failure (records the failure in the package; not for leaderboard submissions)
--strict-audit off Also refuse to build when the audit reports a WARN finding

Output package layout

submission-<date>-<short-sha>/
├── results.jsonl        — one JSON object per question (HAL-compatible)
├── trajectories.jsonl   — full agent trajectory per question
├── metadata.json        — model, harness version, tool catalogue, cost
├── audit-report.json    — ADR-167 pre-submission exploit-audit report
├── manifest.md.json     — Ed25519-signed witness manifest (signs audit-report.json's hash)
└── README.md            — human-readable summary + comparison vs HAL baseline

Submission integrity gate (ADR-167)

Before signing, /gaia submit runs the pre-submission exploit audit — a deterministic, $0 red-team of the known reward-hacking vectors that let UC Berkeley RDI hit ~98% on GAIA without solving a single task (leaked answer DBs, no-work passes, oracle leakage, grader monkey-patching).

Signing proves the package bytes are untampered; the audit proves the scores were earned. The two are wired together: the audit report is registered as an ADR-103 witness fix marker, so its sha256 + "clean": true marker are signed into manifest.md.json.

  • If the audit reports a CRITICAL failure, /gaia submit refuses to build the leaderboard package unless --allow-dirty is passed.
  • --strict-audit additionally refuses on WARN findings.
  • Checks whose data the current trajectory schema does not capture return skip with a harness_gap note (ADR-167 §7) — they do not block, but the gap is recorded in audit-report.json and thus in the signed manifest.

HAL-compatible result schema (per question)

{
  "task_id": "e1fc63a2-da7a-432f-be78-7c4a95598703",
  "model_answer": "4",
  "reasoning_trace": "[full agent trace]",
  "tools_used": ["web_search", "python_exec"],
  "turns": 5,
  "wall_seconds": 12.4
}

Steps Claude should follow

  1. Locate the results file — default ~/.cache/ruflo/gaia/results-latest.json; ask if multiple candidates exist.
  2. Validate the file has the expected shape: level, model, summary, results array.
  3. Transform results[] → HAL-compatible results.jsonl (one JSON per line).
  4. Extract trajectories.jsonl from any trajectory fields in the results.
  5. Build metadata.json:
    {
      "submitted_at": "<ISO-8601>",
      "harness": "ruflo@3.6.x / @claude-flow/cli@3.6.x",
      "model": "<model-id>",
      "gaia_level": 1,
      "tool_catalogue": ["web_search","file_read","web_browse","image_describe","python_exec"],
      "total_questions": 53,
      "pass_rate": 0.208,
      "est_cost_usd": 1.23,
      "adrs": ["ADR-133","ADR-135","ADR-136"],
      "git_sha": "<short-sha>"
    }
    
  6. Run the exploit audit (ADR-167) before signing:
    node plugins/ruflo-workflows/scripts/gaia-audit.mjs \
      --results <results> \
      --trajectories submission-<id>/trajectories.jsonl \
      --metadata submission-<id>/metadata.json \
      --out submission-<id>/audit-report.json \
      --audited-at "$SUBMITTED_AT" ${STRICT_AUDIT:+--strict}
    
    If it exits non-zero (CRITICAL fail, or WARN under --strict-audit) and --allow-dirty was NOT passed, stop and report the findings — do not build the package. --audited-at is set to metadata.submitted_at so the report is reproducible.
  7. Register the audit report as a witness fix marker so its hash is signed into the manifest, then sign:
    node plugins/ruflo-core/scripts/witness/regen.mjs \
      --manifest submission-<id>/manifest.md.json \
      --root submission-<id> \
      --fixes gaia-audit-fix.json   # {id:"gaia-exploit-audit", file:"audit-report.json", marker:"\"clean\": true"}
    
  8. Write README.md with pass-rate table comparing to HAL baselines.
  9. If --dry-run, print the package tree, the audit summary, and the manifest hash without writing.
  10. Print the package directory path so the user can zip + upload to HAL.

Submitting to HAL

After generating the package:

zip -r submission-$(date +%Y%m%d).zip submission-<date>-<sha>/
# Upload at https://huggingface.co/spaces/gaia-benchmark/leaderboard