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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
semantic-links:
skill-links:
- create-adr
related-artifacts:
- docs/issues/open/1669-overhaul-packages/EPIC.md
- docs/issues/open/1669-overhaul-packages/DECISIONS.md
- docs/issues/open/1835-1669-14-decouple-http-protocol-from-tracker-primitives.md
- docs/adrs/index.md
- packages/primitives/src/number_of_bytes.rs
- packages/http-protocol/src/v1/requests/announce.rs
- packages/udp-protocol/src/common.rs
---

# Keep Protocol And Domain Types Decoupled

## Description

Several value types currently exist in more than one package with similar field
shapes. A representative example is `NumberOfBytes`, which appears in:

- `packages/primitives/src/number_of_bytes.rs` (domain-level meaning)
- `packages/http-protocol/src/v1/requests/announce.rs` (HTTP protocol DTO)
- `packages/udp-protocol/src/common.rs` (UDP protocol wire type)

At first glance this can look like accidental duplication that should be
deduplicated into one shared type. However, these types live at different
architectural boundaries and have different reasons to change.

The decision needed here is whether to enforce a single shared type across
layers/protocols, or to keep layer-local/protocol-local types and map at
boundaries.

## Agreement

Keep protocol and domain types decoupled, even when they share similar shape.

This means:

- Domain types remain domain-owned in `packages/primitives`.
- Protocol crates (`http-protocol`, `udp-protocol`) keep protocol-local types.
- Adapters perform explicit mapping at boundaries.

This is an application of single-responsibility design: each layer has one
primary reason to change.

- Domain types change when tracker domain/business policy changes.
- HTTP protocol types change when HTTP/BEP behavior or encoding constraints
change.
- UDP protocol types change when UDP/BEP behavior or wire representation
changes.

As a consequence, a UDP wire-format change should not force broad domain
refactors, and a domain policy change should not force protocol crates to adopt
domain-centric shape.

### Alternatives Considered

**Single shared type for all layers/protocols** (for example one global
`NumberOfBytes` used by domain + HTTP + UDP).

Rejected because:

1. It couples protocol evolution to domain internals and vice versa.
2. It increases blast radius for protocol-specific changes.
3. It weakens boundary ownership and pushes cross-layer assumptions into shared
packages.

### Consequences

#### Positive

- Clear boundaries and ownership per layer.
- Lower coupling between protocol evolution and tracker-domain evolution.
- Easier extraction/publication of protocol crates as independently evolving
packages.

#### Negative

- Some mapping code is required at adapter boundaries.
- Similar-looking structs may appear duplicated and require explicit
documentation to avoid accidental re-coupling.

## Date

2026-05-27

## References

- EPIC: [docs/issues/open/1669-overhaul-packages/EPIC.md](../issues/open/1669-overhaul-packages/EPIC.md)
- Subissue SI-14: [docs/issues/open/1835-1669-14-decouple-http-protocol-from-tracker-primitives.md](../issues/open/1835-1669-14-decouple-http-protocol-from-tracker-primitives.md)
- GitHub issue #1835: <https://github.com/torrust/torrust-tracker/issues/1835>
2 changes: 2 additions & 0 deletions docs/adrs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ semantic-links:
related-artifacts:
- docs/index.md
- docs/adrs/README.md
- docs/adrs/20260527175600_keep_protocol_and_domain_types_decoupled.md
---

# ADR Index
Expand All @@ -16,6 +17,7 @@ semantic-links:
| [20260429000000](20260429000000_keep_database_as_aggregate_supertrait.md) | 2026-04-29 | Keep `Database` as an aggregate supertrait | Split the 18-method monolithic `Database` trait into four narrow context traits (`SchemaMigrator`, `TorrentMetricsStore`, `WhitelistStore`, `AuthKeyStore`) while keeping `Database` as an empty aggregate supertrait with a blanket impl. |
| [20260512102000](20260512102000_define_tracker_client_peer_id_convention.md) | 2026-05-12 | Define tracker-client peer ID convention | Adopt `-RC3000-` Azureus-style defaults for tracker-client, use a once-per-process randomized production suffix, and keep deterministic `RC` test fixtures without cross-package constant coupling. |
| [20260519000000](20260519000000_define_global_cli_output_contract.md) | 2026-05-19 | Define the global CLI output contract | All first-party binaries use JSON on stdout (result data) and stderr (NDJSON diagnostics/progress). No plain text. TTY refusal for stdout-result-data commands. Exit codes 0/1/2. Prescriptive; migration is progressive. |
| [20260527175600](20260527175600_keep_protocol_and_domain_types_decoupled.md) | 2026-05-27 | Keep protocol and domain types decoupled | Keep protocol-local and domain-local value types (for example `NumberOfBytes`) and map at boundaries so HTTP/UDP wire evolution does not force domain-wide refactors and domain changes do not force protocol redesign. |

## ADR Lifecycle

