Skip to content

docs: custom roles REST API reference (CUB-4361) - #11894

Open
paveltiunov wants to merge 63 commits into
masterfrom
pavel-claude/elegant-dirac-88avqw
Open

paveltiunov wants to merge 63 commits into
masterfrom
pavel-claude/elegant-dirac-88avqw

Conversation

@paveltiunov

@paveltiunov paveltiunov commented Sep 16, 2026

Copy link
Copy Markdown
Member

Check List

  • Tests have been run in packages where changes have been made if available
  • Linter has been run for changed code
  • Tests for the changes have been added if not covered yet — docs-only; scripts/extract-api.mjs --check is the gate and passes
  • Docs have been added / updated if required

Issue Reference this PR resolves

CUB-4361. Docs half of cubedevinc/cubejs-enterprise#15056, which adds the /api/v1/roles endpoints to the console-server public API.

Description of Changes Made

  • Regenerated api-reference/api.yaml, docs.json and api-reference/introduction.mdx from the console-server public spec, which now carries /api/v1/roles (list, create, get, update, delete, plus assign/unassign a role for a user).
  • Added Roles to TAG_ORDER in scripts/extract-api.mjs so the group sits with the other access-control groups (Users, Users Admin, Groups, User Groups) instead of being appended A–Z at the end of the Platform Endpoints nav, which is where an unlisted tag lands.
  • Added a Managing roles through the API section to admin/users-and-permissions/custom-roles.mdx. That page is written entirely around the console, which was accurate until now; the section walks the flow the endpoints were added for — create a deployment, scope a role to its numeric id, assign it — and notes the two things that aren't obvious from the schema: "actions": ["All"] is the Full access shortcut, and deployment ids are checked for shape rather than existence.

On extract-api.mjs --check after the rebase onto master

node scripts/extract-api.mjs --check <spec>, against the spec on the linked PR's branch, reports every roles path and schema up to date. It does report the reference out of date overall, on two paths this PR did not touch — the Databricks Metric View syncs endpoints, which landed on cubejs-enterprise master after this branch's regeneration. That drift is already on cube master (the reference was not regenerated when those endpoints shipped) and is not this PR's to carry: regenerating here would fold 419 unrelated reference lines into a docs change that is already reviewed, so this PR leaves them to the change that adds them.

🤖 Generated with Claude Code

https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg


Generated by Claude Code

@mintlify

mintlify Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
cubed3 🟢 Ready View Preview Sep 22, 2026, 10:03 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@github-actions github-actions Bot added docs Issues that require a documentation improvement javascript Pull requests that update Javascript code labels Sep 16, 2026
@claude

claude Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 3m 1s —— View job


Review complete — 3 findings (1 medium, 2 low), no blockers in the generated spec or nav

Details
  • Read the diff and all five changed files
  • Cross-checked api.yaml roles paths/schemas against Policy, PolicyResourceType and the rest of the spec
  • Checked nav consistency: TAG_ORDERdocs.json group → introduction.mdx row → Mintlify slugs
  • Checked prior review threads (none open)
  • Posted findings

Findings

# Severity Location Concern
1 Medium custom-roles.mdx:213-235 "Everything above is also available over the REST API", but the create example has no Base Role — the field this page calls required and license-tier-setting. RoleCreateBody is name/description/policies only.
2 Low custom-roles.mdx:250 The new section sits directly above ## Validation, which is console-only and says an action-less policy is "silently dropped on save" — the opposite of the generated POST /api/v1/roles text ("rejected when it grants no action").
3 Low custom-roles.mdx:242 "a built-in role id can still be assigned", but no endpoint in the spec exposes built-in role ids.

Checks that passed

  • All seven /api/v1/roles operations are present in api.yaml, all seven listed in the docs.json group, tag added to tags: and to TAG_ORDER.
  • Roles lands between Users Admin and User Attributes in nav and in the introduction.mdx table — matches TAG_ORDER (Groups/User Groups aren't in the spec, so they don't occupy slots).
  • Both new cross-links resolve to real operation slugs: list-custom-roles ← summary "List custom roles"; create-a-deployment-with-an-empty-starter-project-and-trigger-its-first-build ← the summary at api.yaml:5202.
  • The doc example's DeploymentRead/SchemaRead and resourceType: Deployment are valid enum members (api.yaml:11007, 11067), and both are reads, so they don't trip the Developer auto-bump the page describes.
  • toMintContent()'s brace escaping leaves the fenced JSON in the createRole description unescaped, which is correct for MDX — the triple-backtick fence pairs up as code spans. Nothing else in the new prose contains braces.

