Skip to content

docs(approvals): name Set Manager and the admin endpoints as the in-product writers of sys_user.manager_id - #22681

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-22662-capabilities-set-manager
Oct 10, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-22662-capabilities-set-manager

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #22662
Clause-②: no

Docs only. The Approvals capabilities overview told readers that no Console field, data-API write or auth admin endpoint sets sys_user.manager_id. The product has had two in-product writers for a while: the Set Manager row action on Setup → Users (set_user_manager, packages/platform-objects/src/identity/sys-user.object.ts) and POST /api/v1/auth/admin/set-user-manager (packages/plugins/plugin-auth/src/admin-set-user-manager.ts). The family grep that triage asked for found one more false sentence of the same kind, on the automation guide. Both are corrected here.

What changed

content/docs/capabilities/approvals.mdx (the card's sentence, warn callout at :14–:24):

  • The callout now names the in-product way to fill the column: a platform admin uses Setup → Users → ⋯ → Set Manager, which calls POST /api/v1/auth/admin/set-user-manager.
    • Who can use it was read from the code, not from the card. The endpoint runs the platform-admin gate (gateAdmin at the mount in plugin-auth/src/auth-plugin.ts). The action is shown only when current_user.isPlatformAdmin == true and is hidden on an idp_provisioned identity.
  • Provisioning stays the bulk path. The admin bulk-import endpoint reads a manager_id column. A seed, or a SCIM / directory-sync path the deployment supplies, can also write it.
  • The "request waits" clause is kept, reworded to match the runtime on main. A manager-only step resolves to nobody, and the node's onEmptyApprovers policy decides what happens. The default, admin_rescue, opens the request and leaves it waiting for an administrator. This is the same reading as automation/approvals.mdx after PR docs(approvals): an entry that resolves to nobody leaves a slot per its kind, and an empty or literal-only slate goes to onEmptyApprovers #22657.
  • The style-list entry on line 12 changes from "needs a provisioned reporting chain" to "needs each user's manager set", because provisioning is no longer the only way to fill the column.
  • The link to Automation → Approvals for the details is unchanged.

content/docs/automation/approvals.mdx (the manager callout, the second family hit, added to the surface):

  • It said "its admin bulk import does not write it either". That is false on main. Since d438b3a9aa (PR feat(plugin-auth): the bulk import admits manager_id, resolved in a second pass through the admin write surface's own refusals #18046), plugin-auth/src/admin-import-users.ts admits a manager_id column:
    • The cell is the manager's email address, or a phone number where the phoneNumber plugin is wired (resolveManagerKey).
    • The column is stripped before the row write and linked in a second pass after runImport returns.
    • The links go through the same applyUserManagerLink derivation the endpoint runs.
    • Each outcome is reported on rows[].manager. The row's user is created either way.
  • The clause is replaced by a paragraph saying what the import does. The SCIM sentence is kept, because the SCIM manager attribute is still not projected onto the column. The v17.5 release notes (content/docs/releases/v17/17-5.mdx:1318) already list the import's manager_id column.
  • This is the in-place family-fix exemption: the same defect class (a docs sentence denying that a product surface writes manager_id), a mechanical correction whose form is set by the code, and the same docs gate family. The claim's file surface already allows "any other hand-written content/docs/** page that the family grep finds".

Family grep (triage 6096320437 close-out)

Roots: content/docs/**, packages/spec/src/** (describes), skills/**. Each instrument ran on the base ee3ae0360d and again on this head.

Instrument 1: every mention of the column or the chain, read line by line, not filtered by claim wording.

git grep -n -i -E "manager_id|reporting chain|reporting line|manager chain|org chart|submitter's (direct )?manager|type: ?'manager'|direct manager|set-user-manager|set manager" REV -- 'content/docs/**' 'packages/spec/src/**' 'skills/**'
  • base ee3ae0360d: 61 lines in 27 files. Head: 65 lines in 27 files, the 4 new lines being this PR's own text.
  • Positive control: set-user-manager hits content/docs/automation/approvals.mdx once on both trees.
  • I read every hit. The claim-bearing ones were content/docs/capabilities/approvals.mdx:12 and :17–:20 (the card). Every other hit is a schema table, a scope table, a query example, an org-chart example, or content/docs/references/** / content/docs/releases/** (generated or release-owned, and not edited).

Instrument 2: the claim phrasings, including ones that span lines or do not name the column. Each hit was kept only if "manager" appears within six lines of it.

no console field|no product surface|no product write|nothing in the product|inside the product|provisioning fills|your own provisioning|only a seed|nothing sets|nothing writes|never set by|no (ui|console|admin|api) (field|endpoint|surface)|no .{0,40}endpoint sets|sets that column|does not write it|doesn't write it|no write surface|reporting chain you provide|chain you provide|deployment supplies|directory-sync|directory sync|scim
  • Base: hits next to "manager" were capabilities/approvals.mdx:15–:19 (the card) and automation/approvals.mdx:94–:96 (the bulk-import clause above). The other hits:
    • references/identity/scim.mdx: generated, a schema heading.
    • releases/v17/17-5.mdx:1321: release-owned, and correct.
    • packages/spec/src/automation/approval.zod.ts:86: a code comment recording that the describe was already corrected.
    • packages/spec/src/migrations/registry.ts:1045: an unrelated global_nav sentence.
    • packages/spec/src/identity/scim.zod.ts: the schema itself.
  • Head: the old phrase "no Console field, data-API" has 0 hits, and "bulk import does not" has 0 hits anywhere under the three roots. The remaining automation/approvals.mdx "deployment supplies" hit is the SCIM sentence, which is true.
  • Positive control: on the base the instrument finds the card's own sentence (no console field at capabilities/approvals.mdx:17).

Hits outside this PR's file surface (named, not edited):

  • packages/spec/src/**: no hit of the claim. ApproverType.describe() (approval.zod.ts:98–:105) only points at the routes os lint names and says nothing about which surfaces write the column, so it is not a hit. It does inherit the os lint text, which is stale; see the next point.
  • skills/**: no hit. skills/objectstack-automation/references/state-machines-and-approvals.md:231 is a table row ("The submitter's manager (sys_user.manager_id)") that makes no claim about writers.
  • Outside the three roots, one runtime string carries the same false clause:
    • Where: MANAGER_ONLY_ROUTES in packages/lint/src/validate-approval-approvers.ts:199, the os lint remedy for approval-approvers-may-resolve-empty. It says "its admin bulk import does not write it either".
    • The test pins it: packages/lint/src/validate-approval-approvers.test.ts:313 expects exactly that wording.
    • Measured on the built @objectstack/lint dist, resolved from packages/cli: a manager-only approval slate gives one info finding whose hint contains that clause.
    • It is a runtime change, so it is outside this card's surface and is routed to the seat. Until it lands, the automation guide's "os lint … carries the same remedy text" is one clause ahead of the lint string. The guide's clause is the true one.

Acceptance notes

  • The Console's user-import wizard does not offer manager_id as a target column. objectui 023f00d, packages/app-shell/src/views/IdentityImportPanels.tsx, offers email, phone_number, name and role. Both pages therefore name the bulk-import endpoint and never the Console's Import button.
  • content/docs/permissions/authentication.mdx § Bulk Import Users does not document the manager_id column, and its upsert sentence lists the columns an update touches without it. Noted only.
  • The capabilities page says "the submitter's direct manager", while the runtime resolves the manager of the record's owner, or of the user a value-named field holds (approval-service.ts, type === 'manager' branch). The wording predates this PR and is unchanged here. Noted only.
  • The code comments in auth-plugin.ts:2614–2618 and admin-set-user-manager.ts:20 still say the bulk import does not carry the column. They describe the tree at the time each was written. They are not published text, and are noted only.

Verification

All readings are on head 992302698c.

  • Gate set: derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, with no paths. The change set is 2 paths against merge base ee3ae0360. The derivation gave 40 commands.
  • Builds: the dist-reading gates need pnpm exec turbo run build --filter='@objectstack/lint...' --filter='@objectstack/client-react...' --concurrency=2, run under os-verify-lock.sh. Result: 35/35 tasks, VERDICT command-exit 0.
  • Runs: all 40 commands ran in this worktree with $? captured before any pipe, and all 40 exited 0. Selected verdict lines:
    • check:doc-anchors: "480 internal #fragment link(s) across 417 source file(s) all resolve to a real heading".
    • check:doc-authoring: "53 published skill files clean".
    • @objectstack/spec check:docs: "225 generated files in sync with packages/spec".
    • @objectstack/spec check:skill-examples: "262 prose examples type-check across 3 surface(s)".
    • @objectstack/lint check:doc-security-posture: "28 ObjectSchema.create example(s) … carry an os validate-clean security posture".
    • check:nul-bytes: "OK (scanned 10660 text file(s) …)".
    • check:role-word: exit 0.
  • Reconciliation: --ran with COMMAND :: exit CODE records gives "40 derived famil(ies) accounted for — 40 run, 0 NOT-MEASURED (a DERIVED zero — all 40 recorded an exit code and none of them is 3)".
  • Not measured locally (left to CI): the CI jobs the derivation lists outside its 40 commands: Build Docs, Test Core shards, the type-check lanes, and the 53 artifact-roster families. No package source changed.
  • Changeset: none. The diff is content/docs/** only, which publishes nothing (skip-changeset).

Generated by Claude Code

…roduct writers of sys_user.manager_id

The capabilities overview said no Console field, data-API write or auth admin
endpoint sets the column; the Set Manager row action and
POST /api/v1/auth/admin/set-user-manager do, and the admin bulk import reads a
manager_id column. The callout now names them, keeps provisioning as the bulk
path, and states the unset case the way the runtime decides it: the node's
onEmptyApprovers policy, by default admin_rescue.

The automation guide's manager callout said the admin bulk import does not
write the column; it does, through the same refusals as the endpoint, so that
clause is replaced by what the import does.

Claude-Session: https://claude.ai/code/session_01Q7Fy4uVkvBWgj9CLihdATJ
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 10, 2026
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Oct 10, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 10, 2026 13:16
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 10, 2026 13:16
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 10, 2026
Merged via the queue into main with commit 5cea006 Oct 10, 2026
38 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-22662-capabilities-set-manager branch October 10, 2026 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants