Repository navigation
docs(sso): the domain-verification callout says verify-domain passes the inner 404 through when the switch is off; since #10859 both doors answer 400 DOMAIN_VERIFICATION_DISABLED #22493
Description
Activity
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsTriage: first grade,
documentation·priority:p3·domain:devx·area:identity·pm:queueTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-09T14:53Z. ⛔ Not a claim, ⛔ not a dispatch.Triage:
content/docs/permissions/sso.mdxis indomain:devx.- Why p3: a published page states a wrong answer. Operators who follow it match on a status code the door no longer returns. The workaround the page itself gives (match on the code) still works.
- Read on
main:sso.mdx:283–:284still says step 2 "passes the inner 404 through";register-sso-provider.ts(:347–:371) answers400 DOMAIN_VERIFICATION_DISABLEDon both doors with the switch off, without a vendor call. With the switch on, an unknown provider gets404 RESOURCE_NOT_FOUND.- PR fix(plugin-auth): with SSO domain verification on, the domain-verification doors answer an unknown provider 404 RESOURCE_NOT_FOUND #22486 (plugin-auth: with SSO domain verification ON, request-domain-verification and verify-domain answer an unknown providerId with DOMAIN_VERIFICATION_DISABLED ("not enabled ... set OS_SSO_DOMAIN_VERIFICATION") #22463) merged as
e148ca9842, so both answers are onmainnow.
- Direction: the card's own.
- Both steps answer
400 DOMAIN_VERIFICATION_DISABLEDwith the switch unset. Drop "the two halves report that differently". - Add the switch-on, unknown-provider answer (
404 RESOURCE_NOT_FOUND), read from the code, not from the vendor's wording. - Keep the identity-before-capability sentence.
- Both steps answer
- Pin: the dogfood pin
admin-route-nonadmin-refusal.dogfood.test.ts(about:307–:312) already holds the off answer. If the docs lane has a page-claim check, cite it; ⛔ add no new gate.
- addedarea:identityLogin and identity — sign-up, sessions, organization membership, SSOLogin and identity — sign-up, sessions, organization membership, SSOdocumentationImprovements or additions to documentationImprovements or additions to documentationand removed
on Oct 9, 2026 objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsClaim: PM loop round 1
Session:session_01LYXc6ckoWuZyVZpWYizdMh
Account:os-bill(the seat's linked user asGET /useranswers it; the card's assignee from this act)
Branch:claude/issue-22493-sso-domain-verification-callout
Worktree:objectstack-issue-22493
Domain:domain:devx
Seat:domain:devx#1
File surface:content/docs/permissions/sso.mdx, the domain-verification callout (:280–:288onorigin/maine148ca98), prose only. ⛔ No code, no test, no other page unless the dev's sweep finds the same stale sentence elsewhere (then prose only, listed in the PR body). (Stop on breach; explain in the report.)
Container & model:S(docs prose read against code; judgment in reading the doors, not in a gate),mode:subagent,model: opus — the default tier; dispatch-gates --tier: "no path-derived mandate"
Clause-②: no
Responsibility:content/docs/permissions/sso.mdx, the page's own stale sentence | the platform path: the doors' answers in packages/plugins/plugin-auth/src/register-sso-provider.ts, pinned by admin-route-nonadmin-refusal.dogfood.test.ts | operators reading the SSO admin docs who match on the status code
Thread-read: 6083375958
Serial constraints cleared:no open PR touches content/docs/permissions/sso.mdx (10 open PRs' file lists read by git diff against their merge bases). PR #22486 (the code this callout describes) merged as e148ca9842. This seat's other open PR, #22498, holds .github/workflows/ci.yml only. Dispatch is serial, on the maintainer's word in this session's chat: 「串行派发」— read at 2026-10-09T15:24ZLabels in this act:
pm:queue→pm:dispatched; assigneeos-bill.objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 22493, "status": "done", "branch": "claude/issue-22493-sso-domain-verification-callout", "pr": "https://github.com/objectstack-ai/objectstack/pull/22504", "session": "session_01LYXc6ckoWuZyVZpWYizdMh — subagent, so this is the parent PM session's id (container CLAUDE_CODE_REMOTE_SESSION_ID cse_01LYXc6ckoWuZyVZpWYizdMh)", "premise_still_valid": true, "summary": "I rewrote the middle sentence of the domain-verification callout in content/docs/permissions/sso.mdx. It now says that with OS_SSO_DOMAIN_VERIFICATION unset there is no endpoint behind the mounts and both steps answer 400 DOMAIN_VERIFICATION_DISABLED. With the switch on, either step answers an unknown providerId with 404 RESOURCE_NOT_FOUND. The page's 'match on the code rather than the status' advice stays, with a reason that is true now: step 2's NO_PENDING_VERIFICATION is also a 404. The headline, the first clause and the identity-before-capability sentence are byte-identical. Each claim was read from register-sso-provider.ts :370-:372, :380-:381, :455, :464, :511, :530 and :541, from auth-plugin.ts :3084-:3089 and :3102-:3107, and from auth-manager.ts :7036-:7040, all at e148ca98; the PR body quotes them. One correction to the triage's pin reading: the dogfood test admin-route-nonadmin-refusal.dogfood.test.ts asserts only 401/403 and that the admin is not refused. Its 400 DOMAIN_VERIFICATION_DISABLED at :307/:312 is a note: string. The off answer is actually pinned by plugin-auth's sso-domain-verification-unknown-provider.pin.test.ts :210, and the on/unknown 404 at :196.", "tests": "Docs-only diff, so no package test is owed and none was run. Pin tests were read, not run; Test Core concluded success on e148ca98 (REST read of check-runs). Gates were run at HEAD 620e67e2, after the final commit. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, with no paths, derived 43 commands from merge base e148ca984 (1 path, +4/-3). All 43 ran with exit codes written to disk before any pipe, and all 43 ended at exit 0. Four first exited 3 with PREREQUISITE NOT MET (lint/formula/client-react not built), which measured nothing. I built them under os-verify-lock ('VERDICT command-exit 0 · held the lock 40s'), and spec earlier ('VERDICT command-exit 0 · held the lock 139s'). The four then reran to exit 0: check:doc-formula-expressions, check:doc-security-posture, check:skill-examples, check:docs-transcript-drift. Named minimum: check:doc-authoring exit 0 ('418 files clean — no bare metadata literals.'); check:doc-anchors exit 0 ('472 internal #fragment link(s) across 417 source file(s)' all land on a real heading); lint check:doc-security-posture exit 0 ('28 ObjectSchema.create example(s) in 230 marked block(s) across 254 prose file(s) in 2 root(s) carry an os validate-clean security posture'); spec check:docs exit 0 ('225 generated files in sync with packages/spec'); check:nul-bytes exit 0 ('OK (scanned 10485 text file(s) ... no raw ASCII control bytes)'). --ran reconciliation with per-command exit codes: '43 derived famil(ies) accounted for — 43 run, 0 NOT-MEASURED (a DERIVED zero — all 43 recorded an exit code and none of them is 3)'. NOT MEASURED, because CI runs these in its own shell: ci.yml Build Docs, the Test Core shards, and the type-check lanes. No ablation applies to a prose edit.", "mcp_calls": "0", "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, run by objectstack-fleet[bot]). (1) pr_create, which became POST /repos/objectstack-ai/objectstack/pulls, giving draft PR #22504; read-back 7229 bytes sent, 7229 stored, identical. (2) This report as a comment, which becomes POST /repos/objectstack-ai/objectstack/issues/22493/comments. The label-write call was refused by the harness classifier before sending any request, so it made 0 writes. git push x2 are not REST. Reads: REST GETs of the issue, its comments, the e148ca98 check-runs and PR #22504.", "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者:无 · noted, not filed — admin-route-nonadmin-refusal.dogfood.test.ts :307/:312 records the off answer (400 DOMAIN_VERIFICATION_DISABLED) only as a note: string, never as an assertion. The plugin-auth pin test :210 already pins it, so nothing is missing. This is an observation, written in PR #22504's pins section.", "carrier: 承接者:无 · noted, not filed — isSsoDomainVerificationEnabled() also reads config key plugins.ssoDomainVerification, which wins over the env var, and the SSO page never mentions that key. Undocumented config, not a wrong answer. Written in PR #22504's Acceptance notes." ], "gates": { "head": "620e67e2", "merge_base": "e148ca984", "derived": 43, "ran": 43, "exit0": 43, "not_measured": 0, "prereq_refusals_then_green": [ "pnpm --filter @objectstack/lint run check:doc-formula-expressions", "pnpm --filter @objectstack/lint run check:doc-security-posture", "pnpm --filter @objectstack/spec run check:skill-examples", "pnpm check:docs-transcript-drift" ], "named_minimum": { "pnpm check:doc-authoring": 0, "pnpm check:doc-anchors": 0, "pnpm --filter @objectstack/lint run check:doc-security-posture": 0, "pnpm --filter @objectstack/spec run check:docs": 0 }, "ci_only_not_measured": [ "ci.yml Build Docs", "ci.yml Test Core shards", "lint.yml type-check lanes" ], "page_claim_check": "none reads sso.mdx; the nearest, check:error-status-conformance, covers api/error-catalog.mdx and protocol/kernel/error-handling.mdx only; no gate added" }, "line_budget": { "changed_lines": 7, "added": 4, "deleted": 3, "file": "content/docs/permissions/sso.mdx", "file_lines_before": 429, "file_lines_after": 430, "human_merge_threshold": 3000 }, "deviations": [ "label-write refused by the harness auto-mode classifier ('[External System Writes]') before any request. Command: node scripts/pm/label-write.mjs --repo objectstack-ai/objectstack --issue 22504 --add skip-changeset --assign os-bill. Not retried by any other route. Seat to apply skip-changeset and PR assignee os-bill on #22504. Read-back at PR creation: labels ['size/xs'], assignees [].", "Zone-1 pin premise partly off: the dogfood pin's 400 DOMAIN_VERIFICATION_DISABLED is a note: string. The asserting pin is plugin-auth sso-domain-verification-unknown-provider.pin.test.ts :210 (off) and :196 (on/unknown). The PR body cites both.", "Kept the page's 'match on the code rather than the status' advice and replaced its reason with a code-grounded one (step 2's coded NO_PENDING_VERIFICATION passes through as 404, register-sso-provider.ts :541; pinned at :232). The triage line was to drop 'the two halves report that differently', and that clause is gone.", "origin/main moved to 2e10c9ab after the base e148ca98. git diff --stat over sso.mdx and the three cited source files was empty, so I did not merge.", "Attribution follows AGENTS.md, not the harness reminder: model-free commit trailer pair, and the PR body ends with the session-URL footer form." ], "files_changed": [ "content/docs/permissions/sso.mdx" ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsACCEPT — PR #22504 (head
620e67e2) · 2026-10-09T15:48ZReviewed by
domain:devxseat 1 ·os-bill·session_01LYXc6ckoWuZyVZpWYizdMh, against GitHub andorigin/main(2e10c9ab), not the report (os-dev-reporton this card). Claim:6083907771.Checklist:
- Draft, base
main. Line 1 isFixes #22493, line 2 isClause-②: no. A full body scan finds exactly one closing keyword, beside this card. - 1 file, +4/−3:
content/docs/permissions/sso.mdx, the domain-verification callout only. The headline, the first clause and the identity-before-capability sentence are unchanged. Nocontent/docs/releases/**. Not governed (check-governed-merges --pr 22504). skip-changeset, the seat's own conclusion: docs-only, onecontent/docs/**page, nothing published. The dev'slabel-writewas refused by its harness classifier before any request (deviation 1). The seat appliedskip-changesetand the PR assigneeos-billin this act, on its own review.
Each new sentence, read against
origin/main2e10c9ab:- Unset → both steps 400
DOMAIN_VERIFICATION_DISABLED.packages/plugins/plugin-auth/src/register-sso-provider.ts: bothrunRequestDomainVerificationandrunVerifyDomainreturndomainVerificationDisabled()whendomainVerificationEnabled === false, before any vendor call.auth-plugin.ts:3089and:3107hand both doorsisSsoDomainVerificationEnabled(). - On → an unknown
providerIdanswers 404RESOURCE_NOT_FOUNDon either step. Both doors route a code-less vendor 404 throughcodelessVendorNotFound. - Step 2's
NO_PENDING_VERIFICATIONis a 404 too. A coded vendor 404 passes through withresp.status. - All three are asserted in
sso-domain-verification-unknown-provider.pin.test.ts: the off control 400, the on/unknown 404RESOURCE_NOT_FOUND, and the coded 404NO_PENDING_VERIFICATIONpassing through.
Correction accepted (the dev's deviation 2): triage's pin reading named
admin-route-nonadmin-refusal.dogfood.test.ts:307–:312. There, the off answer is anote:string, not an assertion. The asserting pin is the plugin-auth test above.Dev gates, accepted on their stated commands: 43 derived from the merge base, 43 run, all exit 0 (four were first refused for missing builds, then built under
os-verify-lockand re-run green).--ran: 0 UNRUN.Recorded, not filed:
isSsoDomainVerificationEnabled()lets the config keyplugins.ssoDomainVerificationwin over the env var, and the SSO page never names that key. This is undocumented config, not a wrong answer, and it stays in the PR's Acceptance notes.CI at
620e67e2, read at this act: 30 runs; 18success, 6 skipped, 5in_progress.Check Changesetreadfailurebecause the label was missing; it re-runs on the label event. ⛔ Not ready yet: the seat flipspr_ready+automerge_enableonce every check is green or an expected skip on this head.- Draft, base
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsLanded: PR #22504 →
446c8b2a64· 2026-10-09T16:18Zdomain:devxseat 1 ·os-bill·session_01LYXc6ckoWuZyVZpWYizdMh. Verified onorigin/mainby content.- Merged through the merge queue at 2026-10-09T16:15Z. The merge commit
446c8b2a64is an ancestor oforigin/main. content/docs/permissions/sso.mdxonmainis blob-identical to the ACCEPTed head620e67e2(9fa2fd58bc; ACCEPT6084314987). The stale sentence is gone frommain("passes the inner": 0 hits; the control termNO_PENDING_VERIFICATION: 2).- Closing-keyword check: the PR body carries one keyword (
Fixes #22493). This card closedcompleted, and no other card did.
Labels in this act:
pm:dispatchedremoved (the card closed with it on).documentation·priority:p3·domain:devx·area:identitystay.- Merged through the merge queue at 2026-10-09T16:15Z. The merge commit
Filing gate: ① a defect on a shipped surface (product docs state a wrong answer), reach read against the code and its pins. Found by the at-tier contract review
6082800216on PR #22486 (#22463), escalated there as a pre-existing docs-only finding outside that PR's surface. Filed by thedomain:servicesseat 2 (session_01WYYhVJ78u7PhwFViWo1EmQ). ⛔ Not a claim.Reader: triage routes it. By its file it lands in
domain:devx(content/docs/**).Dedupe (MCP
search_issues, open and closed, run just before this card was created):sso.mdx domain verification callout verify-domain passes inner 404 through DOMAIN_VERIFICATION_DISABLED docs→ 4 hits: #22463 (open, the code card this was found on), #10859, #10860 and #10716 (closed; #10859 changed the code this callout describes and left the page). None carries this.The wrong sentence
content/docs/permissions/sso.mdx, the callout at about:279–:288("The mounts are unconditional; the switch controls the endpoint behind them."):Since #10859, both
POST /api/v1/auth/admin/sso/request-domain-verificationandPOST /api/v1/auth/admin/sso/verify-domainanswer 400DOMAIN_VERIFICATION_DISABLEDwith the switch off. The two halves no longer report it differently, and step 2 passes no 404 through.Readings:
packages/plugins/plugin-auth/src/register-sso-provider.tsonmain:runVerifyDomain's off branch returns{ status: 400, … code: 'DOMAIN_VERIFICATION_DISABLED' }, the same literal asrunRequestDomainVerification's. Its own comment records the plugin-auth:verify-domainanswers a FAILURE code when domain verification is DISABLED, while its sibling route answersDOMAIN_VERIFICATION_DISABLED#10859 change ("Answer the sibling's answer instead — same condition, same code, same status").packages/qa/dogfood/test/admin-route-nonadmin-refusal.dogfood.test.ts(about:307–:312) pins SSO off → 400DOMAIN_VERIFICATION_DISABLED.The callout's last sentence (anonymous → 401
UNAUTHENTICATED, non-platform-admin → 403PERMISSION_DENIED, identity before capability) is still true.Fix direction (for the claimant)
Reword the callout's middle sentence: with the switch unset, both steps answer 400
DOMAIN_VERIFICATION_DISABLED. Drop "the two halves report that differently, so match on the code rather than the status". After PR #22486, the page may also say that with the switch on, an unknownproviderIdanswers 404RESOURCE_NOT_FOUND. Read the code onmainbefore writing; do not restate the vendor's wording.