Skip to content

docs: SKILL.md named the wrong stream for every envelope - #17

Merged
chaoz23 merged 1 commit into
mainfrom
fix/skill-md-output-stream
Aug 19, 2026
Merged

chaoz23 merged 1 commit into
mainfrom
fix/skill-md-output-stream

Conversation

@chaoz23

@chaoz23 chaoz23 commented Aug 19, 2026

Copy link
Copy Markdown
Owner

Closes #13.

The defect

SKILL.md:37 told consuming agents:

Failures print JSON on stderr, never a traceback.

Every dmcheck envelope goes to stdout. stderr is empty.

An agent that followed the file read stderr for the failure payload and found nothing — an exit code with no envelope, indistinguishable from a crash. This broke the recovery path silently rather than degrading it, which is why it was the highest-impact finding in the family audit.

Verified across all three verdict paths, not just the failing one

I checked every envelope rather than the one that surfaced the bug, so the replacement claim is true of the whole contract and not just the case I happened to probe:

invocation exit stdout stderr
clean session 0 894 B 0 B
findings 1 3867 B 0 B
unreadable input 2 423 B 0 B
bad flag (argparse) 2 0 B 512 B

Mechanism: dmcheck/cli.py:74-77 — _print_invalid uses print().

The replacement

It also disambiguates the exit-2 overload tracked in #15, because the probe made the rule obvious:

Every envelope — clean, findings, and the honest lane — prints JSON on stdout, never a traceback. stderr carries only argparse usage errors, which also exit 2 but emit no JSON. So: exit 2 with an envelope on stdout is the honest lane; exit 2 with empty stdout means the call was malformed — fix it and retry. Read stdout.

That does not close #15 — the codes are still overloaded, and separating them is a code change. It does mean an agent can now tell the two apart correctly in the meantime.

Docs only

No code change, and no test asserts SKILL.md content (grep -rln 'SKILL.md' tests/ scripts/ .github/ → nothing), which is itself the gap chaoz23/srdcheck#82 exists to close. With that gate in place this class of defect fails CI instead of shipping.

Note: fixing this correctly required naming both streams, which exposed a false positive in the gate itself — it treated any mention of stderr as the claim and rejected this text. Fixed in chaoz23/srdcheck#84, which should land first.

🤖 Generated with Claude Code

SKILL.md:37 told consuming agents "Failures print JSON on stderr, never a
traceback." Every dmcheck envelope goes to stdout. stderr is empty.

Verified across all three verdict paths, not just the failing one:

  clean session      exit 0   stdout 894B   stderr 0B
  findings           exit 1   stdout 3867B  stderr 0B
  unreadable input   exit 2   stdout 423B   stderr 0B
  bad flag           exit 2   stdout 0B     stderr 512B  (argparse, no envelope)

Mechanism: cli.py:74-77, _print_invalid uses print().

An agent that followed the file read stderr for the failure payload and found
nothing -- an exit code with no envelope, indistinguishable from a crash. This
broke the recovery path silently rather than degrading it.

The replacement also disambiguates the exit-2 overload tracked in #15, since
the probe made the rule obvious: exit 2 with an envelope on stdout is the
honest lane; exit 2 with empty stdout is a malformed call.

Detected as STREAM_MISMATCH by chaoz23/srdcheck's family conformance gate.

Closes #13

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chaoz23
chaoz23 merged commit a383470 into main Aug 19, 2026
4 checks passed
@chaoz23
chaoz23 deleted the fix/skill-md-output-stream branch August 19, 2026 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant