chore: fix logging and std out printing - #2798
Merged
Merged
Conversation
|
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The new noteStyler.Write can drop buffered output on write errors due to advancing the pending buffer before confirming writes succeed.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR refines the CLI’s human-facing output (notes + tables) while tightening time-bound handling around recorder start times, aiming to make logs more readable and reduce false “from before recording started” failures caused by sub-second header timestamps.
Changes:
- Compare
fromvsStartedAtat whole-second granularity (and update error formatting to RFC3339Nano) with added unit tests for boundary cases. - Improve operator-facing output formatting: multi-line startup summary, earlier
min-observednote, titled tables, and a structured THRESHOLDS section. - Add a CLI-only notes/table styling layer (ANSI color when writing to a terminal; plain text otherwise) and route
Notesthrough it incheckandwatch.
File summaries
| File | Description |
|---|---|
| grafana-alertcheck/internal/gate/schedule.go | Makes startup summary/warning multi-line and more readable. |
| grafana-alertcheck/internal/gate/coverage.go | Applies whole-second comparison for from bounds; uses RFC3339Nano in message. |
| grafana-alertcheck/internal/gate/coverage_test.go | Adds tests covering same-second and boundary-crossing cases for from bounds. |
| grafana-alertcheck/internal/gate/check.go | Uses whole-second comparison for recorder-mode fail-fast; prints min-observed earlier. |
| grafana-alertcheck/internal/gate/check_test.go | Adds recorder-mode test ensuring same-second from passes. |
| grafana-alertcheck/cmd/grafana-alertcheck/watch.go | Routes gate notes through the new note styler. |
| grafana-alertcheck/cmd/grafana-alertcheck/check.go | Routes gate notes through the new note styler. |
| grafana-alertcheck/cmd/grafana-alertcheck/table.go | Adds section titles, thresholds table, and colored “violations” footer when terminal output. |
| grafana-alertcheck/cmd/grafana-alertcheck/table_test.go | Updates assertions for the new table/footer format. |
| grafana-alertcheck/cmd/grafana-alertcheck/style.go | Introduces terminal-detection, note line styling, and section spacing behavior. |
Review details
- Files reviewed: 10/10 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Tofel
force-pushed
the
dx-5122-alerts-assertion-p14
branch
from
September 4, 2026 15:03
e0a1a11 to
24afb29
Compare
Tofel
force-pushed
the
dx-5122-alerts-assertion-p13
branch
from
September 4, 2026 15:03
c97e92d to
10c74ca
Compare
Tofel
force-pushed
the
dx-5122-alerts-assertion-p14
branch
from
September 4, 2026 15:15
24afb29 to
bb77d7f
Compare
Tofel
force-pushed
the
dx-5122-alerts-assertion-p13
branch
2 times, most recently
from
September 7, 2026 09:35
33eea1f to
a0a237e
Compare
Tofel
force-pushed
the
dx-5122-alerts-assertion-p14
branch
2 times, most recently
from
September 7, 2026 09:46
ee198e3 to
5f7c40b
Compare
Tofel
force-pushed
the
dx-5122-alerts-assertion-p13
branch
2 times, most recently
from
September 7, 2026 15:02
4855fcd to
a87fc14
Compare
Tofel
force-pushed
the
dx-5122-alerts-assertion-p14
branch
from
September 7, 2026 15:02
5f7c40b to
7ed660b
Compare
Tofel
force-pushed
the
dx-5122-alerts-assertion-p14
branch
from
September 7, 2026 15:19
7ed660b to
f256983
Compare
Tofel
force-pushed
the
dx-5122-alerts-assertion-p13
branch
from
September 7, 2026 15:19
a87fc14 to
ca3ccc6
Compare
Tofel
removed this pull request from stack #2791
September 9, 2026 09:52
* chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* Wire watch/check subcommands to the gate library, with a table+JSON renderer and H6/H7 exit-code mapping. Extend Result with per-rule/global thresholds and a real skew bound; export SkewHardLimit; reject --states normal. * chore: fix goreleaser.yaml and add version command * chore: implement phase 11 (#2789) * chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: implement phase 9 Invariant defended: H5/H7. The one question: can check report a pass over a window it did not prove? Check() is the I/O shell around the pure decide(). Single-step synthesizes the header and its own sentinel, so no mode flag reaches the pure layer. Log mode stops the recorder before the one full read. The header, not a definition re-resolved after the window closed, is the authority for what was paused when the window opened — it decides `skipped`, the drain set, and the transitionGrace max. The flock, not the pidfile, is the authority for whether a writer still exists. * chore: remove unix build tag * chore: implement phase 10 (#2788) * Wire watch/check subcommands to the gate library, with a table+JSON renderer and H6/H7 exit-code mapping. Extend Result with per-rule/global thresholds and a real skew bound; export SkewHardLimit; reject --states normal. * chore: fix goreleaser.yaml and add version command * chore: implement phase 11 (#2789) * chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: implement phase 8 Invariant defended: H6/H7. The one question: can a violation ever outrank an unobservable rule, or can a pass happen without Violations empty and err nil? Adds classify.go: the pure per-instance classifier (outcome table, preexisting policy, BadFor) and decide(), the seam combining proveCoverage with those timelines under one Policy. Consolidates rule-poll filtering and skew translation onto pollsForRule/runnerTime, shared with coverage.go. * chore: rename some vars + add unit tests * chore: address code review comments * chore: implement phase 9 (#2787) * chore: implement phase 9 Invariant defended: H5/H7. The one question: can check report a pass over a window it did not prove? Check() is the I/O shell around the pure decide(). Single-step synthesizes the header and its own sentinel, so no mode flag reaches the pure layer. Log mode stops the recorder before the one full read. The header, not a definition re-resolved after the window closed, is the authority for what was paused when the window opened — it decides `skipped`, the drain set, and the transitionGrace max. The flock, not the pidfile, is the authority for whether a writer still exists. * chore: remove unix build tag * chore: implement phase 10 (#2788) * Wire watch/check subcommands to the gate library, with a table+JSON renderer and H6/H7 exit-code mapping. Extend Result with per-rule/global thresholds and a real skew bound; export SkewHardLimit; reject --states normal. * chore: fix goreleaser.yaml and add version command * chore: implement phase 11 (#2789) * chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: implement phase 7 Invariant defended: H3. The one question: can a rule be called alive because it looked alive one poll ago? proveCoverage (grafana-alertcheck/internal/gate/coverage.go) is the pure coverage function: nine checks over one rule's polls — sentinel, from-bounds, heartbeat continuity, health error/nodata, liveness, in-window pause, rule absence, KeepLast. Liveness is absolute, never a delta. Cross-domain comparisons translate by each poll's own skew and widen boundary segments by its skew bound, fail-closed. * chore: enhance unit tests * chore: address code review comments * chore: implement phase 8 (#2786) * chore: implement phase 8 Invariant defended: H6/H7. The one question: can a violation ever outrank an unobservable rule, or can a pass happen without Violations empty and err nil? Adds classify.go: the pure per-instance classifier (outcome table, preexisting policy, BadFor) and decide(), the seam combining proveCoverage with those timelines under one Policy. Consolidates rule-poll filtering and skew translation onto pollsForRule/runnerTime, shared with coverage.go. * chore: rename some vars + add unit tests * chore: address code review comments * chore: implement phase 9 (#2787) * chore: implement phase 9 Invariant defended: H5/H7. The one question: can check report a pass over a window it did not prove? Check() is the I/O shell around the pure decide(). Single-step synthesizes the header and its own sentinel, so no mode flag reaches the pure layer. Log mode stops the recorder before the one full read. The header, not a definition re-resolved after the window closed, is the authority for what was paused when the window opened — it decides `skipped`, the drain set, and the transitionGrace max. The flock, not the pidfile, is the authority for whether a writer still exists. * chore: remove unix build tag * chore: implement phase 10 (#2788) * Wire watch/check subcommands to the gate library, with a table+JSON renderer and H6/H7 exit-code mapping. Extend Result with per-rule/global thresholds and a real skew bound; export SkewHardLimit; reject --states normal. * chore: fix goreleaser.yaml and add version command * chore: implement phase 11 (#2789) * chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: implement phase 6 Invariant defended: H2. The one question: can watch return success over a window that nothing is recording? Watch() records the first observation of each non-skipped rule, then detaches a child that polls at the cadence in the header. The parent returns only after the child reports ready on an inherited pipe, and writes the pidfile after that. A clean stop writes the sentinel; a hard error does not. * chore: add a unit test, remove build tags * chore: address code review comments * chore: implement phase 7 (#2785) * chore: implement phase 7 Invariant defended: H3. The one question: can a rule be called alive because it looked alive one poll ago? proveCoverage (grafana-alertcheck/internal/gate/coverage.go) is the pure coverage function: nine checks over one rule's polls — sentinel, from-bounds, heartbeat continuity, health error/nodata, liveness, in-window pause, rule absence, KeepLast. Liveness is absolute, never a delta. Cross-domain comparisons translate by each poll's own skew and widen boundary segments by its skew bound, fail-closed. * chore: enhance unit tests * chore: address code review comments * chore: implement phase 8 (#2786) * chore: implement phase 8 Invariant defended: H6/H7. The one question: can a violation ever outrank an unobservable rule, or can a pass happen without Violations empty and err nil? Adds classify.go: the pure per-instance classifier (outcome table, preexisting policy, BadFor) and decide(), the seam combining proveCoverage with those timelines under one Policy. Consolidates rule-poll filtering and skew translation onto pollsForRule/runnerTime, shared with coverage.go. * chore: rename some vars + add unit tests * chore: address code review comments * chore: implement phase 9 (#2787) * chore: implement phase 9 Invariant defended: H5/H7. The one question: can check report a pass over a window it did not prove? Check() is the I/O shell around the pure decide(). Single-step synthesizes the header and its own sentinel, so no mode flag reaches the pure layer. Log mode stops the recorder before the one full read. The header, not a definition re-resolved after the window closed, is the authority for what was paused when the window opened — it decides `skipped`, the drain set, and the transitionGrace max. The flock, not the pidfile, is the authority for whether a writer still exists. * chore: remove unix build tag * chore: implement phase 10 (#2788) * Wire watch/check subcommands to the gate library, with a table+JSON renderer and H6/H7 exit-code mapping. Extend Result with per-rule/global thresholds and a real skew bound; export SkewHardLimit; reject --states normal. * chore: fix goreleaser.yaml and add version command * chore: implement phase 11 (#2789) * chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: implement phase 5 Add the JSONL evidence log (P5). - log.go: Header/Poll records, reduction, H2 transition markers, §3.2 verification, append-only Writer with flock, ReadLog - flock_unix.go: non-blocking exclusive lock, unix only - schedule.go: DeriveTimingsFromLog — log-mode cadence comes from the header, never from the definitions * chore: remove unix build tags * chore: address code review comments * chore: implement phase 6 (#2784) * chore: implement phase 6 Invariant defended: H2. The one question: can watch return success over a window that nothing is recording? Watch() records the first observation of each non-skipped rule, then detaches a child that polls at the cadence in the header. The parent returns only after the child reports ready on an inherited pipe, and writes the pidfile after that. A clean stop writes the sentinel; a hard error does not. * chore: add a unit test, remove build tags * chore: address code review comments * chore: implement phase 7 (#2785) * chore: implement phase 7 Invariant defended: H3. The one question: can a rule be called alive because it looked alive one poll ago? proveCoverage (grafana-alertcheck/internal/gate/coverage.go) is the pure coverage function: nine checks over one rule's polls — sentinel, from-bounds, heartbeat continuity, health error/nodata, liveness, in-window pause, rule absence, KeepLast. Liveness is absolute, never a delta. Cross-domain comparisons translate by each poll's own skew and widen boundary segments by its skew bound, fail-closed. * chore: enhance unit tests * chore: address code review comments * chore: implement phase 8 (#2786) * chore: implement phase 8 Invariant defended: H6/H7. The one question: can a violation ever outrank an unobservable rule, or can a pass happen without Violations empty and err nil? Adds classify.go: the pure per-instance classifier (outcome table, preexisting policy, BadFor) and decide(), the seam combining proveCoverage with those timelines under one Policy. Consolidates rule-poll filtering and skew translation onto pollsForRule/runnerTime, shared with coverage.go. * chore: rename some vars + add unit tests * chore: address code review comments * chore: implement phase 9 (#2787) * chore: implement phase 9 Invariant defended: H5/H7. The one question: can check report a pass over a window it did not prove? Check() is the I/O shell around the pure decide(). Single-step synthesizes the header and its own sentinel, so no mode flag reaches the pure layer. Log mode stops the recorder before the one full read. The header, not a definition re-resolved after the window closed, is the authority for what was paused when the window opened — it decides `skipped`, the drain set, and the transitionGrace max. The flock, not the pidfile, is the authority for whether a writer still exists. * chore: remove unix build tag * chore: implement phase 10 (#2788) * Wire watch/check subcommands to the gate library, with a table+JSON renderer and H6/H7 exit-code mapping. Extend Result with per-rule/global thresholds and a real skew bound; export SkewHardLimit; reject --states normal. * chore: fix goreleaser.yaml and add version command * chore: implement phase 11 (#2789) * chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: implement phase 4 Add per-rule poll timings, scheduler, and budget check (P4). - schedule.go: DeriveTimings, Scheduler, CheckBudget (§5) - Address review: add Folder/Title resolve test, rename CheckBudget's minPollEvery to tightestUID * chore: enhance unit tests * chore: address code review comments * chore: implement phase 5 (#2783) * chore: implement phase 5 Add the JSONL evidence log (P5). - log.go: Header/Poll records, reduction, H2 transition markers, §3.2 verification, append-only Writer with flock, ReadLog - flock_unix.go: non-blocking exclusive lock, unix only - schedule.go: DeriveTimingsFromLog — log-mode cadence comes from the header, never from the definitions * chore: remove unix build tags * chore: address code review comments * chore: implement phase 6 (#2784) * chore: implement phase 6 Invariant defended: H2. The one question: can watch return success over a window that nothing is recording? Watch() records the first observation of each non-skipped rule, then detaches a child that polls at the cadence in the header. The parent returns only after the child reports ready on an inherited pipe, and writes the pidfile after that. A clean stop writes the sentinel; a hard error does not. * chore: add a unit test, remove build tags * chore: address code review comments * chore: implement phase 7 (#2785) * chore: implement phase 7 Invariant defended: H3. The one question: can a rule be called alive because it looked alive one poll ago? proveCoverage (grafana-alertcheck/internal/gate/coverage.go) is the pure coverage function: nine checks over one rule's polls — sentinel, from-bounds, heartbeat continuity, health error/nodata, liveness, in-window pause, rule absence, KeepLast. Liveness is absolute, never a delta. Cross-domain comparisons translate by each poll's own skew and widen boundary segments by its skew bound, fail-closed. * chore: enhance unit tests * chore: address code review comments * chore: implement phase 8 (#2786) * chore: implement phase 8 Invariant defended: H6/H7. The one question: can a violation ever outrank an unobservable rule, or can a pass happen without Violations empty and err nil? Adds classify.go: the pure per-instance classifier (outcome table, preexisting policy, BadFor) and decide(), the seam combining proveCoverage with those timelines under one Policy. Consolidates rule-poll filtering and skew translation onto pollsForRule/runnerTime, shared with coverage.go. * chore: rename some vars + add unit tests * chore: address code review comments * chore: implement phase 9 (#2787) * chore: implement phase 9 Invariant defended: H5/H7. The one question: can check report a pass over a window it did not prove? Check() is the I/O shell around the pure decide(). Single-step synthesizes the header and its own sentinel, so no mode flag reaches the pure layer. Log mode stops the recorder before the one full read. The header, not a definition re-resolved after the window closed, is the authority for what was paused when the window opened — it decides `skipped`, the drain set, and the transitionGrace max. The flock, not the pidfile, is the authority for whether a writer still exists. * chore: remove unix build tag * chore: implement phase 10 (#2788) * Wire watch/check subcommands to the gate library, with a table+JSON renderer and H6/H7 exit-code mapping. Extend Result with per-rule/global thresholds and a real skew bound; export SkewHardLimit; reject --states normal. * chore: fix goreleaser.yaml and add version command * chore: implement phase 11 (#2789) * chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: implement phase 3 Add Resolve() for alert name resolution (uid:/Title/Folder/Title/ Folder/Group/Title forms, UID collapse, no-match suggestions) and the grafana-alertcheck CLI's list subcommand, the first runnable piece of the gate. Incorporates review fixes: reject empty path segments in classifyForm, guard uid: against an empty suffix, scope the no-match rule count and suggestions to supported rule kinds only, and exit 0 on -h/--help. * chore: enhance unit tests * chore: implement phase 4 (#2782) * chore: implement phase 4 Add per-rule poll timings, scheduler, and budget check (P4). - schedule.go: DeriveTimings, Scheduler, CheckBudget (§5) - Address review: add Folder/Title resolve test, rename CheckBudget's minPollEvery to tightestUID * chore: enhance unit tests * chore: address code review comments * chore: implement phase 5 (#2783) * chore: implement phase 5 Add the JSONL evidence log (P5). - log.go: Header/Poll records, reduction, H2 transition markers, §3.2 verification, append-only Writer with flock, ReadLog - flock_unix.go: non-blocking exclusive lock, unix only - schedule.go: DeriveTimingsFromLog — log-mode cadence comes from the header, never from the definitions * chore: remove unix build tags * chore: address code review comments * chore: implement phase 6 (#2784) * chore: implement phase 6 Invariant defended: H2. The one question: can watch return success over a window that nothing is recording? Watch() records the first observation of each non-skipped rule, then detaches a child that polls at the cadence in the header. The parent returns only after the child reports ready on an inherited pipe, and writes the pidfile after that. A clean stop writes the sentinel; a hard error does not. * chore: add a unit test, remove build tags * chore: address code review comments * chore: implement phase 7 (#2785) * chore: implement phase 7 Invariant defended: H3. The one question: can a rule be called alive because it looked alive one poll ago? proveCoverage (grafana-alertcheck/internal/gate/coverage.go) is the pure coverage function: nine checks over one rule's polls — sentinel, from-bounds, heartbeat continuity, health error/nodata, liveness, in-window pause, rule absence, KeepLast. Liveness is absolute, never a delta. Cross-domain comparisons translate by each poll's own skew and widen boundary segments by its skew bound, fail-closed. * chore: enhance unit tests * chore: address code review comments * chore: implement phase 8 (#2786) * chore: implement phase 8 Invariant defended: H6/H7. The one question: can a violation ever outrank an unobservable rule, or can a pass happen without Violations empty and err nil? Adds classify.go: the pure per-instance classifier (outcome table, preexisting policy, BadFor) and decide(), the seam combining proveCoverage with those timelines under one Policy. Consolidates rule-poll filtering and skew translation onto pollsForRule/runnerTime, shared with coverage.go. * chore: rename some vars + add unit tests * chore: address code review comments * chore: implement phase 9 (#2787) * chore: implement phase 9 Invariant defended: H5/H7. The one question: can check report a pass over a window it did not prove? Check() is the I/O shell around the pure decide(). Single-step synthesizes the header and its own sentinel, so no mode flag reaches the pure layer. Log mode stops the recorder before the one full read. The header, not a definition re-resolved after the window closed, is the authority for what was paused when the window opened — it decides `skipped`, the drain set, and the transitionGrace max. The flock, not the pidfile, is the authority for whether a writer still exists. * chore: remove unix build tag * chore: implement phase 10 (#2788) * Wire watch/check subcommands to the gate library, with a table+JSON renderer and H6/H7 exit-code mapping. Extend Result with per-rule/global thresholds and a real skew bound; export SkewHardLimit; reject --states normal. * chore: fix goreleaser.yaml and add version command * chore: implement phase 11 (#2789) * chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: implement phase 2 Fix retry-error conflation, measure full poll latency, and harden Source test doubles for concurrency. * chore: enhance unit tests * chore: address code review comments * chore: implement phase 3 (#2781) * chore: implement phase 3 Add Resolve() for alert name resolution (uid:/Title/Folder/Title/ Folder/Group/Title forms, UID collapse, no-match suggestions) and the grafana-alertcheck CLI's list subcommand, the first runnable piece of the gate. Incorporates review fixes: reject empty path segments in classifyForm, guard uid: against an empty suffix, scope the no-match rule count and suggestions to supported rule kinds only, and exit 0 on -h/--help. * chore: enhance unit tests * chore: implement phase 4 (#2782) * chore: implement phase 4 Add per-rule poll timings, scheduler, and budget check (P4). - schedule.go: DeriveTimings, Scheduler, CheckBudget (§5) - Address review: add Folder/Title resolve test, rename CheckBudget's minPollEvery to tightestUID * chore: enhance unit tests * chore: address code review comments * chore: implement phase 5 (#2783) * chore: implement phase 5 Add the JSONL evidence log (P5). - log.go: Header/Poll records, reduction, H2 transition markers, §3.2 verification, append-only Writer with flock, ReadLog - flock_unix.go: non-blocking exclusive lock, unix only - schedule.go: DeriveTimingsFromLog — log-mode cadence comes from the header, never from the definitions * chore: remove unix build tags * chore: address code review comments * chore: implement phase 6 (#2784) * chore: implement phase 6 Invariant defended: H2. The one question: can watch return success over a window that nothing is recording? Watch() records the first observation of each non-skipped rule, then detaches a child that polls at the cadence in the header. The parent returns only after the child reports ready on an inherited pipe, and writes the pidfile after that. A clean stop writes the sentinel; a hard error does not. * chore: add a unit test, remove build tags * chore: address code review comments * chore: implement phase 7 (#2785) * chore: implement phase 7 Invariant defended: H3. The one question: can a rule be called alive because it looked alive one poll ago? proveCoverage (grafana-alertcheck/internal/gate/coverage.go) is the pure coverage function: nine checks over one rule's polls — sentinel, from-bounds, heartbeat continuity, health error/nodata, liveness, in-window pause, rule absence, KeepLast. Liveness is absolute, never a delta. Cross-domain comparisons translate by each poll's own skew and widen boundary segments by its skew bound, fail-closed. * chore: enhance unit tests * chore: address code review comments * chore: implement phase 8 (#2786) * chore: implement phase 8 Invariant defended: H6/H7. The one question: can a violation ever outrank an unobservable rule, or can a pass happen without Violations empty and err nil? Adds classify.go: the pure per-instance classifier (outcome table, preexisting policy, BadFor) and decide(), the seam combining proveCoverage with those timelines under one Policy. Consolidates rule-poll filtering and skew translation onto pollsForRule/runnerTime, shared with coverage.go. * chore: rename some vars + add unit tests * chore: address code review comments * chore: implement phase 9 (#2787) * chore: implement phase 9 Invariant defended: H5/H7. The one question: can check report a pass over a window it did not prove? Check() is the I/O shell around the pure decide(). Single-step synthesizes the header and its own sentinel, so no mode flag reaches the pure layer. Log mode stops the recorder before the one full read. The header, not a definition re-resolved after the window closed, is the authority for what was paused when the window opened — it decides `skipped`, the drain set, and the transitionGrace max. The flock, not the pidfile, is the authority for whether a writer still exists. * chore: remove unix build tag * chore: implement phase 10 (#2788) * Wire watch/check subcommands to the gate library, with a table+JSON renderer and H6/H7 exit-code mapping. Extend Result with per-rule/global thresholds and a real skew bound; export SkewHardLimit; reject --states normal. * chore: fix goreleaser.yaml and add version command * chore: implement phase 11 (#2789) * chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
Tofel
added a commit
that referenced
this pull request
Sep 9, 2026
* chore: implement phase 1 Strict parsers for the state and ruler endpoints (H1), a Prometheus-style duration parser, and fixtures sliced from real Grafana 13.1.0 payloads covering every required/optional-field and must-error case, including the "Normal (NoData)"/"Normal (Error)" composite reason states found live in the current fleet capture (not in the original plan's vocabulary). * chore: apply code review comments * chore: implement phase 2 (#2780) * chore: implement phase 2 Fix retry-error conflation, measure full poll latency, and harden Source test doubles for concurrency. * chore: enhance unit tests * chore: address code review comments * chore: implement phase 3 (#2781) * chore: implement phase 3 Add Resolve() for alert name resolution (uid:/Title/Folder/Title/ Folder/Group/Title forms, UID collapse, no-match suggestions) and the grafana-alertcheck CLI's list subcommand, the first runnable piece of the gate. Incorporates review fixes: reject empty path segments in classifyForm, guard uid: against an empty suffix, scope the no-match rule count and suggestions to supported rule kinds only, and exit 0 on -h/--help. * chore: enhance unit tests * chore: implement phase 4 (#2782) * chore: implement phase 4 Add per-rule poll timings, scheduler, and budget check (P4). - schedule.go: DeriveTimings, Scheduler, CheckBudget (§5) - Address review: add Folder/Title resolve test, rename CheckBudget's minPollEvery to tightestUID * chore: enhance unit tests * chore: address code review comments * chore: implement phase 5 (#2783) * chore: implement phase 5 Add the JSONL evidence log (P5). - log.go: Header/Poll records, reduction, H2 transition markers, §3.2 verification, append-only Writer with flock, ReadLog - flock_unix.go: non-blocking exclusive lock, unix only - schedule.go: DeriveTimingsFromLog — log-mode cadence comes from the header, never from the definitions * chore: remove unix build tags * chore: address code review comments * chore: implement phase 6 (#2784) * chore: implement phase 6 Invariant defended: H2. The one question: can watch return success over a window that nothing is recording? Watch() records the first observation of each non-skipped rule, then detaches a child that polls at the cadence in the header. The parent returns only after the child reports ready on an inherited pipe, and writes the pidfile after that. A clean stop writes the sentinel; a hard error does not. * chore: add a unit test, remove build tags * chore: address code review comments * chore: implement phase 7 (#2785) * chore: implement phase 7 Invariant defended: H3. The one question: can a rule be called alive because it looked alive one poll ago? proveCoverage (grafana-alertcheck/internal/gate/coverage.go) is the pure coverage function: nine checks over one rule's polls — sentinel, from-bounds, heartbeat continuity, health error/nodata, liveness, in-window pause, rule absence, KeepLast. Liveness is absolute, never a delta. Cross-domain comparisons translate by each poll's own skew and widen boundary segments by its skew bound, fail-closed. * chore: enhance unit tests * chore: address code review comments * chore: implement phase 8 (#2786) * chore: implement phase 8 Invariant defended: H6/H7. The one question: can a violation ever outrank an unobservable rule, or can a pass happen without Violations empty and err nil? Adds classify.go: the pure per-instance classifier (outcome table, preexisting policy, BadFor) and decide(), the seam combining proveCoverage with those timelines under one Policy. Consolidates rule-poll filtering and skew translation onto pollsForRule/runnerTime, shared with coverage.go. * chore: rename some vars + add unit tests * chore: address code review comments * chore: implement phase 9 (#2787) * chore: implement phase 9 Invariant defended: H5/H7. The one question: can check report a pass over a window it did not prove? Check() is the I/O shell around the pure decide(). Single-step synthesizes the header and its own sentinel, so no mode flag reaches the pure layer. Log mode stops the recorder before the one full read. The header, not a definition re-resolved after the window closed, is the authority for what was paused when the window opened — it decides `skipped`, the drain set, and the transitionGrace max. The flock, not the pidfile, is the authority for whether a writer still exists. * chore: remove unix build tag * chore: implement phase 10 (#2788) * Wire watch/check subcommands to the gate library, with a table+JSON renderer and H6/H7 exit-code mapping. Extend Result with per-rule/global thresholds and a real skew bound; export SkewHardLimit; reject --states normal. * chore: fix goreleaser.yaml and add version command * chore: implement phase 11 (#2789) * chore: implement phase 11 Add coverage.go's declared-KeepLast check (no_data_state/exec_err_state, not just an observed reason) and close the remaining §22 gaps: newly_bad's no-early-exit clock assertion, a recorder-mode gap right after the deploy, a rule's own coverage gap overriding its own recovery, a genuinely skew-discriminating staleness test, exit-2 consequences on two Reason-only coverage tests, and end-to-end checks for log-name collapse, a truncated log, and the real watch-written state histogram. * chore: address code review comments * chore: more concise comments (#2790) * chore: more concise comments * fix: merge conflict * chore: shorten comments * fix: resolve conflict * chore: use testify's require in tests (#2792) * chore: use testify's require in tests * chore: move remaining assumptions to testify * chore: address code review comments * chore: fix logging and std out printing (#2798) * chore: fix logging and std out printing * chore: truncate to seconds when comparing from time * chore: add centralized docs (#2802) * chore: add centralized docs * chore: further update docs * chore: address code review comments (#2807) * chore: address code review comments * chore: get rid of goreleaser
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.
Improves human-facing output for
check/watch:style.gonoteStylercolourises notes by prefix and inserts section breaks — colour only when the destination is a TTY andNO_COLORis unset.table.gooutput is restructured into titled sections (RESULTS / VIOLATIONS / THRESHOLDS) with a coloured violations footer.from < StartedAtbound is now compared at whole-second granularity (incoverage.goand thecheck.gofail-fast), so a--fromin the same second as the recording's start is not judged early.StartupSummaryis reformatted onto multiple lines.Review focus:
style.go(colour/NO_COLOR) and the whole-second truncation incoverage.go/check.go.