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
4 changes: 2 additions & 2 deletions python/src/rowing_data/validation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Conformance checks for a RowingSession (Draft v0.1, core fields).

Hard errors are type-limit violations and an unknown RecordingStrategy value.
Typical-range and timing consistency checks are warnings only (§8).
Typical-range and timing consistency checks are warnings only (§7).
"""

from __future__ import annotations
Expand All @@ -12,7 +12,7 @@
from .fields import field_by_id, field_by_name
from .model import NATIVE_RECORD_ATTRS, RECORD_DEVELOPER_ATTRS, Record, RowingSession

# Informative typical ranges from spec §8.1 — not encoding limits.
# Informative typical ranges from spec §7.1 — not encoding limits.
_TYPICAL = {
"average_drive_force_n": (0.0, 2000.0),
"peak_drive_force_n": (0.0, 2000.0),
Expand Down
23 changes: 6 additions & 17 deletions spec/FIT_STANDARD.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,9 +408,9 @@ Curve data MUST be encoded as **UINT16** arrays (developer fields with array siz

Data that does not fit the FIT file MAY be shipped in a companion `.json` file. This standard does not define its contents or structure; that is up to the producer. The companion file is optional: a FIT file MUST be complete and conforming without it, and consumers MAY ignore it.

## 8. Data Quality and Validation
## 7. Data Quality and Validation

### 8.1 Value Ranges
### 7.1 Value Ranges

Producers MUST NOT exceed FIT type limits (encoded value × scale must fit the base type). Producers SHOULD NOT clamp valid measurements to “typical” ranges.

Expand All @@ -423,36 +423,25 @@ Producers MUST NOT exceed FIT type limits (encoded value × scale must fit the b

Consumers MAY warn on values outside typical ranges but MUST accept physically valid data within type limits.

### 8.2 Missing Data
### 7.2 Missing Data

- Missing or unavailable fields SHOULD be omitted from the file
- Producers MUST NOT emit fields with placeholder values (e.g., -1, 999) without documentation
- Zero values SHOULD indicate actual measurements of zero (not missing data)

### 8.3 Consistency
### 7.3 Consistency

While strict validation is not enforced, producers SHOULD maintain internal consistency:

- Drive + recovery time ≈ stroke period (60 / cadence)
- In-stroke axis metadata consistent with stroke scalars
- Summary oarlock fields = average of per-side fields (when both present)

## 9. Field Registry

### 9.1 Reserved ID Ranges
## 8. Field Registry

A developer field number is a single byte (`field_definition_number`, UINT8), and 255 is the FIT invalid value for that type. Field IDs therefore range from 0 to 254. This is a hard limit of the FIT format, not an allocation choice of this standard.

| Range | Purpose | Status |
|-------|---------|--------|
| 0-19 | Core rowing metrics | Assigned |
| 20-59 | Reserved for future curve data | Available |
| 60 | HandleForceCurve | Assigned |
| 61-89 | Reserved for future curve data | Available |
| 90-92 | In-stroke axis metadata | Assigned |
| 93-199 | Extended standard fields | SlipThreshold (94), WashThreshold (95) and StrokeState (96) assigned; remainder available |
| 200-211 | Dual oarlock per-side | Assigned |
| 212-254 | Reserved for future extensions | Available |
Which IDs are assigned, reserved or available is listed in the [field ID registry](../registry/field-ids.md). It is the single list of allocations; no ID is used before it is recorded there.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

These two registries were drifting, making it hard to maintain


## Appendix A: Terminology

Expand Down
Loading