Description
An unentitled product query for one zone is retried every cycle, and cf2otel only reacts to 429s instead of pacing requests. A per-zone, per-dataset backoff (retry hourly) and a shared token bucket keep a large account within GraphQL limits.
Acceptance Criteria
- #1 A dataset unentitled on a zone is skipped for that zone with a timed retry and reported via the discovery self-metric
- #2 All Cloudflare calls pass a shared, configurable token-bucket limiter
- #3 Tests cover backoff expiry and limiter pacing
Definition of Done
- #1 just check (fmt-check, lint, vet, test, tidy-check, build, vuln)
- #2 just ci before a change that touches the Dockerfile, goreleaser or the image (adds snapshot + image)
- #3 Every new signal or attribute name declared in internal/semconv and listed in docs/signals.md
Implementation Plan
Loop15 E51D: one shared process token bucket for all Cloudflare calls, configurable 0.5 requests/second and burst 1 by default, below the current documented GraphQL quota of 300 queries per five minutes. Typed per-zone/per-dataset unentitled backoff lasts one hour; Logpush skips backed-off zones visibly without blocking others. Preserve existing schedules, retry/permission behavior and read-only APIs; prove through real local HTTP boundaries and fake clock at the process edge. Current vendor quota evidence retained privately; fresh independent reviewer-high required before landing.
Loop17 frozen packet: one local implementation attempt with assertion-red witness, just check and CodeRabbit to terminal result; fresh exact-SHA independent REV before root linear landing. No lane remote writes.
Implementation Notes
Loop15 fresh REV rejected local candidate: same-zone/same-dataset multi-alias denial misses entitlement cache; redirect quota waiting consumes network timeout; opaque-fixture policy violation. Nothing landed. Implementation I1-I4 consumed, but goal sections 7.3 and 8 provide independent review-repair RR1 of 3, now admitted on those concrete findings only. Earlier root park conclusion corrected; no I5 or widened scope. Independent gate vuln was blocked by an overbroad offline instruction, not passed; gate-required public dependency/CVE lookups now explicitly authorized, with no live tenant calls.
Loop15 RR2 is partial: strict settings decoder passes cfapi checks, but the new registered collector test references nonexistent payload fields and did not compile. No green collector recovery, full gate, review or commit is claimed. Final review-repair RR3 of 3 is authorized only to correct the zero-payload assertion to Buffer.Records and complete the reproduced schema/checkpoint repair. Implementation allowance remains zero; no reset or extra repair is granted.
Loop15 FINAL REVIEW FAIL on final candidate despite exact-SHA complete gate passing: enabled=true with missing/null availableFields is still converted into a locally generated entitlement denial and cached for one hour. Independent real-HTTP reproduction passes original base and fails final source. Implementation and review-repair allowances are both exhausted. Candidate is parked and must not land; no extra attempt or counter reset authorized. All local source branches, scratch evidence and checkpoints retained. Public main/runtime do not contain this limiter/backoff candidate.
Loop16 E51D-L-I1 fullgate red on lifecycle/fixture timing, I2 fullgate green with explicit fast fixture budgets and preserved tight assertions. Combined implementation2of2 ceiling consumed; backoff B permanently parked. I2 CodeRabbit14paths covered but two major non-GET/HEAD redirect findings unresolved, no commit. Root corrected its added POST-replay requirement to prioritise read-only client contract and granted review-repair1of2: refuse following POST/other non-GET/HEAD redirects, preserve GET/HEAD pacing and per-hop timeouts; change witness explicitly for intended security behavior. No candidate accepted or source criteria checked yet. Minor contradictory quota300/320 suggestions left pending authorised evidence; default0.5rps/burst1 unchanged.
Loop16 fresh high REV-E51D-L-R1 FAIL8c13880f3d8d9cf95b694a747ba8f8b8fbdd7f93 after independent fullgate and public pacing/redirect witnesses passed. Production CLI accepted raw YAML fractional1.9 and booleantrue burst values as1 through weak decode, violating integer-input contract. Final review-repair2of2 reserved to validate effective raw burst before lossy decode, preserving integer environment override precedence; public CLI assertion-red reproduction retained. Implementations2of2, review-repairs2of2 ceiling after this reservation; B permanently parked, source acceptance remains unchecked. No third release or live pacing proof.
Loop16 FINAL high REV-E51D-L-R2 FAILa967fec19c65b6d07d6a03b6bf3d18121553b5c6: limiter.go35 compares burst identity via float64, so distinct accepted64-bit integers9223372036854775807 and9223372036854775806 are indistinguishable after traffic and different active configuration is accepted. Independent YAML-loader/loopback HTTP reproduction confirmed. Ordinary public boundary/default/redirect matrix/config fixes and full gate passed; frozen exact-integer lifecycle contract does not. Combined implementations2of2 and review-repairs2of2 exhausted; limiter candidate and backoff B permanently parked, no more repair or landing. Retain candidate branches/evidence; no source acceptance or live/CI/release claim. Minimal future authorised fix is exact integer identity, not rounded capacity.
Loop17 fresh REV-E51D-L2 FAIL8a867ee557ba718bae65aefbe3c2795211d459ff: precision-close raw fractional YAML values round through parser float64 before integer validation (1000.00000000000001 becomes1000;1.0000000000000001 and0.99999999999999999 become1). Operational impact low but frozen exact raw-input requirement unmet. Full exact-SHA gate, shared pacing and30case redirect matrix passed; review infrastructure1 golangci lock, not implementation. Root RR1 of combined2 opens only on this independent assertion/CLI reproduction. Preserve integral2.0 and environment precedence; exact scalar rejection without contract weakening, version/dependency bump or unrelated changes.
Loop17 fresh high REV-E51D-L2-RR1 PASS680fa366d38a97364f44496c5391e814c6b5ab17, native exact YAML scalar/alias/merge and environment precedence, integer burst1..1000, default0.5rps/burst1, public pacing and30redirect cases, full exact gate and15path CodeRabbit coverage. One minor retained to preserve strict dotted-key rejection. Exact patches landed069c5e7/72bd3e9/1ed8339/652c55e with equal range-diff, integrated gate/scans green, pushed652c55e852cd7e27a23fe4c8b3fae6741c58af26; exactCI pending. AC2checked; AC3 limiter half proven but fullcriterion waits backoff. Combined implementation1 and review-repair1 remain, E51D-B admitted on landed source, last implementation attempt.
Final Summary
Loop17 both commissioned source halves accepted and landed: fresh high limiter PASS680fa366 and backoff PASS376510aa, exact patches carried unchanged, source settings disabled/absent zone retry at1h and existing complete-poll skip Gauge proved, schema/auth/transient recovery not cached. Shared0.5rps/burst1 pacing/integer bounds/redirect safeguards and expiry/alias/concurrency/registeredDNS red-green tests passed. Backoff landed062bbe7 and pushed2eb6a689e5cd6d247f1af4065035a6044c9af089 with exact gate/scans green, CI pending. Done is sourceAC1/2/3 only: current0.16.1 healthy deployment lacks complete first-hour scrape coverage, tracked separately CFO-0079 (missing completion series after shared limiter); one hour retry running. Backoff release/deploy/live proof still pending, no live-quiet claim.