feat(ios): add native Git knowledge and device-only secrets

This commit is contained in:
冰朔 2026-08-03 22:27:09 +08:00
commit b30f814320
51 changed files with 3019 additions and 97 deletions

View file

@ -1135,6 +1135,35 @@ server deployment.
## Updates & Feature Flags
## Mobile HoloLake knowledge boundary
### Native storage and identity
- **`mobile_vault`** — Creates typed foundation and personal knowledge lakes
inside the application sandbox. It never calls a desktop folder picker.
- **`device_secret_store`** — Stores account sessions and user model keys in a
non-synchronizing, this-device-only Apple Keychain item. Callers keep only an
opaque handle and never receive a persisted plaintext representation.
- **`hololake_account`** — Owns email OTP, device-bound sessions, verified
repository snapshots, the server model catalog, and atomic Markdown write
receipts.
### Knowledge Agent execution
- **`.hololake-sync-policy.json`** — Marks a lake as repository-backed and
excludes `本地密钥/**`, internal HoloLake metadata, and Git internals.
- **`sync_local_markdown_page`** — Sends only a bounded normal Markdown path,
complete content, and the exact current base commit. Success requires a new
40-character repository commit; otherwise the native tool rolls back its
local create or edit.
- **server AI provider** — Sends bounded model messages and tool schemas through
the authenticated HoloLake proxy. The client executes allowlisted knowledge
tools locally and returns their exact receipts for the next model turn. The
server provider key never reaches the device.
- **synchronized delete gate** — Refuses deletion until an atomic repository
delete receipt exists, preventing a local-only success from diverging from
the shared lake.
### Hooks
- **`useUpdater(releaseChannel, automaticChecksEnabled)`** — Channel-aware updater state machine. When automatic checks are enabled, it checks the selected feed after startup; manual checks always remain available. It surfaces checking/available/downloading/ready states and delegates install work to Rust.
- **`useFeatureFlag(flag)`** — Returns boolean for a named feature flag. Checks `localStorage` override (`ff_<name>`), then falls back to telemetry-backed evaluation. Type-safe via `FeatureFlagName` union.

View file

@ -1,6 +1,10 @@
# Architecture
Tolaria is a personal knowledge and life management desktop app. It reads a vault of markdown files with YAML frontmatter and presents them in a four-panel UI inspired by Bear Notes.
HoloLake Era is the human and Agent entry to HoloLake worlds, channels, identity,
knowledge, and receipt-backed native execution. Its knowledge workspace retains
the mature Markdown graph and editor inherited from Tolaria, but the product is
not a renamed desktop vault and the mobile client does not emulate desktop
filesystem or credential behavior.
## Design Principles
@ -56,6 +60,22 @@ No field names, folder paths, or vault-specific values should be hardcoded in th
Notes are not just documents — they are nodes in a structured graph of people, projects, events, responsibilities, and ideas. Every design decision should ask: "Does this make the knowledge graph easier for a human *and* an AI to navigate?" Conventions that are legible to both are better than conventions that are legible only to one.
### Mobile knowledge and credential boundary
On iOS, HoloLake opens app-owned foundation and personal knowledge directories
inside the sandbox rather than calling the desktop folder picker. A synchronized
personal lake is identified by `.hololake-sync-policy.json`: ordinary Markdown
can be written through the authenticated server into the registered code-channel
repository, while `本地密钥/**`, internal metadata, and Git internals are excluded.
The knowledge Agent uses the same bounded read/write tools as the desktop model
target. A normal page create or edit is acknowledged only after an optimistic,
atomic bare-repository update returns the exact new commit. Local state is rolled
back when that receipt is absent. iOS account sessions and user model keys are
stored in non-synchronizing, this-device-only Keychain entries; raw values never
enter Markdown, Git, renderer state, telemetry, or server receipts. See
[ADR 0173](adr/0173-mobile-git-knowledge-and-device-secret-boundary.md).
### Three representations, one authority
Vault data exists in three forms simultaneously:

View file

@ -1,7 +1,7 @@
# HoloLake Era iPhone / TestFlight 承接记录
状态日期2026-07-19
当前版本0.1.7
状态日期2026-08-03
当前版本0.4.6
Bundle ID`com.guanghulab.hololake`
## 为什么这样做
@ -31,6 +31,19 @@ Bundle ID`com.guanghulab.hololake`
## 当前闭环状态
0.4.6 build 25 已被 Apple 接收并完成处理,但它仍停在出口合规法律声明,
且真机运行仍存在知识入口失败。因此 build 25 不分配测试组,也不作为可用版本。
下一次上传必须使用新的 build number并同时包含 ADR 0173 的移动知识边界:
- iOS 沙箱内的光湖基础世界与个人知识湖,不再调用移动端未实现的文件夹选择器;
- 邮箱验证码会话与用户模型密钥写入本机、不可同步的 this-device-only Keychain
- 普通 Markdown 由知识 Agent 读写,并在服务器返回精确 Git 提交后才显示成功;
- `本地密钥/**` 不进入 Markdown 同步、代码仓库、模型上下文、日志或回执;
- 服务器模型密钥留在服务器,手机只得到模型目录和执行结果。
这些源码和自动测试通过之前不得归档Apple 上传、处理完成、测试组分配和真机可用
仍然是四个彼此独立的验收事实。
2026-07-19 已完成付费团队同步、证书创建、iOS 26.5 平台导入、真机登记、前端生产构建和 Xcode scheme 对齐。私人设备标识不得写入仓库。
App Store Connect 应用记录已创建:名称 `HoloLake Era`主语言简体中文Bundle ID `com.guanghulab.hololake`。0.1.7 build 20 已由 Xcode 返回 `App upload complete`。build 19 曾因 `libapp.a` 被错误复制到 App 根目录而被 Apple 以 90171 拒绝;根因是 `project.yml``Externals` 同时声明为 sources现已移除build 20 包内预检确认不再包含该静态库。

View file

@ -0,0 +1,72 @@
# ADR 0173: Mobile Git knowledge and device-secret boundary
## Status
Accepted for the next HoloLake Era iOS internal build.
## Context
The mobile client cannot reuse a desktop folder picker, a desktop Git process,
or a plaintext provider-secret file. Treating the app-owned knowledge lake as a
renamed Tolaria vault also leaves first launch, repository synchronization, and
the knowledge Agent without a truthful mobile execution path.
HoloLake needs three different stores whose boundaries remain visible:
1. a bundled foundation world that can open offline;
2. normal Markdown knowledge that can synchronize with the registered Guanghu
code-channel repository;
3. device-only credentials that must never enter Markdown, Git, model context,
logs, receipts, archives, or server synchronization.
## Decision
- iOS creates and opens managed knowledge directories inside the application
sandbox. It never invokes the unsupported mobile folder picker.
- The foundation world is seeded locally and is not evidence of a server
connection, authenticated identity, persona residency, or repository
synchronization.
- A synchronized personal lake contains a typed
`.hololake-sync-policy.json`. Normal Markdown pages are eligible for
synchronization. `本地密钥/**`, `.hololake-*`, and `.git/**` are excluded.
- Email OTP creates a short, device-bound HoloLake session. The production
token is stored in iOS Keychain with
`AccessibleWhenUnlockedThisDeviceOnly` and synchronization disabled. The
metadata file contains only a stable handle, device id, and expiry.
- User-supplied model keys use the same device-only Keychain protection.
Server-supplied model keys never leave the server.
- The mobile model target uses the existing bounded knowledge-Agent tool
contract. It may search and read the active lake and create or replace a
normal Markdown page.
- A synchronized create or edit is complete only after the server atomically
advances the registered bare repository from the exact previous `main`
commit and returns the new 40-character commit plus content SHA-256. A
conflict or missing receipt rolls back the local mutation.
- The server accepts only bounded Markdown paths and content. Traversal,
non-Markdown paths, `本地密钥`, oversized content, and stale base commits
fail closed. Receipts never echo page content.
- Deletion from a synchronized lake remains disabled until it has the same
atomic server receipt and rollback semantics.
- The model is not an authority. The execution sequence remains:
```text
human event and real state
→ constrained model request
→ native allowlisted knowledge executor
→ local filesystem result
→ atomic repository update
→ verifiable commit receipt
```
## Consequences
- Mobile and desktop share Markdown semantics without pretending their storage
and credential environments are identical.
- The knowledge Agent can perform useful read/write work on iOS while every
external mutation still has a native receipt.
- A server outage leaves local knowledge readable but makes synchronized
writes fail closed.
- A TestFlight archive or an App Store Connect upload is not proof of this
capability. Acceptance requires iOS compilation, automated non-leak tests,
deployed server health, repository readback, and a real-device TestFlight
run.

View file

@ -220,3 +220,6 @@ proposed → active → superseded
| [0167](0167-gestational-history-continuity-ingestion.md) | Gestational history enters Guanghu through a native continuity protocol | active |
| [0168](0168-guanghu-native-prepartition-disk-layout.md) | Guanghu owns a registered pre-partition native disk layout | active |
| [0169](0169-model-native-living-galaxy-system.md) | Model-native HoloLake living galaxy system | accepted |
| [0171](0171-guanghu-world-email-entry-and-live-node-projection.md) | Guanghu world email entry and live node projection | active |
| [0172](0172-persona-subject-existence-and-runtime-predicates.md) | Separate persona subject existence from runtime predicates | active |
| [0173](0173-mobile-git-knowledge-and-device-secret-boundary.md) | Mobile Git knowledge and device-secret boundary | accepted |