feat: add kosli attest decision command (hidden/BETA)#912
Conversation
Implements `kosli attest decision` per kosli-dev/server#5695. Records a compliance decision against a control on a trail, posting to the /api/v2/attestations/{org}/{flow}/trail/{trail}/system endpoint with type_name="decision". The command is hidden (BETA). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The /system endpoint requires control and is_compliant nested under attestation_data rather than at the top-level payload, matching the server's schema validation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move control/is_compliant back to top-level payload fields; keep
attestation_data as a required-but-empty field (reserved for future
structured inputs per server schema)
- Fix flag bindings to point to top-level payload fields
- Add CreateControl helper to testHelpers.go (POST /api/v2/controls/{org})
- Call CreateControl in SetupTest so RCTL-043 exists before attesting
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…evel The server schema requires control as a top-level field and is_compliant nested under attestation_data. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @jumboduck's task in 2m 47s —— View job PR Review:
|
| } | ||
| } | ||
|
|
||
| // CreateControl creates a control in the org via the API. | ||
| func CreateControl(org, identifier, name string, t *testing.T) { | ||
| t.Helper() | ||
| u, err := url.JoinPath(global.Host, "api/v2/controls", org) | ||
| require.NoError(t, err, "control URL should be constructed without error") | ||
|
|
||
| reqParams := &requests.RequestParams{ | ||
| Method: http.MethodPost, | ||
| URL: u, | ||
| Payload: map[string]string{"identifier": identifier, "name": name}, | ||
| Token: global.ApiToken, | ||
| } | ||
| _, err = kosliClient.Do(reqParams) | ||
| require.NoError(t, err, "control should be created without error") | ||
| } | ||
|
|
||
| // CreatePolicy creates a policy on the server |
There was a problem hiding this comment.
Minor: the other helpers like CreateFlow / BeginTrail use command run() methods, which are idempotent on the server side (PUT semantics or "create if not exists"). This helper does a raw POST /api/v2/controls/{org}, which may return an error if a control with this identifier already exists — e.g., if SetupTest() runs multiple times in the same test process.
If the server's control endpoint is idempotent on re-creation, this is fine. Otherwise, consider either checking for existence first, or ignoring "already exists" errors. Worth verifying against the server.
Summary
kosli attest decisioncommand (hidden, BETA) per kosli-dev/server#5695POST /api/v2/attestations/{org}/{flow}/trail/{trail}/systemtype_name=decision,controlat top level,is_compliantnested underattestation_dataCreateControltest helper (directPOST /api/v2/controls/{org}) for test setupTest plan
--name,--control,--compliant; invalid fingerprint; bad annotation key; invalid name dot-format; too many args--fingerprint--attachments,--description,--annotate,--user-datakosli attest decision --helpreflects all flags correctlykosli attest --help🤖 Generated with Claude Code