| 1 | # Windows canonical entry and compatibility / Windows 标准入口与兼容 |
| 2 | |
| 3 | User guidance: [English](WINDOWS_APP_IDENTITY.md) · [中文](WINDOWS_APP_IDENTITY.zh-CN.md). |
| 4 | |
| 5 | ## Installed layout / 安装布局 |
| 6 | |
| 7 | `Reasonix.exe` is the canonical GUI entry; `reasonix-cli.exe` remains the CLI |
| 8 | forwarder. Fresh installers and newly extracted ZIPs omit the root |
| 9 | `reasonix-launcher.exe`. A managed upgrade preserves and refreshes that entry |
| 10 | only when it already exists. There is no automatic retirement deadline. |
| 11 | |
| 12 | `Reasonix.exe` 是标准 GUI 入口,`reasonix-cli.exe` 仍为 CLI 转发入口。 |
| 13 | 新安装、全新解压 ZIP 不包含根目录 `reasonix-launcher.exe`;受控升级仅在旧入口 |
| 14 | 已存在时保留并更新它,不设置自动删除期限。版本目录内的 Electron 程序不属于用户入口。 |
| 15 | |
| 16 | ## Transaction and wire compatibility / 事务与协议兼容 |
| 17 | |
| 18 | Installer activation and the Windows update helper use |
| 19 | `ActivationRequest.WindowsRootEntries`. This input is mutually exclusive with |
| 20 | explicit root members. After taking the activation lock, the shared owner |
| 21 | inspects the legacy entry and constructs an exact root whitelist. Invalid |
| 22 | legacy paths fail activation. Version files and all selected root entries are |
| 23 | published before `current.json`; failures before that commit restore the prior |
| 24 | files through the existing rollback mechanism. Process coordination retains its |
| 25 | existing lock order. Concurrent old and new writers are covered by a forced |
| 26 | interleaving test, not timing-based sleeps. |
| 27 | |
| 28 | 安装器和 Windows 更新器统一使用 `ActivationRequest.WindowsRootEntries`,与显式 |
| 29 | 根成员参数互斥。共享实现持有激活锁后检查旧入口,并生成精确白名单;旧入口路径 |
| 30 | 非法时中止激活。版本文件和所选根入口均在 `current.json` 提交前发布,提交前失败 |
| 31 | 通过既有恢复机制恢复旧文件。进程协调锁顺序不变,并以确定性交错测试覆盖新旧写入者竞争。 |
| 32 | |
| 33 | | Contract / 契约 | Old and new readers / 新旧读取行为 | Change / 变化 | |
| 34 | | --- | --- | --- | |
| 35 | | `current.json` schema 1 | Same strict fields / 相同严格字段 | None / 无 | |
| 36 | | `versioned-v1` | Same version directory resolution / 相同版本目录解析 | None / 无 | |
| 37 | | Windows payload schema 2 | Retains historical launcher member / 保留旧载荷启动器名称 | None / 无 | |
| 38 | | `io.reasonix.desktop` | Same window and shortcut identity / 相同窗口及链接身份 | None / 无 | |
| 39 | | User configuration and sessions / 用户配置与会话 | No migration or new writes / 无迁移或新增写入 | None / 无 | |
| 40 | |
| 41 | Signed payloads and NSIS staging continue to use `reasonix-launcher.exe`. |
| 42 | Already installed update helpers cannot be changed by shipping a new helper; |
| 43 | they must still accept and install the next payload. New activators map these |
| 44 | verified bytes to `Reasonix.exe`, and to the old name when preservation applies. |
| 45 | An old helper may continue publishing both names. This does not require a bridge |
| 46 | release or a new pointer field. It does not reduce the signed payload inventory. |
| 47 | |
| 48 | 签名载荷和 NSIS staging 继续使用 `reasonix-launcher.exe`。安装新版 helper 不会 |
| 49 | 改变执行本次升级的旧 helper,所以必须保持旧载荷契约。新激活器将已验证字节映射 |
| 50 | 到标准入口,必要时同时更新旧入口。旧 helper 可能仍发布两个名字;无需过渡版本、 |
| 51 | 无需添加指针字段,也不减少签名载荷的程序清单。 |
| 52 | |
| 53 | ## Artifact verification / 产物验证 |
| 54 | |
| 55 | The default layout is `canonical`. Historical verification must explicitly select |
| 56 | `legacy-dual`; neither validator auto-detects its policy from archive contents. |
| 57 | The candidate-owned `desktop/packaging/windows-portable-layout.txt` declares the |
| 58 | build layout to the protected release verifier. Recovery of older candidates |
| 59 | without that declaration explicitly uses `legacy-dual`. |
| 60 | |
| 61 | 默认验证 `canonical`;历史产物必须显式指定 `legacy-dual`,不得根据包内文件自动 |
| 62 | 放宽规则。候选源码中的 `desktop/packaging/windows-portable-layout.txt` 声明产物布局, |
| 63 | 受保护的发布验证器读取它;恢复没有此声明的历史候选时,显式使用 `legacy-dual`。 |
| 64 | |
| 65 | ```sh |
| 66 | # New ZIP; verify members and entry bytes without extracting. |
| 67 | node desktop/packaging/verify.mjs dist/Reasonix-windows-amd64.zip |
| 68 | # Historical ZIP; require both identical GUI entries. |
| 69 | node desktop/packaging/verify.mjs OLD.zip --kind windows-portable-zip --portable-layout legacy-dual |
| 70 | # Before packaging: also compare canonical entry with the payload source. |
| 71 | scripts/verify-windows-portable.sh STAGING canonical PAYLOAD/reasonix-launcher.exe |
| 72 | ``` |
| 73 | |
| 74 | The Authenticode verifier additionally checks the exact EXE/DLL inventory and |
| 75 | hashes every mapped PE against its signed payload source. Use |
| 76 | `-PortableLayout legacy-dual` only for historical dual-entry packages; new |
| 77 | packages use the default `canonical`. Signature checks are not replaced by |
| 78 | the structural or byte-equality tests. |
| 79 | |
| 80 | Authenticode 验证器额外校验精确 EXE/DLL 清单,并逐个比对签名载荷源文件哈希。 |
| 81 | 仅历史双入口包使用 `-PortableLayout legacy-dual`;新包默认 `canonical`。 |
| 82 | 结构验证和字节相同比较不能替代签名验收。 |
| 83 | |
| 84 | ## Release acceptance / 发布验收 |
| 85 | |
| 86 | Run root Go tests and the separate Desktop module tests, Electron type checking |
| 87 | and tests, packaging tests, and the activation/shortcut race tests. Windows |
| 88 | cross-compilation only proves compilation; it never counts as a native test. |
| 89 | |
| 90 | 运行根 Go 模块、独立 Desktop 模块、Electron 类型检查与测试、打包测试,以及激活与 |
| 91 | 快捷方式 race 测试。Windows 交叉编译只证明可编译,不计为原生运行测试。 |
| 92 | |
| 93 | Before promotion, record native x64 and ARM64 evidence for both installer and ZIP: |
| 94 | |
| 95 | - Fresh installation, repair, repeat upgrade and existing legacy entry preservation. |
| 96 | - Real unchanged old helper upgrading to the signed candidate, including the |
| 97 | retained `1.38.9` internal sample and an available supported official release. |
| 98 | - Both entry names, CLI argument/output/exit semantics, shortcuts with custom |
| 99 | arguments/icons/working directories, taskbar grouping and repeat launch. |
| 100 | - Strict shell/service handshake, renderer `Version`, clean shell/service exit, |
| 101 | and a separate deliberate mismatch negative case. |
| 102 | - File locks, read-only entries, denied access, invalid pointers and interrupted |
| 103 | activation. Preserve logs and distinguish rollback errors from success. |
| 104 | |
| 105 | 晋级发布前,安装器和 ZIP 均需补齐原生 x64、ARM64 证据:新装、修复、连续升级、旧入口 |
| 106 | 保留;使用真实未修改的旧 helper 升级签名候选(含保留的 `1.38.9` 内测样本和可取得的 |
| 107 | 受支持正式版本);两个入口与 CLI 行为、快捷方式自定义属性、任务栏分组和重复启动; |
| 108 | 严格握手、渲染端 `Version`、正常退出及独立的故意不匹配反例;文件占用、只读、权限错误、 |
| 109 | 损坏指针和安装中断。保留日志,不能把恢复失败报告为成功。 |
| 110 | |
| 111 | Use isolated installations and data homes. Do not replace packaged binaries, |
| 112 | enable development mode, or disable signature/identity checks to obtain a pass. |
| 113 | Missing native or signing evidence blocks release qualification. Publishing and |
| 114 | channel changes remain separate actions; local implementation creates neither. |
| 115 | |
| 116 | 使用独立安装和数据目录,不替换包内程序、不启用开发模式、不关闭签名或身份校验来 |
| 117 | 取得通过结果。缺少原生或签名证据时不能判定可正式发布;公开发布和更新渠道切换是独立动作。 |
| 118 |