Skip to content

feat: targeting rule authoring, for agents that write flags - #8

Merged
Alex (Alexkuva) merged 1 commit into
mainfrom
feat/targeting-authoring
Oct 16, 2026
Merged

Alex (Alexkuva) merged 1 commit into
mainfrom
feat/targeting-authoring

Conversation

@tomflenner

Copy link
Copy Markdown
Contributor

What does this PR change?

Adds feature_flags.targeting_context(), feature_flags.lint_rule(rule) and feature_flags.test_rule(rule, *, targeting_key=None, context=None), sync and async. They wrap get-targeting-context, lint-targeting-rule and test-targeting-rule, with the models generated from the vendored contract (TargetingContext, TargetingContextNode, TargetingRuleVerdict, TargetingRuleIssue, TargetingRuleRehearsal, and the TargetingFactType enum).

This reverses a documented decision. coverage.yaml excluded these three operations as "rule-editor tooling for the Kaiten console, with no SDK audience". This PR maps them instead.

Why?

They have an SDK audience now: anything that writes flags without the console's editor. The Kaiten MCP server is one (kaitencloud/mcp#1). An agent writing a flag has nothing to tell it that a rule names a fact or an entitlement that doesn't exist, and such a rule never errors: it silently never matches. The MCP lints every rule before saving it, and lets an agent dry-run one against a real customer or instance.

Today it reaches these endpoints around the SDK, through its private transport, because there are no methods for them. With this PR it can drop that.

OFREP evaluation stays excluded, as before: it belongs to OpenFeature and the OFREP provider.

Testing

  • task check: generate:check, ruff, mypy --strict, 761 passed. The three operations are in test_contract.py, so each request is validated against the contract and each response is parsed into its model.
  • TargetingContextNode is the first recursive model. The contract test's payload generator now ends a recursion with an empty array or an absent property, not null, so the model round-trip tests cover it.
  • Run live against a local Kaiten stack:
    • targeting_context() returns __kaiten with license, entitlements, instance, customer and deploymentZone;
    • lint_rule accepts a valid rule, and reports a truncated one with its message and line;
    • test_rule with targeting_key and kaiten.instanceSlug matches and returns the facts it read.
  • README: a new paragraph in Feature flags, three API reference rows, and the operation counts (108 → 111; 98 → 101 of 107 core). CHANGELOG entry under Unreleased.

Checklist

  • I have read CONTRIBUTING.md.
  • Every commit in this PR includes a valid DCO Signed-off-by line.
  • I have the right to submit all material in this PR.
  • I have not included secrets or confidential data.
  • I have updated tests where appropriate.
  • I have updated documentation where appropriate.
  • I have preserved required third-party licenses and attributions.

🤖 Generated with Claude Code

Wraps the three operations coverage.yaml excluded as console-only tooling:
get-targeting-context, lint-targeting-rule and test-targeting-rule, as
feature_flags.targeting_context, lint_rule and test_rule.

They have an SDK audience now. An agent writing a flag through the SDK (the
Kaiten MCP server is one) has no editor to tell it that a rule names a fact
or an entitlement that does not exist, and such a rule never fails: it never
matches. These are how it finds out before it saves.

TargetingContextNode is the first recursive model, so the test payload
generator learned to stop a recursion with an empty array or an absent
property, rather than a null the schema does not allow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: tomflenner <flennertom@gmail.com>
@Alexkuva
Alex (Alexkuva) merged commit df68d7d into main Oct 16, 2026
13 checks passed
@Alexkuva
Alex (Alexkuva) deleted the feat/targeting-authoring branch October 16, 2026 08:24
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.

2 participants