docs(desktop): document source provenance and runtime boundaries
This commit is contained in:
1 parent
bbc410b47b
commit
dbdc63c368
2 files changed
+194
-19
No files matched your search
@@ -0,0 +1,96 @@
|
||||
# GenericAgent Desktop 2.0 integration boundary
|
||||
|
||||
GenericAgent Desktop 2.0 is a packaged Tauri desktop application with a generated React renderer and
|
||||
Desktop-specific Python services. The React source is intentionally developed outside this upstream tree;
|
||||
the generated distribution and all runtime interfaces required to execute it are tracked here.
|
||||
|
||||
## Renderer ownership
|
||||
|
||||
- `frontends/desktop/dist/**` contains the generated Desktop 2.0 HTML, JavaScript, CSS, fonts, and images.
|
||||
- `frontends/desktop/static/**` is the independent Desktop v1 implementation and remains available unchanged.
|
||||
- Tauri packages `dist/**`; it does not compile React during an upstream build.
|
||||
- The public React source, issue tracker, and contribution home is
|
||||
<https://github.com/abraxas914/GenericAgent>.
|
||||
- The exact fork commit and generated-file content manifest are recorded in
|
||||
`dist/build-provenance.json`.
|
||||
|
||||
Generated files must not be edited by hand. Renderer changes are made and tested in the fork, rebuilt from an
|
||||
accepted fork `main` commit, and submitted upstream as a refreshed `dist/**` tree with matching provenance.
|
||||
The manifest identifies the submitted bytes; it is not a claim that later builds are bit-for-bit reproducible.
|
||||
|
||||
The production Tauri configuration loads only the tracked asset origin and applies an explicit Content Security
|
||||
Policy. React source tooling is absent from the upstream package path, while WebDriver permission remains isolated
|
||||
to `tauri.e2e.conf.json` and is not granted by the production configuration.
|
||||
|
||||
## Desktop runtime ownership
|
||||
|
||||
Desktop 2.0 uses these repository-owned integration layers:
|
||||
|
||||
- `frontends/desktop_bridge.py`: local HTTP/WebSocket API, model/session/upload/data routes, service control,
|
||||
identity, and Desktop diagnostics.
|
||||
- `frontends/conductor.py`: Desktop collaboration and model-routing integration.
|
||||
- `frontends/cost_tracker.py`: Desktop usage and cost ledger.
|
||||
- `frontends/data_backup.py`: validated Desktop data export, inspection, and import/merge behavior.
|
||||
- `frontends/desktop_settings.py`: locked, atomic read/modify/write updates for shared Desktop preferences.
|
||||
- `frontends/desktop/src-tauri/**`: native bootstrap, permissions, file pickers, runtime/source switching,
|
||||
process/port recovery, window behavior, and package resource resolution.
|
||||
|
||||
The package-owned bridge remains the executable service boundary. `GA_ROOT` can point it at a compatible
|
||||
external GenericAgent repository, but does not replace the package-owned bridge or Tauri shell.
|
||||
|
||||
Desktop data import first backs up the complete destination `memory/**` tree, then applies source-wins memory
|
||||
files. Model responses remain add-only, and Desktop sessions are de-duplicated by session ID. Activation is staged
|
||||
and rolled back on failure. Import is rejected while a managed session or Desktop extra has unfinished work; users
|
||||
must also stop any independent TUI, CLI, or automation process before importing because those external processes
|
||||
are outside the bridge's maintenance gate. The persistent cost ledger is initialized by the Desktop bridge only;
|
||||
existing TUI and conductor processes retain their previous in-memory accounting hot path.
|
||||
|
||||
Browser-origin requests are accepted only from the production Tauri origins, the fixed development origin, the
|
||||
explicit E2E origin, or the bridge's own same origin. Native clients without an Origin remain supported, while
|
||||
cross-site, null, lookalike, wrong-port, preflight, and WebSocket requests are rejected before route handling.
|
||||
Backup exports cannot be written into any managed data or HTTP-readable directory.
|
||||
|
||||
Managed-service state is based on the bridge-owned live child process, not merely a listener on the configured
|
||||
port. A foreign conductor on production port `8900` is reported as an external port conflict and is never stopped
|
||||
or counted as an owned running extra. The alternate conductor port is available only to the isolated package E2E
|
||||
journey; production renderer and CSP contracts remain fixed to `8900`.
|
||||
|
||||
On macOS, the package runtime uses a stable writable root and is refreshed through a package/build/source marker
|
||||
with staged atomic activation. A previously shipped versioned runtime is migrated into that stable root. User
|
||||
configuration, memory, responses, sessions, and token ledger data are preserved; a failed migration or activation
|
||||
restores the previous runtime and marker. Matching markers keep the hot-start copy untouched.
|
||||
|
||||
## Core runtime boundary
|
||||
|
||||
Desktop 2.0 does not own or modify GenericAgent's Agent/LLM/Harness business runtime. In particular, the
|
||||
integration does not change `agentmain.py`, LLM execution, Harness/Agent execution, inference, tool-calling,
|
||||
or memory-scheduling semantics. Desktop bridge and conductor changes translate Desktop requests onto those
|
||||
existing core contracts.
|
||||
|
||||
## Version and release contract
|
||||
|
||||
Desktop package metadata is `0.2.0` across npm, Cargo, Tauri, and generated provenance. Upstream packages consume
|
||||
the tracked `dist/**` tree, so an upstream maintainer can build official Windows, Linux, and macOS artifacts
|
||||
without the React source. A `desktop-portable-*` tag starts three read-only platform builders. One separate
|
||||
publisher receives write permission only after all three succeed, validates the six expected files and checksums,
|
||||
creates an invisible draft with all assets, and then exposes that single entry as a prerelease. Manual
|
||||
`workflow_dispatch` runs produce candidate artifacts only and skip the publisher.
|
||||
|
||||
The Linux builder runs on Ubuntu 22.04, isolates Rust target/bin caches from newer runner ABIs, and rejects any
|
||||
ELF requiring a GLIBC version newer than 2.35. Windows remains unsigned and documents SmartScreen plus checksum
|
||||
verification; macOS remains ad-hoc signed and unnotarized.
|
||||
|
||||
The renderer still uses the existing local loopback bridge contract. This integration neither treats that inherited
|
||||
platform requirement as a new release blocker nor claims to have changed operating-system loopback policy.
|
||||
|
||||
## Validation layers
|
||||
|
||||
- Compiled distribution contract: required entries, asset references, source-map/source leakage, E2E markers,
|
||||
version consistency, exact provenance manifest, and the `dist` package entry.
|
||||
- Python contracts: bridge, conductor, model routing, sessions, uploads, cost ledger, `GA_ROOT`, and data backup.
|
||||
- Rust contracts: formatting, clippy, production and E2E feature tests, and
|
||||
path/identity/port/diagnostic/bootstrap behavior.
|
||||
- Native package contract: Linux Tauri build smoke plus the platform release workflow.
|
||||
|
||||
The richer React unit/browser/native E2E suites remain in the fork and run before its accepted `main` SHA is
|
||||
used to refresh the generated upstream distribution.
|
||||
@@ -1,20 +1,37 @@
|
||||
# packaging
|
||||
# Desktop packaging
|
||||
|
||||
桌面端发布相关材料。本目录的内容**不会**整体打进发布包——CI
|
||||
(`.github/workflows/desktop-release-package.yml`)只从这里挑选 `scripts/` 下的
|
||||
安装/卸载脚本拷进各平台的发布产物,其余文件对构建打包过程是只读参考。
|
||||
This directory contains the scripts and locked Python inputs used to assemble GenericAgent Desktop packages.
|
||||
The directory is not copied wholesale into a release; the workflow selects only the platform scripts and
|
||||
requirements files required by each package.
|
||||
|
||||
## 目录结构
|
||||
## Submitted renderer boundary
|
||||
|
||||
```
|
||||
Official upstream package jobs consume the tracked `frontends/desktop/dist/**` renderer directly. They install
|
||||
only the minimal submitted Tauri CLI manifest and do not run Vite, TypeScript, React tests, or any other renderer
|
||||
source command. Tauri embeds `dist/**` in the native application. The portable `runtime/app` copy deliberately
|
||||
excludes `dist/**` so the same renderer is not duplicated as loose runtime data.
|
||||
|
||||
The React source, issue tracker, and contribution home is
|
||||
<https://github.com/abraxas914/GenericAgent>. The exact accepted fork commit and generated content manifest are
|
||||
recorded in `dist/build-provenance.json`. `frontends/desktop/static/**` remains the independent Desktop v1 and is
|
||||
unchanged by Desktop 2.0 packaging.
|
||||
|
||||
The Semi Design MIT text is tracked as `dist/THIRD_PARTY_NOTICES.txt`. Root attributes force the source notice and
|
||||
compiled notice to LF on every platform, and all three package builders verify the locked notice SHA-256 before
|
||||
building.
|
||||
|
||||
## Inputs
|
||||
|
||||
```text
|
||||
frontends/desktop/packaging/
|
||||
├── README.md # 本说明
|
||||
├── CHECKLIST.md # 发布前功能测试清单(测试协调用,不参与打包)
|
||||
├── TODO.md # 各平台测试分工与计划(测试协调用,不参与打包)
|
||||
└── scripts/ # ← 唯一被 CI 消费的内容
|
||||
├── README.md
|
||||
├── dmg-build-requirements.txt
|
||||
├── python-runtime-requirements.txt
|
||||
└── scripts/
|
||||
├── merge_desktop_settings.py
|
||||
├── windows/
|
||||
│ ├── install_windows.ps1 # 环境准备脚本
|
||||
│ ├── uninstall.bat # 卸载入口(向用户确认后调用 ps1)
|
||||
│ ├── install_windows.ps1
|
||||
│ ├── uninstall.bat
|
||||
│ └── uninstall_windows.ps1
|
||||
├── linux/
|
||||
│ ├── install_linux.sh
|
||||
@@ -24,12 +41,74 @@ frontends/desktop/packaging/
|
||||
└── uninstall.command
|
||||
```
|
||||
|
||||
## CI 如何使用这些脚本
|
||||
- Node is fixed at `22.23.2`; the compiled-only jobs install exactly `@tauri-apps/cli` `2.11.4` with
|
||||
`npm install --package-lock=false`, assert that no source lockfile was created, and never invoke Vite. Rust is
|
||||
fixed at `1.95.0` and crates are locked by `Cargo.lock`.
|
||||
- Root `.gitattributes` pins both the source `public/THIRD_PARTY_NOTICES.txt` path and the delivered
|
||||
`dist/THIRD_PARTY_NOTICES.txt` path to LF; the source file itself stays outside this compiled-only PR. Each of
|
||||
the three builders runs the cross-platform compiled-distribution contract immediately before Tauri embeds the
|
||||
tracked `dist`, locking the notice SHA-256 to
|
||||
`2acf865e87e59090121369aac0575467067fdd7999923a70d785a46ceae3330f` and failing on any byte drift.
|
||||
- python-build-standalone is fixed at release `20260814`, CPython `3.12.14`, an explicit architecture, and an
|
||||
archive SHA-256 on each platform.
|
||||
- The macOS builder runs on the Apple-silicon `macos-15` host and uses host CPython `3.12.10` only for the
|
||||
hash-locked DMG layout tools. That host interpreter is separate from the embedded `3.12.14` runtime.
|
||||
- Windows converts `RUNNER_TEMP` with `cygpath -u` before passing its archive path to POSIX tools.
|
||||
- Linux builds on Ubuntu 22.04, uses a dedicated glibc-2.35 Rust cache prefix with target/bin caching disabled,
|
||||
and scans every packaged ELF to reject a maximum GLIBC requirement above 2.35.
|
||||
- Runtime direct and transitive dependencies use exact versions in `python-runtime-requirements.txt`; downloads
|
||||
require binary wheels. The DMG layout requirements use exact versions and wheel hashes.
|
||||
- Preparation disables Python bytecode writes and removes `__pycache__`, `.pyc`, and `.pyo` files across the
|
||||
complete bundled runtime without removing vendored Python packages.
|
||||
- Checkout, Node/Python setup, artifact upload/download, Rust toolchain, and Rust cache actions use full commit
|
||||
SHA pins and disable persisted checkout credentials.
|
||||
|
||||
`desktop-release-package.yml` 在打各平台 portable 包时,把对应平台的脚本
|
||||
`cp` 进发布目录(例如 Windows 包里放 `install_windows.ps1` /
|
||||
`uninstall.bat` / `uninstall_windows.ps1`)。**修改安装/卸载行为只需改
|
||||
`scripts/` 下的文件,不需要动 workflow。**
|
||||
These controls do not make the packages bit-for-bit reproducible. Runner images, Ubuntu packages, the Windows
|
||||
SDK/UCRT input, platform wheels, and native packaging metadata can change or contain timestamps. Candidate
|
||||
artifact SHA-256 values and real-package journeys remain the evidence for a particular build.
|
||||
|
||||
> 说明:实际的桌面壳二进制(`GenericAgent.exe` / `.AppImage` / `.app`)由 CI
|
||||
> 构建生成并发布到 GitHub Release,不在本仓库内提交,也不在本目录占位。
|
||||
## Candidate artifacts and publication
|
||||
|
||||
Manual `workflow_dispatch` runs build the selected platform or all three platforms as downloadable Actions
|
||||
artifacts. They never create or edit a GitHub Release.
|
||||
|
||||
A maintainer-created `desktop-portable-*` tag starts this publication graph:
|
||||
|
||||
```text
|
||||
Windows builder (contents: read) ─┐
|
||||
Linux builder (contents: read) ─┼─ verified Actions artifacts ─┐
|
||||
macOS builder (contents: read) ─┘ │
|
||||
▼
|
||||
publisher (contents: write)
|
||||
validate six files/checksums
|
||||
create one invisible draft
|
||||
verify uploaded asset set
|
||||
expose one prerelease
|
||||
```
|
||||
|
||||
The three builders do not receive a write token and do not call the GitHub Release API. The publisher runs only
|
||||
for a matching tag push after all three builders succeed; it does not check out source or run package tooling.
|
||||
It refuses to overwrite an existing Release for the tag.
|
||||
|
||||
The prerelease contains exactly:
|
||||
|
||||
- `GenericAgent-Desktop-Windows-Portable.zip`
|
||||
- `SHA256SUMS-windows.txt`
|
||||
- `GenericAgent-Desktop-Linux-Portable.tar.gz`
|
||||
- `SHA256SUMS-linux.txt`
|
||||
- `GenericAgent-Desktop-macOS-aarch64.dmg`
|
||||
- `GenericAgent-Desktop-macOS-aarch64.dmg.sha256`
|
||||
|
||||
The macOS application is ad-hoc signed only. It is not Developer ID signed or notarized, and the published notes
|
||||
retain the documented context-menu / Privacy & Security opening path.
|
||||
|
||||
## Validation
|
||||
|
||||
- `npm run test:dist` verifies required compiled entries, references, source leakage, dead assets, the notice hash,
|
||||
version/CSP/E2E isolation, source provenance, and the atomic release contract.
|
||||
- `python -m pytest frontends/tests` verifies Desktop bridge, conductor, model/session/upload behavior, the
|
||||
Desktop-only cost ledger, transactional data import, package-evidence parsing, owned service/port behavior,
|
||||
`GA_ROOT`, and Tauri security contracts.
|
||||
- Rust formatting, clippy, production/E2E tests, and a Tauri `--no-bundle` build validate the native shell against
|
||||
the tracked renderer.
|
||||
- Shell, Python, PowerShell, YAML, action pinning, boundary diff, and conflict checks run before delivery.
|
||||
Reference in new issue
Block a user