Repository navigation
Harness evidence checks conformance #3766
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
0e98958
Add native harness artifact conformance checks and onboarding guidance
lafrancef a92ed5c
Move harness conformance entry point into scripts
lafrancef 24b4c49
Align P0 harness evidence checks and add four-harness coverage
lafrancef b9d2860
Add scripted harness conformance runner
lafrancef f28cb2a
Separate checker fixtures and gate generated trajectory evidence tables
lafrancef bcf3602
Regenerate trajectory evidence table from tested source
lafrancef d3c74bf
Validate conformance evidence against shared rollout models
lafrancef 6a2c1d9
Reconcile conformance tool witnesses and clarify inspector usage
lafrancef f3ba752
Fix conformance secret-detector false positives
lafrancef 213b911
Accept numeric rewards on masked verification results
lafrancef adc5818
test(agent): document miniSWE submission evidence gap
lafrancef File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
1,367 changes: 1,367 additions & 0 deletions
1,367
...ectory-capabilities/425964eadebb395fea46f594177e2373b4195530934ed44be4ead0d755892c90.json
Large diffs are not rendered by default.
Oops, something went wrong.
121 changes: 121 additions & 0 deletions
121
fern/versions/latest/pages/observability/harness-conformance.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| --- | ||
| title: "Harness Conformance" | ||
| description: "Check P0 trajectory evidence and compare harness artifact coverage." | ||
| position: 3 | ||
| --- | ||
|
|
||
| # Harness Conformance | ||
|
|
||
| Check the evidence retained by a harness/benchmark pair after collecting an evaluation: | ||
|
|
||
| ```bash | ||
| python scripts/inspect_harness_conformance.py \ | ||
| --bundle results/my-harness/rollouts.jsonl \ | ||
| --output results/my-harness/evidence | ||
| ``` | ||
|
|
||
| The `gym-p0/v1` profile checks the currently supported P0 trajectory evidence | ||
| (TE-1–TE-9). Every applicable TE-1–TE-7 must pass, plus **TE-8 or TE-9** on | ||
| every rollout. It replaces the earlier experimental C0–C11 profiles. | ||
|
|
||
| | Evidence | Persisted contract | | ||
| | --- | --- | | ||
| | TE-1: model call status | Exact call/model identity, HTTP or transport outcome, response status and termination metadata preserved from the response. Optional call clocks are checked when present. | | ||
| | TE-2: token counts | Supplied prompt, completion, reasoning, total and cached counts preserved on successful and failed attempts. Provider omission remains unknown. Availability is reported separately. | | ||
| | TE-3: steps | Task, repeat, rollout and step identity; timestamp; model-visible prompt; answer/tool or reasoning fields; resolution or explicit unknown. No step is inferred from an HTTP call. | | ||
| | TE-4: history | Ordered saved model inputs and outputs, including tool results and changed context. Missing media, opaque content and unavailable prior-response history fail. | | ||
| | TE-5: tool record | Execution id/name/status, originating request with dispatched arguments, and output/error. Tool clocks are outside P0. A tool request alone does not prove execution. | | ||
| | TE-6: verifier outcome | The current Gym verification surface: finite rollout reward, including for masked results, and correctly scoped terminal resolution when present. `mask_sample=true` excludes the reward from scores. Masked or explicitly incomplete verification requires nonblank `failure_kind` and `failure_reason`. Extended verifier scope/version and judge provenance are not certified by this profile. | | ||
| | TE-7: payloads | Saved request and response/error bodies. Empty returned bodies and explicit no-response transport failures remain distinct. | | ||
| | TE-8: run join | Exactly one explicit invocation owner per captured attempt, including attempts without response ids; consistent parent relationships and exact references. | | ||
| | TE-9: step join | Every retained policy attempt belongs to exactly one identified step. Retries remain attempts on that step. Explicit compaction-helper refs are excluded from policy steps. | | ||
|
|
||
| TE-2 distinguishes preservation from availability: an absent provider metric is | ||
| not an available zero or a five-count availability pass. Derived totals follow | ||
| Gym's documented prompt-plus-completion convention. Anthropic prompt totals | ||
| include cache reads and cache creation. Missing usage remains visible to health. | ||
|
|
||
| The profile covers retained artifacts. It does not certify live failure/retry | ||
| scenario coverage, closed-run completeness, health, accuracy, or deployment | ||
| readiness. Independent completeness required by some health consumers is separate | ||
| from TE-9's retained reference check. Infra taxonomy (TE-10) and P1 efficiency | ||
| requirements are outside this profile. | ||
|
|
||
| ## Applicability and delivery | ||
|
|
||
| By default the pair has policy steps, tools, and a verifier. Use `--no-tools`, | ||
| `--no-verifier`, or `--no-steps` only when that feature does not apply to the | ||
| pair. Missing evidence never automatically becomes N/A. Contradictory retained | ||
| evidence rejects an exclusion. A step-free pair still needs TE-8. | ||
|
|
||
| `--bundle` accepts a JSONL file, or a directory with exactly one `rollouts.jsonl` | ||
| or `evaluator_rollouts.jsonl`, at its root or under `artifacts/`. | ||
|
|
||
| The delivery surface is the rollout JSONL, including `ng_trajectory` payloads. | ||
| An optional `--capture-dir /absolute/path/to/model-calls` cross-checks exact | ||
| identity sets, payloads, metadata and incomplete markers. It cannot repair a | ||
| missing JSONL payload for a passing delivery verdict. | ||
|
|
||
| Each inspection atomically publishes an immutable directory containing: | ||
|
|
||
| - `evidence_summary.json`: gate, per-TE counts, token availability, applicability, | ||
| source/checker/schema hashes and qualification limits. | ||
| - `evidence_results.jsonl`: per-rollout findings and field locations. | ||
| - `evidence_report.md`: evidence table. | ||
|
|
||
| Exit codes are **0** for a met gate, **1** for unmet evidence, and **2** for an | ||
| input/checker error. An empty input is an error. Reports omit payload contents. | ||
| Identical inputs and checker versions reuse the same report directory. | ||
|
|
||
| ## Compare harnesses | ||
|
|
||
| Use the same task and capture settings when comparing harnesses: | ||
|
|
||
| ```bash | ||
| python scripts/inspect_harness_conformance.py matrix \ | ||
| --harness opencode=results/opencode/rollouts.jsonl \ | ||
| --harness pi=results/pi/rollouts.jsonl \ | ||
| --harness codex=results/codex/rollouts.jsonl \ | ||
| --harness hermes=results/hermes/rollouts.jsonl \ | ||
| --output results/harness-evidence | ||
| ``` | ||
|
|
||
| The command writes per-harness reports plus `harness_evidence.md` and | ||
| `harness_evidence.json`. Applicability flags apply to every input pair in that | ||
| comparison. A matrix FAIL identifies missing or inconsistent evidence; it is not | ||
| a benchmark accuracy result. | ||
|
|
||
| Checker unit tests use hand-authored synthetic evidence contracts, independent of | ||
| harness implementations. Mutations verify missing, conflicting, and malformed | ||
| evidence without prescribing which checks a real harness should pass. | ||
|
|
||
| The [Trajectory Capability Matrix](/main/reference/trajectory-capabilities) is | ||
| generated separately from fresh scripted harness runs. Its regeneration command | ||
| requires passing runner, harness adapter, and checker unit tests at a specific | ||
| Gym commit before replacing the table. | ||
|
|
||
| ## Onboard a producer | ||
|
|
||
| Enable `observability_enabled: true` and set `model_call_capture_dir` to a shared | ||
| absolute directory. Route requests through Gym's correlated model URL and retain | ||
| all attempts. See [Model-call Capture](/main/model-server/model-call-capture). | ||
|
|
||
| Return `ng_agent_observations` with `AgentInvocation` and exact `ModelCallRef` | ||
| keys (`model_call_id`, or unique `model_ref` plus `response_id`). Forward the | ||
| invocation id as `x-session-id` for failed-call joins through the collector. | ||
| A timestamp or shared model name never establishes ownership. | ||
|
|
||
| Supply explicit `TrajectoryTurn` records with the actual prompt and decision | ||
| boundaries. Preserve tool request/result pairs and `ToolCallObservation` outcomes, | ||
| including failures and terminal submission. Keep resolution unknown on | ||
| intermediate steps. Retain the resources server's verification response. | ||
| See [Rollout Evidence](/main/observability/rollout-evidence). | ||
|
|
||
| Inspect a small collected evaluation, fix producer gaps, and collect again. | ||
| Run [rollout health checks](/main/evaluation/rollout-health) separately. Evidence | ||
| checks neither rewrite `quality_summary.json` nor treat a truthfully recorded | ||
| failed model call as missing evidence. | ||
|
|
||
| ```bash | ||
| python -m pytest tests/unit_tests/harness_capabilities -q | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| # Harness trajectory evidence | ||
|
|
||
| Check P0 evidence from a collected evaluation: | ||
|
|
||
| ```bash | ||
| python scripts/inspect_harness_conformance.py \ | ||
| --bundle results/my-harness/rollouts.jsonl \ | ||
| --output results/my-harness/evidence | ||
| ``` | ||
|
|
||
| Use `matrix --harness NAME=PATH` to compare multiple harnesses. The checker uses | ||
| TE-1–TE-9 and the `gym-p0/v1` profile. Reports are `evidence_summary.json`, | ||
| `evidence_results.jsonl`, and `evidence_report.md`. | ||
|
|
||
| For example, this excerpt from `evidence_report.md` shows retained model-call | ||
| evidence passing while one tool record is missing its name: | ||
|
|
||
| ```markdown | ||
| Profile: `gym-p0/v1`. Gate: **not_fulfilled**. Records: 1. | ||
|
|
||
| | Evidence | Artifact verdict | Passing / applicable records | | ||
| |---|---|---| | ||
| | TE-1: model_call_status | fulfilled | 1/1 | | ||
| | TE-5: tool_record | not_fulfilled | 0/1 | | ||
| ``` | ||
|
|
||
| One corresponding entry in that rollout's `findings` array in | ||
| `evidence_results.jsonl` identifies the missing field: | ||
|
|
||
| ```json | ||
| { | ||
| "evidence": "TE-5", | ||
| "assertion": "identity.required", | ||
| "location": "rollouts.jsonl:1/ng_trajectory/tool_calls/0/tool_name", | ||
| "reason": "nonempty value is required" | ||
| } | ||
| ``` | ||
|
|
||
| These verdicts describe evidence conformance, not task success. A rollout with | ||
| zero reward can have fully conforming evidence; a successful task can have | ||
| incomplete evidence. | ||
|
|
||
| Known producer gap: `miniswe_sandboxed_agent` retains its final submit tool call | ||
| as `incomplete`, without output or error evidence. This fails TE-5 with | ||
| `tool.terminal` and `tool.outcome`, so the P0 gate is `not_fulfilled` for those | ||
| rollouts. mini-SWE must save a terminal result correlated with the submit call | ||
| before exiting, and Gym must retain it in the projected evidence. See the | ||
| [mini-SWE observability limits](../../responses_api_agents/miniswe_sandboxed_agent/README.md#native-behavior-and-observability). | ||
|
|
||
| TE-6 requires a finite numeric `reward` even when `mask_sample=true` excludes it | ||
| from scoring. Masked results and explicitly incomplete verification require | ||
| nonblank `failure_kind` and `failure_reason`; a masked `reward=0.0` is valid | ||
| evidence. The Gym profile uses the default unmasked behavior when `mask_sample` | ||
| is omitted and checks `evaluation_completed` when supplied. Both flags must be | ||
| booleans when present. | ||
|
|
||
| Evidence objects must validate Gym's shared models at these paths: | ||
|
|
||
| | JSON path | Model | | ||
| |---|---| | ||
| | `ng_model_call_capture.calls[]` | `ModelCallRecord` | | ||
| | `ng_trajectory.model_calls[]` | `TrajectoryModelCall` | | ||
| | `ng_trajectory.turns[]` | `TrajectoryTurn` | | ||
| | `ng_trajectory.invocations[]` | `AgentInvocation` | | ||
| | `ng_trajectory.tool_calls[]` | `TrajectoryToolCall` | | ||
| | `ng_agent_observations.records[]` | `AgentObservationRecord` (discriminated by `kind`) | | ||
|
|
||
| Validation is strict and reports the object's JSON path. Invalid objects are | ||
| record integrity failures; missing evidence is evaluated by the TE checks and | ||
| explicit applicability. Both trajectory and observation representations are | ||
| validated when present. Invocation and tool checks retain their supported | ||
| fallback between these paths. | ||
|
|
||
| TE requirements apply on top of model validity. For example, TE-3 requires a | ||
| non-null `question`, a non-null `answer` or `reasoning_content`, and an explicitly | ||
| present `resolved` value (including `null` for unknown). TE-5 requires a tool name | ||
| and terminal status; TE-1 requires model/server identity and a supported dialect; | ||
| TE-2 requires nonnegative counts consistent with retained provider usage. Reports | ||
| hash the path/model registry and shared model sources as well as the checker. | ||
|
|
||
| For live harness checks and regenerating the capability table, see the | ||
| [runner guide](../../scripts/harness_conformance/README.md). | ||
|
|
||
| See [Harness Conformance](../../fern/versions/latest/pages/observability/harness-conformance.mdx) | ||
| for contracts, applicability, matrix usage, producer onboarding, and limitations. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """Portable artifact contracts for harness observability. | ||
|
|
||
| Readers supply native Gym JSON; | ||
| artifact conformance is deliberately separate from behavioral qualification. | ||
| """ | ||
|
|
||
| from .checker import inspect_record | ||
|
|
||
|
|
||
| __all__ = ["inspect_record"] | ||
| __version__ = "0.2.0" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| from .cli import main | ||
|
|
||
|
|
||
| raise SystemExit(main()) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.