Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions console/tracker-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@

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

> **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.
> **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.

There are currently three console clients available:

- UDP Client
- HTTP Client
- Tracker Checker

## Documentation

- [Tracker CLI I/O Contract](docs/contracts/tracker-cli-io-contract.md)
- [Tracker Client ADRs](docs/adrs/README.md)

> **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).

## UDP Client
Expand Down Expand Up @@ -186,7 +191,7 @@ This program is free software: you can redistribute it and/or modify it under th

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.

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/>.
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/>.

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# ADR 20260512080000: Define Tracker CLI I/O Contract and Error Handling

- Status: Accepted
- Date: 2026-05-12
- Scope: console/tracker-client

## Context

The tracker client is a growing CLI surface with multiple commands (UDP client, HTTP client,
tracker checker, and monitor features under active development). The project intends to extract
this application into an independent repository.

Without an explicit contract, command outputs and error behavior can diverge, breaking user
automation and increasing maintenance cost.

At the same time, existing commands may not yet fully match the desired target behavior, so the
team needs a migration policy, not a flag day rewrite.

## Decision

Define a global Tracker CLI I/O contract for console/tracker-client.

### 1. Default output format

- JSON is the default output format.

### 2. Output channels

- stdout: normal command results and machine-consumable output.
- stderr: progress reporting, diagnostics, warnings, and error output.

For monitor-style streaming behavior:

- Progress/probe events may be emitted as one JSON object per line (NDJSON style).
- If emitted as progress, they go to stderr.
- Final command result summary goes to stdout as JSON.

### 3. Exit-code semantics

Exit codes represent tracker client app execution state, not tracker endpoint health status.

- 0: command executed successfully, even if one or more trackers reported failures/timeouts.
- 1: generic application/runtime failure (unexpected internal error).
- 2: invalid tracker checker configuration/input errors.

Tracker-specific failures (for example announce timeout, scrape timeout, non-200 HTTP from a
tracker) are represented in JSON result payloads, not in non-zero exit codes.

### 4. Progressive migration policy

- New features and new subcommands must follow this contract.
- Existing features that do not yet comply will be migrated progressively when touched by new
feature work or dedicated refactors.
- No immediate broad rewrite is required.

### 5. Scope location

This policy is intentionally documented under console/tracker-client docs because the tracker
client is expected to be extracted into its own repository.

### 6. Auditability and testing strategy

- Contracts should be auditable through stable structured payloads and explicit field definitions.
- During the monorepo phase, conformance is enforced through issue specs and acceptance criteria.
- After tracker-client extraction to its own repository, add dedicated E2E contract tests for
stdout/stderr behavior, exit codes, NDJSON events, and JSON schema conformance.

## Consequences

### Positive

- Predictable behavior for shell pipelines and automation.
- Clear separation between app-level failure and tracker-level status.
- Lower migration risk through incremental adoption.
- Documentation remains aligned with future repository extraction boundaries.
- Auditable CLI behavior suitable for compliance and regression verification.

### Negative

- Transitional inconsistency until all legacy paths are migrated.
- Additional implementation and review burden to keep channel/exit behavior consistent.
- Full E2E contract coverage is deferred until extraction, so short-term assurance relies on
spec-driven validation.

## Implementation Notes

- Command specs should reference the tracker client I/O contract document.
- New command acceptance criteria should include channel correctness and exit-code behavior.
- Contract schema updates should be backward compatible or explicitly versioned.

## References

- [Tracker CLI I/O Contract](../contracts/tracker-cli-io-contract.md)
- [console/tracker-client/README.md](../../README.md)
17 changes: 17 additions & 0 deletions console/tracker-client/docs/adrs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Tracker Client ADRs

Architecture Decision Records (ADRs) for the console tracker client live in this folder.

These ADRs are scoped to the tracker client application and are intentionally separated from
repository-level ADRs because the tracker client is expected to be extracted into its own
repository in the future.

## Goals

- Capture durable decisions for tracker client behavior and architecture
- Keep CLI/API contracts explicit and stable for automation users
- Allow progressive migration of existing commands toward the target contract

## Index

See [ADR Index](index.md).
5 changes: 5 additions & 0 deletions console/tracker-client/docs/adrs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# ADR Index

