Skip to content

fix: resolve all 28 findings from the refinement audit - #25

Merged
oldhero5 merged 6 commits into
mainfrom
fix/audit-findings
Jun 28, 2026
Merged

fix: resolve all 28 findings from the refinement audit#25
oldhero5 merged 6 commits into
mainfrom
fix/audit-findings

Conversation

@oldhero5

Copy link
Copy Markdown
Owner

Resolves all 28 adversarially-verified findings from the codebase audit, in six themed,
test-backed commits. +13 tests; full suite green, ruff + gitleaks clean.

Critical / High

  • F1/F4 — ERCOT schedules targeted the wrong operating day. DAM now fetches the NEXT day's
    curve (it clears midday); RT/load capture the CURRENT day intraday. ERCOT_DAILY is keyed by the
    Central operating day (timezone + end_offset=2). Regression test asserts the 14:00 CPT tick
    on day D selects D+1 (DAM) and D (RT/load).
  • F2/F6 — DST data loss. The hour-ending instant was localized, so the November fall-back hour
    collapsed (25h→24h) and drop_duplicates deleted one. Now the interval beginning is localized
    so DSTFlag disambiguates; validated against the real 2025-11-02 payload (100 distinct RT
    intervals preserved). Fall-back + spring-forward regression tests added.
  • F3 (+F9/F12) — unbounded vintage growth. commit_vintage now skips a commit whose payload
    matches the latest vintage (ignoring per-commit as_of/fetched_at), so an unchanged hourly
    re-pull no longer writes a fresh full-history vintage; this also makes the per-symbol commit loop
    idempotent on retry and sharply cuts O(N²) rewrites.
  • F5 — read API auth. Optional X-API-Key gate (ENERGEX_READ_API_KEY) on data endpoints;
    /healthz stays open; an unauthenticated start logs a warning.

Medium

F7 raise on data-without-fields · F8 partition-relative freshness (backfills no longer fail the
gate) · F10/F23/F26 deterministic package-relative .env load via an explicit opt-out · F11
/series row cap (413) · F13 retry only on 5xx/transport (no 4xx auth hammering) · F14 compose
requires MINIO_ROOT_*/ARCTIC_*/NEO4J_AUTH instead of baking weak defaults · F19 microsecond
snapshot names.

Low

F15 keep paging when totalPages absent · F16 coerce bad hourEnding · F17 /curve 404 (not 500)
· F18 hub/LZ allowlist drift warning · F20 per-symbol staleness surfaced in the read-back check ·
F21 drop dead config field · F22 symbology _POWER_PREFIX + malformed-id coverage · F24 relabel
legacy :8000 docs as the S2 read API · F25 follow_redirects=False · F27 opt-in scoped CORS · F28
narrow the gitleaks tests/ allowlist.

Notes

  • F14 follow-up (operational): the running stack still uses its current (weak) MinIO/Neo4j
    creds, now provided via .env. Rotating MINIO_ROOT_*/NEO4J_AUTH to strong values, and the
    ARCTIC_* keys (which the existing MinIO data is locked to), requires a credential rotation +
    data migration — intentionally not done here.

oldhero5 added 6 commits June 28, 2026 13:32
…ransport, guard pagination/fields, no-redirect, drift warning

F2,F6: localize the interval-BEGINNING instant so DSTFlag disambiguates the repeated
fall-back hour (validated on 2025-11-02: 25h day no longer collapses to 24h).
F13: retry predicate skips non-retryable 4xx. F7: raise on data-without-fields.
F15: keep paging when totalPages is absent. F16: coerce bad hourEnding. F25:
follow_redirects=False. F18: warn on hub/LZ settlement-point allowlist drift.
… names

F3: skip a commit whose payload matches the latest committed vintage (ignoring
per-commit as_of/fetched_at provenance), so an unchanged hourly ERCOT re-pull no
longer writes a fresh full-history vintage every run. This also makes the _commit_ercot
per-symbol loop idempotent on retry (F9) and sharply cuts full-history rewrites (F12).
F19: microsecond-resolution snapshot names avoid same-second collisions.
… partition-relative freshness

F1: DAM schedule now fetches the NEXT operating day's curve (it clears midday), not a
2-day-stale settled day. F4: RT/load capture the CURRENT day intraday, not the previous
one. ERCOT_DAILY is now keyed by the Central operating day (timezone + end_offset=2 so
today/tomorrow are valid keys). F8: freshness is validated against the partition end, so
backfilling an old operating day no longer fails the 2-business-day gate.
…ped CORS

F5: optional X-API-Key gate (ENERGEX_READ_API_KEY) on data endpoints; healthz stays open;
unauthenticated start logs a warning. F11: cap an unbounded /series read (413; bounded
start/end reads exempt). F17: /curve returns 404 (not 500) on an unknown commodity. F27:
opt-in origin-scoped CORS (ENERGEX_CORS_ORIGINS).
…gy + staleness coverage

F10/F23/F26: load the repo-root .env from a package-relative path (no CWD/parent search)
gated by an explicit ENERGEX_SKIP_DOTENV opt-out (set by conftest) instead of the
'pytest in sys.modules' heuristic; unifies precedence through os.environ.
F21: remove the unused ercot_subscription_key_secondary field. F22: cover _POWER_PREFIX
mode/library invariant + malformed-id rejection. F20: surface per-symbol staleness in the
read-back check metadata.
…lowlist; drop legacy docs

F14: docker-compose now requires MINIO_ROOT_*/ARCTIC_*/NEO4J_AUTH via ${VAR:?...} instead of
baking world-known defaults (minioadmin / energex-arctic-secret) — a fresh deploy fails loudly
rather than silently using weak creds. F28: drop the blanket tests/.* gitleaks allowlist (it
masked nothing) so a real secret under tests/ is still caught. F24: relabel the removed legacy
:8000 service as the S2 read API and replace the dead ENERGEX_DB_PATH/INGEST_CRON env block with
the read-API config.
@oldhero5
oldhero5 merged commit 1b813a0 into main Jun 28, 2026
9 checks passed
@oldhero5
oldhero5 deleted the fix/audit-findings branch June 28, 2026 18:08
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