Task · CFO-0002

Cloudflare API client: read-only REST + GraphQL with entitlement-aware queries

Description

internal/cfapi. The only package that talks to Cloudflare. See doc-0003 for the live-verified contract and traps.

Acceptance Criteria

Definition of Done

Implementation Plan

Wave 2: use typed retention floors and advance past an explicit disclosed gap.

Implementation Notes

Parked AC3: client fails closed on a notOlderThan retention gap instead of clamping the requested window. This preserves gap visibility but does not satisfy the literal clamp criterion; decide contract wording or implement an explicit partial window with disclosure.

Decision 2026-09-23 (Rob): AC3 reworded. Wave 1 failed closed on a retention gap, which never self-heals: the scheduler never advances, so a window older than notOlderThan (31d on the HTTP and Access Groups datasets, or a misconfigured initial_lookback) stalls that collector permanently. Silent clamping was rejected because it hides loss. Contract: skip forward to the retention floor with explicit gap disclosure. Implemented in wave 2 alongside CFO-0025.

Correction: the reworded retention criterion is AC6 (the old AC3 was removed and the new text appended). Wave 2 prep also found the skip-forward must use a margin past the floor, because the cutoff is computed as time.Now()-notOlderThan when the query runs and so moves forward every tick.

Wave 2 AC6 verified at released source a3fa01b2a16c2f8fd56381848437406f44330774: TestGraphQLNegotiatesAndSplits, TestGraphQLRetentionGapCarriesFloor, TestGraphQLRetentionGapDoesNotQuery, TestRetentionGapSkipsPastMovingFloor and TestRetentionGapUsesLatestReportedFloor passed under just check; just ci passed before release. The explicit cf2otel.window.gap signal is declared in internal/semconv and docs/signals.md. Live firewall probing also found that settings.availableFields can advertise fields the query schema rejects; doc-0003 records that exception.

Final Summary

Wave 2 completed typed retention-gap skip-forward with an explicit gap log and counter, plus entitlement/window splitting. Verified by named tests, just check, just ci and the v0.2.2 release source.

View the source file on GitHub