Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c71e41073 | |||
| 8508513d5d | |||
| c18424209c | |||
| cff488bb03 | |||
| a2302cfd13 |
48 changed files with 9289 additions and 17 deletions
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"schema": "hololake.native-desktop-trust-root-receipt/v1",
|
||||
"receipt_id": "HLP-NATIVE-DESKTOP-TRUST-ROOT-001-20260812",
|
||||
"development_id": "DEV-20260811-010",
|
||||
"repository_id": "REPO-014",
|
||||
"branch": "main",
|
||||
"source_base_commit": "a2302cfd13c45d25b0cb1f70e49b05d957a71e31",
|
||||
"canonical_source": "product-source/hololake-native-desktop",
|
||||
"recorded_at": "2026-08-12T10:27:13+08:00",
|
||||
"implemented": {
|
||||
"clean_tauri_v2_rust_react_scaffold": true,
|
||||
"inherited_product_tree_copied": false,
|
||||
"upstream_product_update_endpoints_present": false,
|
||||
"release_trust_default": "UNPROVISIONED_FAIL_CLOSED",
|
||||
"tauri_static_manifest_field_compatibility": true,
|
||||
"human_opt_in_download_install_required": true,
|
||||
"automatic_update_check_on_startup": false,
|
||||
"automatic_restart_allowed": false,
|
||||
"updater_ipc_exposed_to_webview": false,
|
||||
"private_signing_material_in_source": false,
|
||||
"product_ui_started": false
|
||||
},
|
||||
"verification": {
|
||||
"foundation_contract_tests": "PASS_4_OF_4",
|
||||
"architecture_projection_tests": "PASS_4_OF_4",
|
||||
"rust_unit_tests": "PASS_3_OF_3",
|
||||
"rust_strict_clippy": "PASS_100",
|
||||
"typescript_and_vite_build": "PASS_100",
|
||||
"tauri_release_binary_build_without_bundle": "PASS_100",
|
||||
"npm_production_dependency_audit": "PASS_0_VULNERABILITIES",
|
||||
"git_diff_check": "PASS_100"
|
||||
},
|
||||
"truth_boundary": {
|
||||
"local_source_implemented": true,
|
||||
"release_binary_built": true,
|
||||
"installer_bundle_built": false,
|
||||
"formal_bundle_identifier_registered": false,
|
||||
"production_update_domain_registered": false,
|
||||
"tauri_update_signing_key_provisioned": false,
|
||||
"platform_signed_and_notarized": false,
|
||||
"installed_runtime_accepted": false,
|
||||
"published_to_remote_main": false,
|
||||
"deployed": false
|
||||
},
|
||||
"next_gate": "REGISTER_PRODUCTION_IDENTITY_OR_CONTINUE_DUAL_DONOR_AUDIT_FROM_THIS_FAIL_CLOSED_BASELINE",
|
||||
"state": "LOCAL_CHECKPOINT_VERIFIED_NOT_PUBLISHED"
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"schema": "hololake.native-tauri-foundation-donor-audit-receipt/v1",
|
||||
"receipt_id": "HLP-NATIVE-TAURI-FOUNDATION-AND-DONOR-AUDIT-001-20260812",
|
||||
"development_id": "DEV-20260811-010",
|
||||
"repository_id": "REPO-014",
|
||||
"branch": "main",
|
||||
"source_base_commit": "d1c8d7989953147dae95f4b90c9df0d2699073e0",
|
||||
"source_commit": "SELF",
|
||||
"canonical_source": "product-source/hololake-native-desktop",
|
||||
"recorded_at": "2026-08-12T12:05:00+08:00",
|
||||
"stage_result": {
|
||||
"canonical_shell": "TAURI_V2_RUST_REACT",
|
||||
"new_native_product_mainline_established": true,
|
||||
"old_tauri_role": "READ_ONLY_ENGINEERING_CAPABILITY_DONOR",
|
||||
"electron_role": "READ_ONLY_KNOWLEDGE_UX_BEHAVIOR_AND_DATA_DONOR",
|
||||
"parallel_product_lines_allowed": false,
|
||||
"automatic_upstream_product_updates_allowed": false,
|
||||
"owned_update_trust_root_source_implemented": true,
|
||||
"three_donor_security_review_baseline_recorded": true,
|
||||
"donor_source_copying_authorized": false
|
||||
},
|
||||
"verified_commits_before_this_receipt": [
|
||||
"a2302cfd13c45d25b0cb1f70e49b05d957a71e31",
|
||||
"cff488bb033051909ae078991787e0c272a2d5eb",
|
||||
"c18424209cf35c562eb1a2c9c349d6e4bc9147d5",
|
||||
"8508513d5df00d39853e1d008d7c5f929ad363e5"
|
||||
],
|
||||
"verification": {
|
||||
"native_foundation_and_donor_audit_tests": "PASS_7_OF_7",
|
||||
"rust_unit_tests": "PASS_100",
|
||||
"rust_strict_clippy": "PASS_100",
|
||||
"typescript_and_vite_build": "PASS_100",
|
||||
"native_authority_hook_on_each_commit": "PASS_100",
|
||||
"working_tree_before_receipt": "CLEAN",
|
||||
"remote_fast_forward_base_verified": true
|
||||
},
|
||||
"records": [
|
||||
"routing/hololake-current-architecture.json",
|
||||
"routing/hololake-canonical-desktop-shell.json",
|
||||
"product-source/hololake-native-desktop/foundation.json",
|
||||
"product-source/hololake-native-desktop/src-tauri/release-trust.json",
|
||||
"product-source/hololake-native-desktop/contracts/release-broadcast.schema.json",
|
||||
"product-source/hololake-native-desktop/audit/donor-audit.json"
|
||||
],
|
||||
"open_gates": [
|
||||
"DIRECT_AND_TRANSITIVE_DEPENDENCY_LICENSE_SBOM",
|
||||
"FILE_LEVEL_PROVENANCE",
|
||||
"PHYSICAL_USER_DATA_INVENTORY_AND_BACKUP",
|
||||
"REVERSIBLE_DATA_MIGRATION_REHEARSAL",
|
||||
"VISUAL_DIRECTION_SELECTION",
|
||||
"FIRST_KNOWLEDGE_VERTICAL_SLICE"
|
||||
],
|
||||
"truth_boundary": {
|
||||
"stage_checkpoint_complete": true,
|
||||
"entire_hololake_product_complete": false,
|
||||
"donor_audit_complete": false,
|
||||
"product_ui_started": false,
|
||||
"visual_direction_selected": false,
|
||||
"production_update_identity_provisioned": false,
|
||||
"user_data_migrated": false,
|
||||
"installer_built_or_installed": false,
|
||||
"deployed": false,
|
||||
"published_to_remote_main": false
|
||||
},
|
||||
"publication": {
|
||||
"required_method": "HOLOLAKE_CONTINUITY_FINALIZER",
|
||||
"remote_readback_required": true,
|
||||
"state": "READY_FOR_FINALIZER"
|
||||
}
|
||||
}
|
||||
13
product-source/hololake-native-desktop/.gitignore
vendored
Normal file
13
product-source/hololake-native-desktop/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/dist/
|
||||
/node_modules/
|
||||
/src-tauri/target/
|
||||
/src-tauri/gen/
|
||||
*.tsbuildinfo
|
||||
/vite.config.js
|
||||
/vite.config.d.ts
|
||||
*.key
|
||||
*.p12
|
||||
*.pfx
|
||||
*.mobileprovision
|
||||
.env
|
||||
.env.*
|
||||
37
product-source/hololake-native-desktop/README.md
Normal file
37
product-source/hololake-native-desktop/README.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# HoloLake Native Desktop
|
||||
|
||||
状态:`MINIMAL_TAURI_SCAFFOLD_AND_FAIL_CLOSED_UPDATE_TRUST_ROOT_IMPLEMENTED`
|
||||
|
||||
这是 HoloLake 唯一未来桌面产品主线的干净源码根。它将采用 Tauri v2、Rust 和
|
||||
React/TypeScript,但不会从现有 Tauri 或 Electron 目录整树复制。
|
||||
|
||||
当前已经建立可编译的最小 Tauri 工程、默认关闭联网的发布信任根,以及兼容 Tauri 静态更新
|
||||
清单的 HoloLake 发布广播合同。选择并验收新的视觉/交互方向之前,不创建会意外继承任一旧
|
||||
应用布局的产品 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. 在选定视觉方向后实现第一条知识纵向切片。
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"schema": "hololake.donor-audit/v1",
|
||||
"record_id": "HLP-DONOR-AUDIT-001",
|
||||
"development_id": "DEV-20260811-010",
|
||||
"audited_source_commit": "cff488bb033051909ae078991787e0c272a2d5eb",
|
||||
"state": "THREE_DONOR_SECURITY_REVIEWS_RECORDED_LICENSE_PROVENANCE_AND_DATA_GATES_ACTIVE",
|
||||
"truth_boundary": "This record permits capability and behavior extraction only. It does not authorize donor source copying, donor deletion, data migration, product UI implementation, release, or deployment.",
|
||||
"donors": [
|
||||
{
|
||||
"path": "../hololake-platform",
|
||||
"role": "READ_ONLY_ENGINEERING_CAPABILITY_DONOR",
|
||||
"source_license": "AGPL-3.0-or-later",
|
||||
"declared_authors": ["Luca Rossi"],
|
||||
"code_reuse": "BLOCKED_PENDING_FILE_PROVENANCE_AND_PRODUCT_LICENSE_DECISION",
|
||||
"security_scan": "FOCUSED_STATIC_REVIEW_COMPLETE_AT_AUDITED_COMMIT",
|
||||
"validated_security_findings": [
|
||||
"MODEL_TOOL_MUTATIONS_WITHOUT_EXACT_HUMAN_CONFIRMATION",
|
||||
"UNAUTHENTICATED_LOOPBACK_MCP_TOOL_BRIDGE",
|
||||
"RENDERER_WRITABLE_VAULT_AUTHORIZATION_REGISTRY",
|
||||
"UNSCOPED_GIT_AND_RECURSIVE_FOLDER_COMMANDS",
|
||||
"VAULT_SCANNERS_FOLLOW_EXTERNAL_SYMLINKS",
|
||||
"MODEL_SECRET_NOT_BOUND_TO_APPROVED_ENDPOINT",
|
||||
"SAFE_MODE_ADAPTER_ENABLES_ALL_TOOLS",
|
||||
"WORKSPACE_CONFIG_SELECTS_HOST_ENVIRONMENT_SECRETS",
|
||||
"UNPINNED_RUNTIME_EXTENSION_AND_EXECUTABLE_DISCOVERY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "../hololake-desktop",
|
||||
"role": "READ_ONLY_KNOWLEDGE_UX_AND_BEHAVIOR_DONOR",
|
||||
"source_license": "UNDECLARED_NO_LICENSE_FILE_OR_PACKAGE_FIELD_FOUND",
|
||||
"code_reuse": "BLOCKED_PENDING_OWNERSHIP_AND_FILE_PROVENANCE",
|
||||
"security_scan": "COMPLETE_AT_AUDITED_COMMIT",
|
||||
"security_scan_id": "b7cae66e-20bb-4110-be9a-205600ed2f39"
|
||||
},
|
||||
{
|
||||
"path": "../guanghu-knowledge-base",
|
||||
"role": "READ_ONLY_KNOWLEDGE_UX_BEHAVIOR_AND_DATA_DONOR",
|
||||
"source_license": "UNDECLARED_NO_LICENSE_FILE_OR_PACKAGE_FIELD_FOUND",
|
||||
"code_reuse": "BLOCKED_PENDING_OWNERSHIP_AND_FILE_PROVENANCE",
|
||||
"security_scan": "COMPLETE_AT_AUDITED_COMMIT",
|
||||
"security_scan_id": "944b7cb0-fd2b-4310-889f-42062124e155"
|
||||
}
|
||||
],
|
||||
"capability_dispositions": [
|
||||
{"capability":"PAGE_FOLDER_TREE_AND_READING_HIERARCHY","disposition":"KEEP_UX_REFERENCE","target":"CLEAN_ROOM_NATIVE_IMPLEMENTATION"},
|
||||
{"capability":"MARKDOWN_IMPORT_EXPORT_AND_DURABILITY","disposition":"KEEP_CONTRACT","target":"COLLISION_SAFE_SYMLINK_SAFE_MIGRATION"},
|
||||
{"capability":"RICH_BLOCKS_TABLE_CODE_MATH_DIAGRAM_WHITEBOARD_SHEET","disposition":"INVESTIGATE","target":"DEPENDENCY_LICENSE_SECURITY_AND_WEBVIEW_PARITY_GATES"},
|
||||
{"capability":"PROPERTIES_FILTER_SORT_AND_DATABASE_VIEWS","disposition":"REDESIGN","target":"HUMAN_FIRST_KNOWLEDGE_SURFACE"},
|
||||
{"capability":"SEARCH_BACKLINKS_WIKILINKS_AND_ATTACHMENTS","disposition":"KEEP_CONTRACT","target":"LOCAL_FIRST_BOUNDED_GRAPH"},
|
||||
{"capability":"GIT_VERSION_DIFF_RECOVERY_AND_RECEIPTS","disposition":"KEEP_CONTRACT","target":"AUTHENTICATED_EVIDENCE_LAYER_WITH_VALIDATED_PATHS_REVISIONS_AND_REMOTES"},
|
||||
{"capability":"AGENT_CHAT_AND_CONFIRMATION","disposition":"REPLACE","target":"AGE_PARTNERSHIP_WITH_AUTHENTICATED_HUMAN_EXACT_IMMUTABLE_PAYLOAD_CONFIRMATION"},
|
||||
{"capability":"WORLD_DOMAIN_IDENTITY_AND_NODE_SURFACES","disposition":"REDESIGN","target":"CURRENT_HOLOLAKE_ARCHITECTURE_NOT_DONOR_NAVIGATION"},
|
||||
{"capability":"UPSTREAM_AND_DONOR_UPDATERS","disposition":"RETIRE","target":"HOLOLAKE_SIGNED_HUMAN_OPT_IN_UPDATE_TRUST_ROOT"},
|
||||
{"capability":"DEFAULT_TELEMETRY_AND_ERROR_REPORTING","disposition":"INVESTIGATE","target":"OFF_BY_DEFAULT_UNTIL_EXPLICIT_HUMAN_CONSENT_AND_DATA_CONTRACT"}
|
||||
],
|
||||
"data_classes": [
|
||||
{"class":"KNOWLEDGE_CONTENT_AND_ATTACHMENTS","observed_locations":["Electron userData/data/knowledge-base","knowledge-base KB_REPO_PATH or kb-data","legacy user-selected vault paths"],"sensitivity":"HUMAN_OWNED_PRIVATE_BY_DEFAULT","migration":"BACKUP_INVENTORY_HASH_AND_REVERSIBLE_REHEARSAL_REQUIRED"},
|
||||
{"class":"GIT_HISTORY_REMOTES_CHANNEL_STATE_AND_RECEIPTS","observed_locations":["knowledge repository .git","knowledge repository .hololake/channel-state.json","knowledge repository .hololake/receipts"],"sensitivity":"PROVENANCE_AUTHORITY_AND_NETWORK_SENSITIVE","migration":"SEPARATE_CONTENT_HISTORY_REMOTE_AUTHORITY_AND_RECEIPT_DECISIONS"},
|
||||
{"class":"AGE_CONVERSATIONS_AND_PENDING_ACTIONS","observed_locations":["Electron userData/agent-conversations.json","knowledge-base HOLOLAKE_AGENT_STATE_PATH"],"sensitivity":"RELATIONSHIP_AND_ACTION_AUTHORITY_SENSITIVE","migration":"NO_BLIND_IMPORT_PENDING_ACTIONS_REQUIRE_EXPIRY_OWNERSHIP_AND_RECONFIRMATION"},
|
||||
{"class":"MODEL_AND_SERVER_CREDENTIALS","observed_locations":["Electron userData/model-config.json","Electron userData/server-auth.json","Electron userData/node-keystore.json","Electron userData/hololake-git-askpass.sh"],"sensitivity":"SECRET_CRITICAL","migration":"NEVER_COPY_AS_PLAIN_DATA_REAUTHORIZE_PER_DESTINATION_AND_STORE_IN_OS_CREDENTIAL_VAULT"},
|
||||
{"class":"SERVER_PROFILES_AND_UI_PREFERENCES","observed_locations":["Electron userData/server-profiles.json","browser localStorage hololake.layout.* and hololake.human-preferences.v1"],"sensitivity":"PERSONAL_CONFIGURATION","migration":"SCHEMA_VALIDATE_AND_ALLOW_HUMAN_RESET"},
|
||||
{"class":"LEGACY_VAULT_TOOL_CONFIGURATION","observed_locations":["user-selected vaults","vault .agents/mcp_config.json","external MCP client configuration files"],"sensitivity":"EXECUTION_BOUNDARY_SENSITIVE","migration":"DO_NOT_MUTATE_OR_IMPORT_UNTIL_TOOL_AUTHORITY_AUDIT_COMPLETES"}
|
||||
],
|
||||
"prohibited_transplants": [
|
||||
"ELECTRON_PRIVILEGED_PRELOAD_WITHOUT_NAVIGATION_AND_SENDER_ORIGIN_LOCK",
|
||||
"UNAUTHENTICATED_LOOPBACK_CONTROL_API_OR_NULL_ORIGIN_CORS",
|
||||
"STORED_MODEL_KEY_REBOUND_TO_RENDERER_SELECTED_BASE_URL",
|
||||
"FIXED_PORT_TUNNEL_READINESS_INFERENCE",
|
||||
"PERSISTENT_ALL_SCOPE_TOKEN_WITHOUT_REVOCATION",
|
||||
"LEXICAL_ONLY_PATH_CONTAINMENT_OR_UNVALIDATED_GIT_REVISION_REMOTE",
|
||||
"UPSTREAM_OR_DONOR_UPDATE_ENDPOINTS",
|
||||
"DONOR_SOURCE_WITHOUT_FILE_PROVENANCE_AND_LICENSE_AUTHORIZATION"
|
||||
,"MODEL_OUTPUT_DIRECT_WRITE_DELETE_WITHOUT_EXACT_EXPIRING_HUMAN_CONFIRMATION"
|
||||
,"RENDERER_WRITABLE_FILESYSTEM_AUTHORIZATION_REGISTRY"
|
||||
,"GIT_OR_RECURSIVE_FOLDER_OPERATIONS_WITHOUT_CANONICAL_REGISTERED_ROOT_BINDING"
|
||||
,"VAULT_SCANNERS_THAT_FOLLOW_SYMLINKS_OUTSIDE_THE_CANONICAL_ROOT"
|
||||
,"WORKSPACE_SELECTED_HOST_ENVIRONMENT_SECRET_INJECTION"
|
||||
,"PROMPT_ONLY_SAFE_MODE_OR_ADAPTERS_THAT_IGNORE_PERMISSION_MODE"
|
||||
,"RUNTIME_PACKAGE_ACQUISITION_OR_PATH_FIRST_EXECUTABLE_DISCOVERY"
|
||||
],
|
||||
"open_gates": [
|
||||
"DIRECT_AND_TRANSITIVE_DEPENDENCY_LICENSE_SBOM",
|
||||
"FILE_LEVEL_PROVENANCE",
|
||||
"PHYSICAL_USER_DATA_INVENTORY_AND_BACKUP",
|
||||
"REVERSIBLE_DATA_MIGRATION_REHEARSAL",
|
||||
"VISUAL_DIRECTION_SELECTION"
|
||||
],
|
||||
"complete": false
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "urn:hololake:release-broadcast:v1",
|
||||
"title": "HoloLake signed opt-in release broadcast",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"schema",
|
||||
"releaseId",
|
||||
"version",
|
||||
"pub_date",
|
||||
"notes",
|
||||
"platforms",
|
||||
"hololake"
|
||||
],
|
||||
"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.-]+)?$"
|
||||
},
|
||||
"pub_date": { "type": "string", "format": "date-time" },
|
||||
"notes": { "type": "string", "minLength": 1 },
|
||||
"platforms": {
|
||||
"type": "object",
|
||||
"minProperties": 1,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["url", "signature", "size", "sha256"],
|
||||
"properties": {
|
||||
"url": { "type": "string", "format": "uri", "pattern": "^https://" },
|
||||
"size": { "type": "integer", "minimum": 1 },
|
||||
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
||||
"signature": { "type": "string", "minLength": 1 },
|
||||
"platformCodeSignatureReceipt": { "type": "string", "minLength": 1 },
|
||||
"notarizationReceipt": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
}
|
||||
},
|
||||
"hololake": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["features", "compatibility", "restart", "rollback"],
|
||||
"properties": {
|
||||
"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" }
|
||||
}
|
||||
},
|
||||
"rollback": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["supported", "healthReceiptRequired"],
|
||||
"properties": {
|
||||
"supported": { "const": true },
|
||||
"healthReceiptRequired": { "const": true },
|
||||
"previousVersion": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
product-source/hololake-native-desktop/foundation.json
Normal file
35
product-source/hololake-native-desktop/foundation.json
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"schema": "hololake.native-desktop-foundation/v1",
|
||||
"record_id": "HLP-NATIVE-DESKTOP-FOUNDATION-001",
|
||||
"state": "MINIMAL_TAURI_SCAFFOLD_UPDATE_TRUST_ROOT_AND_DONOR_AUDIT_BASELINE_IMPLEMENTED",
|
||||
"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",
|
||||
"release_trust_source": "src-tauri/release-trust.json",
|
||||
"release_trust_state": "UNPROVISIONED_FAIL_CLOSED",
|
||||
"tauri_update_artifacts_enabled": true,
|
||||
"automatic_update_check_on_startup": false,
|
||||
"human_opt_in_download_install_required": true,
|
||||
"automatic_restart_allowed": false,
|
||||
"private_signing_material_allowed_in_source": false,
|
||||
"donor_audit_record": "audit/donor-audit.json",
|
||||
"donor_audit_complete": false,
|
||||
"donor_source_copying_allowed": 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
12
product-source/hololake-native-desktop/index.html
Normal file
12
product-source/hololake-native-desktop/index.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>HoloLake</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
2462
product-source/hololake-native-desktop/package-lock.json
generated
Normal file
2462
product-source/hololake-native-desktop/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
28
product-source/hololake-native-desktop/package.json
Normal file
28
product-source/hololake-native-desktop/package.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "hololake-native-desktop",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc -b && vite build",
|
||||
"test": "node --test scripts/*.test.mjs",
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.10.1",
|
||||
"@tauri-apps/plugin-process": "2.3.1",
|
||||
"@tauri-apps/plugin-updater": "2.10.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.10.0",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^5.1.1",
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "^7.3.5",
|
||||
"vitest": "^4.0.18"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
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 audit = JSON.parse(fs.readFileSync(path.join(root, 'audit/donor-audit.json'), 'utf8'))
|
||||
|
||||
test('all donors remain read-only and source copying stays blocked', () => {
|
||||
assert.equal(audit.complete, false)
|
||||
assert.equal(audit.donors.length, 3)
|
||||
for (const donor of audit.donors) {
|
||||
assert.match(donor.role, /^READ_ONLY_/)
|
||||
assert.match(donor.code_reuse, /^BLOCKED_/)
|
||||
}
|
||||
})
|
||||
|
||||
test('audit preserves security and secret migration prohibitions', () => {
|
||||
assert.ok(audit.prohibited_transplants.includes('UNAUTHENTICATED_LOOPBACK_CONTROL_API_OR_NULL_ORIGIN_CORS'))
|
||||
assert.ok(audit.prohibited_transplants.includes('ELECTRON_PRIVILEGED_PRELOAD_WITHOUT_NAVIGATION_AND_SENDER_ORIGIN_LOCK'))
|
||||
const secretData = audit.data_classes.find((entry) => entry.class === 'MODEL_AND_SERVER_CREDENTIALS')
|
||||
assert.match(secretData.migration, /NEVER_COPY_AS_PLAIN_DATA/)
|
||||
})
|
||||
|
||||
test('visual implementation cannot start while audit gates remain open', () => {
|
||||
assert.ok(audit.open_gates.includes('VISUAL_DIRECTION_SELECTION'))
|
||||
assert.ok(!audit.open_gates.includes('LEGACY_TAURI_SECURITY_SCAN'))
|
||||
const legacyTauri = audit.donors.find((entry) => entry.path === '../hololake-platform')
|
||||
assert.match(legacyTauri.security_scan, /REVIEW_COMPLETE/)
|
||||
assert.ok(legacyTauri.validated_security_findings.includes('MODEL_TOOL_MUTATIONS_WITHOUT_EXACT_HUMAN_CONFIRMATION'))
|
||||
assert.ok(audit.open_gates.includes('REVERSIBLE_DATA_MIGRATION_REHEARSAL'))
|
||||
})
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
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 readText = (relative) => fs.readFileSync(path.join(root, relative), 'utf8')
|
||||
|
||||
const foundation = readJson('foundation.json')
|
||||
const trust = readJson('src-tauri/release-trust.json')
|
||||
const tauriConfig = readJson('src-tauri/tauri.conf.json')
|
||||
const capability = readJson('src-tauri/capabilities/default.json')
|
||||
const broadcast = readJson('contracts/release-broadcast.schema.json')
|
||||
|
||||
test('clean Tauri foundation contains no inherited product updater endpoint', () => {
|
||||
assert.deepEqual(foundation.upstream_product_update_endpoints, [])
|
||||
assert.deepEqual(trust.endpoints, [])
|
||||
assert.deepEqual(trust.allowedReleaseHosts, [])
|
||||
assert.equal(trust.state, 'UNPROVISIONED_FAIL_CLOSED')
|
||||
assert.equal(trust.publicKey, '')
|
||||
for (const relative of [
|
||||
'foundation.json',
|
||||
'src-tauri/release-trust.json',
|
||||
'src-tauri/tauri.conf.json',
|
||||
'src-tauri/src/release_trust.rs',
|
||||
]) {
|
||||
const source = readText(relative)
|
||||
assert.doesNotMatch(source, /refactoringhq|tolaria|outline/i)
|
||||
}
|
||||
})
|
||||
|
||||
test('release activation remains explicitly human controlled', () => {
|
||||
assert.equal(trust.automaticCheckOnStartup, false)
|
||||
assert.equal(trust.automaticDownload, false)
|
||||
assert.equal(trust.humanOptInInstallRequired, true)
|
||||
assert.equal(trust.automaticRestart, false)
|
||||
assert.equal(foundation.automatic_update_check_on_startup, false)
|
||||
assert.equal(foundation.human_opt_in_download_install_required, true)
|
||||
assert.equal(foundation.automatic_restart_allowed, false)
|
||||
})
|
||||
|
||||
test('Tauri can emit signed updater artifacts without exposing updater IPC', () => {
|
||||
assert.equal(tauriConfig.bundle.createUpdaterArtifacts, true)
|
||||
assert.deepEqual(capability.permissions, ['core:default'])
|
||||
assert.equal(capability.permissions.includes('updater:default'), false)
|
||||
})
|
||||
|
||||
test('broadcast remains Tauri-compatible and carries HoloLake human metadata', () => {
|
||||
const platform = broadcast.properties.platforms.additionalProperties
|
||||
assert.equal(platform.required.includes('signature'), true)
|
||||
assert.equal(platform.required.includes('url'), true)
|
||||
assert.equal(broadcast.required.includes('pub_date'), true)
|
||||
assert.equal(broadcast.required.includes('publishedAt'), false)
|
||||
assert.equal(broadcast.required.includes('notes'), true)
|
||||
assert.equal(broadcast.required.includes('hololake'), true)
|
||||
assert.equal(
|
||||
broadcast.properties.hololake.properties.restart.properties.automaticAllowed.const,
|
||||
false,
|
||||
)
|
||||
})
|
||||
5415
product-source/hololake-native-desktop/src-tauri/Cargo.lock
generated
Normal file
5415
product-source/hololake-native-desktop/src-tauri/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
26
product-source/hololake-native-desktop/src-tauri/Cargo.toml
Normal file
26
product-source/hololake-native-desktop/src-tauri/Cargo.toml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
[package]
|
||||
name = "hololake-native-desktop"
|
||||
version = "0.1.0"
|
||||
description = "HoloLake native desktop foundation"
|
||||
authors = ["HoloLake"]
|
||||
license = "AGPL-3.0-or-later"
|
||||
edition = "2021"
|
||||
rust-version = "1.77.2"
|
||||
|
||||
[lib]
|
||||
name = "hololake_native_desktop_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2.5.4", features = [] }
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
tauri = { version = "=2.10.2", features = [] }
|
||||
tauri-runtime = "=2.10.0"
|
||||
tauri-runtime-wry = "=2.10.0"
|
||||
tauri-plugin-updater = "2.10.0"
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Minimum HoloLake desktop foundation; updater actions are not exposed to the webview yet.",
|
||||
"windows": ["main"],
|
||||
"permissions": ["core:default"]
|
||||
}
|
||||
BIN
product-source/hololake-native-desktop/src-tauri/icons/icon.png
Normal file
BIN
product-source/hololake-native-desktop/src-tauri/icons/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"schema": "hololake.release-trust/v1",
|
||||
"state": "UNPROVISIONED_FAIL_CLOSED",
|
||||
"endpoints": [],
|
||||
"publicKey": "",
|
||||
"allowedReleaseHosts": [],
|
||||
"automaticCheckOnStartup": false,
|
||||
"automaticDownload": false,
|
||||
"humanOptInInstallRequired": true,
|
||||
"automaticRestart": false
|
||||
}
|
||||
12
product-source/hololake-native-desktop/src-tauri/src/lib.rs
Normal file
12
product-source/hololake-native-desktop/src-tauri/src/lib.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
mod release_trust;
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.setup(|app| {
|
||||
release_trust::install_updater_if_provisioned(app.handle())?;
|
||||
Ok(())
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("failed to run HoloLake native desktop");
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() {
|
||||
hololake_native_desktop_lib::run();
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
use serde::Deserialize;
|
||||
use tauri::{AppHandle, Runtime, Url};
|
||||
use tauri_plugin_updater::UpdaterExt;
|
||||
|
||||
const EMBEDDED_RELEASE_TRUST: &str = include_str!("../release-trust.json");
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct ReleaseTrust {
|
||||
schema: String,
|
||||
state: TrustState,
|
||||
endpoints: Vec<String>,
|
||||
public_key: String,
|
||||
allowed_release_hosts: Vec<String>,
|
||||
automatic_check_on_startup: bool,
|
||||
automatic_download: bool,
|
||||
human_opt_in_install_required: bool,
|
||||
automatic_restart: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
enum TrustState {
|
||||
UnprovisionedFailClosed,
|
||||
Provisioned,
|
||||
}
|
||||
|
||||
enum ValidatedReleaseTrust {
|
||||
Disabled,
|
||||
Enabled {
|
||||
endpoints: Vec<Url>,
|
||||
public_key: String,
|
||||
},
|
||||
}
|
||||
|
||||
fn validate_release_trust(raw: &str) -> Result<ValidatedReleaseTrust, String> {
|
||||
let trust: ReleaseTrust = serde_json::from_str(raw)
|
||||
.map_err(|error| format!("invalid HoloLake release trust document: {error}"))?;
|
||||
|
||||
if trust.schema != "hololake.release-trust/v1" {
|
||||
return Err("unsupported HoloLake release trust schema".into());
|
||||
}
|
||||
if trust.automatic_check_on_startup || trust.automatic_download || trust.automatic_restart {
|
||||
return Err("automatic check, download and restart must remain disabled".into());
|
||||
}
|
||||
if !trust.human_opt_in_install_required {
|
||||
return Err("human opt-in installation is required".into());
|
||||
}
|
||||
|
||||
match trust.state {
|
||||
TrustState::UnprovisionedFailClosed => {
|
||||
if !trust.endpoints.is_empty()
|
||||
|| !trust.public_key.is_empty()
|
||||
|| !trust.allowed_release_hosts.is_empty()
|
||||
{
|
||||
return Err(
|
||||
"unprovisioned trust must not contain endpoint or public key material".into(),
|
||||
);
|
||||
}
|
||||
Ok(ValidatedReleaseTrust::Disabled)
|
||||
}
|
||||
TrustState::Provisioned => {
|
||||
if trust.endpoints.len() != 1 {
|
||||
return Err("exactly one HoloLake release endpoint is required".into());
|
||||
}
|
||||
if trust.public_key.trim().is_empty() {
|
||||
return Err("the HoloLake updater public key is required".into());
|
||||
}
|
||||
if trust.allowed_release_hosts.len() != 1 {
|
||||
return Err("exactly one HoloLake-owned release host is required".into());
|
||||
}
|
||||
let allowed_host = trust.allowed_release_hosts[0].trim();
|
||||
if allowed_host.is_empty() || allowed_host.contains('/') || allowed_host.contains(':') {
|
||||
return Err("the HoloLake release host must be a bare DNS name".into());
|
||||
}
|
||||
let endpoint = Url::parse(&trust.endpoints[0])
|
||||
.map_err(|error| format!("invalid HoloLake release endpoint: {error}"))?;
|
||||
if endpoint.scheme() != "https" {
|
||||
return Err("the HoloLake release endpoint must use HTTPS".into());
|
||||
}
|
||||
if endpoint.host_str() != Some(allowed_host) {
|
||||
return Err(
|
||||
"the updater endpoint is not owned by the configured HoloLake host".into(),
|
||||
);
|
||||
}
|
||||
Ok(ValidatedReleaseTrust::Enabled {
|
||||
endpoints: vec![endpoint],
|
||||
public_key: trust.public_key,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install_updater_if_provisioned<R: Runtime>(
|
||||
app: &AppHandle<R>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
match validate_release_trust(EMBEDDED_RELEASE_TRUST)? {
|
||||
ValidatedReleaseTrust::Disabled => Ok(()),
|
||||
ValidatedReleaseTrust::Enabled {
|
||||
endpoints,
|
||||
public_key,
|
||||
} => {
|
||||
let updater = tauri_plugin_updater::Builder::new()
|
||||
.pubkey(public_key)
|
||||
.build();
|
||||
app.plugin(updater)?;
|
||||
app.updater_builder().endpoints(endpoints)?.build()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{validate_release_trust, ValidatedReleaseTrust};
|
||||
|
||||
fn document(state: &str, endpoint: &str, public_key: &str, allowed_host: &str) -> String {
|
||||
format!(
|
||||
r#"{{
|
||||
"schema":"hololake.release-trust/v1",
|
||||
"state":"{state}",
|
||||
"endpoints":[{endpoint}],
|
||||
"publicKey":"{public_key}",
|
||||
"allowedReleaseHosts":[{allowed_host}],
|
||||
"automaticCheckOnStartup":false,
|
||||
"automaticDownload":false,
|
||||
"humanOptInInstallRequired":true,
|
||||
"automaticRestart":false
|
||||
}}"#
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unprovisioned_document_disables_update_networking() {
|
||||
let trust =
|
||||
validate_release_trust(&document("UNPROVISIONED_FAIL_CLOSED", "", "", "")).unwrap();
|
||||
assert!(matches!(trust, ValidatedReleaseTrust::Disabled));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accepts_https_shape_but_rejects_insecure_endpoints() {
|
||||
let owned_shape = document(
|
||||
"PROVISIONED",
|
||||
"\"https://releases.example.test/latest.json\"",
|
||||
"public",
|
||||
"\"releases.example.test\"",
|
||||
);
|
||||
assert!(
|
||||
validate_release_trust(&owned_shape).is_ok(),
|
||||
"endpoint ownership is additionally checked by release provisioning"
|
||||
);
|
||||
let insecure = document(
|
||||
"PROVISIONED",
|
||||
"\"http://releases.example.test/latest.json\"",
|
||||
"public",
|
||||
"\"releases.example.test\"",
|
||||
);
|
||||
assert!(validate_release_trust(&insecure).is_err());
|
||||
let mismatched_host = document(
|
||||
"PROVISIONED",
|
||||
"\"https://upstream.example.test/latest.json\"",
|
||||
"public",
|
||||
"\"releases.example.test\"",
|
||||
);
|
||||
assert!(validate_release_trust(&mismatched_host).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_automatic_or_nonconsensual_install_policy() {
|
||||
let automatic = document("UNPROVISIONED_FAIL_CLOSED", "", "", "")
|
||||
.replace("\"automaticDownload\":false", "\"automaticDownload\":true");
|
||||
assert!(validate_release_trust(&automatic).is_err());
|
||||
let no_opt_in = document("UNPROVISIONED_FAIL_CLOSED", "", "", "").replace(
|
||||
"\"humanOptInInstallRequired\":true",
|
||||
"\"humanOptInInstallRequired\":false",
|
||||
);
|
||||
assert!(validate_release_trust(&no_opt_in).is_err());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "HoloLake",
|
||||
"version": "0.1.0",
|
||||
"identifier": "world.guanghu.hololake",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
"devUrl": "http://127.0.0.1:5210",
|
||||
"beforeDevCommand": "npm run dev",
|
||||
"beforeBuildCommand": "npm run build"
|
||||
},
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"label": "main",
|
||||
"title": "HoloLake",
|
||||
"width": 1180,
|
||||
"height": 760,
|
||||
"minWidth": 760,
|
||||
"minHeight": 520
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "default-src 'self'; connect-src 'self' ipc: http://ipc.localhost; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'"
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"createUpdaterArtifacts": true,
|
||||
"category": "Productivity"
|
||||
}
|
||||
}
|
||||
24
product-source/hololake-native-desktop/src/main.tsx
Normal file
24
product-source/hololake-native-desktop/src/main.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './styles.css'
|
||||
|
||||
function FoundationScreen() {
|
||||
return (
|
||||
<main>
|
||||
<p className="eyebrow">HoloLake Native Desktop</p>
|
||||
<h1>新的光湖桌面主线正在建立信任根</h1>
|
||||
<p>
|
||||
当前只完成最小 Tauri 外壳与更新安全边界。知识工作区将在双供体审计和视觉方向确定后开始。
|
||||
</p>
|
||||
<dl>
|
||||
<div><dt>上游更新</dt><dd>已关闭</dd></div>
|
||||
<div><dt>光湖发布广播</dt><dd>等待正式端点与公钥</dd></div>
|
||||
<div><dt>下载与安装</dt><dd>必须由人类选择</dd></div>
|
||||
</dl>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode><FoundationScreen /></StrictMode>,
|
||||
)
|
||||
16
product-source/hololake-native-desktop/src/styles.css
Normal file
16
product-source/hololake-native-desktop/src/styles.css
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
:root {
|
||||
font-family: ui-sans-serif, system-ui, sans-serif;
|
||||
color: #eaf0ff;
|
||||
background: #07101f;
|
||||
font-synthesis: none;
|
||||
}
|
||||
|
||||
body { margin: 0; min-width: 320px; min-height: 100vh; }
|
||||
main { max-width: 720px; margin: 0 auto; padding: 12vh 32px; }
|
||||
.eyebrow { color: #82a7ff; letter-spacing: .08em; text-transform: uppercase; }
|
||||
h1 { font-size: clamp(2rem, 5vw, 4rem); line-height: 1.05; }
|
||||
p { color: #b7c5e5; line-height: 1.7; }
|
||||
dl { margin-top: 48px; border-top: 1px solid #263554; }
|
||||
dl div { display: flex; justify-content: space-between; gap: 24px; padding: 16px 0; border-bottom: 1px solid #263554; }
|
||||
dt { color: #8fa4cf; }
|
||||
dd { margin: 0; text-align: right; }
|
||||
20
product-source/hololake-native-desktop/tsconfig.app.json
Normal file
20
product-source/hololake-native-desktop/tsconfig.app.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"allowJs": false,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
7
product-source/hololake-native-desktop/tsconfig.json
Normal file
7
product-source/hololake-native-desktop/tsconfig.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
12
product-source/hololake-native-desktop/vite.config.ts
Normal file
12
product-source/hololake-native-desktop/vite.config.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
clearScreen: false,
|
||||
server: {
|
||||
host: '127.0.0.1',
|
||||
port: 5210,
|
||||
strictPort: true,
|
||||
},
|
||||
})
|
||||
|
|
@ -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。
|
||||
|
|
|
|||
|
|
@ -0,0 +1,146 @@
|
|||
# HoloLake 新 Tauri 主线、双供体审计与自有更新架构 · 2026-08-12
|
||||
|
||||
> 记录编号:`HLP-CANONICAL-DESKTOP-SHELL-001`
|
||||
>
|
||||
> 决议:`ADR-0178`
|
||||
>
|
||||
> 状态:`CURRENT_CANONICAL · MINIMAL_SCAFFOLD_AND_FAIL_CLOSED_UPDATE_TRUST_ROOT_IMPLEMENTED · 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 · 仍未完成
|
||||
|
||||
- 新目录已形成可编译的最小 Tauri 脚手架和默认不联网的更新信任根,但尚未形成产品 UI;
|
||||
- HoloLake 更新域名、签名密钥托管和开发者证书尚未登记;
|
||||
- 双供体完整功能矩阵、许可证清单、数据迁移图和安全威胁模型尚未完成;
|
||||
- 新 UI 视觉方向尚未由冰朔选择;
|
||||
- 不存在可发布的新主线安装包。
|
||||
|
||||
所以当前事实是:**框架和迁移方法已经纠正,干净开发基线已经建立;生产发布身份、完整供体
|
||||
审计、视觉选择与产品纵向切片仍未完成。**
|
||||
|
|
@ -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.
|
||||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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/,
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
143
routing/hololake-canonical-desktop-shell.json
Normal file
143
routing/hololake-canonical-desktop-shell.json
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
{
|
||||
"schema": "hololake.canonical-desktop-shell/v2",
|
||||
"record_id": "HLP-CANONICAL-DESKTOP-SHELL-001",
|
||||
"version": "2026-08-12.4",
|
||||
"state": "CURRENT_CANONICAL_NATIVE_TAURI_FOUNDATION_WITH_UPDATE_TRUST_ROOT_AND_PARTIAL_DONOR_AUDIT",
|
||||
"development_id": "DEV-20260811-010",
|
||||
"decision": {
|
||||
"canonical_shell": "TAURI_V2_RUST_REACT",
|
||||
"canonical_source": "product-source/hololake-native-desktop",
|
||||
"canonical_source_state": "MINIMAL_TAURI_SCAFFOLD_UPDATE_TRUST_ROOT_AND_DONOR_AUDIT_BASELINE_IMPLEMENTED",
|
||||
"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": "FAIL_CLOSED_LOCAL_TRUST_ROOT_IMPLEMENTED_PRODUCTION_IDENTITY_UNPROVISIONED",
|
||||
"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,
|
||||
"record": "product-source/hololake-native-desktop/audit/donor-audit.json",
|
||||
"electron_shell_security_scan_complete": true,
|
||||
"knowledge_core_security_scan_complete": true,
|
||||
"legacy_tauri_security_scan_complete": true,
|
||||
"file_provenance_and_dependency_license_audit_complete": false,
|
||||
"physical_user_data_inventory_and_migration_rehearsal_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"
|
||||
}
|
||||
106
routing/hololake-canonical-desktop-shell.test.mjs
Normal file
106
routing/hololake-canonical-desktop-shell.test.mjs
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
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,
|
||||
"MINIMAL_TAURI_SCAFFOLD_AND_FAIL_CLOSED_UPDATE_TRUST_ROOT_IMPLEMENTED",
|
||||
);
|
||||
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.hololake.properties.restart.properties.required.const,
|
||||
true,
|
||||
);
|
||||
assert.equal(
|
||||
broadcastSchema.properties.hololake.properties.restart.properties.automaticAllowed.const,
|
||||
false,
|
||||
);
|
||||
assert.match(
|
||||
broadcastSchema.properties.platforms.additionalProperties.properties.url.pattern,
|
||||
/^\^https:/,
|
||||
);
|
||||
assert.equal(
|
||||
broadcastSchema.properties.platforms.additionalProperties.required.includes("signature"),
|
||||
true,
|
||||
);
|
||||
assert.equal(broadcastSchema.required.includes("pub_date"), true);
|
||||
assert.equal(broadcastSchema.required.includes("publishedAt"), false);
|
||||
});
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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": "MINIMAL_TAURI_SCAFFOLD_AND_FAIL_CLOSED_UPDATE_TRUST_ROOT_IMPLEMENTED",
|
||||
"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": "光湖本源域",
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Reference in a new issue