Jason Poindexter
Case study / Vanta / Solo brand, product, and engineering

I put Vanta's permissions in a Rust kernel the model cannot change.

Vanta is an open-source local AI operator for files, research, automation, and messaging. A separate Rust kernel checks every action before it runs. I wrote the mandate, designed the product and brand, built both layers, and shipped a notarized macOS release.

Role
Solo, mandate, brand, product, and engineering
Architecture
Rust safety kernel + TypeScript agent + Electron desktop
Shipped
Desktop v0.9.5 notarized, v0.9.8 current
License
MIT, local-first, provider-agnostic
Origin

The project started with a correction.

On 2 June 2026 I set out to build a local agent. The coding agent drifted and built a website instead. I told it plainly: that is not what I asked for. The correction led to the Rust runtime, the goal ledger, and the first PRD. That moment also became line eight in the manifesto: ship, do not drift.

The supervisory problem

Capability is shipping faster than control.

Agents can now reach files, shells, browsers, messages, and money. Most safety rules still live in a prompt the same model is expected to obey. I did not want the model policing itself. The boundary had to sit somewhere the model could not reach.

  • 01An agent with tool access can delete, send, or spend before a human ever sees the action.
  • 02Prompt-level guardrails let the model propose an action and decide whether it is allowed.
  • 03A warning is not a boundary. The system needs to stop the action before it runs.
  • 04No durable record of what was proposed, what a human approved, and what actually ran.
  • 05Cloud agents send context off-device. I wanted the operator and its record to stay local.
Framing and evidence

Start with the problem, not the finished interface.

I started with the desktop problem, then worked down through the sitemap, user flows, wireframes, and the Rust boundary underneath them.

The evidence is the current repository, renderer and route code, isolated Electron launches, screenshots, smoke scripts, and regression checks. No user study is claimed. Sitemaps, flows, SWOT, and low-fidelity frames are analytical reconstructions from that record.

Project frame

Problem, users, team, and method

observed
How might a local AI operator keep one useful work loop visible while making tool use, approvals, failure, and recovery understandable at every step?
  1. 01Audit
  2. 02Define
  3. 03Map
  4. 04Wireframe
  5. 05Build
  6. 06Verify
Problemobserved

Work, setup, outputs, sessions, and inspection competed for equal attention. The operator had capability, but not one stable mental model for starting, supervising, and recovering a task.

Goalobserved

Reduce the desktop to one work loop: start or resume, watch the run, decide on risky steps, inspect the result, and configure capability only when needed.

Teamobserved

Solo product, UX, brand, and engineering. Jason Poindexter owned the mandate, structure, interaction model, implementation, and release evidence.

Usersreconstructed

Primary: a focused local operator doing work across tools and files. Oversight role: the same person reviewing consequential actions, receipts, and recovery choices. These are task roles, not interview personas.

Methodobserved

Code and route audit, isolated Electron launch, screenshot review, source and packaged-app flow smokes, responsive layout checks, and a blind interface audit.

Constraintsobserved

Local-first, provider-agnostic, one stable desktop shell, a separate Rust enforcement boundary, and no UI shortcut that weakens approval or audit behavior.

Research findings

What the evidence says is broken

7 issues
01P0executed

The source desktop could fail before the work surface rendered.

Evidence
Theme state was referenced outside its owner and the normal TypeScript command did not include the Electron renderer.
Design response
Pass theme state into the overlay boundary, add a renderer-specific typecheck, and fail native smoke on renderer errors or a missing shell.
02P1executed

Several competing shells obscured the main task.

Evidence
Top-level modes, session navigation, header utilities, and inspector tabs all demanded equal weight before a task began.
Design response
Keep three destinations, Work, Outputs, and Connect. Move sessions inside Work and open the inspector only from a related action.
03P1partial

Failure recovery was too global and too generic.

Evidence
One failed dependency could replace the entire desktop, while an execution error appeared as if it were an assistant response.
Design response
Keep the shell and draft visible, scope the failure to the affected surface, preserve partial output, and retry the failed step.
04P1executed

Project files read as a raw inventory instead of usable context.

Evidence
The file rail could expose hundreds of paths without grouping, search, or a selected-context state.
Design response
Move file selection into the composer, group by recent and task relevance, and show removable context chips before send.
05P2proposed

Session management lacked safe feedback and recovery.

Evidence
Archive and delete behavior depended on immediate confirmation without a durable trash path or undo feedback.
Design response
Archive immediately with Undo, move delete to recoverable trash, and expose pending, success, and error states.
06P2executed

Model scope and agent context were hard to inspect.

Evidence
Files, tools, memory, model scope, and permissions were mostly invisible until another panel opened.
Design response
Place model and context in the work header and composer. Render tool and approval evidence in the same run stream.
07P2executed

The contextual rail consumed space even when it had no job.

Evidence
The desktop could open as a three-pane layout with an empty Canvas rail, then change shells on another destination.
Design response
Default to task rail plus work surface. Open Preview, Files, Canvas, or Terminal only when the current task creates that context.

Status reports the July 2026 audit record. Proposed work is not presented as shipped.

Constraint analysis

SWOT reconstructed from the project record

reconstructed

Strengths

Internal / helpful
  • A separate Rust process owns risk, approvals, goals, and audit events.
  • The desktop exposes current goal, tool activity, approvals, outputs, and receipts.
  • The TypeScript agent and desktop can change without moving the enforcement boundary.

Weaknesses

Internal / harmful
  • A solo-built system concentrates product, security, and validation decisions.
  • Several surfaces must explain one run without creating duplicate state.
  • Provider and tool differences increase setup and recovery complexity.

Opportunities

External / helpful
  • Local operators need inspectable control as agents gain access to real tools.
  • Receipts and reusable runs can turn one-off automation into accountable work.
  • A stable kernel can support new interfaces without weakening the boundary.

Threats

External / harmful
  • Provider behavior and tool protocols change outside the product.
  • A reassuring interface can overstate what the kernel actually intercepts.
  • Complex setup can stop users before the supervision model becomes useful.
This is an analytical reconstruction, not a claim that a formal SWOT workshop occurred.
Product correction

One work loop, with the kernel visible inside it.

The desktop audit found too many shells and top-level modes. I cut the product down to one operator loop: start or resume a task, watch the work, stop at risky steps, and review the result. Configuration stays out of the way until it is needed. The kernel remains a separate process, but its state is always visible.

Product decisions

The decisions that set the boundary.

01

I put the boundary in a separate Rust kernel, outside the model.

The thing enforcing control must not be the thing being controlled. vanta-kernel owns risk classification, approvals, goal state, and audit events. The TypeScript agent proposes an action but cannot execute it directly. The kernel decides. A jailbroken prompt still hits code it cannot talk past.

Executed, src/ Rust kernel + vanta-ts/ agent layer, separate processes
02

Autonomy became three explicit states, not a slider.

Safe work proceeds. Consequential work asks. Blocked work stays blocked. A single trust slider forces a bad trade between useful and safe. Vanta classifies every proposed action instead. Low-risk work runs. Consequential work stops for approval. Out-of-scope work is refused. A blocked action cannot be clicked through.

Executed, kernel-gated execution across the three states
03

Local-first, provider-agnostic, and open to audit.

A boundary you cannot inspect is not a boundary you can trust. Vanta runs on your machine with tools connected through MCP. It can use different model providers, and the source is MIT. Anyone running it can inspect the kernel that gates the agent. The installer ships checksum-verified kernels for macOS, Linux, Android, and Windows.

Executed, MIT on GitHub; checksum-verified kernels for 4 platforms
Structure and interaction

Map the work before showing the finish.

The information architecture, user tasks, screen inventory, connected wireflow, individual frames, and implementation boundary are kept in one sequence.

Information architecture

Vanta sitemap

reconstructed
  • Vanta Desktop
    • WorkPrimary operating surface
      • Sessions
      • Conversation
      • Active run
      • Approval queue
      • Attached context
    • OutputsEvidence and reuse
      • Artifacts
      • Previews
      • Changed files
      • Receipts
      • Run history
    • ConnectCapability setup
      • Providers
      • Tools and skills
      • MCP servers
      • Messaging
      • Setup status
    • Utilities
      • Inspector
      • Command palette
      • Settings
The hierarchy is redrawn as a semantic tree. Connectors show parent and child relationships and collapse into a vertical reading order on narrow screens.
User flows

3 complete paths, including recovery

reconstructed
01

Start or resume work

Start or resume a task without losing its prior context.

  1. 01Operator

    Open Vanta

  2. 02Desktop

    Show recent sessions and a new-task prompt

  3. 03Operator

    Resume a session or describe a new task

  4. 04Agent

    Prepare the run with goal, context, model, and tools

  5. 05Desktop

    Stream text, tool events, and current state

  6. 06Operator

    Review the result and receipt

Recovery branch

If setup is incomplete, Vanta keeps the draft task and routes to the missing provider or capability, then returns to the same session.

02

Approve a consequential action

Stop risky work before it runs and show exactly what is waiting.

  1. 01Agent

    Propose a tool action

  2. 02Kernel

    Classify the action as allow, ask, or block

  3. 03Desktop

    Show target, scope, and available evidence

  4. 04Operator

    Allow once or reject

  5. 05Kernel

    Execute or refuse, then record the result

  6. 06Desktop

    Return the run to an explicit state

Recovery branch

A rejection does not end the session. The agent receives the refusal, revises the plan, and any new action is classified again.

03

Recover and reuse output

Keep incomplete work and check every permission again before replay.

  1. 01Desktop

    Detect an interrupted or failed run

  2. 02Desktop

    Mark provenance as incomplete and keep prior events

  3. 03Operator

    Inspect the receipt and choose resume, fork, or stop

  4. 04Agent

    Rebuild context from saved state

  5. 05Kernel

    Reclassify every proposed action

  6. 06Operator

    Review the recovered output

Recovery branch

If the original tool or provider is unavailable, Vanta keeps the evidence and offers a new branch instead of presenting a partial replay as complete.

Application map

Screens, purposes, and routes

9 screens

Operate

Work homeobserved

Start a task or resume a session.

Primary actionStart or resume work
emptyreadysetup needed
Active runConnectModel selection
Active runobserved

Show the goal, streaming response, tool activity, and stop control.

Primary actionStop or queue the next instruction
planningstreamingawaiting approvalfailedcompleted
Approval requestOutput detailRecovery
Approval requestobserved

Hold a consequential action before execution.

Primary actionAllow once or reject
waitingallowedrejectedstale
Active runRun receipt

Inspect

Output detailobserved

Review an artifact, preview, changed file, or diff.

Primary actionOpen source run or attach to a new task
loadingreadymissing output
InspectorRun receiptNew task
Run receiptreconstructed

Trace the goal, tools, approvals, outputs, and final state.

Primary actionReplay or fork
completedpartialfailed
Output detailReplayFork
Recoveryreconstructed

Explain interruption, preserve provenance, and offer a safe next action.

Primary actionResume, fork, or stop
interruptedprovider unavailabletool failed
ResumeForkWork home

Configure

Connectobserved

Configure providers, tools, skills, servers, and channels.

Primary actionConfigure and test one capability
readyneeds setupunavailable
Provider setupWork homeSettings
Model selectionobserved

Choose a saved default or a model for one task.

Primary actionUse for this task
loadingcatalog readyoffline catalog
Active runConnect
Settingsobserved

Manage standing preferences without crowding the work surface.

Primary actionSave preferences
savedsavingsave failed
Work homeConnect
Route labels describe the next reachable state. They are not navigation labels unless the current product uses the same wording.
Connected wireflow

One work loop, with visible branches for setup, approval, output, and recovery.

reconstructed

Each box is a screen or state. The return paths keep the session intact and bring the operator back to Work.

Low-fidelity screens connected from setup and work through approvals, outputs, receipts, and recovery.readychoose modelreturnstart taskkernel asksallow or rejectresulttracereplay or forkinterruptedresume or fork01ConnectCapability setup02Work homeIntent and context03Model selectionOne task or default04SettingsStanding preferences05Active runStreaming and tools06Approval requestKernel holds action07RecoveryResume, fork, or stop08Run receiptTrace and reuse09Output detailPreview or diff
01
ConnectCapability setup
  • readyWork home
02
Work homeIntent and context
  • choose modelModel selection
  • start taskActive run
03
Model selectionOne task or default

End state

04
SettingsStanding preferences
  • returnWork home
05
Active runStreaming and tools
  • kernel asksApproval request
  • resultOutput detail
  • interruptedRecovery
06
Approval requestKernel holds action
  • allow or rejectActive run
