* fix(ui): route OBSIDIVM benchmarks through any backend, not OpenRouter-only
The OBSIDIVM benchmark/self-improvement UI ran its own client-side,
OpenRouter-only LLM path: getApiKey() read only the OpenRouter key, every
call hardcoded openrouter.ai, and the gate hard-blocked with "Configure
OpenRouter API key first" — so a configured Venice key was ignored and a
connected local agent was never used.
Add a client-side backend resolver (OpenRouter key -> Venice key -> connected
agent -> server LLM) and route all benchmark executors, judges, and gates
through it:
- resolveLLMBackend() + LLM_BACKEND_HINT; safeLLMCall()/_safeLLMCallOnce()
become backend-aware (Venice uses api.venice.ai with a Venice-valid model;
OpenRouter unchanged). _backendCall() routes keyless backends through the
existing server endpoints: /api/agents/local/dispatch (drives the connected
Claude Code/Codex/Hermes agent) and /api/llm/chat (server LLM).
- runLiveBenchmark, ctfCallLLM, the self-improvement analyzer, and the config
optimizer now call safeLLMCall instead of a hardcoded openrouter.ai fetch.
- Live-Test / improvement-loop gates and runLLMJudge accept any backend.
Client-side only; no server changes (endpoints already existed). The
recon-only SPECTRA helper is intentionally left OpenRouter-only (out of scope).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(ui): keyless routing must use the API base URL (cross-origin) + model consistency
Addresses review feedback on the OBSIDIVM backend-routing PR.
1. Relative keyless URLs broke the primary cross-origin deployment. _backendCall
fetched '/api/agents/local/dispatch' and '/api/llm/chat' as RELATIVE URLs, but
when the static War Room (GitHub Pages docs/) talks to a separate backend the
app sets T3MP3ST_API.baseUrl = http://<host>:3333. There the relative fetches
hit the Pages origin → 404/CORS, so the headline local-agent / server-LLM
routing silently failed (worked only same-origin). Fix: prefix
`${T3MP3ST_API.baseUrl}` on both; empty base stays relative for same-origin.
Verified: with baseUrl set, both now resolve to http://<host>:3333/api/...
2. Model default consistency. Four benchmark fallbacks read
'anthropic/claude-opus-4.8', out of step with the state default, the <option>,
renderModels and saveApiKey (all 'claude-opus-4.6'). Reverted to 4.6 to match.
(The /api/agents/local/dispatch server route exists — src/server.ts.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(ui): backend-aware gates on the last OpenRouter-only benchmark paths
Addresses the re-review on this PR: two flows this PR claims support Venice /
connected local agent / server LLM still hard-gated on an OpenRouter key.
1. runSingleBenchTest() (single benchmark click): replaced the getApiKey()
length check with `resolveLLMBackend().kind === 'none'` (+ LLM_BACKEND_HINT),
matching runBenchmarks('live'). A Venice-only / agent / server backend can now
click-run a single test instead of being blocked before safeLLMCall().
2. Self-improvement auto-apply:
- autoApplyForLoop() now falls back to applyFallbackImprovements() only when
NO backend exists (resolveLLMBackend().kind === 'none'), not merely when the
OpenRouter key is empty — so the optimizer step uses Venice/agent/server.
- autoApplyRecommendations() entry gate uses the backend check.
- The Auto-Apply button show/hide (displayAnalysis) uses `hasBackend =
resolveLLMBackend().kind !== 'none'` instead of an OpenRouter-only key test.
Verified: gates pass for venice/agent/server, block only when kind==='none';
node --check clean on the inline scripts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The Settings agent card's render() set window.__t3mpLiveAgents from CLIENT-side
pings only (Object.keys(pingStatus).filter(ok)). Agents connected server-side —
via autoReconnect (ping:false) or a status?check=1 re-ping — are live on the
server even though this client never pinged them, so every re-render reset the
count to 0. Since upstream's t3mpHasBackend() is now `llmAvailable || live > 0`,
that clobber made the War Room show "No LLM backbone — connect an agent before
hunting" on localhost even with a genuinely-live local agent (repro: 3 agents
connected, hermes lastPing.ok on the server, yet hasBackend=false after any
detect/render).
Fix: live = max(client-pinged-ok, server-reported-live), reading the server's
own agent state (window.__t3mpServerAgents, refreshed via status?check=1). The
summary and the global now both reflect reality and re-renders no longer break
the gate. Verified: hasBackend stays true across detect/connect re-renders.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The nine "Pliny Specials" dashboard cards (HYDRA / ARACHNE / CERBERUS /
GORGON / SPHINX / LEVIATHAN / TYPHON / GRIFFIN / SIMURGH) were decorative.
Their backend routes were retired long ago; the in-browser versions ran
randomized [SIMULATED] output; none of them were ever on the hunt path.
They only inflated the arsenal with power:100 / offense:100 stat bars that
measured nothing.
Cut them entirely — the cards, the ~5k-line client-side engine block, their
helper functions (runPlinyDemo / renderStatBars / the tabbed info panel),
the associated CSS, and the "Pliny Specials" category filter. The real
tools (CHIMERA / SPECTRA / ORACLE and the rest of the arsenal) are untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>