Skip to content

Commit 09dbbe3

Browse files
committed
docs(cli): consolidate ADR-T-010 implementation record
Promote ADR-T-010 into the canonical implemented command-line output contract. Fold in the rollout plan's scope, command classifications, shared CLI infrastructure summary, implementation status, and regression guards so the ADR itself records the completed migration. Refresh the changelog from stage-by-stage rollout notes into a completed contract summary, and remove the now-obsolete standalone conformance plan. Update ADR-T-009 to describe the helper and config-probe work as prerequisites for the future entry-script rewrite.
1 parent 7673bff commit 09dbbe3

4 files changed

Lines changed: 445 additions & 721 deletions

CHANGELOG.md

Lines changed: 41 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -79,73 +79,51 @@ error system (ADR-T-006), MSRV raised to 1.88.
7979

8080
#### Added
8181

82-
- ADR-T-010, extracting ADR-T-009's helper stdout/stderr convention into
83-
a global command-line output contract for the application.
84-
- Shared stage-1 command-line contract primitives in
85-
`torrust-index-cli-common`: control-plane record schema, baseline exit-code
86-
classes, structured help/version/usage/TTY-refusal/panic record types, and
87-
diagnostic redaction helpers.
88-
- Stage-2 shared CLI infrastructure in `torrust-index-cli-common`: JSON
89-
`clap` help/version/usage wrapping, direct JSON stderr control-plane writes,
90-
a JSON-only panic hook, idempotent JSON stderr tracing with `RUST_LOG` /
91-
`--debug` precedence, a non-interleaving stderr writer, and stdout/no-stdout
92-
command runners, including an async runner for no-stdout side-effect
93-
commands.
94-
- Stage-10 regression guards for ADR-T-010: workspace Clippy lint levels now
95-
deny raw Rust stdout/stderr print macros and direct `std::process::exit`
96-
outside explicit local exceptions, and the `cli_contract` integration test
97-
keeps in-scope binary `main` functions returning `ExitCode` instead of
98-
`Result`.
82+
- ADR-T-010 establishes a repository-wide JSON-only output contract for
83+
first-party command-line entrypoints. Stdout is reserved for result data;
84+
stderr carries diagnostics and control records; commands that emit stdout
85+
result data refuse direct terminal stdout.
86+
- `torrust-index-cli-common` provides the shared implementation for that
87+
contract: JSON `clap` help/version/usage handling, JSON panic diagnostics,
88+
JSON stderr tracing, TTY refusal, stdout JSON emission, command runners,
89+
baseline exit-code classes, control-plane record types, and redaction
90+
helpers.
91+
- Regression coverage now protects the contract with CLI behavior tests,
92+
binary-boundary checks, and workspace lint rules denying accidental raw
93+
stream output or direct process exits outside the shared CLI boundary.
9994

10095
#### Changed
10196

102-
- Helper stdout result schemas are explicitly versioned with top-level
103-
`schema` fields. `torrust-index-auth-keypair` emits `schema`,
104-
`private_key_pem`, and `public_key_pem`; `torrust-index-config-probe` emits
105-
`schema`, `database`, and `auth`; `torrust-index-health-check` emits
106-
`schema`, `target`, `status`, and `elapsed_ms`.
107-
- `torrust-index-auth-keypair`, `torrust-index-config-probe`, and
108-
`torrust-index-health-check` now use the shared JSON `clap` parser and JSON
109-
panic hook. Their `--help`, `--version`, argv errors, TTY refusal, and panic
110-
diagnostics are JSON control-plane records on stderr; stdout remains reserved
111-
for successful result JSON.
112-
- Central application logging now delegates to the shared ADR-T-010 JSON stderr
113-
tracing setup. The `torrust-index` server keeps stdout empty for normal
114-
operation, uses the configured logging threshold as its default filter, and
115-
lets a non-empty `RUST_LOG` override that default.
116-
- Root Rust binaries now return explicit `ExitCode` values at their `main`
117-
boundaries and install the shared JSON panic hook. `parse_torrent` and
118-
`create_test_torrent` now use the shared JSON `clap` parser, JSON stderr
119-
tracing runners, and focused CLI contract tests.
120-
- `parse_torrent` now emits one JSON stdout result object with `schema`,
121-
`torrent`, `original_v1_info_hash`, and `input_byte_length`, leaves stdout
122-
empty on failure, and refuses direct terminal stdout with a JSON stderr
123-
control-plane record.
124-
- `create_test_torrent` now keeps stdout empty, reports the generated torrent
125-
path as a JSON status record on stderr, and converts argument, encode, file
126-
creation, and write failures into JSON diagnostics with explicit exit codes.
127-
- `import_tracker_statistics`, `seeder`, and `upgrade` now use the shared JSON
128-
`clap` parser, JSON panic hook, JSON stderr tracing runner, and no-stdout
129-
side-effect command contract. Their command-reachable tracker statistics,
130-
seeder, and upgrade paths now emit structured tracing diagnostics and
131-
propagate command failures instead of printing plain text or relying on panic
132-
output.
133-
- Command-reachable shared libraries no longer emit raw stream output for
134-
shutdown and mail-template diagnostics. Server shutdown notices now go through
135-
structured tracing, and mail template initialization failures are propagated
136-
to callers instead of printing or exiting from the mailer library.
137-
- The container entry script now follows ADR-T-010 during its pre-`su-exec`
138-
orchestration phase. It keeps stdout empty except for helper stdout captured
139-
internally in command substitutions, emits JSON control-plane records on
140-
stderr, checks for `jq` before JSON-dependent helpers run, emits `DEBUG=1`
141-
phase records instead of enabling `set -x`, and wraps controlled utility
97+
- Helper binaries (`torrust-index-auth-keypair`,
98+
`torrust-index-config-probe`, and `torrust-index-health-check`) share the
99+
JSON CLI boundary. Their successful stdout payloads remain single JSON
100+
objects, now explicitly versioned with a top-level `schema` field, while
101+
help, version, argv errors, TTY refusal, panic diagnostics, and tracing are
102+
emitted as JSON records on stderr.
103+
- The `torrust-index` server and root Rust binaries return explicit
104+
`ExitCode` values at their `main` boundaries and install the shared JSON
105+
panic hook. Central application logging uses JSON tracing on stderr, with a
106+
non-empty `RUST_LOG` taking precedence over the configured default filter.
107+
- `parse_torrent` is a stdout-result command. It emits one JSON object with
108+
`schema`, `torrent`, `original_v1_info_hash`, and `input_byte_length`, leaves
109+
stdout empty on failure, and refuses direct terminal stdout with a JSON
110+
diagnostic record.
111+
- `create_test_torrent`, `import_tracker_statistics`, `seeder`, and `upgrade`
112+
are no-stdout side-effect commands. They keep stdout empty, report status and
113+
diagnostics as JSON/NDJSON on stderr, and propagate command failures instead
114+
of printing plain text or relying on panic output.
115+
- Command-reachable shared libraries use the command diagnostic path instead of
116+
raw stream output. Shutdown notices are structured tracing records, mail
117+
template failures are returned to callers, terminal color formatting is
118+
removed from command paths, and parsing helpers leave reporting decisions to
119+
their command callers.
120+
- The container entry script follows the JSON stderr contract during startup:
121+
it captures helper stdout internally, keeps its own stdout empty before
122+
`su-exec`, checks for `jq` before JSON-dependent helpers run, emits explicit
123+
`DEBUG=1` phase records instead of `set -x`, and wraps controlled utility
142124
failures with captured stderr fields.
143-
- Operator documentation now describes the ADR-T-010 migration state: helper
144-
binaries have the JSON stdout contract, the server emits JSON tracing on
145-
stderr, root Rust command migrations and shared-library cleanup have their
146-
JSON stream contracts, and the container entry script has its stage-eight JSON
147-
stderr contract documented. The conformance plan also records the stage-ten
148-
regression guard implementation.
125+
- Operator documentation and command examples describe the completed contract
126+
across the README, container guide, upgrade notes, and command module docs.
149127

150128
### ADR-T-009 — Container infrastructure refactor
151129

adr/009-container-infrastructure-refactor.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1266,7 +1266,7 @@ Tracked for visibility; not part of this refactor:
12661266
- `docker buildx` multi-platform builds (`linux/arm64`).
12671267
- Image signing with `cosign`.
12681268
- Pin base images (`gcr.io/distroless/cc-debian13` and `:debug`) by digest rather than tag for reproducible builds and supply-chain integrity.
1269-
- Reimplement the entry script's first-boot work as a small Rust binary (`torrust-index-entry`), eliminating vendored `su-exec` (privilege drop via direct `setgroups`/`setgid`/`setuid` syscalls), the shell-based IFS/heredoc parsing of probe output, and most of the curated busybox applet set. The `torrust-index-config` extraction, the ADR-T-010 helper conventions, and the `torrust-index-config-probe` helper are deliberate stepping stones: they pull the parsing surface out of the root crate, establish the stderr-tracing / stdout-JSON contract all helpers share, and prove the script-↔-Rust integration shape before committing to the full rewrite. The entry binary would depend on `torrust-index-config` and `torrust-index-auth-keypair` directly, eliminating the serialisation boundary entirely.
1269+
- Reimplement the entry script's first-boot work as a small Rust binary (`torrust-index-entry`), eliminating vendored `su-exec` (privilege drop via direct `setgroups`/`setgid`/`setuid` syscalls), the shell-based IFS/heredoc parsing of probe output, and most of the curated busybox applet set. The `torrust-index-config` extraction, the ADR-T-010 helper conventions, and the `torrust-index-config-probe` helper are deliberate prerequisites: they pull the parsing surface out of the root crate, establish the stderr-tracing / stdout-JSON contract all helpers share, and prove the script-↔-Rust integration shape before committing to the full rewrite. The entry binary would depend on `torrust-index-config` and `torrust-index-auth-keypair` directly, eliminating the serialisation boundary entirely.
12701270
- Promote `packages/render-text-as-image/` to a published crate and drop the root crate's `path = "packages/..."` override; once that lands, the directory can safely be added to `.containerignore`.
12711271

12721272
---

0 commit comments

Comments
 (0)