Skip to content

fix: docs-audit bug batch (headless, reading helpers, held tasks, standing, teams, fan-out checks, media, remote) - #1604

Draft
santoshkumarradha wants to merge 23 commits into
devfrom
fix/docs-audit-batch
Draft

santoshkumarradha wants to merge 23 commits into
devfrom
fix/docs-audit-batch

Conversation

@santoshkumarradha

@santoshkumarradha santoshkumarradha commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

One stacked branch for the docs-audit bug list (BUGS-MASTER.md, dev 837b2b0). Each commit fixes one issue or one closely related group. Every fix has a named test. For the critical fixes and most others, the reviewer confirmed that the test fails with the fix reverted. Draft: not for merge until the owner has looked.

Fixed

Issue Fix Test (fails without the fix) e2e (real binary, isolated HOME, default model)
#1566 A blank brief is refused where the goal text is resolved, on every road TestReadTextRejectsAnAllBlankArgumentList PASS: codeaf do "" and do " " exit 1 with error: no goal given; 0 usage rows
#1567 Delegate flags are parsed wherever they sit; an unknown flag is refused; -- ends flags TestParseReadsFlagsAfterTheBrief, TestParseRefusesAnUnknownFlagAfterTheBrief PASS: flags-after-brief run shows maxCost=$0.5, ceiling_usd:0.5; --bogus-flag exits 1 naming it
#1568 A read hand-off gets the audit read-only belt (durable flag on the quick node); what it cannot do goes back to the conversation TestQuickWorkerCarriesReadOnlyBelt, TestQuickReadOnlyBeltRefusesWrites not run (model-dependent turn shape)
#1549 Run workers carry the one standing section through the common brief composer TestBeltWorkerBriefCarriesStandingOrders PASS: 2/2 worker briefs carry Standing orders and the rule
#1551 Manager gets a fallback handle at registration; team_start carries the approval posture; fallback rule words show the cost clause TestAnUntitledManagerGetsAHandleWhenRegistered, TestTeamStartOfKindTeamMakesASubTeamWhoseManagerReportsUp, TestTheStartsCardSaysWhoIsStartedAndWhatItCosts PASS (item 1): new manager has "handle":"manager-dohh"
#1552 M gives the keyboard to the new manager; hints say M; key sheet lists M m p r d u TestStartingAManagerReturnsKeyboardToItsComposer, TestTeamsActionKeysAreListedOnTheHelpSheet —
#1553 Redial reclaims the keyboard by client id (only the same window); a redial's ssh stderr goes to the diagnostic tail TestARedialReclaimsTheKeyboardBeforeTheOldPipeLeaves, TestRedialSSHStderrStaysOutOfTheTerminal —
#1555 Project orders compare cleaned paths; card quotes the live allowance; task firings read task: TestProjectStandingOrdersMatchANormalizedWorkspace, TestStandingCardReadsTheLiveDailyBudget, TestATaskFiringUsesTheTaskActivityWord, TestATaskFiringIsDrawnAsATask —
#1557 /drafts draws its page; an empty /skill closes and clears the box (folder refusals kept) TestEmptyDraftPageDrawsItsOwnEmptyState, TestBareSkillOnAnEmptyShelfDoesNotLeaveAPathInTheBox —
#1572 Checker ceiling kept per check task; unfinished checks fail the run and are named TestCrewFactoryGivesEachCheckerItsOwnSpendCeiling, TestSupervisorDoesNotFinishWhenACheckDoesNotFinish not exercised: the planner did not split in two tries
#1576 Team header reads today's decided raise TestTeamsHeaderUsesTodaysRaisedCap —
#1577, #1583 Wall shows only this window's conversations; a tile lands on its conversation TestWallTileFromTeamsPageLandsOnConversation, TestSharedEngineWallDoesNotKeepTheSwappedConversationOpen —
#1578 Inline renderer keeps <id>-style text TestInlineAngleBracketPlaceholdersStayInModelProse —
#1580 ssh control path must fit with OpenSSH's temp suffix too TestSSHControlPathFitsOpenSSHTemporarySuffix —
#1581 Team-name answer wakes the paint clock TestTeamNameAnswerWakesAnIdlePaintClock —
#1585 team_start description no longer claims the person is always asked TestTeamStartDescriptionMatchesTheConversationPosture —
#1586 Images named by sniffed bytes, one helper for both doors TestGenerateImageNamesTheFileByItsBytes, TestGenerateImageUsesTheSniffedExtensionWhenTheProviderLies —
#1587 esc cancels surface-owned browser sign-ins TestEscapeCancelsAPendingCodexBrowserSignIn —
#1588 Speech bills under its own role; media calls write a call-log pair with cost TestSpeakUsageLedgerNamesTheSpeechCall, TestSpeechCallIsWrittenToTheCallLogWithItsCost —
#1589 Composing list admits audio rows with the music id mark TestComposingPickerKeepsAudioRowsMarkedAsMusic —
#1591 Naming its own team in team_post gets the right rule TestSubTeamManagerNamingItsOwnTeamGetsTheRule —
#1535 Hosted surface reaches the engine's memory commands; welcome says whether it remembers TestMemoryCommandsUseTheHostedStoreWhenTheAgentHasNoLocalBrain —

Fixes #1566
Fixes #1567
Fixes #1568
Fixes #1549
Fixes #1551
Fixes #1552
Fixes #1553
Fixes #1555
Fixes #1557
Fixes #1572
Fixes #1576
Fixes #1577
Fixes #1578
Fixes #1580
Fixes #1581
Fixes #1583
Fixes #1585
Fixes #1586
Fixes #1587
Fixes #1588
Fixes #1589
Fixes #1591
Fixes #1535

Partly fixed (issue stays open)

Squash-merge note: some commit messages below say Fixes #1571, Fixes #1554 and Fixes #1574. Delete those lines from the squash message, because these three issues are only partly fixed.

Needs owner ruling (not changed)

Dropped or left to other PRs

How it was checked

🤖 Generated with Claude Code

santoshkumarradha and others added 23 commits September 27, 2026 00:03
readText resolved one empty or all-blank argument to an empty goal with no
error, so `codeaf do ""` ran a paid job with a goal the planner invented.
The blank check now sits where the goal text is resolved, for every road.

Fixes #1566

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Go's flag package stops at the first positional word, so the documented
`senior-dev "<brief>" --max-cost 0.5` form folded every trailing flag into
the brief and ran with the default ceiling. Flags are now read wherever they
sit for every delegate program; `--` still ends them.

Fixes #1567

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The run engine's workers reported dollars but not tokens, so `do --json`
printed zero tokens beside a non-zero spend. Workers, the supervisor and the
summary now carry input and output tokens to the receipt.

Part of #1558 (the token item; the other items stay open)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Browser sign-ins started from /connect or the Codex row live on the surface,
with no turn for esc to interrupt, so the listener stayed pending. Esc now
cancels every surface-owned browser flow through the existing abandon door.

Fixes #1587

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The read hand-off admitted an ordinary quick task with the full belt (bash,
commit), guarded only by a prose line, so a manager's whole directive could be
taken by a "reading" helper that wrote, committed and merged, and a request
for a task on a named model became in-place edits with no branch. The quick
node now carries a durable read-only mark and its worker gets the audit
read-only belt at the one place quick workers are built; a request the reader
cannot serve hands control back to the conversation. A failed hand-off retires
a never-started helper instead of cancelling it into a stopped card, and still
stops one that did start.

Fixes #1568
Part of #1569 (the chat's own prose about model and cost is unchanged)
Part of #1554 (item 3)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TaskGraph.briefLocked appended the project's standing orders to a task
node's brief, but a run's workers are briefed from the plan store by
BeltWorkerBrief, which never saw that tail, so no plan-born worker was told
the rules. The run spec now carries the one rendered standing section and
every worker the run seats gets it through the common brief composer.