| ADR | Date | Title | Short Description |
| ------------------------------------------------------------------------------------- | ---------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [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. |
165 changes: 165 additions & 0 deletions console/tracker-client/docs/contracts/tracker-cli-io-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Tracker CLI I/O Contract

Status: Active

Scope: console/tracker-client commands, with explicit emphasis on tracker checker behavior.

## Purpose

Define stable rules for:

- output format
- stdout/stderr channel usage
- error payload structure
- process exit codes

This contract is designed for automation-first CLI usage and progressive adoption.

## Core Rules

### JSON-first output

- JSON is the default output format for command results.
- Result payloads on stdout are machine-consumable.

### Channel usage

- stdout:
- final command results
- structured status/results intended for downstream processing
- stderr:
- progress reporting
- diagnostics and warnings
- application error output

### Monitor/progress events

For monitor commands (for example `tracker_checker monitor udp`):

- Per-probe progress is emitted as NDJSON style: one JSON object per line.
- Per-probe progress events go to stderr.
- Final aggregate summary goes to stdout as JSON.
Comment thread
josecelano marked this conversation as resolved.

## Error Payload Schema

Application errors should use this envelope:

```json
{ "error": { "kind": "string", "source": "string", "message": "string" } }
```

Field meaning:

- kind: machine-readable error category (for example `invalid_configuration`)
- source: where the error originated (for example `TORRUST_CHECKER_CONFIG`, `config_path`, `runtime`)
- message: human-readable detail

## Exit Codes

Exit codes represent CLI app execution status.

- 0: command executed successfully (tracker failures can still be present in JSON results)
- 1: generic application/runtime failure
- 2: invalid tracker checker configuration/input

Important:

- Tracker endpoint failures do not map to non-zero process exit codes.
- Tracker endpoint failures are part of result JSON payloads.

## Distinguishing App Errors vs Tracker Failures

- App errors:
- invalid CLI/config input
- internal command failures
- serialization/runtime failures
- reported via stderr error JSON and non-zero exit code
- Tracker failures:
- timeout
- connection refused
- non-success status from tracker endpoint
- reported inside stdout result JSON, exit code remains 0

## Stability and Migration

- New features and subcommands must comply with this contract.
- Legacy behavior is migrated progressively.
- Contract changes should remain backward compatible; if a breaking change is required,
introduce a schema version and migration note.

## Auditability Requirements

This contract is intended to be auditable.

- Prefer explicit structured payloads over ad-hoc text messages.
- Keep field names stable once published.
- If any required field changes, bump a schema version and document migration steps.

Recommended metadata fields for auditable outputs:

- `schema_version`
- `command`
- `timestamp`
- `run_id`

These fields can be added progressively as commands are migrated.

## Verification Strategy

### Current repository phase

- Contract conformance is validated by documentation reviews and issue-level acceptance criteria.
- New feature specs should include explicit checks for:
- stdout/stderr channel behavior
- JSON envelope conformance
- exit-code semantics

### Post-extraction phase (target)

When `console/tracker-client` is extracted to its own repository, add dedicated E2E conformance
tests for this contract.

Recommended E2E coverage:

- golden stdout/stderr fixtures for representative command runs
- exit-code assertions (`0`, `1`, `2`)
- NDJSON per-line validation for monitor probe events
- JSON schema validation for final summaries and error envelopes

Until extraction, this remains a planned verification step.

## Examples

### Example 1: Successful run with tracker failures

```text
stdout:
{"udp_trackers":[{"url":"udp://127.0.0.1:6969","status":{"code":"timeout","message":"announce timeout"}}]}

stderr:
{"event":"probe","url":"udp://127.0.0.1:6969","status":"timeout","elapsed_ms":null}

exit code: 0
```

### Example 2: Invalid configuration

```text
stdout:

stderr:
{"error":{"kind":"invalid_configuration","source":"TORRUST_CHECKER_CONFIG","message":"JSON parse error: trailing comma at line 7 column 5"}}

exit code: 2
```

### Example 3: Generic application failure

```text
stdout:

stderr:
{"error":{"kind":"runtime_failure","source":"runtime","message":"failed to initialize async runtime"}}

exit code: 1
```
Loading