Note, not a finding

The regeneration also sweeps in unrelated upstream spec drift not mentioned in the PR description: restrictDataDownload added to AppSettings and to its required list, and showRowTotals on two pivot schemas. Expected for a full regen, but worth naming so it isn't read as part of the roles change.

I could not run node scripts/extract-api.mjs --check <spec> here — the console-server spec lives in cubejs-enterprise and isn't available in this checkout, so the "reference is up to date" claim rests on your run.

· branch `pavel-claude/elegant-dirac-88avqw`

Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
@claude

claude Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 2m 29s —— View job


Review complete — 2 medium, 2 low, no blockers

Details (4 inline comments, verification notes, checklist)

Findings

# Sev Where Concern
1 medium custom-roles.mdx:225-236 The role sample pairs a Global tier of AIBIExplore with a Deployment policy granting SchemaRead. The same page (:127) says DeploymentRead and DownloadData are the only deployment actions that don't force Developer, and :75 says that mirrors a server-side rule. So the example is either ineffective at runtime or a role the console cannot reproduce. api.yaml:4586 carries the same pairing plus PlaygroundRead.
2 medium custom-roles.mdx:247-269 The mapping table, the <Warning> and the <Note> are a third copy of facts already in the page's action catalog (:292-294, :107-112), the Validation section (:277) and api.yaml:4602-4611. docs-mintlify/CLAUDE.md rules this out ("Say it once", "Do not pad"), and duplicated prose next to a generated reference drifts on the next regeneration.
3 low api.yaml:5912-5926, :10930, :10986 restrictDataDownload (added to required) and showRowTotals rode in with the regeneration, unrelated to CUB-4361 and unmentioned in the PR body. Confirm both are live in production console-server, not just on the spec branch.
4 low api.yaml:11880 RoleCreateBody.name truncates the reserved names to "(Admin, Developer, …)"; custom-roles.mdx:277 gives the full set including All and None — the two a caller would never guess.

What checks out

  • TAG_ORDER placement is self-consistent with the generated nav: Groups / User Groups aren't in the spec, so Roles lands right after Users Admin in both docs.json:982 and introduction.mdx:93. The one-line extract-api.mjs change is the right fix for the A–Z fallback.
  • Every $ref the new paths introduce resolves — Policy (api.yaml:11024), PageInfo (:10845), Role, RoleCreateBody, RoleUpdateBody, RolesListResponse.
  • Both new link definitions resolve to real generated slugs: list-custom-roles from summary: List custom roles, and the deployment-creation slug matches api.yaml:5219.
  • All seven docs.json page entries match the method/path pairs actually defined under /api/v1/roles*.
  • Admin-only preamble, idempotency and 404 behaviour are stated on every endpoint; PUT replace-not-merge semantics are called out in both the endpoint text and the RoleUpdateBody.policies description.

Not verified

node scripts/extract-api.mjs --check <spec> was not run — the console-server spec lives in the private cubejs-enterprise repo and isn't reachable from this checkout. Taking the PR body's report of it at face value.

No prior review threads existed on this PR, so there was nothing to resolve or dedupe against.

Checklist

  • Gather context (diff, changed files, spec)
  • Review custom-roles.mdx prose accuracy
  • Review api.yaml / docs.json / introduction.mdx consistency
  • Verify extract-api.mjs tag ordering; --check gate not runnable here
  • Post findings
· branch `pavel-claude/elegant-dirac-88avqw`

Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
Comment thread docs-mintlify/api-reference/api.yaml Outdated
Comment thread docs-mintlify/api-reference/api.yaml
@claude

claude Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 3m 9s —— View job


Review complete — 2 medium, 1 low posted inline; 1 prior thread re-affirmed

Details
  • Read the diff and changed files
  • Verify api.yaml / docs.json / introduction.mdx consistency
  • Check extract-api.mjs TAG_ORDER change
  • Review custom-roles.mdx prose for accuracy and link validity
  • Handle prior review threads
  • Post findings

Findings

Where Severity Concern
custom-roles.mdx:213 medium The Validation intro links to #managing-roles-through-the-api "where a policy with no actions is rejected rather than dropped" — the section never says that. The rule lives only in api.yaml:4602, which renders on a different page.
custom-roles.mdx:268 vs :75 medium The new <Warning> says the server enforces no license tier; :75 (unchanged) says the auto-bump "mirrors the server-side rule that any deployment write or data-model write requires the Developer license tier". The PR's own integration test makes :75 the wrong one, and it's the version a top-to-bottom reader hits first.
custom-roles.mdx:268 low "a rule the builder applies to your input, not one the server applies to yours" — "to yours" is a leftover fragment. Folded into the same comment with a suggestion block.

