Skip to content

refactor: route command output through explicit writers - #123

Merged
entelecheia merged 1 commit into
mainfrom
refactor/94-output-routing
Nov 9, 2026
Merged

entelecheia merged 1 commit into
mainfrom
refactor/94-output-routing

Conversation

@entelecheia

@entelecheia entelecheia commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

Closes #94

Final T4 after #120, #121 and #122. Command/module text follows the supplied writer instead of bypassing it through process stdout. RunContext.Out resolves through Output() with the previous stdout default when nil. CLI contexts pass cmd.OutOrStdout(); console logs and apply-recording warnings use the error writer. Metadata/audit stderr warnings remain separate. Explicit tenant writers (including discard) retain priority.

Module and CLI bare stdout prints are gone. Shared UI helpers cover styled status rows and plain text/tables; names-only lists and raw id/groups/quota payloads keep their bytes. Production glyph literals are centralized in UI, including unstyled constants where a description enters JSON. Tenant uses the leaf UI constants; low-level backup previews use ASCII -> rather than adding an exec-to-UI dependency. Fleet shares the JSON encoder with its existing HTML-escaping mode and uses the same exit-code constant.

Verification

  • AC1/AC2: preceding collector/module-name work is retained. All 35 T3 status/check/doctor byte goldens are unchanged; the full race suite passes them. A new encoder test pins native versus fleet HTML escaping.
  • AC3: an AST/source guard verifies no bare fmt.Print* in module/CLI production code and no production glyph literal outside UI. Explicit-writer, nil fallback, stdout-leak, warning separation, raw-payload and table tests cover the routing.
  • AC4 / contract chore(release): staged fleet rollout of the epic #98 release without disruption #115: remote exact-head full race/build/vet passes at 11455ae, with failing ambient ufw and sshd first on PATH. Twenty managed renderers/constants are byte-identical to main. Config/profiles/fingerprints, fleet remote commands, sudoers and schedule sources are untouched. Six-profile module tests assert actual Check/RunAll outcome order and unchanged managed directories/files/backups.
  • Six-profile full CLI captures use isolated binaries with only existing detector/path seams: Ubuntu/Rocky SystemInfo, private SSH/Docker files and private command fixtures. Every selected module reaches RunAll; all twelve before/after invocations exit 0. Stdout differs only in marker spacing; stderr is identical after query-log clock normalization. File/state/lock/audit checks pass. These are controlled fixtures, not native/live fleet proof.
  • Specs: 21, 0 errors, 1 existing goal warning. Release notes: 32 pass. Source/gofmt checks pass.
  • Reviewer independently completed the previously deferred Mac check at 11455ae after the host became healthy: failing UFW first on PATH, race tests for CLI/module/UI/tenant/exec passed (14.5s/65.6s/1.4s/2.6s/2.2s), go vet ./internal/... clean, specs 21/0 errors. The author's earlier admission deferral is superseded by this exact-head reviewer evidence.

Reviewed text diffs

All six profiles have before/after captures under internal/module/testdata/output-t4/ and full CLI captures under internal/cli/testdata/output-t4/ (plus exit/stderr results). With colors disabled, the common change is one additional space after the status marker:

-  ✓ locale: already satisfied
+  ✓  locale: already satisfied
-  → system: Cap journald at 2G
+  →  system: Cap journald at 2G

When colors are enabled, RunAll uses the existing styled UI markers. Raw payload/table spacing and command words remain unchanged. Rollback symlink previews use ->; machine-facing Storage and Cloudflared arrows retain their existing bytes through unstyled constants. The fixture seeds a chosen Docker log driver so the pre-existing daemon-updates map iteration does not make captures nondeterministic; output is never sorted to hide module ordering.

Release notes

Text status rows use the common marker spacing/style, and rollback symlink previews use an ASCII separator. Commands embedded with a custom output writer now capture their module text consistently. JSON/Prometheus, managed file content and fleet/schedule commands are unchanged. No new reload, restart or operator action is introduced.

Copilot AI balanced review requested due to automatic review settings November 9, 2026 22:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@entelecheia
entelecheia marked this pull request as ready for review November 9, 2026 22:29
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T22:30:41.599756Z 11455ae Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@entelecheia
entelecheia merged commit 779c31d into main Nov 9, 2026
57 checks passed
@entelecheia
entelecheia deleted the refactor/94-output-routing branch November 9, 2026 22:35
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.

refactor: share duplicated helpers and route output through ui

2 participants