diff --git a/CHANGELOG.md b/CHANGELOG.md
index c5c9190..5c84d22 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
## Unreleased
+- Use GPT-6 Luna with high reasoning for both bundled ClawHub judges and forward SkillSpector model/reasoning and optional A.I.G reasoning settings into scanner sandboxes.
+
## 0.2.0 - 2026-09-22
**Highlights:** Preserve scanner evidence, bound benchmark input memory, and identify worker-owned containers for cleanup.
diff --git a/README.md b/README.md
index 4d0ffde..c2f10b7 100644
--- a/README.md
+++ b/README.md
@@ -156,11 +156,11 @@ clawscan scanners skillspector
| ID | Name | Repo | Description | Required env vars | Local dependency setup |
| --- | --- | --- | --- | --- | --- |
| `agentverus` | AgentVerus | [repo](https://github.com/agentverus/agentverus-scanner) | Local file or directory scanner invoked through agentverus-scanner. | none | `npm install --save-dev agentverus-scanner` |
-| `aig` | Tencent AI-Infra-Guard | [repo](https://github.com/Tencent/AI-Infra-Guard/tree/main/skill-scan) | Tencent Zhuque Lab's local directory scanner invoked through `aig-skill-scan`. Produces SARIF 2.1.0 with SkillTrustBench T01-T09 evidence. | `LLM_API_KEY` or `OPENAI_API_KEY`
Optional config
DEFAULT_MODEL, DEFAULT_BASE_URL, DEFAULT_MODEL_CONTEXT_WINDOW, LOG_LEVEL. | `pip install aig-skill-scan` |
+| `aig` | Tencent AI-Infra-Guard | [repo](https://github.com/Tencent/AI-Infra-Guard/tree/main/skill-scan) | Tencent Zhuque Lab's local directory scanner invoked through `aig-skill-scan`. Produces SARIF 2.1.0 with SkillTrustBench T01-T09 evidence. | `LLM_API_KEY` or `OPENAI_API_KEY`
Optional config
DEFAULT_MODEL, REASONING_EFFORT (requires upstream support), DEFAULT_BASE_URL, DEFAULT_MODEL_CONTEXT_WINDOW, LOG_LEVEL. | `pip install aig-skill-scan` |
| `cisco` | Cisco AI Defense skill-scanner | [repo](https://github.com/cisco-ai-defense/skill-scanner) | Local file or directory scanner invoked through `skill-scanner` with JSON report output. Optional upstream env vars enable LLM, VirusTotal, and Cisco AI Defense analyzers. | none
Optional config
SKILL_SCANNER_LLM_API_KEY, SKILL_SCANNER_LLM_PROVIDER, SKILL_SCANNER_LLM_MODEL, SKILL_SCANNER_LLM_BASE_URL, SKILL_SCANNER_LLM_USER, SKILL_SCANNER_LLM_API_VERSION, SKILL_SCANNER_LLM_FORCE_JSON_OBJECT, SKILL_SCANNER_META_LLM_API_KEY, SKILL_SCANNER_META_LLM_MODEL, SKILL_SCANNER_META_LLM_BASE_URL, SKILL_SCANNER_META_LLM_API_VERSION, AWS_PROFILE, AWS_REGION, GOOGLE_APPLICATION_CREDENTIALS, VIRUSTOTAL_API_KEY, AI_DEFENSE_API_KEY, AI_DEFENSE_API_URL. | `uv pip install cisco-ai-skill-scanner` |
| `clawscan-static` | ClawScan Static | [repo](https://github.com/openclaw/clawscan) | Built-in deterministic scanner for high-signal risky skill and OpenClaw plugin patterns; packaged Python bytecode and NUL-obfuscated text are flagged and inspected, while opaque binary omissions remain visible as low-severity evidence. | none | skipped; built in |
| `relyable` | Relyable | [repo](https://github.com/veriker/relyable) | Functional re-derivation evidence: does the skill still do what its docs claim, recomputed? Emits the strongest grade that applies. `exogenous`: a declared `rederive.json` property manifest (idempotence / round-trip), with both sides of the relation computed from the skill's own code and the result mutation-tested against vacuity. `self_spec`: re-runs the author's own committed oracle (shipped tests or documented I/O examples). `cold_golden`: when an LLM key is set, a code-blind model infers goldens from SKILL.md alone and abstains unless the docs pin exact behavior; divergences are reported as unconfirmed, never as accusations. `non_rederivable`: the honest floor, never a fabricated pass. Functional axis only; complements the security scanners and does not detect malware or prompt injection. Skill code runs only inside the Docker sandbox (or with an explicit opt-in), in a scrubbed environment, and the scanner fails closed otherwise. Not preinstalled in the `clawscan-runtime` image. | none
Optional config
RELYABLE_SCAN_ALLOW_HOST_EXEC — explicit ack that the host is disposable when running with --sandbox off.
RELYABLE_LLM_API_KEY (+ RELYABLE_LLM_PROVIDER anthropic|openai, RELYABLE_LLM_MODEL, RELYABLE_LLM_BASE_URL) — explicit per-scanner opt-in that enables the cold_golden lane; key presence only is ever recorded in the payload. Generic ANTHROPIC_API_KEY/OPENAI_API_KEY are honored by standalone relyable-scan but are deliberately not auto-forwarded by ClawScan. | `clawscan install relyable` — not preinstalled in the runtime image |
-| `skillspector` | NVIDIA SkillSpector | [repo](https://github.com/NVIDIA/skillspector) | Local skill or OpenClaw plugin file/directory scanner. Uses LLM mode when provider env vars are set; otherwise runs with `--no-llm`. | none
Optional config
SKILLSPECTOR_PROVIDER, SKILLSPECTOR_MODEL, SKILLSPECTOR_MODEL_REGISTRY, SKILLSPECTOR_LOG_LEVEL, SKILLSPECTOR_SSL_VERIFY, NVIDIA_INFERENCE_KEY, OPENAI_API_KEY, OPENAI_BASE_URL, ANTHROPIC_API_KEY, ANTHROPIC_PROXY_ENDPOINT_URL, ANTHROPIC_PROXY_API_KEY, ANTHROPIC_PROXY_API_VERSION. | `uv tool install git+https://github.com/NVIDIA/skillspector.git` |
+| `skillspector` | NVIDIA SkillSpector | [repo](https://github.com/NVIDIA/skillspector) | Local skill or OpenClaw plugin file/directory scanner. Uses LLM mode when provider env vars are set; otherwise runs with `--no-llm`. | none
Optional config
SKILLSPECTOR_PROVIDER, SKILLSPECTOR_MODEL, SKILLSPECTOR_REASONING_EFFORT, SKILLSPECTOR_MODEL_REGISTRY, SKILLSPECTOR_LOG_LEVEL, SKILLSPECTOR_SSL_VERIFY, NVIDIA_INFERENCE_KEY, OPENAI_API_KEY, OPENAI_BASE_URL, ANTHROPIC_API_KEY, ANTHROPIC_PROXY_ENDPOINT_URL, ANTHROPIC_PROXY_API_KEY, ANTHROPIC_PROXY_API_VERSION. | `uv tool install git+https://github.com/NVIDIA/skillspector.git` |
| `snyk` | Snyk Agent Scan | [repo](https://github.com/snyk/agent-scan) | Local skill scanner invoked through `uvx snyk-agent-scan`. | `SNYK_TOKEN` | verifies `uvx` launcher |
| `socket` | Socket CLI | [repo](https://github.com/SocketDev/socket-cli) | Local file or directory scanner using Socket's public CLI full-scan path. | `SOCKET_CLI_API_TOKEN` | `npm install -g socket` |
| `virustotal` | VirusTotal API | [docs](https://docs.virustotal.com/reference/file) | API-backed local file hash lookup. Skill and OpenClaw plugin directories are scanned as deterministic ZIP archives. | `VIRUSTOTAL_API_KEY` | skipped; API-backed |
@@ -199,9 +199,17 @@ clawscan profiles -v
| Profile | Scanners | Judge |
| --- | --- | --- |
-| `clawhub` | `skillspector`, `clawscan-static`, `aig` | Codex `gpt-5.5`, high reasoning, bundled ClawHub prompt/schema |
+| `clawhub` | `skillspector`, `clawscan-static`, `aig` | Codex `gpt-6-luna`, high reasoning, bundled ClawHub prompt/schema |
+| `clawhub-aig` | `skillspector`, `aig` | Codex `gpt-6-luna`, high reasoning, bundled ClawHub prompt/schema |
| `openclaw-install-policy` | `skillspector`, `clawscan-static` | none |
+Set `SKILLSPECTOR_MODEL=gpt-6-luna` and
+`SKILLSPECTOR_REASONING_EFFORT=high` to select the same model and effort for
+SkillSpector. Both settings pass through the Docker sandbox. The A.I.G model
+uses `DEFAULT_MODEL`; its optional `REASONING_EFFORT` setting also passes
+through, but requires an upstream version that supports it. The bundled
+A.I.G 0.2.2 runtime does not yet support reasoning effort.
+
### Build a custom profile with `.clawscan.yml`
Custom profiles can be created in `.clawscan.yml`.
diff --git a/cmd/clawscan/main_test.go b/cmd/clawscan/main_test.go
index 93b21d7..0debdc6 100644
--- a/cmd/clawscan/main_test.go
+++ b/cmd/clawscan/main_test.go
@@ -505,7 +505,7 @@ func TestRunCommandScannerDetailPrintsHumanReadableInfo(t *testing.T) {
"Repository: https://github.com/Tencent/AI-Infra-Guard/tree/main/skill-scan",
"Description: Tencent Zhuque Lab's local directory scanner invoked through aig-skill-scan",
"Required env vars: LLM_API_KEY",
- "Optional env vars: OPENAI_API_KEY, DEFAULT_MODEL, DEFAULT_BASE_URL, DEFAULT_MODEL_CONTEXT_WINDOW, LOG_LEVEL",
+ "Optional env vars: OPENAI_API_KEY, DEFAULT_MODEL, REASONING_EFFORT, DEFAULT_BASE_URL, DEFAULT_MODEL_CONTEXT_WINDOW, LOG_LEVEL",
"Install:",
"pip install aig-skill-scan",
} {
diff --git a/docs/profiles.md b/docs/profiles.md
index 8cde270..1892f3f 100644
--- a/docs/profiles.md
+++ b/docs/profiles.md
@@ -56,9 +56,17 @@ clawscan profiles -v
| Profile | Scanners | Judge |
| --- | --- | --- |
-| `clawhub` | `skillspector`, `clawscan-static`, `aig` | Codex `gpt-5.5`, high reasoning, bundled ClawHub prompt/schema |
+| `clawhub` | `skillspector`, `clawscan-static`, `aig` | Codex `gpt-6-luna`, high reasoning, bundled ClawHub prompt/schema |
+| `clawhub-aig` | `skillspector`, `aig` | Codex `gpt-6-luna`, high reasoning, bundled ClawHub prompt/schema |
| `openclaw-install-policy` | `skillspector`, `clawscan-static` | none |
+Set `SKILLSPECTOR_MODEL=gpt-6-luna` and
+`SKILLSPECTOR_REASONING_EFFORT=high` to select the same model and effort for
+SkillSpector. Both settings pass through the Docker sandbox. The A.I.G model
+uses `DEFAULT_MODEL`; its optional `REASONING_EFFORT` setting also passes
+through, but requires an upstream version that supports it. The bundled
+A.I.G 0.2.2 runtime does not yet support reasoning effort.
+
## Build a custom profile with `.clawscan.yml`
Custom profiles can be created in `.clawscan.yml`.
diff --git a/docs/scanners.md b/docs/scanners.md
index ba310c0..61fc933 100644
--- a/docs/scanners.md
+++ b/docs/scanners.md
@@ -256,7 +256,7 @@ commas, single-quoted strings, and unquoted keys.
| `cisco` | Cisco AI Defense skill-scanner | [repo](https://github.com/cisco-ai-defense/skill-scanner) | Local file or directory scanner invoked through `skill-scanner` with JSON report output. Optional upstream env vars enable LLM, VirusTotal, and Cisco AI Defense analyzers. | none
Optional config
SKILL_SCANNER_LLM_API_KEY, SKILL_SCANNER_LLM_PROVIDER, SKILL_SCANNER_LLM_MODEL, SKILL_SCANNER_LLM_BASE_URL, SKILL_SCANNER_LLM_USER, SKILL_SCANNER_LLM_API_VERSION, SKILL_SCANNER_LLM_FORCE_JSON_OBJECT, SKILL_SCANNER_META_LLM_API_KEY, SKILL_SCANNER_META_LLM_MODEL, SKILL_SCANNER_META_LLM_BASE_URL, SKILL_SCANNER_META_LLM_API_VERSION, AWS_PROFILE, AWS_REGION, GOOGLE_APPLICATION_CREDENTIALS, VIRUSTOTAL_API_KEY, AI_DEFENSE_API_KEY, AI_DEFENSE_API_URL. | `uv pip install cisco-ai-skill-scanner` |
| `clawscan-static` | ClawScan Static | [repo](https://github.com/openclaw/clawscan) | Built-in deterministic scanner for high-signal risky skill and OpenClaw plugin patterns; packaged Python bytecode and NUL-obfuscated text are flagged and inspected, while opaque binary omissions remain visible as low-severity evidence. | none | skipped; built in |
| `relyable` | Relyable | [repo](https://github.com/veriker/relyable) | Functional re-derivation evidence: does the skill still do what its docs claim, recomputed? Emits the strongest grade that applies. `exogenous`: a declared `rederive.json` property manifest (idempotence / round-trip), with both sides of the relation computed from the skill's own code and the result mutation-tested against vacuity. `self_spec`: re-runs the author's own committed oracle (shipped tests or documented I/O examples). `cold_golden`: when an LLM key is set, a code-blind model infers goldens from SKILL.md alone and abstains unless the docs pin exact behavior; divergences are reported as unconfirmed, never as accusations. `non_rederivable`: the honest floor, never a fabricated pass. Functional axis only; complements the security scanners and does not detect malware or prompt injection. Skill code runs only inside the Docker sandbox (or with an explicit opt-in), in a scrubbed environment, and the scanner fails closed otherwise. Not preinstalled in the `clawscan-runtime` image. | none
Optional config
RELYABLE_SCAN_ALLOW_HOST_EXEC — explicit ack that the host is disposable when running with --sandbox off.
RELYABLE_LLM_API_KEY (+ RELYABLE_LLM_PROVIDER anthropic|openai, RELYABLE_LLM_MODEL, RELYABLE_LLM_BASE_URL) — explicit per-scanner opt-in that enables the cold_golden lane; key presence only is ever recorded in the payload. Generic ANTHROPIC_API_KEY/OPENAI_API_KEY are honored by standalone relyable-scan but are deliberately not auto-forwarded by ClawScan. | `clawscan install relyable` — not preinstalled in the runtime image |
-| `skillspector` | NVIDIA SkillSpector | [repo](https://github.com/NVIDIA/skillspector) | Local skill or OpenClaw plugin file/directory scanner. Uses LLM mode when provider env vars are set; otherwise runs with `--no-llm`. | none
Optional config
SKILLSPECTOR_PROVIDER, SKILLSPECTOR_MODEL, SKILLSPECTOR_MODEL_REGISTRY, SKILLSPECTOR_LOG_LEVEL, SKILLSPECTOR_SSL_VERIFY, NVIDIA_INFERENCE_KEY, OPENAI_API_KEY, OPENAI_BASE_URL, ANTHROPIC_API_KEY, ANTHROPIC_PROXY_ENDPOINT_URL, ANTHROPIC_PROXY_API_KEY, ANTHROPIC_PROXY_API_VERSION. | `uv tool install git+https://github.com/NVIDIA/skillspector.git` |
+| `skillspector` | NVIDIA SkillSpector | [repo](https://github.com/NVIDIA/skillspector) | Local skill or OpenClaw plugin file/directory scanner. Uses LLM mode when provider env vars are set; otherwise runs with `--no-llm`. | none
Optional config
SKILLSPECTOR_PROVIDER, SKILLSPECTOR_MODEL, SKILLSPECTOR_REASONING_EFFORT, SKILLSPECTOR_MODEL_REGISTRY, SKILLSPECTOR_LOG_LEVEL, SKILLSPECTOR_SSL_VERIFY, NVIDIA_INFERENCE_KEY, OPENAI_API_KEY, OPENAI_BASE_URL, ANTHROPIC_API_KEY, ANTHROPIC_PROXY_ENDPOINT_URL, ANTHROPIC_PROXY_API_KEY, ANTHROPIC_PROXY_API_VERSION. | `uv tool install git+https://github.com/NVIDIA/skillspector.git` |
| `snyk` | Snyk Agent Scan | [repo](https://github.com/snyk/agent-scan) | Local skill scanner invoked through `uvx snyk-agent-scan`. | `SNYK_TOKEN` | verifies `uvx` launcher |
| `socket` | Socket CLI | [repo](https://github.com/SocketDev/socket-cli) | Local file or directory scanner using Socket's public CLI full-scan path. | `SOCKET_CLI_API_TOKEN` | `npm install -g socket` |
| `virustotal` | VirusTotal API | [docs](https://docs.virustotal.com/reference/file) | API-backed local file hash lookup. Skill and OpenClaw plugin directories are scanned as deterministic ZIP archives. | `VIRUSTOTAL_API_KEY` | skipped; API-backed |
diff --git a/internal/profiles/clawhub/clawscan.yml b/internal/profiles/clawhub/clawscan.yml
index e4bd6a9..2597aee 100644
--- a/internal/profiles/clawhub/clawscan.yml
+++ b/internal/profiles/clawhub/clawscan.yml
@@ -11,14 +11,17 @@ profiles:
- OPENAI_API_KEY
- CODEX_API_KEY
- SKILLSPECTOR_PROVIDER
+ - SKILLSPECTOR_MODEL
+ - SKILLSPECTOR_REASONING_EFFORT
- LLM_API_KEY
- DEFAULT_MODEL
+ - REASONING_EFFORT
- DEFAULT_BASE_URL
judge:
command: >-
[ -n "$CODEX_API_KEY" ] || export CODEX_API_KEY="$OPENAI_API_KEY";
codex exec --cd {{ workspace }}
- --model gpt-5.5
+ --model gpt-6-luna
--sandbox {{ judge_sandbox }}
--skip-git-repo-check
--ignore-user-config
@@ -41,14 +44,17 @@ profiles:
- OPENAI_API_KEY
- CODEX_API_KEY
- SKILLSPECTOR_PROVIDER
+ - SKILLSPECTOR_MODEL
+ - SKILLSPECTOR_REASONING_EFFORT
- LLM_API_KEY
- DEFAULT_MODEL
+ - REASONING_EFFORT
- DEFAULT_BASE_URL
judge:
command: >-
[ -n "$CODEX_API_KEY" ] || export CODEX_API_KEY="$OPENAI_API_KEY";
codex exec --cd {{ workspace }}
- --model gpt-5.5
+ --model gpt-6-luna
--sandbox {{ judge_sandbox }}
--skip-git-repo-check
--ignore-user-config
diff --git a/internal/profiles/resolver_test.go b/internal/profiles/resolver_test.go
index 02c863d..c232a1a 100644
--- a/internal/profiles/resolver_test.go
+++ b/internal/profiles/resolver_test.go
@@ -66,7 +66,7 @@ func TestResolveArgsUsesEmbeddedClawHubProfile(t *testing.T) {
if string(opts.Judge.Files["clawhub/output.schema.json"]) == "" {
t.Fatal("expected embedded clawhub output schema file")
}
- if got := strings.Join(opts.Sandbox.Env, ","); got != "OPENAI_API_KEY,CODEX_API_KEY,SKILLSPECTOR_PROVIDER,LLM_API_KEY,DEFAULT_MODEL,DEFAULT_BASE_URL" {
+ if got := strings.Join(opts.Sandbox.Env, ","); got != "OPENAI_API_KEY,CODEX_API_KEY,SKILLSPECTOR_PROVIDER,SKILLSPECTOR_MODEL,SKILLSPECTOR_REASONING_EFFORT,LLM_API_KEY,DEFAULT_MODEL,REASONING_EFFORT,DEFAULT_BASE_URL" {
t.Fatalf("sandbox env = %q", got)
}
}
@@ -100,22 +100,28 @@ func TestResolveArgsUsesEmbeddedClawHubAIGCandidateProfile(t *testing.T) {
t.Fatalf("candidate judge file %s differs from clawhub", path)
}
}
- if got := strings.Join(candidate.Sandbox.Env, ","); got != "OPENAI_API_KEY,CODEX_API_KEY,SKILLSPECTOR_PROVIDER,LLM_API_KEY,DEFAULT_MODEL,DEFAULT_BASE_URL" {
+ if got := strings.Join(candidate.Sandbox.Env, ","); got != "OPENAI_API_KEY,CODEX_API_KEY,SKILLSPECTOR_PROVIDER,SKILLSPECTOR_MODEL,SKILLSPECTOR_REASONING_EFFORT,LLM_API_KEY,DEFAULT_MODEL,REASONING_EFFORT,DEFAULT_BASE_URL" {
t.Fatalf("sandbox env = %q", got)
}
}
-func TestClawHubProfilesAliasOpenAIKeyForCodex(t *testing.T) {
+func TestClawHubProfilesConfigureCodex(t *testing.T) {
for _, profile := range []string{"clawhub", "clawhub-aig"} {
t.Run(profile, func(t *testing.T) {
opts, err := ResolveArgs([]string{"./skill", "--profile", profile}, t.TempDir())
if err != nil {
t.Fatal(err)
}
- prefix, _, ok := strings.Cut(opts.Judge.Command, "codex exec")
- if !ok {
+ if !strings.Contains(opts.Judge.Command, "codex exec") {
t.Fatalf("judge command missing codex exec: %q", opts.Judge.Command)
}
+ command := strings.NewReplacer(
+ "{{ workspace }}", "fixture-workspace",
+ "{{ judge_sandbox }}", "read-only",
+ "{{ output_schema:clawhub/output.schema.json }}", "fixture-schema",
+ "{{ output }}", "fixture-output",
+ "{{ prompt:clawhub/prompt.md }}", "/dev/null",
+ ).Replace(opts.Judge.Command)
for _, test := range []struct {
name string
@@ -127,7 +133,7 @@ func TestClawHubProfilesAliasOpenAIKeyForCodex(t *testing.T) {
{name: "explicit codex key wins", openAI: "openai-marker", codex: "codex-marker", output: "codex-marker"},
} {
t.Run(test.name, func(t *testing.T) {
- cmd := exec.Command("sh", "-c", prefix+`sh -c 'printf %s "$CODEX_API_KEY"'`)
+ cmd := exec.Command("sh", "-c", `codex() { printf '%s\n' "$CODEX_API_KEY" "$@"; }; `+command)
cmd.Env = append(
os.Environ(),
strings.Join([]string{"OPENAI_API_KEY", test.openAI}, "="),
@@ -137,8 +143,15 @@ func TestClawHubProfilesAliasOpenAIKeyForCodex(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- if got := string(output); got != test.output {
- t.Fatalf("CODEX_API_KEY = %q, want %q", got, test.output)
+ lines := strings.Split(strings.TrimSpace(string(output)), "\n")
+ if lines[0] != test.output {
+ t.Fatalf("CODEX_API_KEY = %q, want %q", lines[0], test.output)
+ }
+ args := strings.Join(lines[1:], "\x00")
+ for _, want := range []string{"--model\x00gpt-6-luna\x00", "-c\x00model_reasoning_effort=high\x00"} {
+ if !strings.Contains(args, want) {
+ t.Fatalf("codex arguments missing %q: %#v", want, lines[1:])
+ }
}
})
}
@@ -693,7 +706,7 @@ func TestResolveArgsAppliesCLIOverrides(t *testing.T) {
if opts.Sandbox.Image != "ghcr.io/acme/runtime:v1" {
t.Fatalf("sandbox image = %q", opts.Sandbox.Image)
}
- if got := strings.Join(opts.Sandbox.Env, ","); got != "OPENAI_API_KEY,CODEX_API_KEY,SKILLSPECTOR_PROVIDER,LLM_API_KEY,DEFAULT_MODEL,DEFAULT_BASE_URL,ANTHROPIC_API_KEY" {
+ if got := strings.Join(opts.Sandbox.Env, ","); got != "OPENAI_API_KEY,CODEX_API_KEY,SKILLSPECTOR_PROVIDER,SKILLSPECTOR_MODEL,SKILLSPECTOR_REASONING_EFFORT,LLM_API_KEY,DEFAULT_MODEL,REASONING_EFFORT,DEFAULT_BASE_URL,ANTHROPIC_API_KEY" {
t.Fatalf("sandbox env = %q", got)
}
}
diff --git a/internal/runner/aig_scanner_test.go b/internal/runner/aig_scanner_test.go
index 253a3f7..aca7a65 100644
--- a/internal/runner/aig_scanner_test.go
+++ b/internal/runner/aig_scanner_test.go
@@ -149,7 +149,11 @@ func TestAIGScannerDockerRunMountsTargetAndOutputDirectory(t *testing.T) {
t.Fatal(err)
}
artifact, err := Run(opts, RunContext{
- Env: map[string]string{"LLM_API_KEY": "present"},
+ Env: map[string]string{
+ "LLM_API_KEY": "present",
+ "DEFAULT_MODEL": "gpt-6-luna",
+ "REASONING_EFFORT": "high",
+ },
HostCommandRunner: hostRunner,
DockerAvailability: func() error { return nil },
})
@@ -166,6 +170,11 @@ func TestAIGScannerDockerRunMountsTargetAndOutputDirectory(t *testing.T) {
if call.command != "docker" {
t.Fatalf("command = %q", call.command)
}
+ for _, name := range []string{"LLM_API_KEY", "DEFAULT_MODEL", "REASONING_EFFORT"} {
+ if !containsArgPair(call.args, "-e", name) {
+ t.Fatalf("docker args missing env %q: %#v", name, call.args)
+ }
+ }
outputPath := argValue(call.args, "-o")
outputDir := filepath.Dir(outputPath)
if !containsArgPair(call.args, "-w", outputDir) {
diff --git a/internal/runner/scanner_registry.go b/internal/runner/scanner_registry.go
index 1cce62a..16e7f26 100644
--- a/internal/runner/scanner_registry.go
+++ b/internal/runner/scanner_registry.go
@@ -229,6 +229,7 @@ func defaultScannerAdapters() []ScannerAdapter {
OptionalEnv: []string{
"OPENAI_API_KEY",
"DEFAULT_MODEL",
+ "REASONING_EFFORT",
"DEFAULT_BASE_URL",
"DEFAULT_MODEL_CONTEXT_WINDOW",
"LOG_LEVEL",
@@ -341,6 +342,7 @@ func defaultScannerAdapters() []ScannerAdapter {
OptionalEnv: []string{
"SKILLSPECTOR_PROVIDER",
"SKILLSPECTOR_MODEL",
+ "SKILLSPECTOR_REASONING_EFFORT",
"SKILLSPECTOR_MODEL_REGISTRY",
"SKILLSPECTOR_LOG_LEVEL",
"SKILLSPECTOR_SSL_VERIFY",
diff --git a/internal/runner/scanner_registry_test.go b/internal/runner/scanner_registry_test.go
index 96bc35c..c1f8a60 100644
--- a/internal/runner/scanner_registry_test.go
+++ b/internal/runner/scanner_registry_test.go
@@ -91,6 +91,33 @@ func TestDefaultScannerRegistryContainsAllBuiltIns(t *testing.T) {
}
}
+func TestSkillSpectorModelSettingsReachDocker(t *testing.T) {
+ env := map[string]string{
+ "SKILLSPECTOR_MODEL": "gpt-6-luna",
+ "SKILLSPECTOR_REASONING_EFFORT": "high",
+ }
+ opts := Options{Scanners: []string{"skillspector"}}
+ host := &recordingCommandRunner{}
+ commandRunner := dockerCommandRunner{
+ Host: host, Env: env, Image: DefaultSandboxImage,
+ EnvNames: sandboxEnvNames(opts, env),
+ }
+ if _, err := commandRunner.Run("skillspector", []string{"scan", "fixture"}, "", 0); err != nil {
+ t.Fatal(err)
+ }
+ if len(host.calls) != 1 || host.calls[0].command != "docker" {
+ t.Fatalf("calls = %#v", host.calls)
+ }
+ for name := range env {
+ if !containsArgPair(host.calls[0].args, "-e", name) {
+ t.Fatalf("docker args missing env %q: %#v", name, host.calls[0].args)
+ }
+ }
+ if got := sandboxEnvNames(opts, map[string]string{}); len(got) != 0 {
+ t.Fatalf("unset optional env should not be forwarded: %#v", got)
+ }
+}
+
func TestScannerAdaptersDeclareTargetKindSupport(t *testing.T) {
registry := DefaultScannerRegistry()
for _, id := range registry.IDs() {
@@ -340,7 +367,7 @@ func TestDefaultScannerRegistryProvidesCatalogInfo(t *testing.T) {
}
skillspector, _ := registry.Info("skillspector")
- if got := strings.Join(skillspector.OptionalEnv, ","); got != "SKILLSPECTOR_PROVIDER,SKILLSPECTOR_MODEL,SKILLSPECTOR_MODEL_REGISTRY,SKILLSPECTOR_LOG_LEVEL,SKILLSPECTOR_SSL_VERIFY,NVIDIA_INFERENCE_KEY,OPENAI_API_KEY,OPENAI_BASE_URL,ANTHROPIC_API_KEY,ANTHROPIC_PROXY_ENDPOINT_URL,ANTHROPIC_PROXY_API_KEY,ANTHROPIC_PROXY_API_VERSION" {
+ if got := strings.Join(skillspector.OptionalEnv, ","); got != "SKILLSPECTOR_PROVIDER,SKILLSPECTOR_MODEL,SKILLSPECTOR_REASONING_EFFORT,SKILLSPECTOR_MODEL_REGISTRY,SKILLSPECTOR_LOG_LEVEL,SKILLSPECTOR_SSL_VERIFY,NVIDIA_INFERENCE_KEY,OPENAI_API_KEY,OPENAI_BASE_URL,ANTHROPIC_API_KEY,ANTHROPIC_PROXY_ENDPOINT_URL,ANTHROPIC_PROXY_API_KEY,ANTHROPIC_PROXY_API_VERSION" {
t.Fatalf("skillspector optional env = %q", got)
}
@@ -358,7 +385,7 @@ func TestDefaultScannerRegistryProvidesCatalogInfo(t *testing.T) {
if got := strings.Join(aig.RequiredEnv, ","); got != "LLM_API_KEY" {
t.Fatalf("aig required env = %q", got)
}
- if got := strings.Join(aig.OptionalEnv, ","); got != "OPENAI_API_KEY,DEFAULT_MODEL,DEFAULT_BASE_URL,DEFAULT_MODEL_CONTEXT_WINDOW,LOG_LEVEL" {
+ if got := strings.Join(aig.OptionalEnv, ","); got != "OPENAI_API_KEY,DEFAULT_MODEL,REASONING_EFFORT,DEFAULT_BASE_URL,DEFAULT_MODEL_CONTEXT_WINDOW,LOG_LEVEL" {
t.Fatalf("aig optional env = %q", got)
}
if aig.InstallHint != "pip install aig-skill-scan" {