Expand Down
17 changes: 11 additions & 6 deletions docs/issues/open/1669-overhaul-packages/EPIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ priority: p1
github-issue: 1669
spec-path: docs/issues/open/1669-overhaul-packages/EPIC.md
epic-owner: josecelano
last-updated-utc: 2026-05-27 00:00
last-updated-utc: 2026-05-27 18:00
semantic-links:
skill-links:
- create-issue
related-artifacts:
- docs/packages.md
- docs/issues/open/1669-overhaul-packages/
- docs/issues/open/1835-1669-14-decouple-http-protocol-from-tracker-primitives.md
- docs/adrs/20260527175600_keep_protocol_and_domain_types_decoupled.md
- docs/adrs/index.md
- AGENTS.md
---

Expand Down Expand Up @@ -239,8 +242,8 @@ The following crates remain in `torrust/torrust-tracker` for now:
- `torrust-tracker-core`

Rationale: current dependencies indicate unresolved layering/coupling. In particular,
`torrust-tracker-http-tracker-protocol` currently depends on
`torrust-tracker-primitives`. The move can be
`torrust-tracker-http-tracker-protocol` no longer depends on
`torrust-tracker-primitives` (completed in SI-14, #1835). The move can be
revisited after these dependencies are clarified and reduced.

> **Naming policy**: prefix reflects ownership and release identity, not estimated
Expand Down Expand Up @@ -351,7 +354,6 @@ This section lists direct crate dependencies that have a `torrust*` prefix.
- `torrust-bencode`
- `torrust-clock`
- `torrust-located-error`
- `torrust-tracker-primitives`
- `torrust-tracker-udp-tracker-core`
- `torrust-clock`
- `torrust-metrics`
Expand Down Expand Up @@ -534,7 +536,7 @@ Status: TODO unless noted.
#### 3. Numbered Subissues (GitHub Issues Open)

- [x] [#1834](https://github.com/torrust/torrust-tracker/issues/1834) SI-13: Decouple `http-protocol` from `udp-protocol` _(Rule M; remove cross-protocol dependency edge)_
- [ ] [#1835](https://github.com/torrust/torrust-tracker/issues/1835) SI-14: Decouple `http-protocol` from `torrust-tracker-primitives` _(Rule M; remove protocol -> domain coupling as step 2)_
- [x] [#1835](https://github.com/torrust/torrust-tracker/issues/1835) SI-14: Decouple `http-protocol` from `torrust-tracker-primitives` _(Rule M; remove protocol -> domain coupling as step 2)_

#### 4. Draft Specs (No Subissue Number, No GitHub Issue)

Expand Down Expand Up @@ -571,7 +573,10 @@ Details:
| Rename-to-desired-state | [#1829](https://github.com/torrust/torrust-tracker/issues/1829) — Rename crates and folder names to match desired `torrust-tracker` workspace state | [docs/issues/closed/1829-1669-11-rename-crates-and-folders-to-match-desired-tracker-workspace.md](../../closed/1829-1669-11-rename-crates-and-folders-to-match-desired-tracker-workspace.md) | DONE | SI-11 complete; spec archived to `docs/issues/closed/` after issue closure |
| HTTP protocol decoupling | [#1830](https://github.com/torrust/torrust-tracker/issues/1830) — Decouple `http-protocol` from `tracker-core` | [docs/issues/closed/1830-1669-12-decouple-http-protocol-from-tracker-core.md](../../closed/1830-1669-12-decouple-http-protocol-from-tracker-core.md) | DONE | SI-12 complete; removed `http-protocol -> tracker-core` edge and moved mapping to higher layer |
| HTTP/UDP decoupling | [#1834](https://github.com/torrust/torrust-tracker/issues/1834) — Decouple `http-protocol` from `udp-protocol` | [docs/issues/open/1834-1669-13-decouple-http-protocol-from-udp-protocol.md](../../open/1834-1669-13-decouple-http-protocol-from-udp-protocol.md) | DONE | SI-13 complete; removed `http-protocol -> udp-protocol` edge |
| HTTP/primitives decoupling | [#1835](https://github.com/torrust/torrust-tracker/issues/1835) — Decouple `http-protocol` from `torrust-tracker-primitives` | [docs/issues/open/1835-1669-14-decouple-http-protocol-from-tracker-primitives.md](../../open/1835-1669-14-decouple-http-protocol-from-tracker-primitives.md) | TODO | SI-14. Rule M; execute after SI-13; remove protocol -> domain coupling in step 2 |
| HTTP/primitives decoupling | [#1835](https://github.com/torrust/torrust-tracker/issues/1835) — Decouple `http-protocol` from `torrust-tracker-primitives` | [docs/issues/open/1835-1669-14-decouple-http-protocol-from-tracker-primitives.md](../../open/1835-1669-14-decouple-http-protocol-from-tracker-primitives.md) | DONE | SI-14 complete; protocol-owned DTOs introduced and boundary mapping moved to core/server layers |

Proposal note:
After SI-14, there is a proposal to evaluate a dedicated repository for protocol crates so protocol packages can evolve with BEP/spec changes while tracker app packages evolve with domain/product changes. This is proposal-only for now (not committed scope) and is tracked in [#1835](https://github.com/torrust/torrust-tracker/issues/1835) and [docs/issues/open/1835-1669-14-decouple-http-protocol-from-tracker-primitives.md](../../open/1835-1669-14-decouple-http-protocol-from-tracker-primitives.md).

### Draft issues

Expand Down
Loading
Loading