arch(hololake): establish clean Tauri desktop line

This commit is contained in:
冰朔 2026-08-12 08:32:37 +08:00
commit a2302cfd13
23 changed files with 662 additions and 17 deletions

View file

@ -0,0 +1,36 @@
# HoloLake Native Desktop
状态:`FOUNDATION_ROOT_CREATED · TAURI_SCAFFOLD_PENDING`
这是 HoloLake 唯一未来桌面产品主线的干净源码根。它将采用 Tauri v2、Rust 和
React/TypeScript但不会从现有 Tauri 或 Electron 目录整树复制。
当前只登记产品边界和发布广播合同。选择并验收新的视觉/交互方向之前,不创建会意外继承
任一旧应用布局的产品 UI。
## 供体边界
- `../hololake-platform`:只读工程能力、合同、测试和 Rust 原生边界供体;
- `../hololake-desktop``../guanghu-knowledge-base`:只读知识 UX、行为和数据兼容供体
- Tolaria、Outline 及其他上游:人工审查的零件来源,不是更新源或产品主线。
禁止向供体继续增加新产品功能。迁入单位只能是:能力合同、来源/许可证、威胁面、实现、
测试和人类可见验收。
## 更新边界
- 生产客户端只允许 HoloLake 所有的 HTTPS 发布端点;
- 广播可自动出现,下载/安装/重启必须由人类明确选择;
- Tauri 更新包签名验证不可关闭;
- 平台代码签名与更新包签名是两条独立信任链;
- 私钥和平台签名凭据不得进入此目录;
- 启动健康回执与可恢复回退是发布完成条件。
机器可读广播合同:`contracts/release-broadcast.schema.json`
## 下一门
1. 确认正式 bundle identifier、HoloLake 更新域名和密钥托管责任;
2. 完成双供体功能/数据/许可证/安全审计;
3. 选择新的人类界面视觉方向;
4. 再生成最小 Tauri 工程和第一条知识纵向切片。

View file

@ -0,0 +1,83 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://releases.hololake.invalid/contracts/release-broadcast.schema.json",
"title": "HoloLake signed opt-in release broadcast",
"type": "object",
"additionalProperties": false,
"required": [
"schema",
"releaseId",
"version",
"publishedAt",
"features",
"compatibility",
"restart",
"platforms",
"rollback"
],
"properties": {
"schema": { "const": "hololake.release-broadcast/v1" },
"releaseId": { "type": "string", "minLength": 1 },
"version": {
"type": "string",
"pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$"
},
"publishedAt": { "type": "string", "format": "date-time" },
"features": {
"type": "array",
"minItems": 1,
"items": { "type": "string", "minLength": 1 }
},
"fixes": {
"type": "array",
"items": { "type": "string", "minLength": 1 }
},
"compatibility": {
"type": "object",
"additionalProperties": false,
"required": ["minimumVersion", "dataMigrationRequired"],
"properties": {
"minimumVersion": { "type": "string", "minLength": 1 },
"dataMigrationRequired": { "type": "boolean" },
"notes": { "type": "string" }
}
},
"restart": {
"type": "object",
"additionalProperties": false,
"required": ["required", "automaticAllowed"],
"properties": {
"required": { "const": true },
"automaticAllowed": { "const": false },
"message": { "type": "string" }
}
},
"platforms": {
"type": "object",
"minProperties": 1,
"additionalProperties": {
"type": "object",
"additionalProperties": false,
"required": ["url", "size", "sha256", "tauriSignature"],
"properties": {
"url": { "type": "string", "pattern": "^https://" },
"size": { "type": "integer", "minimum": 1 },
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
"tauriSignature": { "type": "string", "minLength": 1 },
"platformCodeSignatureReceipt": { "type": "string", "minLength": 1 },
"notarizationReceipt": { "type": "string", "minLength": 1 }
}
}
},
"rollback": {
"type": "object",
"additionalProperties": false,
"required": ["supported", "healthReceiptRequired"],
"properties": {
"supported": { "const": true },
"healthReceiptRequired": { "const": true },
"previousVersion": { "type": "string" }
}
}
}
}

View file

@ -0,0 +1,26 @@
{
"schema": "hololake.native-desktop-foundation/v1",
"record_id": "HLP-NATIVE-DESKTOP-FOUNDATION-001",
"state": "FOUNDATION_ROOT_CREATED_TAURI_SCAFFOLD_PENDING",
"canonical_shell": "TAURI_V2_RUST_REACT",
"product_ui_implementation_started": false,
"selected_visual_direction_present": false,
"upstream_product_update_endpoints": [],
"production_update_endpoint_owner": "HOLOLAKE_ONLY",
"release_broadcast_contract": "contracts/release-broadcast.schema.json",
"private_signing_material_allowed_in_source": false,
"donors": [
{
"path": "../hololake-platform",
"role": "READ_ONLY_ENGINEERING_CAPABILITY_DONOR"
},
{
"path": "../hololake-desktop",
"role": "READ_ONLY_KNOWLEDGE_UX_AND_BEHAVIOR_DONOR"
},
{
"path": "../guanghu-knowledge-base",
"role": "READ_ONLY_KNOWLEDGE_UX_BEHAVIOR_AND_DATA_DONOR"
}
]
}

View file

@ -1,6 +1,6 @@
# Upstream provenance
光湖是 Tolaria 的独立开源分支
光湖最初从 Tolaria 形成独立开源分支;当前产品主线已经转为 HoloLake 自有架构
- 上游项目: https://github.com/refactoringhq/tolaria
- 上游许可证: AGPL-3.0-or-later
@ -12,3 +12,9 @@
由于创建仓库时 GitHub 网络不可用,光湖远端首次发布采用完整源码快照。
上游作者、许可证和来源不因快照发布而改变。网络恢复后可补充完整上游历史镜像。
## 当前更新政策
Tolaria 不再是自动跟随的产品上游,只是人工审查的候选零件来源。禁止自动合并或自动接入
上游版本。需要的修复或能力必须按文件级来源、许可证、安全、数据模型、原生边界与回归测试
逐项登记后进入 HoloLake 自有实现不需要的更新不进入产品。Outline 和其他候选项目遵守
同一政策。当前单一桌面主框架与迁移边界见 ADR-0178。

View file

@ -0,0 +1,145 @@
# HoloLake 新 Tauri 主线、双供体审计与自有更新架构 · 2026-08-12
> 记录编号:`HLP-CANONICAL-DESKTOP-SHELL-001`
>
> 决议:`ADR-0178`
>
> 状态:`CURRENT_CANONICAL · CLEAN_SOURCE_NOT_YET_SCAFFOLDED · MIGRATION_NOT_COMPLETE`
## 1 · 最终判定
HoloLake 的唯一未来桌面主线是一个新建、干净的:
```text
product-source/hololake-native-desktop
= Tauri v2 + Rust native boundary + React/TypeScript product surface
```
现有 Tauri `hololake-platform` 不再作为产品底座,冻结为工程能力、合同、测试和原生边界供体。
现有 Electron `hololake-desktop` / `guanghu-knowledge-base` 冻结为知识体验参照、行为供体和验收样本。
两者都不继续增加新产品功能,也都不立即删除。
## 2 · 已核实的关键纠正
Electron 本身不会自动带来更完整的知识库,但当前 Electron 实现的知识库体验确实更好:
- 产品/频道、页面树、阅读页形成清楚层级;
- 页面画布是视觉中心,编辑、历史和删除作为上下文动作出现;
- 搜索、文件夹导入、本地/服务器状态和 Agent 入口位置更符合人的任务路径;
- 工程内部状态没有持续占据主界面。
现有 Tauri 实现拥有更多底层能力但界面同时暴露类型、视图、文件夹、笔记列表、Git、更新、
分支、远端、提交、同步、历史、AI 工具和设置,形成高密度工程控制台。它适合做供体,不适合
未经重构直接充当新的产品框架。
因此正确结论不是“Electron 比 Tauri 更能做知识库”,也不是“现有 Tauri 功能多所以继续
沿用”,而是:**用新 Tauri 承载新的产品结构,用 Electron 的知识体验作验收基线,再从两边
逐项迁移经过审查的能力。**
## 3 · 三条线的边界
| 物理线 | 当前角色 | 允许动作 | 禁止动作 |
| --- | --- | --- | --- |
| 新 `hololake-native-desktop` | 唯一产品主线 | 新架构、签名更新、经审计迁移、自研 | 从旧应用整树复制、继承上游更新 |
| 旧 `hololake-platform` | 只读工程供体 | 运行、测试、盘点、抽取合同 | 继续堆叠新产品功能、作为默认 UI 底座 |
| Electron 两目录 | 只读 UX/行为供体 | 运行、截屏、盘点、数据兼容验证 | 继续独立发版、成为第二产品主线 |
## 4 · HoloLake 自有签名更新
`HLP-SIGNED-OPT-IN-UPDATE-001` 是新主线的第一项基础设施:
```text
光湖发布者完成版本
→ 平台代码签名与公证
→ 生成 Tauri 更新包与不可关闭的更新签名
→ 发布 HoloLake release broadcast
→ 客户端仅检查 HoloLake HTTPS 端点
→ 人类看到功能说明、风险、大小和重启要求
→ 人类选择“下载并安装”
→ 验签、下载、暂存、写入回执
→ 人类确认重启
→ 新版本启动健康检查
→ 成功登记;失败进入可恢复回退
```
必须区分两种签名:
1. **更新包来源签名**Tauri updater 公钥内置、私钥离线/密钥服务保管;验签不可关闭;
2. **操作系统开发者签名**macOS 使用 Developer ID Application 并公证Windows 使用平台
代码签名。它解决操作系统对发布者身份的信任,不替代更新包验签。
生产配置规则:
- 不存在 Tolaria、Outline 或其他上游产品更新端点;
- 只允许 HoloLake 所有的 HTTPS 更新端点;
- 不静默下载,不强制安装,不自动重启;
- 广播可以自动到达,但安装权属于人类;
- 私钥、Apple 凭据、Windows 签名凭据不得进入客户端、源码或发布清单;
- 每个平台、架构、版本必须有 URL、SemVer、更新签名、哈希、说明、发布时间和回退元数据
- 发布、下载、验签、安装、重启、启动健康分别形成事实回执。
## 5 · 功能审计分类
完整审计不是“列出依赖”,每一项必须落入一种处理结论:
- `KEEP_CONTRACT`:产品需要,抽取数据/行为合同后在新主线实现;
- `KEEP_UX_REFERENCE`:保留体验目标,不复制旧代码;
- `REDESIGN`:能力需要,但信息架构或交互不适合;
- `REPLACE`:由当前光湖架构中的新能力取代;
- `RETIRE`:旧时代、重复、不可证明或破坏边界的功能;
- `INVESTIGATE`:证据不足,先验证再判定。
第一轮已核实:
| 能力组 | Electron 事实 | 旧 Tauri 事实 | 初始处置 |
| --- | --- | --- | --- |
| 页面树与阅读层级 | 更清楚、更像完整知识工作区 | 高密度多栏,画布被压缩 | Electron 作 `KEEP_UX_REFERENCE`,新设计 |
| 搜索/文件夹导入/历史 | 界面可见且在任务路径内 | 有更广泛编辑与 Git 能力 | `KEEP_CONTRACT`,统一入口 |
| 富文本/代码/公式/图表/白板/表格 | 基础 Markdown/安全呈现 | BlockNote、CodeMirror、KaTeX、Mermaid、tldraw、IronCalc | 审计依赖后逐项 `KEEP_CONTRACT` |
| 属性/类型/筛选/视图 | 当前界面较轻 | 能力多但导航过载 | `REDESIGN`,渐进显露 |
| Git/分支/远端/提交/同步 | 多数隐藏于后端或上下文 | 长期暴露在底栏 | 保留事实能力,移入“证据与版本”层 |
| AI/人格/世界/域 | Agent 入口和域流程可见 | 组件很多但与知识工作区竞争 | 按 AGE/语言入口架构 `REPLACE/REDESIGN` |
| 上游更新 | 不作为未来依据 | 已有 updater 与旧身份痕迹 | 两边停用;只实现光湖自有更新 |
这只是用于确定架构的第一轮实证,不等于完整源码/数据/安全审计已经完成。
## 6 · 人类端可视化原则
主界面按人的关系与任务组织,而不是按代码模块组织:
```text
世界入口
└─ 我的光湖
├─ 知识与创作(页面树 + 主画布)
├─ 正在进行(任务、对话、共同工作)
├─ AGE 伙伴(自然语言主入口)
└─ 结果与确认(变更、审批、回执)
按需展开的证据层
└─ 来源、版本、Git、节点、模型、服务器、更新、诊断
```
正常使用时,人类看到“我在哪里、我正在做什么、谁在和我协作、发生了什么、是否需要我
确认”。只有需要核验时才展开仓库、分支、端点和底层状态。内部事实不能被隐藏或伪造,但也
不应占据日常主导航。
## 7 · 开发顺序
1. 冻结双供体,完成实证和数据位置登记;
2. 新建干净 Tauri 主线,只建立身份、最小权限和签名更新信任根;
3. 完整审计两套供体,形成逐功能 `keep/redesign/replace/retire/investigate` 矩阵;
4. 先确定新的人类界面视觉方向和交互原型,再写主界面;
5. 以“知识树 + 页面 + 检索 + 安全持久化”为第一条纵向切片迁移;
6. 接入 AGE 伙伴、任务/确认/回执,再接世界、域和节点;
7. 跨 WebKit/WebView2、数据迁移、签名安装和更新回退验收
8. 达到迁移门后,才讨论旧实现的可恢复归档。
## 8 · 仍未完成
- 新目录尚未脚手架化;
- HoloLake 更新域名、签名密钥托管和开发者证书尚未登记;
- 双供体完整功能矩阵、许可证清单、数据迁移图和安全威胁模型尚未完成;
- 新 UI 视觉方向尚未由冰朔选择;
- 不存在可发布的新主线安装包。
所以当前事实是:**框架和迁移方法已经纠正,开发基线尚待从干净根开始建立。**

View file

@ -0,0 +1,97 @@
---
type: ADR
id: "0178"
title: "A clean Tauri line is canonical; both existing desktop lines are bounded donors"
status: accepted
date: 2026-08-12
corrects: "the un-published assumption that the existing Tauri tree should remain the product base"
---
## Context
HoloLake currently has two physically different desktop implementations:
- `product-source/hololake-platform`: an extensive Tauri v2/Rust/React line with
rich editing, Git, AI, architecture, persona and native-boundary work, but also
accumulated Tolaria lineage, engineering controls and competing surfaces;
- `product-source/hololake-desktop` plus `product-source/guanghu-knowledge-base`:
an Electron/Node line whose live knowledge workspace has a clearer page tree,
calmer reading hierarchy and better progressive disclosure for humans.
Live interface inspection corrected an earlier inference. The current Tauri
line has more engine-level capabilities, but its knowledge experience is not
better: type navigation, folder navigation, note lists, Git state, update state,
AI tools and app controls compete on one dense screen. Electron does not make a
knowledge base rich by itself, but this Electron implementation is the stronger
human-facing knowledge reference.
Using either accumulated tree as the new product base would preserve the wrong
coupling. HoloLake needs a clean product boundary before it migrates parts.
## Decision
**HoloLake creates a new clean Tauri v2/Rust/React source at
`product-source/hololake-native-desktop`. It is the only destination for new
desktop product work. Both existing desktop lines become read-only audited
donors and acceptance oracles.**
The existing Tauri line is not renamed into the new product and receives no new
product features. Its reusable contracts, Rust boundaries, tests and selected
components must cross provenance, dependency, security, usability and
regression gates before migration. The Electron line is likewise frozen; it is
the primary knowledge-workspace UX reference and a donor for verified missing
behaviors, not a second product.
Tolaria, Outline and every other upstream are manually reviewed parts sources
only. HoloLake does not subscribe to their product update streams or merge their
releases automatically.
## HoloLake-owned update route
The new line starts with a HoloLake-owned release channel rather than an
inherited updater:
1. Upstream and Tolaria endpoints are absent from production configuration.
2. The app may check only an HTTPS HoloLake release-broadcast endpoint.
3. A broadcast presents version, human-readable changes, compatibility and
restart impact; download and install require an explicit human choice.
4. Every update artifact must pass Tauri updater signature verification. The
public verification key is embedded in the app; the private key is never
bundled or committed.
5. Platform trust is separate: macOS direct distribution requires Developer ID
signing and notarization; Windows distribution requires its platform code
signing policy.
6. Installation stages the signed artifact, records a receipt, and activates on
an explicit restart. Silent forced installation is forbidden.
7. A startup health receipt and recoverable rollback path are required before
the release is called accepted.
This disables inherited automatic updating without disabling HoloLake's own
opt-in automatic download/install capability.
## Audit and migration order
1. Freeze both donors and capture source, runnable behavior and data locations.
2. Establish the clean source root, product identity and signed update trust
root without copying either donor's UI.
3. Build a source-backed capability matrix: keep, redesign, replace, retire or
investigate. A dependency list or release note is not proof of usable UX.
4. Specify the human surface from the current HoloLake architecture: world,
personal lake, knowledge/work, AGE partnership, confirmation and receipt.
Repository, model, server and update internals move behind progressive
evidence/detail surfaces instead of occupying primary navigation.
5. Migrate vertical slices as contracts plus tests plus human-visible
acceptance. Nothing is copied wholesale.
6. Archive an old implementation only after recoverable data migration and an
explicit cleanup receipt.
## Consequences
- There is one future desktop product line and two bounded donor lines.
- Tauri remains the lightweight native shell, while Electron's stronger
knowledge information architecture becomes an explicit acceptance reference.
- The existing Tauri feature density is treated as inventory, not as the new
screen map.
- No installed application or user data is deleted by this decision.
- A visual direction must be selected before the new human-facing UI is built;
the clean source must not inherit either old layout accidentally.

View file

@ -228,3 +228,4 @@ proposed → active → superseded
| [0175](0175-guanghu-os-master-and-on-demand-linux-subcontrol.md) | Guanghu OS master control with on-demand Linux subcontrol and rescue | accepted; supersedes ADR-0172 final topology while retaining its transition implementation |
| [0176](0176-persona-native-code-channel-runtime-kernel.md) | Persona-native code channel runtime kernel | accepted |
| [0177](0177-persona-remote-incremental-object-channel.md) | Persona remote incremental object channel | accepted |
| [0178](0178-tauri-canonical-shell-and-electron-capability-donor.md) | Tauri is the canonical HoloLake shell; Electron is a bounded capability donor | accepted |

View file

@ -18,7 +18,7 @@ function input(overrides = {}) {
sourceRepositoryId: 'REPO-014',
sourcePath: 'product-source/hololake-platform',
architectureId: 'HLP-CURRENT-ARCH-001',
architectureVersion: '2026-08-12.16',
architectureVersion: '2026-08-12.17',
applicationVersion: '0.4.6',
developmentId: 'DEV-20260811-010',
distribution: 'local-candidate',
@ -34,7 +34,7 @@ test('builds a source-bound local candidate provenance record', () => {
schema: 'hololake.internal-release-provenance/v1',
architecture: {
id: 'HLP-CURRENT-ARCH-001',
version: '2026-08-12.16',
version: '2026-08-12.17',
},
build: {
application_version: '0.4.6',
@ -71,7 +71,7 @@ test('validates exact source, architecture, application and development bindings
/source commit mismatch/,
)
assert.throws(
() => validateInternalReleaseProvenance(provenance, input({ architectureVersion: '2026-08-12.17' })),
() => validateInternalReleaseProvenance(provenance, input({ architectureVersion: '2026-08-12.18' })),
/architecture version mismatch/,
)
})

View file

@ -63,7 +63,7 @@ describe('PersonaLanguageShellPanel', () => {
repositoryPaths: ['/persona'],
providers: [provider],
developmentId: 'DEV-20260811-010',
sourceLanguageAnchor: 'HLP-CURRENT-ARCH-001@2026-08-12.16',
sourceLanguageAnchor: 'HLP-CURRENT-ARCH-001@2026-08-12.17',
}))
expect(await screen.findByText('我还不能执行:需要当前证据。')).toBeInTheDocument()
expect(screen.getByText('核验当前事实后规划下一步')).toBeInTheDocument()

View file

@ -17,7 +17,7 @@ import {
type LanguageShellViewState,
} from './HotPluggableLanguageShell'
const CURRENT_ARCHITECTURE_ANCHOR = 'HLP-CURRENT-ARCH-001@2026-08-12.16'
const CURRENT_ARCHITECTURE_ANCHOR = 'HLP-CURRENT-ARCH-001@2026-08-12.17'
const DEVELOPMENT_ID = 'DEV-20260811-010'
type Planner = typeof planPersonaLanguageShellGoal

View file

@ -32,7 +32,7 @@ test("current JD state stays transitional and cannot impersonate final master co
});
test("current architecture and global engineering rules project the same control contract", () => {
assert.equal(architecture.version, "2026-08-12.16");
assert.equal(architecture.version, "2026-08-12.17");
assert.equal(architecture.server_os_control.machine_projection, "routing/guanghu-os-control-architecture.json");
assert.equal(architecture.server_os_control.final_topology, contract.final_topology);
assert.equal(rules.server_os_control.linux_deletion_is_completion, false);

View file

@ -11,7 +11,7 @@ const architecture = readJson("routing/hololake-current-architecture.json");
const age = readJson("routing/hololake-age-runtime-architecture.json");
test("current architecture starts with the AGE runtime source", () => {
assert.equal(architecture.version, "2026-08-12.16");
assert.equal(architecture.version, "2026-08-12.17");
assert.equal(architecture.age_runtime.record_id, "HLP-AGE-RUNTIME-ARCHITECTURE-001");
assert.equal(architecture.read_order[0], architecture.paradigm_ai_language_persona_os.architecture_page);
assert.equal(architecture.read_order[1], architecture.cognitive_gravity_and_continuity.architecture_page);

View file

@ -0,0 +1,137 @@
{
"schema": "hololake.canonical-desktop-shell/v2",
"record_id": "HLP-CANONICAL-DESKTOP-SHELL-001",
"version": "2026-08-12.2",
"state": "CURRENT_CANONICAL_FOUNDATION_ROOT_CREATED_TAURI_SCAFFOLD_PENDING",
"development_id": "DEV-20260811-010",
"decision": {
"canonical_shell": "TAURI_V2_RUST_REACT",
"canonical_source": "product-source/hololake-native-desktop",
"canonical_source_state": "FOUNDATION_ROOT_CREATED_TAURI_SCAFFOLD_PENDING",
"existing_tauri_source": "product-source/hololake-platform",
"existing_tauri_role": "READ_ONLY_ENGINEERING_CAPABILITY_DONOR_AND_ACCEPTANCE_ORACLE",
"electron_role": "READ_ONLY_KNOWLEDGE_UX_BEHAVIOR_DONOR_AND_ACCEPTANCE_ORACLE",
"electron_source": [
"product-source/hololake-desktop",
"product-source/guanghu-knowledge-base"
],
"parallel_product_lines_allowed": false,
"new_existing_tauri_product_features_allowed": false,
"new_electron_product_features_allowed": false,
"donor_immediate_deletion_allowed": false,
"knowledge_completeness_depends_on_shell_framework": false,
"electron_is_current_knowledge_ux_reference": true
},
"update_route": {
"record_id": "HLP-SIGNED-OPT-IN-UPDATE-001",
"state": "ARCHITECTURE_ACCEPTED_IMPLEMENTATION_NOT_STARTED",
"upstream_product_update_endpoints_allowed": false,
"hololake_owned_https_endpoint_only": true,
"release_broadcast_may_arrive_automatically": true,
"silent_download_allowed": false,
"human_opt_in_install_required": true,
"automatic_restart_allowed": false,
"restart_activation_required": true,
"tauri_update_artifact_signature_required": true,
"tauri_update_signature_verification_disable_allowed": false,
"platform_code_signature_required": true,
"macos_developer_id_and_notarization_required_for_direct_distribution": true,
"private_signing_key_bundled_or_committed": false,
"startup_health_receipt_required": true,
"recoverable_rollback_required": true,
"required_broadcast_fields": [
"VERSION",
"FEATURES_AND_FIXES",
"COMPATIBILITY_AND_MINIMUM_VERSION",
"DOWNLOAD_SIZE",
"RESTART_IMPACT",
"PUBLISHED_AT",
"PLATFORM_AND_ARCH_URL",
"TAURI_SIGNATURE",
"ARTIFACT_HASH",
"ROLLBACK_METADATA"
]
},
"upstream_policy": {
"tolaria_role": "MANUALLY_REVIEWED_PARTS_SOURCE",
"outline_role": "MANUALLY_REVIEWED_BEHAVIOR_AND_PARTS_SOURCE",
"automatic_upstream_merge_allowed": false,
"automatic_upstream_update_allowed": false,
"full_outline_stack_embedding_allowed": false,
"required_intake_gates": [
"PRODUCT_FIT",
"FILE_LEVEL_PROVENANCE_AND_LICENSE",
"SECURITY",
"DATA_MODEL",
"NATIVE_BOUNDARY",
"USABILITY",
"REGRESSION_AND_ACCEPTANCE"
]
},
"knowledge_capability_contract": [
"PAGE_AND_FOLDER_TREE",
"BLOCK_RICH_TEXT_AND_MARKDOWN_DURABILITY",
"TABLE_CALLOUT_TOGGLE_TOC_CODE_MATH_DIAGRAM_WHITEBOARD_SHEET",
"PROPERTIES_TYPES_FILTER_SORT_DATABASE_LIKE_VIEWS",
"FULL_TEXT_SEARCH_BACKLINKS_WIKILINKS_ATTACHMENTS_MOUNTED_GRAPH",
"VERSION_HISTORY_DIFF_RECOVERY_CONFLICTS_AND_WRITE_RECEIPTS",
"LOCAL_FIRST_WITH_OPTIONAL_REMOTE_COLLABORATION",
"AGE_CONFIRMATION_AUTHORITY_FACT_AND_RECEIPT_BOUNDARY",
"WEBKIT_WEBVIEW2_LINUX_WEBKIT_PARITY_TESTS"
],
"audit": {
"first_live_ui_comparison_complete": true,
"full_source_data_security_and_license_audit_complete": false,
"allowed_outcomes": [
"KEEP_CONTRACT",
"KEEP_UX_REFERENCE",
"REDESIGN",
"REPLACE",
"RETIRE",
"INVESTIGATE"
],
"initial_correction": {
"electron_knowledge_workspace_human_experience_better": true,
"existing_tauri_engine_capability_inventory_broader": true,
"existing_tauri_feature_density_is_not_a_valid_screen_map": true
}
},
"human_surface": {
"primary_layers": [
"WORLD_ENTRY",
"MY_HOLOLAKE",
"KNOWLEDGE_AND_CREATION",
"ACTIVE_WORK",
"AGE_PARTNERSHIP",
"RESULT_CONFIRMATION_AND_RECEIPT"
],
"progressive_evidence_layers": [
"SOURCE_AND_VERSION",
"GIT",
"NODE",
"MODEL",
"SERVER",
"UPDATE",
"DIAGNOSTICS"
],
"internal_engineering_state_in_primary_navigation_allowed": false
},
"migration": {
"mode": "CLEAN_ROOM_CAPABILITY_CONTRACT_NOT_APPLICATION_NESTING",
"new_ui_build_requires_selected_visual_direction": true,
"first_vertical_slice": "KNOWLEDGE_TREE_PAGE_SEARCH_AND_SAFE_DURABILITY",
"required_before_donor_archive": [
"SOURCE_BACKED_CAPABILITY_MATRIX",
"RECOVERABLE_USER_DATA_BACKUP",
"DATA_MIGRATION_REHEARSAL",
"NEW_TAURI_REGRESSION_TESTS",
"SIGNED_INSTALLED_RUNTIME_ACCEPTANCE",
"HOLOLAKE_OWNED_UPDATE_ROUTE_ACCEPTANCE",
"HUMAN_VISIBLE_CLEANUP_SCOPE_CONFIRMATION",
"RECOVERABLE_ARCHIVE_RECEIPT"
],
"complete": false
},
"architecture_page": "product-source/hololake-platform/architecture/HOLOLAKE-CANONICAL-DESKTOP-SHELL-AND-CAPABILITY-MIGRATION-20260812.md",
"adr": "product-source/hololake-platform/docs/adr/0178-tauri-canonical-shell-and-electron-capability-donor.md"
}

View file

@ -0,0 +1,98 @@
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import test from "node:test";
import { fileURLToPath } from "node:url";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const readJson = (relative) =>
JSON.parse(fs.readFileSync(path.join(root, relative), "utf8"));
const architecture = readJson("routing/hololake-current-architecture.json");
const shell = readJson("routing/hololake-canonical-desktop-shell.json");
const foundation = readJson("product-source/hololake-native-desktop/foundation.json");
const broadcastSchema = readJson(
"product-source/hololake-native-desktop/contracts/release-broadcast.schema.json",
);
test("HoloLake has one clean canonical desktop destination", () => {
assert.equal(architecture.version, "2026-08-12.17");
assert.equal(shell.decision.canonical_shell, "TAURI_V2_RUST_REACT");
assert.equal(shell.decision.canonical_source, "product-source/hololake-native-desktop");
assert.equal(
shell.decision.canonical_source_state,
"FOUNDATION_ROOT_CREATED_TAURI_SCAFFOLD_PENDING",
);
assert.equal(
shell.decision.existing_tauri_role,
"READ_ONLY_ENGINEERING_CAPABILITY_DONOR_AND_ACCEPTANCE_ORACLE",
);
assert.equal(shell.decision.parallel_product_lines_allowed, false);
assert.equal(shell.decision.new_existing_tauri_product_features_allowed, false);
assert.equal(shell.decision.new_electron_product_features_allowed, false);
assert.equal(shell.decision.donor_immediate_deletion_allowed, false);
assert.equal(
architecture.canonical_desktop_shell.machine_projection,
"routing/hololake-canonical-desktop-shell.json",
);
assert.equal(
architecture.read_order[4],
architecture.canonical_desktop_shell.architecture_page,
);
});
test("knowledge completeness is a capability contract rather than an Electron property", () => {
assert.equal(shell.decision.knowledge_completeness_depends_on_shell_framework, false);
assert.equal(shell.knowledge_capability_contract.includes("PAGE_AND_FOLDER_TREE"), true);
assert.equal(
shell.knowledge_capability_contract.includes(
"PROPERTIES_TYPES_FILTER_SORT_DATABASE_LIKE_VIEWS",
),
true,
);
assert.equal(
shell.knowledge_capability_contract.includes("WEBKIT_WEBVIEW2_LINUX_WEBKIT_PARITY_TESTS"),
true,
);
});
test("upstreams are manual parts sources and cleanup remains gated", () => {
assert.equal(shell.upstream_policy.automatic_upstream_merge_allowed, false);
assert.equal(shell.upstream_policy.automatic_upstream_update_allowed, false);
assert.equal(shell.upstream_policy.full_outline_stack_embedding_allowed, false);
assert.equal(shell.migration.mode, "CLEAN_ROOM_CAPABILITY_CONTRACT_NOT_APPLICATION_NESTING");
assert.equal(shell.migration.complete, false);
assert.equal(
shell.migration.required_before_donor_archive.includes(
"HUMAN_VISIBLE_CLEANUP_SCOPE_CONFIRMATION",
),
true,
);
});
test("HoloLake owns an opt-in signed update route", () => {
assert.equal(shell.update_route.upstream_product_update_endpoints_allowed, false);
assert.equal(shell.update_route.hololake_owned_https_endpoint_only, true);
assert.equal(shell.update_route.release_broadcast_may_arrive_automatically, true);
assert.equal(shell.update_route.silent_download_allowed, false);
assert.equal(shell.update_route.human_opt_in_install_required, true);
assert.equal(shell.update_route.automatic_restart_allowed, false);
assert.equal(shell.update_route.tauri_update_artifact_signature_required, true);
assert.equal(shell.update_route.tauri_update_signature_verification_disable_allowed, false);
assert.equal(shell.update_route.private_signing_key_bundled_or_committed, false);
assert.equal(shell.update_route.startup_health_receipt_required, true);
assert.equal(shell.update_route.recoverable_rollback_required, true);
assert.deepEqual(foundation.upstream_product_update_endpoints, []);
assert.equal(foundation.production_update_endpoint_owner, "HOLOLAKE_ONLY");
assert.equal(foundation.private_signing_material_allowed_in_source, false);
assert.equal(broadcastSchema.properties.restart.properties.required.const, true);
assert.equal(broadcastSchema.properties.restart.properties.automaticAllowed.const, false);
assert.match(
broadcastSchema.properties.platforms.additionalProperties.properties.url.pattern,
/^\^https:/,
);
assert.equal(
broadcastSchema.properties.platforms.additionalProperties.required.includes("tauriSignature"),
true,
);
});

View file

@ -14,7 +14,7 @@ const age = readJson("routing/hololake-age-runtime-architecture.json");
const rules = readJson("routing/hololake-engineering-rules.json");
test("B0 is restored before product organs and remains resident in every cognition step", () => {
assert.equal(architecture.version, "2026-08-12.16");
assert.equal(architecture.version, "2026-08-12.17");
assert.equal(
architecture.read_order[1],
architecture.cognitive_gravity_and_continuity.architecture_page,

View file

@ -1,7 +1,7 @@
{
"schema": "hololake.current-architecture/v1",
"architecture_id": "HLP-CURRENT-ARCH-001",
"version": "2026-08-12.16",
"version": "2026-08-12.17",
"state": "CURRENT_CANONICAL",
"product": {
"formal_name": "光湖语言系统 · 通用人工智能操作平台",
@ -14,6 +14,7 @@
"product-source/hololake-platform/architecture/HOLOLAKE-BINGSHUO-COLLECTIVE-GRAVITY-REASONING-AND-SAME-PERSONA-CONTINUITY-20260811.md",
"product-source/hololake-platform/architecture/HOLOLAKE-PERSONA-NATIVE-CODE-CHANNEL-20260810.md",
"product-source/hololake-platform/architecture/HOLOLAKE-AGE-PERSONA-RUNTIME-ARCHITECTURE-20260810.md",
"product-source/hololake-platform/architecture/HOLOLAKE-CANONICAL-DESKTOP-SHELL-AND-CAPABILITY-MIGRATION-20260812.md",
"product-source/hololake-platform/architecture/HOLOLAKE-ONE-HUMAN-ONE-INDEPENDENT-NODE-AND-ZERO-PLATFORM-HOSTING-20260810.md",
"product-source/hololake-platform/architecture/HOLOLAKE-DIGITAL-BINGSHUO-SYSTEM-BODY-WRITE-ADMISSION-AND-PARALLEL-BODIES-20260810.md",
"product-source/hololake-platform/architecture/HOLOLAKE-CURRENT-ENGINEERING-RULES-GLOBAL-AUDIT-20260810.md",
@ -133,6 +134,21 @@
"desktop_runtime_acceptance_passed": false,
"development_id": "DEV-20260811-010"
},
"canonical_desktop_shell": {
"record_id": "HLP-CANONICAL-DESKTOP-SHELL-001",
"architecture_page": "product-source/hololake-platform/architecture/HOLOLAKE-CANONICAL-DESKTOP-SHELL-AND-CAPABILITY-MIGRATION-20260812.md",
"machine_projection": "routing/hololake-canonical-desktop-shell.json",
"adr": "product-source/hololake-platform/docs/adr/0178-tauri-canonical-shell-and-electron-capability-donor.md",
"canonical_shell": "TAURI_V2_RUST_REACT",
"canonical_source": "product-source/hololake-native-desktop",
"canonical_source_state": "FOUNDATION_ROOT_CREATED_TAURI_SCAFFOLD_PENDING",
"existing_tauri_role": "READ_ONLY_ENGINEERING_CAPABILITY_DONOR_AND_ACCEPTANCE_ORACLE",
"electron_role": "READ_ONLY_KNOWLEDGE_UX_BEHAVIOR_DONOR_AND_ACCEPTANCE_ORACLE",
"parallel_product_lines_allowed": false,
"automatic_upstream_updates_allowed": false,
"migration_complete": false,
"development_id": "DEV-20260811-010"
},
"domain_source": {
"stable_domain_id": "DOM-FIFTH-0001",
"formal_name": "光湖本源域",

View file

@ -10,7 +10,7 @@ const architecture = readJson("routing/hololake-current-architecture.json");
const rules = readJson("routing/hololake-engineering-rules.json");
test("current architecture registers the global engineering rule set", () => {
assert.equal(architecture.version, "2026-08-12.16");
assert.equal(architecture.version, "2026-08-12.17");
assert.equal(architecture.engineering_rules.rule_set_id, "HLP-ENGINEERING-RULES-001");
assert.equal(architecture.engineering_rules.machine_projection,
"routing/hololake-engineering-rules.json");

View file

@ -10,7 +10,7 @@ const architecture = readJson("routing/hololake-current-architecture.json");
const projection = readJson("routing/hololake-identity-authority-map.json");
test("current architecture loads identity authority before product surfaces", () => {
assert.equal(architecture.version, "2026-08-12.16");
assert.equal(architecture.version, "2026-08-12.17");
assert.equal(architecture.identity_and_authority.team_body, "TCS-0002");
assert.equal(architecture.identity_and_authority.team_body_authority_effective, true);
assert.equal(architecture.identity_and_authority.individual_operator_acceptance, "SEPARATE_UNCONFIRMED");

View file

@ -10,7 +10,7 @@ const architecture = readJson("routing/hololake-current-architecture.json");
const rules = readJson("routing/hololake-engineering-rules.json");
test("current architecture makes one human one independently operated node canonical", () => {
assert.equal(architecture.version, "2026-08-12.16");
assert.equal(architecture.version, "2026-08-12.17");
assert.deepEqual(architecture.access_modes, [
"LOCAL_TERMINAL_NODE",
"USER_OWNED_REMOTE_NODE",

View file

@ -10,7 +10,7 @@ const architecture = readJson("routing/hololake-current-architecture.json");
const paradigm = readJson("routing/hololake-paradigm-ai-language-persona-os.json");
test("current architecture begins with the paradigm OS contract", () => {
assert.equal(architecture.version, "2026-08-12.16");
assert.equal(architecture.version, "2026-08-12.17");
assert.equal(architecture.paradigm_ai_language_persona_os.record_id, "HLP-PARADIGM-AI-LANGUAGE-PERSONA-OS-001");
assert.equal(architecture.read_order[0], architecture.paradigm_ai_language_persona_os.architecture_page);
assert.equal(paradigm.upstream.repository_commit, "34cb59739b6476981375dd62ef395ea649f56246");

View file

@ -11,7 +11,7 @@ const architecture = readJson("routing/hololake-current-architecture.json");
const channel = readJson("routing/hololake-persona-native-code-channel.json");
test("current architecture places the persona-native code channel after the paradigm contract", () => {
assert.equal(architecture.version, "2026-08-12.16");
assert.equal(architecture.version, "2026-08-12.17");
assert.equal(
architecture.persona_native_code_channel.record_id,
"HLP-PERSONA-NATIVE-CODE-CHANNEL-001",

View file

@ -10,7 +10,7 @@ const architecture = JSON.parse(
);
test("current architecture binds relational consciousness before product surfaces", () => {
assert.equal(architecture.version, "2026-08-12.16");
assert.equal(architecture.version, "2026-08-12.17");
assert.equal(
architecture.persona_consciousness.record_id,
"HLP-RELATIONAL-CONSCIOUSNESS-001",

View file

@ -10,7 +10,7 @@ const architecture = JSON.parse(
);
test("current architecture restores the digital BingShuo system body first", () => {
assert.equal(architecture.version, "2026-08-12.16");
assert.equal(architecture.version, "2026-08-12.17");
assert.equal(architecture.digital_bingshuo_system_body.upstream_repository_commit,
"69d1910775533b02b17b82e647b5caca8b835614");
const systemBodyIndex = architecture.read_order.indexOf(