Skip to content

feat(claude): split output contract into terse mid-turn and self-contained wrap-up - #40

Merged
jinyeow merged 1 commit into
mainfrom
feat/output-contract-wrapup
Jul 27, 2026
Merged

feat(claude): split output contract into terse mid-turn and self-contained wrap-up#40
jinyeow merged 1 commit into
mainfrom
feat/output-contract-wrapup

Conversation

@jinyeow

@jinyeow jinyeow commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Why?

The measurable gap. The concise output style specified the final message of a turn in exactly
one unspecified phrase — "tight bullets" — under a rule that already demanded "be extremely concise"
for every message. Nothing required the wrap-up to be understandable on its own. This ships four
named slots (What changed / What this means / Caveat / Verify) plus a mechanical trigger for
when they apply, so the final message of a multi-file or multi-stage turn can no longer be a bullet
list of identifiers borrowed from a subagent report ("B4", "Slice 2", "the MI-020 failure shape") —
which is what it had actually degenerated into.

Concrete maintenance consequence. The wrap-up is the only part of a turn that gets re-read later.
When it is unreadable without scrolling back through the tool calls, the turn has to be re-derived
from scratch — either by scrolling, or by asking for a re-explanation, which is the request that
prompted this change. A fixed header sequence also makes an omission visible: a missing named slot
reads as a gap, where a missing sentence does not.

Size. 3 files, +19/−8 (claude/AGENTS.md +12/−3, claude/output-styles/concise.md +13/−4,
claude/README.md +2/−1). No code, no tests — this is prompt text on both the advisory and the
enforced path.

Cost, honestly. The output contract is now roughly ten dense rules where it was three. Every rule
added raises the chance the whole block is partially dropped under heavy context load, which is the
failure mode this work keeps hitting. None of this text has been exercised on a real transcript yet —
it has been reviewed five times and used zero times. If wrap-ups read as mechanical after a week of
real use, the first thing to cut is the precedence rule.

Change

Split the contract by position in the turn rather than softening terseness globally:

  • Mid-turn stays extremely concise — one signpost line per batch of related actions, no
    per-call narration.
  • Final wrap-up is self-contained, in full sentences, written for a junior-to-mid engineer
    who saw none of the tool calls.

Adds the fixed header sequence, the trigger (two or more files changed, or two or more named stages
each producing a deliverable), a shorthand-expansion rule (plain description first, label in brackets
after), and an explicit "no length cap, but every line earns its place" rule.

Both the advisory copy (claude/AGENTS.md, also installed as ~/.codex/AGENTS.md, so Codex CLI
reads it and never sees the output style) and the enforced copy (claude/output-styles/concise.md,
injected at system-prompt level) are updated in sync, per the sync note in the latter's frontmatter.

Review

Five passes: Codex MCP (three rounds), an Opus red-team subagent, a Fable subagent, and a cold-read
pass with no history to counter anchoring. Passes 4–5 were mostly correcting wording introduced in
passes 1–3, which is where returns flattened. The final Codex pass returned zero findings.

Notable rejections of my own drafting: an anti-padding brake ("if the wrap-up is longer than the diff,
it is padding" — meaningless on read-only turns, and wrong in the routine small-diff-after-long-
investigation case) and a precedence rule that wrapped skill output shapes rather than deferring to
them (a findings-only review contract stops being findings-only once wrapped).

The sharpest catch came from the red-teamer and had survived two prior passes: the below-trigger rule
read absolutely ("a direct 1–2 line answer, no headers"), which forbade the Verify command on
single-file changes — the most common turn shape in this repo.

Deferred

A blocked turn — several things asked, most done, one stuck — has no good slot for the blocker; the
current rule puts it in the last bullet under What changed. Two fixes were considered (an optional
fifth Blocked on header, or a rule that the blocker leads the wrap-up) and both were deliberately
declined for now. Reasoning is recorded in the project brain. Revisit with real examples.

Not live on merge

The live config is the C:\Users\jin-y\dotfiles clone, so this takes effect only after that clone is
pulled — and output styles load at session start, so it needs a fresh session after that.

…ained wrap-up

The "be extremely concise" rule applied to every message including the final
summary, and the wrap-up was specified as "tight bullets" — i.e. shorter still.
Nothing required the final message to stand on its own, so summaries came out
dense with unexplained shorthand carried over from subagent and review-skill
reports.

Split the contract by position in the turn instead of softening it:

- Mid-turn stays terse (one signpost line per batch, unchanged).
- The wrap-up is self-contained, written for a junior-to-mid engineer who saw
  none of the tool calls, using a fixed header sequence: What changed (or
  What I found on read-only turns) / What this means / Caveat / Verify.
- Trigger is mechanical: two or more changed files, or two or more named stages
  each with their own deliverable; a no-file-change turn qualifies on two or
  more separately reportable findings or one requested report artifact.
- Shorthand must be expanded on first use — plain description first, label in
  brackets after — covering in-house nouns as well as labels, and vocabulary
  invented by a subagent or review skill must be translated before relaying.
- No numeric length cap; the brake is that every line must explain the outcome
  or change what the reader does next.

Scoped the global "extremely concise" preference to the working phase, and
scoped the no-cap rule to replies (prompts authored for other models still take
an explicit cap, per "Prompting downstream models").

Mirrored in the concise output style, which enforces at system-prompt level what
AGENTS.md can only advise, and refreshed the settings table description.
@jinyeow
jinyeow merged commit 983ec88 into main Jul 27, 2026
5 checks passed
@jinyeow
jinyeow deleted the feat/output-contract-wrapup branch July 27, 2026 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant