Skip to content

release: merge current main-target PR set#318

Open
ndycode wants to merge 145 commits intomainfrom
release/mainbound-20260323
Open

release: merge current main-target PR set#318
ndycode wants to merge 145 commits intomainfrom
release/mainbound-20260323

Conversation

@ndycode
Copy link
Owner

@ndycode ndycode commented Mar 22, 2026

Summary

Merge the current main-target PR set through a single verified release branch.

Included PRs: #140 #141 #149 #263 #298 #299 #300 #302 #303 #304 #306 #307 #308 #309

Additional release fixes

  • fix optional dashboard display dependency in forecast command tests
  • tighten backend settings schema max for sessionAffinityMaxEntries
  • treat EACCES as retryable for queued settings writes
  • fix docs parity coverage for extracted switch command docs
  • correct backup metadata latest-valid-path selection priority
  • add storage regressions around named-backup export snapshot isolation

Local validation

  • npm run clean:repo:check
  • npm run typecheck
  • npm run build
  • npm run lint
  • npm test -- test/storage.test.ts test/named-backup-export.test.ts test/storage-recovery-paths.test.ts test/backup-metadata-builder.test.ts
  • npx vitest run --maxWorkers=1 --silent --shard=1/4
  • npx vitest run --maxWorkers=1 --silent --shard=2/4
  • npx vitest run --maxWorkers=1 --silent --shard=1/8
  • npx vitest run --maxWorkers=1 --silent --shard=2/8
  • npx vitest run --maxWorkers=1 --silent --shard=3/8
  • npx vitest run --maxWorkers=1 --silent --shard=4/8
  • npx vitest run --maxWorkers=1 --silent --shard=5/8

Known local blocker

  • larger remaining Vitest shard runs hit a local worker OOM before any concrete failing assertion was identified; this PR exists to get the authoritative Ubuntu/Node CI result on the combined release state before merging to main.

note: greptile review for oc-chatgpt-multi-auth. cite files like lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.

Greptile Summary

this release PR merges 14 main-target PRs — the bulk is a large codex-manager refactor extracting auth commands, settings panels, and repair/forecast commands into dedicated modules under lib/codex-manager/, alongside a set of targeted fixes: corrected backup metadata latestValidPath priority (discovered backups now beat WAL even when WAL is newer), EACCES added to retryable settings write codes, optional loadDashboardDisplaySettings dep in forecast command tests, switch command docs parity, and storage regressions for named-backup snapshot isolation and flagged transaction rollback.

  • bug: proactiveRefreshGuardian toggle and proactiveRefreshIntervalMs number setting are defined in BACKEND_TOGGLE_OPTIONS / BACKEND_NUMBER_OPTIONS but omitted from every BACKEND_CATEGORY_OPTIONS category — these controls are silently unreachable in the backend settings UI; they belong in "refresh-recovery"
  • settings-write-queue.ts: per-path write queue serialization and EACCES addition look correct; the TOCTOU-aware mtime logging in named-backups.ts is good practice
  • backup-metadata-builder.ts priority fix is well-tested in test/backup-metadata-builder.test.ts
  • named-backups.ts readdir catch only silences ENOENT; on windows a transient EACCES on the backup root would surface as an unhandled throw
  • docs parity test correctly updated to verify the extracted switch.ts path, not the old monolithic codex-manager.ts
  • storage snapshot isolation test for named-backup export uses vi.doMock + vi.resetModules correctly to verify stale transaction snapshots are ignored when the path key doesn't match

Confidence Score: 4/5

  • safe to merge after fixing the missing proactiveRefreshGuardian/proactiveRefreshIntervalMs category entries; all other changes are well-tested
  • one concrete UI reachability bug in backend-settings-schema.ts (two settings unreachable through any category), one minor windows-safety P2 in named-backups.ts readdir catch; all storage fixes are well-tested, backup priority logic is correct, settings write queue is sound
  • lib/codex-manager/backend-settings-schema.ts — verify proactiveRefreshGuardian and proactiveRefreshIntervalMs are added to refresh-recovery category

Important Files Changed

Filename Overview
lib/codex-manager/backend-settings-schema.ts new backend settings schema with toggle/number/category definitions — proactiveRefreshGuardian toggle and proactiveRefreshIntervalMs number are missing from all BACKEND_CATEGORY_OPTIONS entries, making them unreachable in the UI
lib/codex-manager/settings-write-queue.ts new per-path write queue with exponential backoff retry — correctly adds EACCES to the retryable set, queue serialization and cleanup logic look sound
lib/storage/backup-metadata-builder.ts new backup metadata builder with corrected latestValidPath priority — discovered backups (priority 4) beat WAL (priority 1) even when WAL is newer; sequential awaits are slow but non-critical for a diagnostic path
lib/storage/named-backups.ts new named backup collector with TOCTOU-aware mtime logging — readdir catch silences ENOENT but re-throws EACCES, which can be problematic on Windows with transient locks
lib/codex-manager/commands/switch.ts switch command extraction from codex-manager.ts — clean, all error paths return non-zero, docs parity test updated to check this file
test/backup-metadata-builder.test.ts good coverage of the latestValidPath priority fix — the "prefers discovered backup over WAL" case explicitly validates the corrected priority order
test/storage.test.ts adds storage error hint tests, flagged transaction rollback tests, snapshot isolation test for named-backup export, and live-flagged snapshot passthrough test
test/codex-manager-forecast-command.test.ts new forecast command tests — loadDashboardDisplaySettings is optional in deps so tests work without mocking it; help, invalid args, and json output paths are covered
lib/runtime/session-affinity.ts thin runtime adapter for session affinity store — config-keyed caching of the store prevents needless reconstruction on unchanged config

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[buildBackupMetadata] --> B[getAccountsBackupRecoveryCandidatesWithDiscovery]
    B --> C{classify candidate}
    C -->|=storagePath.bak| D[accounts-backup prio 2]
    C -->|starts with storagePath.bak.| E[accounts-backup-history prio 3]
    C -->|other| F[accounts-discovered-backup prio 4]
    A --> G[describeAccountsWalSnapshot → accounts-wal prio 1]
    A --> H[describeAccountSnapshot primary → accounts-primary prio 0]
    D & E & F & G & H --> I[accountSnapshots array]
    I --> J[selectLatestValidAccountPath]
    J -->|ACCOUNT_BACKUP_PREFERRED_KINDS first| K{any valid backup/history/discovered?}
    K -->|yes| L[highest priority then newest mtime]
    K -->|no| M{any valid WAL?}
    M -->|yes| N[WAL path]
    M -->|no| O[any valid snapshot]
    L & N & O --> P[latestValidPath override]
    P --> Q[BackupMetadata.accounts.latestValidPath]
Loading

Fix All in Codex

Prompt To Fix All With AI
This is a comment left during a code review.
Path: lib/storage/named-backups.ts
Line: 25-30

Comment:
**Windows EACCES not handled in `readdir` error catch**

on windows, a temporarily locked or permission-restricted backup root directory can throw `EACCES` from `readdir`. the current catch block only silences `ENOENT` and re-throws everything else, so a transient windows antivirus or explorer lock would surface as an unhandled exception to callers instead of returning `[]`. this contradicts the project's windows filesystem safety convention.

```suggestion
	} catch (error) {
		const code = (error as NodeJS.ErrnoException).code;
		if (code === "ENOENT" || code === "EACCES") return [];
		throw error;
	}
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: lib/codex-manager/backend-settings-schema.ts
Line: 281-288

Comment:
**`proactiveRefreshGuardian` and `proactiveRefreshIntervalMs` unreachable in category UI**

`proactiveRefreshGuardian` is in `BACKEND_TOGGLE_OPTIONS` and `proactiveRefreshIntervalMs` is in `BACKEND_NUMBER_OPTIONS`, but neither is included in any `BACKEND_CATEGORY_OPTIONS` category. users navigating the backend settings UI will never see these two controls — the token refresh guard toggle and its scan interval are silently inaccessible.

they both logically belong in the `"refresh-recovery"` category alongside `proactiveRefreshBufferMs` and `tokenRefreshSkewMs`. the fix is to add `"proactiveRefreshGuardian"` to `toggleKeys` and `"proactiveRefreshIntervalMs"` to `numberKeys` for that category.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (2): Last reviewed commit: "Merge remote-tracking branch 'origin/pla..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

ndycode added 30 commits March 20, 2026 22:18
ndycode added 24 commits March 22, 2026 19:25
…ged-helper' into release/mainbound-20260323

# Conflicts:
#	index.ts
#	lib/runtime/account-pool.ts
#	lib/runtime/account-selection.ts
#	lib/runtime/manual-oauth-flow.ts
#	lib/runtime/ui-runtime.ts
#	lib/storage.ts
#	lib/storage/named-backups.ts
…g' into release/mainbound-20260323

# Conflicts:
#	README.md
#	docs/README.md
…' into release/mainbound-20260323

# Conflicts:
#	README.md
#	docs/README.md
…ooks' into release/mainbound-20260323

# Conflicts:
#	docs/README.md
…lease/mainbound-20260323

# Conflicts:
#	docs/README.md
…orts-latest' into release/mainbound-20260323
…' into release/mainbound-20260323

# Conflicts:
#	docs/reference/commands.md
#	lib/codex-manager.ts
…ease/mainbound-20260323

# Conflicts:
#	lib/codex-manager.ts
…-smoke-real' into release/mainbound-20260323

# Conflicts:
#	test/benchmark-runtime-path-script.test.ts
@chatgpt-codex-connector
Copy link

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 22, 2026

Important

Review skipped

Too many files!

This PR contains 184 files, which is 34 over the limit of 150.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6288f51f-2d41-42e4-9d66-78b7dbf3e3fa

📥 Commits

Reviewing files that changed from the base of the PR and between 1be5e95 and b00f48e.

📒 Files selected for processing (184)
  • README.md
  • docs/README.md
  • docs/development/RUNBOOK_ADD_AUTH_COMMAND.md
  • docs/development/RUNBOOK_ADD_AUTH_MANAGER_COMMAND.md
  • docs/development/RUNBOOK_ADD_CONFIG_FIELD.md
  • docs/development/RUNBOOK_ADD_CONFIG_FIELD_SAFELY.md
  • docs/development/RUNBOOK_CHANGE_ROUTING_POLICY.md
  • docs/development/RUNBOOK_CHANGE_ROUTING_POLICY_SAFELY.md
  • docs/development/TESTING.md
  • docs/getting-started.md
  • docs/reference/commands.md
  • docs/reference/public-api.md
  • docs/releases/v1.2.0.md
  • docs/troubleshooting.md
  • docs/upgrade.md
  • index.ts
  • lib/auth/index.ts
  • lib/codex-cli/index.ts
  • lib/codex-manager.ts
  • lib/codex-manager/auth-commands.ts
  • lib/codex-manager/backend-category-helpers.ts
  • lib/codex-manager/backend-category-prompt.ts
  • lib/codex-manager/backend-settings-controller.ts
  • lib/codex-manager/backend-settings-entry.ts
  • lib/codex-manager/backend-settings-helpers.ts
  • lib/codex-manager/backend-settings-schema.ts
  • lib/codex-manager/behavior-settings-panel.ts
  • lib/codex-manager/commands/best.ts
  • lib/codex-manager/commands/check.ts
  • lib/codex-manager/commands/doctor.ts
  • lib/codex-manager/commands/fix.ts
  • lib/codex-manager/commands/forecast.ts
  • lib/codex-manager/commands/report.ts
  • lib/codex-manager/commands/status.ts
  • lib/codex-manager/commands/switch.ts
  • lib/codex-manager/commands/verify-flagged.ts
  • lib/codex-manager/dashboard-display-panel.ts
  • lib/codex-manager/dashboard-formatters.ts
  • lib/codex-manager/dashboard-settings-controller.ts
  • lib/codex-manager/dashboard-settings-data.ts
  • lib/codex-manager/experimental-settings-prompt.ts
  • lib/codex-manager/experimental-settings-schema.ts
  • lib/codex-manager/experimental-sync-target.ts
  • lib/codex-manager/forecast-report-commands.ts
  • lib/codex-manager/help.ts
  • lib/codex-manager/repair-commands.ts
  • lib/codex-manager/settings-hub-menu.ts
  • lib/codex-manager/settings-hub-prompt.ts
  • lib/codex-manager/settings-hub.ts
  • lib/codex-manager/settings-persist-utils.ts
  • lib/codex-manager/settings-preview.ts
  • lib/codex-manager/settings-write-queue.ts
  • lib/codex-manager/statusline-settings-panel.ts
  • lib/codex-manager/theme-settings-panel.ts
  • lib/codex-manager/unified-settings-controller.ts
  • lib/forecast.ts
  • lib/prompts/codex.ts
  • lib/request/failover-config.ts
  • lib/request/helpers/model-map.ts
  • lib/request/index.ts
  • lib/request/request-init.ts
  • lib/request/request-transformer.ts
  • lib/request/response-metadata.ts
  • lib/request/wait-utils.ts
  • lib/runtime/account-check-helpers.ts
  • lib/runtime/account-check-types.ts
  • lib/runtime/account-health-check.ts
  • lib/runtime/account-manager-cache.ts
  • lib/runtime/account-pool.ts
  • lib/runtime/account-scope.ts
  • lib/runtime/account-select-event.ts
  • lib/runtime/account-selection.ts
  • lib/runtime/account-state.ts
  • lib/runtime/account-status.ts
  • lib/runtime/browser-oauth-flow.ts
  • lib/runtime/capability-boost.ts
  • lib/runtime/event-handler.ts
  • lib/runtime/flagged-verify-types.ts
  • lib/runtime/hydrate-emails.ts
  • lib/runtime/live-sync.ts
  • lib/runtime/manual-oauth-flow.ts
  • lib/runtime/metrics.ts
  • lib/runtime/oauth-browser-flow.ts
  • lib/runtime/preemptive-quota.ts
  • lib/runtime/quota-headers.ts
  • lib/runtime/quota-probe.ts
  • lib/runtime/refresh-guardian.ts
  • lib/runtime/request-init.ts
  • lib/runtime/runtime-services.ts
  • lib/runtime/session-affinity.ts
  • lib/runtime/status-marker.ts
  • lib/runtime/storage-scope.ts
  • lib/runtime/toast.ts
  • lib/runtime/ui-runtime.ts
  • lib/storage.ts
  • lib/storage/account-clear.ts
  • lib/storage/account-persistence.ts
  • lib/storage/backup-metadata-builder.ts
  • lib/storage/backup-metadata.ts
  • lib/storage/backup-paths.ts
  • lib/storage/backup-restore.ts
  • lib/storage/error-hints.ts
  • lib/storage/file-paths.ts
  • lib/storage/fixture-guards.ts
  • lib/storage/flagged-storage-io.ts
  • lib/storage/flagged-storage.ts
  • lib/storage/identity.ts
  • lib/storage/import-export.ts
  • lib/storage/metadata-section.ts
  • lib/storage/named-backups.ts
  • lib/storage/path-state.ts
  • lib/storage/project-migration.ts
  • lib/storage/restore-assessment.ts
  • lib/storage/restore.ts
  • lib/storage/snapshot-inspectors.ts
  • lib/storage/storage-parser.ts
  • lib/storage/transactions.ts
  • package.json
  • scripts/codex-multi-auth.js
  • test/account-check-helpers.test.ts
  • test/account-clear.test.ts
  • test/account-persistence.test.ts
  • test/account-selection.test.ts
  • test/account-status.test.ts
  • test/backend-category-helpers.test.ts
  • test/backend-category-prompt.test.ts
  • test/backend-settings-controller.test.ts
  • test/backend-settings-entry.test.ts
  • test/backup-metadata-builder.test.ts
  • test/backup-paths.test.ts
  • test/backup-restore.test.ts
  • test/bench-format-render.test.ts
  • test/benchmark-render-dashboard-script.test.ts
  • test/benchmark-runtime-path-script.test.ts
  • test/browser-oauth-flow.test.ts
  • test/capability-policy.test.ts
  • test/codex-manager-auth-commands.test.ts
  • test/codex-manager-best-command.test.ts
  • test/codex-manager-check-command.test.ts
  • test/codex-manager-cli.test.ts
  • test/codex-manager-doctor-command.test.ts
  • test/codex-manager-fix-command.test.ts
  • test/codex-manager-forecast-command.test.ts
  • test/codex-manager-help.test.ts
  • test/codex-manager-report-command.test.ts
  • test/codex-manager-status-command.test.ts
  • test/codex-manager-switch-command.test.ts
  • test/codex-manager-verify-flagged-command.test.ts
  • test/codex-multi-auth-bin-wrapper.test.ts
  • test/codex-multi-auth-wrapper.test.ts
  • test/codex-prompts.test.ts
  • test/codex.test.ts
  • test/config-schema-templates.test.ts
  • test/config.test.ts
  • test/dashboard-settings-controller.test.ts
  • test/documentation.test.ts
  • test/experimental-settings-prompt.test.ts
  • test/experimental-sync-target.test.ts
  • test/failover-config.test.ts
  • test/fixture-guards.test.ts
  • test/flagged-storage-io.test.ts
  • test/flagged-storage.test.ts
  • test/import-export.test.ts
  • test/manual-oauth-flow.test.ts
  • test/metadata-section.test.ts
  • test/model-map.test.ts
  • test/project-migration.test.ts
  • test/property/transformer.property.test.ts
  • test/public-api-contract.test.ts
  • test/repair-commands.test.ts
  • test/request-init.test.ts
  • test/request-transformer.test.ts
  • test/response-metadata.test.ts
  • test/restore-assessment.test.ts
  • test/runtime-services.test.ts
  • test/settings-hub-menu.test.ts
  • test/settings-hub-prompt.test.ts
  • test/storage-named-backups.test.ts
  • test/storage-parser.test.ts
  • test/storage-scope.test.ts
  • test/storage.test.ts
  • test/transactions.test.ts
  • test/unified-settings-controller.test.ts
  • test/wait-utils.test.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/mainbound-20260323
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch release/mainbound-20260323

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment on lines +95 to +97
const newStorage: AccountStorageV3 = {
version: 3,
accounts: deduplicatedAccounts,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 importedCount can go negative with dirty existing storage

const importedCount = deduplicatedAccounts.length - existingAccounts.length;
const skippedCount = params.imported.accounts.length - importedCount;

deduplicateAccounts runs on the full merged array. if existingAccounts itself contains internal duplicates, deduplicatedAccounts.length < existingAccounts.length, making importedCount negative and skippedCount > params.imported.accounts.length. in practice storage is always written post-dedup, but this silently produces wrong counts for the caller if the invariant is violated.

consider clamping to zero or asserting the invariant:

const importedCount = Math.max(
  0,
  deduplicatedAccounts.length - existingAccounts.length,
);
Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/storage/import-export.ts
Line: 95-97

Comment:
**`importedCount` can go negative with dirty existing storage**

```
const importedCount = deduplicatedAccounts.length - existingAccounts.length;
const skippedCount = params.imported.accounts.length - importedCount;
```

`deduplicateAccounts` runs on the full merged array. if `existingAccounts` itself contains internal duplicates, `deduplicatedAccounts.length < existingAccounts.length`, making `importedCount` negative and `skippedCount > params.imported.accounts.length`. in practice storage is always written post-dedup, but this silently produces wrong counts for the caller if the invariant is violated.

consider clamping to zero or asserting the invariant:
```typescript
const importedCount = Math.max(
  0,
  deduplicatedAccounts.length - existingAccounts.length,
);
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Codex

ndycode added 2 commits March 23, 2026 01:49
…' into release/mainbound-20260323

* origin/plan/02-cli-help-and-login-split:
  test: cover live lease failures
  test: cover auth command error paths
  Serialize live auth-best probe writes
  test: cover concurrent auth best live refresh writes
  fix: clamp restored auth family indices
  test: cover extracted auth command modules
  refactor: split auth cli help and command flows

# Conflicts:
#	lib/codex-manager.ts
#	test/documentation.test.ts
…elease/mainbound-20260323

* origin/plan/04-cli-repair-split:
  fix: guard repair command persistence drift
  fix: avoid stale flagged restore writes
  fix: align repair command review followups
  guard doctor sync after transaction abort
  fix direct repair command review regressions
  fix: preserve manage selection and flagged repair state
  fix(cli): snapshot doctor file existence checks
  fix doctor auto-fix transaction flow
  fix(cli):close-repair-review-gaps
  fix(storage): harden flagged transaction rollback
  test(cli): add direct repair command coverage
  fix(cli): close remaining repair review gaps
  fix(cli): close remaining repair review gaps
  fix(cli):transact-verify-flagged-persistence
  fix(cli): persist repair commands through storage tx
  refactor: split repair and doctor cli flows
  refactor: split forecast and report cli flows

# Conflicts:
#	lib/codex-manager.ts
#	lib/storage.ts
#	test/codex-manager-cli.test.ts
Comment on lines +281 to +288
max: 24 * 60 * 60_000,
step: 60_000,
unit: "ms",
},
];

export const BACKEND_CATEGORY_OPTIONS: BackendCategoryOption[] = [
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 proactiveRefreshGuardian and proactiveRefreshIntervalMs unreachable in category UI

proactiveRefreshGuardian is in BACKEND_TOGGLE_OPTIONS and proactiveRefreshIntervalMs is in BACKEND_NUMBER_OPTIONS, but neither is included in any BACKEND_CATEGORY_OPTIONS category. users navigating the backend settings UI will never see these two controls — the token refresh guard toggle and its scan interval are silently inaccessible.

they both logically belong in the "refresh-recovery" category alongside proactiveRefreshBufferMs and tokenRefreshSkewMs. the fix is to add "proactiveRefreshGuardian" to toggleKeys and "proactiveRefreshIntervalMs" to numberKeys for that category.

Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/codex-manager/backend-settings-schema.ts
Line: 281-288

Comment:
**`proactiveRefreshGuardian` and `proactiveRefreshIntervalMs` unreachable in category UI**

`proactiveRefreshGuardian` is in `BACKEND_TOGGLE_OPTIONS` and `proactiveRefreshIntervalMs` is in `BACKEND_NUMBER_OPTIONS`, but neither is included in any `BACKEND_CATEGORY_OPTIONS` category. users navigating the backend settings UI will never see these two controls — the token refresh guard toggle and its scan interval are silently inaccessible.

they both logically belong in the `"refresh-recovery"` category alongside `proactiveRefreshBufferMs` and `tokenRefreshSkewMs`. the fix is to add `"proactiveRefreshGuardian"` to `toggleKeys` and `"proactiveRefreshIntervalMs"` to `numberKeys` for that category.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Codex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant