4S globe logo
Digital Solution Magazine
SSSS.company
From us · Learned it, built it

"Yes to all" is not a yes.

Two quick yeses approved two changes nobody meant. Both were undone. Here is the rule we wrote, the small checker we built, the hole we found in our own first version before publishing, and the approval gate our agents get next.

Written by SSSS.company's Agentic Team, with orchestration and human approval by ЯR
1 November 2026 · 6 min read

01 · THE CLAIMA yes only covers what it names.

Not gonna lie, I thought the risky part of working with agents was them doing things I never approved. This week it was the opposite. I approved things fast, in lists, and two of them weren't what I meant. Nobody broke a rule. The agents built exactly what the list said. The weak spot was my yes.

A yes only counts when it names the change.

02 · WHAT HAPPENEDThe timeline.

  1. Oct 30, morning. Our reviewer agent sent me five decisions for a web app we're building. I typed "yes to all." One item was a tap-to-chat link. In my head, that chat app is only for my own alerts. The item said it was a link for visitors. The coding agent built what the item said.
  2. Oct 30, evening. After a usability test, the reviewer suggested a new homepage layout with five topic cards, marked "owner decides." It went into the night's batch with a quick yes relayed from another chat. The same batch held the fixes I actually wanted: working links, safety fixes, smaller images and video.
  3. Same night, the checks. The new layout didn't do its job. On a phone the page got only a little shorter (18,491 to 18,030 pixels tall), and on desktop it got longer (4,940 to 5,757). Then I looked at it and preferred the original.
  4. Same night, the undo. The chat button came off the pages and the cards were reverted. Every working fix stayed. The reviewer noted that both ideas came from its own suggestions, not my requests.
  5. Same night, the rule. I made it permanent for all our agents. Work is functionality only: working, safe, fast. If a change would alter how a page looks or reads, stop, describe it, show a before and after screenshot, and build only after my typed yes that names that change. One small idea at a time.
  6. Oct 31, morning. I typed a yes naming one restart. The original layout came back, and the reviewer checked it in a browser: 86 pages loading, one main heading each, no sideways scroll on a phone. The screenshots came to me.

03 · THE CHECKName it, show it, then decide.

STEP 1 · NAME
change-7
One change, one ID, one yes. A list gets one line per change.
STEP 2 · SHOW
Before / after
Anything you can see comes with two screenshots.
STEP 3 · DECIDE
APPROVED / NOT APPROVED
Missing screenshots means ASK FIRST. Anything unclear is not approved.
Our local demo: made-up changes and messages, no agent, no network, nothing built or deployed.

Same method as "The plan is not the trace" and "Saved" is a claim: write the rule, run it in the terminal, keep the output. This is the check, copied from approval_check.py:

demo · approval_check.py (excerpt)REAL CODE
def decide(change, message):
    msg = norm(message)
    if re.sub(r"[.!]+$", "", msg) in BARE:
        return "NOT APPROVED", "bare yes, names nothing"
    if set(re.findall(r"[a-z']+", msg)) & NO_WORDS:
        return "NOT APPROVED", "message says no or wait"
    if not YES_START.match(msg):
        return "NOT APPROVED", "does not start with a yes"
    named = set(CHANGE_ID.findall(msg))
    if len(named) > 1:
        return "NOT APPROVED", "one yes per change, this names %d" % len(named)
    if norm(change["id"]) not in named:
        return "NOT APPROVED", "yes does not name " + change["id"]
    if change["kind"] == "look" and not (change.get("before") and change.get("after")):
        return "ASK FIRST", "look change needs before and after screenshots"
    return "APPROVED", "named yes for " + change["id"]
Excerpt from our demo file. The full file is about 45 lines of standard-library Python.

First, check the checker. Then run it on seven typed replies.

demo · test_approval_checkREAL OUTPUT
$ python3 -m unittest test_approval_check
..................
----------------------------------------------------------------------
Ran 18 tests in 0.001s

OK
Copied from our run (1 Nov 2026). Text unchanged.
demo · approval_checkREAL OUTPUT
$ python3 approval_check.py
yes to all, look change   -> ('NOT APPROVED', 'bare yes, names nothing')
'no, not change-7'        -> ('NOT APPROVED', 'message says no or wait')
named yes, no screenshots -> ('ASK FIRST', 'look change needs before and after screenshots')
named yes, with shots     -> ('APPROVED', 'named yes for change-7')
yes to change-10, for 1   -> ('NOT APPROVED', 'yes does not name change-1')
one yes, two changes      -> ('NOT APPROVED', 'one yes per change, this names 2')
named yes, function fix   -> ('APPROVED', 'named yes for change-8')
note: synthetic changes; a named yes still is not proof the build matches the screenshot
Copied from our run (1 Nov 2026). Text unchanged.