Fixes #1549

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…llowance, task firings say task

A project order stored with a trailing separator did not reach its own
project and was listed under other projects; the standing card quoted the
day allowance the session started with, not the one /budget set (the one the
spend rail enforces); and a firing that ran a task was drawn as "said:".

Fixes #1555

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/drafts claimed every key while its page had no overlay height or rows, so
it drew nothing until esc. /skill on an empty shelf opened a picker with no
choices and left `/skill ` in the box, so later commands became its path.
The drafts page is drawn and pointed like every other place, and an empty
skill catalog closes the picker and clears the box once both reads answer.

Fixes #1557

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the cards and pages say what is true

- A manager made with M had no handle until its first turn titled it, so
  team_send from the global manager could not reach it. SetManager now gives
  an untitled manager a unique fallback handle when it is registered.
- A sub-team started by team_start did not inherit the starting manager's
  approval posture; the start entry now carries it and the child gets it
  before it runs.
- The team_start consent card quoted the policy's fallback rule word
  "default" instead of the cost clause; approval names its fallback rules
  and the card treats them as no rule.
- team_start's description told the model the person is always asked first,
  so a manager under an allowing posture reported an approval nobody gave.
- After M the keyboard stayed on the teams page; hints said m; the key sheet
  omitted M m p r d u.
- After Raise to $4 the header kept the recurring cap; it reads today's
  decided raise, the packet the cap gate uses.
- A sub-team manager naming its own team in team_post got an unknown-team
  refusal; it is now told team_post is for the team above.

Fixes #1551
Fixes #1552
Fixes #1576
Fixes #1585
Fixes #1591

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…p is not a failure

- A task held by the busy-machine gate had already taken its folder lock and
  checked out its branch, and /stop could not end it until the driver woke.
  Admission is now checked first: an admitted run keeps the synchronous
  route, folder, store, copy order (so its refusals still leave no run
  behind); a held run seeds only its plan store, shows queued with the
  machine-busy reason, and prepares its folder and copy after admission.
  A stop on a held run settles it at once through one driver settlement.
- After an engine restart an interrupted belt run's plan store stayed live,
  so its root read working forever with no worker; startup now archives it.
- An explicit stop recorded the crew as not kept, so the crew line said
  failed and offered /redo stronger and the router learned a failure. A stop
  is now its own outcome with no learning signal and reads stopped.

Fixes #1571
Fixes #1554

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e ledger and the call log

- Both image doors chose a file suffix from the provider's declared type and
  kept a requested .png, so JPEG bytes were saved as .png. One helper in the
  provider now names an image from its sniffed bytes, falling back to the
  declared type, and both doors use it.
- speak billed through the unnamed auxiliary usage path, so its spend had no
  role in usage.jsonl, and media HTTP calls wrote no call-log rows. Speech now
  records under its own role, and every media request writes one start/end
  call-log pair carrying the provider's cost.

Fixes #1586
Fixes #1588

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every launch of the ssh link teed its stderr to the terminal, so a redial
while the TUI held the alternate screen painted ssh's diagnostics over it.
Only the first launch writes to the terminal now; a redial's stderr goes to
the session's diagnostic tail.

Part of #1553 (the stderr item; the keyboard-focus item stays open)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…task titles end on a whole phrase

- The / list and /help omitted /land now, /crew cap task <dollars> and
  /cache clean now, which dispatch and the manual already support.
- /compact on a short chat printed the engine's raw sentinel error; it now
  says nothing to compact yet.
- The fallback task title could end on a dangling word ("... each of"); it
  now stops at the nearest phrase boundary.

Part of #1559 (the /new title, key-sheet and /status items stay open)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A --host redial arrives before the old pipe has detached, so the engine still
recorded that dead pipe as the driver and made the returning window a
watcher ("another window"). Each surface now carries a stable client id
across its redials, and a returning window replaces the recorded driver only
when that driver is its own previous connection; another live window keeps
the keyboard.

Fixes #1553

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… bad check paths are refused, kept branches reach /land

