| 1 | # Model connection regression fixes |
| 2 | |
| 3 | ## Follow-up approval review |
| 4 | |
| 5 | The follow-up fixes bind installation approval to imported environment and header |
| 6 | values with a durable keyed digest, while keeping those values out of the public |
| 7 | preview. Existing plan IDs require a new preview after upgrading. Plugin CLI JSON |
| 8 | again includes actions, risk, plan ID, failures and recovery instructions. |
| 9 | |
| 10 | Desktop tab metadata now exposes a runtime-bound pending-settings hint. This lets |
| 11 | a preserved draft reach backend apply-before-admission after a credential save; |
| 12 | it does not mark the old controller authenticated. CLI submission checks saved |
| 13 | settings asynchronously before authentication, rebuilds through its existing |
| 14 | controller replacement path and submits only to the activated controller. |
| 15 | Failed builds preserve the original controller and draft; stale completions do |
| 16 | not start another session. |
| 17 | |
| 18 | Authentication also guards actual primary, child and auxiliary requests through |
| 19 | the request context, preserving concrete provider capability interfaces and wire |
| 20 | requests. Missing credentials cover sibling models; HTTP and streamed rejection |
| 21 | errors carry the actual request model, so a child's 403 cannot block its parent. |
| 22 | Project credential edits and shell setup use document deltas, preserving unknown |
| 23 | and nested fields without promoting project providers into global configuration. |
| 24 | Windows repair preserves both repair and rollback error chains. |
| 25 | |
| 26 | Regression coverage: `TestImportedExecutionInputsInvalidateApproval`, |
| 27 | `TestPluginDryRunPreservesApprovalPlan`, |
| 28 | `TestSavedCredentialAllowsAdmissionThroughPendingMetadata`, |
| 29 | `TestTurnAppliesExternalCredentialSaveBeforeAuthentication`, |
| 30 | `TestTurnSettingsCompletionCannotStartAnotherSession`, |
| 31 | `TestMissingCredentialBlocksSiblingModel`, |
| 32 | `TestSubagentRejectionMustNotBlockPrimary`, |
| 33 | `TestRequestGateObservesHTTPAndStreamRejectionsWithoutChangingRequest`, |
| 34 | `TestProjectCredentialEditPreservesUnknownProviderFields`, |
| 35 | `TestProjectShellSetupPreservesUnknownFields`, and composer workspace/auth tests. |
| 36 | |
| 37 | Compatibility: `modelSettingsPending` is optional and defaults to false. Existing |
| 38 | TOML and credential files remain readable. Legacy unkeyed credential receipts |
| 39 | return `unknown_result` rather than replaying a write whose content cannot be |
| 40 | verified; new receipts use the existing durable HMAC protocol. |
| 41 | |
| 42 | The following findings were reproduced with disposable Reasonix homes and |
| 43 | local fixtures. No production credentials or model requests are used. |
| 44 | |
| 45 | | Finding | Repair | Regression evidence | |
| 46 | | --- | --- | --- | |
| 47 | | F1: credential paste reaches chat | Terminal and native clipboard delivery are intercepted by the credential editor | `TestAuditSetupPasteDoesNotEnterChat` | |
| 48 | | F2: repair overwrites concurrent credentials | Verification opens without creating, truncating, or rewriting the file | `TestAuditRepairVerificationPreservesConcurrentSave`, `TestRepairPreservesCredentialContentsAndFileIdentity` | |
| 49 | | F3: key-only shell edit is skipped | Credential edits participate in the operation/precondition stream and trigger publication | `TestAuditShellSetupKeyOnlyEditPersists`, `TestShellCredentialOnlyEditRejectsConcurrentRotation` | |
| 50 | | F4: separate edits share the last key | Credential drafts are keyed by connection identity | `TestAuditShellSetupDistinctConnectionKeysStaySeparate` | |
| 51 | | F5: repair follows linked home | Validate home/target components and identity; mutate/roll back the opened file handle | `TestAuditRepairRefusesLinkedHome` | |
| 52 | | F6: TUI edits shadowed project provider | Choose the source selected by the config merger | `TestAuditSetupEditsEffectiveProviderSource`, `TestProviderEditPathRespectsProjectOverrideOfBuiltins` | |
| 53 | | F7: recovery invents commit evidence | Journal the exact candidate revision before strict atomic publication; require matching revision and references | `TestAuditRecoverDoesNotInventReceiptAfterExternalEdit`, persistence-boundary tests | |
| 54 | | F8: receipt replay conflicts after restart | Use a private durable HMAC key; recheck receipts under writer locks | `TestAuditDurableReceiptAcrossProcessRestart` (actual child process) | |
| 55 | | F9: preferences cannot recover receipts | Empty slot sets are valid; receipt queries recover proven publications | `TestAuditRecoverCommittedPreferenceReceipt`, `TestReceiptQueryRecoversPublishedPreferenceBeforeMark` | |
| 56 | | F10: cleanup loses failure evidence | Retain journals on failed deletion or changed configuration | `TestAuditCleanupRetainsEvidenceOnFailedRemoval` | |
| 57 | | F11: auxiliary authentication keeps requesting | Record title and sibling auxiliary errors; isolate 403 by model and 401 by connection | `TestAuditTitleAuthenticationRejectionStopsFurtherRequests`, `TestAuxiliaryAuthenticationFailureIsScopedToConnectionAndModel` | |
| 58 | | F12: frontend retry bypasses readiness | Remove local send authorization; refresh authoritative backend tab metadata after serialized retry | `composer-authentication-recovery.test.tsx`, `TestRetryAuthenticationPublishesAuthoritativeTabRefresh` | |
| 59 | |
| 60 | Browser fixture: `desktop/frontend/bench/authentication-recovery.html`. It uses |
| 61 | the real Composer with a disposable host. Verified delayed retry, tab switching, |
| 62 | controller unavailability, replacement connection, draft preservation, and |
| 63 | backend Ready enabling send. Model submission count stays zero throughout. |
| 64 | |
| 65 | Compatibility: TOML, `.env`, and RPC field names remain unchanged. Transaction |
| 66 | records retain schema 1 and add the `config_prepared` phase using existing |
| 67 | revision fields. Older records without a publication revision remain uncertain |
| 68 | when references exist; they are not converted into success. Legacy Desktop |
| 69 | digests return `unknown_result` when replay content cannot be verified. Old |
| 70 | applications still read the saved connection configuration and credentials. |
| 71 | |
| 72 | Windows handle-based repair is cross-compiled locally. Native ACL, sharing and |
| 73 | reparse-point behavior requires Windows CI; cross-compilation is not that evidence. |
| 74 | |
| 75 | Local validation (2026-09-17): root and independent Desktop module `go test ./...`, focused shared-core and |
| 76 | Desktop race tests, shared-package `go vet`, frontend production build and test |
| 77 | typecheck, Composer and app-lifecycle suites, and the browser scenario above |
| 78 | passed. The actual Electron smoke passed the service handshake, renderer RPC, |
| 79 | native window query, website view, child-service ownership, and clean exit. |
| 80 | The smoke service used its standard binary name because the process assertion |
| 81 | matches `reasonix-desktop` in the executable name. |
| 82 |