Skip to content

feat: add kosli get evaluation with --show-input and --fixture for replay - #1319

Merged
pbeckham merged 6 commits into
mainfrom
7567-get-evaluation
Nov 3, 2026
Merged

pbeckham merged 6 commits into
mainfrom
7567-get-evaluation

Conversation

@pbeckham

@pbeckham pbeckham commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Adds kosli get evaluation (beta) to read a server-side evaluation back, show the input its policy read (--show-input -o json), and write its input, params and policy to a directory (--fixture --dir) so the decision can be re-run with stock OPA. Until now an evaluation could only be read through the raw API, and what it was given was not retrievable. The still-pending timeout message now points at this command.

Part of kosli-dev/server#7567

Checklist

  • Docs are autogenerated from CLI help — make sure the help text reflects your changes
  • Helm chart updated not needed
  • Terraform provider updated not needed

🤖 Generated with Claude Code

…eplay

A server-side evaluation could only be read back through the raw API, and
nothing showed what it was given, so a decision could not be re-run with
stock OPA to check it (kosli-dev/server#7567).

get evaluation prints an evaluation's status, policy, trails, outcome or
error, and the decision it recorded. --show-input adds the document the
policy read as input under .input, and --fixture --dir writes input.json,
data.json (params under "params") and the policy files: an inline policy's
from the evaluation, a published version's from its bundle. The command is
beta, like the rest of server-side evaluation.

The still-pending error now points at kosli get evaluation instead of a raw
GET, and the evaluation id is escaped into one path segment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pbeckham

pbeckham commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

Choices a reviewer may want to question

  • Pending evaluations: --fixture exports them, since the server serves /input at any status. The issue left this TBD.
  • data.json is {"params": ...}, so opa eval --data data.json exposes it as data.params.
  • .input is the server's input document, not the shape client-side evaluate trail --show-input builds. The issue asked for the same shape; the two have not been compared.
  • No digest check: the written policy/ is not re-digested against the evaluation's digest.
  • Recorded at is shown as the issue lists it; what recorded_at means is still an open question on the server issue.

Small fixes along the way

  • The evaluation id is escaped into one path segment.
  • The /input read opts out of the client's 409 retry, since its 409 ("no policy input can be built") is permanent and the retry discarded the message.

Not verified

A full replay with opa eval reproducing a recorded outcome. Tests run against a fake server, since the local stack has no evaluator; this needs a staging check after release.

@github-actions github-actions Bot added go Pull requests that update go code feat labels Nov 2, 2026
@claude

claude Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @pbeckham's task in 1m 9s —— View job


Follow-up review: c72e7e3..ef419c8

This range is one commit, ef419c8e, touching only cmd/kosli/getEvaluation_test.go.

Previous finding addressed by this commit:

  • fakeEvaluationRead's bundle route silently returning 200 instead of 404 when unconfigured — ✅ Resolved. newFakeEvaluationRead now seeds bundle: fakeRoute{status: http.StatusNotFound}, matching the doc comment's "anything else is a 404". The two tests that configure the bundle (TestAFixtureOfAPublishedPolicyUnpacksItsBundle, TestAFixtureRefusesABundleEntryOutsideTheDirectory) were correctly updated from fake.bundle.body = ... to fake.bundle = fakeRoute{body: ...}, replacing the whole struct so status resets to the zero value (which the handler still maps to 200 OK) instead of staying at 404 alongside the new body. Verified no other test references publishedBundlePath or fake.bundle without setting the full struct, so nothing regresses.

Previous findings not touched by this diff (unchanged from the last follow-up, all in getEvaluation.go or unrelated test regions):

  • Recorded at 1970 risk — not touched; author declined, thread already resolved.
  • withInput splice edge cases — not touched; author declined, thread already resolved.
  • evaluationURL not rejecting ./.. — already resolved in 695dda87.
  • SnykCode XSS on the test fake — already resolved (false positive, then fixed anyway in d256b4d6).
  • Test-coverage gap from the c72e7e33 revert (pending inline-policy fixture with absent files no longer covered) — still open; this commit doesn't touch runFixture or the readPending/inline-policy fixtures.

New in this diff: No new bugs, security issues, or regressions found in the changed lines — the fix is minimal, correct, and self-contained to the test fake.

Comment thread cmd/kosli/getEvaluation_test.go Fixed
Comment thread cmd/kosli/getEvaluation.go Resolved
Comment thread cmd/kosli/getEvaluation.go Resolved
Comment thread internal/evaluations/wait.go Resolved
pbeckham and others added 2 commits November 2, 2026 13:35
A URL path resolves . and .. however they are escaped, so `get evaluation .`
read the list route and printed an empty evaluation with exit 0 instead of
saying the id was wrong.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…its test fake

The audit coverage test fails for any command or flag the audit does not
know about, so get evaluation and its flags are added to the coverage file
and to the audit spec, marked as needing server-side evaluation like the
rego-policy commands.

Snyk Code fails the build on a test fake that wrote a body looked up by the
request path. The fake now picks a route with a switch, so nothing it writes
is derived from the request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread cmd/kosli/getEvaluation_test.go Resolved
@claude

claude Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Follow-up review: 695dda8..d256b4d

Previous findings:

  • SnykCode XSS on the test fake (fmt.Fprint) — ✅ Resolved. d256b4d6 replaced the map-lookup + fmt.Fprint with an explicit switch-routed fakeRoute struct and io.WriteString, so nothing written is derived from the request path. (Author initially dismissed as a false positive, then fixed anyway since Snyk Code gates the build.)
  • Pending evaluation may print a 1970 "Recorded at" (getEvaluation.go:172) — ⏭️ Not addressed. Not touched by these commits; author declined, reasoning the server's EvaluationResponse never sends a null/absent recorded_at.
  • Edge cases in the withInput splice (getEvaluation.go:162) — ⏭️ Not addressed. Not touched by these commits; author declined as speculative for shapes the current API can't produce.
  • evaluationURL not rejecting ./.. ids (internal/evaluations/wait.go) — ✅ Resolved, already fixed in 695dda87 (the base of this diff).

New in this diff: 1 inline comment — the refactored fakeEvaluationRead test helper routes publishedBundlePath through the switch even when no test has set fake.bundle, so an unconfigured bundle request now silently returns 200 with an empty body instead of the 404 the helper's own doc comment promises ("anything else is a 404"). No current test is affected, but it's a latent trap for future tests.

View job run

The server now returns an inline policy's files only once the evaluation
has finished, so polling a pending one does not resend the bundle on every
read. Without them a fixture of a pending inline evaluation would have been
written with no policy at all; it is refused instead, before anything is
read or written. A pending published-policy evaluation is still exported,
since its bundle is read from the rego policy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server change that would have dropped an inline policy's files from a
pending evaluation (kosli-dev/server#7825) was closed, so the server keeps
serving them in every state and the refusal blocked a case that works.

This reverts commit dbc79af.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread cmd/kosli/getEvaluation_test.go Resolved
@claude

claude Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Follow-up review: dbc79af..c72e7e3

This range is just two commits that cancel out: dbc79af4 added a refusal for --fixture on a pending inline-policy evaluation, and c72e7e33 reverts it, restoring the original (e98aa475) behavior of exporting a fixture for any pending evaluation.

Previous findings — none touch the lines changed here, all are either already resolved or live in code this diff doesn't touch:

  • SnykCode XSS on the test fake — ✅ already resolved (pre-existing).
  • Recorded at 1970 risk (getEvaluation.go:172 pre-diff) — ⏭️ not touched; author declined, thread already resolved.
  • withInput splice edge cases (getEvaluation.go:162 pre-diff) — ⏭️ not touched; author declined, thread already resolved.
  • evaluationURL not rejecting ./.. — ✅ already resolved in 695dda87.
  • fakeEvaluationRead's bundle route silently returning 200 instead of 404 when unconfigured — ⏭️ still open, but its location (newFakeEvaluationRead) isn't touched by dbc79af4/c72e7e33, so out of scope for this round.

New in this diff: 1 inline comment — the revert deletes both the pending-inline-policy check in runFixture and the test that exercised it, but the replacement readPending fixture now carries files all along, so no test covers the actual edge case the removed check protected against (a pending inline evaluation whose files are genuinely absent). If that's still possible server-side, --fixture will now silently write an incomplete fixture with no policy/ files and no error.

View job run

The fake's zero-value bundle route turned into a 200 with an empty body, so a
test that forgot to stub the bundle would read a successful empty download
rather than the 404 the fake's comment promises.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pbeckham
pbeckham merged commit 4bfe4cc into main Nov 3, 2026
23 checks passed
@pbeckham
pbeckham deleted the 7567-get-evaluation branch November 3, 2026 09:33
dangrondahl pushed a commit to kosli-dev/docs that referenced this pull request Nov 4, 2026
Shows how to read back a pending or finished evaluation, replay it with
OPA, and type-check a policy against its input schema before publishing.
Beta: server-side evaluation is per-org beta; command released in CLI
v2.53.0.

Based on [add kosli get evaluation with --show-input and --fixture for
replay](kosli-dev/cli#1319), [Serve what an
evaluation was given for offline
replay](kosli-dev/server#7764) and [Serve the
JSON Schemas of a Rego policy's
input](kosli-dev/server#7844).

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat go Pull requests that update go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants