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
Allowed IP ranges console field: show the caller's current address before saving, and show the refusal's address when a save would lock the admin out #30313
Filing gate: ② the ui half of #30203 (PR #30309 adds the server refusal), noted by its dev (os-dev-report 6650755695, carrier domain:ui). ⛔ Not a claim. Triage sets lane and grade.
Reader: the authentication settings page, field allowed_ip_ranges.
Dedupe: allowed ip ranges → only #30203. New.
What is missing
After PR #30309, a save whose list leaves out the saving request's own address is refused: 400 SETTINGS_VALIDATION, invalid_value, with the address in constraint.clientAddress and a localized message naming the recovery (OS_AUTH_ALLOWED_IP_RANGES set empty). The console field does not tell the admin their current address before saving, so the first they learn of it is the refusal.
Wanted
Show the caller's current address (as the server resolves it, trustProxy included) beside the field.
On the refusal, show constraint.clientAddress next to the field rather than a generic error.
Claim: PM loop round 3 · 2026-11-05T09:15Z
Session: session_01Utp6CXwx3YCQLACa3k46id (card thread, os-dev); dispatched by seat session session_01Utp6CbPN5UYMnBaNJPJWfG
Account: os-bill
Branch: claude/project-thread-u7ugt9 (platform-assigned to the card thread; it can push only this branch)
Worktree: objectstack-issue-30313
Domain: domain:ui
Seat: domain:ui#3
File surface: the Setup settings form's field-error rendering (located by the dev), ui/packages/i18n/src/** strings if needed, their tests, one root .changeset/ file; ⛔ packages/** (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default tier (opus) — dispatch-gates --tier at 870ebce3: no path-derived mandate, effort: high
Clause-②: yes (widening) if @object-ui/i18n keys or a published export are added; the dev measures and the seat corrects to no if none
Metadata-protocol: none
Responsibility: an admin saving allowed IP ranges cannot see which address the server will judge, and a refusal shows a generic error | server half #30203 (PR #30309) refuses a list that leaves out the saver's own address and names it in constraint.clientAddress | admins setting org IP restrictions
Thread-read: 6651929906
Premise: holds
Serial constraints cleared: server half PR #30309 merged (d1d90b7). Item 1 needs a served read of the caller's address; if none exists, it goes out of scope as a server card and the PR says Refs #30313. main red at claim (#30367), not this card's.
Card thread session session_01Utp6CXwx3YCQLACa3k46id, branch claude/project-thread-u7ugt9, measured at 870ebce3 (origin/main). No PR: item 2 is already delivered on main, and item 1 has no served read to build on.
Item 2, measured live (showcase backend objectstack dev --seed-admin --fresh plus the branch's Console under vite, Playwright, admin signed in, Setup, System, Settings, auth): typing 203.0.113.0/24 into Allowed IP ranges and pressing Save changes sends PUT /api/settings/auth, answered 400 SETTINGS_VALIDATION with details.fields[0] = field allowed_ip_ranges, code invalid_value, constraint.clientAddress127.0.0.1, and a message that names that address. The settings page's existing generic path (extractFieldErrors in @object-ui/react, the fieldErrors slot in SettingsView, FieldError under the row in SettingsField) renders that message in red directly under the textarea: "No entry in this list matches 127.0.0.1, the address you are connected from, so saving it would refuse your own next sign-in. Add your address or its range to the list, or save the list from an address it matches. If you are locked out, start the server with OS_AUTH_ALLOWED_IP_RANGES set to an empty value." The toast reads "1 setting needs attention: Allowed IP ranges". So the refusal already shows the address next to the field, not a generic error; the card's premise for item 2 does not hold. The server builds the sentence per request locale (en, zh-CN, ja-JP, es-ES), so the address reaches the row in every shipped locale.
Item 1: no route answers the caller's address as the server resolves it. AuthManager.resolveClientAddress is read only inside the D5 allow-list middleware, the invitation-preview door and the settings write predicate; nothing serves it. The client must not guess it, so item 1 is server work, reported below for the seat to file.
{
"issue": 30313,
"status": "done",
"branch": "claude/project-thread-u7ugt9",
"pr": null,
"session": "session_01Utp6CXwx3YCQLACa3k46id",
"premise_still_valid": false,
"summary": "Item 2 is already delivered on main: a refused save shows the server's sentence naming constraint.clientAddress in red under the Allowed IP ranges field (measured live at 870ebce3, PUT /api/settings/auth 400 SETTINGS_VALIDATION, row text quoted above). Item 1 needs a served read of the caller's address as the server resolves it; none exists, so it is reported out of scope as server work. No code change, no PR.",
"tests": "No diff, so no tests owed. Live measurement: showcase closure built under os-verify-lock (VERDICT command-exit 0), objectstack dev --seed-admin --fresh, Console via vite with DEV_PROXY_TARGET, Playwright save of 203.0.113.0/24: response 400 with constraint.clientAddress 127.0.0.1; row innerText = label plus the refusal sentence naming 127.0.0.1.",
"gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack :: exit 2, its line: this branch changes nothing against origin/main (merge base 870ebce33), nothing to derive; no other gate owed",
"dogfood_battery": "n/a — no PR",
"mcp_calls": "3 — mcp__github__issue_read (get, get_comments x2); no write tool",
"api_writes": "1 — this comment via post-stamped (POST issues/30313/comments)",
"open_questions": [],
"security_findings": "withheld",
"out_of_scope_findings": [
"carrier: domain:server (seat files) · the Allowed IP ranges field cannot show the admin's current address before saving because no route serves the caller's address as AuthManager.resolveClientAddress establishes it (trustProxy included); a served read, for example a field on an authenticated settings or auth read, is the server half item 1 needs, and the Console row would then show it beside the field · dedupe words: allowed ip ranges current address, resolveClientAddress read, caller client address"
]
}
Release: 2026-11-05T09:34Z — the domain:ui#3 claim 6654241338 ends with no PR (premise_still_valid: false, os-dev-report 6654556555).
Item 2 (the refusal's address beside the field) already holds on main at 870ebce3: the generic settings field-error path shows the server's sentence naming constraint.clientAddress directly under Allowed IP ranges, and the toast names the setting. Measured with Playwright (shot in the report). No ui change needed.
The card goes back to pm:queue for item 1's ui half once #30398 lands. If triage prefers to close it and let #30398 carry the whole of item 1, that is fine too.
Claim: PM loop round 3 · 2026-11-05T14:24Z
Session: session_01L6bhgVfPeFZkN1FP93imKU (seat); the dev is a card thread the project's coordinator opens
Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
Branch: the card thread's designated claude/project-thread-* branch, named in a claim amendment once the thread reports it
Worktree: objectstack-issue-30313
Domain: domain:ui
Seat: domain:ui#4 (the ui seats' split of 2026-11-05T14:16Z gives #30313 to this seat once #30398 lands)
File surface: ui/apps/console/src/pages/settings/** (the read in api.ts, the address beside the allowed_ip_ranges row in SettingsField.tsx / SettingsView.tsx); the console locale files for any new words, in every shipped locale; their tests; one root .changeset/ file. ⛔ packages/** (the server read is #30398's, landed). No open PR touches ui/apps/console/src/pages/settings/** (read across the 59 open PRs just now)
Container & model: M, mode:thread, model: default (dispatch-gates --tier at fa9c0aa2: no path-derived mandate; floor sonnet · default opus · ceiling fable), effort: high
Clause-②: no: a console read of a served route; if a package gains an export, the dev declares it and the seat corrects this line to yes
Metadata-protocol: none
Responsibility: the Allowed IP ranges row does not show the caller's address as the server judges it before a save | GET /api/v1/auth/admin/client-address (PR #30483, platform-admin gate, no-store) answers { clientAddress, trustProxy } from judgedClientAddress, the same call the save check uses | every admin who edits Allowed IP ranges
Thread-read: 6654596793
Premise: item 1 holds, read at origin/mainfa9c0aa2: ui/ has no caller of client-address. Blocked-by: #30398 is closed (2026-11-05T13:56Z, PR #30483 merged, landing 6659838213). Item 2 already holds on main (os-dev-report 6654556555, measured live at 870ebce3), so the dev re-measures it and does not rebuild it; if it still holds, the PR may say Fixes #30313.
Serial constraints cleared: none in flight on the surface; #30399 and PR #30531 (this seat) are in pages/auth/, not pages/settings/.
席位核对 · Amendment · 2026-11-05T14:27Z · claim 6660433935 branch named
Branch: claude/project-thread-7phf7w
The card thread's harness-designated branch (a project-thread platform exception to the claude/issue-<n>-<slug> convention), based on origin/mainfa9c0aa2, which holds PR #30483; the dev thread is session session_01L6bhgVFhcnGrB1Wp8fLTwB. Everything else in claim 6660433935 stands.
Card thread session session_01L6bhgVFhcnGrB1Wp8fLTwB, branch claude/project-thread-7phf7w (claim 6660433935, amendment 6660489115 names it), base fa9c0aa2. Draft PR #30540, head da21d372 (code head 7dbb9868; two evidence commits after it add and remove five PNGs, net zero).
Item 1, delivered. The Authentication settings page reads GET /api/v1/auth/admin/client-address (PR #30483) and draws one line under Allowed IP ranges: the judged address, plus which source it came from (trustProxy on: a trusted proxy's forwarded headers; off: the connection itself, which behind a proxy is the proxy's address), or, for clientAddress: null, that a non-empty list cannot be saved from here. A refused or failed read draws nothing. Live at da21d372: the read answers 200 no-store{ clientAddress: 127.0.0.1, trustProxy: false } for the seeded admin, and the row shows "Your address, as the server judges it: 127.0.0.1. ..." (zh-CN: "服务器判定的你的地址:127.0.0.1。...").
Item 2, re-measured, still holds. Saving 203.0.113.0/24 answers 400 SETTINGS_VALIDATION, invalid_value, constraint.clientAddress127.0.0.1, and the row shows the server's sentence naming 127.0.0.1 in red under the field, with the new line kept beside it. So the PR says Fixes #30313.
Screenshots (before/after, en-US and zh-CN) are in the PR body.
{
"issue": 30313,
"status": "done",
"branch": "claude/project-thread-7phf7w",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30540",
"session": "session_01L6bhgVFhcnGrB1Wp8fLTwB",
"premise_still_valid": true,
"summary": "Item 1: the console reads GET /api/v1/auth/admin/client-address on the auth settings page and draws the judged address under Allowed IP ranges, in one of three sentences (trustProxy off, on, or no address), in all ten shipped packs; any failed read draws nothing. SettingsField gains an optional note slot named by the control's aria-describedby. Item 2 re-measured live and still holds (the refusal names constraint.clientAddress under the row), so the PR uses Fixes. Files: ui/apps/console/src/pages/settings/{api.ts,SettingsView.tsx,SettingsField.tsx}, one new test file, ui/packages/i18n/src/locales/*.ts (3 keys each), one root changeset (@object-ui/console, @object-ui/i18n patch). No packages/** path.",
"tests": "ui/: vitest run apps/console/src/pages/settings under os-verify-lock at 7dbb9868: Test Files 35 passed (35), Tests 297 passed (297), VERDICT command-exit 0; the new file SettingsView.clientAddress-30313.test.tsx has 9 cases. Ablation via ablation-replace.mjs (anchor clientAddressNote call to undefined, anchor 1 to 0, blob b5ed73e9 to d292d590): 4 failed, 5 passed (the presence cases red, the absence cases green as expected); restored, blob equals HEAD, git diff HEAD empty. Live rig: showcase objectstack dev --seed-admin plus the branch console under vite plus Playwright, readings quoted above and in the PR body.",
"gates": "dispatch-gates --commands at 7dbb9868 (15 paths, after deepening the shallow clone to find the merge base): 35 derived, 35 run, all exit 0; --ran: 35 run, 0 NOT-MEASURED, 0 UNRUN. Also @object-ui/console type-check and @object-ui/i18n type-check after building the console closure: VERDICT command-exit 0. eslint on the changed files: 0 errors, 5 pre-existing warnings on untouched lines. CI check-runs on #30540: in_progress at report time; the seat reads them.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — fleet-write relay pr_create (PR #30540), and this os-dev-report comment via post-stamped",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": ["carrier: none · noted, not filed: the en pack sits in the eager closure and gains three sentences; CI's Bundle Analysis measures the budget"]
}
State change: pm:dispatched removed; nothing remains on this card. The follow-up from #30398's landing (one line in authentication.mdx now that the UI shows the address) is the domain:server#2 seat's; this record is its notice.
Activity
objectstack-fleet commentedon Nov 5, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 ·
domain:ui·pm:queue· 2026-11-05T07:03Z⛔ Not a claim.
domain:uihalf of Allowed IP ranges: an administrator can exclude their own address unwarned, and clearing the field does not take effect until a restart #30203: the allowed-IP-ranges field shows the caller's current address before saving, and the refusal's address when a save would lock the admin out. p2, as Allowed IP ranges: an administrator can exclude their own address unwarned, and clearing the field does not take effect until a restart #30203.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG
Claim: PM loop round 3 · 2026-11-05T09:15Z
Session:
session_01Utp6CXwx3YCQLACa3k46id(card thread, os-dev); dispatched by seat sessionsession_01Utp6CbPN5UYMnBaNJPJWfGAccount:
os-billBranch:
claude/project-thread-u7ugt9(platform-assigned to the card thread; it can push only this branch)Worktree:
objectstack-issue-30313Domain:
domain:uiSeat:
domain:ui#3File surface: the Setup settings form's field-error rendering (located by the dev),
ui/packages/i18n/src/**strings if needed, their tests, one root.changeset/file; ⛔packages/**(stop on breach; explain in the report)Container & model:
M,mode:thread,model: default tier (opus) — dispatch-gates --tier at 870ebce3: no path-derived mandate,effort: highClause-②: yes (widening) if
@object-ui/i18nkeys or a published export are added; the dev measures and the seat corrects tonoif noneMetadata-protocol: none
Responsibility: an admin saving allowed IP ranges cannot see which address the server will judge, and a refusal shows a generic error | server half #30203 (PR #30309) refuses a list that leaves out the saver's own address and names it in
constraint.clientAddress| admins setting org IP restrictionsThread-read: 6651929906
Premise: holds
Serial constraints cleared: server half PR #30309 merged (d1d90b7). Item 1 needs a served read of the caller's address; if none exists, it goes out of scope as a server card and the PR says
Refs #30313. main red at claim (#30367), not this card's.objectstack-fleet commentedon Nov 5, 2026
domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG
os-dev-report
Card thread session
session_01Utp6CXwx3YCQLACa3k46id, branchclaude/project-thread-u7ugt9, measured at870ebce3(origin/main). No PR: item 2 is already delivered on main, and item 1 has no served read to build on.Item 2, measured live (showcase backend
objectstack dev --seed-admin --freshplus the branch's Console under vite, Playwright, admin signed in, Setup, System, Settings,auth): typing203.0.113.0/24into Allowed IP ranges and pressing Save changes sendsPUT /api/settings/auth, answered 400SETTINGS_VALIDATIONwithdetails.fields[0]= fieldallowed_ip_ranges, codeinvalid_value,constraint.clientAddress127.0.0.1, and a message that names that address. The settings page's existing generic path (extractFieldErrorsin@object-ui/react, thefieldErrorsslot inSettingsView,FieldErrorunder the row inSettingsField) renders that message in red directly under the textarea: "No entry in this list matches 127.0.0.1, the address you are connected from, so saving it would refuse your own next sign-in. Add your address or its range to the list, or save the list from an address it matches. If you are locked out, start the server with OS_AUTH_ALLOWED_IP_RANGES set to an empty value." The toast reads "1 setting needs attention: Allowed IP ranges". So the refusal already shows the address next to the field, not a generic error; the card's premise for item 2 does not hold. The server builds the sentence per request locale (en, zh-CN, ja-JP, es-ES), so the address reaches the row in every shipped locale.Item 1: no route answers the caller's address as the server resolves it.
AuthManager.resolveClientAddressis read only inside the D5 allow-list middleware, the invitation-preview door and the settings write predicate; nothing serves it. The client must not guess it, so item 1 is server work, reported below for the seat to file.{ "issue": 30313, "status": "done", "branch": "claude/project-thread-u7ugt9", "pr": null, "session": "session_01Utp6CXwx3YCQLACa3k46id", "premise_still_valid": false, "summary": "Item 2 is already delivered on main: a refused save shows the server's sentence naming constraint.clientAddress in red under the Allowed IP ranges field (measured live at 870ebce3, PUT /api/settings/auth 400 SETTINGS_VALIDATION, row text quoted above). Item 1 needs a served read of the caller's address as the server resolves it; none exists, so it is reported out of scope as server work. No code change, no PR.", "tests": "No diff, so no tests owed. Live measurement: showcase closure built under os-verify-lock (VERDICT command-exit 0), objectstack dev --seed-admin --fresh, Console via vite with DEV_PROXY_TARGET, Playwright save of 203.0.113.0/24: response 400 with constraint.clientAddress 127.0.0.1; row innerText = label plus the refusal sentence naming 127.0.0.1.", "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack :: exit 2, its line: this branch changes nothing against origin/main (merge base 870ebce33), nothing to derive; no other gate owed", "dogfood_battery": "n/a — no PR", "mcp_calls": "3 — mcp__github__issue_read (get, get_comments x2); no write tool", "api_writes": "1 — this comment via post-stamped (POST issues/30313/comments)", "open_questions": [], "security_findings": "withheld", "out_of_scope_findings": [ "carrier: domain:server (seat files) · the Allowed IP ranges field cannot show the admin's current address before saving because no route serves the caller's address as AuthManager.resolveClientAddress establishes it (trustProxy included); a served read, for example a field on an authenticated settings or auth read, is the server half item 1 needs, and the Console row would then show it beside the field · dedupe words: allowed ip ranges current address, resolveClientAddress read, caller client address" ] }Report taken 2026-11-05T09:32Z.
objectstack-fleet commentedon Nov 5, 2026
domain:ui#3 · os-bill · session_01Utp6CbPN5UYMnBaNJPJWfG
Release: 2026-11-05T09:34Z — the
domain:ui#3claim 6654241338 ends with no PR (premise_still_valid: false, os-dev-report 6654556555).870ebce3: the generic settings field-error path shows the server's sentence namingconstraint.clientAddressdirectly under Allowed IP ranges, and the toast names the setting. Measured with Playwright (shot in the report). No ui change needed.resolveClientAddress's result. Filed Allowed IP ranges: no route serves the caller's address as the server resolves it, so the console cannot show an admin which address the lock-out check will judge before they save #30398 (domain:server, untriaged).Blocked-by: #30398
Resume-from: none
The card goes back to
pm:queuefor item 1's ui half once #30398 lands. If triage prefers to close it and let #30398 carry the whole of item 1, that is fine too.objectstack-fleet commentedon Nov 5, 2026
domain:ui#4 · os-sales · session_01L6bhgVfPeFZkN1FP93imKU
Claim: PM loop round 3 · 2026-11-05T14:24Z
Session:
session_01L6bhgVfPeFZkN1FP93imKU(seat); the dev is a card thread the project's coordinator opensAccount:
os-sales(the seat's linked user asGET /useranswers it; the card's assignee)Branch: the card thread's designated
claude/project-thread-*branch, named in a claim amendment once the thread reports itWorktree:
objectstack-issue-30313Domain:
domain:uiSeat:
domain:ui#4(the ui seats' split of 2026-11-05T14:16Z gives #30313 to this seat once #30398 lands)File surface:
ui/apps/console/src/pages/settings/**(the read inapi.ts, the address beside theallowed_ip_rangesrow inSettingsField.tsx/SettingsView.tsx); the console locale files for any new words, in every shipped locale; their tests; one root.changeset/file. ⛔packages/**(the server read is #30398's, landed). No open PR touchesui/apps/console/src/pages/settings/**(read across the 59 open PRs just now)Container & model:
M,mode:thread,model: default(dispatch-gates --tieratfa9c0aa2: no path-derived mandate; floor sonnet · default opus · ceiling fable),effort: highClause-②: no: a console read of a served route; if a package gains an export, the dev declares it and the seat corrects this line to
yesMetadata-protocol: none
Responsibility: the Allowed IP ranges row does not show the caller's address as the server judges it before a save |
GET /api/v1/auth/admin/client-address(PR #30483, platform-admin gate,no-store) answers{ clientAddress, trustProxy }fromjudgedClientAddress, the same call the save check uses | every admin who edits Allowed IP rangesThread-read: 6654596793
Premise: item 1 holds, read at
origin/mainfa9c0aa2:ui/has no caller ofclient-address.Blocked-by: #30398is closed (2026-11-05T13:56Z, PR #30483 merged, landing 6659838213). Item 2 already holds on main (os-dev-report 6654556555, measured live at870ebce3), so the dev re-measures it and does not rebuild it; if it still holds, the PR may sayFixes #30313.Serial constraints cleared: none in flight on the surface; #30399 and PR #30531 (this seat) are in
pages/auth/, notpages/settings/.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:ui#4 · os-sales · session_01L6bhgVfPeFZkN1FP93imKU
席位核对 · Amendment · 2026-11-05T14:27Z · claim 6660433935 branch named
Branch:
claude/project-thread-7phf7wThe card thread's harness-designated branch (a project-thread platform exception to the
claude/issue-<n>-<slug>convention), based onorigin/mainfa9c0aa2, which holds PR #30483; the dev thread is sessionsession_01L6bhgVFhcnGrB1Wp8fLTwB. Everything else in claim 6660433935 stands.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:ui#4 · os-sales · session_01L6bhgVFhcnGrB1Wp8fLTwB
os-dev-report
Card thread session
session_01L6bhgVFhcnGrB1Wp8fLTwB, branchclaude/project-thread-7phf7w(claim 6660433935, amendment 6660489115 names it), basefa9c0aa2. Draft PR #30540, headda21d372(code head7dbb9868; two evidence commits after it add and remove five PNGs, net zero).Item 1, delivered. The Authentication settings page reads
GET /api/v1/auth/admin/client-address(PR #30483) and draws one line under Allowed IP ranges: the judged address, plus which source it came from (trustProxyon: a trusted proxy's forwarded headers; off: the connection itself, which behind a proxy is the proxy's address), or, forclientAddress: null, that a non-empty list cannot be saved from here. A refused or failed read draws nothing. Live atda21d372: the read answers 200no-store{ clientAddress: 127.0.0.1, trustProxy: false }for the seeded admin, and the row shows "Your address, as the server judges it: 127.0.0.1. ..." (zh-CN: "服务器判定的你的地址:127.0.0.1。...").Item 2, re-measured, still holds. Saving
203.0.113.0/24answers 400SETTINGS_VALIDATION,invalid_value,constraint.clientAddress127.0.0.1, and the row shows the server's sentence naming 127.0.0.1 in red under the field, with the new line kept beside it. So the PR saysFixes #30313.Screenshots (before/after, en-US and zh-CN) are in the PR body.
{ "issue": 30313, "status": "done", "branch": "claude/project-thread-7phf7w", "pr": "https://github.com/objectstack-ai/objectstack/pull/30540", "session": "session_01L6bhgVFhcnGrB1Wp8fLTwB", "premise_still_valid": true, "summary": "Item 1: the console reads GET /api/v1/auth/admin/client-address on the auth settings page and draws the judged address under Allowed IP ranges, in one of three sentences (trustProxy off, on, or no address), in all ten shipped packs; any failed read draws nothing. SettingsField gains an optional note slot named by the control's aria-describedby. Item 2 re-measured live and still holds (the refusal names constraint.clientAddress under the row), so the PR uses Fixes. Files: ui/apps/console/src/pages/settings/{api.ts,SettingsView.tsx,SettingsField.tsx}, one new test file, ui/packages/i18n/src/locales/*.ts (3 keys each), one root changeset (@object-ui/console, @object-ui/i18n patch). No packages/** path.", "tests": "ui/: vitest run apps/console/src/pages/settings under os-verify-lock at 7dbb9868: Test Files 35 passed (35), Tests 297 passed (297), VERDICT command-exit 0; the new file SettingsView.clientAddress-30313.test.tsx has 9 cases. Ablation via ablation-replace.mjs (anchor clientAddressNote call to undefined, anchor 1 to 0, blob b5ed73e9 to d292d590): 4 failed, 5 passed (the presence cases red, the absence cases green as expected); restored, blob equals HEAD, git diff HEAD empty. Live rig: showcase objectstack dev --seed-admin plus the branch console under vite plus Playwright, readings quoted above and in the PR body.", "gates": "dispatch-gates --commands at 7dbb9868 (15 paths, after deepening the shallow clone to find the merge base): 35 derived, 35 run, all exit 0; --ran: 35 run, 0 NOT-MEASURED, 0 UNRUN. Also @object-ui/console type-check and @object-ui/i18n type-check after building the console closure: VERDICT command-exit 0. eslint on the changed files: 0 errors, 5 pre-existing warnings on untouched lines. CI check-runs on #30540: in_progress at report time; the seat reads them.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 — fleet-write relay pr_create (PR #30540), and this os-dev-report comment via post-stamped", "open_questions": [], "security_findings": "none", "out_of_scope_findings": ["carrier: none · noted, not filed: the en pack sits in the eager closure and gains three sentences; CI's Bundle Analysis measures the budget"] }objectstack-fleet commentedon Nov 5, 2026
domain:ui#4 · os-sales · session_01L6bhgVfPeFZkN1FP93imKU
Landing record · 2026-11-05T16:17Z
PR #30540 merged 2026-11-05T16:15Z as
b6f4c0e8b7(seat ACCEPT 6661693056 on headda21d372),Fixes #30313.git grep -c client-address origin/main -- ui/apps/console/src/pages/settings/api.tsgit grep -c clientAddressNote origin/main -- ui/apps/console/src/pages/settings/SettingsView.tsxState change:
pm:dispatchedremoved; nothing remains on this card. The follow-up from #30398's landing (one line inauthentication.mdxnow that the UI shows the address) is thedomain:server#2seat's; this record is its notice.Generated by Claude Code