07
RecoveryResume, fork, or stop
  • resume or forkActive run
08
Run receiptTrace and reuse
  • replay or forkActive run
09
Output detailPreview or diff
  • traceRun receipt
The desktop canvas keeps every connector attached to its frame. Narrow screens use the same routes as a vertical wireflow so the sequence stays readable without sideways scrolling.
Wireframes

Structure and state before visual finish

7 frames
01

Shared application shell

The shell stays stable while the task state changes inside it.

reconstructed
Project, model, kernel, utilities
Work, Outputs, Connect, sessions
Current task surface
Composer, context, send or stop
Primary actionContinue the current task
States

empty / active / approval / output open / recovery

02

Work home

Recent sessions, one task entry, and capability status.

reconstructed
Global status and model
Session navigator
Task entry and recent work
Goal and kernel state
Primary actionStart or resume work
States

empty / ready / setup needed

03

Active run

The run stays legible while text and tool events stream.

reconstructed
Run state and stop control
Sessions
Conversation and tool activity
Goal and event inspector
Primary actionStop or queue next
States

planning / streaming / approval / failed / complete

04

Approval request

The action, target, scope, and evidence appear before the decision.

reconstructed
Run paused
Action and diff preview
Risk and target
Reject
Allow once
Primary actionAllow once or reject
States

waiting / allowed / rejected / stale

05

Output detail

One output with preview, source run, and reuse actions.

reconstructed
Output identity and source run
Preview or file diff
Metadata, receipt, and actions
Primary actionOpen source or reuse output
States

loading / ready / missing

06

Connect

Capability setup is grouped by what the operator is trying to enable.

reconstructed
Setup status
Providers
Tools and skills
MCP servers
Messaging channels
Primary actionConfigure and test
States

ready / needs setup / unavailable

07

Recovery

Incomplete provenance is visible before resume, fork, or stop.

proposed
Interrupted run state
Completed events and missing step
Recovery explanation
Resume
Fork
Stop
Primary actionResume, fork, or stop
States

interrupted / provider unavailable / tool failed

Reconstructed frames document current structure. Proposed frames name an unresolved or future state and should not be read as shipped UI.
System architecture

The desktop observes the run. The kernel decides what may execute.

observed

This comes from the current repository. The layers separate what the interface shows, what the agent proposes, and what the kernel allows to run.

01
Desktop interfaceIntent, oversight, and intervention
WorkOutputsConnectInspectorApproval UI
02
Desktop APISession boundary and live event transport
HTTP handlersSession stateSSE streamApproval adapter
03
TypeScript agentContext, model calls, tools, and goal-aware loop
ConversationRun preparationProvider adaptersTool registry
04
Rust safety kernelEnforced action boundary
Risk assessmentApprovalsGoal ledgerAudit events
05
External systemsResources reached only after classification
Local filesShellBrowserMCP toolsModel providers
Execution sequence
  1. Operator states a goal
  2. Agent prepares context and proposes an action
  3. Safety client sends the action to the kernel
  4. Kernel returns allow, ask, or block
  5. Allowed work executes, asked work waits, blocked work stops
  6. Events, outputs, and receipts return to the desktop
The desktop app

The boundary, on screen.

Vanta ships as a macOS desktop app. The kernel state stays visible. Tool calls and approvals appear in the work stream. The output rail opens only when there is a file, preview, or receipt to inspect. A consequential action stops the run until a person answers.

The finished desktop work surface, shown only after the sitemap, task flows, screen map, and low-fidelity wireframes.
The finished desktop work surface, shown only after the sitemap, task flows, screen map, and low-fidelity wireframes.
Approval required. The kernel holds a file edit, shows the target path and a diff preview, and waits for Allow once or Reject.
Approval required. The kernel holds a file edit, shows the target path and a diff preview, and waits for Allow once or Reject.
Work. Every tool call is listed and checked off, with runtime, tool count, and gated state always visible.
Work. Every tool call is listed and checked off, with runtime, tool count, and gated state always visible.
Provider-agnostic in practice. OpenAI, OpenRouter, and Azure catalogs, with a per-task model and a saved default.
Provider-agnostic in practice. OpenAI, OpenRouter, and Azure catalogs, with a per-task model and a saved default.
An autonomous run: the agent works the goal, and the kernel gates anything consequential.
An autonomous run: the agent works the goal, and the kernel gates anything consequential.
Desktop surfaces, v0.9.5
SurfaceWhat it carries
WorkChat, live tool activity, run receipts, files, model scope, approvals, recovery
SightCapture a macOS area, window, or all displays into removable task context
ConnectSetup state for providers, skills, MCP servers, messaging, Google services
ModelsLive catalog with a default and a one-task model selection
OutputsGenerated files, previews, diffs, receipts, and other run artifacts
Oversight in practice

