docs: record PR 892 code and issue audit

This commit is contained in:
Hydra
2026-09-16 12:31:16 +03:00
parent 8c4626e8ef
commit 5d08e10c80
2 changed files with 229 additions and 4 deletions
+21 -4
View File
@@ -219,12 +219,16 @@ Closed the reproduced connection bugs with the #892 fix and pending-main status.
Closure: https://github.com/oblien/openship/issues/668#issuecomment-5694012488
Commits: [`30c564b0`](https://github.com/oblien/openship/commit/30c564b0ed741246e3e75195de9e0f97ddc556a4).
The final PR audit repairs build-log retry scheduling after EOF/errors and isolates replacement attempts. HTTP 401/403 stops retries; replay resumes after the highest received event ID and filters duplicates before terminal writes.
Commits: [`30c564b0`](https://github.com/oblien/openship/commit/30c564b0ed741246e3e75195de9e0f97ddc556a4), [`a57cc76b`](https://github.com/oblien/openship/commit/a57cc76b62cae1c784235476cd8ed4f53863e64f).
Verification: 17 React lifecycle and real ReadableStream cases pass; 12 reproduced failures on main. Dashboard TypeScript passes.
Verification: Closure recheck: all 17 terminal/log lifecycle cases pass again at 0285ccb2.
Verification: EOF/error and replay regressions fail before their fixes. All 104 stream/PTY/processor cases pass, including permission failures, terminal completion and stale attempt cleanup.
### #661: fixed-in-branch
Confirmed duplicate release/changelog/advisory requests between native startup and dashboard consumers, plus overlapping web refreshes. The desktop process now shares and caches one typed snapshot; the renderer uses its IPC result and concurrent manual checks join the active request. Shared core installer types replace duplicate local definitions. Successful checks clear obsolete offers; offline failures do not invalidate a staged installer.
@@ -381,10 +385,14 @@ Verification: Closure recheck: all four client-to-tRPC-to-IMAP deletion cases pa
Confirmed orphan sessions when a browser disconnects during shell/audit setup. Adapted and merged contributor PR #579, preserving original authorship and GitHub merge credit. Also made unaudited IDs collision-free and closed service-runtime leases on rejected or failed handshakes. Established sessions still park for reconnect.
Commits: [`380d2526`](https://github.com/oblien/openship/commit/380d25260649cf8eb590854d7833c5ca3dea037e).
The final PR code audit also binds resumed sessions to the server/service authorized by the current handshake. A token from another target is rejected without consuming or closing its parked shell.
Commits: [`380d2526`](https://github.com/oblien/openship/commit/380d25260649cf8eb590854d7833c5ca3dea037e), [`dacf2b0e`](https://github.com/oblien/openship/commit/dacf2b0efef713076d0404f42cd55d379ae945b6).
Verification: 15 behavioral regressions plus six existing registry cases pass; 11 of the new cases fail against main. API TypeScript passes.
Verification: Both cross-target resume cases fail on the reviewed PR head. Same-target resumes and all 116 focused terminal/restore cases pass after hardening.
### #424: already-fixed-main
Configuration question: explicit service/Compose host-interface port mappings already support LAN IP:port access. Answered with the current Networking Ports setting and 0.0.0.0:8080:5173 example; the managed classic-app loopback default stays intentional.
@@ -535,7 +543,9 @@ Contributor PR #469 is integrated with its original commit and GitHub merge cred
Producer preflight refusals now remain non-destructive in restore reporting. The orchestrator records possible writes only when it hands the artifact stream to the producer, with a cancellation check before that boundary. AOF/credential refusal no longer claims partial data loss; earlier partial writes still retain their warning.
Commits: [`f1dc8a74`](https://github.com/oblien/openship/commit/f1dc8a740210c542215de0e287740abef259db5f), [`38cc1a03`](https://github.com/oblien/openship/commit/38cc1a0395ac3f2c4b34b005cf0d5d450d66d6a6), [`9ede7762`](https://github.com/oblien/openship/commit/9ede77620bc7eb500ee1568aa7f3d46d61932703), [`3822b062`](https://github.com/oblien/openship/commit/3822b0620f5cb4f1c57e462b5a441023d1df6846), [`e4587335`](https://github.com/oblien/openship/commit/e4587335306102f65db4db55a339b45500c32b9c).
The final PR audit preserves Redis/Valkey snapshot settings when artifact opening or CONFIG SET acknowledgement fails before any write. Restore downloads now propagate source errors and close on early target refusal; possible partial writes still require recovery before restarting.
Commits: [`f1dc8a74`](https://github.com/oblien/openship/commit/f1dc8a740210c542215de0e287740abef259db5f), [`38cc1a03`](https://github.com/oblien/openship/commit/38cc1a0395ac3f2c4b34b005cf0d5d450d66d6a6), [`9ede7762`](https://github.com/oblien/openship/commit/9ede77620bc7eb500ee1568aa7f3d46d61932703), [`3822b062`](https://github.com/oblien/openship/commit/3822b0620f5cb4f1c57e462b5a441023d1df6846), [`e4587335`](https://github.com/oblien/openship/commit/e4587335306102f65db4db55a339b45500c32b9c), [`8c4626e8`](https://github.com/oblien/openship/commit/8c4626e8ef367de329c95c9c4501d1761284b45f).
Verification: PR #468: 1,059 core cases and 224 API stack/language cases pass; nine new cases fail against main.
@@ -547,6 +557,8 @@ Verification: All 255 backup/restore tests pass. Two unsafe-RDB preflight report
Verification: The host-command ownership guard now recognizes the generated Ruby Dockerfile as image installation, separately from host provisioning. Its allowance is restricted to the Debian/Alpine install verbs; the full adapter suite passes 3,788 tests.
Verification: Failed open/acknowledgement/transport regressions fail before the persistence repair. Broken downloads previously timed out with an unhandled error; source failure and early input refusal now finish cleanly. All 33 Redis and 116 focused API terminal/restore cases pass.
### #220: fixed-in-branch
Current main blocks style elements but still leaks through escaped CSS URL names/schemes, image-set strings and CSS-variable substitution; reproduced four bypasses in Chromium.
@@ -617,10 +629,14 @@ Revalidated the historical SECURITY.md findings against main. SEC-01 already enf
The security-help umbrella remains open. The September 5 report is retained with current remediation status; the bounded checks are not an exhaustive security certification. Contributor security PRs #152 and #193 are already merged; #224 is already closed.
Commits: [`3c35e5ba`](https://github.com/oblien/openship/commit/3c35e5bad490c6e631eef167d03c8f936e758aff).
Terminal resume now binds the parked session to the target authorized by the fresh handshake, in addition to the existing user, project and organization checks.
Commits: [`3c35e5ba`](https://github.com/oblien/openship/commit/3c35e5bad490c6e631eef167d03c8f936e758aff), [`dacf2b0e`](https://github.com/oblien/openship/commit/dacf2b0efef713076d0404f42cd55d379ae945b6).
Verification: 18 API boundary regressions and three database import regressions fail against main and pass on the integration branch. The full API suite passes 6,221 tests across 523 files; the full database suite passes 327 tests across 40 files. API TypeScript passes. Valid owner/native/desktop paths, historical deployment logs, and rollback/Compose lifecycle cases remain covered.
Verification: Both terminal target-substitution regressions fail before this hardening; valid same-target resumes remain covered.
### #123: fixed-in-branch
Main already applies per-user/per-route limits after authentication and one central policy to raw Better Auth routes. The missing follow-up was a coarse limit before session lookup.
@@ -661,5 +677,6 @@ Verification: Six regressions fail on current main.
- CI matrix selection is verified with actual Turbo dry runs; the compound-script argument forwarding regression is corrected, and every workspace test plus script tests remains included.
- Closure recheck: 108 reports are classified, including the new feature follow-up #894. All 39 resolved reports are closed with evidence (23 fixed here, 16 already fixed in main). The 69 remaining reports have explicit partial, reproduction-dependent or feature status.
- Closure recheck at 0285ccb2: 354 targeted GitHub, monorepo, log/terminal, Compose, service-state, app-routing and mail regression cases pass across 20 files. Application code is unchanged by the tracking update.
- Final PR audit: all 112 pre-review commits and 257 changed files traced against main, including manual merge resolutions and superseded architecture paths. Five additional defects repaired in three code commits; 253 focused tests and 12 typecheck/dependency-build tasks pass. See the [PR review](pr-892-review.md) for the commit index and issue-by-issue result.
Feature requests remain outside this bug batch. Reproduction gaps stay open with a diagnostic request. Issues fixed on this branch are closed with a comment identifying #892 and the pending merge to main; partial and ongoing umbrella reports stay open.
+208
View File
@@ -0,0 +1,208 @@
# PR #892 code and issue review
Baseline: `4e66349c27b48df13697c1b6d4a95f7a6cf4a3d6` (`main`, re-fetched during this review). Initial PR head: `9c6d75f86e314cf5c7f4a6b2522be15defe9e5d5`. Reviewed code head after hardening: `8c4626e8ef367de329c95c9c4501d1761284b45f`.
The review traced all 112 existing PR commits (70 ordinary commits and 42 merges) through the final diff and merge adaptations, covering 257 changed files. Twenty merges contain manual resolutions; the other 22 add no manual resolution. Older controller implementations and unused helpers were checked against the retained platform/SDK paths. The index below records the disposition of each commit.
The five concrete findings below are fixed in three additional code commits. No unresolved merge blocker was found in the reviewed bug-fix scope. This is a recommendation for this integration branch; the open runtime-role, licensing and broader security/testing discussions retain their separate scope.
## Findings fixed in this review
| Finding | Failure and correction | Commit |
| --- | --- | --- |
| R1: Terminal resume token could select a different target from the authorized handshake | Resume now requires the parked session's server/service to match the freshly authorized target. Both cross-target regressions failed before the fix; valid same-target resumes pass. | [`dacf2b0e`](https://github.com/oblien/openship/commit/dacf2b0efef713076d0404f42cd55d379ae945b6) |
| R2: Build-log reconnection was suppressed by its own connecting guard | Unexpected EOF and read error produced no retry. Retries now run after attempt completion; replaced attempts cannot change current state. | [`a57cc76b`](https://github.com/oblien/openship/commit/a57cc76b62cae1c784235476cd8ed4f53863e64f) |
| R3: Build reconnection retained the initial history cursor and could repeat terminal output | Replay test requested since=12 after receiving event 13. The hook now resumes from 13 and filters duplicate IDs before any terminal write. | [`a57cc76b`](https://github.com/oblien/openship/commit/a57cc76b62cae1c784235476cd8ed4f53863e64f) |
| R4: Redis/Valkey restore preparation could leave automatic snapshots disabled | Failed artifact open, missing CONFIG SET acknowledgement and transport loss left save empty. Previous settings now return before any write; rollback failure is explicit. | [`8c4626e8`](https://github.com/oblien/openship/commit/8c4626e8ef367de329c95c9c4501d1761284b45f) |
| R5: A failed backup download could raise an unhandled error and leave apply stuck | A broken source timed out with an uncaught exception; early target refusal left the download open. Both now finish as failed with cleanup and appropriate partial-write state. | [`8c4626e8`](https://github.com/oblien/openship/commit/8c4626e8ef367de329c95c9c4501d1761284b45f) |
The regressions were run before their respective fixes and failed. These were defects found in paths touched by the batch; they are not all regressions introduced by this PR.
## Architecture and consistency
- API controllers retain the shared platform operations and SDK contracts. Superseded deployment/deletion implementations and redundant test-runner setup are not carried into the final tree.
- Active deployment ownership has one core predicate and shared engine loaders; project import/restore validation uses the same project/organization rule.
- Compose uses the existing reconciler and environment layers. Source refresh, explicit edits/removals, ambiguous legacy provenance, explicit advanced resets and frozen rollback snapshots were checked together.
- Static-container routing uses the existing upstream and service-owned port resolution. Ruby/PHP stages reuse the shared build planner and workspace; Valkey reuses the Redis/RDB producer.
- Mail deletion reuses IMAP operations, remote-content blocking has one parsed policy, and TLS changes remain specific to the intended transport. Release consumers share the changelog parser and desktop release snapshot.
- Stream ownership, retries and cleanup preserve the current target. Failed restore downloads unwind before reporting completion, and possible partial writes retain their warning.
## Issue-by-issue outcome
These 23 reports are fixed in the integration branch and closed with comments stating that the merge into main is pending. The [full ledger](bugfix-batch-2026-09-16.md) records their original reproductions, verification and commit links, plus the 16 reports already fixed in main and the remaining open reports.
| Issue | Reviewed outcome |
| --- | --- |
| [#893](https://github.com/oblien/openship/issues/893) | Live Compose expressions recover from known provenance; ambiguous legacy values require drift review; source failures stop before queuing. Explicit edits and frozen rollback values retain precedence. |
| [#879](https://github.com/oblien/openship/issues/879) | Remaining static-container root route resolves its recorded primary service/port. Self-app claim convergence and skipped-route diagnostics are already in main. |
| [#668](https://github.com/oblien/openship/issues/668) | Log/PTY readers belong to the current target and stalled handshakes time out visibly. This audit also repairs build retry scheduling and replay cursors. |
| [#661](https://github.com/oblien/openship/issues/661) | One desktop release snapshot and coalesced web requests prevent duplicate provider reads; failed refresh remains retryable. |
| [#660](https://github.com/oblien/openship/issues/660) | Existing background operations show logs inline through the shared stream/consent UI. Reconnect attaches with GET without resubmitting work. |
| [#638](https://github.com/oblien/openship/issues/638) | Draft deletion requires confirmation and preserves normal cleanup, keyboard dismissal/focus and pending-request protection. |
| [#608](https://github.com/oblien/openship/issues/608) | Shared host probes support macOS/Linux and valid units; failed probes do not invent zero measurements. |
| [#556](https://github.com/oblien/openship/issues/556) | The host edge brands its own 502/504 responses and preserves status, app error bodies and old-route upgrade behavior. Unreachable Cloud-edge hosts remain outside this repository. |
| [#506](https://github.com/oblien/openship/issues/506) | Main already resolves absent loopback bindings through the live upstream. Overview now avoids presenting a stale project port for service-based deployments. |
| [#504](https://github.com/oblien/openship/issues/504) | Non-catalog server projects can use the existing Connection card; backend outputs govern visibility and project reads wait for an ID. |
| [#501](https://github.com/oblien/openship/issues/501) | The PHP Node asset stage inherits installed Composer/generated files, including custom dependency paths and monorepo roots. |
| [#488](https://github.com/oblien/openship/issues/488) | Existing parsed-secret preservation is retained; unknown database state cannot authorize regenerated credentials or configuration writes. |
| [#487](https://github.com/oblien/openship/issues/487) | Preview, prefetch and final writer share the database-layout result; unavailable/foreign layouts refuse instead of guessing. |
| [#429](https://github.com/oblien/openship/issues/429) | Context, keyboard and optimistic deletion all invoke the existing IMAP deletion path with source-folder identity. Automatic refresh is tracked separately in #894. |
| [#426](https://github.com/oblien/openship/issues/426) | Abandoned handshakes release slots, shells and runtime leases. Resume now also requires the authorized server/service to match the parked session. |
| [#408](https://github.com/oblien/openship/issues/408) | Permission-denied Docker rechecks refresh stale SSH login groups once; active commands/retained terminals survive the pool replacement. |
| [#396](https://github.com/oblien/openship/issues/396) | Traffic failures are visible and retryable; domain/project scope and cache revisions prevent discarded requests and stale results. |
| [#392](https://github.com/oblien/openship/issues/392) | Amavis transport receives its own TLS level/wrapper settings, including persisted installs; external relay STARTTLS remains mandatory. |
| [#278](https://github.com/oblien/openship/issues/278) | CLI rename sends only a display name through the existing SDK update operation; slug, volumes and route identity are preserved. |
| [#220](https://github.com/oblien/openship/issues/220) | Parsed HTML/CSS closes remote-resource bypasses while images are blocked; existing XSS protections and allowed embedded content remain. |
| [#195](https://github.com/oblien/openship/issues/195) | One environment guard rejects preview variable sets on production targets before mutations; a real preview project still activates its own deployment. |
| [#192](https://github.com/oblien/openship/issues/192) | Release descriptions use the shared changelog parser with bounded fallback and safe backfill; manual release notes survive reruns. |
| [#123](https://github.com/oblien/openship/issues/123) | Main already fixes per-route policy ordering; the remaining standalone pre-authentication gap gains a separate trusted-edge-aware ceiling. |
Open scope remains explicit: #231 covers multi-process roles/release phases beyond the included Rails/PHP/Valkey repairs; #610 still needs upstream provenance/notices; #148 and #216 are ongoing security/testing umbrellas. #876 has no verified cause for its fresh-install queue failure. #894 preserves the separate automatic-inbox-refresh request. The additional download cleanup strengthens the existing restore path originally covered by #434; its missing-container fix was already in main.
## Verification
- This hardening pass: 116 API tests across 12 terminal/restore suites, 104 dashboard tests across three stream/PTY suites, and 33 Redis producer tests pass. They include cancellation, integrity, valid resumes, denied requests, target replacement, replay filtering, partial writes and failed persistence rollback.
- API, dashboard, platform and adapter typechecks plus dependency builds pass: 12 Turbo tasks. The baseline integration already passed the complete workspace suites, production API/dashboard builds, packaged SDK/CLI checks on Node 22, documentation validation, and the real Docker/SSH/browser/mail probes recorded in the full ledger.
- Main remains at the baseline above; all 18 contributor PR merge commits remain ancestors of this branch. No public operation contract, dependency, migration or new runtime-role model was added by the three hardening commits.
Focused commands used for the hardening pass (from the indicated workspace):
```sh
# apps/api
node ../../node_modules/vitest/vitest.mjs run test/modules/backups/restore- test/modules/terminal/ test/modules/service-terminal/
# apps/dashboard
node ../../node_modules/vitest/vitest.mjs run src/hooks/useLogStream.test.tsx src/hooks/usePtyConnection.test.tsx src/lib/sseMessageProcessors.test.ts
# packages/adapters
node ../../node_modules/vitest/vitest.mjs run src/backup/producers/redis-bgsave.test.ts
# repository root
node node_modules/turbo/bin/turbo run lint --filter=@repo/api --filter=@repo/dashboard --filter=@repo/adapters --filter=@repo/platform --concurrency=2
```
## Existing commit index
This index follows the original 112-commit review range. Merge rows describe conflict/adaptation decisions; their contributor changes are assessed in the final integrated behavior, rather than treated as independent duplicate fixes.
| Commit | Change | Review disposition |
| --- | --- | --- |
| [`7755d03c`](https://github.com/oblien/openship/commit/7755d03c8d613b5d18014e7547e3427dc0c58836) | fix(api): retry errored certificates in SSL renewal selection | Renewal retry retained in the shared domain service and repository through d61cf25e; first issuance and external TLS stay excluded. |
| [`8489a584`](https://github.com/oblien/openship/commit/8489a5849500626367f08d9daa44f156aa8287d8) | fix(api): return deployment_id/project_id from the deploy trigger | Superseded by main's shared deployments.create response contract, including masking and deployment/project IDs; legacy controller copy removed. |
| [`0878f773`](https://github.com/oblien/openship/commit/0878f7736cd1ea2cac9ebd616cf3dbcd9ef27e49) | fix(api): block server deletion while it hosts active deployments | Superseded by main's workload-aware server decommission operation; the legacy counter/force-delete path is not restored. |
| [`078eca8a`](https://github.com/oblien/openship/commit/078eca8a9d6af6e86bd4774c0b7cb9b234b9c090) | fix(cli): confirm server rm and fail install on component error | Current SDK server removal and command-exit handling retained; duplicate legacy confirmation/force and install-error implementations removed. |
| [`f5a4ec14`](https://github.com/oblien/openship/commit/f5a4ec1457e2a9c12bd4e4d4d7efb0ffc0360fb2) | fix(cli): preserve context endpoints on re-login | Endpoint preservation retained through the SDK-based login adaptation; invalid credentials do not replace saved context. |
| [`52c3fa74`](https://github.com/oblien/openship/commit/52c3fa745898363a5cd6c593c3ba11b815898981) | test(email): add unit tests for webmail server security primitives | Security primitive tests retained through d3f7b974 with current mail behavior and resource cleanup. |
| [`454f41cc`](https://github.com/oblien/openship/commit/454f41cc519842bd8f4c9d0b617d2471130d5272) | test(email): run the webmail tests on vitest, matching every other workspace | Proposed runner switch superseded; mail tests use the server's existing Bun runner without adding another test framework. |
| [`cc91437e`](https://github.com/oblien/openship/commit/cc91437e27450da7b869a6157fca4aa3733c3af3) | webmail: block remote CSS fetches when remote images are off | Remote CSS blocking adapted to the current sanitizer in 0dc00f11; existing removal of unsafe style elements remains. |
| [`faa955d8`](https://github.com/oblien/openship/commit/faa955d8ff87820abca037b483164ccd19791daf) | webmail: close review gaps in remote-content blocking | Privacy follow-ups retained and expanded with parsed CSS/HTML; escaped functions, image sets and substitutions covered. |
| [`c5b258f3`](https://github.com/oblien/openship/commit/c5b258f3d0134a6d079a5a649de234e3119c6de2) | test(dashboard): add vitest component-test infrastructure | Current main already provides the dashboard harness; redundant infrastructure/dependencies removed in 6b475f47. |
| [`1f0177ec`](https://github.com/oblien/openship/commit/1f0177ecf2d56df3b142f9e602d44c0448ba51e0) | test(dashboard): cover deployment phase, project status, subdomain, and dotenv logic | Existing phase/status suites retained; dotenv and subdomain coverage added against current public behavior. |
| [`bfb9a564`](https://github.com/oblien/openship/commit/bfb9a5640381f888ae223bfb1f2a71801a4cbdf3) | docs: document dashboard test setup and component testing | Testing documentation adapted to the existing Node/Happy DOM dashboard environments. |
| [`07c7dc27`](https://github.com/oblien/openship/commit/07c7dc27ddc758a9510466ad1ecc6b65af772bf9) | fix(dashboard): address review feedback on test docs, typo, and exhaustiveness guard | Documentation corrections retained; obsolete phase helper changes superseded by the current parser and suites. |
| [`9711f305`](https://github.com/oblien/openship/commit/9711f305c51cf55a148f34f0ea8f71798eef792a) | test(dashboard): cover SSE build, log, and generic message processors | Build/log/generic stream callback coverage adapted in b0e87ea0; existing install-phase behavior retained. |
| [`16d53f82`](https://github.com/oblien/openship/commit/16d53f82db3cdddf0789c4e0e9f9a56e8dfb9104) | test(dashboard): add first component test covering Button | Button interaction/ref/disabled coverage retained with the existing Happy DOM harness. |
| [`de042768`](https://github.com/oblien/openship/commit/de0427680d99af05498f08b77b80f11c226e3661) | feat(api): add a pre-auth per-IP flood guard on /api (#123) | Standalone pre-authentication ceiling ported without reintroducing the already-fixed per-route double charging. |
| [`d4a67c32`](https://github.com/oblien/openship/commit/d4a67c32389e3add9fb966842b379003c32b00ce) | feat(api): gate the flood guard behind an edge-trust config | Explicit edge trust bypasses only the pre-auth ceiling; route authentication and tighter policies remain enforced. |
| [`c6e8e275`](https://github.com/oblien/openship/commit/c6e8e2757470ab21af4a2b98ae5e6932a8447ea4) | docs(api): document OPENSHIP_TRUST_EDGE in .env.example | Edge-trust setting documented with its standalone default; implementation matches configuration parsing. |
| [`e5e095b9`](https://github.com/oblien/openship/commit/e5e095b9b8f4984954a0e846570c7ec6aa77d532) | fix(email): route bin/trash action through IMAP delete instead of labels | IMAP deletion retained through all action entry points with source-folder identity and error propagation. |
| [`a01ae40b`](https://github.com/oblien/openship/commit/a01ae40b36ceb4569a157478abeac523e8bc08d9) | fix(adapters): copy vendor/ into the PHP asset stage so package CSS resolves | PHP asset fix adapted to copy the installed workspace, supporting custom dependency directories and monorepos. |
| [`b786c11c`](https://github.com/oblien/openship/commit/b786c11cf18dfdf95eb2757c5f97c4fa95bd42cb) | feat(core): parse Gemfile.lock for the resolved gem set and Ruby version | Resolved Gemfile.lock dependencies retained; unused Ruby-version helper removed, without claiming new version-selection behavior. |
| [`48e0f97b`](https://github.com/oblien/openship/commit/48e0f97b0416fdbb9734a0b3226722f0e5da6bea) | fix(core): rails loses storage/ on redeploy and installs its gems twice | Rails storage persistence and production asset defaults retained through existing stack/volume mechanisms; duplicate gem install removed. |
| [`614fdacd`](https://github.com/oblien/openship/commit/614fdacd0abcfb4f3c45470aa352ecf8a1379112) | feat(adapters): Ruby build recipe with a real toolchain | Ruby toolchain recipe adapted to the shared planner with matched Bundler settings, runtime libraries and non-root execution. |
| [`c8bcb1ef`](https://github.com/oblien/openship/commit/c8bcb1efb93fe40ce93c1c1e5c1a229b9a8684cf) | fix(mail): disable TLS on amavis loopback transport and use opportunistic TLS on relay | Local Amavis exemption retained; proposed external TLS downgrade removed in favor of hop-specific settings. |
| [`ec8b64d0`](https://github.com/oblien/openship/commit/ec8b64d0d492adeef5124f3ada5f781ee51fd09d) | fix(relay): remove hardcoded smtp_tls_wrappermode on port 587 relay | Relay port transitions explicitly clear wrapper mode while preserving mandatory provider STARTTLS. |
| [`d9cd28d0`](https://github.com/oblien/openship/commit/d9cd28d0b69f338155db2673714d82f8034eb62b) | fix(dashboard): show ConnectionCard for non-catalog internal projects | Connection card uses current workload/target metadata and server-resolved outputs, including non-catalog projects. |
| [`b8172581`](https://github.com/oblien/openship/commit/b81725812e75729f2916e5f019ec4d3d7ad769a3) | Merge branch 'main' into fix/critical-deploy-ssl-server-bugs | Intermediate main merge preserved deployment masking; final thin controller and shared response contract supersede this legacy implementation. |
| [`313c87ed`](https://github.com/oblien/openship/commit/313c87ed79fd260dec697f7f91040ea653b31b4a) | fix(terminal): finalize sessions abandoned mid-handshake so slots aren't leaked | Abandoned terminal cleanup adapted to current leases/auditing; later audit also binds resume tokens to the authorized target. |
| [`da16dce5`](https://github.com/oblien/openship/commit/da16dce5efdd2baf175e82eff853acafe3037eb5) | feat(release): publish the version's changelog section as the release notes | Release notes use the shared exact-version changelog parser and preserve existing manually edited descriptions. |
| [`394c06b7`](https://github.com/oblien/openship/commit/394c06b7a26bef6de109bfe97c492c8df0bb7321) | fix(edge): serve an Openship page for upstream-down 502/504 | Host-generated 502/504 page retained with original status and application responses preserved; existing vhosts upgrade. |
| [`ec5edbe5`](https://github.com/oblien/openship/commit/ec5edbe5e4f07325b8c2c58cc68987161ef98126) | fix(dashboard): surface analytics overview timeouts instead of empty stats | Analytics errors stay visible and retryable; no-data states no longer conceal request failure. |
| [`1a5b74a4`](https://github.com/oblien/openship/commit/1a5b74a4520946fc0bf07d5314d217339205548f) | style(dashboard): apply prettier formatting to analytics overview files | Formatting-only contributor follow-up; final analytics behavior reviewed with the shared endpoint hook. |
| [`e217c178`](https://github.com/oblien/openship/commit/e217c1783ff3acafb0412fd4be4b25150427398a) | fix(dashboard): scope analytics error to traffic summary block in MonitoringView | Traffic errors remain scoped to traffic; resource/geography panels and monitoring domain selection stay independent. |
| [`93814966`](https://github.com/oblien/openship/commit/93814966c66a97181144b0f81031ffab4db5ee3e) | chore: merge upstream main into fix/analytics-overview-timeout-and-error-ui | Ancestry/alignment merge with no additional manual conflict resolution; final integrated behavior reviewed. |
| [`df7bf4b4`](https://github.com/oblien/openship/commit/df7bf4b4d3a1abcfcaec6334a74b2d7978261e3f) | fix(api): support macOS hosts in server system stats monitoring | Portable host probes moved to the shared adapter/platform path; macOS/Linux units and failed probes reviewed. |
| [`e34315aa`](https://github.com/oblien/openship/commit/e34315aafde2c03e08e6aa45c9e76a78fad09516) | fix(dashboard): wire confirmation dialog to draft project deletion | Draft deletion confirmation retained and hardened for focus, dismissal and duplicate requests. |
| [`d16e81c6`](https://github.com/oblien/openship/commit/d16e81c64642a653e4216bd368424b4103349c39) | docs: start the next bug review batch from merged main | Initial ledger revision superseded by the final issue ledger; no runtime change. |
| [`eec2d39d`](https://github.com/oblien/openship/commit/eec2d39d8a901290615c42424126438d43a85eb8) | Merge current architecture and harden draft deletion confirmation | Resolved draft UI adaptation against current main; confirmation uses the existing cleanup path and actual keyboard interactions. |
| [`c4e730e6`](https://github.com/oblien/openship/commit/c4e730e61374119caad4e4a35d9370a8463e3943) | Merge pull request #639 from chbndrhnns/fix/draft-project-delete-confirmation | Integrates contributor PR #639 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`2f793401`](https://github.com/oblien/openship/commit/2f793401f0942eadb6aabbdd5635b0c9d3de2457) | Adapt macOS monitoring to shared platform and portable host probes | Removed obsolete controller-owned monitoring code; shared portable adapter command feeds current platform operations. |
| [`aac37169`](https://github.com/oblien/openship/commit/aac37169ea236d07bfa898c6e8edc28de2dbcf74) | Format behavioral coverage for portable server metrics | Formatting of portable metrics coverage only; actual command execution and platform fixtures retained. |
| [`5bde4848`](https://github.com/oblien/openship/commit/5bde484890beb362925c870dec603efe9fde4e79) | Merge pull request #645 from chbndrhnns/fix/server-monitor-macos-support | Integrates contributor PR #645 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`7f03725b`](https://github.com/oblien/openship/commit/7f03725b79fb57477e3a873cc87bb8c578bf0c31) | Adapt PHP asset stage fix to reuse the installed workspace | Resolved PHP stage adaptation by reusing the complete installed builder workspace, without a second dependency installer. |
| [`93d6c982`](https://github.com/oblien/openship/commit/93d6c982b00e5273d3ca3e8690646da85d922b9a) | Exercise generated PHP asset stages with installed package stylesheets | Real generated PHP asset-stage regressions cover root and custom monorepo dependency paths. |
| [`d8dbf53c`](https://github.com/oblien/openship/commit/d8dbf53c979ec2994f76fae6c511d23f05232be9) | Merge pull request #467 from sudanese/fix/php-asset-stage-vendor | Integrates contributor PR #467 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`24c26321`](https://github.com/oblien/openship/commit/24c263214e66c0c19d9e880847c104e4620f869a) | Adapt terminal disconnect fix and close remaining session ownership gaps | Resolved terminal lifecycle adaptation, including unique session IDs, abandoned audits and runtime lease disposal. |
| [`380d2526`](https://github.com/oblien/openship/commit/380d25260649cf8eb590854d7833c5ca3dea037e) | Merge pull request #579 from Farahat612/fix/426-terminal-session-leak | Integrates contributor PR #579 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`25ee2392`](https://github.com/oblien/openship/commit/25ee23928bb50200ddb2004f3f150c25a882ae12) | fix(routing): proxy static container roots through their owning service | Static container root routes use the recorded primary service and existing live upstream/port ownership resolver. |
| [`d0e2979a`](https://github.com/oblien/openship/commit/d0e2979a15a737e128749de3ffbc2a0db9ba1abc) | docs: track all open reports and completed bug integrations | Interim issue inventory superseded by the final ledger; no runtime change. |
| [`30c564b0`](https://github.com/oblien/openship/commit/30c564b0ed741246e3e75195de9e0f97ddc556a4) | fix(dashboard): keep log and terminal connections owned by the current target | Current-target stream ownership and handshake timeouts retained; this audit additionally repairs retry scheduling and replay cursors. |
| [`829b811a`](https://github.com/oblien/openship/commit/829b811ae48ed85a27f494f4730541ad892eb7dc) | fix(updates): share release checks across desktop and dashboard consumers | Desktop owns a shared release snapshot; concurrent checks coalesce and failed refreshes remain retryable. |
| [`93d2349b`](https://github.com/oblien/openship/commit/93d2349b1027773b1888dab948b77869d307e823) | docs: clarify bundled mail engine license boundaries (#610) | Component and packaging inventory corrects blanket licensing claims; missing upstream provenance remains open. |
| [`e3cb57ec`](https://github.com/oblien/openship/commit/e3cb57eca01c9fe711301526642d84377305149a) | fix(dashboard): keep issue operation logs inline and owned (#660) | Inline issue logs reuse the existing prepare stream and consent UI; reconnect is attach-only and old readers cannot take over. |
| [`9a42a51c`](https://github.com/oblien/openship/commit/9a42a51c20d85c65c5ffdb9dfef3ac29ba9d2cc9) | docs: record current bug review evidence and remaining scope | Interim evidence/remaining-scope record superseded by the final ledger; no runtime change. |
| [`9af1cb98`](https://github.com/oblien/openship/commit/9af1cb9861ee76633dae003442c83b1e6abfb9d3) | Merge current architecture and bug integration into PR #557 | Resolved edge coverage against the current renderer; upstream semantics and route-generation upgrade preserved. |
| [`f24e0a7d`](https://github.com/oblien/openship/commit/f24e0a7dbbe4d07439e5655c3293f581700dec4c) | test(edge): exercise current route upgrades and container reloads | Edge upgrade/reload tests exercise the current renderer and generation marker rather than an obsolete route shape. |
| [`90dd8681`](https://github.com/oblien/openship/commit/90dd8681034ac2c8a60acc2879156fca1a3dce88) | Merge pull request #557 from AbdullahM07/fix/edge-upstream-down-page | Integrates contributor PR #557 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`7d90d71e`](https://github.com/oblien/openship/commit/7d90d71e31a17bff0c67d1d1bd949cdc62b27820) | Merge current architecture and adapt PR #507 connection discovery | Resolved ConnectionCard adaptation using the current workload model and backend output resolution. |
| [`ceb66a52`](https://github.com/oblien/openship/commit/ceb66a52f408a39dfd9d036c56e99a2eab38e98b) | fix(dashboard): defer connection reads until the project exists | Connection discovery waits for a real project ID; unresolved initial data cannot start invalid endpoint reads. |
| [`74fe1521`](https://github.com/oblien/openship/commit/74fe15218151275399ea684186402276286d7639) | Merge pull request #507 from santhiprakash/fix/connection-card-504 | Integrates contributor PR #507 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`ba9b8085`](https://github.com/oblien/openship/commit/ba9b8085375d2f8886886a534c842534a56f0ed2) | fix(dashboard): avoid a stale project port on service overviews (#506) | Service-based Overview omits a stale project-wide port; service details remain the source of actual ports. |
| [`49c580fe`](https://github.com/oblien/openship/commit/49c580fecb21e8d045afe5f759b65b5ec6caa203) | fix(cli): refuse unresolved database storage before writing configuration | One database-layout resolver serves preview/prefetch/write; failed probes cannot overwrite secrets or guess storage layout. |
| [`17100b3e`](https://github.com/oblien/openship/commit/17100b3e3805be65fae77ee11a73b15fa0a93fd4) | Merge current architecture into PR #430 and preserve keyboard delete folder | Preserved keyboard deletion source folder while integrating the IMAP action fix. |
| [`eaa2a4fa`](https://github.com/oblien/openship/commit/eaa2a4fa48e9f1bb13e7ca0dfec6d01903c580f6) | test(email): verify trash actions through IMAP deletion | Client-to-tRPC-to-IMAP tests preserve folder identity, including duplicate UIDs and failed operations. |
| [`5dbd9b2b`](https://github.com/oblien/openship/commit/5dbd9b2b1455739791d4533a2921f0de676e8201) | Merge pull request #430 from santhiprakash/fix/email-bin-imap-move-429 | Integrates contributor PR #430 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`a435f5c9`](https://github.com/oblien/openship/commit/a435f5c90aa895bc2d5c031092f2f2609926f2a5) | fix(system): refresh stale SSH login groups without interrupting active sessions | SSH group refresh is conditional and coalesced; active commands/retained terminals survive until their executor can be released. |
| [`705b004d`](https://github.com/oblien/openship/commit/705b004d96ff6da062ef63ecf03099e5a8ef8c27) | fix(compose): recover cached environment provenance and require source refresh | Compose provenance recovery preserves explicit edits and frozen rollbacks; ambiguous values/source failures stop deployment before queuing. |
| [`bb58f129`](https://github.com/oblien/openship/commit/bb58f129be6559966e3a23886ee966e7729f2817) | Merge bug integration and adapt analytics recovery to current dashboard | Resolved analytics adaptation through existing endpoint caching; monitoring panels and domain selection remain independent. |
| [`f6e22f5f`](https://github.com/oblien/openship/commit/f6e22f5fa7c86dd7d6f8e5ef1469f1ad1215b409) | fix(dashboard): protect refreshed analytics from stale polling responses | Cache revisions and request identity prevent obsolete polling/completions from replacing refreshed analytics. |
| [`0834b84c`](https://github.com/oblien/openship/commit/0834b84ce52dc0eaa9bbc73337e055e7bf94408a) | Merge pull request #421 from santhiprakash/fix/analytics-overview-timeout-and-error-ui | Integrates contributor PR #421 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`3cefff5c`](https://github.com/oblien/openship/commit/3cefff5cb8459b26413d28904c48a693d14b977e) | Merge bug integration and adapt relay TLS repair to the current mail engine | Moved relay repair to the platform service; local filter TLS override does not weaken external relay encryption. |
| [`da951633`](https://github.com/oblien/openship/commit/da951633373c139e0edbcef2ba14e82568914032) | Merge pull request #477 from farrasrayhand/fix/postfix-amavis-tls | Integrates contributor PR #477 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`0dc00f11`](https://github.com/oblien/openship/commit/0dc00f11b67493bbca41f580027db550ef5dd3aa) | fix(email): adapt remote content blocking to the current sanitizer | Kept current XSS protections and introduced one parsed remote-resource policy for HTML and inline CSS. |
| [`8138b1ee`](https://github.com/oblien/openship/commit/8138b1ee521579d77fef05a3b81ff690db369bca) | Merge pull request #222 from ahmedhesham6/fix/webmail-css-remote-resource-blocking | Integrates contributor PR #222 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`e965f5cb`](https://github.com/oblien/openship/commit/e965f5cb71865fc2b27c3da5ca9a95ca780cf51d) | fix(deploy): reject preview variables on production runtimes | One shared environment guard rejects preview variables on production targets before mutation; preview projects still activate normally. |
| [`d61cf25e`](https://github.com/oblien/openship/commit/d61cf25ef4e833af055990df1b0f505cd4bf40d0) | fix: adapt certificate renewal and login fixes to platform APIs | Retained SDK/platform controller boundaries; carried renewal and login repairs, dropped superseded deletion/deploy copies. |
| [`2f37a0a3`](https://github.com/oblien/openship/commit/2f37a0a394bd2bbe445d398b89f391ec0278d69d) | Merge pull request #196 from Rish-it/fix/critical-deploy-ssl-server-bugs | Integrates contributor PR #196 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`1ceb4de7`](https://github.com/oblien/openship/commit/1ceb4de7a47289600e4fd026c442c6445a795e41) | fix(api): adapt standalone flood protection to current route policies | Kept main route-level rate policies and introduced the separate configurable pre-authentication ceiling. |
| [`328d5ceb`](https://github.com/oblien/openship/commit/328d5cebe2802bb61a513c3e501637f18031aa9e) | Merge pull request #232 from shuvamk/feat/rate-limit-flood-guard | Integrates contributor PR #232 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`ea34b3e4`](https://github.com/oblien/openship/commit/ea34b3e4b4c8403f9b5ab13d5ccba3a8cc8f7ea0) | fix(core): adapt Rails storage and build defaults to current integration | Retained Rails persistence/default fixes and lockfile dependency parsing; removed the unused version helper. |
| [`f1dc8a74`](https://github.com/oblien/openship/commit/f1dc8a740210c542215de0e287740abef259db5f) | Merge pull request #468 from a-abdellatif98/feat/rails-stack-registry | Integrates contributor PR #468 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`782171b6`](https://github.com/oblien/openship/commit/782171b6c8d8eea4831d6efbfc06a9fabb79b241) | fix(cli): expose safe project display-name changes | CLI display-name edit uses existing SDK project update and sends only the name, preserving runtime identity. |
| [`38cc1a03`](https://github.com/oblien/openship/commit/38cc1a0395ac3f2c4b34b005cf0d5d450d66d6a6) | fix(backup): support Valkey and verify RDB restore preconditions | Valkey reuses Redis/RDB catalog and producer; persistence preconditions fail closed. This audit also restores save settings on preparation failure. |
| [`f8b9b0aa`](https://github.com/oblien/openship/commit/f8b9b0aa834f6230168e071607daa4da87945480) | Merge current architecture and adapt the Ruby container recipe | Adapted Ruby build/runtime stages to shared workspace, preparation, environment and runtime-copy helpers. |
| [`be1d0365`](https://github.com/oblien/openship/commit/be1d03659f001b58ac596aa618095f4b7c7421fc) | Merge latest bug batch into the adapted Ruby recipe | Aligned Ruby recipe tests with the latest planner changes; assertions retain native-gem and non-root guarantees. |
| [`9ede7762`](https://github.com/oblien/openship/commit/9ede77620bc7eb500ee1568aa7f3d46d61932703) | Merge pull request #469 from a-abdellatif98/feat/rails-docker-recipe | Integrates contributor PR #469 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`f7de2351`](https://github.com/oblien/openship/commit/f7de2351764e31c186c2c4b7727658bbd4c32684) | Merge current architecture and share release changelog parsing | Unified release, updater and website changelog parsing; standalone extraction works without installed workspace dependencies. |
| [`d4d62906`](https://github.com/oblien/openship/commit/d4d6290614441a1a48d8dc485cc8b7cd66791f77) | Merge pull request #591 from Farahat612/feat/changelog-release-notes | Integrates contributor PR #591 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`ece434ec`](https://github.com/oblien/openship/commit/ece434ecf72ef7c7e9d271c6a41e5fbe7598c1cb) | fix(contracts): keep ensure environment schema declaration-safe | Ensure-input schema remains declaration-safe without changing the runtime contract; SDK build/typechecks pass. |
| [`f041d5df`](https://github.com/oblien/openship/commit/f041d5dfd13145e7fe8b70be1a1329aaa5e546c5) | docs(cli): describe the current Node installer path | Node installer entry-point comment correction only; execution is unchanged. |
| [`248ba220`](https://github.com/oblien/openship/commit/248ba220d677602c55348bc8998cb15524205622) | fix: preserve explicit Compose advanced resets | Explicit advanced:null reset remains distinct from omission while Compose environment provenance is retained. |
| [`3822b062`](https://github.com/oblien/openship/commit/3822b0620f5cb4f1c57e462b5a441023d1df6846) | fix: report restore writes only after producer preflight | Restore destructive reporting begins at artifact handoff; producer preflight failures do not claim data loss. Download cleanup hardened in this audit. |
| [`d3f7b974`](https://github.com/oblien/openship/commit/d3f7b97446d6bb8c2ff07fd1fb2c117bd5985478) | test: adapt webmail coverage to the current Bun server | Adapted contributor coverage to Bun and current security behavior; removed redundant test-runner dependencies. |
| [`3c35e5ba`](https://github.com/oblien/openship/commit/3c35e5bad490c6e631eef167d03c8f936e758aff) | fix: enforce host and active deployment ownership | Shared project/org ownership predicate and loaders cover runtime access, cleanup and imports; local execution requires the owning organization. |
| [`9fc8e945`](https://github.com/oblien/openship/commit/9fc8e945fe88eac4d92fc61dd21c0d2dceda9954) | merge: validate webmail tests with current ownership fixes | Ancestry/alignment merge with no additional manual conflict resolution; final integrated behavior reviewed. |
| [`6b475f47`](https://github.com/oblien/openship/commit/6b475f47e538cfb81d2a9651560aa8924ccd7134) | test: retain current dashboard harness and add parser coverage | Retained existing dashboard harness and phase/status suites; added only useful current-parser coverage. |
| [`b6a41165`](https://github.com/oblien/openship/commit/b6a41165d65f94325510179335cbff7456774ceb) | Merge pull request #219 from ahmedhesham6/test/email-server-coverage | Integrates contributor PR #219 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`54d8ba97`](https://github.com/oblien/openship/commit/54d8ba975bf9d7f876f6d50d576fb29a469174e7) | merge: align dashboard tests with the integration branch | Ancestry/alignment merge with no additional manual conflict resolution; final integrated behavior reviewed. |
| [`508adde8`](https://github.com/oblien/openship/commit/508adde85b4bac18c6124e510f2569f145bc2a7e) | Merge pull request #243 from walidozich/chore/dashboard-test-infrastructure | Integrates contributor PR #243 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`5e8f044e`](https://github.com/oblien/openship/commit/5e8f044eaf5f9d23d0916810b4cea28aa9171046) | test: type Compose recovery fixtures against service rows | Compose recovery fixtures use Partial<Service>; runtime assertions and reconciliation behavior remain intact. |
| [`b0e87ea0`](https://github.com/oblien/openship/commit/b0e87ea0419c1ce90336ed6078fca37050067ff4) | test: cover current dashboard streams and buttons | Adapted stream and Button tests to current contracts and the existing Happy DOM environment. |
| [`119d611a`](https://github.com/oblien/openship/commit/119d611a168f369936f09248158598842a75168b) | merge: align dashboard coverage with typed Compose fixtures | Ancestry/alignment merge with no additional manual conflict resolution; final integrated behavior reviewed. |
| [`0558e611`](https://github.com/oblien/openship/commit/0558e611cfbd2ccd02cbec6bafb2203a0af7c943) | Merge pull request #248 from walidozich/test/dashboard-sse-processors | Integrates contributor PR #248 with original history; no additional manual conflict resolution. Final behavior reviewed with its adaptation. |
| [`e4587335`](https://github.com/oblien/openship/commit/e4587335306102f65db4db55a339b45500c32b9c) | test: distinguish image installs from host package ownership | Host-command guard recognizes the bounded Ruby image-install recipe; host execution ownership checks remain enforced. |
| [`144ac58b`](https://github.com/oblien/openship/commit/144ac58b6f3864129e3bca9d81dbb6b963c58b96) | docs: refresh CLI references for the verified bug fixes | CLI reference output matches public commands and environment-target semantics. |
| [`d443d124`](https://github.com/oblien/openship/commit/d443d1242c81ac9891edb4ec6741f97f44b693b2) | docs: finalize issue-to-fix review and integration evidence | Final issue/evidence ledger update; the changelog parser change is trailing-whitespace cleanup only. |
| [`435f408c`](https://github.com/oblien/openship/commit/435f408c7e3c5b156b7479c4986a1c8138cce182) | fix(ci): apply matrix filters to the workspace runner | CI matrix filters reach Turbo directly; test workspace partitions remain disjoint and complete. |
| [`f18f9c74`](https://github.com/oblien/openship/commit/f18f9c74845a3a437a75ba4a70ee1022f6c7196b) | docs: record CI matrix and desktop validation | CI/desktop evidence documentation only. |
| [`d2b4d2f9`](https://github.com/oblien/openship/commit/d2b4d2f9f9f01c483adebac5d27c234050c41cc4) | fix(test): preserve root workspace filter arguments | Root test filters still reach a single workspace runner; script tests have their own command and run once in CI. |
| [`42e193df`](https://github.com/oblien/openship/commit/42e193df45104ea119dc1adc92fbbba1ef77cc06) | docs: record root test command compatibility | Root test command compatibility documentation only. |
| [`0285ccb2`](https://github.com/oblien/openship/commit/0285ccb2345311ef827707b567a7a2f43edfd05a) | docs(ci): clarify matrix runner ownership | CI runner ownership documentation only; required aggregate check preserved. |
| [`9c6d75f8`](https://github.com/oblien/openship/commit/9c6d75f86e314cf5c7f4a6b2522be15defe9e5d5) | docs: reconcile verified bug closures | Resolved issue closures reconciled with evidence; partial scopes and reproduction gaps remain open. |
## Additional hardening commits
| Commit | Reviewed result |
| --- | --- |
| [`dacf2b0e`](https://github.com/oblien/openship/commit/dacf2b0efef713076d0404f42cd55d379ae945b6) | Both terminal controllers reject a token for another server/service; normal resumes keep their session and shell. |
| [`a57cc76b`](https://github.com/oblien/openship/commit/a57cc76b62cae1c784235476cd8ed4f53863e64f) | Retry after attempt completion, preserve replacement ownership, stop on permission failure, and advance/filter the replay cursor. |
| [`8c4626e8`](https://github.com/oblien/openship/commit/8c4626e8ef367de329c95c9c4501d1761284b45f) | Restore Redis save settings before any write when preparation fails; forward read errors and close downloads on early target refusal. |
The documentation commit containing this report and the updated issue ledger changes no runtime behavior.