feat!: retire the legacy org rules API, expose the policy reflections - #54
Merged
Conversation
The cloud API deleted the old policy/equipment surface; `/v1/org/rules` now
answers 410 Gone. Methods that can only throw are worse than no methods, so
they are removed rather than deprecated.
REMOVED from `org`: listRules, getRule, createRule, updateRule, deleteRule —
and the OrgRule, OrgRuleAction, OrgRuleMethod, OrgRuleRateLimitWindow,
OrgRuleCondition, CreateOrgRuleInput and UpdateOrgRuleInput types. Authoring
moved to the *PolicyRule family, which has been available since 2.8.0.
ADDED, so nothing is lost with them — the read-only policy reflections, which
report what the PUBLISHED policy actually allows rather than a stored
assignment list:
- org.getEffectiveAppPermissions({ provider }) replaces the retired
/v1/org/rules/permissions/:provider
- getEffectiveCredentials(agentId) replaces GET /v1/agents/:id/secrets
and /connections
- getConnectionAgentAccess(connectionId) replaces GET /v1/connections/:id/agents
- listAppPermissionDefinitions() the tool catalog an app-target
rule can name
The difference matters: the old reads returned stored assignments, so a
credential granted by a policy rule was invisible to them. The reflections
resolve the rules, so it is not.
Tests pin the request paths (a wrong one silently returns another resource's
shape), url-encoding, error mapping, and the absence of the removed methods and
types from the public surface.
BREAKING CHANGE: org.listRules, org.getRule, org.createRule, org.updateRule and
org.deleteRule are removed along with the OrgRule* and *OrgRuleInput types. Use
the *PolicyRule methods to author rules and org.getEffectiveAppPermissions to
read what they permit.
Three findings from review. The verdict union was wrong against the cloud's own type: it is allow | approval | block | mixed | unmanaged, not allowed/blocked/needsApproval, and rateLimited does not exist — a rate limit rides rateLimit/rateLimitWindow on an allow. Anyone narrowing on the shipped values would have matched nothing. The reflection set was asymmetric: the CLI could read PROJECT app permissions and the SDK only the org scope. getEffectiveAppPermissions now exists on both, sharing one type — the shape is identical at either scope and basis.scope reports which produced it, so OrgEffectiveAppPermissions was the wrong name and is now just EffectiveAppPermissions. The test mock reused a single Response, whose body can only be read once; a second call in one test threw "Body has already been read" rather than exercising the code. It mints a fresh Response per call now.
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.
Companion follow-up to onecli-cloud#709 (policy step 10 — "drop the old policy/equipment model").
/v1/org/rulesnow answers 410 Gone, so these methods can only throw. Shipping them would be worse than removing them.Removed
org.listRules,org.getRule,org.createRule,org.updateRule,org.deleteRule, and theOrgRule,OrgRuleAction,OrgRuleMethod,OrgRuleRateLimitWindow,OrgRuleCondition,CreateOrgRuleInput,UpdateOrgRuleInputtypes.Authoring moved to the
*PolicyRulefamily, available since 2.8.0.Added — so nothing goes with them
The read-only policy reflections. They report what the published policy allows, not a stored assignment list:
org.getEffectiveAppPermissions({ provider })/v1/org/policy/effective-app-permissionsgetEffectiveAppPermissions({ provider, agentId? })/v1/policy/effective-app-permissionsgetEffectiveCredentials(agentId)/v1/agents/{id}/effective-credentialsgetConnectionAgentAccess(connectionId)/v1/connections/{id}/effective-agentslistAppPermissionDefinitions()/v1/apps/permission-definitionsThe difference is load-bearing: the old reads returned stored assignments, so a credential granted by a policy rule was invisible to them. The reflections resolve the rules, so it is not.
Review
Walked through
typescript-proandtypescript-advanced-types— noany, no enums, discriminated unions for the credential and provenance shapes, declaration files generated, strict mode. Three fixes:EffectiveToolVerdictunion was wrong against the API: it isallow | approval | block | mixed | unmanaged, andrateLimiteddoes not exist — a rate limit ridesrateLimit/rateLimitWindowon anallow. Anyone narrowing on the shipped values would have matched nothing.basis.scopereports which produced it, soOrgEffectiveAppPermissionswas the wrong name.Response, whose body reads once — a second call threw "Body has already been read" instead of exercising the code.Verification
tsc,tsupbuild, 108 vitest. Tests pin the request paths (a wrong one silently returns another resource's shape), url-encoding, error mapping, and the absence of the removed methods and types from the public surface.Related
Land last, after the docs and CLI PRs.
🤖 Generated with Claude Code