From 4fbf7ca5df7a437fabe63cffbe79cdcb0f637025 Mon Sep 17 00:00:00 2001 From: ymote <151983+ymote@users.noreply.github.com> Date: Wed, 30 Sep 2026 19:27:13 -0700 Subject: [PATCH 1/4] docs(adr): 0005 the app contract (proposed) [skip ci] One small, versioned crate (octosense-app-contract 1.x) between App Hub and every app: manifest, policy resolution, integrity and running a package. Additive-only within 1.x; new manifest fields classified optional or required (`requires`), so older hosts refuse what they can't enforce; a fixture corpus and an API-diff check; consumers depend on the version from a registry, so App Hub changes no longer force app releases. Co-Authored-By: Claude Opus 5.5 --- docs/adr/0005-app-contract.md | 93 +++++++++++++++++++++++++++++++++++ docs/adr/README.md | 1 + docs/adr/README.zh-CN.md | 1 + 3 files changed, 95 insertions(+) create mode 100644 docs/adr/0005-app-contract.md diff --git a/docs/adr/0005-app-contract.md b/docs/adr/0005-app-contract.md new file mode 100644 index 00000000..a856fbff --- /dev/null +++ b/docs/adr/0005-app-contract.md @@ -0,0 +1,93 @@ +# ADR 0005: The app contract: one small, versioned interface between App Hub and every app + +- **Date:** 2026-09-30 +- **Status:** Proposed +- **Scope:** What an app (a mini app, a script app, or a native app that runs other apps, such as Rinx) may depend on from App Hub; how that interface is versioned and kept stable; how OctoSense and apps depend on it so that App Hub changes never force an app release. +- **Relates to:** [ADR 0002](0002-event-driven-app-agents.md) (app manifests and agents); [ADR 0004](0004-native-apps-hosting-and-peers.md) (native apps, storage contract); App Hub `crates/app-policy`; hagency-org/Rinx#37 (Rinx release tags, point 6: break the App Hub lockstep). + +## Context + +### What apps take from App Hub today + +Rinx runs mini apps, and to do that it uses App Hub's own code: about 30 call sites in `src/miniapps/`, `crates/system-apps` and `crates/miniapp-catalog`. OctoSense's shell uses the same crate. + +| What it does | App Hub code (`octosense-app-policy` unless noted) | +| --- | --- | +| Read a manifest | `AppManifest`, `SCHEMA` | +| Decide what an app may do | `policy::resolve`, `HostLimits`, `AppPolicy` | +| Check a package wasn't tampered with | `digest_dir`, `bundle_digest`, `admit_digest`, `RefuseAllSignatures`, `SignatureVerifier` | +| Run a mini app: entry script, assets, Splash settings | `SCRIPT_ENTRY`, `script_source`, `AssetServer`, `rewrite_assets`, `splash_adapter::apply` | +| The mini-app catalog | all of `octosense-app-hub`, re-exported by Rinx's `miniapp-catalog` as `hub` | + +`octosense-app-policy` also carries what only App Hub and the shell need: agent policy, listings, research scopes, the host service registry, containers and session profiles. It is versioned `0.1.0` and changes whenever App Hub does. + +### Why App Hub changes force Rinx releases + +- Every consumer names App Hub by **git commit**. Cargo treats two commits of one git repository as two different crates, so a build that contains OctoSense (App Hub at commit A) and Rinx (App Hub at commit B) links two copies, and the phone build fails ("specification is ambiguous"). +- A `[patch]` cannot point a git source at another commit of the same URL. OctoSense worked around it with a second host spelling (`www.github.com`), removed in #221 once Rinx v1.0.2 matched; the next App Hub change (App Hub #44, OctoSense #210) brought the conflict straight back. +- The manifest parser is **strict** (`#[serde(deny_unknown_fields)]` on every manifest struct). A manifest with a field an older reader does not know is rejected. That is deliberate and right for security (a silently ignored field could be a restriction), but it means a manifest written for a newer App Hub cannot run in an older Rinx, and vice versa. + +So the coupling is real (the mini-app rules are shared on purpose: a mini app in Rinx must get the same manifest format, permissions and integrity checks as an app in App Hub), but it is enforced at the wrong granularity: every commit, instead of every change to the rules. + +## Decision + +### 1. One contract crate, small on purpose + +App Hub publishes **`octosense-app-contract`**, versioned `1.x`, holding only what an app or host needs to read, check and run an app package: + +- **Manifest:** `AppManifest` and its parts, `SCHEMA`, `MANIFEST_FILE`, `parse`. +- **Policy:** `policy::resolve`, `HostLimits`, `AppPolicy` (the app-facing part: capabilities, network hosts, storage block, limits). +- **Integrity:** `digest_dir`, `bundle_digest`, `admit`, `admit_digest`, `SignatureVerifier`, `RefuseAllSignatures`. +- **Running a package:** `SCRIPT_ENTRY`, `script_source`, `ASSETS_PLACEHOLDER`, `AssetServer`, `StaticAssets`, `rewrite_assets`, and the Splash isolate settings an app is given (`IsolateSettings`, `splash_adapter::apply`). + +Everything else stays inside App Hub and may change freely: the catalog and store, listings, research scopes, the host service registry, agent session profiles, the Card runner. **No app depends on `octosense-app-hub` or `octosense-app-policy` directly any more**; Rinx's `miniapp-catalog` keeps its own catalog on top of the contract. `octosense-app-policy` itself depends on the contract and re-exports it, so App Hub and the shell keep one implementation. + +### 2. The stability rules + +Within `1.x`: + +- **Additive only.** New types, new functions, new optional manifest fields, new enum variants behind `#[non_exhaustive]`. Nothing is removed or renamed, and no existing field, default or rule changes meaning. A change that would break this is `2.0` (section 4). +- **Unknown manifest fields are classified, not ignored.** The strict parser stays, with one rule for growth, after PNG's critical chunks: + - every field added in `1.x` declares whether it is **optional** (a host that does not know it may run the app without it: it only adds information or asks for less) or **required** (it restricts or changes what the app gets); + - a manifest that uses required fields lists them in `requires: ["", …]`; a host that does not know a listed feature **refuses the app** with a clear message ("needs a newer host"); + - unknown fields that are not covered by a `requires` entry and are marked optional in the manifest's own `schema_minor` are ignored; anything else is still rejected. + + So an older host never runs an app with weaker rules than its author wrote, and a newer manifest field never breaks an older host unless it has to. +- **`schema` stays `1`** for the whole `1.x` line; `schema_minor` records which additions a manifest uses. +- **Behaviour is pinned by fixtures.** The contract crate keeps a corpus of real manifests and packages from every released `1.x`. Every release must accept all of them with the same resolved policy, digest and run settings; CI fails otherwise. + +### 3. Depend on the version, not a commit + +- `octosense-app-contract` is published to a registry, so consumers write `octosense-app-contract = "1"` and Cargo resolves one `1.x` for the whole build. No lockstep, no duplicate copies, no host-alias tricks. +- **Registry: crates.io (recommended)** because App Hub is public and Rinx and third-party apps can depend on it with no extra setup. The alternative is a private registry for the OctoSense org (Cloudsmith, Kellnr, or a git-index registry), at the cost of credentials in every consumer's CI. Plain git dependencies cannot work: Cargo never unifies two git commits. +- OctoSense's root `Cargo.toml` pins the exact contract version it ships with (`=1.y.z` in `Cargo.lock`); apps state the lowest `1.x` they need. Inside OctoSense, OctoSense's choice is what links. +- Rinx's CI builds against the lowest and the highest `1.x` it claims. + +### 4. Breaking changes + +A change that cannot be additive becomes `octosense-app-contract 2.0`. Hosts support `1.x` and `2.x` side by side for at least one OctoSense release (a manifest's `schema` picks the parser), apps move at their own pace, and `1.x` keeps getting security fixes until the transition ends. This should be rare and is decided in an ADR. + +### 5. Who changes the contract + +The contract crate lives in the App Hub repository under `crates/app-contract`, with its own changelog. A pull request that touches it needs review from App Hub and from one app owner (Rinx). CI runs: the fixture corpus, a public-API diff (`cargo public-api` or `cargo semver-checks`) that fails on any non-additive change within `1.x`, and Rinx's build against the new version. + +## Consequences + +- App Hub can change its store, catalog, Card runner and internal policy as often as needed without touching any app; only contract changes are coordinated, and those are additive by rule. +- Rinx releases when Rinx changes, not when App Hub does; OctoSense no longer needs host aliases or same-commit pins for App Hub. +- Manifests gain `requires` and `schema_minor`; older manifests (no `requires`) keep working unchanged. +- The contract surface is now public API: a deliberate cost, paid for with the fixture corpus and the API-diff check. +- Publishing adds a release step (a crates.io token in App Hub's CI) and a version to bump for each contract change. + +## Plan + +1. **Stopgap now:** restore OctoSense's `www.github.com` App Hub alias (dropped in #221), so #210 (App Hub 2a3d84b3) lands without a Rinx release. Rinx 1.0.3 is not made. +2. **App Hub:** create `crates/app-contract` with the section 1 surface, moved out of `app-policy` (which re-exports it); add `requires`/`schema_minor`; add the fixture corpus and the API-diff check; publish `1.0.0`. +3. **OctoSense:** depend on `octosense-app-contract = "1"` where the shell uses the contract; remove the App Hub alias. +4. **Rinx:** replace its `octosense-app-policy` and `octosense-app-hub` uses with the contract (about 30 call sites, plus its own catalog types); release as Rinx `1.1.0`, the last release coupled to an App Hub commit. +5. **Other apps** (AppCard, OctoScript tooling) follow the same rule when they next change. + +## Open questions + +- crates.io or a private registry (section 3). +- Whether `IsolateSettings` belongs in the contract (it is what a host gives an app) or stays host-side with a narrower contract type. diff --git a/docs/adr/README.md b/docs/adr/README.md index 141cdec0..08f20b1b 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -12,6 +12,7 @@ How these decisions fit together in the code on `main`, and which parts are stil | [0002](0002-event-driven-app-agents.md) | Event-driven app agents: apps think on their own triggers and publish cards to the glance screen | Proposed | | [0003](0003-shared-octos-client-access.md) | Talk to Octos: one kernel for native and external clients (opt-in) | Implemented; Android unverified | | [0004](0004-native-apps-hosting-and-peers.md) | Native apps, app agents and cross-app work: one manifest, hosting per target, an agent for every app, approvals by the person | Implemented | +| [0005](0005-app-contract.md) | The app contract: one small, versioned interface between App Hub and every app | Proposed | ## Home (phone shell) decisions, 2026-09-16 to 2026-09-25 diff --git a/docs/adr/README.zh-CN.md b/docs/adr/README.zh-CN.md index 3c579a6a..797adbac 100644 --- a/docs/adr/README.zh-CN.md +++ b/docs/adr/README.zh-CN.md @@ -12,6 +12,7 @@ OctoSense 仓库的决策:Shell、Shell 服务、系统应用,以及桌面 | [0002](0002-event-driven-app-agents.md)(英文) | 事件驱动的应用智能体:应用按自己的触发条件思考,并把卡片发布到一览屏 | 提议中 | | [0003](0003-shared-octos-client-access.md)(英文) | Talk to Octos:原生与外部客户端共用一个内核(需手动开启) | 已实现;Android 未验证 | | [0004](0004-native-apps-hosting-and-peers.md)(英文) | 原生应用、应用智能体与跨应用协作:一份清单、按目标平台托管、每个应用都有智能体、由本人批准 | 已实施 | +| [0005](0005-app-contract.md)(英文) | 应用契约:App Hub 与每个应用之间一个小而带版本的接口 | 提议中 | ## Home(手机 Shell)的决策,2026-09-16 至 2026-09-25 From 023b6a59b972d97652a26a1e32a160aeea4edc58 Mon Sep 17 00:00:00 2001 From: ymote <151983+ymote@users.noreply.github.com> Date: Wed, 30 Sep 2026 19:48:24 -0700 Subject: [PATCH 2/4] docs(adr): 0005 review decisions: crates.io; sandbox settings stay host-side [skip ci] - Registry: crates.io. - The contract fixes what an app may do (AppPolicy); each host builds its own sandbox from it and may only restrict further. IsolateSettings and the Splash adapter leave the contract (an optional, non-contract helper crate). Co-Authored-By: Claude Opus 5.5 --- docs/adr/0005-app-contract.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/adr/0005-app-contract.md b/docs/adr/0005-app-contract.md index a856fbff..38e4009d 100644 --- a/docs/adr/0005-app-contract.md +++ b/docs/adr/0005-app-contract.md @@ -38,7 +38,9 @@ App Hub publishes **`octosense-app-contract`**, versioned `1.x`, holding only wh - **Manifest:** `AppManifest` and its parts, `SCHEMA`, `MANIFEST_FILE`, `parse`. - **Policy:** `policy::resolve`, `HostLimits`, `AppPolicy` (the app-facing part: capabilities, network hosts, storage block, limits). - **Integrity:** `digest_dir`, `bundle_digest`, `admit`, `admit_digest`, `SignatureVerifier`, `RefuseAllSignatures`. -- **Running a package:** `SCRIPT_ENTRY`, `script_source`, `ASSETS_PLACEHOLDER`, `AssetServer`, `StaticAssets`, `rewrite_assets`, and the Splash isolate settings an app is given (`IsolateSettings`, `splash_adapter::apply`). +- **Running a package:** `SCRIPT_ENTRY`, `script_source`, `ASSETS_PLACEHOLDER`, `AssetServer`, `StaticAssets`, `rewrite_assets`. + +**What an app may do is in the contract; how a host sandboxes it is not (decided 2026-09-30).** The contract's `AppPolicy` fixes the app's permissions and limits: capabilities, network hosts, storage, budgets. Each host turns that into its own sandbox settings (App Hub's `IsolateSettings`, `splash_adapter::apply`, Rinx's own Splash setup), under one rule: **a host may restrict more than `AppPolicy` says, never less.** Hosts can evolve their sandboxes freely. App Hub may publish its Splash setup as a separate helper crate for other hosts to reuse, but that helper is not part of the contract and carries no stability promise. The fixture corpus checks `AppPolicy`, not any host's settings. Everything else stays inside App Hub and may change freely: the catalog and store, listings, research scopes, the host service registry, agent session profiles, the Card runner. **No app depends on `octosense-app-hub` or `octosense-app-policy` directly any more**; Rinx's `miniapp-catalog` keeps its own catalog on top of the contract. `octosense-app-policy` itself depends on the contract and re-exports it, so App Hub and the shell keep one implementation. @@ -59,7 +61,7 @@ Within `1.x`: ### 3. Depend on the version, not a commit - `octosense-app-contract` is published to a registry, so consumers write `octosense-app-contract = "1"` and Cargo resolves one `1.x` for the whole build. No lockstep, no duplicate copies, no host-alias tricks. -- **Registry: crates.io (recommended)** because App Hub is public and Rinx and third-party apps can depend on it with no extra setup. The alternative is a private registry for the OctoSense org (Cloudsmith, Kellnr, or a git-index registry), at the cost of credentials in every consumer's CI. Plain git dependencies cannot work: Cargo never unifies two git commits. +- **Registry: crates.io (decided 2026-09-30).** App Hub's source is already public, and Rinx, OctoSense and third-party apps can depend on it with no credentials or setup. A published version can never be deleted, only yanked, so releases go through review. A private registry was the alternative, rejected because every consumer's CI and machine would need a token and outside app developers could not use it. Plain git dependencies cannot work: Cargo never unifies two git commits. - OctoSense's root `Cargo.toml` pins the exact contract version it ships with (`=1.y.z` in `Cargo.lock`); apps state the lowest `1.x` they need. Inside OctoSense, OctoSense's choice is what links. - Rinx's CI builds against the lowest and the highest `1.x` it claims. @@ -82,12 +84,12 @@ The contract crate lives in the App Hub repository under `crates/app-contract`, ## Plan 1. **Stopgap now:** restore OctoSense's `www.github.com` App Hub alias (dropped in #221), so #210 (App Hub 2a3d84b3) lands without a Rinx release. Rinx 1.0.3 is not made. -2. **App Hub:** create `crates/app-contract` with the section 1 surface, moved out of `app-policy` (which re-exports it); add `requires`/`schema_minor`; add the fixture corpus and the API-diff check; publish `1.0.0`. +2. **App Hub:** create `crates/app-contract` with the section 1 surface, moved out of `app-policy` (which re-exports it); add `requires`/`schema_minor`; add the fixture corpus and the API-diff check; set up a crates.io publishing token in App Hub's release workflow; publish `1.0.0`. 3. **OctoSense:** depend on `octosense-app-contract = "1"` where the shell uses the contract; remove the App Hub alias. -4. **Rinx:** replace its `octosense-app-policy` and `octosense-app-hub` uses with the contract (about 30 call sites, plus its own catalog types); release as Rinx `1.1.0`, the last release coupled to an App Hub commit. +4. **Rinx:** replace its `octosense-app-policy` and `octosense-app-hub` uses with the contract (about 30 call sites, plus its own catalog types), and build its mini-app sandbox from `AppPolicy` (or App Hub's optional helper crate); release as Rinx `1.1.0`, the last release coupled to an App Hub commit. 5. **Other apps** (AppCard, OctoScript tooling) follow the same rule when they next change. -## Open questions +## Decided on review (2026-09-30) -- crates.io or a private registry (section 3). -- Whether `IsolateSettings` belongs in the contract (it is what a host gives an app) or stays host-side with a narrower contract type. +- **Registry:** crates.io (section 3). +- **Sandbox settings:** not in the contract. The contract fixes what an app may do (`AppPolicy`); each host builds its own sandbox from that and may only restrict further (section 1). From 570e0973b071e3f75bc36caa270ac83603b5f529 Mon Sep 17 00:00:00 2001 From: ymote <151983+ymote@users.noreply.github.com> Date: Wed, 30 Sep 2026 20:27:58 -0700 Subject: [PATCH 3/4] docs(adr): accept ADR 0005 [skip ci] Co-Authored-By: Claude Opus 5.5 --- docs/adr/0005-app-contract.md | 2 +- docs/adr/README.md | 2 +- docs/adr/README.zh-CN.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/adr/0005-app-contract.md b/docs/adr/0005-app-contract.md index 38e4009d..7dc69a53 100644 --- a/docs/adr/0005-app-contract.md +++ b/docs/adr/0005-app-contract.md @@ -1,7 +1,7 @@ # ADR 0005: The app contract: one small, versioned interface between App Hub and every app - **Date:** 2026-09-30 -- **Status:** Proposed +- **Status:** Accepted (2026-09-30) - **Scope:** What an app (a mini app, a script app, or a native app that runs other apps, such as Rinx) may depend on from App Hub; how that interface is versioned and kept stable; how OctoSense and apps depend on it so that App Hub changes never force an app release. - **Relates to:** [ADR 0002](0002-event-driven-app-agents.md) (app manifests and agents); [ADR 0004](0004-native-apps-hosting-and-peers.md) (native apps, storage contract); App Hub `crates/app-policy`; hagency-org/Rinx#37 (Rinx release tags, point 6: break the App Hub lockstep). diff --git a/docs/adr/README.md b/docs/adr/README.md index 08f20b1b..11c7457c 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -12,7 +12,7 @@ How these decisions fit together in the code on `main`, and which parts are stil | [0002](0002-event-driven-app-agents.md) | Event-driven app agents: apps think on their own triggers and publish cards to the glance screen | Proposed | | [0003](0003-shared-octos-client-access.md) | Talk to Octos: one kernel for native and external clients (opt-in) | Implemented; Android unverified | | [0004](0004-native-apps-hosting-and-peers.md) | Native apps, app agents and cross-app work: one manifest, hosting per target, an agent for every app, approvals by the person | Implemented | -| [0005](0005-app-contract.md) | The app contract: one small, versioned interface between App Hub and every app | Proposed | +| [0005](0005-app-contract.md) | The app contract: one small, versioned interface between App Hub and every app | Accepted | ## Home (phone shell) decisions, 2026-09-16 to 2026-09-25 diff --git a/docs/adr/README.zh-CN.md b/docs/adr/README.zh-CN.md index 797adbac..30880363 100644 --- a/docs/adr/README.zh-CN.md +++ b/docs/adr/README.zh-CN.md @@ -12,7 +12,7 @@ OctoSense 仓库的决策:Shell、Shell 服务、系统应用,以及桌面 | [0002](0002-event-driven-app-agents.md)(英文) | 事件驱动的应用智能体:应用按自己的触发条件思考,并把卡片发布到一览屏 | 提议中 | | [0003](0003-shared-octos-client-access.md)(英文) | Talk to Octos:原生与外部客户端共用一个内核(需手动开启) | 已实现;Android 未验证 | | [0004](0004-native-apps-hosting-and-peers.md)(英文) | 原生应用、应用智能体与跨应用协作:一份清单、按目标平台托管、每个应用都有智能体、由本人批准 | 已实施 | -| [0005](0005-app-contract.md)(英文) | 应用契约:App Hub 与每个应用之间一个小而带版本的接口 | 提议中 | +| [0005](0005-app-contract.md)(英文) | 应用契约:App Hub 与每个应用之间一个小而带版本的接口 | 已接受 | ## Home(手机 Shell)的决策,2026-09-16 至 2026-09-25 From 16d58e0018938704471afc066ea55d59be7f7f46 Mon Sep 17 00:00:00 2001 From: ymote <151983+ymote@users.noreply.github.com> Date: Thu, 1 Oct 2026 00:42:11 -0700 Subject: [PATCH 4/4] docs(adr): ADR 0005 implemented (#243) [skip ci] Co-Authored-By: Claude Opus 5.5 --- docs/adr/0005-app-contract.md | 2 +- docs/adr/README.md | 2 +- docs/adr/README.zh-CN.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/adr/0005-app-contract.md b/docs/adr/0005-app-contract.md index 7dc69a53..53fe7827 100644 --- a/docs/adr/0005-app-contract.md +++ b/docs/adr/0005-app-contract.md @@ -1,7 +1,7 @@ # ADR 0005: The app contract: one small, versioned interface between App Hub and every app - **Date:** 2026-09-30 -- **Status:** Accepted (2026-09-30) +- **Status:** Accepted (2026-09-30); **Implemented** (2026-10-01): `octosense-app-contract` 1.0.0 on crates.io (App Hub [#46](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/46), [#47](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/47)); Rinx 1.1.0 depends on it and on no App Hub commit (hagency-org/Rinx [#49](https://github.com/hagency-org/Rinx/pull/49), tag `v1.1.0`); OctoSense takes the contract from crates.io, pins Rinx by tag and has no App Hub host alias ([#243](https://github.com/OctoSense-org/OctoSense/pull/243)). Not yet exercised on a device: Rinx's own mini-app catalog and sandbox (they sit behind a Matrix sign-in). - **Scope:** What an app (a mini app, a script app, or a native app that runs other apps, such as Rinx) may depend on from App Hub; how that interface is versioned and kept stable; how OctoSense and apps depend on it so that App Hub changes never force an app release. - **Relates to:** [ADR 0002](0002-event-driven-app-agents.md) (app manifests and agents); [ADR 0004](0004-native-apps-hosting-and-peers.md) (native apps, storage contract); App Hub `crates/app-policy`; hagency-org/Rinx#37 (Rinx release tags, point 6: break the App Hub lockstep). diff --git a/docs/adr/README.md b/docs/adr/README.md index 11c7457c..cec497ee 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -12,7 +12,7 @@ How these decisions fit together in the code on `main`, and which parts are stil | [0002](0002-event-driven-app-agents.md) | Event-driven app agents: apps think on their own triggers and publish cards to the glance screen | Proposed | | [0003](0003-shared-octos-client-access.md) | Talk to Octos: one kernel for native and external clients (opt-in) | Implemented; Android unverified | | [0004](0004-native-apps-hosting-and-peers.md) | Native apps, app agents and cross-app work: one manifest, hosting per target, an agent for every app, approvals by the person | Implemented | -| [0005](0005-app-contract.md) | The app contract: one small, versioned interface between App Hub and every app | Accepted | +| [0005](0005-app-contract.md) | The app contract: one small, versioned interface between App Hub and every app | Implemented | ## Home (phone shell) decisions, 2026-09-16 to 2026-09-25 diff --git a/docs/adr/README.zh-CN.md b/docs/adr/README.zh-CN.md index 30880363..cdaaab09 100644 --- a/docs/adr/README.zh-CN.md +++ b/docs/adr/README.zh-CN.md @@ -12,7 +12,7 @@ OctoSense 仓库的决策:Shell、Shell 服务、系统应用,以及桌面 | [0002](0002-event-driven-app-agents.md)(英文) | 事件驱动的应用智能体:应用按自己的触发条件思考,并把卡片发布到一览屏 | 提议中 | | [0003](0003-shared-octos-client-access.md)(英文) | Talk to Octos:原生与外部客户端共用一个内核(需手动开启) | 已实现;Android 未验证 | | [0004](0004-native-apps-hosting-and-peers.md)(英文) | 原生应用、应用智能体与跨应用协作:一份清单、按目标平台托管、每个应用都有智能体、由本人批准 | 已实施 | -| [0005](0005-app-contract.md)(英文) | 应用契约:App Hub 与每个应用之间一个小而带版本的接口 | 已接受 | +| [0005](0005-app-contract.md)(英文) | 应用契约:App Hub 与每个应用之间一个小而带版本的接口 | 已实施 | ## Home(手机 Shell)的决策,2026-09-16 至 2026-09-25