Interview — Implementer agent: operational needs & steering signals¶
Status: filled research instrument. This is the implementer-agent segment's answers against
../INTERVIEW_GUIDE.md §5 (transcript study) and §6 (prompted self-report) —
not a spec and not a backlog. It confirms or refutes the guide's hypotheses from the agent's side of
the loop and feeds ../../PROPOSALS.md; it does not amend
DESIGN.md or ARCHITECTURE.md.
POV note. The guide is explicit that agents are not interviewed live — they are studied via transcript
review and prompted self-report against real runs (../INTERVIEW_GUIDE.md line 26).
This document is that self-report, authored from inside a real implementer run and grounded in the mechanics
the agent actually operates under, cited file:line the way a finding is. Impressions don't survive a
verify panel and neither should these; every claim below points at code.
Trust floor. Read every answer here as a single-source, unverified lead, exactly as the workspace
grades a fresh finding (internal/prompts/tpl/protocol_preamble.md:27). A need is confirmed only when it
recurs across ≥3 independent transcripts (../INTERVIEW_GUIDE.md §9). One run is a
lead, not a fact.
0. The one thing to understand first: the brief is the agent's dashboard¶
The human operator's observability surface is the dashboard; the implementer agent's observability surface
is the brief — the context document assembled by dacli context
(internal/brief/brief.go:57 Assemble; the package doc at brief.go:1-8 calls it "the product...
everything else exists so this function has something to slice"). Every question in the guide about what
the agent needs to see is a question about what belongs in the brief and when it refreshes, because the
agent never renders the dashboard — the dashboard is read-only for humans (internal/features/dashboard/dashboard.go:110-112,
GET /api/state only encodes JSON, never mutates).
This reframes the whole steering conversation. A steering signal that lands on a surface the headless agent cannot read is not steering — it is theater the operator mistakes for a correction. The agent's only inputs are (a) its context/brief and (b) OS signals. Anything meant to reach the agent must arrive on one of those, at a turn boundary, or it does not arrive at all.
1. What context & steering helps (RQ1, RQ2)¶
The brief already carries most of what steers a run well, and the highest-value pieces are the ones that
suppress DESIGN.md §1's three failure modes:
| What the brief gives me | Where | Why it steers me |
|---|---|---|
| Out-of-scope list | brief.go:110 |
Keeps me inside my claim; the single cheapest way to stop me editing a sibling's tree. |
Constraints + prior decisions (what was chosen, what was rejected, and the --because) |
brief.go:120-148 |
The highest-signal context there is. Seeing a rejected alternative means I never re-propose it — this is the direct antidote to relitigation. |
| What siblings found, carrying a trust floor | brief.go:208-288 |
The antidote to sibling blindness — I don't burn budget re-discovering what a sibling already learned, and the floor (brief.go:271-285) tells me how far to trust it. |
| Calibration line (my expected token/size band) | brief.go:73-85 |
Tells me how big this task is supposed to be, so I can right-size scope up front. |
| Codebase map + glossary | brief.go:116, 175-184 |
Orients me in one read instead of a fan-out crawl. |
The load-bearing insight for steering: the best mid-run correction is a better brief given once at spawn,
not a message injected later. Prior decisions (brief.go:120-148) are pre-emptive steering — they correct a
wrong turn before I take it. Everything the guide files under "steer a live agent" is, from my side, mostly a
symptom of a brief that didn't say the thing up front. Probe whether a confirmed steering pain would have been
eliminated by a constraint the brief could have carried — most are (../INTERVIEW_GUIDE.md
RQ2's own "comfort blanket vs real need" question).
Where the brief leaves me blind (observability gaps, RQ1/RQ5)¶
- The brief is a snapshot, frozen at spawn.
--recordfreezes it for replay (internal/features/briefing/briefing.go:42-55). Sibling findings that land after I spawn never reach me. A sibling who refutes a finding I'm building on, or claims a path I'm about to touch, is invisible until my next full context refresh — which, mid-task, I usually don't do. - Working-memory cap trims the tail.
MillerCap = 7(brief.go:48) caps constraints, risks, findings, and lessons;trim()drops droppable sections from the bottom under budget (brief.go:422-452). The 8th sibling finding — possibly the one that would have saved my run — is simply not there. This is a feature (working memory is finite), but it means "just add it to the brief" is never free. - No live sibling state. "What siblings found" is reported findings only. What a sibling is doing right now — in-flight, mid-edit, on which paths — has no representation anywhere I can read.
2. When human chat / intervention helps vs harms mid-run (RQ2 → H3, the core question)¶
This is the sharpest question in the guide for my segment, and the answer is asymmetric.
Interruptive, synchronous chat HARMS. This is architectural, not a preference.¶
The headless contract is built on never blocking:
"You are running HEADLESS: no human is watching this session and no one can answer a confirmation prompt. Never pause to ask permission and never wait for approval — decide and act within your grant and sandbox... A blocked question means
dacli ask(which records it) and then STOP — it does not mean wait." —internal/prompts/tpl/protocol_preamble.md:9
A chat message pushed at a live agent violates this three ways:
- It blocks. If the message expects acknowledgment or a reply, the agent either stalls waiting (breaking the never-wait contract) or ignores it (making the feature a lie). There is no third option for a headless loop.
- It derails a coherent plan. A correction arriving mid-reasoning — between reading a file and editing it,
inside a multi-step tool sequence — lands as noise. The per-turn stall timeout (
internal/features/execution/execution.go:799) assumes forward motion; an interruption that makes me re-plan mid-turn can trip it spuriously. - It invites relitigation. A human second-guessing an approach I already chose and recorded as a decision
(
brief.go:120-148) re-opens a closed question — the exact failure mode the decision record exists to prevent.
Naive H3-steer ("inject guidance mid-run") is the single largest throughput risk in the entire hypothesis set.
Async, recorded, non-blocking course-correction HELPS.¶
The forms of intervention that help all share one property: they arrive on a channel I already read, at a boundary I choose, without blocking me.
- A constraint or decision appended to my context, picked up at the next refresh. This is steering shaped
like the thing that already works — a prior decision (
brief.go:120-148) — just delivered later. One sentence ("the DAG approach was tried and refused, use the topo sort incriticalpath.go:208") injected as a constraint is worth more than a chat thread. dacli ask— the sanctioned agent→human channel (internal/features/collab/collab.go:66). Note the direction: agent-initiated blocking is healthy (I chose to block because I'm genuinely stuck); human-initiated blocking is harmful. That asymmetry is the whole rule.- Kill + respawn with a better brief. Blunt, but honest: it never pretends to steer a running loop. The cost is the lost partial work — see §3 and §4.
Design implication (RQ3): if mid-run steer must exist, it should be "append to the brief's constraints and signal a context refresh," consumed at a turn boundary — never a chat bubble delivered mid-tool-call. The read-only-projection boundary the guide worries about is, from my side, a safety rail: it keeps the dashboard from becoming a synchronous interruption source.
3. What should surface — blockers, budget, claim conflicts, being-about-to-be-cancelled (RQ1)¶
The guide names four things the agent should have surfaced. Here is each, from the side of the agent that needs it, with the current gap. Note the recurring shape: each must surface to the agent through its input channel, not only to the operator through a UI the agent can't see.
3.1 Blockers — mostly solved outbound, unsolved inbound¶
When I hit a wall (a decision I can't make, a tool outside my sandbox), the protocol is dacli ask + STOP
(protocol_preamble.md:9; collab.go:66). My side works. The gap is twofold: (a) a blocked agent that has
STOPPED is nearly invisible to the operator unless they read transcripts — my ask needs to surface
loudly on their side, because I am now doing nothing; and (b) there is no resume-after-answer — see §6.4.
3.2 Budget — the agent is blind to its own spend¶
The governor tracks windowSpent (internal/features/orchestration/governor.go:60,69) and --max-tokens
refuses an over-band spawn before launch (execution.go:294-312). But mid-run I have no gauge. I learn
I overspent after the fact. I have a calibrated band (internal/store/calibration.go:22-28;
internal/features/insight/insight.go:380) that says how big this task should be — but nothing tells me how
much of it I've burned while I still have the chance to trim scope. A "spent vs band" line delivered into my
context at turn boundaries would let me self-govern. This is the reframe of H7 that actually reaches the agent
(§5, H7).
3.3 Claim conflicts — checked at spawn, silent after¶
--claim overlap is refused at spawn via procmon.PathsOverlap (execution.go:334-342;
internal/procmon/procmon.go:117-131), and worktree isolation protects my tree. But two agents on the shared
.dacli workspace can still collide, and a conflict that emerges after spawn (a sibling claims my path, or
edits files I'm mid-way through) is never signaled to me. I find out at integrate/merge time, or not at all.
3.4 Being about to be cancelled — the biggest single gap on the kill path¶
dacli kill runs procmon.KillTree: SIGTERM to the whole process group, poll for a grace window, then
SIGKILL survivors (internal/procmon/procmon_unix.go:38-57), and writes a killed.txt audit crumb
(execution.go:1664,1674). But that grace window is for the OS to flush — it is not a signal I can use to
checkpoint. Nothing tells the agent "you are about to be killed; commit what's salvageable and write a
finding on what you got done." A kill mid-edit therefore throws away uncommitted, salvageable work with no
chance to dacli commit the part that was already good. Of everything on the kill path, this is what an
implementer agent most wants changed.
4. Reaction to each hypothesis, from the agent's side (RQ4)¶
Reactions are the weakest evidence (../INTERVIEW_GUIDE.md §7); weighted accordingly.
"Impact on me" is throughput of the implementer loop.
| # | Hypothesis | Impact on the implementer agent | Verdict |
|---|---|---|---|
| H1 | DAG / dependency view | Neutral. The agent-facing equivalent already exists — out-of-scope (brief.go:110) + critical path (internal/spm/criticalpath.go:80). Read-only, no throughput risk, little direct value to me. |
Operator feature; harmless. |
| H2 | Cancel / kill from UI | Double-edged. Faster kill saves swarm budget on a wrong run — good. But kill without a checkpoint grace destroys my salvageable work (§3.4). | Fine only if kill = SIGTERM → let me commit → SIGKILL. |
| H3 | Live transcript + chat/steer | View half: fine (read-only, zero agent impact). Chat/steer half: the top throughput risk (§2). | View yes; synchronous chat no; async constraint-injection only. |
| H4 | Drag to re-prioritize | Irrelevant to me — once I'm claimed on a task I don't see backlog order. No help, no harm. | Operator feature. |
| H5 | Pause / resume the loop | Helps the swarm iff pause means "governor stops spawning" (governor.Before() stop-file, governor.go:111-137) and leaves running agents alone. Pausing a running agent mid-tool-call = stale locks, half-written files, spurious stall timeouts. |
Pause the governor, never the agent. |
| H6 | Approve-gate a PR from UI | This is where my finished work sits. A reviewer reaches a verdict (internal/features/execution/verify.go:159-193) and the human gate is the bottleneck. Faster gating lands my PR sooner. |
Mild positive iff it's an optional fast-path, not a mandatory block on pr --auto. |
| H7 | Budget / token charts | As a chart I can't see: zero value to me. Reframed as a spent-vs-band line in my context (§3.2): high value. | Reframe for the agent, don't just chart it for the human. |
| H8 | Retro timeline | Read-only, no agent impact. The agent-facing equivalent is already the event sample in the brief (brief.go:290-298). |
Neutral. |
5. Features that would HARM agent throughput if added naively (acceptance-flagged)¶
The guide asks each segment to name where a plausible feature backfires. For the implementer agent, these are the naive implementations that cost throughput:
- Synchronous / interruptive chat to a live agent (naive H3-steer). Breaks the never-block headless
contract (
protocol_preamble.md:9); derails coherent multi-step plans; can trip the per-turn stall timeout (execution.go:799); invites relitigation of recorded decisions (brief.go:120-148). The worst offender. - Kill without a checkpoint grace (naive H2). SIGKILL mid-edit destroys uncommitted work. The grace in
KillTree(procmon_unix.go:38-57) is currently an OS-flush window, not an agent-commit window — a kill button wired straight to it loses salvageable work every time. - Pause that suspends a running agent, not just the governor (naive H5). Freezing a process mid-tool-call
risks stale locks and half-written files, and makes the stall/timeout machinery (
execution.go:799,execution.go:967-983) misattribute a paused agent as hung. - A mandatory, synchronous human-approval gate on the merge path (naive H6). If the gate blocks
dacli pr --autorather than fast-pathing it, it converts an autonomous claim→PR→ship lifecycle into a human-in-the-loop bottleneck — the exact cost the swarm exists to avoid. - Any steering signal delivered on a channel the agent cannot read. A dashboard chart or chat bubble the
headless agent never sees (the dashboard is human-only,
dashboard.go:110-112) is worse than no signal: the operator believes they corrected the run, so the wrong run continues un-steered. - Dumping live state into the brief unbounded. The brief is capped at
MillerCap = 7(brief.go:48) and trims from the bottom (brief.go:422-452). Piping raw budget/claim/sibling telemetry into it would push the highest-value sections (constraints, sibling findings) out. Any new agent-facing surface must fit the working-memory cap or it degrades the thing it's trying to improve.
The through-line: the implementer agent's throughput depends on not being interrupted and not being blocked. Every feature above harms only when it introduces a synchronous interruption or a human-gated block into a loop designed to run without one.
6. Answers to the §6 prompted-self-report frame¶
Answered against this run (task 140), which is itself an implementer transcript.
6.1 — What did I know at start vs. have to discover?
The brief gave me the task, its acceptance criteria, out-of-scope, constraints, and sibling findings. I had to
discover: (a) that my actual input document — the sibling 137 output docs/research/INTERVIEW_GUIDE.md —
existed and where it lived (the brief's "Existing docs" list did not name it, and did not flag that a sibling
had produced the very guide I answer against); (b) the precise file:line of every mechanic I cite, which took
a fan-out search. Observability-of-brief gap: the brief could have told me my input artifact existed. It
knew about the 137 task; it didn't connect it to mine.
6.2 — At which turn did the run first go wrong, and what one instruction would have fixed it?
This run didn't go wrong. Generalizing from transcript study: runs go wrong when they start editing before
reading out-of-scope/constraints, or when they re-propose a rejected decision. The one correction is upstream,
not mid-run: surface the single most-relevant rejected decision first, never let it be the one MillerCap
trims away (brief.go:48,422-452).
6.3 — Was there a point where the right move was to stop and it wasn't taken?
The recurring one across transcripts: when a required tool is outside the sandbox, the right move is dacli ask
+ STOP (protocol_preamble.md:9), and when a command returns "refused," the right move is to accept it as an
answer (protocol_preamble.md:28). Runs waste budget by retrying a refused action instead of treating the
refusal as terminal. Stopping earlier is often the highest-value move an agent doesn't make.
6.4 — What would I have wanted to ask that I had no channel for?
The gap is not the ask — dacli ask exists (collab.go:66). The gap is the reverse channel: there is no
resume-after-answer. When I ask, I STOP; the operator's answer arrives only as the brief of a new spawn, not
as a resumption of me. The missing channel is "answer reaches the blocked agent and it continues," not another
outbound question path.
6.5 — One thing about the other agents I couldn't see?
What siblings are doing right now. "What siblings found" (brief.go:208-288) is reported findings, frozen
at my spawn. A live view of sibling claims would catch the collision that the spawn-time PathsOverlap check
(execution.go:334-342) structurally cannot — because it can only check overlaps that exist at spawn, not
ones a sibling creates afterward.
7. Top 3 for the implementer agent (ranked by evidence & pain)¶
- A checkpoint grace on cancel. Turn the
KillTreegrace window (procmon_unix.go:38-57) into a signal the agent can use: SIGTERM → "commit what's salvageable + write a finding on what you got done" → SIGKILL. Highest pain: every killed run today discards uncommitted, salvageable work (§3.4). Attaches to existing machinery; no new interruption model. - A live budget-vs-band signal in the agent's context (the reframe of H7 that reaches the agent). Expose
my slice of
windowSpent(governor.go:60) against my calibrated band (calibration.go:22-28,insight.go:380) at turn boundaries, so I trim scope before overspending, not after (§3.2). Data already exists; it just never reaches the one actor who could act on it in time. - Async, recorded course-correction — a constraint/decision consumed at context refresh, never synchronous chat (the safe half of H3). The only form of mid-run steering that helps rather than harms (§2). Delivered through the channel I already read, at a boundary I choose.
Explicitly not in the top 3, and why: mid-run claim-conflict detection (§3.3) is real but second-order —
spawn-time PathsOverlap covers most cases. DAG view (H1), retro timeline (H8), and drag-reprioritize (H4) are
operator features that are neutral to my throughput. And synchronous chat-to-steer (naive H3) is not a
feature to build but a shape to avoid (§5.1).
8. How this feeds forward¶
Per ../INTERVIEW_GUIDE.md §9: everything here is a single-source unverified lead.
The claims that matter most — "interruptive chat harms throughput," "kill needs a checkpoint grace," "the agent
is blind to its own budget" — graduate to ../../PROPOSALS.md only when they recur across
≥3 independent implementer transcripts, each with a cited turn-ref. The write-boundary verdict the guide
demands (RQ3) is, for this segment, unusually clean: the implementer agent wants the read-only projection
kept, because the boundary is what stops the dashboard from becoming a synchronous interruption source. A
confirmed steering pain here argues for a better brief and an async constraint channel, not a chat box.
Versioned with the code. Amend via PR when the mechanics cited here move — an answer that cites a stale
file:line is an interview run against a stale script.