Skip to content

test: every --json command prints exactly one JSON document on stdout - #54

Merged
sre-helmcode merged 2 commits into
mainfrom
fix/json-stdout-clean
Oct 14, 2026
Merged

sre-helmcode merged 2 commits into
mainfrom
fix/json-stdout-clean

Conversation

@sre-helmcode

Copy link
Copy Markdown
Contributor

What

A guard test for the --json contract: with --json, stdout carries exactly one JSON document (JSON Lines for the commands that follow a run: nan run, nan automations run, nan runs logs) and nothing else; every hint, note and warning goes to stderr.

cmd/json_output_test.go:

  • TestEveryJSONCommandIsCovered walks the cobra tree and fails if a command with a --json flag has no case (and if a case names a command without one), so a new --json command cannot ship unchecked.
  • TestJSONStdoutIsOnlyJSON runs all 24 --json commands (30 invocations, including --detach, -f, rotate with --url --secret --no-grace, secrets set create and replace) through the real command tree against httptest fakes, with os.Stdout/os.Stderr redirected to files as a shell redirect sees them. It asserts one JSON document (or valid JSON Lines), no hint text, no control characters, no secret value, and the documented exit code.
  • TestTriggersAddJSONKeepsTheNoteOnStderr pins the case from the report: URL and signing secret in the JSON, the one-time note on stderr.

Why

The 0.1.33 prod E2E reported nan automations triggers add ... --json | jq failing on the "Store these now" note. The investigation found no CLI bug: the note already goes to stderr; the E2E ran > out.json 2>&1. An audit of every --json command found no stdout leak. This PR locks the contract in.

Evidence

  • Known-bad mutations: moving the one-time note to stdout, and printing the approval_kinds warning to stdout in automations create --json, both fail the test.
  • go build ./..., go vet ./..., gofmt -l . clean; go test ./... green.

Deploy notes

Test only, no behaviour change: internal/tui.Version is NOT bumped, so merging publishes no release.

🤖 Generated with Claude Code

barckcode and others added 2 commits October 14, 2026 16:34
Walks the command tree, requires a case for every command with a --json
flag, runs each against httptest fakes with os.Stdout/os.Stderr redirected
to files, and asserts stdout is exactly one JSON document (JSON Lines for
the commands that follow a run) with no hint text. The one-time trigger
note is asserted on stderr.

No behaviour change: the prod E2E report came from a 2>&1 redirect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…--json guard

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sre-helmcode
sre-helmcode merged commit 21ca879 into main Oct 14, 2026
5 checks passed
sre-helmcode pushed a commit that referenced this pull request Oct 20, 2026
Brings #50, #51, #52, #53, #54, #56 and #57 onto the new structure:

- mimo-v2.6-flash, qwen3.8-flash at 1M, and the Codex model catalogue:
  the writer changes go to internal/tools, the catalogue and its
  embedded prompt to internal/tools/codexprompt.
- BYOK runs, secrets and automation writes, and notifications: the
  commands go to internal/cli and hang off NewRootCmd; their goldens
  to internal/cli/testdata.
- The --json contract test counts the commands with a --json of their
  own, not the one every command inherits from the root.
- The embedded Codex prompt is Apache-2.0: its NOTICE and licence are
  now in THIRD-PARTY-NOTICES.txt.
- Messages without em dashes, and the new code lint-clean.
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.

2 participants