⚠️ This README is STALE — it predates the two biggest architecture reversals and is retained only for the spike history below. Source of truth: CLAUDE.md + docs/roadmap.md. What changed since this was written:
- Runtime: eve is GUTTED → the engine is the Claude Agent SDK, direct to Anthropic (
engine/audit.ts); no eve, no Vercel AI Gateway. (This doc's "eve, not Claude Agent SDK" is now reversed.)- Host: NOT Vercel serverless → a container/VM for the audit worker (Phase 6,
deploy/); the sandbox isdocker run --network noneviaengine/tools/run-simnet-poc.ts, not an eve backend.- The
agent/layout below is eve-era. Real engine tools live inengine/tools/(fetch_contract_source+run_simnet_pocONLY);find_value_contractswas REMOVED (discovery is currently MISSING — re-add perdocs/plans/discovery-find-value-contracts.md).- Repo renamed
audit-sentinel→sentinel.
Continuous Stacks asset-safety audit pipeline. A separate project, powered by
secondlayer — it depends on the published @secondlayer/* packages and
consumes secondlayer's hosted services (Index / Subgraphs / Streams /
Subscriptions) over HTTP with an API key. secondlayer is a dependency, not a
parent; this repo lives outside the secondlayer monorepo with its own release
cadence, license, and business.
Runtime: eve (Vercel's durable agent framework). Validated sandbox-PoC-first.
The load-bearing seam — safely reproduce a confirmed vuln in an isolated Clarity
VM — works end to end. simnet/poc/finding-1.ts reproduces audit Finding 1
(socialize-debt forces unbounded LP loss) on the v0-vault-sbtc vault:
bun run poc:finding-1 # 15/15 assertions pass
One authorized-contracts call drives total-assets to 0, LP redeem() reverts
with ERR-OUTPUT-ZERO, and 50,001,000 sats stay locked in the contract — no
mainnet, no network, deterministic.
- Run the spike — done (this dir).
- eve, not Claude Agent SDK — adopted as runtime.
- Vercel host — schedules → Vercel Cron; sandbox → Vercel Sandbox.
- Opus 4.8 + ceilings —
model: "anthropic/claude-opus-4.8"(agent/agent.ts). Smoke test confirmed eve loads it and routes to the AI Gateway; the gateway rejects it on the free tier (403 — add paid credits). Add Vercel AI Gateway credits to run Opus. Long fan-out audits rely on eve's durable, checkpointed sessions to survive Vercel function limits — confirm concurrency/ duration quotas before the first big sweep.
eve build compiles the full project (3 tools, 7 subagents, schedule, channel);
the built Nitro server boots and serves /eve/v1. A POST to /eve/v1/session
emits session.started {modelId: anthropic/claude-opus-4.8} → message.received
→ gateway 403 (free tier). Integration is green end to end; only billing blocks
the actual Opus response.
- Node ≥ 24 (eve hard requirement; repo was on 22). Installed via nvm.
aioverride 6.0.167 → 7.0.0-beta.178 in rootpackage.json(eve 0.12 pins it).@secondlayer/stacks(the only otheraiconsumer) still builds clean.- app
zod3.25 → 4.4.3 (eve's schema normalizer uses zod-v4 internals; a v3 schema made it crash withCannot read properties of undefined (reading 'input')). - eve's
devTUI needs an interactive stdin and--no-uiis buggy in 0.12.0; use the built server (eve build+node .output/server/index.mjs) for headless/CI, orbun run devin a real terminal for the TUI.
- simnet uses
@stacks/clarinet-sdk(3.20.0, the new home of clarinet-sdk), not@hirosystems/clarinet-sdk. - clarity values use
@secondlayer/stacks/clarity(Cl), not@stacks/transactions— dogfooding our own package. Wire-compatible because@stacks/clarinet-sdkships the same new string-typed CV representation.
agent/
agent.ts # defineAgent — Opus 4.8
instructions.md # orchestrator persona + guardrails
tools/
fetch_contract_source.ts # /v2/contracts/source (proven)
find_value_contracts.ts # TVL-ranked targets (stub -> Index/subgraph)
run_simnet_poc.ts # runs a simnet PoC in eve's deny-all sandbox
subagents/ # auditor-access-control, auditor-reentrancy, verifier
# (4 more dims mirror these)
schedules/weekly-sweep.ts # cron "0 9 * * 1" -> Vercel Cron
simnet/
contracts/sbtc-token.clar # permissive SIP-010 mock (test plumbing)
contracts/vault.clar # reduced vault; socialize-debt/redeem/convert VERBATIM
poc/finding-1.ts # the runnable reproduction (clarinet-sdk wasm VM)
vault.clar copies the vulnerable functions (socialize-debt, redeem,
deposit, total-assets, conversions) verbatim from mainnet. Only test plumbing
is reduced — local sBTC mock, simplified DAO auth, same-block pass-through
accrue — none of which touches the vulnerability. as-contract is used for the
self-principal (valid on Clarity 3; becomes as-contract? in Clarity 4).
agent/sandbox.ts uses eve's docker() backend with networkPolicy: "deny-all" — OSS, no Vercel, no KVM. Simnet/exploit PoCs need zero egress, so deny-all is a perfect fit. The runner image (simnet/Dockerfile) bakes bun + @stacks/clarinet-sdk + @secondlayer/stacks + the PoC, so the sandbox is self-contained and offline.
Validated airgapped:
bun run sandbox:build # docker build -t audit-sentinel-simnet:local simnet
bun run sandbox:run # docker run --rm --network none ... → Finding-1, 15/15, no network
Researched upgrade paths: gVisor runsc (stronger no-KVM isolation) → microsandbox() Network.none() (microVM, needs KVM) → Daytona behind a custom SandboxBackend for the multi-tenant phase (note: AGPL-3.0 — needs legal sign-off before shipping in a proprietary product; E2B / Alibaba OpenSandbox are Apache-2.0 fallbacks).
- ✅ Remaining 4 auditor dimensions ported (share-accounting, interest-math, flashloan-economics, invariants-dos) — 7 subagents total.
- ❌ STALE:
find_value_contractswas REMOVED in the eve→Agent-SDK migration (it was an eve tool). Discovery is currently MISSING — re-add perdocs/plans/discovery-find-value-contracts.md.subgraphs/token-balances.tsis a DEFINED-but-undeployed schema (superseded byasset-holdings.ts). - ✅ secondlayer-webhook HTTP bridge (
webhooks/secondlayer-webhook.ts) — verifies the signature and forwards to/eve/v1/session. (NativedefineChannelroute is deferred: 0.12.0's channel generics are heavy and the HTTP-channel doc 404s.)
- Add Vercel AI Gateway paid credits, then re-run the smoke test for a live Opus response (and a tool-calling round-trip).
- Deploy
token-balancessubgraph; setSECONDLAYER_API_URL/_API_KEY. - Confirm Vercel function concurrency/duration ceilings for ~1M-token sweeps.