Repository navigation
drift/01: the twin-parity ledger lint - #23
Merged
Merged
Conversation
Tools/parity_ledger.py, stdlib-only, in the doc_comment_lint idiom (local command, baseline file, exit 0/1). Five machine-checked rules over the mirrored Swift/Kotlin trees: declared twin references must resolve on the other side (scanned repo-wide, including app targets); a declaration with test callsites but no production callsite is an error; camelCase<->SNAKE_CASE constant pairs must agree value-for-value (full constant-expression evaluation — 48 * 3_600 is compared as 172800, not 48; unparseable initializers surface as findings, never silently skipped); duplicate/callsite counters ratchet against the baseline; one-sided files, functions, computed properties and constants need a twin-map entry. Inventory spans the five mirrored package pairs (StrandAnalytics, StrandImport, WhoopStore, WhoopProtocol, OuraProtocol <-> analytics, ingest, data, protocol, oura); deliberate exclusions are recorded in the map's scope block. Kotlin parsing handles extension receivers with generics, trailing commas, and getter properties; ambiguous constant names are disambiguated via mapped owners or reported, never dropped. Baseline identities are line-shift-stable but value-fingerprinted: a known constant drift that drifts AGAIN counts as a new finding. The checked-in twin map is bootstrapped from the declared twin annotations in the tree (357 references, 340 resolving); same-name matches are recorded as suggestions only. The 263-finding baseline captures today's debt, including the sdnnIndex dead twin reference, the test-only hardened resting-HR path on both platforms (#10), 4 duplicate Android-UI Pearson implementations, 12 dayString implementations — and two previously unknown constant drifts (SleepStagerV2 padLo/padHi: Swift 330/390 vs Kotlin 360/420). Current tree: exit 0 against the baseline in ~14 s, byte-identical across runs; 24 unittest probes cover every rule plus baseline semantics (known finding suppressed, new finding red, disappeared finding tolerated, counter regression red, value change red). Part of the drift-control plan in #17 (step 1). Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Path filters cover the ledger's own files AND every scanned source tree, so a PR touching only Swift/Kotlin twin sources runs the ledger. Discovery-based unittest run picks up new test files without editing the workflow. Co-Authored-By: Codex <noreply@openai.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
9 of 10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Plan step 1 of #17: the twin-parity ledger — a stdlib-Python lint in the
doc_comment_lint.pyidiom (local command first, baseline file, exit 0/1, CI as fork convenience) that puts a machine behind the parity disciplinedocs/CROSS_PLATFORM.mdpromises.Five machine-checked rules
//-comment annotations included). Catches thesdnnIndexclass on introduction day.48 * 3_600compares as172800, not48; unparseable initializers surface as findings, never silently skipped.Inventory spans the five mirrored package pairs (StrandAnalytics, StrandImport, WhoopStore, WhoopProtocol, OuraProtocol ↔ analytics, ingest, data, protocol, oura); deliberate exclusions live in the map's scope block. Kotlin parsing handles extension receivers with generics, trailing commas, and getter properties. Baseline identities survive line shifts but are value-fingerprinted — a known constant drift that drifts again is a new finding.
What it already found
Beyond mechanizing the known items: two previously unreported constant drifts —
SleepStagerV2padLo/padHiare 330/390 in Swift vs 360/420 in Kotlin (evidence for the fund table in #17; fix PR to follow separately).Verification
doc_comment_lint.pyuntouched and green.Review
Two independent Codex reviews: the first (verdict red) found real parser and enforcement gaps — CI path filters missing the scanned sources, inventory scope excluding WhoopProtocol, first-literal-only constant parsing, trailing-comma arity, extension receivers, computed properties, name-only callsite counting, comment-form dead-twin scanning, baseline identity without value fingerprint, missing baseline-semantics tests. All eleven were fixed; the focused re-review of those fixes returned green with zero findings.
Part of the drift-control plan in #17.
🤖 Generated with Claude Code