Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
1883751
feat(tier1): decouple the SkillSpector model from provider chat defau…
rng1995 Oct 8, 2026
68ba452
feat(llm): gate reasoning-model request shape, detect refusals and si…
rng1995 Oct 8, 2026
585940c
feat(tier3): pin Claude Code 2.1.292 and Codex 0.161.0 and set Claude…
rng1995 Oct 8, 2026
6d24e34
feat(gateway): default gateway agents to GPT-6.1 Sol and Claude Opus 5.5
rng1995 Oct 8, 2026
fff8311
feat(openai): default OpenAI to GPT-6.1 Sol
rng1995 Oct 8, 2026
7b3431c
feat(anthropic): default Anthropic and Bedrock to Claude Opus 5.5
rng1995 Oct 8, 2026
f0d98cf
ci(gitleaks): allowlist the Bedrock model ID in SkillSpector bridge t…
rng1995 Oct 8, 2026
c3f75a6
docs(provider-config): drop stale default-model wording from effort c…
rng1995 Oct 8, 2026
29e2926
fix(llm): keep complete verifier verdicts from a truncated reply
rng1995 Oct 8, 2026
ef1a715
fix(llm): clamp Anthropic max_tokens to the SDK limit and rebuild sch…
rng1995 Oct 8, 2026
402eaa7
fix(provider-config): pin SkillSpector defaults as literals and docum…
rng1995 Oct 8, 2026
c592290
fix(tier3): carry step judge models into multi-step logical rewards
rng1995 Oct 8, 2026
749ce18
test(llm): cover medium effort for dedup verdicts and the dimension a…
rng1995 Oct 8, 2026
a6d3721
refactor(tier3): build the eval-core judge payload from the shared cl…
rng1995 Oct 8, 2026
baa7fdb
Merge main into naren/model-defaults-gpt-6-1-sol-opus-5-5
rng1995 Oct 13, 2026
59c8fd4
Merge main into naren/model-defaults-gpt-6-1-sol-opus-5-5
rng1995 Oct 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,10 @@ condition = "AND"
targetRules = ["generic-api-key"]
regexes = ['''^cw-key-123456$''']
paths = ['''^tests/test_harbor_environment_contract\.py$''']

[[allowlists]]
description = "Bedrock model ID that follows a credential name in SkillSpector bridge tests"
condition = "AND"
targetRules = ["generic-api-key"]
regexes = ['''^us\.anthropic\.claude-opus-5$''']
paths = ['''^tests/validators/test_security\.py$''']
71 changes: 71 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,65 @@ All notable changes to SkillEvaluator are documented in this file.

### Changed

- SkillSpector now has its own default model per provider instead of
following the chat default, so chat-default upgrades no longer reach
SkillSpector before it supports them. An explicit `SKILL_EVAL_LLM_MODEL`
still reaches it, and `SKILLSPECTOR_MODEL` still overrides both. The bridge
forwards your `SKILLSPECTOR_MODEL_<SLOT>`, `SKILLSPECTOR_MODEL_REGISTRY` and
`SKILLSPECTOR_REASONING_EFFORT` settings (never `SKILLSPECTOR_TEMPERATURE`),
defaults the reasoning effort to `medium` for GPT-6 models, and records the
requested `skillspector_model` and `skillspector_reasoning_effort` next to
`skillspector_version` in the security result.
- Install instructions and the missing-scanner hint now pin SkillSpector to
`v2.12.0` instead of its default branch.
- GPT-6 models get the GPT-5 request shape everywhere SkillEvaluator calls a
model: no `temperature`, and `max_completion_tokens` on the native OpenAI
endpoint. Gateway catalog IDs such as `aws/anthropic/bedrock-claude-opus-5`
are recognized as the Claude model they name.
- Output-token limits are sized per model family. OpenAI reasoning models get
at least 32,768 tokens; other models get 16,384 for `--llm-verify`, rubric
evaluation, deduplication verdicts and judges, 8,192 for report suggestions
and 16,000 for dataset generation. On the Anthropic API, Claude Opus 4 and
4.1 stay at the 8,192 tokens the Anthropic SDK allows without streaming.
- Reasoning effort is sent only to GPT-6 models and to Claude 5.5 or later on
the Anthropic API: `high` for `--llm-verify`, `medium` for rubric evaluation,
deduplication verdicts and judges.
- Rubric evaluation and deduplication verdicts request structured output. The
verifier and deduplication prompts ask for `rationale` instead of
`reasoning`; replies that still say `reasoning` are accepted.
- The `goal_accuracy` RAGAS scorer is skipped for GPT-5 and GPT-6 judges, which
reject its sampling settings.
- `run_config.json` records the judge reasoning effort, and each standard
judge's details record `judge_model_used`, `judge_reasoning_effort` and
`judge_fallback_used`. Skill lift leaves out a case whose two conditions were
judged by different models and counts it in `judge_mixed_cases`.
- Removed the unused `CONTENT_DEDUP_LLM_*` constants and `LLM_VERIFY_MODEL`; an
LLM client built from explicit credentials uses the provider default model.
- Tier 3 pins the agent CLIs Harbor installs: Codex 0.161.0 and Claude Code
2.1.292, instead of the latest release. Claude Code runs Claude 5.5 and later
models with `reasoning_effort=medium`; Codex keeps `high`. Local mode keeps
your installed CLIs and fails a trial early when they are too old for the
model: Claude 5.5 needs Claude Code 2.1.280 or newer, and GPT-6 needs Codex
0.159.1 or newer.
- OpenAI-compatible gateway agent defaults: Codex moves to
`openai/openai/gpt-6.1-sol` and Claude Code to
`aws/anthropic/bedrock-claude-opus-5-5`. OpenCode stays on
`nvidia/nvidia/nemotron-3-super-120b-long-ctx`, no longer tied to the gateway
chat default. Claude Code on the shared gateway key runs with
`CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1`, so gateways that forward to
another provider do not reject its pre-release request fields.
- The OpenAI default model moves from `gpt-5.6-sol` to `gpt-6.1-sol` for chat,
judging, Codex and SkillSpector, which runs it at `medium` reasoning effort,
so the effort values above apply to the OpenAI defaults. OpenCode keeps
`openai/gpt-5.6-sol` unless `SKILL_EVAL_LLM_MODEL` is set, because
GPT-6.1 Sol supports tool calls only on the Responses API.
- The Anthropic and Bedrock default models move from Claude Opus 5 to Claude
Opus 5.5 (`claude-opus-5-5` and `us.anthropic.claude-opus-5-5`) for chat,
judging and Claude Code. On the Claude API they get the effort values above
and server-side refusal fallback, and Claude Code runs them at
`reasoning_effort=medium`.
SkillSpector stays on `claude-opus-5` and `us.anthropic.claude-opus-5`, which
SkillSpector v2.12.0 supports.
- Docker Claude Code and Codex containers no longer get the distribution
`nodejs` and `npm` packages from agent setup, except on Alpine images. On
Debian-based images, including the default eval image, those packages also
Expand All @@ -26,6 +85,18 @@ All notable changes to SkillEvaluator are documented in this file.

### Fixed

- Safety-classifier refusals, content filters and output-token truncation are
detected instead of being read as empty or malformed output. `--llm-verify`
and rubric evaluation report the cause, and `--llm-verify` keeps the
complete verdicts of a truncated reply. Claude 5.5 or later requests to the
native Claude API use server-side fallback to Claude Opus 4.8. In the Harbor
verifier, Bedrock retries a filtered Claude 5.5 reply on Claude Opus 4.8, and
a refusal or empty judge reply moves on to the next
`LLM_JUDGE_FALLBACK_MODELS` entry.
- The Harbor verifier's last-resort judge model follows the selected provider.
With no judge or chat model configured, it used to request an OpenAI model
from Anthropic, Bedrock, NVIDIA Build and gateways. The unused host-side
`llm_judge.DEFAULT_JUDGE_MODEL` constant is removed.
- Fixed Docker Codex and Claude Code setup wasting its timeout installing
distribution Node/npm before Harbor's own installers. Native, gateway Codex,
and NVIDIA Build agents now provision Node/npm only on the installer branches
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export OPENAI_API_KEY='sk-...'

NVIDIA Build defaults to `nvidia/nemotron-3-super-120b-a12b` for evaluator chat,
Tier 3 agent execution, and judging. Its embedding default is
`nvidia/nemotron-3-embed-1b`; OpenAI defaults to `gpt-5.6-sol` and
`nvidia/nemotron-3-embed-1b`; OpenAI defaults to `gpt-6.1-sol` and
`text-embedding-3-small`. These are configured defaults, not automatically
updated selections of the latest models. To select a different evaluator model:

Expand Down
13 changes: 11 additions & 2 deletions docs/agents-and-sandboxes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ SkillEvaluator selects the provider-native default: `opencode` for NVIDIA Build,

