fix(migration): close cooldown-key strand gap + allowlist guard test (W4)#247
Merged
Merged
Conversation
…(W4)
Adversarial verification of the W1-A..W3 changeset confirmed MAS-safety,
entitlement-verifier soundness, and the reentrancy fix all hold, and surfaced one
real latent issue: ClaudeCredentials.keychainReadCooldownKey
("claudeCodeKeychainReadCooldownUntil") is written to
UserDefaults(suiteName:"group.yyh.CLI-Pulse") ?? .standard. The app-group store is
safe, but the .standard FALLBACK would strand a non-cli_pulse_/non-privacy. key on
the DEVID unsandbox transition — falsifying UnsandboxedDataMigration's "every
app-owned standard-defaults key is prefixed" invariant.
- Rename the key -> "cli_pulse_claude_keychain_read_cooldown_until" so the
migration allowlist covers it even on the fallback (orphans the old 30-min
timestamp once — benign). Make the constant internal for a guard test.
- Add UnsandboxedDataMigrationTests.test_appOwnedKeyPrefixes_coverEveryKnownStandardDefaultsKey
asserting every audited app-owned standard-defaults key (incl. privacy.* and the
cooldown constant) matches appOwnedKeyPrefixes.
- Clarify the omitted selfDeviceId precondition in the canStartLocalManagedSession
doc + the W1-B menu comment (verifier: doc drift, NOT behavior — predicate
unchanged; it's intentional + test-locked).
swift test full: 1826 tests, 0 failures (existing ClaudeKeychainCooldownTests
still pass via the constant).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
A 5-way adversarial verification of the W1-A..W3 changeset (#243/#244/#245/#246) confirmed MAS-safety (high), entitlement-verifier soundness (medium), and the reentrancy fix (high) all hold, and surfaced one real latent issue + two doc-comment drifts. (The bulk of W4 — the ship-config entitlement-invariant test — already shipped in W1-A as
DevidEntitlementsInvariantTests.)Fixes
ClaudeCredentials.keychainReadCooldownKey("claudeCodeKeychainReadCooldownUntil") is written toUserDefaults(suiteName:"group.yyh.CLI-Pulse") ?? .standard. The app-group store doesn't move on unsandbox, but the?? .standardfallback would strand a non-cli_pulse_/non-privacy.key → falsifyingUnsandboxedDataMigration's "every app-owned standard-defaults key is prefixed" invariant. Renamed →"cli_pulse_claude_keychain_read_cooldown_until"(orphans the old 30-min timestamp once — benign); made the constant internal for a guard test.test_appOwnedKeyPrefixes_coverEveryKnownStandardDefaultsKeyasserts every audited app-owned standard-defaults key (incl.privacy.*+ the cooldown constant) matchesappOwnedKeyPrefixes; a future unprefixed revert fails here.selfDeviceId(local helper pairing, NOT cloud Remote-Control) precondition in thecanStartLocalManagedSessiondoc + W1-B menu comment. Predicate unchanged — it's intentional + test-locked (SessionControlIntegrationGapTests); dropping it would break row-ownership invariants.Validation
swift testfull: 1826 tests, 0 failures. ExistingClaudeKeychainCooldownTestsstill pass (they go through the renamed constant, transparent to the change).🤖 Generated with Claude Code