Real regression runs that explicitly pass -RequireCredentials should still fail fast when credentials cannot be confirmed. This keeps the real-ASR signal strict while leaving the default runtime smoke suite decoupled from legacy credentials.json.\n\nConstraint: default smoke suite must not depend on migrated plaintext JSON.\nRejected: Keep warning-only behavior in real regression mode | allows credential-missing runs to appear as valid real-ASR regressions.\nConfidence: high\nScope-risk: narrow\nDirective: Keep -RequireCredentials in windows-real-regression as a hard gate unless credential-vault probing is added.\nTested: git diff --check\nNot-tested: Running Windows PowerShell regression scripts in Linux environment.\nRelated: #230
Windows smoke scripts should no longer fail solely because credentials.json was migrated into the OS credential vault. The default suite now runs runtime startup without the obsolete JSON gate, and explicit legacy JSON checks warn instead of blocking vault-backed test machines.\n\nConstraint: Provider credentials now live in the OS credential vault after migration.\nRejected: Query Windows Credential Manager from smoke scripts | larger platform-specific parsing surface for a smoke gate that only needs to avoid the obsolete JSON blocker.\nConfidence: high\nScope-risk: narrow\nDirective: Do not make Windows smoke defaults depend on migrated plaintext credentials.json.\nTested: git diff --check\nTested: Python sanity check for conflict markers in edited PowerShell scripts\nNot-tested: PowerShell parser unavailable in this Linux environment.\nRelated: #230
Credential writes should not fail only because an old migration source cannot be deleted. Once current vault data is readable and writable, legacy plaintext cleanup remains best-effort and logged so users can still save or remove credentials even if credentials.json is locked or read-only.\n\nThe rebase also brought the new Japanese and Korean locale files onto this branch, so the credential storage notice key is filled there to keep the frontend type contract intact.\n\nConstraint: credentials.json is obsolete migration data after vault write.\nRejected: Propagate legacy JSON deletion failures on every vault save | blocks credential updates despite a valid vault.\nConfidence: high\nScope-risk: narrow\nDirective: Do not make credential updates depend on deleting legacy plaintext files.\nTested: cargo check --manifest-path src-tauri/Cargo.toml\nTested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit\nTested: npm run -s build\nTested: git diff --check\nNot-tested: Manual locked/read-only credentials.json cleanup.\nRelated: #230
When the current legacy credentials.json source wins migration, older per-account vault entries should not remain as stale fallback data. After the JSON payload is successfully written to the chunked vault and plaintext cleanup succeeds, the migration now removes those older per-account entries as well.
Constraint: credentials.json is the previous Tauri source of truth and must win over stale Swift-era vault entries.\nRejected: Leave per-account entries for fallback | keeps stale secrets reachable after successful migration.\nConfidence: high\nScope-risk: narrow\nDirective: Clean old per-account vault entries after any successful authoritative migration source is saved.\nTested: cargo check --manifest-path src-tauri/Cargo.toml\nTested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit\nTested: npm run -s build\nTested: git diff --check\nNot-tested: Manual upgrade with both credentials.json and stale per-account vault entries.\nRelated: #230
Legacy per-account vault migration must be all-or-nothing. If one old entry is temporarily unreadable, saving the readable subset and deleting the original entries can silently drop the failed secret, so update-path migration now aborts on any legacy vault read error while the non-mutating read fallback remains conservative.
Constraint: migration cleanup deletes old per-account vault entries after saving the chunked manifest.\nRejected: Migrate the readable subset | can discard an unreadable legacy secret before retry.\nConfidence: high\nScope-risk: narrow\nDirective: Do not remove legacy per-account vault entries unless every legacy account read completed without error.\nTested: cargo check --manifest-path src-tauri/Cargo.toml\nTested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit\nTested: npm run -s build\nTested: git diff --check\nNot-tested: Manual transient per-account vault read failure during upgrade.\nRelated: #230
Linux credential storage must survive reboot after the legacy plaintext file is removed. The keyring linux-native feature uses kernel keyutils, so the Linux build now enables the persistent Secret Service-backed combo and the migration read fallback also considers older per-account vault entries when a current manifest is unreadable.
Constraint: credentials.json must be removed after successful vault migration.\nConstraint: keyring linux-native/keyutils is an in-memory cache across reboot.\nRejected: Keep plaintext JSON as Linux fallback | violates the vault storage boundary.\nConfidence: high\nScope-risk: moderate\nDirective: Linux credential storage must remain persistent if legacy plaintext cleanup is enforced.\nTested: cargo check --manifest-path src-tauri/Cargo.toml\nTested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit\nTested: npm run -s build\nTested: git diff --check\nNot-tested: Manual Secret Service read/write on a desktop Linux keyring session.\nRelated: #230
Vault migration should not silently report success when credentials were written to the OS vault but the previous plaintext credentials file could not be removed. Propagating that cleanup error on write/update paths makes the remaining plaintext exposure visible instead of treating the migration as complete.
Constraint: credentials.json is allowed only as a migration source, not a durable fallback after a successful vault write.\nRejected: Keep deletion best-effort only | can leave plaintext credentials indefinitely with no user-visible failure.\nConfidence: high\nScope-risk: narrow\nDirective: Do not hide legacy plaintext deletion failures on credential write paths.\nTested: cargo check --manifest-path src-tauri/Cargo.toml\nTested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit\nTested: npm run -s build\nTested: git diff --check\nNot-tested: Manual permission-denied legacy file cleanup on installed apps.\nRelated: #230
The migration path must prefer the current legacy JSON source over older per-account vault leftovers, clean those leftovers after a valid manifest is available, and avoid write operations overwriting a damaged or unreadable vault payload with fallback defaults.
Constraint: credentials.json is migration-only, but it was the previous Tauri source of truth.\nRejected: Use read fallback for mutating updates | can overwrite unreadable vault data with defaults.\nConfidence: high\nScope-risk: narrow\nDirective: Mutating credential operations must propagate chunked vault read errors instead of saving fallback roots.\nTested: cargo check --manifest-path src-tauri/Cargo.toml\nTested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit\nTested: npm run -s build\nTested: git diff --check\nNot-tested: Manual migration with simultaneous JSON and stale per-account vault entries.\nRelated: #230
Credential vault saves now write a fresh generation of chunks before switching the manifest, so failed chunk writes or crashes do not overwrite chunks still referenced by the previous manifest. The same change also migrates documented per-account vault entries into the chunked manifest before falling back to legacy JSON.
Constraint: Windows Credential Manager requires chunking, and legacy credentials may exist either as plaintext JSON or documented per-account vault entries.
Rejected: Overwrite stable chunk names before manifest update | can mix old and new payloads after partial writes.
Confidence: high
Scope-risk: narrow
Directive: Treat the manifest as the commit pointer; write new-generation chunks before updating it and delete old chunks only after manifest write succeeds.
Tested: cargo check --manifest-path src-tauri/Cargo.toml
Tested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit
Tested: npm run -s build
Tested: git diff --check
Not-tested: Manual crash injection during OS vault writes.
Related: #230
Users upgrading from the plaintext credentials file should not lose access to existing settings just because the OS vault backend is temporarily unavailable or migration cannot be written. Keep the old file migration-only, but return its contents as the compatibility source when vault reads or writes fail.
Constraint: credentials.json remains a legacy compatibility source only, not the normal write target.
Rejected: Return defaults on vault read/write errors | hides existing upgrade data and makes configured providers appear empty.
Confidence: high
Scope-risk: narrow
Directive: Do not reintroduce plaintext writes; fallback reads are only for pre-PR legacy migration compatibility.
Tested: cargo check --manifest-path src-tauri/Cargo.toml
Tested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit
Tested: npm run -s build
Tested: git diff --check
Not-tested: Manual vault-unavailable upgrade run on Windows/macOS/Linux.
Related: #230
The OS vault migration keeps provider state as one logical JSON payload, but Windows Credential Manager limits each credential blob. Store the logical payload as a manifest plus bounded chunks so long API keys, multiple providers, or extra headers do not make future saves fail on Windows.
Constraint: Windows Credential Manager generic credential blob is capped and keyring stores passwords as UTF-16 on Windows.
Rejected: Split each provider field into independent vault entries | broader schema rewrite and more migration surface than needed for this review fix.
Confidence: high
Scope-risk: narrow
Directive: Keep the legacy plaintext credentials.json path migration-only; do not add compatibility for transient PR-internal vault formats unless the release shipped them.
Tested: cargo check --manifest-path src-tauri/Cargo.toml
Tested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit
Tested: npm run -s build
Tested: git diff --check
Not-tested: Live Windows Credential Manager write with oversized real provider payload.
Related: #230
Provider credentials should follow the platform credential-store threat model instead of continuing normal plaintext JSON writes. The vault now stores the existing multi-provider credentials payload in the OS credential store, migrates the legacy JSON file only when the vault has no entry, removes the legacy file after a successful write, and keeps raw credential IPC restricted to the main settings window.
Constraint: User explicitly chose Keychain/Credential Manager/Linux keyring for issue #230.
Constraint: Preserve the existing provider schema and active-provider routing with minimal frontend churn.
Rejected: Keep plaintext JSON as the documented product choice | user rejected this direction.
Rejected: Split every credential field into separate vault entries | larger migration surface and risks losing active provider state.
Confidence: medium
Scope-risk: moderate
Directive: Security-model and storage-strategy choices must be confirmed with the user before implementation.
Tested: cargo check --manifest-path src-tauri/Cargo.toml; npm run -s build; git diff --check; grep for stale plaintext/Keychain fallback wording.
Not-tested: Manual migration on macOS Keychain, Windows Credential Manager, or Linux desktop keyring.
Related: https://github.com/appergb/openless/issues/230