Skip to content

Commit 6a7e8d1

Browse files
committed
docs(tracker-client): define IO contract and align issue specs
1 parent 97a209c commit 6a7e8d1

8 files changed

Lines changed: 1006 additions & 2 deletions

console/tracker-client/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@
22

33
A collection of console clients to make requests to BitTorrent trackers.
44

5-
> **Disclaimer**: This project is actively under development. We’re currently extracting and refining common functionality from the[Torrust Tracker](https://github.com/torrust/torrust-tracker) to make it available to the BitTorrent community in Rust. While these tools are functional, they are not yet ready for use in production or third-party projects.
5+
> **Disclaimer**: This project is actively under development. We’re currently extracting and refining common functionality from the [Torrust Tracker](https://github.com/torrust/torrust-tracker) to make it available to the BitTorrent community in Rust. While these tools are functional, they are not yet ready for use in production or third-party projects.
66
77
There are currently three console clients available:
88

99
- UDP Client
1010
- HTTP Client
1111
- Tracker Checker
1212

13+
## Documentation
14+
15+
- [Tracker CLI I/O Contract](docs/contracts/tracker-cli-io-contract.md)
16+
- [Tracker Client ADRs](docs/adrs/README.md)
17+
1318
> **Notice**: [Console apps are planned to be merge into a single tracker client in the short-term](https://github.com/torrust/torrust-tracker/discussions/660).
1419
1520
## UDP Client
@@ -186,7 +191,7 @@ This program is free software: you can redistribute it and/or modify it under th
186191

187192
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the [GNU Lesser General Public License][LGPL_3_0] for more details.
188193

189-
You should have received a copy of the *GNU Lesser General Public License* along with this program. If not, see <https://www.gnu.org/licenses/>.
194+
You should have received a copy of the _GNU Lesser General Public License_ along with this program. If not, see <https://www.gnu.org/licenses/>.
190195

191196
Some files include explicit copyright notices and/or license notices.
192197

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# ADR 20260512080000: Define Tracker CLI I/O Contract and Error Handling
2+
3+
- Status: Accepted
4+
- Date: 2026-05-12
5+
- Scope: console/tracker-client
6+
7+
## Context
8+
9+
The tracker client is a growing CLI surface with multiple commands (UDP client, HTTP client,
10+
tracker checker, and monitor features under active development). The project intends to extract
11+
this application into an independent repository.
12+
13+
Without an explicit contract, command outputs and error behavior can diverge, breaking user
14+
automation and increasing maintenance cost.
15+
16+
At the same time, existing commands may not yet fully match the desired target behavior, so the
17+
team needs a migration policy, not a flag day rewrite.
18+
19+
## Decision
20+
21+
Define a global Tracker CLI I/O contract for console/tracker-client.
22+
23+
### 1. Default output format
24+
25+
- JSON is the default output format.
26+
27+
### 2. Output channels
28+
29+
- stdout: normal command results and machine-consumable output.
30+
- stderr: progress reporting, diagnostics, warnings, and error output.
31+
32+
For monitor-style streaming behavior:
33+
34+
- Progress/probe events may be emitted as one JSON object per line (NDJSON style).
35+
- If emitted as progress, they go to stderr.
36+
- Final command result summary goes to stdout as JSON.
37+
38+
### 3. Exit-code semantics
39+
40+
Exit codes represent tracker client app execution state, not tracker endpoint health status.
41+
42+
- 0: command executed successfully, even if one or more trackers reported failures/timeouts.
43+
- 1: generic application/runtime failure (unexpected internal error).
44+
- 2: invalid tracker checker configuration/input errors.
45+
46+
Tracker-specific failures (for example announce timeout, scrape timeout, non-200 HTTP from a
47+
tracker) are represented in JSON result payloads, not in non-zero exit codes.
48+
49+
### 4. Progressive migration policy
50+
51+
- New features and new subcommands must follow this contract.
52+
- Existing features that do not yet comply will be migrated progressively when touched by new
53+
feature work or dedicated refactors.
54+
- No immediate broad rewrite is required.
55+
56+
### 5. Scope location
57+
58+
This policy is intentionally documented under console/tracker-client docs because the tracker
59+
client is expected to be extracted into its own repository.
60+
61+
### 6. Auditability and testing strategy
62+
63+
- Contracts should be auditable through stable structured payloads and explicit field definitions.
64+
- During the monorepo phase, conformance is enforced through issue specs and acceptance criteria.
65+
- After tracker-client extraction to its own repository, add dedicated E2E contract tests for
66+
stdout/stderr behavior, exit codes, NDJSON events, and JSON schema conformance.
67+
68+
## Consequences
69+
70+
### Positive
71+
72+
- Predictable behavior for shell pipelines and automation.
73+
- Clear separation between app-level failure and tracker-level status.
74+
- Lower migration risk through incremental adoption.
75+
- Documentation remains aligned with future repository extraction boundaries.
76+
- Auditable CLI behavior suitable for compliance and regression verification.
77+
78+
### Negative
79+
80+
- Transitional inconsistency until all legacy paths are migrated.
81+
- Additional implementation and review burden to keep channel/exit behavior consistent.
82+
- Full E2E contract coverage is deferred until extraction, so short-term assurance relies on
83+
spec-driven validation.
84+
85+
## Implementation Notes
86+
87+
- Command specs should reference the tracker client I/O contract document.
88+
- New command acceptance criteria should include channel correctness and exit-code behavior.
89+
- Contract schema updates should be backward compatible or explicitly versioned.
90+
91+
## References
92+
93+
- [Tracker CLI I/O Contract](../contracts/tracker-cli-io-contract.md)
94+
- [console/tracker-client/README.md](../../README.md)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Tracker Client ADRs
2+
3+
Architecture Decision Records (ADRs) for the console tracker client live in this folder.
4+
5+
These ADRs are scoped to the tracker client application and are intentionally separated from
6+
repository-level ADRs because the tracker client is expected to be extracted into its own
7+
repository in the future.
8+
9+
## Goals
10+
11+
- Capture durable decisions for tracker client behavior and architecture
12+
- Keep CLI/API contracts explicit and stable for automation users
13+
- Allow progressive migration of existing commands toward the target contract
14+
15+
## Index
16+
17+
See [ADR Index](index.md).
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# ADR Index
2+
3+
| ADR | Date | Title | Short Description |
4+
| ------------------------------------------------------------------------------------- | ---------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
5+
| [20260512080000](20260512080000_define_tracker_cli_io_contract_and_error_handling.md) | 2026-05-12 | Define Tracker CLI I/O Contract and Error Handling | Standardize JSON-first output, stdout/stderr channel rules, and exit-code semantics for tracker checker commands with progressive migration for existing features. |
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Tracker CLI I/O Contract
2+
3+
Status: Active
4+
5+
Scope: console/tracker-client commands, with explicit emphasis on tracker checker behavior.
6+
7+
## Purpose
8+
9+
Define stable rules for:
10+
11+
- output format
12+
- stdout/stderr channel usage
13+
- error payload structure
14+
- process exit codes
15+
16+
This contract is designed for automation-first CLI usage and progressive adoption.
17+
18+
## Core Rules
19+
20+
### JSON-first output
21+
22+
- JSON is the default output format for command results.
23+
- Result payloads on stdout are machine-consumable.
24+
25+
### Channel usage
26+
27+
- stdout:
28+
- final command results
29+
- structured status/results intended for downstream processing
30+
- stderr:
31+
- progress reporting
32+
- diagnostics and warnings
33+
- application error output
34+
35+
### Monitor/progress events
36+
37+
For monitor commands (for example `tracker_checker monitor udp`):
38+
39+
- Per-probe progress is emitted as NDJSON style: one JSON object per line.
40+
- Per-probe progress events go to stderr.
41+
- Final aggregate summary goes to stdout as JSON.
42+
43+
## Error Payload Schema
44+
45+
Application errors should use this envelope:
46+
47+
```json
48+
{ "error": { "kind": "string", "source": "string", "message": "string" } }
49+
```
50+
51+
Field meaning:
52+
53+
- kind: machine-readable error category (for example `invalid_configuration`)
54+
- source: where the error originated (for example `TORRUST_CHECKER_CONFIG`, `config_path`, `runtime`)
55+
- message: human-readable detail
56+
57+
## Exit Codes
58+
59+
Exit codes represent CLI app execution status.
60+
61+
- 0: command executed successfully (tracker failures can still be present in JSON results)
62+
- 1: generic application/runtime failure
63+
- 2: invalid tracker checker configuration/input
64+
65+
Important:
66+
67+
- Tracker endpoint failures do not map to non-zero process exit codes.
68+
- Tracker endpoint failures are part of result JSON payloads.
69+
70+
## Distinguishing App Errors vs Tracker Failures
71+
72+
- App errors:
73+
- invalid CLI/config input
74+
- internal command failures
75+
- serialization/runtime failures
76+
- reported via stderr error JSON and non-zero exit code
77+
- Tracker failures:
78+
- timeout
79+
- connection refused
80+
- non-success status from tracker endpoint
81+
- reported inside stdout result JSON, exit code remains 0
82+
83+
## Stability and Migration
84+
85+
- New features and subcommands must comply with this contract.
86+
- Legacy behavior is migrated progressively.
87+
- Contract changes should remain backward compatible; if a breaking change is required,
88+
introduce a schema version and migration note.
89+
90+
## Auditability Requirements
91+
92+
This contract is intended to be auditable.
93+
94+
- Prefer explicit structured payloads over ad-hoc text messages.
95+
- Keep field names stable once published.
96+
- If any required field changes, bump a schema version and document migration steps.
97+
98+
Recommended metadata fields for auditable outputs:
99+
100+
- `schema_version`
101+
- `command`
102+
- `timestamp`
103+
- `run_id`
104+
105+
These fields can be added progressively as commands are migrated.
106+
107+
## Verification Strategy
108+
109+
### Current repository phase
110+
111+
- Contract conformance is validated by documentation reviews and issue-level acceptance criteria.
112+
- New feature specs should include explicit checks for:
113+
- stdout/stderr channel behavior
114+
- JSON envelope conformance
115+
- exit-code semantics
116+
117+
### Post-extraction phase (target)
118+
119+
When `console/tracker-client` is extracted to its own repository, add dedicated E2E conformance
120+
tests for this contract.
121+
122+
Recommended E2E coverage:
123+
124+
- golden stdout/stderr fixtures for representative command runs
125+
- exit-code assertions (`0`, `1`, `2`)
126+
- NDJSON per-line validation for monitor probe events
127+
- JSON schema validation for final summaries and error envelopes
128+
129+
Until extraction, this remains a planned verification step.
130+
131+
## Examples
132+
133+
### Example 1: Successful run with tracker failures
134+
135+
```text
136+
stdout:
137+
{"udp_trackers":[{"url":"udp://127.0.0.1:6969","status":{"code":"timeout","message":"announce timeout"}}]}
138+
139+
stderr:
140+
{"event":"probe","url":"udp://127.0.0.1:6969","result":"timeout","elapsed_ms":10000}
141+
142+
exit code: 0
143+
```
144+
145+
### Example 2: Invalid configuration
146+
147+
```text
148+
stdout:
149+
150+
stderr:
151+
{"error":{"kind":"invalid_configuration","source":"TORRUST_CHECKER_CONFIG","message":"JSON parse error: trailing comma at line 7 column 5"}}
152+
153+
exit code: 2
154+
```
155+
156+
### Example 3: Generic application failure
157+
158+
```text
159+
stdout:
160+
161+
stderr:
162+
{"error":{"kind":"runtime_failure","source":"runtime","message":"failed to initialize async runtime"}}
163+
164+
exit code: 1
165+
```

0 commit comments

Comments
 (0)