Traverse Permanence & Security Audit
Full-framework analysis of durability/determinism guarantees and security risk vs. opportunity.
Source: specs, crates, CI gates, SECURITY.md · July 2026
Spec vs. implementation readiness
Isolation (WASM sandbox + WASI deny-by-default) is specified, implemented, and close to production-ready. CI gates (coverage, supply-chain, contractual checks) are specified and implemented for 3 of 6 crates, but not production-ready across the workspace — the CLI's ~9k-line HTTP surface and the MCP server both ship outside the coverage gate.
Findings register
| Severity | Domain | Location | Finding |
|---|---|---|---|
| Critical | Security | security.rs:46-49 · http_api.rs | Runtime defaults to Development; unsigned artifacts allowed; HTTP serve never forces Production. |
| Critical | Security | security.rs:120-147 · http_api.rs:983+ | JWT identity derived by base64 payload parse only — no signature/JWKS verification; alg:none accepted in tests. |
| High | Security | http_api.rs:938-951 | Arbitrary bearer strings become subject_id; --allow-unauthenticated and loopback bypasses enable impersonation. |
| High | Security | security.rs:287-310 | Sigstore verification is a verified:// stub; CI uses placeholder bundles as if verified. |
| High | Security | traverse-mcp/stdio_server.rs | MCP stdio has no auth — any stdin writer can execute capabilities and read full traces. |
| High | Permanence | events/broker.rs · types.rs | Event replay is in-memory only (default 5m retention); no durable journal, WAL, or cross-restart permanence. |
| Medium | Security | security.rs:156-185 · wasm.rs | Runtime checksum gate missing from verify_artifact; SHA-256 only optional in WasmExecutor. |
| Medium | Security | events/types.rs:19-39 | TraverseEvent lacks subject_id/actor_id — identity not propagated to events or subscription filters (spec 030 FR-006/016). |
| Medium | Security | security.rs:187-204 | Governed-artifact trust level uses path/URL heuristics, not registry or approved-specs lookup. |
| Medium | Permanence | data_store.rs | Only Memory + LocalFile adapters; no SQLite/cloud durability, no workspace-scoped keys, no integrity hashes on records. |
| Medium | Permanence | trace/private.rs | Private traces hash I/O well, but traces are not an append-only durable store — audit evidence is process-lifetime. |
| Medium | Governance | approved-specs.json · 022 | MCP stdio server implemented and CI-required but spec 022 unapproved; specs 057–059 approved but unimplemented. |
| Medium | Governance | ci/coverage-targets.txt | 100% coverage enforced only for contracts/registry/runtime — CLI (~9k LOC http_api) and MCP ungated. |
| Low | Security | SECURITY.md:11 | Vulnerability reporting path points to a stale personal SUPPORT.md path (cogolo). |
| Low | Architecture | spec 051 · crates/traverse-registry | Registry extraction approved but not executed — dual-source risk with capability publish targeting external repo. |
Permanence guarantee matrix
What the framework claims to keep durable, deterministic, or attributable — vs. what code actually preserves across process restart and time.
| Guarantee | Specified | Implemented | Gap |
|---|---|---|---|
| Deterministic execution (same inputs → same outputs) | Yes (constitution + NFRs) | Partial — WASM/expedition strong; inference/Ollama non-deterministic | No formal determinism test suite across executors |
| Immutable governing specs | Yes (approved-specs.json) | Yes — registry marks immutable | Some approved specs still say Status: Draft in headers |
| Artifact integrity (signature + checksum) | Yes (030, 031) | Ed25519 real; Sigstore stub; checksum optional | Production path can skip checksum; Sigstore false confidence |
| Event replay / recovery | Yes (036) | In-process cursor replay + retention prune | No durable log; restart loses buffer; default 5m window |
| Audit trail permanence | Partial (030 NFR-003, 035 audit JSONL) | HTTP audit JSONL; execution traces in-memory/export | No tamper-evident, append-only, long-retention audit store |
| Identity-bound evidence | Yes (030 FR-006) | Derived identity on request path | Events/subscriptions omit subject_id — audit cannot attribute emitters |
| App / workspace state durability | Partial (032, 052) | LocalFileDataStore + .traverse workspace state | No multi-node durability; no record integrity seals |
| Contractual immutability at execution | Yes (040) | Draft quarantine + contractual CI gate | Gate validates JSON shape, not runtime behavioral equivalence |
Security & permanence strengths
Security strengths
- Ed25519 artifact verification is real and deterministic
- WASM deny-by-default WASI + ABI import CI gate
- Draft contract quarantine at execution boundary
- HTTP workspace auth, scopes, audit JSONL (partial)
- Supply-chain CI: lockfile, SBOM, reproducible build checks
- No production unsafe; hot paths largely avoid unwrap/panic
Permanence strengths
- Approved specs marked immutable in governance registry
- Cursor replay + duplicate event_id suppression (036)
- Private traces hash inputs/outputs (no raw I/O leakage)
- Semver progression and contractual enforcement gates
- Expedition WASM path is a deterministic vertical slice
- LocalFileDataStore provides basic on-disk persistence
Crate maturity & blast radius
| Crate | Maturity | Coverage | Risk signal |
|---|---|---|---|
| traverse-contracts | Mature | 100% gated | Low |
| traverse-registry | Mature (extraction pending) | 100% gated | Med — dual home |
| traverse-runtime | Core / mature | 100% gated | Med — security defaults |
| traverse-cli | Real, monolithic | Ungated | High — 9k LOC HTTP TCB |
| traverse-mcp | Functional (docs say stub) | Ungated | High if exposed |
| traverse-expedition-wasm | Reference binary | Ungated | Low |
Opportunity roadmap
Ranked by risk reduction per effort. P0 items close exploit paths that contradict approved specs 030/031 today.
| Opportunity | Why it matters | Effort |
|---|---|---|
| Flip production security default + real JWT verify | Closes the two highest exploit paths before any network exposure | M |
| Replace Sigstore stub; add runtime checksum to verify_artifact | Makes artifact permanence/integrity claims honest | M |
| Durable event journal + configurable long retention | Turns 036 replay from session recovery into real permanence | L |
| Propagate subject_id/actor_id into TraverseEvent + filters | Enables attributable audit and multi-tenant event isolation | S |
| MCP auth boundary + redacted traces | Prevents local-tool surface from becoming full execution authority | S |
| Coverage-gate CLI http_api + MCP | Largest TCB is currently outside the 100% coverage constitution claim | M |
| Execute registry extraction (051) cleanly | Removes dual-source permanence risk for governed artifacts | L |
| First connector plugin + SQLite data adapter | Unlocks durable external I/O without expanding host ABI surface | M |
| Formal threat model + fix SECURITY.md reporting path | Documents trust boundaries operators currently must infer | S |
| Approve or decouple 022; implement or defer 057–059 | Closes governance drift between approved registry and shipped code | M |
Trust boundary map
HTTP API (serve)
Broadest attack surface. Dev defaults, unverified JWT, optional unauthenticated mode. Also the richest permanence surface (registration, traces, sessions).
MCP stdio
Implicit local trust only. Full execute + trace export with no credential check. Safe as an IDE child process; unsafe if redirected or remotely bridged.
WASM guest
Wasmtime isolation + WASI deny-by-default is solid. Host ABI whitelist exists but traverse_host::* functions are not linked yet.
Artifact / supply chain
Ed25519 works. Sigstore and checksum gates are incomplete. Publish/sync trusts the external registry path before extraction completes.
Recommended next moves
- 1
Treat all network-facing surfaces as non-production until JWT crypto verification and Production-default security ship.
- 2
Add a durable event/audit journal if compliance or multi-restart recovery is a product requirement — in-memory 5-minute replay is not permanence.
- 3
Close governance holes: approve or decouple spec 022; coverage-gate CLI/MCP; finish or explicitly defer specs 051/057–059.
Key evidence
crates/traverse-runtime/src/security.rs · crates/traverse-cli/src/http_api.rs · crates/traverse-mcp/src/stdio_server.rs · crates/traverse-runtime/src/events/broker.rs · specs/030, 031, 036 · SECURITY.md
Read the honest production-readiness breakdown, or dig into the governing specs yourself.