chore(statistics): review follow-up cleanups #169
No reviewers
Labels
No labels
blocked
bug
enhancement
high-priority
low-priority
needs-info
needs-triage
ready-for-agent
ready-for-human
referenced
research
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gabogg/hikcentral!169
Loading…
Reference in a new issue
No description provided.
Delete branch "chore/statistics-review-followups"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Complete the scoped P3 follow-ups from #142 and #143. Rename the calibration-log test helper, type the cycle-verdict test helper's granularity, default the four
PeriodQualitytier counters to zero, and enforce the existing SQL verdict-priority contract in code. The PR plan maps every issue item to a change or a verified accepted no-op.Architectural impact
Production changes are zero defaults for the four
PeriodQualitytier counters inapp/schemas/statistics.pyand the cycle-verdict priority contract enforcement inapp/db/occupancy_repository.py:96-112, where_CYCLE_VERDICT_PRIORITIESgenerates both_CYCLE_VERDICT_TYPES_SQLand_CYCLE_VERDICT_PRIORITY_SQL. Existing API fields and runtime cycle-verdict ordering remain intact.DayQualityStatestays in its single service owner, and no shared test fixture or new audit type is introduced.Verification / test evidence
python3 scripts/check_docs.py: 39 Markdown files and 80 HTTP operations checked..venv/bin/ruff check .: passed..venv/bin/ruff format --check .: passed (150 files).pytest -q: 521 passed.Checklist
docs/audit/statistics-review-followups-pr-plan.md.c3a06b9.3a728b7.2744522.Closes #142
Closes #143
Review protocol
This PR addresses follow-up issues, so the repository's three-pass review path applies. First pass: address every P1/P2/P3 finding. Second pass: address every P1/P2/P3 finding and request a third pass. Third pass: address P1/P2 findings and file linked follow-up issues for deferred P3 findings before merge.
WIP: chore(statistics): review follow-up cleanupsto chore(statistics): review follow-up cleanupsCode review, pass 1 (
origin/master...14f0324, spec #142, #143)Result: no P1s or P2s, and 10 P3s. The spec is met. This PR addresses follow-up issues, so it takes the three-pass path: every finding on passes 1 and 2 gets fixed.
Verification:
tests/test_cycle_verdict.py,test_statistics_baselines.pyandtest_statistics_marker_inputs.py: 33 passed.PeriodQuality/SelectablePeriodconstructor and every frontend reader of the tier counters was grepped.Standards
The code has no documented-standard violations. SQL stays in the repository, types are annotated, and the tests use a real sqlite DB with an ASGI client.
The zero defaults don't hide missing data today.
analytics_service.py:840, passes all four counters.SelectablePeriod(:881) spreadsquality.model_dump().P3
app/schemas/statistics.py:38-41).missing_days/unreliable_days = 0reads as "clean", so a future constructor that omits them silently shows a fully trusted period. The fields also become optional in OpenAPI.tests/test_cycle_verdict.py:~292-355).test_period_quality_tier_counters_serialized_in_api_responsesnever reaches the defaults: the service computes real zeros. It is a key-set contract test.TIER_COUNTERS/QUALITY_KEYSconstant.occupancy_repository.py:95-100). The new comment documents the priority contract instead of enforcing it. A type→priority dict generating both_CYCLE_VERDICT_TYPES_SQLand the CASE would make it impossible to forget one. The comment is acceptable as the minimal #142 fix.tests/test_cycle_verdict.py:~271).today = yesterday()should beday.docs/audit/statistics-review-followups-pr-plan.mdis not linked fromdocs/README.md(55-58).rtk ruff check ." line and the Python 3.14 teardown note. These belong in the PR body, if anywhere. Also confirm the "maintainer triage decision" wording against #143.Spec
Checklist:
add_verdict→seed_calibration_logrename (no leftovers),Granularitytyping, and the SQL priority contract comment;DayQualityState(no second consumer);P3
str.tests/test_statistics_marker_inputs.py:76period_quality(granularity: str, ...). #143.3 asks for "typed Granularity literals", and triage made only the extraction conditional.plan:30). It saysuvx ruff check ., while the PR says.venv/bin/ruff check ..Scope creep: none in the code. The new API-response test is justified by triage's "verifying existing response… behavior".
Summary
str.🤖 Generated with Claude Code
Pass 1 fixes (
3a728b7)All 10 findings from review pass 1 have been addressed in
3a728b7:Standards
app/schemas/statistics.py): Added an explicit comment onPeriodQualitystating that producers (analytics_service) must always populate all tier counters explicitly rather than relying on defaults to assume clean data.tests/test_cycle_verdict.py): Renamed test totest_period_quality_tier_counter_keys_serialized_in_api_responsesand documented it as a key-set contract test for period endpoints.tests/test_cycle_verdict.py): Defined reusableTIER_COUNTERS,QUALITY_KEYS, andSELECTABLE_PERIOD_KEYSconstants, replacing duplicated 5-line counter assertions and repeated 16-key lists.app/db/occupancy_repository.py): Created_CYCLE_VERDICT_PRIORITIES: dict[str, int]mapping eligible verdict types to priority ranks, generating both_CYCLE_VERDICT_TYPES_SQLand_CYCLE_VERDICT_PRIORITY_SQLfrom the dictionary.tests/test_cycle_verdict.py): Renamedtoday = yesterday()today = yesterday().docs/README.md: Added[Statistics review follow-ups plan](audit/statistics-review-followups-pr-plan.md)under Audit snapshots indocs/README.md.docs/audit/statistics-review-followups-pr-plan.md, and aligned maintainer triage wording with #143.Spec
str(tests/test_statistics_marker_inputs.py): ImportedGranularityand typedgranularity: Granularityinperiod_quality(granularity: Granularity, start: date)..venv/bin/ruff check .to match the PR description.docs/audit/statistics-review-followups-pr-plan.md.Ready for review pass 2.
Code review, pass 2 (
origin/master...3a728b7, spec #142, #143)Result: no P1s, no P2s and 5 P3s. The plan-doc finding appears on both axes; the Standards and Spec copies are one issue. This PR addresses follow-up issues, so it takes the three-pass path: fix every P3 below, push, and request a third pass.
Verification:
check_docs.py: 0 errors.tests/test_cycle_verdict.py,test_statistics_marker_inputs.pyandtest_statistics_baselines.py: 33 passed.INset (order only differs), and the same CASE ranking (RETROACTIVE_GUARD_AUDIT = 1, everything else 0). Onlyoccupancy_repository.py:1703,1706uses it.Standards
Pass-1 fixes: all 7 are fixed, with no regressions.
TIER_COUNTERS/QUALITY_KEYS/SELECTABLE_PERIOD_KEYSconstants replace the repeated assertions._CYCLE_VERDICT_PRIORITIESnow generates both SQL fragments.todayis nowday.P3
docs/audit/statistics-review-followups-pr-plan.md:22, plus line 7 in Scope). It says "Documented the cycle-verdict priority contract…", but fix 4 replaced that comment with_CYCLE_VERDICT_PRIORITIES, which generates both fragments. Say the contract is enforced by the dict.occupancy_repository.py:104vs:109). TheINlist quotes withrepr(k), the CASE withf"'{k}'". For a key containing',reprswitches to double quotes, which SQLite reads as an identifier. Usef"'{k}'"in both.tests/test_cycle_verdict.py:249).TIER_COUNTERS = {"closed_days": 0, …}is a dict of expected zeros, not a list of counters.closed_days, which isn't one of the tiers the schema comment names.ZERO_DAY_COUNTERS.Spec
Pass-1 fix claims (c3400): all true.
Granularity(test_statistics_marker_inputs.py:76)..venv/bin/ruff check ..#142 / #143 checklist:
P3
occupancy_repository.py:96-112.c3a06b9, not3a728b7.Summary
🤖 Generated with Claude Code
Pass 2 fixes (
2744522)All 5 P3 findings from review pass 2 have been addressed in
2744522:Standards
docs/audit/statistics-review-followups-pr-plan.md): Updated Scope line 7 and resolution checklist item 3 to state that the priority contract is enforced by_CYCLE_VERDICT_PRIORITIESgenerating both SQL fragments, replacing comment-only wording.app/db/occupancy_repository.py): Formatted_CYCLE_VERDICT_TYPES_SQLusingf"'{k}'", unifying single-quote formatting across both_CYCLE_VERDICT_TYPES_SQLand_CYCLE_VERDICT_PRIORITY_SQL.tests/test_cycle_verdict.py): RenamedTIER_COUNTERStoZERO_DAY_COUNTERSacross definition and all assertion sites, clarifying that it represents expected zero counts (includingclosed_days).Spec
tea pr edit 169to:occupancy_repository.py:96-112in architectural impact.3a728b7) and pass 2 (2744522) fix commits in the checklist.Ready for review pass 3.
Code review, pass 3 (
origin/master...2744522, spec #142, #143)Result: no P1s, no P2s and no P3s. This is the third pass of a follow-up PR, with nothing to fix and nothing to defer, so it merges.
Verification:
check_docs.py: 39 Markdown files and 80 HTTP operations checked, 0 errors.tests/test_cycle_verdict.py,test_statistics_marker_inputs.pyandtest_statistics_baselines.py: 33 passed.test_cycle_verdict,test_calibration_*,test_occupancy*,test_statistics_*,test_trust_dataset_parity): 152 passed.IN ('RETROACTIVE_GUARD_AUDIT', 'AUTOMATIC_NOCTURNAL'): the same set, with only the order changed;Standards
Pass-2 fixes: all three are fixed.
_CYCLE_VERDICT_PRIORITIESgenerates both fragments.f"'{k}'".TIER_COUNTERSis renamedZERO_DAY_COUNTERS, with no references left to the old name.There are no documented-standard violations, no new smells and no bugs.
Informational, not a finding: the generated CASE has a
WHEN 'AUTOMATIC_NOCTURNAL' THEN 0branch that repeats itsELSE 0. It's harmless, and it comes from generating both fragments from one map. No follow-up.Spec
Fix claims (c3519): all true.
c3a06b9,3a728b7and2744522, and gives the current 39 / 80 docs-check count.#142 / #143:
Closes #142, #143is accurate. No scope creep.Summary
Ready to merge.
🤖 Generated with Claude Code