Re-affirmed 1 prior thread still applies: the AIBIExplore + SchemaRead sample (thread on custom-roles.mdx:247). The JSON at :236-249 grants SchemaRead alongside a Global AIBIExplore, while the page's own Tip at :131 says only DeploymentRead and DownloadData escape the bump to Developer — so the flagship example is a role the builder would not let you build. Not re-posted; the open thread carries it.

Checked and clean

  • docs.json:981-994 — all 7 nav page strings resolve to a real path + method in api.yaml:4510-4744.
  • Both new reference links resolve: list-custom-roles matches summary List custom roles under tag Roles; the deployment-creation slug matches the one already used at introduction.mdx:74.
  • extract-api.mjs:216Roles sits with the other access-control tags. Groups / User Groups aren't in the current spec, so Roles lands right after Users Admin in both the nav and the intro table, consistently.
  • Nothing in the generated x-mint.content blocks trips the unescaped-brace or frontmatter hazards the script's own comments warn about.
  • --check against the upstream spec could not be run here — the source spec lives in cubejs-enterprise and isn't available to this checkout. Taking the PR body's word that it passes.

Security / performance / tests

Docs-only; no runtime surface. One note worth keeping in view: every new operation's description opens with 🔒 Admin only, and the endpoints are admin-gated server-side, so the reference doesn't leak a callable surface to non-admins.

· branch [`pavel-claude/elegant-dirac-88avqw`](https://github.com/cube-js/cube/tree/pavel-claude/elegant-dirac-88avqw)

Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
@claude

claude Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Reviewing PR #11894

  • Read the diff and changed files
  • Check custom-roles.mdx prose against the generated spec
  • Check api.yaml / docs.json / introduction.mdx consistency with extract-api.mjs
  • Run the --check gate if the spec is reachable
  • Review prior threads, post findings

View job run · pavel-claude/elegant-dirac-88avqw

@claude

claude Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 4m 4s —— View job


Review — 1 high, 2 medium. All three are on custom-roles.mdx; the generated artifacts check out.

Details — findings, what I verified, what I couldn't
  • Read the diff and changed files
  • Check the roles spec against the docs page claims
  • Check nav/tag ordering and generator change
  • Reconcile with prior review threads
  • Post findings

Findings

Sev Where What
High custom-roles.mdx:264 "built-in roles are not listed, editable or assignable" is false on the third term. Your own reply on efe7fbd established that assignRole branches on the negative id and always has; api.yaml restricts only DELETE and PUT /roles/{roleId}, and says nothing of the kind on the assign endpoint. PUT /api/v1/roles/-7/users/{id} grants Admin and returns 200. Leaving it unadvertised was defensible — asserting the opposite points a privilege-escalation audit the wrong way.
Medium custom-roles.mdx:251 Says the auto-bump "applies to your payload too"; the <Warning> at :260 says it is builder-only and "not one the server applies to what you send". ff91d58 narrowed :260 and left :251 asserting the broad version first.
Medium custom-roles.mdx:213–217 The new intro promises to flag where the API validates differently but names only the action-less policy. The reserved-name bullet gets no qualifier, so "name": "AIBIViewer" 400s from a name the page implies is free, and "name": "All" succeeds from one it says is rejected.

Checked and clean

  • Nav ordering. Roles after Users Admin in docs.json:982 matches TAG_ORDERGroups and User Groups have no tags in this spec, so Roles lands where the generator would put it. introduction.mdx:93 is in the same position.
  • Link targets. #auto-bump-to-developer resolves to :69 (I initially read this as a dead anchor — it isn't; only the sentence around it is wrong). ref-api-rolesList custom roles, ref-api-create-deploymentapi.yaml:5221. Both slugs match their summary.
  • Schema refs. Role, RoleCreateBody, RoleUpdateBody, RolesListResponse resolve Policy (api.yaml:11026) and PageInfo (:10847), both pre-existing. Seven paths in the spec, seven in the nav group.
  • restrictDataDownload / showRowTotals. Your earlier thread reads correctly — pre-existing drift between this repo's committed reference and the enterprise spec on master, not fields riding in on the branch.
  • Page-vs-reference consistency on the rest of the API section: the 400 conditions, the PUT-replaces-not-merges note, the id-shape-not-existence note and the admin-only requirement all match the x-mint descriptions.

Not run

node scripts/extract-api.mjs --check <spec> — the spec lives in the private cubedevinc/cubejs-enterprise repo, so I can't reproduce the up-to-date claim from here. Worth noting the gap you identified stands: nothing in CI catches this reference drifting from the enterprise spec, which is why a regen on an unrelated PR keeps surfacing unrelated fields.

No prior review threads were open — the thread list paged out empty, so nothing to resolve or dedupe against.

· branch [`pavel-claude/elegant-dirac-88avqw`](https://github.com/cube-js/cube/tree/pavel-claude/elegant-dirac-88avqw)

Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
@claude

claude Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Reviewing PR #11894

  • Read the PR diff and changed files
  • Check the docs prose against the generated reference
  • Check extract-api.mjs / docs.json / introduction.mdx consistency
  • Reconcile with prior review threads
  • Post findings

View job run · branch pavel-claude/elegant-dirac-88avqw

@claude

claude Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 5m 23s —— View job


Approve with nits — 0 high, 2 medium, 2 low. Generated reference, nav and links all check out.

Full review
  • Read the diff against origin/master
  • Read the changed files in full
  • Verify generated-reference consistency (nav entries vs. spec paths, TAG_ORDER, link slugs, anchors)
  • Check prior review threads (zero unresolved — all settled)
  • Post findings

Findings

# Severity Where Concern
1 Medium api-reference/api.yaml:4747 Assign/unassign publish '200' from the generator's no-declared-response fallback; your own integration test reports 204. A client checking status === 200 treats a successful assign as a failure.
2 Medium api-reference/api.yaml:11924 RoleUpdateBody.policies and name accept null, and nothing says what PUT {"policies": null} does — no-op, 400, or strip every grant. That payload is what a partially-filled struct serializes to.
3 Low api-reference/api.yaml:11897 "Pass [] to create a role that grants nothing yet" and the 400 on a policy that "grants no action" use one phrase for opposite outcomes. Policy also has no minItems: 1, so the empty-policy case validates against the published schema and 400s against the service.
4 Low custom-roles.mdx:260 The <Warning> restates the auto-bump asymmetry already given at :251, against docs-mintlify/CLAUDE.md's "don't restate the same point in prose and again in a callout".

Findings 1–3 are upstream (cubejs-enterprise spec source), not editable here — they'd come back on the next regeneration if fixed only in api.yaml.

Verified clean

  • TAG_ORDER placement (scripts/extract-api.mjs:216) lands Roles where intended: the spec declares no Groups / User Groups tags (api.yaml:40-42 runs Users Admin → Roles → User Attributes), so the nav group in docs.json:982 and the introduction.mdx:93 row sit in the same position the generator computes. No manual-vs-generated drift.
  • All three new link references resolve. /api-reference/roles/list-custom-roles and create-a-custom-role match the List custom roles / Create a custom role summaries under the Roles tag; /api-reference/deployment-creation/create-a-deployment-with-an-empty-starter-project-and-trigger-its-first-build matches api.yaml:5228 under Deployment Creation. #auto-bump-to-developer matches the #### Auto-bump to Developer heading at custom-roles.mdx:69.
  • docs.json nav lists exactly the seven operations the spec defines, method and path verbatim, and remains valid JSON.
  • $ref targets exist: Policy (api.yaml:11033), PageInfo (api.yaml:10854).
  • The sample's tier is right. AIBIDevelop with SchemaRead is consistent with the auto-bump rule at custom-roles.mdx:131, which exempts only DeploymentRead and DownloadData.
  • The reserved-name divergence at custom-roles.mdx:217 matches the eight names in RoleCreateBody (api.yaml:11890), in both directions — the five the API adds, and None/All which it doesn't reserve.
  • restrictDataDownload / showRowTotals are pre-existing drift between the two repos, as you established on the earlier thread, not fields riding in on this branch.

Notes, no action asked

The --check gate can't run in CI because the spec lives in a private repo, which is why two unrelated fields swept in on a docs PR about roles. Nothing to do in this PR; the gap is real and worth its own issue.

No prior unresolved review threads — the eight rounds above are all resolved, so none of these four findings duplicates one.

· branch `pavel-claude/elegant-dirac-88avqw`

Comment thread docs-mintlify/api-reference/api.yaml
The page made the same point — a custom role's Base Role confers the tier
and no deployment access — in six places, most of them added by this PR.
docs-mintlify/CLAUDE.md says to say it once. The Base Role section keeps the
statement and the built-in comparison, now one paragraph instead of two; the
concept list stops at the tier, the Base Role actions section links back
instead of restating, and the two action rows say what the permission grants
without re-litigating where the built-in roles get it from.

Walkthrough 1 built an Org Viewer that could not export, weaker than the
built-in Viewer it is named after, with nothing at the point of decision
saying so. Offer Download data the way walkthrough 2 does — conditionally,
and free, since it does not trigger the auto-bump.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
"Sit at every tier" reads as the tier granting them, which is the misreading
the rest of the page exists to prevent — :48 and the Org Viewer walkthrough
both say the Base Role carries no deployment-scoped access. The property is
exemption from the auto-bump, so say that, and say the policy still has to
grant them.

Chat history's exemption and its caution were stated three times; the anchor
and the catalog row now carry one fact each — what the permission shows, and
where the auto-bump rule lives — and walkthrough 2 keeps the practical note.

Download data exports query results as CSV; exporting a dashboard as PNG or
PDF is the separate Dashboard Exports API, so walkthrough 1 no longer offers
it as "dashboards and results".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
Giving walkthrough 1 its chat and its export made the finished role identical
to the built-in Viewer — same tier, same scope, same three actions — on a page
that opens by framing custom roles as what you reach for when you need finer
control. Narrowing the step again would cost the role its chat, which is the
defect db7cb29 fixed, so name the outcome instead: it reproduces the built-in
Viewer, and the reason to write it as a custom role is what you change next.

The auto-bump lead-in also gave as its reason a restatement of its own claim,
and repeated the policy rule that the Base Role bullet already owns. The list
is the section's content; it needs neither.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
The step offers Download data conditionally, so "as written" had two
referents and the claim was false on the branch where a reader leaves it
off. Say which branch it describes — and since that branch is the page's own
first example of narrowing, make it the first way out rather than the
abstract "drop an action the built-in grants".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
@paveltiunov
paveltiunov force-pushed the pavel-claude/elegant-dirac-88avqw branch from 7fb0133 to 81332dc Compare September 22, 2026 18:11
@claude

claude Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 3m 26s —— View job


1 low — :56 offers Full access as the Developer-equivalent while calling the built-in Developer "nearly every action"

Review details
  • Gather context (this round touches only custom-roles.mdx; api.yaml, docs.json, introduction.mdx, extract-api.mjs unchanged since the last round)
  • Read custom-roles.mdx in full
  • Resolve stale threads / dedupe findings
  • Post findings

Finding

custom-roles.mdx:56 — the same sentence says the built-in Developer's policy carries "nearly every deployment action" and that Full access (All) is what a Developer-equivalent uses. :112 and :130 define Full access as every current and future deployment action, so the recommended role is strictly broader than the built-in it is matched to, and nothing on the page says so. Posted inline with two one-clause fixes.

Checked and not posted

  • :73 — "Check any other action" (was "any other one") no longer leans on the preceding "deployment-scoped"; a reader could take a Global permission as bumping the tier. Wording only, and the examples that follow are both deployment actions.
  • :153/:160 — the Org Viewer walkthrough now ends by saying the role it just built matches the built-in Viewer. Self-undercutting, but :160 redeems it by naming what you'd change from there, and it is a deliberate product-advice call rather than a defect.
  • Anchors #auto-bump-to-developer, #base-role, #global-permissions, #validation, #managing-roles-through-the-api all resolve; the four exempt actions at :73 agree with :153 and :174; the catalog at :278 no longer claims to be every grantable action.

Threads

1 prior thread of mine returned by the listing; 0 resolved, 1 re-affirmed (custom-roles.mdx:48 — the bullet's trailing clause still duplicates :56 and still hangs off an "It determines:" stem; unchanged in the current file, no reply refuting it). No overlap with this round's finding: different line, different root cause.

· branch `pavel-claude/elegant-dirac-88avqw`

Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
The built-in Developer's deployment policy is every deployment action
except Access chat history (`default-roles.ts` filters it out of
`actionsByResourceType[Deployment]`), while Full access (`All`) expands to
that list unfiltered. Offering Full access as the way to build "a
Developer-equivalent" therefore over-granted, silently. Name the exclusion
where the built-in is described and let the contrast fall out of it.

Also drops the Base Role bullet's trailing clause: the paragraph eight
lines below already says a custom role starts with no deployment access,
and says it with the supporting detail. "Grants no deployment-scoped
access" is also not something the Base Role determines, which is what the
list it sits in is enumerating.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
@claude

claude Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 4m 45s —— View job


Docs-only change, 3 low-severity findings — 1 claim to verify, 2 wording defects introduced this round

Review details
  • Read changed files
  • Review custom-roles.mdx prose for accuracy/contradictions
  • Check generated reference (api.yaml, docs.json, introduction.mdx) consistency
  • Resolve stale review threads / dedupe findings
  • Post findings

Findings (all inline)

# Location Concern
1 custom-roles.mdx:160 "Org Viewer reproduces the built-in Viewer — assigning that role does the same thing" asserts tier equivalence. Base Role Viewer emits AIBIView; the built-in Viewer role is viewerRole/AIBIViewer, and AIBIViewer is a separate member of the Policy.actions enum (api.yaml:11496). Needs one look at viewerRole's Global policy in default-roles.ts.
2 custom-roles.mdx:56 "including the data-model ones" attaches to the chat-history exception rather than to "every deployment action" three commas earlier; and "it takes chat history too" reads as as the built-in Developer does, which is the opposite of the contrast the preceding sentence sets up. Suggestion splits the chain per role.
3 custom-roles.mdx:153 Step 4 now grants Access AI agents and Download data, so the heading at :138 ("with read access to all deployments") no longer describes it — it was accurate when the step checked only Access deployment.

Checked and clean

  • docs.json parses (jq -e), and the seven Roles nav entries match the seven operations in api.yaml:4754-5044.
  • Every link reference resolves: list-custom-roles / create-a-custom-role match the operation summaries Mintlify slugifies, authentication.mdx exists, and the deployment-creation slug matches api.yaml:5504. Anchors #auto-bump-to-developer, #base-role, #global-permissions, #validation, #managing-roles-through-the-api all have headings.
  • Page ↔ spec agreement on the facts the two both state: the eight reserved built-in names (:216 vs api.yaml:12364), the four auto-bump exemptions (:73 vs api.yaml:4829), 409 on create and rename, 404 on a built-in id for GET/PUT/DELETE, null rejected for name/policies on update, and the Admin-sentinel 404 on assign.
  • TAG_ORDER places Roles with the other access-control tags (extract-api.mjs:229); unlisted tags would append A–Z, which is what the one-line change avoids.
  • Action catalog (:304-321) matches the builder's card (:114-128) — 13 granular actions plus All, no row on one side missing from the other.

Review threads

Listing returned 0 of my own threads (single page, hasNextPage: false) — none to resolve, none re-affirmed. All three findings above are new.

Not reviewed: the two pre-existing Databricks Metric View syncs drifts the PR body calls out, and the 200-alongside-204 generator fallback — both already agreed as out of scope and tracked as follow-ups.

· `pavel-claude/elegant-dirac-88avqw`

Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx
`viewerRole` carries three policies, not two: Global `AIBIView`, the three
deployment actions over every deployment, and an Agent policy with
`AgentRead`. The console's role builder writes only Global and deployment
policies (`policyAdapter.ts` drops every other resource type), so a custom
role cannot reproduce that third one and "assigning that role does the same
thing" was false. The claim now covers what was actually checked — the same
tier and the same deployment access — and the agent policy stays unmentioned
for the same reason `WorkbookManage` does: it is not something the builder
can express.

Also rewrites the built-ins paragraph so each role gets its own clause. In
one chain, "including the data-model ones" attached to Access chat history
rather than to "every deployment action" three commas earlier, and "it takes
chat history too" read as agreeing with the built-in Developer when the point
was the contrast.

And renames the first walkthrough's heading: it stopped being "read access"
when the step gained Access AI agents and Download data.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
@claude

claude Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 4m 26s —— View job


Review complete — 3 findings (1 medium, 2 low). No blockers.

Full review
  • Fetch base and read the diff
  • Read custom-roles.mdx in full
  • Check api.yaml / docs.json / extract-api.mjs consistency
  • Resolve stale threads, dedupe findings
  • Post review

Findings

Site Concern
Medium custom-roles.mdx:153 Access AI agents is presented as what delivers Analytics Chat, but f0da067's own message reports the built-in viewerRole also carries an Agent/AgentRead policy the builder cannot write. If that is the gate, the walkthrough produces a role without chat and :124 is wrong for every custom role. Checkable against console-server.
Low custom-roles.mdx:45 "Every custom role has exactly one Base Role" contradicts :263 — an API-created role can have zero. :20 and :67 are already scoped to the builder; this is the remaining absolute.
Low custom-roles.mdx:278 The builder-vs-API caveat covers actions but not resourceType. PolicyResourceType (api.yaml:11515) is ten values; :223 leaves a reader believing the wire format is Global + Deployment.

Checked and clean

  • All four link refs resolve: list-custom-roles / create-a-custom-role match the operation summaries at api.yaml:4778 / :4811, api-reference/authentication is in docs.json:738, and the deployment-creation slug matches the summary at api.yaml:5504.
  • docs.json:1002-1011 lists all seven roles operations, and Roles sits between User Groups and User Attributes in extract-api.mjs:229 — with the other access-control groups, as the PR body says.
  • api.yaml roles section is internally consistent with the page: the reserved-name list at :12364-12367 matches custom-roles.mdx:216; the four auto-bump exemptions at :4829 match :73; the Admin 404 at :5024 and :5042 matches :269; the RoleUpdateBody null semantics at :12393-12395 match :267.
  • The actions enum the catalog now points at is real — 53 values at api.yaml:11446-11502 — so :278's pointer is not a dead end.
  • The declared 200 alongside 204 on the three no-body operations (:4880/:4884, :4984/:4988, :5017/:5021) is the generator's fallback, already flagged upstream as a follow-up and not this PR's to fix.

Review threads

The listing returned 0 threads — no prior claude-authored threads on this PR, nothing to resolve, no duplicates possible. All three findings posted fresh.

· branch `pavel-claude/elegant-dirac-88avqw`

Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
"Every custom role has exactly one Base Role" is a claim about roles, and
the Warning further down says the opposite for a role created over the API —
one sent without a `Global` tier policy is accepted and has none. The two
neighbouring statements were already scoped to the builder; this one is now
too.

The action catalog's caveat covered one of the two dimensions the builder
narrows. `PolicyResourceType` has ten values and `policyAdapter.ts` writes
two of them, so a Report, Workbook, Agent or Folder policy is grantable over
the API with nothing on the page hinting it exists — and the wire-format
sentence above ("the Base Role is a Global policy… each deployment policy
card is one Deployment policy") reads as the whole format because it is the
only description of it the page gives.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
@claude

claude Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 3m 57s —— View job


Review complete — no blocking issues; 3 low (editorial) findings posted inline

Details
  • Gather context (diff vs origin/master, changed files)
  • Read custom-roles.mdx in full
  • Check api.yaml, docs.json, introduction.mdx, extract-api.mjs
  • Reconcile with prior review threads
  • Post findings

Scope of this round

The five newest commits (a49995eb3ec022) touch only custom-roles.mdx — the Base Role section, the auto-bump exemption paragraph, walkthrough 1, and the action-catalog lead-in. api.yaml, docs.json, introduction.mdx and extract-api.mjs are unchanged since the last round and were re-checked for consistency rather than re-reviewed.

Findings

Location Concern
low custom-roles.mdx:278 "wider in both directions" describes two ways the API is wider, not two directions — nothing narrows. And "agents" in the no-card list collides with AI → Access AI agents at :124, which the builder does render (DeploymentAgentRead is a Deployment action; the Agent resourceType is what has no card).
low custom-roles.mdx:48 a49995e cut the substantive half of this bullet; what remains restates bullet :47 and duplicates the table header at :50 ("What the tier licenses").
low custom-roles.mdx:160 "leave Download data off" is offered as a variation on the built-in Viewer, but :153 already presents it as optional — so it is not a change "from here".

Checks that came back clean

  • Internal consistency of the newly-rewritten claims. :56 (built-in Viewer/Explorer carry DeploymentRead, DeploymentAgentRead, DownloadData; Developer carries every deployment action bar chat history) agrees with :73's four auto-bump exemptions, with walkthrough 1's equivalence claim at :160, and with the action catalog at :309-321.
  • :56 on Full access — "unlike the built-in Developer it takes chat history as well" is consistent with :130 and with All in the deployment-action table.
  • Anchors and link refs. #base-role, #global-permissions, #auto-bump-to-developer, #managing-roles-through-the-api, #validation all resolve in-file; /api-reference/authentication exists; roles-and-permissions.mdx:31 provides #restricting-data-downloads. All four [ref-api-*] definitions at :271-274 are file-scoped and reachable from their uses at :216 and :278.
  • Nav ordering. docs.json:1002 places Roles after Users Admin, which matches the TAG_ORDER edit at extract-api.mjs:229Groups and User Groups have no groups in docs.json, so nothing sorts between them.
  • api.yaml cross-check. Policy (:11444) carries both the actions and resourceType enums that :278 points a reader at, so that pointer lands. The reserved-name list at :216 matches RoleCreateBody.name (:12364-12367); the 404-on-all-three claim at :267 matches the declared responses on GET/PUT/DELETE /api/v1/roles/{roleId}; the Admin-404 claim at :269 matches assignRoleToUser's 404 description at :5024.
  • Claims about console-server internals (policyAdapter.ts, default-roles.ts, RolesService) are not verifiable from this repo — they were checked for self-consistency across the page and the spec only.

Review threads

gh list-review-threads cube-js cube 11894 returned 0 of my own threads (empty nodes, hasNextPage: false) — every earlier thread is already resolved. Nothing to resolve, nothing to re-affirm, and the duplicate check cleared all three findings above.

· branch [`pavel-claude/elegant-dirac-88avqw`](https://github.com/cube-js/cube/tree/pavel-claude/elegant-dirac-88avqw)

Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
Comment thread docs-mintlify/admin/users-and-permissions/custom-roles.mdx Outdated
- The Base Role's second bullet had nothing left after a49995e took its
  substantive half: its subject repeated the table header two lines below
  and its gloss repeated the concept list at the top of the page. With one
  bullet remaining, the list became a sentence.
- "Wider in both directions" says one of them narrows; neither does. And
  "agents" collided with the **Access AI agents** deployment action the
  builder does render — what has no card is the `Agent` resourceType, so
  the list now names the enum values.
- "Leave Download data off" was offered as a departure from what the
  walkthrough produces, but the step already presents that action as
  conditional, so it is one of the walkthrough's own paths. Dropped; the
  two genuine departures stay.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014vmXD5G9wKFi5cV6Vn6xkg
@claude

claude Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Claude finished @paveltiunov's task in 3m 52s —— View job


Approve — no blocking findings (0 high, 0 medium, 2 non-blocking notes)

Review detail
  • Gather context (combined diff vs origin/master, changed files)
  • Read custom-roles.mdx in full; cross-check every claim against api.yaml
  • Check docs.json, introduction.mdx, extract-api.mjs
  • Resolve stale threads / dedupe findings
  • Post review

What I checked

Docs-only change. I verified the page against the generated reference rather than reading the two independently:

Claim on the page Reference
custom-roles.mdx:213 — API reserves every built-in role name, not None/All api.yaml RoleCreateBody.name names the same eight
:247 deployment ids checked for shape, not existence api.yaml:4866-4869
:249 400 on a policy with no actions / no resources api.yaml:4805-4808
:249 tier is not checked against actions api.yaml:4854-4861
:251, :264 409 on create and on rename api.yaml:4809, :4954
:264 built-in id 404s on GET/PUT/DELETE api.yaml:4887, :4915, :4953
:266 assignment resolves built-ins, Admin 404s api.yaml:5023-5026, :5040-5043
:275 action and resourceType enums are on POST /api/v1/roles Policy.actions (53 values) and PolicyResourceType at api.yaml:11444, :11515Report, Workbook, Agent, ChatThread all present
:279-318 action catalog every internal name in the three tables is in the Policy.actions enum

Also consistent: the four exempt actions at :70 match the list in api.yaml:4829; walkthrough 1's three actions (:150) match the built-in Viewer set stated at :53, which is what :157 then claims; walkthrough 2 (:171) recommends only exempt actions, so the Explorer tier it is for survives. Anchors #validation, #auto-bump-to-developer, #base-role, #global-permissions, #managing-roles-through-the-api all resolve; [ref-api-auth]api-reference/authentication.mdx exists; the Roles nav group in docs.json:1002 and the intro table row sit where TAG_ORDER puts them.

The restrictDataDownload / showRowTotals drift described in the PR body is no longer in the diff — api.yaml now carries roles paths and schemas only. The PR body paragraph about it is stale, which costs nothing.

Two non-blocking notes, neither new

Both were raised and deliberately deferred earlier in the thread, and neither is tracked by an open thread now. Recording them so they don't evaporate:

  1. Policy.actions and Policy.resources (api.yaml:11446, :11506) carry no minItems: 1, so {"resourceType": "Deployment", "actions": [], "resources": []} validates against the published schema and then 400s against the service — invisible to the Try-it panel and to generated clients. The fix is a request-only policy schema, since Policy is shared with Role.policies and RoleWithAccess where an empty array is a legitimate response.
  2. delete, assign and unassign declare both 200 and 204 (api.yaml:4880/4884, 4984/4988, 5017/5021). The 200 is the generator's no-declared-response fallback; suppressing it means changing the generator, which would rewrite seven already-released operations.

Review threads

gh list-review-threads cube-js cube 11894 returned 0 unresolved threads — none of mine, none human-opened. Nothing to resolve, nothing to re-affirm.

· branch `pavel-claude/elegant-dirac-88avqw`

This branch was successfully deployed

1 active deployment
staging - docs-mintlify f5c02576 Deployed Sep 22, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Issues that require a documentation improvement javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants