Skip to content

Show how a config's values compare to the compiled defaults - #38

Merged
andyyhope merged 2 commits into
mainfrom
feature/default-diff
Aug 25, 2026
Merged

Show how a config's values compare to the compiled defaults#38
andyyhope merged 2 commits into
mainfrom
feature/default-diff

Conversation

@andyyhope

Copy link
Copy Markdown
Owner

Alongside coverage, the mapping audit now diffs every value a config supplies against
the flag's compiled default — so a large file tells you what it actually does, not
just that it parses.

let audit = try FlagMappingAudit(AppFlags.self, applying: json)
print(audit.defaultsDescription)
// Default vs config:
//   changes (2):
//     • new-onboarding: false → true
//     • tier: "free" → "pro"
//   restated (2) — same as the default, could be omitted:
//     • markets
//     • page-size
  • changesDefault — the values this config actually changes.
  • matchesDefault — the values it restates identically to the compiled default, and
    could drop from a bloated file.
  • defaults — the full per-flag comparison (FlagDefaultComparison), for asserting on
    a specific flag.

Informational only

Whether a value matches its default or differs from it, isComplete is untouched.
Restating a default is not a coverage failure, and neither is changing one — it is a
diff, for you to read and assert on as you like. Independent of absent: a flag the
config never supplies has no incoming value and does not appear in the diff.

Reuses the mapped values

It compares the boxes a real apply would store, not the raw JSON, so a whole number
sent for a Double flag matches a Double default — JSON's single number type does
not create a false change. A record list restated exactly matches its default, and
config field order does not matter, since both canonicalise to sorted-key JSON. Both
are pinned by tests — the record path is where a false change was most likely.

Verified

752 tests on a clean build. DocC clean with --warnings-as-errors, both example apps
and the iOS package scheme build. Additive only — no breaking changes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NnwCqKNm8rZ63Au6bpYdaD

andyyhope and others added 2 commits August 25, 2026 15:07
Alongside coverage, the mapping audit now diffs every value a config supplies
against the flag's compiled default: `changesDefault` is what the config actually
changes, `matchesDefault` is what it merely restates and could drop, and `defaults`
carries the full per-flag comparison.

    Default vs config:
      changes (2):
        • new-onboarding: false → true
        • tier: "free" → "pro"
      restated (2) — same as the default, could be omitted:
        • markets
        • page-size

Purely informational — restating a default, or changing it, is not a coverage
problem, so isComplete is untouched. It reuses the same mapped boxes a real apply
would store, so a whole number sent for a Double flag matches a Double default
rather than reading as a change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NnwCqKNm8rZ63Au6bpYdaD
The highest-risk path for a false "change": a record list restated by the config
must compare equal to its compiled default, and config field order must not matter.
Both canonicalise to sorted-key JSON, so both hold — locked in.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NnwCqKNm8rZ63Au6bpYdaD
@andyyhope
andyyhope merged commit 06978dd into main Aug 25, 2026
6 checks passed
@andyyhope
andyyhope deleted the feature/default-diff branch August 25, 2026 05:13
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