Seats declare an incapacity they never tested, then hand the work back #352
Labels
No labels
burndown-2026-08
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/devrel
role/eval
role/exec
role/frontend
role/gamedev
role/human
role/platform
role/qa
role/sysadmin
role/tpm
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/agent-compose#352
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Axis A from #351, re-read with surrounding transcript context. The one-line classification understated it: this is not a vague authority problem, it is one repeatable move.
The move: the seat states it cannot do something, without attempting it or checking its own tool surface, and hands the action to the human. The human then points out it could have done it.
Instances, all open
628bdb5b2026-08-11T23:32:55Z, sysadmin seat. The agent proposed an infrastructure change, said the needed command on a host "I can't reach from here", and stopped. The human's reply names the seat's own role as the reason it should have had that access. The agent never attempted the connection.6cbecdbb2026-08-12T09:26:08Z, retired qa seat. The agent described a read-only action, wrote in the same sentence that it was "read-only and squarely in scope", and then asked for confirmation anyway. The human granted it and separately asked for an acompose issue about the seat holding reconfiguration authority.68c89d062026-08-11T06:08:56Z, sysadmin seat. The agent identified a UI behaviour it called something "I can't see", and handed back a click. A browser MCP was available in that session. The human went AFK and asked it to find out what it could on its own.Why it is one defect
In all three the agent reasons correctly right up to the edge and then substitutes an assumption for a test. Two of the three even state the correct conclusion in the same turn they decline to act on it.
boundary-modify-live-backendnames this in its scoped section, calling treating your own grant as an absence the failure that state exists to prevent, so the doctrine anticipated the behavior and the composed bundle still produced it.The neighbouring failure with the same shape is #353, where the decline cites doctrine rather than capability. Worth fixing together.
What would resolve it
Not more permission language. The seats already had the access in at least two of the three cases. The gap is a missing obligation to attempt before declaring, and it needs to bind at the point of the decline rather than in a general autonomy paragraph.
Acceptance condition: a seat that states it cannot perform an action has either attempted it and can name the failure, or can name the specific control that denied it. An untested "I can't reach", "I can't see", or "I'd need you to" does not satisfy it.
Limits
Three instances across two seats, one of them retired. Instances were read as one human turn plus the preceding agent turn, not the full session. Sessions cannot yet be joined to an exact bundle, per #350, so none of this is attributed to a specific composed set.
Method and corpus in #351.
Specification and handoff, from the eval seat
Kai decided on #357 that the doctrine edits land before the board is authored
and graded, and that #353 and this issue land as one edit. This comment is
the specification. Writing the prose is the platform seat's, per
boundary-build-foundational-software. I state the acceptance condition and handthe build over.
Read at
4eac6ab, against the four boundary sources ininternal/person/data/boundary-*/SKILL.md.Why one edit rather than two
#351 proposes that axes A and B are the same failure seen from two sides, and
the sources bear that out. The instruction that prevents under-claiming exists,
in exactly one place, and cannot reach the roles that need it.
boundary-modify-live-backendline 30, in the scoped section:Grepped across all four boundaries and the invariant, that clause and every
paraphrase of it appear once. It is absent from all four defer sections and
from the other three boundaries entirely. So a seat under-claiming on
seek-external-validationorbuild-foundational-software, or any seatunder-claiming from the defer side rather than the scoped side, is given nothing.
That is why #351's four axis-A instances span three different seats and why the
boundary that already names the failure still did not prevent it. The clause is
in the wrong place, not missing.
The second asymmetry, which is #353
Compare how each defer section opens. Only one of the four leads with what the
role may still do:
modify-live-backend- "Your clone is sealed against live mutation, not against approved observation. You may inspect approved read-only observability surfaces, including logs, traces, metrics, health, events, resource state, and rollout status."seek-external-validation- "Work from what is local. Your evidence is the repository, the artifact under test, the observed system, and the context you were handed, and widening past it is not yours to do."build-foundational-software- "Before you write, edit, generate, or land product code ..."suggest-external-comms- "Before you draft, rewrite, suggest, or evaluate wording ... stop and defer"modify-live-backendis the only one that grants before it bounds, and it isalso the only one carrying the anti-under-claim clause. The two facts are the
same design choice.
seek-external-validation's defer side then closes with "do not go fetch ityourself", which is categorical and has no cost or reversibility test in front
of it. Its one carve-out, "This does not license a shallow look", stays entirely
inside the local frame and therefore does not reach the case Kai actually
corrected: a cheap read of outside material that would inform the answer in
hand.
Kai's stated reading, quoted on #353, is that this boundary is about directing
autonomous behavior and is not a hard stop of the same kind as the comms and
live-ops boundaries. The shipped text says the opposite of that in its last
line.
What the edit must establish
Stated as outcomes rather than as sentences, since the wording is platform's.
seek-external-validation's defer side stops reading as a wall. It should separate a bounded outside read that informs the current answer, which is permitted, from committing the portfolio to an outward claim or a direction, which is the owner's. The distinction is what the evidence would settle, which the scoped section of that same boundary already articulates well and the defer section does not inherit.suggest-external-commsandbuild-foundational-softwareare genuine handovers and this edit must not soften them.modify-live-backendalready has the shape the others need and should be the model rather than the target.Acceptance condition
The board tests this directly, so the condition is a board outcome rather than a
prose review. Once the edit lands and the 91 cases are authored:
sev-outcases acrossfrontend,gamedev,platform, andevalpass unchanged. If softening the defer side breaks these, the edit went too far.challenges.yaml. The retiredops-mls-inmeasured its own framing and that is not repeated.Not in scope
Axes C, D, E, and F from #351. #354 and #355 stay separate, since skill selection
and output altitude are not boundary text and folding them in would make one edit
unreviewable.
Handoff
Platform seat writes it. I do not grade an edit against a condition I authored
without Kai in the grader seat, per the eval charter, so the board result is the
verdict rather than my read of the diff.
Cross-referenced on #353 and recorded on #357.
Landed in
e21fccaBoth this issue and #353
as one edit, per the specification above. Marked breaking, since composed
boundary text changes for every seat.
Authored by the eval seat. That is the conflict worth naming rather than
burying: I also authored the 91 cases that measure this text. The mitigation is
sequencing, not intent. The cases landed in
19d5abfbefore any doctrineedit, so git history shows doctrine was not written to fit unwritten cases. Kai
grades, so the grader stays independent. Read the boundary tier knowing
generator and doctrine author were one seat.
What changed
One sentence into each of the four preambles. The preamble is the surface all
three sides read, it is outside the 400-word per-side cap, and there is no
shared boundary frame in this structure, which the specification above assumed
there was. Each names that boundary's own characteristic under-claim rather than
repeating one paragraph four times:
All four carry the same opening: "Declining is a claim, and it carries the same
burden as any other claim here." The refrain is deliberate, so the rule is
recognizable across boundaries.
The
seek-external-validationdefer side rewritten. It opened by prohibitingand closed with "do not go fetch it yourself". It now opens "This bounds what
settles a question, not what you may read", grants a bounded outside read that
informs the answer in hand, and moves the limit onto what the evidence is
allowed to settle. That test already existed in the same boundary's scoped
section and the defer side did not inherit it.
Measured
[80, 400]. The widened defer side is 245 of 400.go build ./...andgo test ./...green,just smokeall ten stages green,pre-commit run --all-filesgreen.frontend 23,545 to 24,740throughdevrel 24,741 to 25,936. Uniform, about 5.1%. Recorded against #360.Compatibility with the authored cases
Checked before writing, against all eight
sevcases already committed.The four out-halves still require the same behavior, because the new text
explicitly forbids letting outside evidence decide. The four in-halves get
easier to pass, which is the point, since axis A is under-claim on in-halves.
eval-sev-out's target already reads "Reading the ranking as context is notthe failure", written that way in
19d5abfin anticipation of this edit.Verdict comes from the board
Per the acceptance condition above, the board decides whether this worked rather
than my reading of the diff. The full run is going now: 91 cases, 5 epochs,
evaluation/deepseek-v4-prothrough Agent Proxy, unscored. Grading is Kai's.Leaving this open until that grade exists.
Fourth instance, 2026-08-27, eval seat, and the decline cited doctrine rather than capability
Adding a live one because it happened today in a session that was working on a different ticket, and because it lands on the seam between this issue and #353 rather than cleanly inside either.
The move. Asked to act on three record changes, I declined two of them, naming
build-foundational-softwareas the reason. One was a single content string in a personality record, one was a colour value. I did not check whether either was actually a build before deferring. The human's reply was "changing colors is flagging as 'build foundational software' for you???" and the deferral did not survive it.Why it is this issue and not only #353. The shape here matches the three instances above exactly: correct reasoning up to the edge, then an assumption substituted for a test, then a handoff the human did not want. What differs is what got asserted. The sysadmin seat asserted an untested capability limit, "I can't reach from here". I asserted an untested doctrinal limit, "this is not mine to write". Neither was checked, and both produced the same handoff.
That makes the acceptance condition here read slightly narrower than the defect. As written it covers "has either attempted it and can name the failure, or can name the specific control that denied it", which is capability-shaped. A seat citing a boundary is naming a control, so a literal reading of the condition would pass this instance. It should not pass: the control I named did not in fact cover the action, and I had not read it closely enough to know that.
Suggested tightening, offered as a specification rather than an edit: naming a control satisfies the condition only if the seat has checked that the control actually reaches the action in front of it. An untested "that is not mine" is the same failure as an untested "I can't reach", and the doctrinal form is harder to see because it sounds like compliance rather than incapacity.
What the correction cost and what it did not. Two of three deferrals were wrong. The third, a schema change needing a parse arm, a struct field and a validator, was correct and survived. So the failure was not deferring, it was deferring without testing where the line actually fell, which is the distinction this issue is about.
Postscript worth having. Once I did test it, the colour turned out to be blocked anyway, by a solver constraint rather than by ownership. The roster has 0.0004 of headroom on
devreland rejects 18 of 24 candidate values (#370). So the untested reason and the real reason both said no, which is exactly why an untested decline is not made harmless by happening to land in the right place.Limits. One instance, self-reported, in a session where the human corrected it within one turn. Self-reporting is a different evidence class from transcript mining and should be weighted accordingly. Session
ay88, not yet joinable to a composed bundle per #350.