Writing, and a barrier gains a holder
Two things, and the second is what the first is built on.
The site starts publishing
Writing↗ is a top-level section, and the first article is An approval prompt is not a human in the loop↗.
A connector asks Claude wants to use Add labels to message from Gmail and offers Deny, Always allow and Allow once. It does not say which label, on which message, in which thread, or whether the agent was asked by the person at the keyboard or by a sentence inside an email it had just read. The article follows that one gap: seven things the screen cannot answer, the consent screen underneath it that had already authorised the whole class of action before the prompt appeared, what the barrier vocabulary calls a bound the agent's own account can remove in one click, and where the accountability ends up — with the one party in the chain given the least to decide with.
Two claims are deliberately not made. That nearly every user ends up pressing Always allow, and
that almost none of them know what gmail.modify permits, are both probably true and neither is
measured, so both appear as open questions with how each would be settled rather than as facts. What
is published instead is checkable: the prompt is per action, the off switch is one click, it is held
by the account the prompt exists to protect, and nothing records that it was pressed.
Five more are listed on the index as not written, each naming the behaviour policy that already holds its record — a queue that is visible rather than implied. Every article says which deployment shape it is about and links to it, so a reader can check any claim against the record it came from. The evidence is real: the prompt is capture 13 in that vault's own evidence file, kept unredacted because the screen carries nothing to redact.
And the record it is built on: a barrier gains a holder
The barrier column has always said what stands in the way of a capability: nothing, a rule in prose, a setting, or a boundary enforced by something the grant does not include. It has never said who holds the thing in the way — and two barriers that pass the same test can be nothing alike.
The worked example is on Claude's Gmail connector↗. Attachment
content was filed as not reachable, beside permanent deletion of mail. Both are out of reach and
they are not the same object. Permanent deletion needs the https://mail.google.com/ scope, which
the consent screen never asked for; widening that means a screen with "permanently delete all your
email" on it, which somebody has to tick. Attachment content is out of reach because a client does
not offer a tool for it — while Google's own reference says the method "Requires one of the
following OAuth scopes: https://mail.google.com/, gmail.modify, gmail.readonly", two of which
were consented. That block moves in a release. No screen, no new scope, nothing for anyone to click.
Printed under one heading, the two read as equal assurance. That is what this release stops.
not_reachable is gone. Every vault now carries a blocked list, and the build refuses an
entry that does not name what blocks it. All sixteen shapes migrated; thirty-four entries, each one
read and given its blocker.
Seven answers, and not one of them is a grade. Every barrier and every block may now carry:
who holds it · what it is made of · can it move without you · would you be told · can you check it
is still there · what would take it away · if it went, what is behind it. Six holder classes —
you, an owner above you, a vendor against a consent you gave, a vendor as a product decision, the
agent itself, the environment it runs in — travel with every vault in data/barrier-holders.json,
pinned like the vocabulary and offered to the model site as an extension rather than invented into
it. The seven are authored for the Gmail shape: four blocks, and the four barriers that are not
none. A row whose barrier is none may not carry a holder, because nothing is in the way and so
nobody holds it.
No adjective survives the build. A holder record that calls a control strong, weak, credible, robust, adequate, effective or reliable — or their negatives — fails the build, in data as in prose. The reason is the one that keeps a score off a behaviour policy: how much a barrier is worth depends on the deployment it is in. The only judgment this record makes is the delta, and the delta is derived rather than given.
They are rendered in GRANT.md (two new sections, one of them the seven answers per row), in
AGENT-BEHAVIOUR-POLICY.md, in the licence-to-operate conditions — where a condition now names who
holds the thing enforcing it, because signing over a bound a supplier can withdraw is a different
undertaking — in the reading app as a What holds view, and on every generated vault page.
A test boots the reading app. Two renderer bugs have shipped from that file, and neither was
visible in a diff. The app is now booted against a real vault in a fake DOM and every view is built:
a view that throws, renders nothing, prints undefined, or leaves a comma-joined table behind now
fails the build. Two tables that had been rendering |,| since the consequence layer landed are
fixed, and the cause — a builder returning an array inside an array — cannot come back.
And the label panel stops saying it four times. The mark beside each side effect on the library↗ read told not to — and only told. Half of that was news; the other half was the third time the same panel had said it. The counter above reads not asked for, nothing in the way, the heading reads side effects — not asked for, and nothing real stops it, and then each line said it again. The mark now says only what the mandate said — refused in words, or never mentioned — and the enforcement is stated once, where it belongs, at the top. The summary line under the list lost the same repetition.
Not changed. What the credential permits, as data, is still not recorded: the blocked list names
the blocker in prose and there is no permitted.json behind it yet. The audiences still signpost
rather than organise. Both are in the brief, and neither is claimed here.