What the operator can always see, stop, and undo.

A person needs to see the boundary working and step in when something is wrong. Vanta shows the current goal, tool calls, approval state, outputs, and run record in the work surface.

Supervision model
QuestionHow Vanta answers it
What is it doing right now?Live tool activity in Work; each call named and checked off as it completes
Is the boundary up?Kernel online and gated read in the chrome, not buried in settings
What is it working toward?Standing goal in the right rail, backed by the kernel goal ledger
When does it stop for me?Consequential actions halt the run in the approval queue before execution
What are my choices?Allow once or Reject; standing access is a separate deliberate setting
How do I stop a runaway?Stop control, plus a per-turn tool-budget circuit breaker that yields control
What happened?Run receipts, diffs, outputs, and an audit event log per run
Recovery

Recovery is re-gated, not replayed on trust.

A saved run can be inspected, forked, or replayed. Replay never reuses an old approval. Every action passes through the current kernel and asks again when required. After a restart, interrupted work returns as incomplete instead of pretending the run finished cleanly.

LiveVanta Desktop, running. Switch sessions, open the inspector, toggle the model.
Checking my own work

I audited the desktop against sixteen frameworks.

I designed the supervision model, which makes me a bad person to judge it alone. I ran a blind audit and a separate user-flow review that looked for failure instead of trying to confirm the design.

LiveBlind audit of Vanta Desktop, sixteen-framework sweep.
LiveDesktop user-flow report.
Verification

What I verified for the current release.

The v0.9.8 release records 1,473 TypeScript test files and 13,687 passing tests, with 3 intentional skips. It also records typecheck, a production desktop build, architecture tests, and an Electron layout and replay smoke. The smoke used fixture data, not a live paid provider. v0.9.8 does not claim a new notarized DMG. v0.9.5 is the notarized and stapled Apple Silicon build.

Evidence ledger
ClaimStatus
Kernel gates actions across three statesExecuted, shipped in Desktop v0.9.5
13,687 tests passing, 3 intentional skipsExecuted, recorded in the v0.9.8 release
Signed, notarized, stapled macOS buildExecuted, v0.9.5 DMG
Replay re-gates through the current kernelExecuted, v0.9.8 fix
Path canonicalized before assessmentExecuted, v0.9.7 fix after approval and sandbox scope disagreed
Resistance to a determined adversaryNot claimed. No external audit or red-team result exists yet
Adoption or usage outcomesNot claimed. No telemetry; the product does not track users
The brand

Observe. Interface. Execute.

The raven watches before it acts. That made it the right mark for Vanta. The palette uses three colors. An editorial serif carries the argument and mono carries system state, so the person and the machine never sound the same.

Vanta Black#050507Bone White#F4EFE3Signal Violet#7C3AED
  1. 01 Observe
  2. 02 Interface
  3. 03 Execute
Agent loopTypeScript, any provider
proposes action →
vanta-kernelRust, enforced boundaryclassify · gate
low risk
Execute
high risk
Approval queue → human
every event → log
The raven operator, the brand mark for a local AI operator
The raven operator, the brand mark for a local AI operator
Operator field kit, the brand system in use
Operator field kit, the brand system in use
The website

See it live.

The website uses the same visual system as the desktop app. The docs explain the boundary to a person. The kernel enforces it for the machine.

Livevanta.theft.studio
My role

I designed the operator and built its safety boundary.

I wrote the mandate, designed the brand and interface, built the Rust and TypeScript architecture, and shipped the Electron app to a notarized release.

The controls are shipped, and the release records the tests and builds above. That is not adversarial proof. Vanta has no external security audit or red-team result, and I do not claim it can stop a determined attacker. The product does not track users, so there is no adoption data. The two-layer architecture, enforced gate, notarized macOS build, and MIT source are available to inspect.