Skip to content

SHA-20: PROFILE scopes CORE/DOMAIN/FULL with gen field catalog - #57

Merged
shaonianche merged 1 commit into
mainfrom
agent/code-expert/9860e48c
Aug 1, 2026
Merged

SHA-20: PROFILE scopes CORE/DOMAIN/FULL with gen field catalog#57
shaonianche merged 1 commit into
mainfrom
agent/code-expert/9860e48c

Conversation

@shaonianche

Copy link
Copy Markdown
Owner

Summary

Implements Multica SHA-20 (Stage 4 H) under architecture decision O1: grow ConformanceLevel.PROFILE beyond the developer-field subset toward data-driven rules from bundled Profile.xlsx 21.205.0, without making FULL the default for strict=True.

What landed

  • ProfileScope: CORE | DOMAIN | FULL
    • CORE (default / DEFAULT_PROFILE_SCOPE): developer-field rules + ambiguous subfield ERROR (unchanged default for DEFAULT_LEVELS / Builder strict=True)
    • DOMAIN (opt-in): CORE + native base-type + closed-enum checks on high-frequency Activity/Workout messages (file_id, session, lap, record, event, device_info, workout, workout_step, activity)
    • FULL (opt-in): same native rules for the entire catalog
  • Gen export fit_tool/profile/field_catalog.py (1 406 fields, 101 closed enum types) via fit_tool/gen/field_catalog.py + gen-profile
  • profile_rule_coverage(scope) publishes message/field/enum coverage % for docs/tests
  • API: validate_fit_file(..., profile_scope=...), FitFile.validate(..., profile_scope=...), package exports
  • README + design-doc §3.1 milestones M1–M5 status; Towncrier news/SHA-20.feature

Coverage (FULL)

Metric Value
Messages 123 / 123 (100%)
Fields 1406 / 1406 (100%)
Closed enum fields 154 / 154 (100%)
DOMAIN field coverage ~31.8% of full catalog

Not in this PR (honest Partial)

  • Units/scale WARNING families
  • Native “required field” matrix beyond existing FILE_TYPE Activity rules
  • Open-list types (manufacturer, bitfields, …) intentionally excluded from closed-enum ERROR

Test plan

  • uv run pytest fit_tool/tests/test_profile_scope.py fit_tool/tests/test_validation.py fit_tool/tests/test_public_api.py
  • uv run pytest (425 passed, 1 skipped)
  • uv run ruff check fit_tool
  • SDK Activity.fit passes ProfileScope.FULL

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 56e4db0f3e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

enum_types: list[EnumTypeSpec] = []
for type_name in sorted(profile.types_by_name.keys()):
type_ = profile.types_by_name[type_name]
if type_.base_type is not BaseType.ENUM:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Exclude ranged enum types from the closed-enum catalog

When FULL scope validates user_profile.activity_class, this condition treats the type as a closed set merely because its base type is ENUM. However, ActivityClass.LEVEL is a 0x7f mask, LEVEL_MAX is 100, and ATHLETE is a combinable 0x80 flag, so valid encoded levels such as 50 or ATHLETE | 50 are absent from PROFILE_ENUM_VALUES; _collect_closed_enum_findings consequently reports them as errors. Exclude ranged/bitfield enum families such as activity_class or represent their masks and ranges explicitly.

Useful? React with 👍 / 👎.

@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.76404% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.72%. Comparing base (4339fd3) to head (c30aa21).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
fit_tool/validation.py 88.63% 5 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #57      +/-   ##
==========================================
- Coverage   92.83%   92.72%   -0.12%     
==========================================
  Files          35       36       +1     
  Lines        2625     2721      +96     
  Branches      437      461      +24     
==========================================
+ Hits         2437     2523      +86     
- Misses        112      117       +5     
- Partials       76       81       +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Rebased onto main after Workout/Course FILE_TYPE. Adds ProfileScope,
gen-exported field catalog, DOMAIN/FULL native checks.

Codex P2: exclude ranged/bitfield enums such as activity_class from
closed-enum validation.

Co-authored-by: multica-agent <github@multica.ai>
@shaonianche
shaonianche force-pushed the agent/code-expert/9860e48c branch from 56e4db0 to c30aa21 Compare August 1, 2026 13:54

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c30aa2176f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# ENUM base types that are ranges / bitfields, not closed value sets.
# Example: activity_class uses LEVEL mask 0x7f and ATHLETE flag 0x80.
_OPEN_OR_RANGED_ENUM_TYPES = frozenset({
'activity_class',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Exclude the manufacturer file-type range from closed enums

The earlier ranged-enum concern has fresh evidence in FileType: the generated profile defines MFG_RANGE_MIN = 247 and MFG_RANGE_MAX = 254, so intermediate manufacturer-defined file types are valid, yet only activity_class is excluded here and the catalog stores just the endpoints. Under DOMAIN/FULL, _collect_closed_enum_findings consequently reports FileIdMessage.type = 250 (and other values from 248 through 253) as outside file; add file to the ranged handling or encode its interval, then regenerate the catalog.

AGENTS.md reference: AGENTS.md:L53-L58

Useful? React with 👍 / 👎.

@shaonianche
shaonianche merged commit 514ae61 into main Aug 1, 2026
7 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant