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
{{ message }}
Repository navigation
Authentication settings: clearing a key (or resetting the namespace) answers saved, but the running value keeps the last stored one until a restart (lockout threshold, max sessions per user and siblings) #30312
Filing gate: ② a sibling of #30203, found and measured by its dev (PR #30309, os-dev-report 6650755695, out_of_scope class a). #30203 fixed one key (allowed_ip_ranges) only. ⛔ Not a claim. Triage sets the grade.
Reader: domain:server, plugin-auth (auth-plugin.tsapplySettings).
Dedupe: auth settings cleared default restart, restore default not applied, isExplicit → only #30203 (one key, fixed by PR #30309). New.
What happens
PUT /api/settings/auth with a key set to null (the console's clear), or the namespace reset, answers saved. The key then resolves source: 'default', and every if (isExplicit(key)) branch in applySettings skips it, so the running value keeps the last stored one until a restart. Measured on the real AuthPlugin + SettingsService: lockout_threshold 3 and max_concurrent_sessions_per_user 2 stay in force after both are saved null.
Claim: PM loop round 7
Session: session_01Utp6Cbvcmv8YWFhFJwzjKL (seat) · dev thread session_01Utp6CZPLJKSBMtARXMHc4W
Account: os-bill
Branch: claude/project-thread-nbraza (harness-pinned thread branch; platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-30312
Domain: domain:server
Seat: domain:server#2
File surface: packages/plugins/plugin-auth/src/auth-plugin.ts (bindAuthSettings / applySettings only), a helper module beside it if needed, tests under packages/plugins/plugin-auth/src/, one changeset .changeset/30312-auth-settings-clear-applies-default.md. ⛔ packages/services/service-settings/**, packages/spec/**, ui/**, apps/**, skills/**, docs/adr/**, content/docs/releases/**, .claude/** (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default tier (opus) — dispatch-gates --tier: no path-derived mandate, effort: high
Clause-②: no expected — a clear that answered saved now takes effect, the documented behaviour; the dev re-declares (narrowing) if a refusable piece now refuses a clear it let through
Metadata-protocol: none
Responsibility: every isExplicit branch in applySettings skips a key that resolves source: 'default', so a clear or a namespace reset leaves the last stored value in force until a restart | the settings service's clear and reset themselves (unchanged) | every deployment that clears an authentication setting
Thread-read: 6651923544
Premise: holds as measured by #30203's dev (os-dev-report 6650755695); re-measured first — at dbf53efe ~30 isExplicit branches in applySettings, only allowed_ip_ranges restores the declared value (PR #30309)
Serial constraints cleared: #30201 / #30202 / #30302 landed (PRs #30293, #30298, #30376); this seat's #30385 is in service-settings and allowed-ip-ranges.ts, both outside this surface; pull main before PR and before landing.
Order: project file server-seat2/dispatch-30312.md, delivered as the card thread's opening message.
{
"issue": 30312,
"status": "done",
"branch": "claude/project-thread-nbraza",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30447",
"session": "session_01Utp6CZPLJKSBMtARXMHc4W",
"premise_still_valid": true,
"summary": "Premise re-measured at dbf53efe on the real AuthPlugin + SettingsService: lockout_threshold 3 and max_concurrent_sessions_per_user 2 stayed in force after a null save; a namespace reset left lockout_threshold 4. Fix: auth-settings-declared.ts snapshots the deployment-declared options once in init() and maps all 33 auth manifest keys to the piece their declared value restores through (plain patch, emailAndPassword piece, plugins piece, mfa piece, session merge, rateLimit / google / audience groups); applySettings tracks which keys the running config took from the store and restores each that now resolves source default in the same pass. allowed_ip_ranges folded into the same table (#30203 pins unchanged). Seat ruling A: sign-in-method-floor.ts judges a cleared email_password_enabled at the declared value (measured: without it a declared-off deployment could clear into a lockout), Clause-② yes (narrowing).",
"tests": "auth-settings-clear.pin.test.ts 17/17. plugin-auth suite on 8b9f159f: VERDICT command-exit 0, Test Files 225/225, Tests 3971 passed 10 skipped; typecheck check:test-typecheck OK. Ablations A1-A11 via scripts/ablation-replace.mjs (src imports, no dist): each red (A1 7 incl. three #30203 pins, A2 3, A3 1, A4 1, A5 1, A6 1, A7 2, A8 1, A9 2, A10 1, A11 1), each restored blob == HEAD, git diff HEAD empty.",
"gates": "dispatch-gates --commands on f58be8f5: 64 derived; --ran: 63 run exit 0, 1 NOT-MEASURED (pnpm check:dual-build-cjs-loads exit 3, needs whole-workspace build, CI). check-plugin-teardown-shape --self-test exit 3 (shallow) then 0 after fetching 621a4876. pnpm lint exit 0. CI check-runs: in_progress at report time.",
"dogfood_battery": "f58be8f5 · VERDICT command-exit 0, held 40m35s · Test Files 419 passed 3 skipped (422) · Tests 3492 passed 36 skipped (3528) · no failure",
"mcp_calls": "5 — mcp__github__issue_read x3 (get, get_comments x2), mcp__github__pull_request_read x2 (get #30376 precedent, get #30447 read-back); no write tool",
"api_writes": "2 — relay pr_create (fleet-write run 42021746367, read-back identical 10451 bytes, #30447); this os-dev-report comment via post-stamped. Plus git push (not REST).",
"deviations": [
"file surface widened to packages/plugins/plugin-auth/src/sign-in-method-floor.ts (seat ruling A, 10:22Z)",
"harness assign/review-request step skipped per the order's Writes line; PR has no assignee",
"session_expiry_days / session_refresh_days now merge over the declared session block instead of replacing it (needed for the mixed clear case)"
],
"files_changed": [
".changeset/30312-auth-settings-clear-applies-default.md",
"packages/plugins/plugin-auth/src/auth-plugin.ts",
"packages/plugins/plugin-auth/src/auth-settings-declared.ts",
"packages/plugins/plugin-auth/src/auth-settings-clear.pin.test.ts",
"packages/plugins/plugin-auth/src/sign-in-method-floor.ts"
],
"line_budget": "+670 / -29 over 5 files (test 358, helper 141, auth-plugin +138 net)",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"observation · one rate-limit key cleared while the other stays stored: the explicit branch uses built-in fallbacks 10/60 for the cleared half, not the declared rateLimit; pre-existing · carrier: none"
]
}
closed by Fixes #30312. BREAKING (narrowing): clearing an authentication setting, or resetting the namespace, takes effect at once; the one clear that would lock everyone out is refused at the save door.
Release
rides the next release by its changeset
State change: pm:dispatched removed, assignee cleared.
Activity
objectstack-fleet commentedon Nov 5, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 ·
domain:server·pm:queue· 2026-11-05T07:02Z⛔ Not a claim.
Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#2 · os-bill · session_01Utp6Cbvcmv8YWFhFJwzjKL
Claim: PM loop round 7
Session:
session_01Utp6Cbvcmv8YWFhFJwzjKL(seat) · dev threadsession_01Utp6CZPLJKSBMtARXMHc4WAccount:
os-billBranch:
claude/project-thread-nbraza(harness-pinned thread branch; platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-30312Domain:
domain:serverSeat:
domain:server#2File surface:
packages/plugins/plugin-auth/src/auth-plugin.ts(bindAuthSettings/applySettingsonly), a helper module beside it if needed, tests underpackages/plugins/plugin-auth/src/, one changeset.changeset/30312-auth-settings-clear-applies-default.md. ⛔packages/services/service-settings/**,packages/spec/**,ui/**,apps/**,skills/**,docs/adr/**,content/docs/releases/**,.claude/**(stop on breach; explain in the report)Container & model:
M,mode:thread,model: default tier (opus) — dispatch-gates --tier: no path-derived mandate,effort: highClause-②: no expected — a clear that answered saved now takes effect, the documented behaviour; the dev re-declares
(narrowing)if a refusable piece now refuses a clear it let throughMetadata-protocol: none
Responsibility: every
isExplicitbranch inapplySettingsskips a key that resolvessource: 'default', so a clear or a namespace reset leaves the last stored value in force until a restart | the settings service's clear and reset themselves (unchanged) | every deployment that clears an authentication settingThread-read: 6651923544
Premise: holds as measured by #30203's dev (os-dev-report 6650755695); re-measured first — at
dbf53efe~30isExplicitbranches inapplySettings, onlyallowed_ip_rangesrestores the declared value (PR #30309)Serial constraints cleared: #30201 / #30202 / #30302 landed (PRs #30293, #30298, #30376); this seat's #30385 is in
service-settingsandallowed-ip-ranges.ts, both outside this surface; pullmainbefore PR and before landing.Order: project file
server-seat2/dispatch-30312.md, delivered as the card thread's opening message.objectstack-fleet commentedon Nov 5, 2026
domain:server#2 · os-bill · session_01Utp6Cbvcmv8YWFhFJwzjKL
os-dev-report
{ "issue": 30312, "status": "done", "branch": "claude/project-thread-nbraza", "pr": "https://github.com/objectstack-ai/objectstack/pull/30447", "session": "session_01Utp6CZPLJKSBMtARXMHc4W", "premise_still_valid": true, "summary": "Premise re-measured at dbf53efe on the real AuthPlugin + SettingsService: lockout_threshold 3 and max_concurrent_sessions_per_user 2 stayed in force after a null save; a namespace reset left lockout_threshold 4. Fix: auth-settings-declared.ts snapshots the deployment-declared options once in init() and maps all 33 auth manifest keys to the piece their declared value restores through (plain patch, emailAndPassword piece, plugins piece, mfa piece, session merge, rateLimit / google / audience groups); applySettings tracks which keys the running config took from the store and restores each that now resolves source default in the same pass. allowed_ip_ranges folded into the same table (#30203 pins unchanged). Seat ruling A: sign-in-method-floor.ts judges a cleared email_password_enabled at the declared value (measured: without it a declared-off deployment could clear into a lockout), Clause-② yes (narrowing).", "tests": "auth-settings-clear.pin.test.ts 17/17. plugin-auth suite on 8b9f159f: VERDICT command-exit 0, Test Files 225/225, Tests 3971 passed 10 skipped; typecheck check:test-typecheck OK. Ablations A1-A11 via scripts/ablation-replace.mjs (src imports, no dist): each red (A1 7 incl. three #30203 pins, A2 3, A3 1, A4 1, A5 1, A6 1, A7 2, A8 1, A9 2, A10 1, A11 1), each restored blob == HEAD, git diff HEAD empty.", "gates": "dispatch-gates --commands on f58be8f5: 64 derived; --ran: 63 run exit 0, 1 NOT-MEASURED (pnpm check:dual-build-cjs-loads exit 3, needs whole-workspace build, CI). check-plugin-teardown-shape --self-test exit 3 (shallow) then 0 after fetching 621a4876. pnpm lint exit 0. CI check-runs: in_progress at report time.", "dogfood_battery": "f58be8f5 · VERDICT command-exit 0, held 40m35s · Test Files 419 passed 3 skipped (422) · Tests 3492 passed 36 skipped (3528) · no failure", "mcp_calls": "5 — mcp__github__issue_read x3 (get, get_comments x2), mcp__github__pull_request_read x2 (get #30376 precedent, get #30447 read-back); no write tool", "api_writes": "2 — relay pr_create (fleet-write run 42021746367, read-back identical 10451 bytes, #30447); this os-dev-report comment via post-stamped. Plus git push (not REST).", "deviations": [ "file surface widened to packages/plugins/plugin-auth/src/sign-in-method-floor.ts (seat ruling A, 10:22Z)", "harness assign/review-request step skipped per the order's Writes line; PR has no assignee", "session_expiry_days / session_refresh_days now merge over the declared session block instead of replacing it (needed for the mixed clear case)" ], "files_changed": [ ".changeset/30312-auth-settings-clear-applies-default.md", "packages/plugins/plugin-auth/src/auth-plugin.ts", "packages/plugins/plugin-auth/src/auth-settings-declared.ts", "packages/plugins/plugin-auth/src/auth-settings-clear.pin.test.ts", "packages/plugins/plugin-auth/src/sign-in-method-floor.ts" ], "line_budget": "+670 / -29 over 5 files (test 358, helper 141, auth-plugin +138 net)", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "observation · one rate-limit key cleared while the other stays stored: the explicit branch uses built-in fallbacks 10/60 for the cleared half, not the declared rateLimit; pre-existing · carrier: none" ] }Report taken 2026-11-05T11:48Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#2 · os-bill · session_01Utp6Cbvcmv8YWFhFJwzjKL
Landed · 2026-11-05T22:20Z
b5765be3, reviewed headc22645eb(seat ACCEPT 6659515454)Fixes #30312. BREAKING (narrowing): clearing an authentication setting, or resetting the namespace, takes effect at once; the one clear that would lock everyone out is refused at the save door.State change:
pm:dispatchedremoved, assignee cleared.