Repository navigation
feat: scope evaluators to the current project on create - #274
Draft
quinn-galileo wants to merge 9 commits into
Draft
quinn-galileo wants to merge 9 commits into
quinn-galileo wants to merge 9 commits into
Conversation
Add project_ids and is_global to the evaluator create paths and default the scope to the current project, so non-admins can create evaluators when metric RBAC is on. Surface is_global and scope_projects on Evaluator. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…roject fixture Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Resolve conflicts keeping both sides and thread scope through the new decision evaluator create path. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
|
I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
- Resolve the CHANGELOG merge conflict, keeping main's entries and ours. - Reject a bare string for project_ids instead of splitting it into characters. - DecisionEvaluator.create no longer marks the evaluator failed on a scope ValidationError, matching the LLM and code paths. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
quinn-galileo
commented
Oct 19, 2026
quinn-galileo
left a comment
Collaborator
Author
There was a problem hiding this comment.
- Store constructor project_ids/is_global privately; public is_global and scope_projects now only reflect the API response (None/[] until populated). - An Unset is_global in the response maps to None. - Explain a missing default project in the NotFoundError message, normalise a whitespace-only context project, and document scope errors on create(). - Add regression tests for create() on a fetched evaluator and tighten tests. - Correct the CHANGELOG validation wording and note the project must exist. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
quinn-galileo
commented
Oct 19, 2026
This was referenced Oct 19, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
quinn-galileo
changed the base branch from
main
to
chore/sao-9342-t0-regenerate-client
October 20, 2026 15:41
This branch has not been deployed
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.
Why
With metric RBAC on (now the server default), a create request that carries neither
is_globalnorproject_idsis treated as global, and only org admins may create global metrics. The SDK never sent scope, so every non-admin evaluator create returned 403. This PR adds scope to every SDK evaluator create path and defaults it to the user's current project. Ticket: SAO-9342.What changed
New
project_ids: list[str] | Noneandis_global: bool | NoneonEvaluators.create_custom_llm_evaluator,Evaluators.create_decision_evaluator, the module-levelcreate_custom_llm_evaluator/create_decision_evaluator(trailing keyword params, positional order unchanged), and keyword-only onLlmEvaluator,CodeEvaluatorandDecisionEvaluator.Evaluator.is_globalandEvaluator.scope_projectsreport only what the API returned:None/[]until the evaluator is populated bycreate(),get(),list()orrefresh(). The scope you pass to a constructor is kept privately and read only bycreate(), so callingcreate()on an evaluator fetched withget()resolves scope from the current project, not from the fetched server values.The scope sent on create, in order:
is_global=Trueand non-emptyproject_idsValidationError, nothing sentis_global=Trueis_global=True, noproject_idsproject_ids=[...]is_global=False, those ids (deduplicated, order kept)project_ids=[]ValidationErrorSPLUNK_AO_PROJECT_ID, thenSPLUNK_AO_PROJECT)is_global=False,project_ids=[<that project's id>]NotFoundError, nothing sent (no silent fallback to global)is_global=False, noproject_ids, no current projectValidationErrorThe current project must already exist. Unlike logging, creating an evaluator does not create it, and the
NotFoundErrorsays so and points atproject_ids=[...]oris_global=True.Behaviour change for admins: an admin with a current project set now gets a project-scoped evaluator. Pass
is_global=Truefor a global one. The CHANGELOG says so, and names 0.6.0 as the minimumsplunk-aoversion for creating project-scoped evaluators.Where to start reading
_resolve_create_scopeinsrc/splunk_ao/evaluators.pyholds all the rules above.src/splunk_ao/evaluator.py: the constructors andcreate()ofLlmEvaluator,CodeEvaluatorandDecisionEvaluator, and_populate_from_scorer_response.Testing
poetry run pytest tests/test_evaluators.py tests/test_evaluator.py tests/test_decision_scorers.py -n 0(254 passed, including tests/test_projects.py) andpoetry run invoke type-check(clean). All network is mocked. Tests cover the default, each precedence step, explicit override, global, nothing-set, every validation error, not-found, constructor forwarding, and population from the response, for the LLM, code and decision paths.Related PRs
🤖 Generated with Claude Code