Serve existing accounts with private dashboard defaults - #3890
roboclaw-bot wants to merge 3 commits into
Conversation
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: blocked before merge. Reviewed September 23, 2026, 2:15 AM ET / 06:15 UTC (Revision 8). ClawSweeper reviewWhat this changesAdds opt-in multi-account HTTP dashboard snapshots with private labels, selected-account metrics, inventory warnings, and preservation of healthy results when another account times out. Merge readiness⛔ Blocked before merge - 2 items remain Keep open: the feature remains absent from main and the latest release, the predecessor’s concrete objections are addressed, and no blocking implementation defect was found. Repository policy excludes automatic closure. Priority: P2 Review scores
Verification
How this fits togetherCodexBar’s HTTP dashboard collects usage from locally configured accounts and presents authenticated JSON snapshots and browser cards. This change expands account collection while retaining the existing provider fetchers and dashboard transport. flowchart TD
A[Local accounts and profiles] --> B[Selected or expanded collection]
C[Authenticated dashboard request] --> B
B --> D[Provider fetches and Claude adapter]
D --> E[Completed usage and account errors]
E --> F[Privacy and selected-account projection]
F --> G[JSON snapshot and browser cards]
Decision needed
Why: The predecessor’s closure established concrete requirements and raised scope concerns; satisfying those requirements does not itself establish acceptance of this larger follow-up. Before merge
Agent review detailsSecurityNone. Review metrics
Technical reviewBest possible solution: Support a serve-only, explicitly enabled account projection with private defaults, existing credential discovery, and unchanged selected-account behavior. Do we have a high-confidence way to reproduce the issue? Not applicable as a new capability; current-main source confirms the missing expansion, and supplied compiled-server captures demonstrate the proposed behavior. Is this the best way to solve the issue? Yes, technically: reusing existing account discovery and the shared snapshot pipeline is a focused approach that preserves current defaults; product acceptance remains separate. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 1c8657a083d5. LabelsLabel changes: No label changes. Label justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (7 earlier review cycles)
|
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
|
Added exact-head compiled-server evidence for 8a2263b: the same malformed managed-account store is silent at d56adea but now yields a generic inventory warning while keeping both healthy profiles. Private/full/redacted, ordinary selected mode, and combined inventory/timeout scenarios passed. Complete sanitized responses, provenance, permanent JSON excerpt and before/after captures are in the PR body. @clawsweeper re-review |
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
|
Thanks @roboclaw-bot. Head |
Summary
Follow-up to #3832, addressing the maintainer’s privacy-default and whole-adapter-failure feedback without changing account management or credentials.
codexbar serve --all-accounts, projecting existing visible Codex profiles and configured token accounts into dashboardaccounts[].--identity fullexplicitly restores identities, aliases and error details;--identity redactedretains masked domains/plan labels but not aliases/raw errors.accountsand reportaccountsError; a successful empty list never falls back to token accounts. Independent provider-level usage remains available./usage,/cost, transport/auth and credential-store behavior remain unchanged.Requested by and co-authored with @VACInc.
Work sessions
Latest follow-up: Claude-swap collection precedence
Source: 418c815. When the enabled Claude adapter owns the dashboard account list, keep ordinary selected/ambient Claude collection for provider-level data, but do not fetch non-selected configured Claude token accounts whose rows would be discarded. Disabling the adapter restores normal opt-in expansion; other providers are unchanged. Adapter failure and successful-empty authority remain unchanged. There is no new UI or JSON shape change.
Actual provider-fetch regression
A compiled regression enters serveUsageOutput, its detached provider coordinator, the real fetchUsageOutputs account loop, and ClaudeUsageFetcher. Task-local synthetic credential/OAuth responses are installed inside the worker, and the actual usage-fetch callback records account IDs. This is collector/provider-path proof, not a new public-HTTP capture or live provider probe. Validation ran in a network-disabled disposable container with test credential/session isolation.
Two synthetic token accounts are configured, with the second active. With the old collection policy (8a2263b plus the test seam), adapter-on expanded collection fetched both accounts and the regression failed: output.payload.count: 2; expected: 1. After the guard, all four combinations pass:
Additional assertions preserve IBM Bob expansion and reject adapter eligibility when Claude is disabled. Existing privacy, adapter-failure/empty-success, inventory and deadline regressions also pass.
Local final verification: 24 focused tests / 4 suites, full 96 selections / 8 groups first-pass with zero retries/timeouts, strict SwiftLint including the new test file, canonical SwiftFormat, and final-follow-up autoreview through P2 passed. Full macOS make check also passed on the exact new source (the local Linux aggregate cannot run macOS plutil).
PASS — exact-source macOS CI: https://github.com/roboclaw-bot/CodexBar/actions/runs/35820172634. Workflow 6159885 checked out source 418c815 explicitly. Full make check, build/discovery, focused regressions/architecture and plugin-engine A/B passed. All 1,338 discovered selections were exercised (683 + 655; 89/89 + 88/88 groups) with zero failures, retries or timeouts. The new Claude-swap collection regression passed on macOS. Earlier runs below apply to their labeled source revisions.
ClawSweeper revision 7, exact source 418c815: no actionable code/security findings; proof accepted. Its merge-readiness status remains blocked pending a maintainer decision accepting the overall serve-only feature scope, separate from the completed collection-guard fix. This does not waive the upstream fork-CI approval gate or constitute merge authorization.
Inventory-warning follow-up (8a2263b)
Source: 8a2263b. Expanded snapshots now warn Account list incomplete if managed Codex inventory is unreadable or configured token-account IDs are missing from the collected rows. Healthy rows remain visible. Represented account failures/timeouts do not masquerade as missing inventory. The warning is generic in every identity mode; ordinary snapshots and raw /usage JSON are unchanged. Configured Claude adapter results still take precedence, including empty success.
Runtime proof
Compared the previous commit d56adea and this commit using the same malformed managed-account store and two synthetic profile homes. The prior server silently returned both visible profiles; the new server returns the same healthy usage plus the inventory warning. The production renderer is unchanged. Both screenshot captures show the normal stale badge because captured snapshots have aged; it is independent of the new warning.
A network-isolated disposable Linux container exercised normal CLI file-discovery paths, with only synthetic homes/accounts and no real credential mounts or Keychain access. Six current-server scenarios passed: healthy inventory, private/full/redacted expansion with corrupt inventory, ordinary selected mode, and corrupt inventory plus a timed-out sibling. Auth401 and no-store were retained; /usage still returned both visible profiles without the internal warning field.
Actual private-mode HTTP response — selected fields, unmodified values
{ "id": "codex", "identity": null, "error": null, "accountsError": "Account list incomplete", "accounts": [ { "label": "Account 1", "active": false, "identity": null, "error": null, "windows": [ { "usedPercent": 20, "label": "Session", "resetAt": "2026-09-23T04:15:10Z", "remainingPercent": 80, "kind": "session" } ] }, { "label": "Account 2", "active": true, "identity": null, "error": null, "windows": [ { "usedPercent": 65, "label": "Session", "resetAt": "2026-09-23T04:15:10Z", "remainingPercent": 35, "kind": "session" } ] } ] }Before
After
Complete new responses, baseline response and provenance
New local proof: all 95 Linux selections / 8 groups passed with no retries or timeouts; 22 focused tests across the three dashboard suites passed, including five new inventory tests with 15 parameterized cases. Canonical SwiftFormat and strict SwiftLint passed, and the complete staged candidate passed independent autoreview through P2.
PASS — inventory-warning head 8a2263b macOS verification: https://github.com/roboclaw-bot/CodexBar/actions/runs/35813570966. Workflow 34c130a explicitly checked out source 8a2263b. Full make check, compilation, focused regressions/architecture, both full-suite shards, and plugin-engine A/B passed. All 1,337 discovered selections were covered (682 + 655; 89/89 and 88/88 groups, no failures, retries or timeouts). The new inventory-warning suite also passed on macOS.
Original feature HTTP evidence (d56adea)
Exact source
d56adeae31dbcd869da4cb59424b759d1f243624. These are field projections of actual JSON returned by the compiled HTTP server, not hand-written expected responses. Complete unmodified response bodies and provenance are linked below. All names/emails are synthetic; no real credentials, private paths, hostnames or IP addresses are published.The server used isolated local fixtures with external networking disabled. Codex used a synthetic OAuth usage endpoint. Claude used a fake executable through the real subprocess reader, parser and dashboard projection, with one configured token account deliberately present as a possible fallback. No activation or real Keychain/provider access occurred.
Assertions passed: five Codex scenarios and nine Claude scenarios; private/full/redacted identity behavior; non-email alias and raw-error suppression; healthy sibling retention; whole-adapter failure omits the accounts key; successful empty adapter results retain accounts: [] without token fallback. Every Claude scenario also checked authenticated HTTP 200, unauthenticated 401 and Cache-Control: no-store.
The excerpts below are retained directly in this PR body. Full-artifact signed links expire on 2026-09-30.
codex-private
{ "id": "codex", "identity": null, "error": null, "accounts": [ { "id": "codex:af162a5bb1a39dbfc0cc4d404a65f7c20f6c2e583da59ea3662f1a725c1fb986", "label": "Account 1", "active": false, "identity": null, "error": null, "windows": [ { "usedPercent": 20, "kind": "session", "label": "Session", "remainingPercent": 80, "resetAt": "2026-09-22T19:58:27Z" } ] }, { "id": "codex:4ef86dbdc02577ece42b520e66b61bedf56d54d86b2b9720430ff1394b116084", "label": "Account 2", "active": true, "identity": null, "error": null, "windows": [ { "usedPercent": 65, "kind": "session", "label": "Session", "remainingPercent": 35, "resetAt": "2026-09-22T19:58:27Z" } ] } ] }codex-full
{ "id": "codex", "identity": { "accountEmail": "fixture2@example.test", "plan": "Plus" }, "error": null, "accounts": [ { "id": "codex:af162a5bb1a39dbfc0cc4d404a65f7c20f6c2e583da59ea3662f1a725c1fb986", "label": "fixture1@example.test", "active": false, "identity": { "accountEmail": "fixture1@example.test", "plan": "Plus" }, "error": null, "windows": [ { "kind": "session", "usedPercent": 20, "resetAt": "2026-09-22T19:58:28Z", "label": "Session", "remainingPercent": 80 } ] }, { "id": "codex:4ef86dbdc02577ece42b520e66b61bedf56d54d86b2b9720430ff1394b116084", "label": "fixture2@example.test", "active": true, "identity": { "accountEmail": "fixture2@example.test", "plan": "Plus" }, "error": null, "windows": [ { "kind": "session", "usedPercent": 65, "resetAt": "2026-09-22T19:58:28Z", "label": "Session", "remainingPercent": 35 } ] } ] }codex-redacted
{ "id": "codex", "identity": { "accountEmail": "redacted@example.test", "plan": "Plus" }, "error": null, "accounts": [ { "id": "codex:af162a5bb1a39dbfc0cc4d404a65f7c20f6c2e583da59ea3662f1a725c1fb986", "label": "Account 1", "active": false, "identity": { "accountEmail": "redacted@example.test", "plan": "Plus" }, "error": null, "windows": [ { "usedPercent": 20, "resetAt": "2026-09-22T19:58:28Z", "label": "Session", "remainingPercent": 80, "kind": "session" } ] }, { "id": "codex:4ef86dbdc02577ece42b520e66b61bedf56d54d86b2b9720430ff1394b116084", "label": "Account 2", "active": true, "identity": { "accountEmail": "redacted@example.test", "plan": "Plus" }, "error": null, "windows": [ { "usedPercent": 65, "resetAt": "2026-09-22T19:58:28Z", "label": "Session", "remainingPercent": 35, "kind": "session" } ] } ] }codex-timeout
{ "id": "codex", "identity": null, "error": { "kind": "provider", "code": 1, "message": "Account usage unavailable" }, "accounts": [ { "id": "codex:af162a5bb1a39dbfc0cc4d404a65f7c20f6c2e583da59ea3662f1a725c1fb986", "label": "Account 1", "active": false, "identity": null, "error": null, "windows": [ { "label": "Session", "remainingPercent": 80, "kind": "session", "usedPercent": 20, "resetAt": "2026-09-22T19:58:29Z" } ] }, { "id": "codex:4ef86dbdc02577ece42b520e66b61bedf56d54d86b2b9720430ff1394b116084", "label": "Account 2", "active": true, "identity": null, "error": "Account usage unavailable", "windows": [] } ] }claude-rows-private
{ "id": "claude", "identity": null, "error": { "message": "Account usage unavailable", "code": 1, "kind": "runtime" }, "accounts": [ { "id": "claude-swap:1", "label": "Account 1", "active": true, "identity": null, "error": null, "windows": [ { "kind": "session", "label": "Session", "usedPercent": 20, "remainingPercent": 80, "resetAt": null } ] }, { "id": "claude-swap:2", "label": "Account 2", "active": false, "identity": null, "error": "Account usage unavailable", "windows": [] } ] }claude-rows-full
{ "id": "claude", "identity": null, "error": { "kind": "runtime", "message": "Error: selected source requires web support and is only supported on macOS.", "code": 1 }, "accounts": [ { "id": "claude-swap:1", "label": "Private Team", "active": true, "identity": { "plan": null, "accountEmail": "fixture1@example.test" }, "error": null, "windows": [ { "remainingPercent": 80, "label": "Session", "kind": "session", "usedPercent": 20, "resetAt": null } ] }, { "id": "claude-swap:2", "label": "Secret Client", "active": false, "identity": { "plan": null, "accountEmail": "fixture2@example.test" }, "error": "Unrecognized claude-swap status: private failure for Private Team fixture2@example.test", "windows": [] } ] }claude-rows-redacted
{ "id": "claude", "identity": null, "error": { "code": 1, "message": "Account usage unavailable", "kind": "runtime" }, "accounts": [ { "id": "claude-swap:1", "label": "Account 1", "active": true, "identity": { "plan": null, "accountEmail": "redacted@example.test" }, "error": null, "windows": [ { "label": "Session", "usedPercent": 20, "remainingPercent": 80, "kind": "session", "resetAt": null } ] }, { "id": "claude-swap:2", "label": "Account 2", "active": false, "identity": { "accountEmail": "redacted@example.test", "plan": null }, "error": "Account usage unavailable", "windows": [] } ] }claude-failure-private
{ "id": "claude", "identity": null, "error": { "message": "Account usage unavailable", "code": 1, "kind": "runtime" }, "accountsError": "Account list unavailable" }claude-failure-full
{ "id": "claude", "identity": null, "error": { "kind": "runtime", "code": 1, "message": "Error: selected source requires web support and is only supported on macOS." }, "accountsError": "claude-swap reported FixtureError: Private Team fixture2@example.test unavailable" }claude-failure-redacted
{ "id": "claude", "identity": null, "error": { "message": "Account usage unavailable", "code": 1, "kind": "runtime" }, "accountsError": "Account list unavailable" }claude-empty-private
{ "id": "claude", "identity": null, "error": { "code": 1, "kind": "runtime", "message": "Account usage unavailable" }, "accounts": [] }Complete captured HTTP bodies and provenance
Original feature verification (d56adea)
Independent full-candidate autoreview: scoped-clean through P2; final review includes lint cleanup/helper relocation.
Swift 6.3.3 Linux compilation and
make test: 94 discovered selections, all 8 groups passed first attempt; zero failures, retries or timeouts.Focused account/privacy regressions: 17 test methods with parameterized cases, including non-email aliases, selected-account failures, adapter failures in both scopes, successful-empty adapter precedence and warm identity-cache separation.
Repository portable/script/JavaScript/type/documentation gates passed. SwiftLint passed all 2,572 configured files and both additional Linux regression files. Canonical SwiftFormat passed 2,573 files (five skipped by repository configuration), plus both new Linux regression files.
Real compiled HTTP server with isolated synthetic profiles: selected/private/full/redacted/timeout scenarios passed; unauthorized dashboard requests returned 401; responses retained no-store;
/usagekept both account identities. No live provider credentials or Keychain access.Production web renderer with captured HTTP responses at 1200×800 light and 390px dark: private labels, selected marker, no narrow overflow, selected Codex credits shown only on that account.
PASS — exact-source macOS verification: https://github.com/roboclaw-bot/CodexBar/actions/runs/35805101500. Workflow commit 6ef2489 checked out source d56adea. Full make check, focused account/deadline/rendering/architecture regressions, both full-suite shards, and provider plugin-engine A/B checks passed. The shards covered all 1,336 discovered selections (681 + 655), with 89/89 and 88/88 groups passing first attempt, no failures, retries or timeouts.
Upstream approval gate
This host is Linux; the macOS-only gates unavailable locally were completed by the exact-source fork run above. Upstream fork CI requires maintainer approval; the fresh head’s workflow status must be checked independently. Independent fork verification does not approve, bypass or replace that gate. No merge has been performed.
Visual evidence
Signed proof image links expire on 2026-09-30.
Production renderer using synthetic responses from the compiled HTTP server; 1200×800/light. The first view is the unchanged selected-account mode; the second is the new private expanded mode.
Before
After
Scope notes
The one-shot
dashboardcommand gets no new flag. Existing provider fetching is reused; most added lines are regression tests. Stable public IDs are correlation handles, not an anonymity promise. Browser snapshots previously served with explicit identity remain client-held data; signing out clears the built-in browser cache.View the OpenClaw team session