Skip to content

Commit 105907b

Browse files
committed
update
1 parent a9c5c8f commit 105907b

100 files changed

Lines changed: 52163 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agent/naming-audit/_SUMMARY.md

Lines changed: 906 additions & 0 deletions
Large diffs are not rendered by default.

.agent/naming-audit/abacpolicies.md

Lines changed: 272 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Naming Audit: accountaccesscontrol
2+
3+
**Path:** `packages/accountaccesscontrol/src/v1/`
4+
**Versions audited:** v1
5+
**Inferred domain:** Account-level Databricks IAM rule sets — list assignable roles for a resource and read/replace the grant rules attached to that resource.
6+
**Total weird names flagged:** 19
7+
8+
## Summary
9+
| Severity | Count |
10+
| --- | --- |
11+
| High | 4 |
12+
| Medium | 7 |
13+
| Low | 5 |
14+
| Observation | 3 |
15+
16+
## High severity
17+
18+
### 1. `Role``src/v1/model.ts:68`
19+
- **Why weird:** A top-level type called `Role` that contains nothing but a single `name?: string` field. The name implies a rich role definition (permissions, scope, description), but the type is just a string wrapper around a role identifier path such as `roles/account.admin`. At call site `Role[]` reads like an array of role objects, yet it carries no role semantics — only one name string each. The type is also unqualified (the package already speaks of "rules", "grants", "principals", "rule sets" — `Role` here means "grantable-role reference for an access-control rule set", not anything broader).
20+
- **Category:** 1, 11 (vague/generic type; trivial wrapper)
21+
- **Suggested name:** `AssignableRole` (and inline the `name` field on `GetAssignableRolesForResourceResponse` as `roleNames: string[]` if no other fields are ever added).
22+
- **Rationale:** This type only ever appears in `GetAssignableRolesForResourceResponse.roles`. Either elevate it to a more meaningful type (`AssignableRole`) or eliminate the wrapper. As-is, `Role` is a confusing top-level export because it does not represent a role — it represents a role *reference*.
23+
24+
### 2. `RuleSet` vs `RuleSetUpdateRequest` (duplicate body shape) — `src/v1/model.ts:73,89`
25+
- **Why weird:** `RuleSet` and `RuleSetUpdateRequest` are structurally identical (`name`, `etag`, `grantRules`). They model the same resource — one as a response body, one as the update body — but expose it under two top-level names. `UpdateRuleSetRequest` then *wraps* `RuleSetUpdateRequest` under a `ruleSet` field, so the developer sees three overlapping shapes (`RuleSet`, `RuleSetUpdateRequest`, `UpdateRuleSetRequest`) for one concept. The "Request" suffix on the inner body type does not match how the field is used downstream (the wire payload is keyed `rule_set`, not `rule_set_update_request`).
26+
- **Category:** 12, 11 (duplicate concepts; redundant wrapper)
27+
- **Suggested name:** Collapse to `RuleSet` only. The update endpoint body should be `{ name, ruleSet: RuleSet }`. Remove `RuleSetUpdateRequest` entirely.
28+
- **Rationale:** A single canonical `RuleSet` shape avoids the read/write divergence. The legacy upstream uses `RuleSetResponse` and `RuleSetUpdateRequest` as separate types because Go does not have structural typing; in TypeScript the duplication is wasteful and confusing.
29+
30+
### 3. `UpdateRuleSetRequest.ruleSet` vs `UpdateRuleSetRequest.name` overlap — `src/v1/model.ts:105`
31+
- **Why weird:** `UpdateRuleSetRequest` has both a top-level `name` and `ruleSet.name` (because `RuleSetUpdateRequest` also carries `name`). Two `name` fields on the same request that conceptually identify the same thing is a footgun — which one wins? The wire format hints that the outer one is the URL path identifier and the inner one is the body, but nothing in the TS type encodes that.
32+
- **Category:** 6, 16 (misleading; field contradicting type domain)
33+
- **Suggested name:** Drop the outer `name` (use it from `ruleSet.name`), or rename the outer to `pathName`/`resourceName` to make the routing role explicit.
34+
- **Rationale:** The doc comment on the outer field is just "Name of the rule set." — identical to the inner one. Developers will set one and not the other and silently 4xx.
35+
36+
### 4. `GetRuleSetRequest.etag` semantics — `src/v1/model.ts:25`
37+
- **Why weird:** A `GET` request type carrying an `etag` is unusual — `etag` normally rides in headers (`If-Match`/`If-None-Match`) and the field doc describes optimistic concurrency control on PUT, not GET. The field is also marshalled into the query string here (`params.append('etag', req.etag)` in `client.ts:118`), which is non-standard HTTP and easy to misuse. The name `etag` is also lowercase, contradicting common practice (`eTag`/`ETag`). The same doc text on `RuleSet.etag` then describes its read use ("freshness").
38+
- **Category:** 3, 6 (acronym casing; misleading)
39+
- **Suggested name:** `minimumEtag` or `ifNoneMatch` would explain semantics; keep canonical casing as `etag` only if it matches the wire param exactly. At minimum, the doc should say "passed as `?etag=` query parameter; the server returns a snapshot at least as fresh as this etag" rather than copy-pasting the PUT-side concurrency doc.
40+
- **Rationale:** The current name plus copy-pasted comment makes the field look like an `If-Match` header even though it is a freshness floor on GET.
41+
42+
## Medium severity
43+
44+
### 5. `accountId` doc string `<Databricks> account ID.``src/v1/model.ts:7,27,107`
45+
- **Why weird:** The literal `<Databricks>` tag appears in the doc comments, leaking the upstream protobuf templating markup into the public TypeScript surface. It is not Markdown, not a link, and not HTML — just stray angle brackets that will render oddly in IDE hover popups and TypeDoc. The same `accountId` doc text also doesn't disclose that this value is a fallback overridable by `ClientOptions.accountId` (per the client comment on line 41-42 of `client.ts`).
46+
- **Category:** 14, 19 (Go/Java-style template leak; underspecified ID)
47+
- **Suggested name:** Keep `accountId` but rewrite the doc as `"Databricks account ID. If omitted, falls back to the value supplied to ClientOptions."`
48+
- **Rationale:** Document the type — UUID? — and remove the templating artifact.
49+
50+
### 6. `GrantRule.role` is a string, not a `Role``src/v1/model.ts:65`
51+
- **Why weird:** The package exports a `Role` type and then immediately ignores it: `GrantRule.role` is `string`. So `Role` is the response shape from `getAssignableRolesForResource`, but `GrantRule.role` is the same identifier path serialized inline. Two representations of the same concept.
52+
- **Category:** 12, 6 (duplicate concepts; misleading)
53+
- **Suggested name:** Either type `GrantRule.role` as `Role['name']` / a branded `RoleName` string, or drop the `Role` wrapper and use `string[]` for `GetAssignableRolesForResourceResponse.roles`. Consistency in either direction.
54+
- **Rationale:** Developers will write `grantRule.role = role.name` constantly because the types don't line up.
55+
56+
### 7. `GetAssignableRolesForResourceRequest` / `Response` verbosity — `src/v1/model.ts:5,21`
57+
- **Why weird:** 41 characters each. The "ForResource" suffix is implied — every assignable-roles query is for a resource (the resource is the only meaningful query param). The pair reads like a Java RPC service name (`Get<Subject>For<Object>Request`).
58+
- **Category:** 7, 17 (overly verbose; inconsistent verb)
59+
- **Suggested name:** `ListAssignableRolesRequest` / `ListAssignableRolesResponse`. Reflects that the operation returns a list (it already does), and aligns with REST list conventions.
60+
- **Rationale:** Symmetry with `GetRuleSet`/`UpdateRuleSet` would suggest `Get...`, but the operation returns an array and is closer to a list semantically. Also: the corresponding method is named `getAssignableRolesForResource`, which has the same problem — `listAssignableRoles` would be cleaner.
61+
62+
### 8. `getAssignableRolesForResource` method verb mismatch — `src/v1/client.ts:72`
63+
- **Why weird:** The other two methods (`getRuleSet`, `updateRuleSet`) read as `<verb><Resource>`; this one is `<verb><Plural><For><Other>`. The "ForResource" is redundant — the method already takes a `resource` field. Inconsistent action verb shape across the same service surface (also category 17, since the operation is really a `list`).
64+
- **Category:** 7, 17 (verbose; verb inconsistency)
65+
- **Suggested name:** `listAssignableRoles(req)`.
66+
- **Rationale:** Three-method surface reads better as `getRuleSet`, `updateRuleSet`, `listAssignableRoles`.
67+
68+
### 9. `GrantRule.principals: string[]``src/v1/model.ts:63`
69+
- **Why weird:** Generic `string[]` for principals, where each entry is one of three formats (`users/<USERNAME>`, `groups/<GROUP_NAME>`, `servicePrincipals/<SERVICE_PRINCIPAL_APPLICATION_ID>`). The shape is documented in the JSDoc but not in the type. Callers have to read the comment to know what to put in.
70+
- **Category:** 15, 19 (generic field losing meaning; underspecified ID)
71+
- **Suggested name:** Type the field with a discriminated union or template literal — e.g. `principals: PrincipalRef[]` where `type PrincipalRef = \`users/${string}\` | \`groups/${string}\` | \`servicePrincipals/${string}\``.
72+
- **Rationale:** TypeScript can encode this; the Go SDK cannot. The 1:1 port leaves type information on the floor.
73+
74+
### 10. `RuleSet.name` and `GrantRule.role` are both `name` paths — `src/v1/model.ts:75,65`
75+
- **Why weird:** "Name" in this API is a hierarchical resource path (`accounts/<ACCOUNT_ID>/ruleSets/default`), not a human-readable label. Same overload for `role` (`roles/account.admin`). Calling these `name`/`role` and typing them as `string` hides that they are resource paths.
76+
- **Category:** 15, 16 (generic field; field contradicting domain)
77+
- **Suggested name:** `ruleSet.resourceName`, `grantRule.roleName` (or branded template-literal types). At minimum the JSDoc should explicitly say "resource path".
78+
- **Rationale:** Half of all integration bugs in this API will be wrong-format names. The type system can help.
79+
80+
### 11. `grantRules` plural inside `RuleSet` vs `GrantRule` (singular type, plural field) — `src/v1/model.ts:86`
81+
- **Why weird:** Not wrong, but worth noting: `RuleSet.grantRules: GrantRule[]` is fine; however the wire form uses `grant_rules` and the doc comment on `RuleSet` does not mention `grantRules` at all. The single-rule case is also confusing: a `RuleSet` is a *set of* `GrantRule`s, but a `GrantRule` itself binds N principals to 1 role — so a "rule" is many-to-one.
82+
- **Category:** 9, 6 (singular/plural; misleading)
83+
- **Suggested name:** Keep `grantRules`, but document explicitly that one rule = N principals × 1 role, and a rule set = N rules. Consider `roleGrants: GrantRule[]` as the field name — closer to industry vocabulary (IAM role grants).
84+
- **Rationale:** Improves discoverability.
85+
86+
## Low severity
87+
88+
### 12. `etag` casing — `src/v1/model.ts:51,85,101`
89+
- **Why weird:** Lowercase `etag` (rather than `eTag`/`ETag`/`etag`). HTTP spec uses `ETag`. JavaScript ecosystem split is roughly even, but most TS SDKs (AWS, Azure, GitHub Octokit) use `etag` lowercase, so this is *probably* fine. Flag it for consistency review only.
90+
- **Category:** 3 (acronym casing)
91+
- **Suggested name:** Confirm the project-wide policy. If the codebase uses `eTag` elsewhere, align here.
92+
- **Rationale:** Defer to global policy.
93+
94+
### 13. `accountId` vs `account_id` snake-case duality — `src/v1/model.ts:7`
95+
- **Why weird:** The TS interface uses `accountId`, but the marshal/unmarshal transforms (line 181) convert to `account_id`. This is intentional and standard for a generated SDK; flagging only because it means the public surface is camelCase but logs and wire bodies are snake_case. Nothing to do.
96+
- **Category:** 14 (Go/Java-style name parallel)
97+
- **Suggested name:** None — this is correct.
98+
- **Rationale:** Documenting the convention.
99+
100+
### 14. `GetRuleSetRequest.name` ambiguity with `RuleSet.name``src/v1/model.ts:38`
101+
- **Why weird:** A request type and a response type both have a `name` field with subtly different semantics: the request `name` is the *lookup key* the caller supplies; the response `name` is the *canonical name* the server returns. Same word, two roles. Common pattern, but worth flagging.
102+
- **Category:** 1 (vague)
103+
- **Suggested name:** Acceptable, but consider `GetRuleSetRequest.resourceName` for clarity.
104+
- **Rationale:** Minor readability win.
105+
106+
### 15. `flattenQueryParams` is exported but unused — `src/v1/utils.ts:123`
107+
- **Why weird:** This helper is `export`ed from `utils.ts`. It is not used by `client.ts` and is not re-exported from `index.ts`. Either it is dead code or the export modifier is wrong.
108+
- **Category:** 11 (effectively trivial / dead)
109+
- **Suggested name:** Drop the `export` keyword if internal-only; if it is meant for other generated clients, move it to a shared core package.
110+
- **Rationale:** Hygiene.
111+
112+
### 16. `HttpCallOptions` shadows `CallOptions``src/v1/utils.ts:15`
113+
- **Why weird:** The package imports `CallOptions` from `@databricks/sdk-options/call` and defines its own `HttpCallOptions` here. The names suggest the latter is a subtype/extension of the former, but they actually describe different concerns — `CallOptions` is retry/signal/timeout policy; `HttpCallOptions` is request + client + logger bundle. The naming makes them look related.
114+
- **Category:** 1 (vague/generic)
115+
- **Suggested name:** `HttpExecutionContext` or `HttpCallContext`.
116+
- **Rationale:** Disambiguates from the public `CallOptions`.
117+
118+
## Observations
119+
120+
### O1. `Client` is the only exported class — `src/v1/client.ts:39`
121+
- The class is just `Client`. With `import { Client } from '@databricks/sdk-accountaccesscontrol/v1'` the consumer sees a bare `Client` symbol. This is consistent across all generated packages, so it is a project-wide pattern, but it makes IDE autocomplete and stack traces ambiguous when multiple service clients are imported in the same file (everyone is `Client`). Common workarounds (`import { Client as AccountAccessControlClient }`) push the rename burden onto the user. Worth flagging at the project level.
122+
123+
### O2. `executeCall` / `executeHttpCall` naming — `src/v1/utils.ts:26,65`
124+
- Two functions with overlapping names. `executeCall` is the public-CallOptions translator; `executeHttpCall` is the wire-level request executor. The names do not signal that `executeCall` wraps the `Call` callback (which itself wraps `executeHttpCall`). Could be `applyCallOptions` and `sendHttpRequest` respectively. Generated code; flag for upstream.
125+
126+
### O3. `parseResponse` / `marshalRequest` asymmetry — `src/v1/utils.ts:113,119`
127+
- The pair are conceptual inverses (decode wire → typed; encode typed → wire) but use different verbs. `parseResponse`/`serializeRequest` or `unmarshalResponse`/`marshalRequest` would pair better. Generated code.
128+
129+
## Domain glossary
130+
- `accountId` — Databricks account UUID (the top-level tenant container, distinct from a workspace).
131+
- `etag` — HTTP entity tag used here both as a freshness floor on GET and as an optimistic concurrency token on PUT.
132+
- `iam` — Identity and Access Management; the broader Databricks IAM surface this package is a subset of.
133+
- `principal` — User, service principal, or group — the subject of an access rule.
134+
- `Role` — Reference to a grantable account-level role (e.g. `roles/account.admin`).
135+
- `RuleSet` — A versioned collection of `GrantRule`s attached to a resource.
136+
- `GrantRule` — A binding of N principals to 1 role within a `RuleSet`.
137+
- `SP_ID` / `SERVICE_PRINCIPAL_APPLICATION_ID` — Service principal application ID (UUID).
138+
- `resource` — Hierarchical name identifying what the rule set or roles list applies to (account, group, service principal, or tag policy).
139+
140+
## File coverage
141+
- `src/v1/model.ts` (185 lines): read fully.
142+
- `src/v1/client.ts` (171 lines): read fully.
143+
- `src/v1/utils.ts` (151 lines): read fully.
144+
- `src/v1/index.ts` (17 lines): read fully.
145+
- `package.json` (41 lines): read for context.

0 commit comments

Comments
 (0)