
StareBrain
Say it once. It just happens.
Building StareBrain — natural language commands for Android, confirm before anything executes. Here's a scenario most agent builders haven't tested: your agent gets permission to do something. Four minutes later, that permission is revoked — a token expires, a setting changes, someone says no. But the agent already has the technical capability queued up. At minute five, it executes anyway. At minute six, some downstream system records it as done.
The agent had permission. Was it still authorized at the moment it actually mattered? Those are different questions, and almost nobody's system can tell them apart.
Worse: if you try to stop the action after authority changes, and the request already left for an external provider, flipping your own app's state to "blocked" doesn't prove anything happened — or didn't. You're guessing, wearing the costume of a system that checked.
Spent this week in a thread with people independently landing on the same fix from completely different systems — WordPress admin tools, AI ops platforms, and now StareBrain. The fix: never let permission be a thing you check once and trust forever. Every action gets a short-lived, parameter-bound token — re-verified the instant before it fires, not five minutes earlier when it was requested. And once something leaves the system's boundary, "blocked" isn't a real status anymore. Only "confirmed clean" or "unresolved" are honest.
That's the actual engineering behind "say it, it happens" — nothing executes on stale authority, ever. Confirmed before it runs, or it doesn't run.
Building in public as I go — waitlist link in profile if the 9:00-to-9:06 problem is one you've hit too.
Building StareBrain — say a command in plain English, see exactly what it's about to do, confirm before anything runs. Been circling this for three weeks. Deep in confirmation-model design, provenance tags, verified non-execution states — genuinely useful thinking, and also, I realized this week, a very comfortable place to hide from the one thing that actually mattered: putting the product in front of a single real person.
Got asked directly what the smallest possible ask looks like, one that isn't a screen share, isn't me narrating, isn't me in the room at all. Landed on this: send a friend the APK, one line — "trying this out, can you type one thing you'd actually want your phone to do and see what happens? No need to explain anything back unless something's confusing."
No walkthrough. No context-setting call. No "let me show you first." If they need me to explain it before trying, that's data too — it means the first-run experience isn't carrying its own weight yet.
Sent it today. First time in three weeks this was true instead of hypothetical. Whatever happens next is the first real data point I've had.
Building in public as I go — waitlist link in profile if you want to follow along.
1 Like
1 Comment
1 Comment
-
1
This is exactly the difficult part. We can explain our own app for ten minutes because we already see the whole idea, but a new user only sees that first screen.
Sending it without a walkthrough is brave, but probably very useful. I would be especially interested in what the person thinks the app is for before you explain it. That misunderstanding may teach you even more than whether they complete the first action.
Building StareBrain — say a command in plain English, see exactly what it's about to do, confirm before anything runs. Got called out today in a way that's sticking with me. I'd concluded my data schema keeps a value and its provenance tag together — reasoned through it, felt confident, moved on. Someone pointed out that reasoning about your own schema barely counts as a test, because it's the easiest place for a comfortable answer to hide. You're grading your own homework and calling it verification.
The actual test was almost insultingly simple: take one real entry, push it through whatever code path copies or logs it, print what comes out the other side. Five minutes. Either the tag survives or it doesn't. No amount of confident reasoning substitutes for just running it.
This connects to something a few of us have been circling all week from a different angle — the "number I feel good about vs. the number that's real" problem. Confident internal reasoning is a declared claim about my own code, same as "good conversations" is a declared claim about demand. Neither is fake. Both are just the wrong thing to trust until something independent checks them.
Going to make a habit of asking, before believing anything I've concluded about my own system: did I check this, or did I just think about it clearly? Those feel identical from the inside, which is exactly the problem.
Building in public as I go — waitlist link in profile if you want to follow along.
1 Like
Comment
Building StareBrain — say a command in plain English, see exactly what it's about to do, confirm before anything runs. Got called out today in a way that's sticking with me. I'd concluded my data schema keeps a value and its provenance tag together — reasoned through it, felt confident, moved on. Someone pointed out that reasoning about your own schema barely counts as a test, because it's the easiest place for a comfortable answer to hide. You're grading your own homework and calling it verification.
The actual test is almost insultingly simple: take one real entry, push it through whatever code path copies or logs it, print what comes out the other side. Five minutes. Either the tag survives or it doesn't. No amount of confident reasoning substitutes for actually running it.
Haven't run it yet as I write this — which is itself the point. "I'll check it later" is just another version of trusting my own conclusion a little longer. Going to actually do it today and report back whichever way it goes, including if it turns up the exact bug this whole two-week series has been about, in my own code.
Building in public as I go — waitlist link in profile if you want to follow along.
1 Like
Comment
Building StareBrain — say a command in plain English, see exactly what it's about to do, confirm before anything runs. Two weeks into this confirmation-model series, and today's push found a failure mode underneath everything I'd already fixed. Not a bug in my logic. A bug in what survives when my data moves.
I'd added expiry to observed capabilities — timestamp it, downgrade it once stale, don't let an old observation quietly pass as current. Felt solid. Then someone pointed out expiry only works if the tag survives long enough to expire. Transcription can kill it before that clock even starts.
The example: someone measures a hardware value once, on one unit, one afternoon. That number gets copied into a database. By the second copy, it reads as a plain fact. Nobody rewrote it maliciously — a summarizer just kept the value and dropped the field that said "this was observed, once, under these conditions." As put to me today: it didn't age out. It got promoted to a fact by being transcribed.
That's a different failure than anything I'd built defenses for. My expiry logic assumes the tag makes it to the clock. This shows the clock can just never start, silently, the first time the value passes through code that has no reason to know the provenance field was load-bearing.
The fix isn't "remember to preserve the field everywhere" — that's trusting every future piece of code to behave correctly, the exact mistake that caused my original bug two weeks ago. The real fix: value and provenance can't be two separable fields at all. They have to be one object, so that anything copying or summarizing it either carries the whole thing or visibly breaks — never silently succeeds with half of it.
Going to go check whether my current schema treats these as splittable before I add anything else on top of a foundation that might not survive its own first summary.
Building in public as I go — waitlist link in profile if you want to follow along.
1 Like
Comment
Building StareBrain — say a command in plain English, see exactly what it's about to do, confirm before anything runs. Yesterday I admitted I might be solving my own problem, not a user's. Today someone asked a harder, more specific version of that question: is there a number you're currently allowed to feel good about that isn't users, and has it quietly become the thing you're optimizing?
Yes. IH engagement. Two weeks of threads, people pushing back on the confirmation model, someone offering to test my exact scenario, replies running long and substantive — all of that felt like progress, and none of it correlates with users, because it was never measuring users. It was measuring whether strangers on one forum find my reasoning interesting. Those aren't the same thing, and I'd let the first one quietly borrow credibility from the second without saying so, even to myself.
Someone else added the sharper point: without real users, every design decision stays declared, never observed — you can sharpen a question forever and learn nothing new. Then described putting something in front of actual strangers and having them re-rank two weeks of internal debate in one afternoon. The feature they thought was load-bearing, nobody touched. The one they almost cut was what people opened first.
That's not an argument I can win by being more rigorous. It requires a different observer than the one I've had for two weeks — me, and a forum that self-selects for people who like arguing about product design.
So: going to go get five real users in front of this before writing another build log. The thread's been genuinely useful, but it's the cheapest, easiest number to keep feeling good about, and that's exactly the tell that it stopped being evidence and became a proxy.
Building in public as I go — waitlist link in profile if you want to follow along.
1 Like
Comment
Building StareBrain — say a command in plain English, see exactly what it's about to do, confirm before anything runs. Been deep in confirmation-model design for two weeks now — risk to recoverability to consequence-travel to capability-vs-state to declared-vs-verified. Today someone asked a question that punctured the whole thing: does provenance actually change what a user decides, or does it just make the system feel more trustworthy to me, the person who built it?
Honest answer: I don't know, and I can't know until real people are making real decisions with it in front of them. My best guess — it's probably invisible 95% of the time and load-bearing the other 5%, the moment something's gone wrong and someone's deciding whether a retry is safe. But that guess is itself a declared claim, not an observed one. Exactly the distinction this whole two weeks has been about, applied to my own confidence in the work.
Second thing that landed today, more abstract but maybe more important: someone suggested the recurring bug isn't really about capability or state or provenance specifically — it's the same underlying question showing up at every layer: what actually grounds this claim as true? Fix it at one layer (capability vs. state) and it reappears one level up (declared vs. verified capability). No reason to think this stops. So the declared/observed/inferred tagging isn't really the fix, it's a way of noticing the question keeps recurring wherever I stop looking too early.
Which means the real risk right now isn't a technical gap, it's time allocation. I've spent two weeks getting sharper at a question that might not matter to a single real user yet, because there are no real users to check that against. Going to actually go get some before going another layer deeper.
Building in public as I go — waitlist link in profile if you want to follow along.
1 Like
Comment
Building StareBrain — say a command in plain English, see exactly what it's about to do, confirm before anything runs. Yesterday I posted about splitting capability (static — can this action ever reach someone else) from state (dynamic — did this attempt reach that far). Felt like a real fix. Today someone pointed out I'd built the same bug into the fix itself.
The catch: a declared capability isn't the same as a verified one. Someone described the hardware version of this — a USB device can declare a 1000Hz report interval in its descriptor, but that doesn't mean it delivers 1000Hz. The descriptor is capability; the measured interval is observed state. A tool that just reports the descriptor is showing a promise while looking like it's showing a measurement.
I'd been treating my capability tags as ground truth because they're static. Static isn't the same as verified. "A sent SMS can reach a third party" is a design-time claim about the action type — I was trusting it like a spec sheet, not like something that needs checking. Under a bad OS permission change or an API deprecation, a capability tag could silently go stale, and I'd have zero record it was ever anything but "known." Same failure shape as the timeout-collapsed-into-failure bug from earlier this week, just one layer higher up the stack.
Fix: give "what remains unknowable" a sibling field — how do we know? Declared, observed, or inferred. Applies to every fact in the record now, not just the ones flagged as uncertain. Cheap to tag at write time, close to impossible to reconstruct later if you skip it.
Two weeks into this confirmation model and I'm still finding holes in fixes I thought were done a day earlier. Starting to think that's just what the process looks like, not a sign I'm doing it wrong.
Building in public as I go — waitlist link in profile if you want to follow along.
1 Like
Comment
Building StareBrain — say a command in plain English, see exactly what it's about to do, confirm before anything runs. Been refining the confirmation model all week: risk → recoverability → how far did the consequence travel. Today's push sharpened it into something I can actually build against instead of reason about.
The distinction: capability is a static fact about an action type — can it, in principle, ever reach someone else. A wifi toggle can't. A sent SMS always can, by definition, no matter how it's implemented. State is a dynamic fact about one specific attempt — did this run actually reach the tier its capability allows.
Why this matters: it means the expensive part (tracking uncertain state, handling "we don't know") only has to happen for actions whose capability tier permits leaving your own boundary in the first place. A wifi toggle's unknown state is trivial — there's no boundary to have crossed even if you don't know. A sent SMS's unknown state is real, because its capability was always "can reach someone else." Capability sets the ceiling on how much an unknown state can matter. Tag actions by capability up front, and "unknown" stops being the default answer for everything.
Also converged on the actual event-record shape today, pulled from a few different threads: not a status word, but last-confirmed-stage, an evidence ID where one exists, a timestamp, and an explicit "what remains unknowable" field. That last one's the piece most systems skip — making the gap itself a first-class field instead of an implicit silence, which is what stops "we don't know" from quietly decaying into "nothing happened" over time.
One more rule I'm now enforcing rather than leaving as an accident of code path: only UNRESOLVED gets retried. A confirmed DENIED never does. Obvious once stated, but I don't think my system was actually enforcing that as a rule before today.
Building in public as I go — waitlist link in profile if you want to follow along.
1 Like
Comment
Building StareBrain — say a command in plain English, see exactly what it's about to do, confirm before anything runs. Follow-up to last week's build log, because someone gave me a model that broke a fix I thought was already solid.
My system had two states: executed, or blocked. Turns out blocked was doing more work than it earned. My earlier fix — tag every attempt with an ID, drop stale results that don't match — stops the interface from showing a wrong result. It does nothing to revoke the authority of an older, already-in-flight attempt to actually go complete somewhere downstream I'm not watching. Fixing what the screen says isn't the same as fixing what happened.
The real model needs three states, not two:
EXECUTED — observed evidence of the actual side effect
DENIED_CONFIRMED — denied, and verified it never crossed the execution boundary
DENIED_UNRESOLVED — denied, but downstream state can't be conclusively closed
That third one is uncomfortable, because for some actions it might be permanent. I can't query someone's phone to prove a text never arrived. The most honest claim I can make is "never submitted to the provider" — narrower and weaker than "not delivered," but true.
Also landed on a reframe today that's changing how the confirmation screen itself reads: once something's crossed the boundary where consequences aren't fully yours to control anymore, undo stops being reversal and becomes recovery. Reversal means the event un-happens. Recovery means you're managing the aftermath as well as you can. A confirmation screen's real job might be telling you which one you're about to sign up for, before you tap confirm.
Slower week than expected, in a good way — more time spent finding gaps in fixes I thought were done than writing new code.
Building in public as I go — waitlist link in profile if you want to follow along.
1 Like
Comment
About
Got tired of tapping through five screens on my phone for things I already knew exactly how to describe in one sentence. StareBrain exists to close that gap, say what you want done, see exactly what it's about to do, the


Comment