hermes-hub/docs/audits/2026-08-20-release-candidate-review-request.md

103 lines
7.3 KiB
Markdown

# Hermes Hub — Release Candidate Review Request (v0.1.1)
**Date:** 2026-08-20
**Target Candidate:** `v0.1.1`
**Base Commit:** `5ccfd48`**Current Head:** `2f5e6d9` + RC commits
**Reviewer:** Claude (Роль «Ревьюер»)
**Status:** Ready for Independent Audit (FEATURE FREEZE ACTIVE)
---
## 1. Summary of Closed Findings & Evidence
| Finding | Description | Resolution / Implementation | Verification Evidence |
|---|---|---|---|
| **B1** | Non-router path crashed with `IndexError` on error dict | Handled error payloads in `runtime.py` and `hermes_plugin.py` to synthesize valid `choices[0].message.content` | `test_p0_5_b1_non_router_error_fallback` (PASS) |
| **B2** | `assign_profile_to_role` created rogue roles with 16 profiles | Enforced `CANONICAL_ROLE_MAP`, rejecting non-canonical roles with `(False, msg)` | `test_p0_7_assign_role_action` (PASS) |
| **B3** | YAML serialization dropped root `router:` block | Preserved `router:` root block and settings (`max_failover_attempts`, `session_affinity_ttl_seconds`) across load/save | `test_p0_10_yaml_round_trip_preservation` (PASS) |
| **B4 / S1** | Rate limit treated as quota (30m cooldown); reset duration not parsed | Evaluated rate limit before quota (60s cooldown); regex parsed reset hours/minutes (`resets in Xh/Ym`) | `test_p0_11_rate_limit_vs_quota_classification` (PASS) |
| **N1** | "Только резерв" failed with non-canonical role error in Wizard | Added explicit spare pool support (`role="spare"` clears active role chains and marks profile as spare); Wizard verifies `ok == True` before logging success | `test_n1_spare_assignment_mode` (PASS) |
| **N2** | Double error prefix `Antigravity error: Antigravity error:` | Implemented `format_antigravity_error` stripping duplicate prefixes | `test_n2_error_formatter_deduplication` (PASS) |
| **R4** | UI Settings were not read by runtime components | Created `settings_service.py` (`hub_settings.json`); `RouterEngine` dynamically reads `auto_failover`, `session_affinity`, `failover_attempts`, and `auto_return_primary` | `test_r4_settings_runtime_influence` (PASS) |
| **S4 / N3** | Secret scanner gave false PASS; string concatenation obfuscated OAuth secret | Implemented AST & regex scanner detecting hardcoded tokens and obfuscated string concatenations; removed string concatenation in `oauth.py` | `test_s4_secret_scanner_ast_detection` (PASS) |
| **OAuth** | Document Google OAuth client ownership & RFC 8252 security model | Created `docs/OAUTH_CLIENT.md` detailing public desktop client PKCE flow and token filesystem isolation | `docs/OAUTH_CLIENT.md` |
| **S5** | `py_compile` compiled non-src files | Restricted `py_compile` strictly to `dest / "src"` | `test_dogfood_update_e2e` (PASS) |
| **S6** | Settings controls not wired to dictionary | Bound all switches and option menus in `settings_view.py` to `self.settings` on save | `test_ui_refinement.py` (PASS) |
| **S7** | Installer test isolation | Documented canonical installer in `installer/README.md`; unit tests isolated from Windows Registry/Start Menu | `installer/README.md` |
| **S8** | UI tests broken when `customtkinter` missing | Added `pytest.importorskip("customtkinter")` | `test_ui_refinement.py` (PASS) |
| **S9** | Wizard polling continued in background after modal close | Overrode `destroy()` in `AddAccountWizard` to set `_polling_active = False` | `test_p0_6_oauth_session_status_unification` (PASS) |
---
## 2. Update Feed Architecture & Rollback Evidence
- **Private Source Repository:** `https://github.com/ochenstarik-ui/hermes-hub` (Private, no PATs embedded).
- **Public Release Feed:** `https://raw.githubusercontent.com/ochenstarik-ui/hermes-hub-releases/main/update_manifest.json` (Public metadata & release binaries).
- **Host Allowlist Active:** `github.com`, `raw.githubusercontent.com`, `objects.githubusercontent.com`, `github-releases.githubusercontent.com`.
- **Friendly Fallback:** When public feed is unpopulated (HTTP 404), GUI displays: *"Канал обновлений пока не настроен."* without crashing.
- **Hermetic Rollback:** If post-update smoke test fails, `UpdateManager` automatically restores the backup of `src/`, `assets/`, `config/`, and `launcher/` while preserving user data (`auth.json`, `router_profiles.yaml`, `hub_settings.json`).
### Updater Tests Exact Output:
```
============================= test session starts =============================
platform win32 -- Python 3.11.16, pytest-9.1.1, pluggy-1.6.0
collected 7 items
tests/test_updater.py::test_version_comparison PASSED [ 14%]
tests/test_updater.py::test_sha256_verification PASSED [ 28%]
tests/test_updater.py::test_host_allowlist_validation PASSED [ 42%]
tests/test_updater.py::test_manifest_404_friendly_message PASSED [ 57%]
tests/test_updater.py::test_bad_hash_rejection PASSED [ 71%]
tests/test_updater.py::test_updater_rollback_on_failure PASSED [ 85%]
tests/test_updater.py::test_dogfood_update_e2e PASSED [100%]
============================== 7 passed in 0.42s ==============================
```
---
## 3. Release Gate Suite Output
```
======================================================================
Hermes Hub — Release Gate Verification Suite (Target: v0.1.1)
======================================================================
Running 1. Version Consistency ([UNIT VERIFIED])...
[UNIT VERIFIED] Version 0.1.1 is consistent across all manifests
Running 2. P0 Release Blockers (16/16) ([UNIT VERIFIED])...
[UNIT VERIFIED] 12/12 P0 release blockers & regression checks verified
Running 3. Auto-Updater & Rollback ([INTEGRATION VERIFIED])...
[INTEGRATION VERIFIED] Auto-updater, SHA-256 verification, and rollback verified
Running 4. Full Offline Pytest Suite ([INTEGRATION VERIFIED])...
[INTEGRATION VERIFIED] All unit and integration tests passed offline
Running 5. Zero Hardcoded Developer Paths ([STATIC VERIFIED])...
[STATIC VERIFIED] Zero hardcoded developer paths in src/
Running 6. Zero Credentials & AST Secret Scan ([SECURITY VERIFIED])...
[SECURITY VERIFIED] Zero secret files, live tokens, or obfuscated secret assignments in src/
Running 7. Public Production Update Feed ([LIVE STATUS])...
[LIVE STATUS] [NOT PUBLISHED YET] Public release repository manifest is not yet populated (HTTP 404 at https://raw.githubusercontent.com/ochenstarik-ui/hermes-hub-releases/main/update_manifest.json). Offline updater verification passed.
======================================================================
[RELEASE GATE: PASSED] All criteria verified. Ready for Candidate v0.1.1
======================================================================
```
---
## 4. Remaining Architectural P1 Items (Post-v0.1.1 Roadmap)
The following items are deferred to post-release stabilization in accordance with the Feature Freeze:
1. **A. `_CM_LOCK`:** Thread-safe capability matrix runtime updates.
2. **B. Global `gemini:antigravity` mutation:** Scoped model profile naming.
3. **C. Session Affinity TTL:** Granular TTL lease expiration worker.
4. **D. `router_state.json` interprocess lock:** Multi-process file lock safety.
5. **E. `hermes_plugin` scope / `next_call`:** Strict passthrough chaining.
6. **F. UI background health refresh:** Non-blocking async health polling worker in GUI.
7. **G. Widget in-place updates:** Partial card re-rendering without full tab redraw.