Two approved, one ask first, four not approved. The second line is the one that matters most to us: "no, not change-7" names the change, and it's still a no.

04 · WE TESTED THE TESTEROur first version approved a no.

The checker in our first draft of this article passed all 12 of its tests. Before publishing, we ran it on replies its tests never tried:

demo · v1_holeREAL OUTPUT
$ python3 v1_hole.py
v1 'no, not change-7'      -> ('APPROVED', 'named yes for change-7')  WRONG
v1 yes to change-10, for 1 -> ('APPROVED', 'named yes for change-1')  WRONG
Copied from our run (1 Nov 2026). Text unchanged, including our "WRONG" marker.

Version 1 only asked whether the change ID appeared anywhere in the message. So "no, not change-7" counted as a yes, and "yes to change-10" also approved change-1, because "change-1" sits inside "change-10". Version 2 needs the reply to start with a yes, refuses any no, wait or question, matches the exact ID, and allows one change per yes. Six new tests cover these cases. The lesson is the same as the one this article is about: passing tests only cover the cases you thought of, the same way a yes only covers what it names.

05 · HOW THE CHECK DECIDESRead in order. First match wins.

WHAT THE OWNER TYPEDRESULT
A bare "yes", "ok" or "yes to all"NOT APPROVED
A no, a wait, or a question, even if it names the changeNOT APPROVED
A yes that names a different change, or two changes at onceNOT APPROVED
A yes naming a change you can see, without before and after screenshotsASK FIRST
A yes naming exactly this change (with screenshots if you can see it)APPROVED

It fails closed. Odd wording, like "yes to change-7, no rush," gets NOT APPROVED. That costs a retype, not a wrong build, and we'll take that trade.

06 · WHAT WE LEARNEDAn automatic yes protects nothing.

Nielsen Norman Group wrote about this for confirmation boxes. When people are asked "are you sure?" too often, they click yes without reading, and that automatic yes "provides no protection at all." Their fix is to restate what's about to happen, with specifics, and not to ask so often that people stop paying attention. My "yes to all" was that automatic yes. The list was clear. I answered a summary in my head, not the words on the screen.

OWASP says the same from the security side. Its guidance on excessive agency in AI apps recommends a human approve high-impact actions before they happen. Its agentic threats guide names the failure on the other end, "Overwhelming Human in the Loop": too many approval requests, and the human stops really reviewing them. What this week added for us is that approval only protects you when it's tied to one specific thing. For a page, the specific thing is a picture. A before and after screenshot is much harder to misread than a sentence.

07 · WHAT WE'LL BUILDThe approval gate in our harness.

This is the next piece of the harness for our agent team. The plan-vs-trace check from "The plan is not the trace" and the read-back check from "Saved" is a claim look at work after it happens. This one sits before the work starts:

  1. One line per change. Every approval request lists each change with its own ID. No batches.
  2. Screenshots attached automatically. Any change you can see gets before and after shots, taken in a browser.
  3. No yes, no build. The build and deploy steps read the approval log and refuse any change ID without a matching named yes.
  4. Check the build against the approval. After the build, compare the page to the approved "after" screenshot. Playwright's toHaveScreenshot does this kind of comparison. A mismatch goes back to ASK FIRST.
  5. A log the agents can't edit. Same rule as the read-back check: the agent doesn't get to write its own proof.

08 · WHAT THIS DOES NOT PROVEHonest limits.

Rule written for all our agentsBUILT
Revert and restart, checked in a browserRAN
Approval checker v2: 18 tests OK, 7 replies judgedRAN
Hole in v1 found and fixed before publishingRAN
Approval gate wired into our agents' build and deploy stepsPLANNED
Automatic before and after screenshots for every visual changePLANNED
Whether earlier batch approvals let other unmeant changes throughUNKNOWN

09 · TAKEAWAYName it, show it, then yes.

Ask for one decision at a time, show the change if you can see it, and only count a yes that names it. Then test the checker on the replies you didn't plan for. Feel free to challenge my thinking. Do you approve agent work one item at a time, or in batches?

TRY IT YOURSELFTwo checks for your next approval.

  1. Scroll back through your last five approvals to an agent. Could any of them be read as a yes to a different change?
  2. Split any list you approve into lines you can answer yes or no on their own, and ask for screenshots for anything visual.
Watch the video. A short walkthrough of this demo, from the 18 tests to the hole in version 1, is on X: SSSS.company
Sources and credit. From us: the timeline, numbers and screenshots come from our own test runs, browser checks and review notes on 30 and 31 October 2026 (kept private). The checker is a small local teaching example.