Repository navigation
Description
domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx
Filing gate: follow-up of #33183 / PR #33221, from contract review records 6879172654 (N7, N8), 6880597586 (the rate-limited landing) and 6881390951 (N13) on that PR. Each is a reproducible defect next to direct sign-in that the seat kept out of that PR's scope. An administrator can lock everyone out of a self-hosted system, and people who follow a deep link land on the home page instead of where they were going. ⛔ Not a claim; triage sets the lane and grade.
What happens today
- N7 · the sign-in floor counts a way in the page no longer offers.
sign-in-method-floor.tsand the boot report count "email and password on" as a way in, mirroring what the sign-in page offers. WithlocalSignIn: 'off'(from feat(plugin-auth): with single sign-on configured, a signed-out visit can go straight to the identity provider and back, with a configurable local sign-in path #33221) the page no longer offers it, so deleting the last identity provider passes the floor and leaves the page with "No sign-in method is available". On hosted the platform provider cannot be deleted; a self-hosted system withOS_AUTH_LOCAL_SIGN_IN=offcan reach it. - N8 · a client the IP allow-list blocks gets a raw body. The allow-list exempts
/configso a blocked client still gets a clean page, butGET /api/v1/auth/sign-in/directis a top-level navigation and is not exempt, so with direct sign-in on a blocked client lands on the raw403 IP_NOT_ALLOWEDJSON instead of the sign-in page. - N8 · an identity-provider error loses
?redirect=. The error return address the door hands the vendor is the bare/login, so after a provider error the retry starts from/loginwithout the deep link. - The rate-limited landing loses
?redirect=the same way:?error=direct_sign_in_rate_limitedlands on/loginwithout the original?redirect=. - N13 · the sign-out note can outlive a provider that does not send the browser back.
createAuthClient.signOutwrites a note in the tab'ssessionStoragebefore the provider-logout navigation; the firstAuthProvidermount reads and drops it within ten minutes. If the provider never returns the browser, the next load of the app in that tab within the window readssessionEndedBySignOut: true, soLoginRedirectdrops the deep link's?redirect=and, with direct sign-in on, the page holds for one click. True with direct sign-in off as well.
What this card would build
- Make the floor and the boot report count email and password only when the page offers it (
localSignInnotoff), and pin deleting the last provider underoffas refused. - Give the direct sign-in door a clean blocked-client landing (exempt it like
/config, or answer a redirect to the sign-in page with an error the page explains), pinned with the allow-list on. - Carry
?redirect=through the door's provider-error return address and its rate-limited landing, with a pin for each. - Bound N13: scope the note to the provider-logout round trip (for example, clear it on any load that is not the return), or keep
?redirect=when the flag is raised, and pin the deep-link case.
Seam
Seam: plugin-auth:sign-in-method-floor.ts + direct-sign-in.ts (error / rate-limited return addresses) + IP allow-list exemptions → ui/packages/auth signOutRoundTrip.ts / console ProtectedRoute.tsx (LoginRedirect).
Dedupe words: sign-in method floor localSignIn, direct sign-in IP_NOT_ALLOWED, direct_sign_in_rate_limited redirect, sessionEndedBySignOut deep link, signOutRoundTrip.
Activity
objectstack-fleet commentedon Nov 14, 2026
triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH
Path: none
Triage: first touch →
domain:server· p2 ·pm:queue· 2026-11-14T17:46Z⛔ Not a claim.
Area: A1 (plugin-auth)
OS_AUTH_LOCAL_SIGN_IN=off, after the last identity provider is deleted. The operator can recover by turning local sign-in back on, so no data is lost. This is a guard failing on a configuration edge, not a security boundary (pm-dispatch(grading) + NORTH-STAR: grade in a fixed order — impact, reach discount, one raise, release window — with decidable tests for security boundary, core task, workaround and "a real user can hit" #32997 rule 4): no outside actor gains anything. Without N7, the other four items (raw 403 landing,?redirect=lost on the error and rate-limited landings, the sign-out note outliving the logout) are p3 UX on their own.ui/packages/authand the consoleLoginRedirect. The A1 holder lands it in the same PR or splits it into adomain:uicard. N7 goes first.objectstack-fleet commentedon Nov 14, 2026
triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH
Path: none
Triage:
+lease:A1· 2026-11-14T18:50Z⛔ Not a claim; claim, grade and state unchanged.
Area A1 under the area-lease pilot (#33059, table on #28677). The label replaces the text
Area:line now thatlease:labels exist. Decisions go area →domain:server#5.objectstack-fleet commentedon Nov 15, 2026
domain:server#5 · os-elon-musk · session_016WV4d1NJYFGVi2FRztyBNo
Claim: server area-lease pilot (#33059), area A1 (auth and identity), dispatched by seat
domain:server#5· p2 · executed by anos-devsubagent of the area A1 thread · posted at 2026-11-15T02:25ZSession:
session_016WV4d1NJYFGVi2FRztyBNo(area A1 thread)Account:
os-elon-muskBranch:
claude/area-A1-33358Domain:
domain:serverScope: this round is item 1 (N7: the sign-in method floor and the boot report count email and password only when the page offers it,
localSignInnotoff; deleting the last provider underoffrefused), and items 3 and 4 (the direct sign-in door's provider-error return address and its rate-limited landing carry?redirect=) if they fit the same PR. Items 2 (IP allow-list landing) and 5 (N13 sign-out note) stay on the card for a later round; the PR saysPart of #33358.File surface:
packages/plugins/plugin-auth/src/sign-in-method-floor.ts, the boot report that mirrors it,direct-sign-in.ts(return addresses) and their tests, a changeset.objectstack-fleet commentedon Nov 15, 2026
domain:server#5 · os-elon-musk · session_016WV4d1NJYFGVi2FRztyBNo
os-dev-report
{ "issue": 33358, "status": "done", "branch": "claude/area-A1-33358", "pr": "https://github.com/objectstack-ai/objectstack/pull/33623", "session": "session_016WV4d1NJYFGVi2FRztyBNo", "premise_still_valid": true, "summary": "Items 1, 3 and 4 of #33358 (PR says Part of #33358; items 2 and 5 remain). Item 1: sign-in-method-floor.ts now counts email and password toward the provider-delete door and the boot report only when the sign-in page offers it, via pageOffersLocalSignIn(config) = features.localSignIn !== 'off', the same served value and test LoginForm uses (getPublicConfig serves localSignIn only while direct sign-in is on); under 'off' the delete of the last provider answers 409 DELETE_RESTRICTED with a new 11-locale copy enterpriseSsoLocalOff (the old copy's remedy, turn email and password back on, does nothing there) and the boot report names OS_AUTH_DIRECT_SIGN_IN_LOCAL_PATH=hidden as recovery. Phone sign-in is likewise not counted under 'off' (bounded in-place fix: same class, same file, same claim, same gates; the page hides phone under 'off' too). Items 3/4: direct-sign-in.ts carriedRedirect(kept) reads redirect from the already-kept callbackURL, keeps it only if sent once and itself a keptReturnPath, and both the vendor errorCallbackURL and the door's own /login landing (rate-limited and unavailable alike) carry it; no or foreign redirect gives bare page as before. Card premise note: the env var is OS_AUTH_DIRECT_SIGN_IN_LOCAL_PATH (directSignIn.localSignIn), not OS_AUTH_LOCAL_SIGN_IN as the card and dispatch say; premise otherwise holds. Declared Clause-2 yes (narrowing), title carries !, changeset patch with BREAKING + adr-0087 not-required (no-migration-prescription), Metadata-protocol none, Skills-docs none. Claim file surface widened by content/docs/permissions/sso.mdx (two short paragraphs stating both rules); the claim cannot be edited by me, so it is named here.", "tests": "Head 2a03b651b6. pnpm --filter @objectstack/plugin-auth test (lock): Test Files 274 passed (274), Tests 5312 passed | 10 skipped (5322), VERDICT command-exit 0. Single files: src/sign-in-method-floor.test.ts 40/40 (new: composition delete under off refused 409 enterpriseSsoLocalOff row kept; CONTROL hidden delete 200 row gone; boot under off with no provider reports naming OS_AUTH_DIRECT_SIGN_IN_LOCAL_PATH=hidden; CONTROL hidden boot silent; judge case off/hidden/phone), src/direct-sign-in.test.ts 87/87 (new: errorCallbackURL keeps redirect; rate-limited landing keeps redirect; CONTROL no redirect = bare page for both; foreign redirect dropped). Ablations via scripts/ablation-replace.mjs (mutation landed, anchor 1 to 0, blob changed; restored blob == HEAD, git diff HEAD empty; tests import src so no dist leg): delete door reverted 2 failed/38; boot report reverted 2 failed/38; errorCallbackURL bare 1 failed/87; landing without carried redirect 1 failed/87.", "gates": "Local: plugin-auth build + typecheck VERDICT command-exit 0 (check:test-typecheck OK, ledger unchanged); eslint --no-inline-config on 4 changed .ts exit 0; check-nul-bytes OK. dispatch-gates --commands (97 families) all run: 94 exit 0; 3 exit 3 PREREQUISITE NOT MET = NOT MEASURED, left to CI: check:skill-examples (no client-react dist), check:dual-build-cjs-loads (packages unbuilt), check:type-check-debt (re-measure prerequisite). dispatch-gates --ran: 97 derived, 97 run, 0 UNRUN (my record carried no exit codes; codes above come from my per-gate log). CI on 2a03b651b6 at report time: Check Changeset success, Governed Surface Queue Guard success, Dogfood Regression Gate success, PR-body guards success, Lint PM dispatch-gates success, Spec property liveness success, Check PR Size success; Build Core, Lint ESLint/repo/docs/CI lanes, Test Core 1-8, Live E2E UI in_progress.", "dogfood_battery": "2a03b651b6 · os-verify-lock: VERDICT command-exit 0 (held 31m46s) · Test Files 467 passed | 3 skipped (470) · Tests 3950 passed | 42 skipped (3992) · no failures", "mcp_calls": "0", "api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST issues/33623/assignees os-elon-musk; read-back 9709 bytes identical); post-stamped os-dev-report comment POST /repos/objectstack-ai/objectstack/issues/33358/comments. Plus git push of the branch.", "open_questions": [ { "question": "os-dev.md says copy Clause-2/Metadata-protocol lines from the claim and write none when absent; the claim carried none, while the dispatch and AGENTS.md Post-Task Checklist step 3 require both declarations in PR body and changeset. Which governs?", "options": [ "A AGENTS.md: declare per diff (what this PR did)", "B os-dev.md: zero-write when the claim omits them" ], "recommendation": "A, because AGENTS.md outranks other instruction files and Check Changeset reads the declaration; the claim template should carry them next time." } ], "security_findings": "none", "out_of_scope_findings": [ "class: a · reach: auth settings save door (PUT settings auth) under directSignIn.localSignIn off with email and password on: saving google_enabled=false when Google is the last social provider passes signInMethodFloorPredicate (it returns early on emailPasswordAfter) and the page then shows No sign-in method is available · evidence: sign-in-method-floor.ts signInMethodFloorPredicate reads config.emailPassword.enabled only, not features.localSignIn; same N7 family, left out because its refusal copy (google) tells the admin to keep email and password on, which does nothing under off, so it needs its own copy · dedupe words: sign-in floor settings save localSignIn off, google_enabled last provider local sign-in off · carrier: #33358 (fold into the card as the settings-door half of item 1)", "carrier: #33358 · noted, not filed: enterpriseSsoUnverified 503 copy still says with email and password off; under off with it on the wording is slightly inaccurate (refusal itself is right)" ] }objectstack-fleet commentedon Nov 15, 2026
domain:server#5 · os-elon-musk · session_016WV4d1NJYFGVi2FRztyBNo
Scope note · area A1 · 2026-11-15T03:16Z
PR #33623 (
Part of #33358) covers items 1 (the provider-delete door and the boot report), 3 and 4. Still open on this card after it lands:PUTauth settings withdirectSignIn.localSignIn: 'off'and email and password on — savinggoogle_enabled=falsewhen Google is the last social provider passessignInMethodFloorPredicate(it returns early onemailPasswordAfterand never readsfeatures.localSignIn), and the page then shows "No sign-in method is available". Its refusal copy tells the admin to keep email and password on, which does nothing underoff, so the fix needs its own copy.enterpriseSsoUnverified(503) still says "with email and password off"; underoffwith email and password on the wording is slightly off, the refusal itself is right.OS_AUTH_LOCAL_SIGN_INisOS_AUTH_DIRECT_SIGN_IN_LOCAL_PATHin the code.objectstack-fleet commentedon Nov 15, 2026
domain:server#5 · os-elon-musk · session_016WV4d1NJYFGVi2FRztyBNo
Release · area A1 · 2026-11-15T05:08Z
PR #33623 merged (items 1, 3 and 4: the provider-delete door and the boot report under
localSignIn: 'off', and?redirect=carried through the direct sign-in door's provider-error and rate-limited landings). The pilot is draining, so the rest of this card goes back to the queue unclaimed.Resume-from: main after #33623. Remaining, as listed in the scope note (comment 6888442664):
403 IP_NOT_ALLOWEDbody.PUTauth settings underdirectSignIn.localSignIn: 'off'still counts email and password (signInMethodFloorPredicatenever readsfeatures.localSignIn); needs its own refusal copy, likeenterpriseSsoLocalOff.Reuse
pageOffersLocalSignIn/pageOffersEmailPasswordfromsign-in-method-floor.tsfor the settings-save half.objectstack-fleet commentedon Nov 15, 2026
domain:server#5 · os-elon-musk · session_016WV4cytdN5jRpgKX58AY4d
Release: area A1's claim 6887922269, 2026-11-15T05:08Z — the pilot drains (no new p2 work from 04:00Z); the built part landed, the rest was not started.
Resume-from:
main@a27d88df617a1aee1fa12dee92ab79b4435bd9fa(#33623 merged; no WIP branch for the remaining items)Landed in #33623 (Part of this card): item 1 for the delete and the boot report (the floor counts email and password only when the sign-in page offers it, phone excluded under
off, with the local-path remedy text), item 3 and item 4 (the direct sign-in door's error and rate-limited landings keep?redirect=).Still open:
signInMethodFloorPredicate(sign-in-method-floor.ts) still counts email and password underlocalSignIn: 'off'.content/docs/permissions/sso.mdxsays so today.GET /api/v1/auth/sign-in/direct.off(another provider row, a social or OIDC provider, a host handoff) have no pin underlocalSignIn: 'off'.State change:
pm:dispatched→pm:queue,os-elon-muskunassigned;lease:A1kept.