You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Noticed while completing the ISecurityService contract test for #7831 (PR #8139) — recorded, not fixed, and deliberately kept outside that PR's two-file scope. Filed unassigned.
The observation
packages/client/src/index.ts declares 32 methods returning Promise< any >, on a package that already depends on @objectstack/spec ("@objectstack/spec": "workspace:*" in its dependencies) — so the precise contract types are reachable, and the any is not forced by a decoupling constraint.
The worked example that surfaced it, security.describeDelegableScope:
Its own TSDoc, immediately above, names placeableBusinessUnitIds, assignablePositions, the adminScopes they derive from, and isTenantAdmin: true — that is, the comment describes exactly the shape DelegableScope already declares in packages/spec/src/contracts/security-service.ts, and that the route really returns. The type is written, published and reachable, then dropped at the SDK boundary.
Why it may be worth grading
packages/client*/** is the "Public API, DX, type safety" lane in AGENTS.md's Context Routing table, and it is the surface customer projects actually hold.
It is the check:exported-any shape one layer out. That gate exists in packages/spec precisely because the api-surface snapshot records that an export exists, never what it resolves to; the client has no equivalent gate, and 32 of its methods currently resolve to any.
I did not measure whether each of the 32 has a precise spec type available — only that describeDelegableScope does. The count is therefore not a severity claim: some are likely genuinely open shapes (the contract deliberately types AudienceBindingSuggestion as Record< string, unknown >, for one), and separating those from the real gaps is exactly what a triage round is for.
Noticed while completing the
ISecurityServicecontract test for #7831 (PR #8139) — recorded, not fixed, and deliberately kept outside that PR's two-file scope. Filed unassigned.The observation
packages/client/src/index.tsdeclares 32 methods returningPromise< any >, on a package that already depends on@objectstack/spec("@objectstack/spec": "workspace:*"in itsdependencies) — so the precise contract types are reachable, and theanyis not forced by a decoupling constraint.The worked example that surfaced it,
security.describeDelegableScope:Its own TSDoc, immediately above, names
placeableBusinessUnitIds,assignablePositions, theadminScopes they derive from, andisTenantAdmin: true— that is, the comment describes exactly the shapeDelegableScopealready declares inpackages/spec/src/contracts/security-service.ts, and that the route really returns. The type is written, published and reachable, then dropped at the SDK boundary.Why it may be worth grading
packages/client*/**is the "Public API, DX, type safety" lane in AGENTS.md's Context Routing table, and it is the surface customer projects actually hold.check:exported-anyshape one layer out. That gate exists inpackages/specprecisely because theapi-surfacesnapshot records that an export exists, never what it resolves to; the client has no equivalent gate, and 32 of its methods currently resolve toany.statusunion by hand, and it is missingexpired(same divergence family as #7726) #7781 (the client SDK hand-typing an invitationstatusunion that spec already declared, then drifting from it). That one was a hand-copy that rotted; this is the other half — no type at all.Explicitly NOT claimed
I did not measure whether each of the 32 has a precise spec type available — only that
describeDelegableScopedoes. The count is therefore not a severity claim: some are likely genuinely open shapes (the contract deliberately typesAudienceBindingSuggestionasRecord< string, unknown >, for one), and separating those from the real gaps is exactly what a triage round is for.Related: #7831, PR #8139, #7781.