Repository navigation
fix(lint): the approval-approvers-may-resolve-empty remedy names the admin bulk import's manager_id column - #22703
Conversation
…admin bulk import's manager_id column instead of saying it writes nothing (#22683) The hint on a manager-only approver slate said "its admin bulk import does not write it either". The import has admitted a manager_id column since the second pass landed: the cell holds the manager's identity key and the link is applied once every row exists, through the same derivation as set-user-manager. The hint now names that column among the routes that work here, beside Set Manager and the endpoint, and the pin asserts the corrected wording and its placement. Claude-Session: https://claude.ai/code/session_01S3aAf11JjbW1mSGL1EhfFj Co-authored-by: Claude <noreply@anthropic.com>
… clause, not the family grep's phrase The pin asserting that the hint no longer says the import does not write the column spelled the old phrase as a regex literal, so the family grep for that phrase matched the pin itself. It now matches the clause's tail, which the new hint never contains. Claude-Session: https://claude.ai/code/session_01S3aAf11JjbW1mSGL1EhfFj Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 3 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 4 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 87008381f276eddeae4ed99a60bbc83580d04ba9 && git checkout 87008381f276eddeae4ed99a60bbc83580d04ba9
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin d8830c28056b9f466adfe9d59cd179b1d0fa6784 d63e3f6ec127585a0a785bb99c5be8326f66a3a4 && git checkout -B drift-repro d8830c28056b9f466adfe9d59cd179b1d0fa6784 && git merge --no-ff d63e3f6ec127585a0a785bb99c5be8326f66a3a4
node scripts/docs-audit/affected-docs.mjs --json d8830c28056b9f466adfe9d59cd179b1d0fa6784
|
Fixes #22683
Clause-②: no
What was wrong
On a node whose approvers are all
{ type: 'manager' },os lintreportsapproval-approvers-may-resolve-empty(info). Its hint ended the SCIM clause with "and its admin bulk import does not write it either". That has been false since the import admitted amanager_idcolumn (PR #18046), so the remedy sent an author with a whole file of reports away from a supported route. The guide (automation/approvals.mdx, corrected by PR #22681) already names that column and saysos lint"carries the same remedy text", so the lint string was one clause behind it.What changed (3 files, +69 / -15)
packages/lint/src/validate-approval-approvers.tsMANAGER_ONLY_ROUTES: the false clause is gone. The bulk import (POST /api/v1/auth/admin/import-users) is named as a route that works, right after the endpoint and its refusals and ahead of the clause that hands SCIM and directory sync to the deployment. It reads amanager_idcolumn holding the manager's email (or phone where phone sign-in is enabled), links each row once every row in the file exists, through the same refusals, and reports a link it cannot make on that row'smanagerresult without failing the user. Theidp_provisionedclause keeps its wording and now says the import's column is refused too.MANAGER_ONLY_REMEDY: names Set Manager (Setup → Users, row menu or record header) beside the endpoint it posts to. The card's done-when says "beside Set Manager and the endpoint"; the hint did not name Set Manager at all before, so this is the one addition beyond dropping the clause. The word "Console" is still used only inside the existing denial.info),stackWiresManagerChainas the one silencer, the fallback clause, the closing sentences.packages/lint/src/validate-approval-approvers.test.ts: the pin on "admin bulk import does not write it either" is replaced. The 'GRADES the routes' test now asserts the import path,reads a manager_id column,once every row in the file exists, the per-row report, that the old clause is gone, and that the import is named before the clause that hands the remaining routes to the deployment. The 'names the REAL remedy' test asserts Set Manager..changeset/22683-approver-remedy-bulk-import.md:@objectstack/lintpatch,Clause-②: no.Premise check (measured on origin/main cb3bb93 before writing a sentence)
The import does what the new sentence says, read in
packages/plugins/plugin-auth/src/admin-import-users.ts:MANAGER_COLUMN = 'manager_id';resolveManagerKeyreads the cell as an email, or a phone number only when the phone plugin is wired; the cell is deleted from the row before the identity write; the second pass runs afterrunImportreturns, resolves the key against this batch's rows and then againstsys_user, and callsapplyUserManagerLink(the endpoint's derivation); a failure goes tonoteManagerFailureon the row, never a whole-import failure;dryRunskips the pass. Behaviour:pnpm --filter @objectstack/plugin-auth exec vitest run --maxWorkers=2 src/admin-import-users-manager-pass.test.tsafter building@objectstack/plugin-auth^...:Test Files 1 passed (1),Tests 20 passed (20), including a link to a manager created by a later row and its control where the manager does not exist yet.Grep for the family (the card's done-when), on this branch at head d63e3f6
A wider pass over
packages,content,skills(CHANGELOGs excluded) for "import does not write" and "does not write it either" has one hit: a comment in the test file that quotes the retired clause. It also finds no other claim that the import or anything else fails to writemanager_id; the only near-misses are two past-tense history notes ("had no product write surface") inauth-route-ledger.tsandadmin-set-user-manager.test.ts, true of the column before the endpoint landed. With this card the enumeration coverspackages/lint/src,content/docsandskills/.Verification
Tests 47 passed (47); after:Tests 47 passed (47)(pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2 src/validate-approval-approvers.test.ts).Tests 2 failed | 45 passed (47),expected 'sys_user.manager_id is not a profile …' to contain 'Set Manager'and... to contain '/api/v1/auth/admin/import-users'. Direction: red, as expected. Restored withgit checkout HEAD -- path; the file's blob hash read143561c356c5871ccbc2c42d082c1b854797171dbefore and after, andgit diff HEADwas empty.pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2:Test Files 135 passed (135),Tests 6231 passed (6231)(at b9731fc; the later commit changes one regex in the test file, re-run on its own: 47 passed).pnpm --filter @objectstack/lint run typecheck(tsc --noEmit pluscheck:test-typecheck): OK.pnpm --filter @objectstack/lint run build: success,check-dts-emitted: 6/6. In the builtdist/index.jsanddist/index.cjs: new clause 1, old clause 0, control string 1.validateApprovalApproverscalled from the builtdist/index.cjson a manager-only flow returns oneinfofinding whose hint carries the new text.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 62 commands from this diff at head d63e3f6 (identical to the dispatch-time list); all 62 run on that head, every one exit 0, reconciled with--ran:62 derived, 62 run, 0 NOT-MEASURED, 0 UNRUN. Two ratchet gates (check:type-check-debt,check:query-options-erasure) hit this box's own 240 s runner cap under load 17 on the first pass and passed on re-run (re-measured in 522.7s, 26 raw tsc error(s) total, none above its recorded number;ratchet holds).eslint --no-inline-config --format jsonon the two changed files: 2 files, 0 errors, 0 warnings. The repo-widepnpm lintis CI's. Invariance:eslint.config.mjsnever enables type-aware linting (noparserOptions.project, line 328), so this diff cannot move the verdict of a file it did not touch.Acceptance notes
origin/mainmoved to d8830c2 during the run; its only difference from the base onpackages/lintand.changesetis an unrelated changeset, so this branch was not merged forward. The merge queue validates the merged generation.Test Core,Build Core, dogfood and temporal jobs, repo-widepnpm lint.idp_provisionedclause now says the import's column is refused too. That is the import'sapplyUserManagerLinkdelegation (covered byadmin-import-users-manager-pass.test.ts, "directory-owned identity"), not a new claim about the endpoint.rule-explanations.ts,content/docsorskills/edits.Generated by Claude Code