Skip to content

feat(kg): add thresholds read commands over v1 threshold config - #1316

Open
kblaschke512 wants to merge 2 commits into
mainfrom
feat/kg-thresholds
Open

kblaschke512 wants to merge 2 commits into
mainfrom
feat/kg-thresholds

Conversation

@kblaschke512

@kblaschke512 kblaschke512 commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds read-only gcx kg thresholds over the Asserts v1 threshold config API. Refs #1078 — writes (set -f, upsert, delete) follow in a second PR, so this one carries no destructive paths.

gcx kg thresholds get                                  # whole config; table by default
gcx kg thresholds get -o yaml                         # PrometheusRules resource envelope
gcx kg thresholds list --category request|resource    # custom/global split; table by default

Why v1, not v2

The Asserts app UI and every threshold users have actually configured run on v1 — ManageAssertions.service.ts calls only /v1/config/threshold-rule(s), across six call sites. ThresholdsV2ConfigController has zero call sites in the plugin UI; it appears only in the proxy authz allow-list (pkg/plugin/authz/authz.go) and its own tests. So a v2 client would diverge from what the product actually uses.

Re-checked at asserts-app-plugin@dc0b960b and asserts-adi@4f4d8a8880 (2026-09-11): both controllers still exist, neither is @Deprecated, and the v1 endpoint map is unchanged.

The two read endpoints in this PR were verified live against a dev stack — response shapes match the DTOs exactly ({active, expr, labels, record}). The write endpoints are from source reading only; they land with the follow-up PR.

Notes for review

  • get supports human and machine output. Table is the default and reuses the existing prom-rules table codecs. JSON/YAML preserve the PrometheusRulesDto resource envelope through the existing RuleToResource path.
  • list tables follow ADR-002. One column list defines narrow and wide output; LABELS is the only WideOnly column.
  • Machine formats preserve backend shapes. A KG-local helper sends flattened rows to human-readable formats and the DTO/resource envelope to machine formats. It remains local because this PR owns KG, not Instrumentation or the shared internal/output contract. ADR-002 and those packages are unchanged.
  • Expressions remain complete. Multi-line PromQL is folded onto one table row without truncation, while whitespace inside quoted literals is preserved. Special label values are quoted so they cannot break or ambiguate table cells.
  • Zero results serialize as [], never null.
  • --category is validated before any request and path-escaped before being added to the URL.

Testing

  • GCX_AGENT_MODE=false mise run all — lint 0 issues, full suite green, docs/reference generation and build green
  • Unit tests cover both endpoints, default and machine output, golden narrow/wide/empty tables, untruncated multi-line expressions, quoted literal whitespace, special labels, zero-result JSON, category validation, and URL path escaping
  • Both commits carry verified SSH signatures

Out of scope

  • Writes (set -f whole-config replace, upsert, delete) — follow-up PR; set replaces everything, so it gets a confirmation prompt plus --yes
  • v2 API — unadopted by the UI
  • Shared output abstraction or Instrumentation changes
  • The remaining hand-rolled KG codecs — those belong to the 🚀 simplify the codec providers #1275 sweep

🤖 Generated with Claude Code

@kblaschke512
kblaschke512 requested review from a team as code owners September 11, 2026 17:13
kblaschke512 and others added 2 commits September 14, 2026 11:51
Add `gcx kg thresholds get` (whole config as YAML) and `list --category
request|resource` (custom/global split) over the Asserts v1 threshold API.
Targets v1 — the version the Asserts UI and all user thresholds run on.

Tables are declared as one column list per ADR-002; goldens captured from a
hand-rolled codec pair still pass unchanged. Machine formats keep the
custom/global wire split via a local format switch.

Verified against a dev stack, which caught two things unit tests missed: real
threshold exprs are multi-line PromQL that broke the table apart, now collapsed
and clipped; and `get` must encode a *pointer* to the unstructured envelope,
since MarshalJSON is on the pointer receiver and a value leaks an "Object" key.

Read-only first; writes land in a follow-up. Refs #1078.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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