Two issues blocked OpenAI-compatible servers that aren't Ollama-on-/v1:
1. LocalAdapter.isOpenAIWire matched only a literal /v1 path, so versioned
endpoints like Zhipu/z.ai's /api/paas/v4 silently fell through to Ollama's
native /api/chat wire format and failed. Match any /vN instead of literally /v1.
2. The `local` provider was treated as always-keyless, so servers that require
a bearer (Zhipu/z.ai, Together, ...) could never authenticate. Read an
optional key from TEMPEST_LOCAL_API_KEY (ZAI_API_KEY / ZHIPUAI_API_KEY as
aliases), wire it through getApiKey/hasApiKey so `tempest test` and the
mission engine accept a configured local provider, and document the options
in the env template.
The key is read from env in-memory and never persisted into the store, matching
the existing env-key hardening invariant (api-key-env-static).
Adds src/__tests__/local-openai-wire-static.test.ts pinning both fixes.
Verified end-to-end against z.ai's GLM models (glm-4.5-air / 4.6 / 5.2).
The opt-in code/supply-chain scanners (semgrep, gitleaks, trufflehog, trivy,
syft, grype, checkov) are subcommand-driven and non-networked, but had no
bespoke arg template — so adapterToCustomTool fell through to DEFAULT_TEMPLATE
and spawned `<binary> <target>`. For these that is a broken invocation:
`semgrep <host>` never runs a scan, and with no target it is `semgrep ''`.
semgrep in particular is advertised on the arsenal's headline tool list.
Add per-binary templates that mirror each tool's catalog commandHint and
operate on a filesystem PATH (default: the working dir "."):
semgrep → scan --config auto --json <path>
gitleaks → detect --source <path> --report-format json --redact --no-banner
trufflehog → filesystem <path> --json --no-update
trivy → fs --format json <path>
syft → dir:<path> -o cyclonedx-json
grype → dir:<path> -o json
checkov → -d <path> -o json
Subcommand + output flags are hardcoded (never taken from an LLM string),
matching the conservative pattern of the existing templates. The path is the
only tunable and is sanitised by scanPath(): a leading '-' (flag injection) or
an inherited http(s) mission target is rejected in favour of ".". Option-looking
targets are still refused up front by the factory's existing guard (no spawn).
Adds table-driven tests asserting the exact argv for each scanner, the "."
default, http(s)-target rejection, and the option-looking-path refusal.
Three new category loadouts, each = arsenal + an offline-scorable benchmark, opt-in and
honestly scoped (roster marks all 🚧; pacu/frida stay catalog_only, unit-tested non-mintable):
- cloud: aws/az/gcloud + scoutsuite/cloudfox/pmapper; cloud:bench IaC-misconfig detection
- mobile: apkleaks/mobsfscan/drozer/objection/class-dump; mobile:bench static ruleset
- binary/RE: ghidra/objdump/checksec/strings/readelf/gdb; binary:bench decompiled-sink detector
Mobile/binary benches are DETECTOR REGRESSION CHECKS (rules+fixtures co-authored — a pass is a
floor, not a detection rate). No new headline numbers; verify-claims 24/24.
tsc clean; 337 tests; lint 0 errors.
Adds three coordinated capabilities and tightens two defaults on purpose — this is
safety hardening, NOT a backward-compatible drop-in (see "Tightened defaults").
Fifteen independent adversarial review passes; findings fixed and test-pinned.
- Pack-hunt safety: a strict-majority adjudicator with a comment/string/regex/
raw-string/heredoc/POD-aware cite-check (language-gated across C/C++/Py/Rust/Go/
Java/JS/TS/shell/SQL/PHP/Ruby/Perl) so a hallucinated killing-guard can't refute
a real finding — the cited comparison's operator must match source, and a
string/regex/heredoc/generic-arglist/template-interpolation is blanked before
matching. Plus a rate-limit/degraded-health tracker, a global LLM semaphore, and
a PackBoard with an atomic claim CAS + snapshot-on-emit/clone-on-ingest.
- Opt-in Kali+ arsenal (T3MP3ST_FULL_ARSENAL, OFF by default): 35 default tools
(31 built-in + 4 external-CLI wrappers) -> 83 with the catalog armed (verify-claims
CLAIM 4). Most adapters need the underlying binary installed. metasploit / hydra /
bloodhound are never minted through the generic factory.
- Capability-approval + spicy-action gate for the NEW dangerous arsenal only
(pre-existing built-ins keep running freely): approve-once, fail-safe deny when
unattended, redacted audit trail over SSE. T3MP3ST_GATE_BUILTINS=1 extends it to
the spicy built-in probes. Audit redaction is a pure, unit-tested module.
Tightened defaults (intentional, ON by default — NOT backward-compatible):
- Egress containment: once a mission target is set, built-in networked tools refuse
off-scope public hosts (not the target/subdomains, not loopback/private) with
SCOPE DENIED — keeps the agent on authorized scope.
- Role-specialized operator toolkits: each archetype gets a curated default tool
menu (scanner -> scan tools, exploiter -> sqli/xss/etc). Tools stay registered
team-wide; the per-role menu is the operator's working set.
UX (from live-tester feedback): a one-click "Approve & run" modal when a standard
Hunt blocks on an external-target receipt (was a dead-end); bounded-parallel
benchmark file ingestion; the deterministic mission-gate chip co-located with the
subjective SITREP pace narration (no more "behind schedule" next to a clean gate);
and click-through finding detail + evidence in the UI (was export-only).
Docs: README + INTEGRITY_LEDGER made re-derivable — honest 35/83 tool count, the
egress-containment default documented, and the Cybench number reconciled to the
single verify-claims-enforced 23/40 = 58% (dropped the stale/uncited 21 and 26).
README voice pass: killed the underselling `Successful Exploits: 0` disqualifier
(read as "never popped anything" — false, given CVE-Zero + the live disclosure
pipeline); swagger now rests on receipts, not vibes. Also corrected the operator
status — the downstream operators run the SAME real tool-backed ReAct loop as
recon (not "orchestration stubs"); the honest limit is that the coordinated swarm
is unproven (single-agent is the benchmarked path), not that they're scaffolding.
Gates: 292 tests, tsc + lint clean, verify-claims 20/20, arsenal:smoke 125/0,
disclosure-CLI self-test 11/11.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>