| Agent | Notes |
| --- | --- |
| `claude-code` | Anthropic's Claude Code CLI. `claude` is an accepted alias. |
| `codex` | OpenAI's Codex CLI. The OpenAI-provider default. Runs with `reasoning_effort=high` so scores and cost stay comparable across Harbor releases. |
| `claude-code` | Anthropic's Claude Code CLI. `claude` is an accepted alias. Harbor installs Claude Code 2.1.292. Claude 5.5 and later models run with `reasoning_effort=medium`; older models keep Claude Code's default effort. |
| `codex` | OpenAI's Codex CLI. The OpenAI-provider default. Harbor installs Codex 0.161.0. Runs with `reasoning_effort=high` so scores and cost stay comparable across Harbor releases. |
| `opencode` | The OpenCode CLI. |

The pinned CLI releases apply wherever Harbor installs the agent: Docker and
the remote environments. [Local mode](#local-mode) runs the CLI already on your
machine instead.

The `claude` alias is canonicalized to `claude-code` everywhere an agent
name can appear — `-a/--agents`, `--agent-model`, and `harbor.agents` in
`evals/config.yml` — so both spellings always name the same agent.
Expand Down Expand Up @@ -350,6 +354,11 @@ hard-unsupported and fails closed before agent-runtime discovery —
directs you to WSL2 or `--env-mode docker`. Only `claude-code`, `codex`,
and `opencode` can run in local mode.

Local mode does not install the pinned CLI releases. Each trial checks the
installed version against the selected model instead and fails before the agent
starts when it is too old: Claude 5.5 and later models need Claude Code 2.1.280
or newer, and GPT-6 models need Codex 0.159.1 or newer.

The sandbox policy is controlled by environment variables:

| Variable | Default | Effect |
Expand Down
2 changes: 1 addition & 1 deletion docs/ci-integration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
- name: Install external Python scanners
run: |
uv tool install semgrep
uv tool install git+https://github.com/NVIDIA/SkillSpector.git
uv tool install git+https://github.com/NVIDIA/SkillSpector.git@v2.12.0

- name: Install Gitleaks
run: |
Expand Down
5 changes: 3 additions & 2 deletions docs/cli-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ Use `skillevaluator tier3 PATH` for the complete workflow with automatic missing
| `--n-concurrent INTEGER` | unset | Concurrent eval cases per agent. |
| `--max-agents INTEGER` | unset | Maximum agents to run in parallel. |
| `--model TEXT` | unset | Global agent model override. |
| `--agent-model TEXT` | unset | Per-agent model override, `AGENT=MODEL` (repeatable), e.g. `--agent-model codex=gpt-5.6-sol`. Accepts the `claude` alias for `claude-code`. |
| `--agent-model TEXT` | unset | Per-agent model override, `AGENT=MODEL` (repeatable), e.g. `--agent-model codex=gpt-6.1-sol`. Accepts the `claude` alias for `claude-code`. |
| `--custom-dockerfile-mode [preserve\|rebase]` | unset | How a custom `evals/environment/Dockerfile` is applied: `rebase` (built-in default) swaps its `FROM` line onto the eval base image; `preserve` keeps your `FROM` and appends the eval dependencies. |
| `--skill-workspace-mode [isolated\|group]` | unset | `isolated` (built-in default) stages only the target skill in the agent workspace; `group` also stages the skills from `--include-skills` / `skill_workspace.include`. |
| `--include-skills PATH` | none | Additional skill(s) to mount into the eval environment (repeatable; paths must exist). Requires group workspace mode (`--skill-workspace-mode group` or `skill_workspace.mode: group` in `evals/config.yml`). |
Expand All @@ -415,7 +415,8 @@ Use `skillevaluator tier3 PATH` for the complete workflow with automatic missing
| `--progress [auto\|rich\|plain\|off]` | `auto` | Progress display for the run: `rich` live view, `plain` line output, or `off`. |

Without a `--model`/`--agent-model` override, agent execution uses
`gpt-5.6-sol` for OpenAI, `claude-opus-5` for Anthropic, and
`gpt-6.1-sol` for OpenAI (OpenCode: `openai/gpt-5.6-sol` unless
`SKILL_EVAL_LLM_MODEL` is set), `claude-opus-5-5` for Anthropic, and
`nvidia/nemotron-3-super-120b-a12b` for NVIDIA Build. OpenCode displays the
last value as `nvidia/nvidia/nemotron-3-super-120b-a12b` because its adapter
namespace precedes the NVIDIA catalog ID.
Expand Down
18 changes: 10 additions & 8 deletions docs/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,15 @@ Set `SKILL_EVAL_LLM_PROVIDER` to one of `openai`, `anthropic`, `nv_build`, `bedr
export OPENAI_API_KEY='sk-...'
```

Default model: `gpt-5.6-sol` (OpenAI GPT-5.6 Sol frontier). For a lower-cost override set `SKILL_EVAL_LLM_MODEL=gpt-5.4-mini`. Endpoint `https://api.openai.com/v1`. Override the endpoint with `SKILL_EVAL_LLM_BASE_URL` (takes precedence) or `OPENAI_BASE_URL` — but a base URL that is a non-canonical alias of the native OpenAI endpoint is rejected; use `https://api.openai.com/v1` verbatim. On the canonical endpoint, `gpt-5*` models automatically send `max_completion_tokens` instead of `max_tokens`.
Default model: `gpt-6.1-sol` (OpenAI GPT-6.1 Sol frontier). For a lower-cost override set `SKILL_EVAL_LLM_MODEL=gpt-5.4-mini`. Endpoint `https://api.openai.com/v1`. Override the endpoint with `SKILL_EVAL_LLM_BASE_URL` (takes precedence) or `OPENAI_BASE_URL` — but a base URL that is a non-canonical alias of the native OpenAI endpoint is rejected; use `https://api.openai.com/v1` verbatim. On the canonical endpoint, GPT-5 and GPT-6 models automatically send `max_completion_tokens` instead of `max_tokens`. Tier 3's OpenCode agent uses `openai/gpt-5.6-sol` unless `SKILL_EVAL_LLM_MODEL` is set, because OpenCode calls tools through Chat Completions and GPT-6.1 Sol supports tool calls only on the Responses API.
</Tab>
<Tab title="Anthropic" language="anthropic">
```bash title="Anthropic setup"
export SKILL_EVAL_LLM_PROVIDER=anthropic
export ANTHROPIC_API_KEY='sk-ant-...'
```

Default model: `claude-opus-5`, using the Anthropic SDK's default endpoint. Override it with `SKILL_EVAL_LLM_BASE_URL` (highest precedence) or `ANTHROPIC_BASE_URL`; when neither is set, SkillEvaluator uses the Anthropic default.
Default model: `claude-opus-5-5`, using the Anthropic SDK's default endpoint. Override it with `SKILL_EVAL_LLM_BASE_URL` (highest precedence) or `ANTHROPIC_BASE_URL`; when neither is set, SkillEvaluator uses the Anthropic default.

For Anthropic, either base-URL variable must be an absolute HTTP(S) API root. Supply an unversioned root such as `https://gateway.example.com` or a legacy URL whose final segment is `/v1`, such as `https://gateway.example.com/team/v1`. SkillEvaluator normalizes the latter to its API root so the Anthropic SDK, the Tier 3 verifier, and a matching Claude Code agent each form request paths with exactly one `/v1/messages` suffix. An independently credentialed Claude Code route applies the same normalization and validation to `ANTHROPIC_BASE_URL` when the evaluator uses another provider. Routing through path prefixes, ports, IP addresses, internationalized domain names, and ordinary safe percent escapes is preserved.

Expand Down Expand Up @@ -125,7 +125,7 @@ Set `SKILL_EVAL_LLM_PROVIDER` to one of `openai`, `anthropic`, `nv_build`, `bedr
# (environment variables, shared profile, or an assumed role).
```

Default model: `us.anthropic.claude-opus-5` on the AWS Bedrock Runtime (US geo inference profile for Claude Opus 5).
Default model: `us.anthropic.claude-opus-5-5` on the AWS Bedrock Runtime (US geo inference profile for Claude Opus 5.5).
</Tab>
<Tab title="OpenAI-compatible" language="openai-compatible">
```bash title="OpenAI-compatible setup"
Expand All @@ -140,15 +140,15 @@ Set `SKILL_EVAL_LLM_PROVIDER` to one of `openai`, `anthropic`, `nv_build`, `bedr
| --- | --- | --- |
| Evaluator and standard judge | `nvidia/nvidia/nemotron-3-super-120b-long-ctx` | `SKILL_EVAL_LLM_MODEL`; judge-only: `LLM_JUDGE_MODEL` then `SKILL_EVAL_JUDGE_MODEL` |
| Tier 2 embeddings | `nvidia/nvidia/nemotron-3-embed-1b` | `SKILL_EVAL_EMBEDDING_MODEL` |
| Codex agent | `openai/openai/gpt-5.6-sol` | `--agent-model codex=MODEL` |
| Claude Code agent | `aws/anthropic/bedrock-claude-opus-5` | `--agent-model claude-code=MODEL` |
| Codex agent | `openai/openai/gpt-6.1-sol` | `--agent-model codex=MODEL` |
| Claude Code agent | `aws/anthropic/bedrock-claude-opus-5-5` | `--agent-model claude-code=MODEL` |
| OpenCode agent | `nvidia/nvidia/nemotron-3-super-120b-long-ctx` | `--agent-model opencode=openai/MODEL` |

Gateways can use different catalog IDs. Supply those exact IDs through the overrides; SkillEvaluator never substitutes a different model after a request fails. OpenCode's `openai/` prefix selects its adapter and is removed before sending the catalog ID. `SKILL_EVAL_LLM_MODEL` controls evaluation and judging; it does not replace these separate gateway agent defaults. Agent selection uses `--agent-model` / `--model`, then `harbor.agents.AGENT.model`, then the harness default, and records the model source in the run report.

For Tier 3 in Docker, OpenCode requires Chat Completions, Codex requires Responses, and Claude Code requires Anthropic Messages, each with tool-call support. Selecting a shared URL does not add those APIs to a server. See the [Claude gateway requirements](https://code.claude.com/docs/en/llm-gateway).

Claude Code inherits the shared key and URL, stripping a terminal `/v1` from its API root while retaining any path prefix. An explicit `ANTHROPIC_BASE_URL` overrides that root. An explicit `ANTHROPIC_API_KEY` selects an independent Claude route: without `ANTHROPIC_BASE_URL`, it keeps the native Anthropic endpoint and defaults to `claude-opus-5`. CLI and skill-config model overrides still take precedence. Existing native-provider routes are unchanged.
Claude Code inherits the shared key and URL, stripping a terminal `/v1` from its API root while retaining any path prefix. An explicit `ANTHROPIC_BASE_URL` overrides that root. With the shared key, Claude Code runs with `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1`, so it does not send pre-release request fields that a gateway forwarding to another provider rejects. An explicit `ANTHROPIC_API_KEY` selects an independent Claude route: without `ANTHROPIC_BASE_URL`, it keeps the native Anthropic endpoint and defaults to `claude-opus-5-5`. CLI and skill-config model overrides still take precedence. Existing native-provider routes are unchanged.
</Tab>
</Tabs>

Expand Down Expand Up @@ -258,7 +258,7 @@ schema_version: 1
harbor:
agents:
codex:
model: gpt-5.6-sol
model: gpt-6.1-sol
```

You can also supply that model at invocation time with `--agent-model codex=MODEL`. See [Tier 3: Live Evaluation](tier3-live-evaluation.mdx) for the full run workflow.
Expand Down Expand Up @@ -313,7 +313,9 @@ variables.

The `--llm` security analysis runs [SkillSpector](https://github.com/NVIDIA/SkillSpector), which has its own provider environment (`SKILLSPECTOR_PROVIDER` plus per-provider credential variables). SkillEvaluator bridges your configured provider automatically for that invocation, so the one key above is all you need. For `nv_build`, the bridge uses SkillSpector's OpenAI-compatible provider path pointed at the public Build endpoint, so the same `NVIDIA_API_KEY` covers this too; it does not create a second NVIDIA credential name.

The subprocess environment is isolated. Only the selected provider settings and basic process environment variables (`PATH`, `HOME`, TLS bundles, temp dirs) pass through — other ambient credentials in your shell are never forwarded.
The subprocess environment is isolated. Only the selected provider settings and basic process environment variables (`PATH`, `HOME`, TLS bundles, temp dirs) pass through — other ambient credentials in your shell are never forwarded. Your SkillSpector model settings (`SKILLSPECTOR_MODEL_<SLOT>`, `SKILLSPECTOR_MODEL_REGISTRY`, `SKILLSPECTOR_REASONING_EFFORT`) pass through too; `SKILLSPECTOR_TEMPERATURE` does not.

SkillSpector sends its own structured-output requests, so it has its own default model per provider instead of following the chat default. On Anthropic and Bedrock it stays on Claude Opus 5 while the chat default is Claude Opus 5.5. An explicit `SKILL_EVAL_LLM_MODEL` still reaches SkillSpector, and `SKILLSPECTOR_MODEL` overrides both. SkillSpector v2.12.0 does not return structured output for Claude 5.5 models: if `SKILL_EVAL_LLM_MODEL` names one, also set `SKILLSPECTOR_MODEL` to a supported model such as `claude-opus-5` (Bedrock: `us.anthropic.claude-opus-5`), or the `--llm` security stage is reported incomplete. See [SkillSpector bridge](environment-variables.mdx#skillspector-bridge) for the defaults.

Setting `SKILLSPECTOR_PROVIDER` yourself overrides the bridge, but it must name a supported public provider (`openai`, `anthropic`, or `bedrock` — or `nv_build` to force the Build mapping); anything else fails closed and the subprocess receives no credential.

Expand Down
Loading
Loading