Jarvis: Proving What Actually Happened

CTRL+STRUM // BUILDER LOG

Jarvis: Proving What Actually Happened

Posted on April 03, 2026

Mission Log 004 — Plan / Build / Debrief

Before we get into this, quick reality check:

There’s a lot going on in a system like Jarvis.

Routes, logs, policies, execution layers, replay logic — we could easily disappear into thousands of lines of code and never come back.

That’s not what this is.

This is what we do at CTRL+Strum:

  • Break down the most important pieces
  • Translate real code into human language
  • Actually build something real while we do it

Because that’s our lane:

dev education + personality + real system building

Not theory. Not fluff. Real systems.


This whole thing started with a simple idea:

AI agents shouldn’t control your systems.

In the second video, I designed a system where they don’t:

proposal → approval → execution

Then I started building it.

…and everything worked.

Which is usually when things are about to go very wrong.

So let’s break it down the way Jarvis actually experiences it.


🧠 PLAN — “If I log everything, I’ll know the truth”

The idea sounded simple:

  • Log what was proposed
  • Log what got approved
  • Log what ran
  • Log what happened after

Then replay it and say:

“this is exactly what happened”

That’s the plan.

That’s also how you accidentally build a system that tells very confident lies.


🔧 BUILD — What the system is actually doing

Let’s walk through the real flow — and translate it like normal people.

🟢 Step 1: Ingress (ideas only)

This is where something like OpenClaw sends Jarvis an idea.

POST /api/ingress
if (!isIngressEnabled()) {
  return NextResponse.json({ error: "Ingress disabled" }, { status: 403 });
}

What this actually means:

If the front door is locked… we’re not even talking.

const timestamp = request.headers.get("x-jarvis-timestamp");
const nonce = request.headers.get("x-jarvis-nonce");
const signature = request.headers.get("x-jarvis-signature");

What this actually means:

Who are you, when did you send this, and can you prove it?

const id = crypto.randomUUID();
const traceId = crypto.randomUUID();

What this actually means:

Thanks for the idea. I’m naming it now.

That part matters, because the agent does not control the official identity of the event. Jarvis does.

status: "pending",
requiresApproval: true,

What this actually means:

Cool idea. Absolutely not running that yet.

This is one of the most important boundaries in the whole system.

Ingress means:

  • accept the idea
  • verify the request
  • assign IDs
  • store it as pending

No execution happens here.


🟡 Step 2: Approval (intent only)

Once the proposal exists, a human can approve or deny it.

POST /api/approvals/:id
const newStatus = body.action === "approve" ? "approved" : "denied";

What this actually means:

Human says yes or no.

approvedAt: now

What this actually means:

We timestamp decisions so future us doesn’t argue.

This route only changes intent.

It does not run code. It does not touch the system. It just says:

“this is allowed to happen.”


🔴 Step 3: Execution (reality)

Execution is its own step, and Jarvis checks approval again before anything runs.

if (event.status !== "approved") {
  return NextResponse.json({ error: "Event is not approved" });
}

What this actually means:

No approval? No action. Not today.

const policyResult = await evaluateExecutePolicy(...)

What this actually means:

Even if you were approved… I’m still double-checking.

That’s not paranoia. That’s good systems design.

Approval is one gate. Execution policy is another.

Approval ≠ Execution.

And if your system treats them like the same thing… you don’t have a control plane.


🧾 Step 4: Receipts (the truth layer)

When something actually runs, Jarvis writes a receipt.

{
  traceId,
  at,
  kind,
  status,
  summary
}

What this actually means:

Here’s what actually happened, when, and how it went.

Not what we planned. Not what we approved.

What actually happened.

This is the layer that doesn’t care what you meant — only what actually happened.

And for code-related actions, Jarvis can log even more:

  • commit hash
  • rollback command
  • files changed
  • repo before / after state

That’s not just logging. That’s a receipt.


🔍 Step 5: Replay (the “what happened?” button)

GET /api/traces/:traceId

This route is supposed to rebuild the whole story:

  • proposal
  • approval
  • execution
  • receipts
  • policy decisions
  • reconciliation logs

At least… that was the plan.


🧪 DEBRIEF — The Part Where It Was Lying (politely)

Everything looked right.

But under the hood, Jarvis was pulling logs from:

  • different files
  • different days
  • different sources

…and then trusting the order they showed up in.

No sorting. Just vibes. Which is… not what you want in a control plane.

And that’s a subtle bug, but a dangerous one.

Because if your replay system gets the order wrong, then:

  • execution might point to the wrong action
  • timelines can drift
  • everything still looks right… until you need it to be true

That’s the worst kind of bug:

the one that tells a convincing story.


🧠 Translation (real world version)

Imagine your bank app showed:

  • $100 deposit
  • $50 withdrawal
  • $75 deposit

…but in the wrong order.

Technically correct. Emotionally unacceptable.


🔧 The Fix — respect time, not vibes

Inside the replay logic, the fix was actually pretty small:

receipts.sort((a, b) => a.at.localeCompare(b.at));
const latestReceipt = receipts.at(-1);

What this actually means:

We are now putting things in the order they really happened.

And:

The last thing that happened is the truth.

That means execution is no longer:

“whatever receipt we found first”

It is now:

“the latest receipt in the timeline”

Which is a very big difference for a very small patch.


🧠 Small but important cleanup

We also stopped using a vague variable name:

primary

and replaced it with:

proposalEvent

What this actually means:

We finally admitted what the variable actually is.

It’s not the source of truth for everything. It’s the event we’re using as the proposal envelope — the point where the idea entered the system.


🧩 What Jarvis guarantees now

  • proposal → what entered the system
  • approval → what was allowed
  • execution → what actually ran
  • receipts → everything in order
  • policy → why it was allowed
  • reconciliation → what changed afterward

That means replay is no longer “best guess.”

It’s deterministic.


🛡️ Why this system is actually safe

Jarvis is safe because it separates responsibility.

  • Ingress → ideas only
  • Approval → intent only
  • Execution → controlled action
  • Receipts → immutable truth

There is no path that goes:

“agent sends request → system just runs it”

That path does not exist. That is the entire point of the system.


🚀 What this actually changes

Before this:

  • replay mostly worked
  • timelines looked fine
  • demos were… slightly stressful

Now:

  • execution is provable
  • timelines are correct
  • debugging actually makes sense
  • the system feels solid

This is not a flashy feature.

It’s a trust feature.


⚠️ One small limitation

Right now, replay only scans the last 7 days of logs.

So if something happened a month ago… it’s not coming back yet.

That’s fine for now. Very much a future-me problem.


🧠 Final Thought

This wasn’t a giant feature.

It was a quiet realization:

my system could reconstruct events… but it couldn’t guarantee they were in the right order.

And if you can’t guarantee order:

you can’t guarantee truth.

Now it can.


🎬 What’s Next

Now that Jarvis can:

  • control execution
  • log everything
  • prove what happened

we can finally move outward.

Next step: OpenClaw + real agents.

And that’s where things stop being theoretical… and start getting real.


CTRL+Strum
music, tech, and weird science — but make it real

> Last note sent by Ben Tankersley