- Every checker in a run drew from one checker-seat tally, so after the
  first few checks the rest stopped "at its spend ceiling" having spent
  almost nothing. The ceiling is now kept per check task (the run's task cap
  is still shared), and a run whose checks did not finish no longer ends done;
  its landing names the unfinished checks.
- A planner-declared per-part check was stored verbatim even when it named a
  path that does not exist and that the part does not produce (issue_.go).
  Such a check is now refused at division admission with the check and path
  named, so the planner rewrites it; nothing guesses a filename.
- A run kept on a protected or moved checkout was invisible to /land. Kept,
  conflicted and aborted run branches are now listed and landable by /land,
  and editor .orig backups are classified as droppings so they never reach a
  task branch.

Fixes #1572
Fixes #1573
Fixes #1574

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sed, never used

A /task typed on Home in project B's window could open on another window's
live engine for project A and commit there, carrying A's uncommitted edits.
The keeper, the one place every new conversation is bound, now holds an
absolute ask to the workspace the engine answers for and refuses a mismatch
visibly ("could not open the conversation in <B> · the engine answered for
<A>") before anything is sent. Plain messages and /task are covered as one
target path.

Part of #1466 (the road that reaches the wrong engine is not yet found; this
stops it from running anything there)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Teams lands on it

- The wall built its tiles from the tab strip, which remembers visited and
  other windows' conversations, so a new window showed another window's
  conversation as open here. It now draws the front tab and the ones this
  window holds.
- Opening a tile closed the wall but did not leave the page it was opened
  from, so from Teams it landed back on Teams. Tile opens now go through the
  shared landing seam.

Fixes #1583
Fixes #1577

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d memory works, long homes dial, check rows show

- Model prose placeholders like <id> were parsed as raw HTML and dropped;
  the shared inline renderer now keeps their source text.
- The team naming card's async answer marked the wall dirty but did not wake
  the paint clock, so it drew only on the next key; it now wakes it.
- The composing model list required a music modality; audio-output rows with
  the music id mark (Lyria) are admitted, plain speech rows are not.
- /memory, /remember, /memories and /forget said memory is off on the
  default hosted engine road because only an in-process agent was consulted.
  The welcome now says whether the engine remembers, and the hosted surface
  reaches the engine's memory commands over the wire.
- --host under a long codeaf home failed because the ssh control-path check
  ignored OpenSSH's 17-character temporary suffix; both forms must now fit,
  or multiplexing is left off.
- A plan's check row that repeats its worker's title was deduplicated away
  from the Tasks column; check rows are never hidden by title.

Fixes #1578
Fixes #1581
Fixes #1589
Fixes #1535
Fixes #1580
Part of #1556 (the check-row item; the landing-race item stays open)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The real-binary check showed that archiving an interrupted run's plan store
on startup made a task that never ran read done after a restart. A done that
nothing earned is worse than the working row it replaced, so the reconcile
is removed and #1554 item 1 stays open for a fix that says interrupted.

Refs #1554

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The full session suite showed the refusal is too eager: a declared check
that names a package a part will create (go test ./internal/rank) was
refused as a missing path, which broke the family-check lift. Guessing
which paths a part will produce is not a sound seam, so the refusal is
removed and #1573 stays open.

Refs #1573

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@santoshkumarradha

Copy link
Copy Markdown
Member Author

Independent read-only review of all 23 commits (origin/dev...4643131c5).

Verdict: 22 ok, 1 minor concern, no blockers.

Minor concern: internal/remote/server.go:1055. Redial ownership is recognised only when the client sends ClientID. Older clients keep the old redial behaviour. This keeps compatibility and adds no regression.

Checked per commit: root cause at the right seam, regressions and security (read-only helper toolset, ssh socket path, key handling), test coverage, and complexity.

Before merge:

  • Drop Fixes #1571, Fixes #1554 and Fixes #1574 from the squash message. These are partial fixes.
  • Confirm the 10 internal/tui3 credit-warning test failures also appear on dev without this PR.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment