Skip to content

docs(triage-bot): as-built reference + shared architecture proposal (PP-4858) - #1355

Draft
mauricecarrier7 wants to merge 6 commits into
developfrom
docs/pp-4858-triage-bot-architecture
Draft

docs(triage-bot): as-built reference + shared architecture proposal (PP-4858)#1355
mauricecarrier7 wants to merge 6 commits into
developfrom
docs/pp-4858-triage-bot-architecture

Conversation

@mauricecarrier7

Copy link
Copy Markdown
Contributor

Output of the PP-4858 spike, plus two small changes it surfaced.

Draft because these are for reading and comment first. Review inline, on the sentence.

The two documents

docs/architecture/triage-bot-v1-as-built.md describes the triage bot as it works today, written as the behavioral contract another platform reproduces: normalization, scoring and the four suggest guards, the redaction rules and their order, the corpus schema, and the escalation state machine. Platform-specific detail is labeled so nobody ports it by mistake.

docs/architecture/triage-bot-shared-architecture-proposal.md designs the server and Android halves. It opens with a decision memo naming what is being asked for, what is deliberately not being approved yet, and three risks that still need someone's name against them.

If you have fifteen minutes and a decision to make: read the cover memo, then the delivery plan and organizational dependencies. Everything else is reference.

Recommendation

A hybrid. The corpus ships as a versioned CDN artifact rather than a new service, because the org already distributes versioned content that way in two places. Ticket submission becomes a per-library endpoint on the existing Circulation Manager. The AI key proxy stays a hard prerequisite for the AI fallback but is sequenced last, since it is the only piece that may need new infrastructure. Classification and redaction stay on the phones. Android gets a small hand-written Kotlin module kept in step by shared test fixtures rather than shared code.

Three findings worth reading even if nothing else is

  1. The AI proxy design written in the iOS code cannot be built as described. The patron's bearer token is encrypted rather than signed, only the Circulation Manager can decrypt it, and the patron's password is inside it. No separate service can verify a patron without also being able to read every patron's password.
  2. There is no infrastructure-as-code anywhere in the org and no self-service deploy path. Standing up a new service is a request to whoever operates the AWS account, not something engineering can schedule. The plan front-loads everything needing no new infrastructure.
  3. There is no HelpSpot integration server-side to extend. That work is a build from scratch and is not estimable until API documentation, a sandbox, and a support contact exist.

Also in this PR

  • Notify-me-on-fix is no longer offered. It promised a notification nothing could deliver. Hidden behind a pure policy in Core, with the reducer handler and its coverage intact, so restoring it is one line once delivery exists. Mutation-verified.
  • The redaction leak gate now runs. scripts/triage-corpus-check.sh described itself as a release gate but had no caller anywhere. Its --self-test, which proves the guard goes red when redaction is disabled, was therefore never running. Wired into CI and verify-pr.sh.

How it was checked

Four grounded passes over android-core, circulation, library-registry and the analytics tooling. Three independent reviews from backend, Android and iOS perspectives. A source audit of every factual claim. And one experiment: the matching engine was rebuilt in Python from the document alone, without reading the Swift, then run against the real conformance corpora. It matched 85 of 85. The claim that another platform can build from this document is demonstrated rather than asserted.

Verification

  • Package suite green (285 tests), including the two new policy tests
  • Redaction leak gate and its self-test pass
  • Documented counts match source: 293 test functions, 70 corpus cases
  • All internal anchors resolve; diagrams parse

Related: PP-4882 and sub-tasks PP-4883 to PP-4886 cover the gaps that need closing before the bot's flag is turned on for patrons. The bot ships in 3.3.0 with its master switch off, so nothing is patron-facing yet.

🤖 Generated with Claude Code

t and others added 4 commits July 29, 2026 11:19
…PP-4858)

Two documents for the PP-4858 spike.

triage-bot-v1-as-built.md describes the bot as it works today, written as
the behavioral contract another platform reproduces: the classifier's
normalization, scoring and guards, the 15 redaction patterns with their
order and replacement tokens, the corpus schema, and the escalation state
machine. Platform-specific detail is labeled so nobody ports it by mistake.

triage-bot-shared-architecture-proposal.md designs the server and Android
halves. It opens with a decision memo naming what is being asked for, what
is deliberately not being approved yet, and the risks that still need an
accepter.

Also corrects the package README, which claimed 26 tests and named the
clipboard as the ticket transport, and adds a pointer from CLAUDE.md so
anyone changing the package reads the contract first.

**Scope:** documentation only, plus a README correction and a CLAUDE.md
pointer. No production code in this commit.

**Not done:** the docs describe several gaps rather than fixing them, most
notably that the clipboard transport does not honor the patron's field
omissions. Those are tracked under PP-4882.

**Deferred:** cross-platform conformance fixtures are specified but not
built; they are a Phase 2 deliverable and the Android estimate depends on
them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
When the bot recognised a problem already fixed in a later release, it
offered the patron a "Notify me" option. Tapping it produced a friendly
confirmation and did nothing else: no notification was ever scheduled and
no part of the app could have delivered one. It was a promise we had no
way to keep, so the affordance is hidden rather than shown.

The rule lives in a pure KBMatchActionPolicy in Core, following the
existing HelpEntryPointPolicy pattern, so the decision is testable without
a SwiftUI host. The reducer's handler stays behind it with its existing
coverage, which makes restoring the option a one-line change once real
delivery exists.

The test pins the case that used to render the chip, so a regression that
restores the old entry.fixedInVersion != nil rule fails rather than
shipping a false promise. Mutation-verified: flipping the policy to return
entryHasFixVersion fails the suite.

**Scope:** one new pure policy type, its test, and the call site in the
match card. No behavior change to the reducer or the classifier.

**Not done:** actual notification delivery. Deciding what "notify me"
should mean, local reminder, push, or dropping it entirely, is a product
call tracked by PP-4886.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
scripts/triage-corpus-check.sh describes itself as a release-time
credential-leak gate, and RedactionCorpusTests already runs inside the
package suite. The script itself had no caller: not verify-pr.sh, not
release-gates.yml, not any workflow, despite three files describing it as
running at release time.

The part that was therefore never running is --self-test, which disables
redaction to prove the guard goes red on an un-redacted corpus. That is the
check that catches a guard which has silently stopped guarding, and the
suite alone cannot catch it.

Wired into both places an engineer actually runs: the CI job, immediately
after the package tests so build products are warm, and verify-pr.sh as a
triage_redaction_gate check. Costs seconds.

Dry-run clean on the current tree: guard passes, and the self-test
correctly goes red when redaction is disabled.

**Scope:** two call sites. The gate script and the tests it runs are
unchanged.

**Not done:** release-gates.yml still does not run it. That workflow is
ubuntu-only and the gate needs a Swift toolchain, so adding it there means
either a macOS runner or a container, which is a bigger change than this.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The proposal carried a named escalation about unredacted logs in the
shipped Android app, addressed to the android-core maintainer, with the
affected fields and log level enumerated.

Raising it was right; the venue was not. A shared architecture proposal
that circulates to leadership is the wrong place for a maintainer to first
encounter a finding about their own codebase, and an iOS-side document
enumerating another team's credential handling reads as an audit published
over their head rather than a colleague's note. The specifics belong in a
direct conversation with the owner, who then has the chance to assess,
confirm, or say it is already handled.

What the document needs is the planning fact, which is unchanged and still
stated: the existing Android report path attaches unredacted logs, the bot
would use that path, so redaction is a prerequisite workstream for the
Android client and is plausibly larger than the bot module itself.

**Scope:** removes the escalation section and its contents entry, restates
section 8.4 without the field-level detail, and neutralizes the supporting
footnote. No change to any recommendation, decision, or estimate.

**Not done:** the finding itself is unaffected and still needs an owner on
the Android side. That conversation happens directly, not through this
document.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

🏗️ CodeAtlas Ledger Analysis

✅ All Checks Passed


♿ Accessibility (via AccessLint)

💡 Static analysis against WCAG 2.1 AA guidelines for iOS accessibility.

No accessibility issues detected


🏛️ Architecture Analysis

Metric Value ℹ️ What This Means
Components 46 Distinct modules/layers detected in your codebase
Dependency Cycles 16 Circular dependencies (A→B→C→A). Goal: 0
Layer Violations 2 Dependencies that break architectural boundaries
Hotspots 14 Files with high complexity + frequent changes
Avg Coupling 4.96 How interconnected modules are (lower is better, <1.0 is good)

ℹ️ This diff changed 0 architecture-relevant files — the numbers above are the repo baseline, unchanged by this PR.

⚠️ 2 layer violation(s) — see Architecture Findings below for the offending dependency edge(s).

🔄 Dependency Cycles

See full report for cycle details.

📋 Architecture Findings

See full report for detailed findings.


🔍 Reachability Analysis

💡 Detects code that cannot be reached from entry points (dead code).

ℹ️ No architecture-relevant files in this diff — reachability not evaluated.


📊 0 files analyzed | 📦 Download Full Report

Powered by CodeAtlas Ledger
• Accessibility: AccessLint

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

🧪 Unit Test Results

📊 View Full Interactive Report

❌ 3 TESTS FAILED

8187 tests | 8043 passed | 3 failed | 139 skipped | ⏱️ 15m 7s | 📊 98.2% | 📈 45.1% coverage

All 942 classes — 3 with failures (full matrix)
Class Tests Passed Failed Skipped Duration
✅ AccessLintComplianceTests 11 11 0 0 737ms
✅ AccessibilityAnnouncementCenterTests 20 20 0 0 1.82s
✅ AccessibilityLabelTests 9 9 0 0 47ms
✅ AccessibilityPreferencesTests 26 26 0 0 329ms
✅ AccessibilityServiceTests 11 11 0 0 197ms
✅ AccountAuthDocCarryoverTests 5 5 0 0 822ms
✅ AccountAuthSurfaceHostsTests 7 7 0 0 207ms
✅ AccountAwareNetworkTests 10 10 0 0 4.45s
✅ AccountDetailCredentialStateTests 7 0 0 7 955ms
✅ AccountDetailPINVisibilityTests 25 0 0 25 601ms
✅ AccountDetailSignOutConfirmationTests 2 0 0 2 87ms
✅ AccountDetailViewModelGapTests 1 1 0 0 123ms
✅ AccountDetailViewModelLeakTests 1 1 0 0 445ms
✅ AccountDetailViewModelSignedInDerivationTests 5 0 0 5 280ms
✅ AccountDetailViewModelTests 19 0 0 19 453ms
✅ AccountDetailsAuthenticationIsBrowserBasedTests 10 10 0 0 93ms
✅ AccountDetailsNeedsAuthAggregateTests 10 10 0 0 170ms
✅ AccountDetailsURLTests 17 17 0 0 1.57s
✅ AccountErrorReportingTests 1 1 0 0 2ms
✅ AccountModelGapTests 9 9 0 0 798ms
✅ AccountModelTests 20 20 0 0 888ms
✅ AccountProfileDocumentTests 3 3 0 0 716ms
✅ AccountScopeAdapterTests 4 4 0 0 615ms
✅ AccountStateMachineTests 13 13 0 0 4.33s
✅ AccountSwitchBorrowReauthCouplingContractTests 4 4 0 0 671ms
✅ AccountSwitchCleanupTests 8 8 0 0 607ms
✅ AccountSwitchIntegrationTests 8 8 0 0 769ms
✅ AccountSwitchLifecycleTests 9 0 0 9 273ms
✅ AccountsManagerAccountIndexTests 7 7 0 0 249ms
✅ AccountsManagerAuthDocContractTests 1 1 0 0 103ms
✅ AccountsManagerCacheReadTests 4 4 0 0 771ms
✅ AccountsManagerCacheTests 16 16 0 0 272ms
✅ AccountsManagerCancellationTests 5 5 0 0 687ms
✅ AccountsManagerCatalogLoadJoinTests 3 3 0 0 1.57s
✅ AccountsManagerCurrentAccountSwitchContractTests 5 5 0 0 1.18s
✅ AccountsManagerFirstRunDecodeTests 3 3 0 0 510ms
✅ AccountsManagerGapTests 3 3 0 0 114ms
✅ AccountsManagerHelpersTests 12 12 0 0 65ms
✅ AccountsManagerIsolationLintTests 4 4 0 0 1.50s
✅ AccountsManagerLaunchSnapshotTests 13 13 0 0 2.25s
✅ AccountsManagerStateMachineWiringTests 18 18 0 0 2.71s
✅ AccountsManagerTests 51 48 0 3 17.41s
✅ ActiveSessionsViewModelTests 12 12 0 0 412ms
✅ AdobeActivationTests 6 6 0 0 150ms
✅ AdobeCertificateGapTests 7 7 0 0 457ms
✅ AdobeDRMCharacterizationTests 21 21 0 0 307ms
✅ AdobeDRMErrorGapTests 3 3 0 0 10ms
✅ AdobeDRMHandlerTests 12 12 0 0 197ms
✅ AdobeDRMServiceGapTests 2 2 0 0 14ms
✅ AlertModelCoverageTests 6 6 0 0 62ms
✅ AlertModelRetryTests 7 7 0 0 160ms
✅ AlertModelTests 2 2 0 0 228ms
✅ AlertPresentationRawGuardLintTests 6 6 0 0 100ms
✅ AlertUtilsTests 20 20 0 0 563ms
✅ AnnotationContractTests 3 3 0 0 82ms
✅ AnnotationDeviceIDTests 2 2 0 0 148ms
✅ AnnotationPostResponseContractTests 1 1 0 0 4ms
✅ AnnouncementChainTests 5 5 0 0 49ms
✅ AnnouncementTests 3 3 0 0 31ms
✅ AnonymousBorrowBaselineFixtureTests 13 13 0 0 170ms
✅ AnonymousBorrowCandidateFixtureTests 6 6 0 0 27ms
✅ AnonymousBorrowDeltaTests 2 2 0 0 19ms
✅ AppContainerAudiobookFactoryTests 3 3 0 0 744ms
✅ AppContainerAuthCoordinatorRegistrationTests 3 3 0 0 10ms
✅ AppContainerImageLoaderInjectionTests 4 4 0 0 86ms
✅ AppContainerIsolationLintTests 7 7 0 0 1.97s
✅ AppContainerResetTests 5 5 0 0 134ms
✅ AppContainerTests 5 5 0 0 20ms
✅ AppContainerWithSignInModalSheetPresenterTests 2 2 0 0 14ms
✅ AppHealthViewModelTests 8 8 0 0 203ms
✅ AppLaunchTrackerExtendedTests 16 16 0 0 238ms
✅ AppLaunchTrackerTests 10 10 0 0 479ms
✅ AppLaunchTrackerWiringTests 2 2 0 0 90ms
✅ AppRatingServiceOverrideTests 3 3 0 0 33ms
✅ AppRatingServiceTests 9 9 0 0 503ms
✅ AppRouteTests 5 5 0 0 34ms
✅ AppTabHostMiniPlayerIntegrationTests 6 6 0 0 317ms
✅ AppTabHostViewBadgeCountTests 10 10 0 0 617ms
✅ AppTabRouterCoverageTests 4 4 0 0 4.71s
✅ AppTabRouterGapTests 3 3 0 0 21ms
✅ ArrayExtensionsTests 6 6 0 0 104ms
✅ AudioBookmarkGapTests 6 6 0 0 199ms
✅ AudioEngineWrapperTests 8 8 0 0 134ms
✅ AudioInterruptionLogicTests 6 6 0 0 20ms
✅ AudioSessionActivatorTests 8 8 0 0 73ms
✅ AudiobookAccessibilityTests 7 7 0 0 64ms
✅ AudiobookBackgroundAudioTests 2 2 0 0 36.43s
✅ AudiobookBearerTokenRecoveryTests 21 21 0 0 111ms
✅ AudiobookBookmarkBusinessLogicConcurrencyTests 3 3 0 0 280ms
✅ AudiobookBookmarkBusinessLogicPositionWriteTests 8 8 0 0 381ms
✅ AudiobookBookmarkBusinessLogicTests 21 21 0 0 4.24s
✅ AudiobookChapterTOCNormalizationTests 6 6 0 0 67ms
✅ AudiobookColdLoadRecoveryTests 4 4 0 0 112ms
✅ AudiobookContentGateTests 11 11 0 0 404ms
✅ AudiobookCrossVendorSmokeTests 4 4 0 0 80ms
✅ AudiobookDataManagerEmptyQueueTests 1 1 0 0 5ms
✅ AudiobookDataManagerErrorHandlingTests 5 5 0 0 476ms
✅ AudiobookDataManagerModelsTests 20 20 0 0 607ms
✅ AudiobookDataManagerNetworkSyncTests 5 5 0 0 503ms
✅ AudiobookDataManagerSaveTests 4 4 0 0 79ms
✅ AudiobookDataManagerStoreRecoveryTests 5 5 0 0 217ms
✅ AudiobookFileLoggerTests 15 15 0 0 337ms
❌ AudiobookFirstOpenHangTests 15 14 1 0 2.65s
✅ AudiobookLoadFailureSAMLReauthTests 10 10 0 0 1.18s
✅ AudiobookLoaderDispatchTests 7 7 0 0 2.08s
✅ AudiobookLoaderFinalizeBuildTests 11 11 0 0 769ms
✅ AudiobookLoaderOPDSShapeMatrixTests 8 0 0 8 156ms
✅ AudiobookLoaderPredicateTests 11 11 0 0 155ms
✅ AudiobookLoaderTests 2 2 0 0 129ms
✅ AudiobookMorphingPlayerViewTests 20 20 0 0 273ms
✅ AudiobookNetworkValidationTests 3 3 0 0 148ms
✅ AudiobookOpenStateRaceTests 3 3 0 0 447ms
✅ AudiobookPhoneAlertContentTests 3 3 0 0 12ms
✅ AudiobookPlaybackStateTests 3 3 0 0 263ms
✅ AudiobookPlaybackTests 26 26 0 0 169ms
✅ AudiobookPlaytimesLifecycleTests 6 6 0 0 604ms
✅ AudiobookPositionAdapterContractTests 3 3 0 0 1.07s
✅ AudiobookPositionPolicyValidatorTests 14 14 0 0 315ms
✅ AudiobookPositionRestoreTests 20 20 0 0 593ms
✅ AudiobookReadinessPlaybackContractTests 2 2 0 0 294ms
✅ AudiobookSAMLReauthTests 6 6 0 0 65ms
✅ AudiobookSessionErrorDescriptionTests 4 4 0 0 33ms
✅ AudiobookSessionErrorExtTests 4 4 0 0 48ms
✅ AudiobookSessionErrorTests 3 3 0 0 7ms
✅ AudiobookSessionManagerErrorMappingTests 6 6 0 0 200ms
✅ AudiobookSessionManagerFlagGatePresentationTests 4 4 0 0 100ms
✅ AudiobookSessionManagerPresenterMigrationTests 10 10 0 0 353ms
✅ AudiobookSessionManagerShutdownTests 12 12 0 0 1.51s
✅ AudiobookSessionPresenterLifecycleContractTests 3 3 0 0 213ms
✅ AudiobookSessionPresenterTests 31 31 0 0 452ms
✅ AudiobookSessionStateTests 6 6 0 0 391ms
✅ AudiobookSessionStateTransitionTests 22 22 0 0 4.26s
✅ AudiobookSkipIntervalSettingsTests 7 7 0 0 283ms
✅ AudiobookSleepTimerIntegrationTests 5 5 0 0 408ms
✅ AudiobookStorageLocationTests 3 3 0 0 162ms
✅ AudiobookTOCTests 18 18 0 0 505ms
✅ AudiobookTimeEntryTests 6 6 0 0 25ms
✅ AudiobookTimeTrackerEdgeTests 8 8 0 0 145ms
✅ AudiobookTimeTrackerLifecycleTests 5 5 0 0 1.35s
✅ AudiobookTimeTrackerTests 9 9 0 0 183ms
✅ AudiobookTrackCompletionTests 2 2 0 0 91ms
✅ AudiobookTypeRoutingTests 5 5 0 0 87ms
✅ AudiobookVendorAdapterTests 5 5 0 0 58ms
✅ AudiobookVendorRecoveryContractTests 1 1 0 0 59ms
✅ AudiobookmarkTests 4 4 0 0 92ms
✅ AuthCoordinatorTelemetryTests 5 5 0 0 44ms
✅ AuthDecisionEventEmissionTests 7 7 0 0 88ms
✅ AuthDocumentContractTests 2 2 0 0 6ms
✅ AuthDocumentVariantsContractTests 5 5 0 0 12ms
✅ AuthErrorCategoryTests 12 12 0 0 276ms
✅ AuthErrorProblemDocSeamTests 6 6 0 0 431ms
✅ AuthFlowSecurityTests 3 0 0 3 38ms
✅ AuthReducerTests 21 21 0 0 670ms
✅ AuthTypeTests 7 7 0 0 86ms
✅ AuthenticationTests 19 19 0 0 464ms
✅ BackgroundDownloadHandlerTests 28 28 0 0 312ms
✅ BackgroundListenerTests 2 2 0 0 10ms
✅ BackgroundReconciliationContractTests 8 8 0 0 2.09s
✅ BackgroundSessionRoutingTests 6 6 0 0 21ms
✅ BackupExclusionMigrationTests 3 3 0 0 35ms
✅ BadgeDefinitionTests 33 33 0 0 307ms
✅ BadgeServiceTests 16 16 0 0 243ms
✅ BadgeUnlockPhaseTests 4 4 0 0 6ms
✅ BadgesViewModelTests 14 14 0 0 175ms
✅ BasicAuthEmptyCredentialTests 4 4 0 0 29ms
✅ BearerTokenAdapterTests 5 4 0 1 106ms
✅ BearerTokenFulfillFlowTests 4 4 0 0 40ms
✅ BearerTokenRefreshTests 4 4 0 0 17ms
✅ BearerTokenResponseDetectionTests 7 7 0 0 139ms
✅ BeginningPositionPolicyTests 8 8 0 0 429ms
✅ BookAvailabilityFormatterTests 18 18 0 0 157ms
✅ BookButtonMapperHoldReadyTests 10 10 0 0 197ms
✅ BookButtonMapperTests 21 21 0 0 1.29s
✅ BookButtonMapperViewModelTests 18 18 0 0 436ms
✅ BookButtonStateTests 8 8 0 0 321ms
✅ BookButtonTypeMetaTests 4 4 0 0 90ms
✅ BookButtonTypeTests 13 13 0 0 327ms
✅ BookCellModelActionTests 18 18 0 0 698ms
✅ BookCellModelCacheInvalidationTests 9 9 0 0 306ms
✅ BookCellModelCachePrefetchSafetyTests 9 9 0 0 430ms
✅ BookCellModelCacheTests 22 22 0 0 1.56s
✅ BookCellModelComputedPropertyTests 19 19 0 0 493ms
✅ BookCellModelOfflineTests 9 9 0 0 279ms
✅ BookCellModelRegistryBindingTests 4 4 0 0 154ms
✅ BookCellModelStateTests 16 16 0 0 2.59s
✅ BookCellModelStreamingHTMLTests 2 2 0 0 126ms
✅ BookCellStateComprehensiveTests 14 14 0 0 353ms
✅ BookContentResetServiceTests 2 2 0 0 26ms
✅ BookDetailMetadataHydrationTests 6 6 0 0 110ms
✅ BookDetailMetadataMergeContractTests 5 5 0 0 140ms
✅ BookDetailOpenRoutingTests 3 3 0 0 124ms
✅ BookDetailViewModelAudiobookDismissTests 1 1 0 0 15ms
✅ BookDetailViewModelTests 91 91 0 0 5.40s
✅ BookFileManagerAccountScopingTests 5 5 0 0 205ms
✅ BookFileManagerSideloadResolutionTests 4 4 0 0 97ms
✅ BookFileManagerTests 8 8 0 0 57ms
✅ BookListViewAccessibilityTests 9 9 0 0 151ms
✅ BookPreviewTests 4 4 0 0 48ms
✅ BookRegistryStoreTests 26 26 0 0 612ms
✅ BookRegistrySyncReadinessTests 7 3 0 4 1.16s
✅ BookRegistrySyncReentrancyTests 6 6 0 0 322ms
✅ BookRegistrySyncSideloadExemptionTests 2 0 0 2 75ms
✅ BookRegistrySyncTests 36 31 0 5 1.80s
✅ BookReturnCleverReauthTests 1 1 0 0 124ms
✅ BookReturnServiceAuthCoordinatorTests 3 3 0 0 627ms
✅ BookReturnServiceContractTests 9 9 0 0 581ms
❌ BookReturnServiceTests 19 18 1 0 17.74s
✅ BookServiceAudiobookOpenTests 2 2 0 0 16ms
✅ BookSignInRedirectHandlerTests 8 8 0 0 661ms
✅ BookStateIntegrationTests 8 8 0 0 852ms
✅ BookmarkBusinessLogicExtendedTests 6 6 0 0 560ms
✅ BookmarkDeletionLogTests 3 3 0 0 795ms
✅ BookmarkDeviceIdMatchingTests 3 3 0 0 154ms
✅ BookmarkExistenceTests 4 4 0 0 298ms
✅ BookmarkManagerTests 24 24 0 0 2.89s
✅ BookmarkSortingTests 1 1 0 0 162ms
✅ BookmarkSyncTests 3 3 0 0 441ms
✅ BorrowAndDownloadIntegrationTests 7 7 0 0 349ms
✅ BorrowErrorMessageTests 13 13 0 0 96ms
✅ BorrowErrorPresenterTests 6 6 0 0 141ms
✅ BorrowOperationAuthCoordinatorTests 6 6 0 0 314ms
✅ BorrowOperationCleverReauthTests 2 2 0 0 1.00s
✅ BorrowOperationContractTests 8 8 0 0 865ms
✅ BorrowOperationStreamingHTMLTests 3 3 0 0 90ms
✅ BorrowOperationTests 13 13 0 0 1.45s
✅ BorrowOperationTimeoutTests 3 3 0 0 120ms
✅ BorrowReauthResettingTests 4 4 0 0 547ms
✅ BorrowReducerContractTests 2 2 0 0 18ms
✅ BorrowReducerCoreContractTests 12 12 0 0 493ms
✅ BorrowReducerTests 21 21 0 0 1.11s
✅ BundledRegistrySnapshotTests 5 5 0 0 172ms
✅ ButtonStateMonotonicClampTests 10 10 0 0 5.38s
✅ ButtonStateTests 16 16 0 0 515ms
✅ ButtonStyleTypeTests 2 2 0 0 190ms
✅ C64ConversionTests 6 6 0 0 7ms
✅ CarPlayAudiobookBridgePresenterMigrationTests 2 2 0 0 11ms
✅ CarPlayAuthHelperReadinessTests 3 3 0 0 589ms
✅ CarPlayChapterListTests 3 3 0 0 123ms
✅ CarPlayIntegrationTests 2 2 0 0 98ms
✅ CarPlayLibraryRefreshTests 3 3 0 0 83ms
✅ CarPlayNowPlayingTemplateTests 4 4 0 0 659ms
✅ CarPlayOpenAppAlertTests 6 6 0 0 482ms
✅ CarPlayPlaybackErrorTests 8 8 0 0 31ms
✅ CarPlayTests 12 12 0 0 152ms
✅ CarPlayTimeTrackingTests 3 3 0 0 126ms
✅ CatalogAPIDedupeTests 3 3 0 0 461ms
✅ CatalogAPIEntryPointTests 1 1 0 0 3ms
✅ CatalogAccessibilityTests 8 8 0 0 251ms
✅ CatalogCacheKeyAndIsolationTests 12 12 0 0 40.21s
✅ CatalogCacheMetadataExactBoundaryTests 4 4 0 0 19ms
✅ CatalogCacheMetadataTests 21 21 0 0 559ms
✅ CatalogCrawlSchedulerTests 9 9 0 0 205ms
✅ CatalogFeedModelTests 4 4 0 0 33ms
✅ CatalogFilterGroupModelTests 17 17 0 0 516ms
✅ CatalogFilterModelTests 17 17 0 0 376ms
✅ CatalogFilterServiceTests 29 29 0 0 666ms
✅ CatalogFilterTests 1 1 0 0 2ms
✅ CatalogLaneAssemblyTests 7 7 0 0 84ms
✅ CatalogLaneModelStructTests 20 20 0 0 863ms
✅ CatalogLaneModelTests 3 3 0 0 6ms
✅ CatalogLaneMoreFilterStateTests 8 8 0 0 173ms
✅ CatalogLaneMoreViewModelTests 43 43 0 0 454ms
✅ CatalogLaneRowViewAccessibilityTests 11 11 0 0 83ms
✅ CatalogLaneSortingTests 5 5 0 0 82ms
✅ CatalogLoadIntegrationTests 6 6 0 0 98ms
✅ CatalogOPDS2NegotiationTests 12 12 0 0 607ms
✅ CatalogPreloaderTests 6 6 0 0 63ms
✅ CatalogProblemDocumentTests 6 6 0 0 112ms
✅ CatalogRepositoryCoreTests 9 9 0 0 861ms
✅ CatalogRepositoryStaleWhileRevalidateTests 12 12 0 0 465ms
✅ CatalogRepositoryTests 19 19 0 0 991ms
✅ CatalogSearchViewModelRegistryUpdateTests 5 5 0 0 174ms
✅ CatalogSearchViewModelTests 67 67 0 0 5.17s
✅ CatalogSelectorsTests 2 2 0 0 13ms
✅ CatalogSortServiceTests 14 14 0 0 233ms
✅ CatalogStateTests 7 7 0 0 70ms
✅ CatalogViewContinueRowsIntegrationTests 3 3 0 0 150ms
✅ CatalogViewLibraryIconTests 2 2 0 0 20ms
✅ CatalogViewModelStateMachineTests 19 19 0 0 504ms
✅ ChaosFaultInjectionTests 5 5 0 0 192ms
✅ ChapterChangeDetectorTests 5 5 0 0 30ms
✅ ChapterTOCNormalizerTests 7 7 0 0 83ms
✅ CirculationAnalyticsTests 4 4 0 0 53ms
✅ ColdStartResumeIntegrationTests 10 10 0 0 2.19s
✅ ColorExtensionTests 5 5 0 0 155ms
✅ ConcurrentBookStateTests 3 3 0 0 307ms
✅ ConcurrentDownloadStateTests 3 3 0 0 242ms
✅ ConcurrentTokenRefreshTests 2 2 0 0 129ms
✅ ContinueRowSectionTests 6 6 0 0 425ms
✅ ContinuousPlaybackTrackingTests 3 3 0 0 563ms
✅ CookiePersistenceTests 10 10 0 0 1.06s
✅ CrawlStateTests 16 16 0 0 643ms
✅ CrawlableFeedAnalysisTests 17 17 0 0 348ms
✅ CrawlerFallbackTests 12 12 0 0 442ms
✅ CredentialEdgeCaseTests 6 6 0 0 95ms
✅ CredentialPrivacyTests 4 4 0 0 340ms
✅ CredentialPromptCoordinatorTests 4 4 0 0 82ms
✅ CredentialSnapshotInvalidationTests 5 0 0 5 5.49s
✅ CredentialStoreCharacterizationTests 7 7 0 0 531ms
✅ CrossDeviceBookmarkSyncTests 12 12 0 0 141ms
✅ CrossDeviceSyncE2ETests 8 8 0 0 2.09s
✅ CrossDomain401Tests 8 8 0 0 242ms
✅ CrossFormatMappingTests 14 14 0 0 137ms
✅ DPLAErrorTests 3 3 0 0 21ms
✅ DRMAdversarialTests 4 1 0 3 272ms
✅ DRMFulfilledPublicationTests 6 6 0 0 54ms
✅ DataBase64Tests 3 3 0 0 20ms
✅ DataReceptionComparisonTests 2 2 0 0 40ms
✅ DateExtensionTests 9 9 0 0 1.06s
✅ DateFormattingTests 4 4 0 0 163ms
✅ Date_NYPLAdditionsTests 7 7 0 0 1.23s
✅ DebugSettingsForceSkeletonsTests 4 4 0 0 46ms
✅ DebugSettingsGapTests 4 4 0 0 15ms
✅ DebugSettingsTests 31 31 0 0 801ms
✅ DefaultCatalogAPITests 31 31 0 0 2.57s
✅ DefaultRecentlyReadingServiceTests 13 13 0 0 98ms
✅ DeriveInitialStateTests 4 4 0 0 27ms
✅ DeveloperSettingsEngineeringTierTests 4 4 0 0 5ms
✅ DeveloperSettingsViewModelOverrideTests 3 0 0 3 59ms
✅ DeviceLogCollectorGapTests 2 2 0 0 23ms
✅ DeviceLogCollectorTests 13 13 0 0 981ms
✅ DeviceOrientationTests 7 7 0 0 112ms
✅ DeviceSpecificErrorMonitorTests 11 11 0 0 265ms
✅ DictionaryExtensionsTests 5 5 0 0 248ms
✅ DiskBudgetManagerTests 7 7 0 0 139ms
✅ DiskBudgetTests 2 2 0 0 15ms
✅ DownloadAccountContextAdapterTests 11 11 0 0 659ms
✅ DownloadAlertPresenterTests 8 8 0 0 442ms
✅ DownloadAnnouncementServiceTests 12 12 0 0 217ms
✅ DownloadAuthRetryHandlerAuthCoordinatorTests 6 6 0 0 4.72s
✅ DownloadAuthRetryHandlerTaskLifecycleTests 4 4 0 0 390ms
✅ DownloadAuthRetryHandlerTests 17 17 0 0 2.30s
✅ DownloadCancellationHandlerTests 5 5 0 0 73ms
✅ DownloadCompleteMomentTests 6 6 0 0 14ms
✅ DownloadCompletionParserTests 9 9 0 0 746ms
✅ DownloadCoordinatorIntegrationTests 10 10 0 0 166ms
✅ DownloadCoordinatorTests 11 11 0 0 421ms
✅ DownloadDiskSpaceTests 2 2 0 0 27ms
✅ DownloadErrorInfoTests 3 3 0 0 16ms
✅ DownloadErrorRecoveryPolicyTests 11 11 0 0 903ms
✅ DownloadErrorRecoveryTests 3 3 0 0 56ms
✅ DownloadFreeSpaceExhaustionTests 11 11 0 0 307ms
✅ DownloadInfoTests 5 5 0 0 472ms
✅ DownloadIntegrityTests 10 10 0 0 818ms
✅ DownloadOnlyOnWiFiTests 10 10 0 0 282ms
✅ DownloadPersistenceStoreTests 5 5 0 0 77ms
✅ DownloadProgressPublisherCoreTests 19 19 0 0 1.14s
✅ DownloadProgressPublisherTests 2 2 0 0 267ms
✅ DownloadQueueIntegrationTests 3 3 0 0 351ms
✅ DownloadQueueOrchestratorTests 9 9 0 0 350ms
✅ DownloadRMSDKHandoffTests 1 1 0 0 1ms
✅ DownloadReconciliationLaunchOrderContractTests 2 2 0 0 23ms
✅ DownloadReconciliationTests 17 17 0 0 1.18s
✅ DownloadRedirectTests 7 7 0 0 9ms
✅ DownloadResumeAfterKillTests 7 7 0 0 129ms
✅ DownloadSlotManagementTests 5 5 0 0 57ms
✅ DownloadStartCoordinatorContractTests 5 5 0 0 118ms
✅ DownloadStartCoordinatorTests 9 9 0 0 242ms
✅ DownloadStartDispatcherContractTests 12 12 0 0 490ms
✅ DownloadStartDispatcherTests 26 26 0 0 1.31s
✅ DownloadStartReducerContractTests 24 24 0 0 405ms
✅ DownloadStateMachineIntegrationTests 15 15 0 0 818ms
✅ DownloadStateMachineTests 5 5 0 0 68ms
✅ DownloadStateManagerTests 16 16 0 0 279ms
✅ DownloadTaskLifecycleServiceTests 9 9 0 0 72ms
✅ DownloadTaskPersistenceTests 14 14 0 0 126ms
✅ DownloadThrottlingContractTests 2 2 0 0 9ms
✅ DownloadThrottlingServiceTests 10 10 0 0 330ms
✅ DownloadTransferRetryTests 6 6 0 0 2.21s
✅ DownloadWatchdogTests 3 3 0 0 226ms
✅ EPUBKeyCommandsPP4289Tests 4 4 0 0 728ms
✅ EPUBModuleTests 4 4 0 0 170ms
✅ EPUBPositionTests 10 10 0 0 301ms
✅ EPUBSearchViewModelTests 18 18 0 0 128ms
✅ EPUBToolbarToggleTests 11 11 0 0 42ms
✅ EffectBoundaryTests 6 6 0 0 31ms
✅ EmailAddressTests 16 16 0 0 146ms
✅ EpubSampleFactoryTests 5 5 0 0 14ms
✅ ErrorActivityTrackerTests 12 12 0 0 463ms
✅ ErrorDetailTests 14 14 0 0 251ms
✅ ErrorDetailViewControllerGapTests 3 3 0 0 155ms
✅ ErrorDetailViewControllerTests 14 14 0 0 1.13s
✅ ErrorLogExporterTests 5 5 0 0 99ms
✅ ExecutorNetworkHermeticityTests 1 1 0 0 595ms
✅ ExpiredLoanStringsTests 5 5 0 0 36ms
✅ FacetEnumTests 3 3 0 0 18ms
✅ FacetToolbarAccessibilityTests 5 5 0 0 58ms
✅ FacetViewModelLogoDelegateTests 4 4 0 0 35ms
✅ FacetViewModelTests 18 18 0 0 287ms
✅ FetchManifestWithBearerTokenLCPSafetyTests 1 1 0 0 86ms
✅ FetchManifestWithBearerTokenTests 9 9 0 0 133ms
✅ FetchOpenAccessManifestLCPSafetyTests 4 4 0 0 16ms
✅ FileURLGenerationTests 3 3 0 0 18ms
✅ FindawayChapterStatusGuardTests 1 1 0 0 2ms
✅ FindawaySavedVsPlayedTests 1 1 0 0 81ms
✅ FloatTPPAdditionsTests 5 5 0 0 69ms
✅ FocusIndicationTests 7 7 0 0 162ms
✅ FontManagerTests 17 17 0 0 174ms
✅ ForceResetTests 6 6 0 0 64ms
✅ GeneralCacheClearOnUpdateTests 3 3 0 0 231ms
✅ GeneralCacheTests 20 20 0 0 875ms
✅ GroupEnumTests 1 1 0 0 18ms
✅ HTMLTextViewTests 70 70 0 0 21.55s
✅ HoldNotificationClassificationTests 2 2 0 0 17ms
✅ HoldsBadgeCountTests 9 9 0 0 156ms
✅ HoldsBookViewModelTests 8 8 0 0 215ms
✅ HoldsReducerTests 11 11 0 0 978ms
✅ HoldsSyncFailureTests 12 12 0 0 643ms
✅ HoldsViewModelTests 23 23 0 0 268ms
✅ HostFailureTrackerTests 2 2 0 0 8ms
✅ ImageCacheContinuationTests 1 1 0 0 379ms
✅ ImageCacheOffMainIsolationTests 2 2 0 0 212ms
✅ ImageCacheTypeTests 1 1 0 0 2ms
✅ ImageCoverKeyUnificationTests 2 2 0 0 3ms
✅ ImageLoaderTests 14 14 0 0 131ms
✅ InflightFeedFetchesTimeoutTests 4 4 0 0 10.33s
✅ IntExtensionsTests 4 4 0 0 167ms
✅ IsReaderActiveTrackingModifierTests 4 4 0 0 24ms
✅ KeyboardNavigationFKATests 11 11 0 0 247ms
✅ KeyboardNavigationHandlerTests 16 16 0 0 113ms
✅ KeyboardVoiceOverTests 5 5 0 0 118ms
✅ LCPAcquisitionPredicateTests 4 4 0 0 121ms
✅ LCPAdapterTests 8 8 0 0 208ms
✅ LCPAudiobookURLSchemeTests 4 4 0 0 44ms
✅ LCPAudiobooksTests 21 21 0 0 1.13s
✅ LCPBotanCRLGuardTests 5 5 0 0 191ms
✅ LCPCharacterizationTests 31 31 0 0 1.37s
✅ LCPClientTests 9 9 0 0 145ms
✅ LCPFulfillmentHandlerTests 8 8 0 0 775ms
✅ LCPKeychainMigrationTests 3 3 0 0 22ms
✅ LCPLibraryServiceTests 20 20 0 0 600ms
✅ LCPLicenseDocumentDetectionTests 5 5 0 0 28ms
✅ LCPLicenseFilePathTests 3 3 0 0 46ms
✅ LCPOrphanedDownloadRegistryTests 4 4 0 0 113ms
✅ LCPPDFAcquisitionPredicateTests 5 5 0 0 78ms
✅ LCPPDFDiskExtractTests 5 5 0 0 131ms
✅ LCPPDFOpenProgressTests 13 13 0 0 87ms
✅ LCPPassphraseReadinessTests 2 2 0 0 21ms
✅ LCPSessionIdentifierTests 3 3 0 0 83ms
✅ LegacySAMLProblemDocumentPropagationTests 7 7 0 0 744ms
✅ LibrariesSectionViewModelTests 16 16 0 0 263ms
✅ LibraryCatalogMergerTests 9 9 0 0 85ms
✅ LibraryRegistryCrawlerTests 15 15 0 0 496ms
✅ LicensesServiceTests 4 4 0 0 281ms
✅ LiveCrawlableParsingTest 4 0 0 4 66ms
✅ LoanEvictionPolicyTests 13 13 0 0 198ms
✅ LoanRenewalServiceTests 9 9 0 0 281ms
✅ LocalBookContentServiceTests 7 7 0 0 146ms
✅ LocalFileAdapterTests 6 5 0 1 443ms
✅ LogTests 13 13 0 0 397ms
✅ LoginKeyboardTests 8 8 0 0 1.95s
✅ MainActorHelpersTests 22 22 0 0 709ms
✅ MappedCatalogBridgeTests 3 3 0 0 8ms
✅ MappedCatalogModelTests 11 11 0 0 335ms
✅ MockBackendExpiredCredentialsTests 3 3 0 0 38ms
✅ MockBackendHoldsTests 3 3 0 0 2.02s
✅ MockBackendIntegrationTests 4 4 0 0 222ms
✅ MockBackendLoanLimitTests 2 2 0 0 63ms
✅ MockBackendRouteMatchingTests 4 4 0 0 124ms
✅ MockBackendServerDownTests 1 1 0 0 52ms
✅ MockIsolationLintTests 5 5 0 0 1.70s
✅ MultiLibraryTokenIsolationTests 14 14 0 0 13.15s
✅ MyBooksDownloadCenterAccountIdThreadingTests 7 7 0 0 2.15s
✅ MyBooksDownloadCenterAccountScopeSeamTests 3 3 0 0 80ms
✅ MyBooksDownloadCenterAdeptGapTests 3 3 0 0 14ms
✅ MyBooksDownloadCenterConcurrencyTests 22 22 0 0 319ms
✅ MyBooksDownloadCenterEvictionTests 7 7 0 0 1.42s
✅ MyBooksDownloadCenterOfflineTests 8 8 0 0 188ms
✅ MyBooksDownloadSessionInvalidationTests 3 3 0 0 31ms
✅ MyBooksSimplifiedBearerTokenTests 17 17 0 0 402ms
✅ MyBooksViewModelBooksPublisherTests 3 3 0 0 65ms
✅ MyBooksViewModelConcurrencyTests 4 4 0 0 670ms
✅ MyBooksViewModelDownloadStateTests 3 3 0 0 70ms
✅ MyBooksViewModelEmptyArrayTests 3 3 0 0 32ms
✅ MyBooksViewModelEmptyStateTests 4 4 0 0 56ms
✅ MyBooksViewModelExtendedTests 15 15 0 0 271ms
✅ MyBooksViewModelFacetIntegrationTests 4 4 0 0 32ms
✅ MyBooksViewModelFacetPublisherTests 5 5 0 0 63ms
✅ MyBooksViewModelFilterSortInteractionTests 2 2 0 0 13ms
✅ MyBooksViewModelFilterTests 9 9 0 0 126ms
✅ MyBooksViewModelGuardConditionsTests 2 2 0 0 24ms
✅ MyBooksViewModelLargeDatasetTests 2 2 0 0 418ms
✅ MyBooksViewModelLoadAccountTests 2 2 0 0 425ms
✅ MyBooksViewModelLoginStateTests 4 4 0 0 379ms
✅ MyBooksViewModelMultipleAuthorSortingTests 3 3 0 0 17ms
✅ MyBooksViewModelNotificationTests 4 4 0 0 343ms
✅ MyBooksViewModelOfflineFilteringTests 3 3 0 0 113ms
✅ MyBooksViewModelPublisherTests 7 7 0 0 160ms
✅ MyBooksViewModelSearchEdgeCaseTests 6 6 0 0 54ms
✅ MyBooksViewModelSearchQueryTests 3 3 0 0 43ms
✅ MyBooksViewModelSortPersistenceTests 3 3 0 0 54ms
✅ MyBooksViewModelSortingIntegrationTests 5 5 0 0 258ms
✅ MyBooksViewModelSortingTests 6 6 0 0 388ms
✅ MyBooksViewModelStateTransitionTests 3 3 0 0 331ms
✅ MyBooksViewModelUIBindingTests 3 3 0 0 17ms
✅ NSErrorAdditionsTests 7 7 0 0 145ms
✅ NSNotificationTPPTests 3 3 0 0 35ms
✅ NavigationCoordinatorTests 18 18 0 0 167ms
✅ NavigationFreezePreventionTests 5 5 0 0 47ms
✅ NetworkCacheClearRoutingTests 3 3 0 0 67ms
✅ NetworkExecutorCredentialGuardTests 8 8 0 0 132ms
✅ NetworkExecutorResponseRegressionTests 4 4 0 0 51ms
✅ NetworkExecutorTaskTypeTests 3 3 0 0 54ms
✅ NetworkOfflineDetectionTests 3 3 0 0 4ms
✅ NetworkQueueTests 11 11 0 0 208ms
✅ NetworkRequestQueueTests 2 2 0 0 10.11s
✅ NetworkRetryLogicTests 7 7 0 0 140ms
✅ NetworkTimeoutTests 2 2 0 0 40ms
✅ NotificationEventTypeContractTests 7 7 0 0 50ms
✅ NotificationPayloadContractTests 10 10 0 0 3.23s
✅ NotificationServiceStateMachineTests 9 9 0 0 1.60s
✅ NotificationServiceTests 16 16 0 0 123ms
✅ NotificationServiceTokenTests 13 13 0 0 172ms
✅ NotificationSyncThrottleTests 5 5 0 0 134ms
✅ NotificationTokenDataTests 4 4 0 0 125ms
✅ NotificationTokenRegistrationTests 10 10 0 0 491ms
✅ NowPlayingCoordinatorBackgroundTests 6 6 0 0 776ms
✅ NowPlayingCoordinatorTests 19 19 0 0 4.07s
✅ OAuthSAMLRedirectRegressionTests 4 4 0 0 457ms
✅ OIDCAuthDocumentParsingTests 4 4 0 0 555ms
✅ OIDCAuthTypeTests 5 5 0 0 94ms
✅ OIDCAuthenticationPropertyTests 8 8 0 0 421ms
✅ OIDCCallbackEdgeCaseTests 9 9 0 0 3.09s
✅ OIDCCallbackHandlingTests 5 5 0 0 601ms
✅ OIDCCallbackSchemeTests 3 3 0 0 51ms
✅ OIDCIsolationRegressionTests 6 6 0 0 299ms
✅ OIDCLoginRoutingTests 3 3 0 0 235ms
✅ OIDCMakeRequestTests 3 3 0 0 933ms
✅ OIDCNSCodingTests 1 1 0 0 44ms
✅ OIDCNetworkLayer401Tests 5 5 0 0 468ms
✅ OIDCReauthOnExpiredTokenTests 5 5 0 0 403ms
✅ OIDCRedirectURIConstructionTests 6 6 0 0 466ms
✅ OIDCRegressionTests 9 9 0 0 455ms
✅ OIDCSelectedAuthenticationTests 2 2 0 0 76ms
✅ OIDCSignOutRegressionTests 6 6 0 0 583ms
✅ OIDCTokenRefreshRegressionTests 6 6 0 0 529ms
✅ OIDCUpdateUserAccountTests 5 5 0 0 281ms
✅ OIDCViewModelRegressionTests 1 1 0 0 31ms
✅ OIDCViewModelSignInTests 2 2 0 0 41ms
✅ OPDS1BorrowEntryContractTests 4 4 0 0 174ms
✅ OPDS1CatalogGroupedContractTests 3 3 0 0 14ms
✅ OPDS1HoldEntriesContractTests 4 4 0 0 135ms
✅ OPDS1LoansFeedContractTests 6 6 0 0 84ms
✅ OPDS1ParsingTests 34 34 0 0 745ms
✅ OPDS1RevokeResponseContractTests 2 2 0 0 14ms
✅ OPDS2AuthenticationDocumentTests 18 18 0 0 484ms
✅ OPDS2AvailabilityTests 4 4 0 0 43ms
✅ OPDS2BookBridgeTests 44 44 0 0 942ms
✅ OPDS2BorrowResponseContractTests 3 3 0 0 22ms
✅ OPDS2CatalogWiringTests 21 21 0 0 1.24s
✅ OPDS2CatalogsFeedTests 3 3 0 0 441ms
✅ OPDS2ContributorTests 2 2 0 0 99ms
✅ OPDS2EmptyFeedContractTests 1 1 0 0 38ms
✅ OPDS2FeedContractTests 4 4 0 0 73ms
✅ OPDS2FeedParsingTests 11 11 0 0 522ms
✅ OPDS2FeedTests 14 14 0 0 260ms
✅ OPDS2FullMetadataTests 4 4 0 0 19ms
✅ OPDS2FullPublicationTests 13 13 0 0 51ms
✅ OPDS2IntegrationTests 18 18 0 0 336ms
✅ OPDS2LinkArrayTests 5 5 0 0 50ms
✅ OPDS2LinkComputedPropertyTests 20 20 0 0 4.74s
✅ OPDS2LinkRelTests 1 1 0 0 1ms
✅ OPDS2LinkTests 2 2 0 0 54ms
✅ OPDS2ParsingTests 38 38 0 0 741ms
✅ OPDS2PublicationExtendedTests 53 53 0 0 3.09s
✅ OPDS2PublicationImageTests 6 6 0 0 196ms
✅ OPDS2PublicationNarratorTests 3 3 0 0 59ms
✅ OPDS2PublicationTests 2 2 0 0 56ms
✅ OPDS2SamlIDPTests 6 6 0 0 58ms
✅ OPDS2SearchResultsContractTests 3 3 0 0 54ms
✅ OPDS2SubjectTests 2 2 0 0 8ms
✅ OPDS2SupportingTypesTests 5 5 0 0 260ms
✅ OPDSAcquisitionPathExpandedTests 15 15 0 0 230ms
✅ OPDSFeedCacheTests 14 14 0 0 453ms
✅ OPDSFeedMigrationTests 11 11 0 0 347ms
✅ OPDSFeedParsingTests 2 2 0 0 79ms
✅ OPDSFeedServiceStateMachineTests 3 3 0 0 886ms
✅ OPDSFeedServiceTests 2 2 0 0 44ms
✅ OPDSFormatTests 13 13 0 0 110ms
✅ OPDSParserCoreTests 4 4 0 0 147ms
✅ OPDSParserTests 4 4 0 0 21ms
✅ OPDSParsingTests 57 57 0 0 1.45s
✅ OfflineActionTests 29 29 0 0 356ms
✅ OfflineQueueCoordinatorTests 11 11 0 0 124ms
✅ OfflineQueueServiceExtendedTests 13 13 0 0 156ms
✅ OfflineQueueServiceTests 17 17 0 0 404ms
✅ OpenAccessAdapterTests 13 13 0 0 192ms
✅ OverdriveDeferredFulfillmentTests 6 6 0 0 112ms
✅ OverdriveDownloadHandlerTests 9 9 0 0 264ms
✅ OverdriveFulfillmentTests 25 24 0 1 424ms
✅ PDFExtensionsTests 20 20 0 0 373ms
✅ PDFKitThumbnailProviderTests 5 5 0 0 162ms
✅ PDFReaderTests 12 12 0 0 579ms
✅ PDFSearchEmptyStateTests 4 4 0 0 26ms
✅ PP3596RegressionTests 3 3 0 0 40.17s
✅ Palace 2 2 0 0 <1ms
✅ PalaceCheckPropertyTests 8 8 0 0 223ms
✅ PalaceErrorCategoryTests 20 20 0 0 410ms
✅ PalaceErrorExtendedTests 23 23 0 0 113ms
✅ PalaceErrorTests 11 11 0 0 345ms
✅ PalaceHapticTests 4 4 0 0 29ms
✅ PalaceMotionTests 11 11 0 0 129ms
✅ PalacePDFViewTests 12 12 0 0 139ms
❌ PalacePreferencesSettingsRoundTripTests 10 9 1 0 2m 40s
✅ PalacePressableButtonStyleTests 6 6 0 0 288ms
✅ PalaceTestSetupObservationTests 4 4 0 0 307ms
✅ PalaceWiringTestCaseTests 4 4 0 0 67ms
✅ ParserFuzzTests 4 4 0 0 25.10s
✅ PatronProfileContractTests 4 4 0 0 19ms
✅ PerformanceMonitorTests 14 14 0 0 573ms
✅ PerformanceReportTests 14 14 0 0 146ms
✅ PersistentLoggerTests 9 9 0 0 1.50s
✅ PlaybackBootstrapperAudioSessionTests 2 2 0 0 287ms
✅ PlaybackBootstrapperTests 8 8 0 0 225ms
✅ PlaybackFailureRecordTests 5 5 0 0 13ms
✅ PlaybackOpenPolicyTests 7 7 0 0 88ms
✅ PlaybackRateTests 18 18 0 0 462ms
✅ PlaybackTrackingRegressionTests 5 5 0 0 350ms
⚠️ PoolResponsivenessProbeTests 5 4 0 0 2.68s
✅ PositionPersistenceLogicTests 6 6 0 0 301ms
✅ PositionPersistenceTests 2 2 0 0 345ms
✅ PositionSyncServiceTests 13 13 0 0 634ms
✅ PositionSyncTests 5 5 0 0 20ms
✅ PositionWriterContractTests 6 6 0 0 99ms
✅ PostUpdateMigrationTests 5 5 0 0 133ms
✅ ProblemDocumentContractTests 4 4 0 0 36ms
✅ ProblemDocumentLoanExpiryTests 5 5 0 0 46ms
✅ ProblemDocumentTests 12 12 0 0 75ms
✅ ProblemReportEmailTests 8 8 0 0 371ms
✅ RatingCardMotionGateTests 5 5 0 0 42ms
✅ RatingEligibilityPolicyTests 17 17 0 0 99ms
✅ RatingEngagementTrackerTests 9 9 0 0 245ms
✅ RatingFeedbackPresenterTests 3 3 0 0 9ms
✅ RatingPromptPresenterTests 15 15 0 0 1.49s
✅ ReachabilityTests 10 10 0 0 33ms
✅ Reader2BookmarkContractTests 3 3 0 0 47ms
✅ Reader2PositionAdapterContractTests 4 3 0 1 307ms
✅ Reader2PositionResumeContractTests 3 3 0 0 120ms
✅ ReaderAccessibilityTests 7 7 0 0 1.05s
✅ ReaderChromeToggleFadeTests 3 3 0 0 13ms
✅ ReaderEditingActionsTests 5 5 0 0 27ms
✅ ReaderErrorTests 5 5 0 0 89ms
✅ ReaderNavBarVoiceOverTests 2 2 0 0 8ms
✅ ReaderServicePDFRouteTests 3 3 0 0 35ms
✅ ReaderServiceSyncTests 3 3 0 0 745ms
✅ ReaderThemeTests 24 24 0 0 1.14s
✅ ReadingPositionTests 22 22 0 0 1.85s
✅ ReadingSessionTrackerTests 13 13 0 0 617ms
✅ ReadingStatsServiceTests 12 12 0 0 284ms
✅ ReadingStatsStoreTests 9 9 0 0 205ms
✅ RedirectHandlingIntegrationTests 4 4 0 0 100ms
✅ RedirectPolicyTests 9 9 0 0 70ms
✅ RegistryDownloadServicingSeamTests 2 2 0 0 16ms
✅ RegistryFileRecoveryTests 23 23 0 0 1.71s
✅ RemoteFeatureFlagsGapTests 4 4 0 0 903ms
✅ RemoteFeatureFlagsSideLoadingTests 5 5 0 0 77ms
✅ RemoteFeatureFlagsTests 21 21 0 0 1.87s
✅ ResourcePropertiesLengthTests 3 3 0 0 11ms
✅ RetryClassificationTests 17 17 0 0 625ms
✅ ReturnFlowTests 1 1 0 0 171ms
✅ ReturnReducerContractTests 16 16 0 0 326ms
✅ RightsManagementDetectionTests 5 5 0 0 63ms
✅ RightsManagementDispatchContractTests 8 8 0 0 703ms
✅ RightsManagementDispatcherTests 10 10 0 0 935ms
✅ RuntimeQuiescenceGateTests 11 10 0 1 3.67s
✅ RuntimeQuiescenceLintTests 5 5 0 0 992ms
✅ SAMLCookieSyncTests 5 5 0 0 158ms
✅ SAMLLogoutCallbackDetectionTests 4 4 0 0 106ms
✅ SAMLLogoutLinkParsingTests 5 5 0 0 269ms
✅ SAMLLogoutURLTests 4 4 0 0 28ms
✅ SAMLPlusBiblioBoardExpirationTests 8 8 0 0 613ms
✅ SEMigrationsTests 6 6 0 0 450ms
✅ SafeDictionaryTests 21 21 0 0 468ms
✅ SamplePlayerErrorTests 5 5 0 0 14ms
✅ SampleTypeTests 8 8 0 0 304ms
✅ SceneDelegateTests 1 1 0 0 7ms
✅ ScopedResetTests 9 9 0 0 215ms
✅ SearchAccessibilityTests 11 11 0 0 179ms
✅ SearchFlowIntegrationTests 8 8 0 0 108ms
✅ SettingsViewModelComputedPropertyTests 6 6 0 0 150ms
✅ SettingsViewModelEdgeCaseTests 7 7 0 0 93ms
✅ SettingsViewModelGapTests 1 1 0 0 4ms
✅ SettingsViewModelSyncTests 14 14 0 0 1.70s
✅ SettingsViewModelTests 33 33 0 0 853ms
✅ SideloadBoundaryTests 6 6 0 0 1.78s
✅ SideloadImportContractTests 1 1 0 0 2.92s
✅ SideloadedBookManagerTests 17 17 0 0 1.05s
✅ SideloadedBookRegistryTests 14 14 0 0 273ms
✅ SideloadedLaneBridgeTests 6 6 0 0 213ms
✅ SideloadedLaneViewModelTests 7 7 0 0 98ms
✅ SignInFormPresentationTests 3 3 0 0 4ms
✅ SignInModalLifecycleTests 9 9 0 0 125ms
✅ SignInModalPredicateTests 3 3 0 0 116ms
✅ SignInModalSAMLOIDCTests 6 6 0 0 68ms
✅ SignInOAuthErrorPropagationTests 8 8 0 0 861ms
✅ SignInRequestServiceCharacterizationTests 11 11 0 0 488ms
✅ SignInToReadFlowIntegrationTests 5 5 0 0 898ms
✅ SignInWebSheetIntegrationTests 3 3 0 0 8.02s
✅ SignInWebSheetViewModelTests 31 31 0 0 457ms
✅ SignOutCacheClearingTests 3 3 0 0 23ms
✅ SingletonResetRegistryTests 5 5 0 0 59ms
✅ SkeletonTests 22 22 0 0 1.48s
✅ StatsViewModelTests 10 10 0 0 323ms
✅ StatusAnnouncementTests 22 22 0 0 786ms
✅ StopPositionSaveTests 2 2 0 0 7ms
✅ StoreTests 5 5 0 0 168ms
✅ StreamingReaderPresentationContractTests 1 1 0 0 13ms
✅ StreamingReaderProgressStoreTests 7 7 0 0 171ms
✅ StreamingReaderViewControllerScrollRestoreTests 12 12 0 0 1.76s
✅ StreamingReaderViewModelTests 9 9 0 0 51ms
✅ StringExtensionTests 8 8 0 0 831ms
✅ StringExtensionsTests 3 3 0 0 26ms
✅ StringHTMLEntitiesTests 7 7 0 0 40ms
✅ StringNYPLAdditionsTests 4 4 0 0 227ms
✅ String_NYPLAdditionsTests 4 4 0 0 240ms
✅ SupportSectionDecisionTests 5 5 0 0 201ms
✅ SyncConflictResolutionTests 3 3 0 0 1.72s
✅ SyncDeletionGuardTests 5 5 0 0 126ms
✅ SyncDeletionRatioTests 6 6 0 0 196ms
✅ SyncPermissionTests 5 5 0 0 191ms
✅ TPPAccountAuthStateEnumTests 5 5 0 0 91ms
✅ TPPAccountListDataSourceTests 3 3 0 0 199ms
✅ TPPAdobeActivationSkipTests 6 6 0 0 421ms
✅ TPPAgeCheckCompletionTests 5 5 0 0 182ms
✅ TPPAgeCheckIsValidTests 5 5 0 0 357ms
✅ TPPAgeCheckStateMachineTests 4 4 0 0 425ms
✅ TPPAgeCheckTests 6 6 0 0 1.31s
✅ TPPAgeCheckVerifyDecisionTests 5 5 0 0 388ms
✅ TPPAlertUtilsTests 45 45 0 0 920ms
✅ TPPAnnotationsHermeticTests 15 15 0 0 658ms
✅ TPPAnnotationsOverrideTests 4 4 0 0 132ms
✅ TPPAnnotationsTests 29 29 0 0 6.31s
✅ TPPAnnouncementManagerTests 3 3 0 0 27ms
✅ TPPAuthDocumentContractTests 3 3 0 0 145ms
✅ TPPBackgroundExecutorTests 3 3 0 0 91ms
✅ TPPBadgeImageGapTests 2 2 0 0 17ms
✅ TPPBaseReaderViewControllerInitialLocationTests 10 10 0 0 99ms
✅ TPPBasicAuthTests 11 11 0 0 40ms
✅ TPPBookAccessibilityLabelTests 8 8 0 0 1.02s
✅ TPPBookAuthorCoverageTests 3 3 0 0 305ms
✅ TPPBookAuthorTests 6 6 0 0 215ms
✅ TPPBookBearerTokenTests 9 8 0 1 611ms
✅ TPPBookButtonsStateTests 7 7 0 0 119ms
✅ TPPBookContentMetadataFilesHelperTests 9 9 0 0 533ms
✅ TPPBookContentTypeConverterStreamingHTMLTests 2 2 0 0 3ms
✅ TPPBookContentTypeConverterTests 4 4 0 0 1.54s
✅ TPPBookContentTypeExtendedTests 4 4 0 0 82ms
✅ TPPBookContentTypeTests 14 14 0 0 137ms
✅ TPPBookCoverRegistryTests 17 17 0 0 979ms
✅ TPPBookCreationTests 7 7 0 0 363ms
✅ TPPBookExtensionsTests 21 21 0 0 405ms
✅ TPPBookIsDRMProtectedTests 9 9 0 0 602ms
✅ TPPBookLocationCoverageTests 7 7 0 0 61ms
✅ TPPBookLocationEdgeCaseTests 27 27 0 0 464ms
✅ TPPBookLocationKeyTests 3 3 0 0 64ms
✅ TPPBookLocationTests 11 11 0 0 419ms
✅ TPPBookModelGapTests 4 4 0 0 22ms
✅ TPPBookRegistryAccountCaptureContractTests 4 4 0 0 830ms
✅ TPPBookRegistryAsyncReadinessTests 3 3 0 0 131ms
✅ TPPBookRegistryAtomicWriteTests 7 7 0 0 1.06s
✅ TPPBookRegistryBookRetrievalTests 7 7 0 0 155ms
✅ TPPBookRegistryBookmarkTests 7 7 0 0 566ms
✅ TPPBookRegistryCorruptedDataTests 5 5 0 0 53ms
✅ TPPBookRegistryDataTests 4 4 0 0 104ms
✅ TPPBookRegistryDependencyTests 4 4 0 0 41ms
✅ TPPBookRegistryFacadeContractTests 6 6 0 0 259ms
✅ TPPBookRegistryFulfillmentIdTests 4 4 0 0 45ms
✅ TPPBookRegistryLargeCorpusTests 5 5 0 0 53.15s
✅ TPPBookRegistryLoadReentrancyTests 2 2 0 0 24ms
✅ TPPBookRegistryLocationTests 4 4 0 0 158ms
✅ TPPBookRegistryMigrationTests 16 16 0 0 3.56s
✅ TPPBookRegistryMutationContractTests 10 10 0 0 1.12s
✅ TPPBookRegistryPersistenceTests 10 10 0 0 556ms
✅ TPPBookRegistryProcessingTests 2 2 0 0 35ms
✅ TPPBookRegistryPublisherTests 6 6 0 0 326ms
✅ TPPBookRegistryRebuildRefusalContractTests 1 1 0 0 23ms
✅ TPPBookRegistryRecordPersistenceTests 3 3 0 0 69ms
✅ TPPBookRegistryRecordTests 10 10 0 0 72ms
✅ TPPBookRegistryStateConcurrencyTests 2 2 0 0 108ms
✅ TPPBookRegistryStateManagementTests 11 11 0 0 545ms
✅ TPPBookRegistrySyncContractTests 4 1 0 3 266ms
✅ TPPBookRegistryThreadSafetyTests 3 3 0 0 271ms
✅ TPPBookRegistryUpdateAndRemoveTests 1 1 0 0 65ms
✅ TPPBookRequiresAdobeDRMTests 6 6 0 0 421ms
✅ TPPBookSerializationTests 13 13 0 0 223ms
✅ TPPBookStateInitializationTests 4 4 0 0 38ms
✅ TPPBookStateTests 4 4 0 0 78ms
✅ TPPBookTests 98 98 0 0 1.90s
✅ TPPBookmarkDeletionLogTests 11 11 0 0 110ms
✅ TPPBookmarkFactoryInitTests 2 2 0 0 9ms
✅ TPPBookmarkFactoryServerAnnotationEdgeCaseTests 5 5 0 0 45ms
✅ TPPBookmarkFactoryTests 15 15 0 0 836ms
✅ TPPBookmarkR3ConversionTests 5 5 0 0 62ms
✅ TPPBookmarkR3LocationTests 13 13 0 0 73ms
✅ TPPBookmarkSpecTests 1 1 0 0 4ms
✅ TPPCachingTests 3 3 0 0 53ms
✅ TPPCapturedCredentialsTests 5 5 0 0 244ms
✅ TPPCirculationAnalyticsRequestShapeContractTests 2 2 0 0 1.32s
✅ TPPConfigurationCustomRegistryTests 16 16 0 0 207ms
✅ TPPConfigurationTests 22 22 0 0 945ms
✅ TPPContentTypeTests 9 9 0 0 5.66s
✅ TPPCredentialConcurrencyTests 3 3 0 0 51ms
✅ TPPCredentialIsolationE2ETests 5 0 0 5 476ms
✅ TPPCredentialPersistenceTests 6 6 0 0 572ms
✅ TPPCredentialSnapshotCoherenceTests 3 0 0 3 116ms
✅ TPPCredentialSnapshotTests 8 8 0 0 192ms
✅ TPPCredentialsCoverageTests 9 9 0 0 53ms
✅ TPPCredentialsTests 26 26 0 0 539ms
✅ TPPCrossLibrarySignOutTests 6 6 0 0 505ms
✅ TPPDRMFailureCredentialPreservationTests 4 4 0 0 439ms
✅ TPPErrorLoggerTests 27 27 0 0 672ms
✅ TPPIdleSignOutRegressionTests 13 13 0 0 652ms
✅ TPPJWKConversionTest 1 1 0 0 60ms
✅ TPPKeychainManagerTests 5 5 0 0 415ms
✅ TPPLastReadPositionPosterTests 13 13 0 0 128ms
✅ TPPLastReadPositionSynchronizerIntegrationTests 5 5 0 0 72ms
✅ TPPLastReadPositionSynchronizerTests 23 23 0 0 2.09s
✅ TPPLastReadPositionSynchronizer_BehaviorDocumentationTests 5 5 0 0 142ms
✅ TPPLastReadPositionSynchronizer_BookLocationTests 9 9 0 0 63ms
✅ TPPLastReadPositionSynchronizer_ConcurrencyTests 3 3 0 0 151ms
✅ TPPLastReadPositionSynchronizer_ReadiumBookmarkTests 9 9 0 0 360ms
✅ TPPLastReadPositionSynchronizer_SyncLogicTests 10 10 0 0 164ms
✅ TPPLastReadPositionSynchronizer_WriterDelegationTests 4 4 0 0 181ms
✅ TPPLoginNoActivationTests 3 3 0 0 222ms
✅ TPPMainThreadCheckerTests 4 4 0 0 38ms
✅ TPPMigrationManagerTests 15 15 0 0 142ms
✅ TPPNetworkExecutorAPITests 14 14 0 0 400ms
✅ TPPNetworkExecutorConcurrencyTests 4 4 0 0 2.90s
✅ TPPNetworkExecutorStubbedTests 17 17 0 0 1.26s
✅ TPPNetworkExecutorTests 3 3 0 0 185ms
✅ TPPNetworkResponderAuthCoordinatorTests 5 5 0 0 1.10s
✅ TPPNetworkResponderSizeLimitTests 5 5 0 0 259ms
✅ TPPNetworkResponderTests 12 12 0 0 159ms
✅ TPPOPDSAcquisitionPathTests 5 5 0 0 198ms
✅ TPPOPDSEntryTests 5 5 0 0 52ms
✅ TPPOPDSFeedTests 3 3 0 0 98ms
✅ TPPOPDSGroupSwiftTests 3 3 0 0 21ms
✅ TPPOPDSLinkTests 7 7 0 0 66ms
✅ TPPOpenSearchDescriptionExpandedTests 10 10 0 0 76ms
✅ TPPOpenSearchDescriptionTests 1 1 0 0 1ms
✅ TPPPDFDocumentMetadataTests 15 15 0 0 137ms
✅ TPPPDFDocumentTests 8 8 0 0 151ms
✅ TPPPDFLocationCoverageTests 7 7 0 0 230ms
✅ TPPPDFLocationTests 10 10 0 0 130ms
✅ TPPPDFPageBookmarkTests 9 9 0 0 483ms
✅ TPPPDFPageTests 5 5 0 0 130ms
✅ TPPPDFReaderModeTests 6 6 0 0 58ms
✅ TPPPDFReaderSearchBindingTests 3 3 0 0 82ms
✅ TPPPerAccountIsolationTests 8 0 0 8 274ms
✅ TPPPreferredAuthSelectionTests 8 8 0 0 425ms
✅ TPPProblemDocumentCacheManagerTests 12 12 0 0 293ms
✅ TPPProblemDocumentTests 21 21 0 0 294ms
✅ TPPReaderAppearanceTests 4 4 0 0 335ms
✅ TPPReaderBlockNavigationTests 12 12 0 0 675ms
✅ TPPReaderBookmarksBusinessLogicTests 12 12 0 0 676ms
✅ TPPReaderBookmarksReadinessTests 2 2 0 0 244ms
✅ TPPReaderFontTests 4 4 0 0 49ms
✅ TPPReaderFootnoteAccessibilityTests 16 16 0 0 974ms
✅ TPPReaderPageListBusinessLogicTests 27 27 0 0 161ms
✅ TPPReaderPositionReportTests 10 10 0 0 155ms
✅ TPPReaderPreferencesLoadTests 3 3 0 0 687ms
✅ TPPReaderSettingsTests 28 28 0 0 2.59s
✅ TPPReaderTOCBusinessLogicTests 15 15 0 0 200ms
✅ TPPReaderTOCFlattenTests 2 2 0 0 63ms
✅ TPPReadiumBookmarkLocationMatchingTests 5 5 0 0 25ms
✅ TPPReadiumBookmarkTests 23 23 0 0 652ms
✅ TPPReauthenticatorMockTests 2 2 0 0 4ms
✅ TPPReauthenticatorTests 4 4 0 0 34ms
✅ TPPReturnPromptHelperTests 5 5 0 0 81ms
✅ TPPSAMLCookieExpirationTests 7 7 0 0 533ms
✅ TPPSAMLFlowTests 10 10 0 0 43ms
✅ TPPSAMLReauthFlowTests 2 2 0 0 462ms
✅ TPPSAMLRegressionTests 4 4 0 0 149ms
✅ TPPSAMLSignInTests 26 26 0 0 2.36s
✅ TPPSAMLStateIsolationTests 4 4 0 0 522ms
✅ TPPSAMLStateMachineTests 6 6 0 0 472ms
✅ TPPSettingsTests 6 6 0 0 255ms
✅ TPPSignInAdobeSkipTests 14 14 0 0 585ms
✅ TPPSignInAuthStateTransitionTests 3 3 0 0 523ms
✅ TPPSignInBusinessLogicExtendedTests 58 58 0 0 5.76s
✅ TPPSignInBusinessLogicOAuthTests 11 11 0 0 3.30s
✅ TPPSignInBusinessLogicSignOutTests 11 11 0 0 3.25s
✅ TPPSignInBusinessLogicStateMachineTests 10 10 0 0 521ms
✅ TPPSignInBusinessLogicTests 23 23 0 0 5.71s
✅ TPPSignInBusinessLogicTokenFlowTests 3 3 0 0 291ms
✅ TPPSignInBusinessLogicValidationCallbackOrderTests 2 2 0 0 320ms
✅ TPPSignInCapabilitiesCharacterizationTests 12 12 0 0 654ms
✅ TPPSignInErrorHandlingTests 2 2 0 0 84ms
✅ TPPSignInProfileDocEdgeCaseTests 3 3 0 0 338ms
✅ TPPSignedInStateProviderTests 3 3 0 0 57ms
✅ TPPUserAccountAuthStateTests 6 6 0 0 38ms
✅ TPPUserAccountConcurrencyTests 1 1 0 0 20ms
✅ TPPUserAccountGapTests 4 4 0 0 66ms
✅ TPPUserAccountIsolationLintTests 3 3 0 0 858ms
✅ TPPUserAccountTestFactoryTests 7 0 0 7 301ms
✅ TPPUserFriendlyErrorTests 11 11 0 0 96ms
✅ TPPUserNotificationsTests 10 10 0 0 160ms
✅ TPPXMLSwiftTests 16 16 0 0 1.75s
✅ TPPXMLTests 3 3 0 0 318ms
✅ TabBarModernizationTests 8 8 0 0 338ms
✅ TearDownRequiredLintTests 5 5 0 0 1.94s
✅ TestAppContainerFactoryTests 5 5 0 0 94ms
⚠️ TestTargetHermeticityRegressionTests 4 3 0 0 345ms
✅ TimeEntryTests 3 3 0 0 515ms
✅ TokenRefreshAndRetryQueueTests 9 9 0 0 4.75s
✅ TokenRefreshIntegrationTests 2 2 0 0 521ms
✅ TokenRefreshInterceptorAuthCoordinatorTests 8 8 0 0 200ms
✅ TokenRefreshInterceptorTests 24 24 0 0 487ms
✅ TokenRefreshOnForegroundTests 10 10 0 0 3.00s
✅ TokenRefreshTests 25 25 0 0 625ms
✅ TokenRefreshWatchdogTests 5 5 0 0 105ms
✅ TokenRequestCredentialGuardTests 13 13 0 0 715ms
✅ TokenRequestTests 11 11 0 0 3.21s
✅ TokenResponseTests 21 21 0 0 154ms
✅ TriageBotKeyAdminTests 4 4 0 0 56ms
✅ TypographyPresetTests 21 21 0 0 485ms
✅ TypographyServiceTests 31 31 0 0 1.24s
✅ TypographySettingsViewModelTests 27 27 0 0 1.05s
✅ UIAlertCACommitGuardTests 9 9 0 0 887ms
✅ UIColor_NYPLAdditionsTests 1 1 0 0 2ms
✅ URLBackupExclusionTests 3 3 0 0 189ms
✅ URLExtensionTests 16 16 0 0 79ms
✅ URLExtensionsTests 11 11 0 0 776ms
✅ URLRequestExtensionsCoverageTests 3 3 0 0 65ms
✅ URLRequestExtensionsTests 11 11 0 0 360ms
✅ URLRequestNYPLAdditionsTests 11 11 0 0 81ms
✅ URLRequest_NYPLTests 1 1 0 0 2ms
✅ URLResponseAuthenticationTests 10 10 0 0 4.48s
✅ URLResponseNYPLTests 14 14 0 0 1.42s
✅ URLSessionCredentialStorageTests 3 3 0 0 9ms
✅ URLSessionStubbingResetTests 2 2 0 0 12ms
✅ URLTypeTests 2 2 0 0 15ms
✅ URLValidationTests 5 5 0 0 51ms
✅ UnifiedOPDSServiceStateMachineTests 2 2 0 0 189ms
✅ UserAccountPublisherAuthStateTests 5 5 0 0 81ms
✅ UserAccountPublisherTests 14 14 0 0 296ms
✅ UserAccountValidationTests 11 11 0 0 867ms
✅ UserDefaultsIsolationLintTests 2 2 0 0 893ms
✅ UserProfileDocumentTests 7 7 0 0 48ms
✅ UserRetryTrackerTests 10 10 0 0 283ms
✅ XCTestCase_testUserDefaultsTests 3 3 0 0 129ms
✅ iPadOnMacRMSDKGuardTests 7 7 0 0 18ms

📊 Full interactive matrix: report

Failed tests
BookReturnServiceTests.First Run
AudiobookFirstOpenHangTests.Retry 1
PalacePreferencesSettingsRoundTripTests.Retry 2

Names only — open the interactive report above for messages + stack frames.

📊 Testing Coverage Breakdown

Unit Test Line Coverage (testable surfaces): 45.1%

Total coverage incl. UI/lifecycle: 44.1% (17 files excluded from testable denominator — see scripts/coverage-exclude.json)

Target Lines Covered
Palace.app 44.1%

Why two coverage numbers? Testable coverage subtracts files that can't be exercised from xcodebuild — SwiftUI views, UIKit VCs, lifecycle (see scripts/coverage-exclude.json) — so raising it means more testable logic is tested, not that we shipped less UI. Total coverage is kept for continuity. The excluded paths are covered by simdrive E2E journeys (see chaos-replay-on-pr.yml).

📈 What changed vs. base

Test count: +8

⚠️ New failures — passing on base, failing on this branch
AudiobookFirstOpenHangTests.Retry 1
BookReturnServiceTests.First Run
PalacePreferencesSettingsRoundTripTests.Retry 2

🔗 Interactive HTML Report | CI Run Details

Counts above were produced by this CI run's xcresult parse — reproduce via the run link.

📦 Downloadable Artifacts
Artifact Description
test-report 📄 Markdown + HTML reports
test-data 📊 JSON data for tooling
test-results 🔍 Full xcresult (open in Xcode)

Final editing pass before review. No facts, recommendations, numbers, or
citations changed.

Roles replace people throughout. The cover memo's accountable owner is now
the iOS dev rather than a named individual, and every "maintainer" is now
the Android dev or a phrase about the work itself. Where a sentence needed
a role word to carry meaning, it was rephrased around the work: "the
maintainer's to assess" became "this sits with the Android dev". Factual
properties of a codebase kept the fact and dropped the title, so
"single-maintainer repo" reads "single-contributor repo" and states the
commit distribution instead. Documents that circulate should describe
roles and work, not individuals.

Voice moves from argued to documented. Removed rhetorical closers, moral
framing about discipline, bold used for emphasis rather than scanning,
empty intensifiers, and phrasing that praised the analysis. Reasons are
stated once, factually, instead of built toward.

Kept deliberately: the UNVERIFIED markers, the retractions, the "both
numbers are proposals, not findings" note, and the steelmanned counter to
the engine recommendation. Those read as hedging only if you mistake
accuracy for timidity; three reviewers named them the documents' most
useful property.

One real gap closed in the recommendation path: the cover memo asked
approval for the first two delivery phases without mentioning that the iOS
launch gate precedes them, so a reader tracing "what happens first" hit a
contradiction between the memo and the plan. Fixed with a pointer rather
than more text.

**Scope:** voice, role language, and one cross-reference. Both documents
got shorter.

**Not done:** the style is now recorded outside this repo so it applies by
default to future documentation; nothing in this commit enforces it here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… toggle, telemetry decision (#1359)

* fix(triage-bot): honor field omissions on the clipboard send path (PP-4883)

The patron reviews the support ticket field-by-field and can switch pieces
off (barcode, library, network, logs). Only the email path stripped those
fields; the clipboard/copy path (the shipping default, submission flag off)
JSON-encoded the raw draft, so anything the patron switched off was still
in what got copied — the payload even listed the fields it was supposed to
have removed (as-built gap 12). Content-level redaction still ran on both
paths, so no secret leaked; the narrow failure was that the patron said
"not this" and we copied it anyway.

Centralize ticket serialization in Core (TicketWirePayload), which always
encodes sanitizedForSubmission(). Route both the clipboard gateway and the
email diagnostics attachment through it, so the two paths produce
byte-identical bytes and cannot drift apart. Document the serialization
contract on the TicketGateway protocol so a future send path can't
reintroduce the gap.

Tests: TicketWirePayloadTests (Core, runs in the fast swift-test gate that
already guards email) pins that omitted fields are absent, non-omitted
fields survive, and the copy payload is byte-identical to the email
attachment. ClipboardTicketGatewayTests pins the gateway itself via an
injected write sink (no global UIPasteboard). Full Core suite: 289 passed.

**Scope:** clipboard/email serialization parity only. No change to what the
redactor strips or to the email path's behavior (byte-identical output).
**Not done:** full Palace test suite (runs on PR CI); SoD critical-path
review markers (privacy/redaction path).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(triage-bot): patron-facing diagnostics toggle + privacy review record (PP-4884)

The bot had a working "don't send diagnostics" preference
(DiagnosticsGatingContextProvider) with tests, but setIncludeDiagnostics had
zero callers — no screen, no row, no toggle — so every patron was on the
default (ON). The choice was written and never given to anyone (as-built
gap 5).

Add an "Include diagnostics" toggle to the Support settings section, shown
only when the bot is active. It binds via @AppStorage to the exact key the
gating context provider reads, now exposed as
UserDefaultsDiagnosticsPreference.defaultsKey, so flipping the switch changes
what the bot collects with no other wiring and no key drift. A caption
explains the trade honestly: off means support has only app + device version
to work with.

Also records the privacy review as a durable decision document
(docs/architecture/triage-bot-privacy-review.md): what the bot collects, what
leaves the device and when, on-device retention, the consent model, and open
items for the reviewing roles (identifier hash strength, default-on posture,
support-side retention). The engineering facts are cited to code; the answer
itself is a product/legal call recorded in the doc's Decision block.

Test: DiagnosticsPreferenceTests pins that a toggle write under defaultsKey is
read back by the default-key preference the factory builds (guards the
toggle and provider against drifting apart). Full Core suite: 289 passed;
app builds on iPhone 17 Pro sim.

**Scope:** engineering wiring for the toggle + the recorded review doc.
**Not done / needs product-legal (story Done-when, not code):** the toggle
COPY needs product sign-off (marked in-code); the privacy review needs a
recorded answer in the Decision block before the bot is enabled for patrons.
**Deferred:** none.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(triage-bot): telemetry destination decision + measurement yardstick (PP-4885)

The bot reports what happens as patrons use it — conversations started,
answers offered, guided-step outcomes, escalations — through a fixed 12-key
allow-list carrying no patron text. In release builds the events reach
Firebase, and nothing on the other end reads them (as-built gap 6). So no one
can say whether the bot helps, and the whole shared-architecture plan assumes
we learn from iOS in the field first.

Record the decision and the yardstick (resolves open decision 4 of the
shared-architecture proposal):
  - Recommend Firebase for the pilot (the data already flows there, zero new
    infrastructure) with the Circulation Manager ingestion endpoint as the
    follow-on once the feature earns the larger investment.
  - Define the three questions as concrete metrics over the real event
    vocabulary: auto-resolution rate, per-category miss rate, guided-flow
    abandonment by step. Names the honest limit — missed-input phrasings are
    deliberately not in telemetry, so category miss rate points where to look
    and the escalated support tickets supply the actual phrasings.
  - Propose starting thresholds to ratify so the rollout has a number, not a
    vibe.

Docs only. Producing an actual number needs no app change (events already
reach Firebase); it needs the destination decision and the queries, owned by
whoever holds that console.

**Scope:** the written decision + metric definitions + proposed thresholds.
**Not done / needs product-infra (story Done-when, not code):** ratify the
destination and thresholds in the doc's Decision block; assign a query owner.
No in-app view is built — it would front-run the destination decision and
would not measure field usage, which is what the rollout needs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(triage-bot): guard the omit-guarantee in the reducer, in the fast CI gate (PP-4883)

Addresses the qa_test SoD block. The original fix routed the clipboard gateway
through the sanitizing serializer, but the gateway-level test that pinned it
(ClipboardTicketGatewayTests) runs in NEITHER CI job: macOS `swift test`
compiles it away under `#if canImport(UIKit)`, and the Palace xcodebuild scheme
runs only PalaceTests/TenPrintCoverTests, not the package's IOS test target. So
the exact gap-12 mutation — a gateway reverting to encode the raw draft — would
ship the leak again with CI green.

Move the guarantee to the pure-Core reducer: the draft handed to the
`.submitTicket` effect is now `sanitizedForSubmission()`, at both the confirm
and retry sites, so the wire draft is omit-stripped before ANY gateway sees it,
independent of which gateway runs. `.submitting(ticket:)` keeps the original
draft so the failure/retry/persist path still shows what the patron reviewed.
sanitize is idempotent, so the gateway/composition serialization sanitize
becomes harmless defense-in-depth.

SubmitEffectSanitizationTests drives the reducer and asserts the emitted
effect's draft is wire-ready (confirm path, retry path, and nothing-omitted
control). It runs in the fast `swift test` gate; reverting the reducer sanitize
fails it with 5 assertion failures (verified by mutation).

Also applies the architect's non-blocking note: the email JSON attachment now
passes the raw draft to TicketWirePayload.jsonData (sole sanitize owner) instead
of a pre-sanitized draft, removing the double-sanitize idempotency reliance.
Byte-identical output preserved (TicketWirePayloadTests pins it). Core suite:
292 passed.

**Scope:** reducer submit-effect sanitize + its Core test + email single-owner
cleanup. No behavior change to the failure/retry/persist UX (state draft
unchanged).
**Not done:** wiring the package IOS/UI test targets into CI is a separate,
board-stability-sensitive change (deferred; the reducer guard covers the
privacy regression in the meantime).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: t <t@t.io>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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