Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
97752e1
feat(git): add short-lived Gitoxide admission helper
zhiiw Aug 23, 2026
3453011
fix(git): classify unsupported repository formats
zhiiw Aug 23, 2026
f37f761
feat(git): bind helper artifacts to opaque capabilities
zhiiw Aug 23, 2026
39b5ebf
feat(git): own short-lived helper invocations
zhiiw Aug 23, 2026
514c9d2
feat(git): issue repository admission capabilities
zhiiw Aug 23, 2026
728a950
test(git): isolate concurrent helper fixtures
zhiiw Aug 23, 2026
f421c33
feat(git): import admitted source heads
zhiiw Aug 23, 2026
8b55588
build(git): lock source import dependency
zhiiw Aug 23, 2026
2348d69
fix(git): bound managed tree traversal
zhiiw Aug 24, 2026
59d62ce
fix(runtime-host): preserve tree policy failures
zhiiw Aug 24, 2026
5bf0ef4
style(gitoxide): match pinned Rust formatting
zhiiw Aug 24, 2026
dd5430f
fix(gitoxide): make source import restartable
zhiiw Aug 24, 2026
66e5341
feat(git): publish exact-base successors
zhiiw Aug 23, 2026
25f56f6
build(git): enable tree editing
zhiiw Aug 23, 2026
c739ed9
fix(git): validate complete successor trees
zhiiw Aug 24, 2026
24830e5
feat(git): materialize exact projections
zhiiw Aug 23, 2026
2a24596
style(git): format projection helper
zhiiw Aug 23, 2026
59fe107
fix(git): enforce one managed tree policy
zhiiw Aug 24, 2026
db9cd19
feat(release): package the Gitoxide helper authority
zhiiw Aug 23, 2026
59d1ad7
feat(git): read files from accepted trees
zhiiw Aug 23, 2026
c274f59
fix(ci): pin the Gitoxide release toolchain
zhiiw Aug 23, 2026
2155999
fix(git): retain helper-owned blob storage
zhiiw Aug 23, 2026
8bc2622
fix(release): cover dual-licensed Cargo crates
zhiiw Aug 23, 2026
99b0ad0
fix(git): verify accepted blob identity
zhiiw Aug 24, 2026
798dbf6
fix(runtime-host): bind helper resolution to packaged resources
zhiiw Aug 24, 2026
575de40
fix(git): align direct reads with tree policy
zhiiw Aug 24, 2026
d110452
feat(runtime-host): rebuild managed npm producer boundary
zhiiw Aug 23, 2026
cb7210c
test(windows): inventory managed producer contracts
zhiiw Aug 23, 2026
6c7159b
docs(runtime-host): license the managed producer contract
zhiiw Aug 23, 2026
4d2d798
fix(runtime-host): reject unsafe lockfile package paths
zhiiw Aug 24, 2026
a2d933a
feat(runtime-host): attest managed npm runtime
zhiiw Aug 23, 2026
84d0d72
docs(runtime-host): license the npm attestation contract
zhiiw Aug 23, 2026
74c10af
test(runtime-host): preserve producer path policy
zhiiw Aug 24, 2026
dd18177
fix(runtime-host): make npm attestation the sole issuer
zhiiw Aug 24, 2026
22bcc40
Merge branch 'codex/m1-3-npm-attestation-rebuild' into codex/m1-3-git…
zhiiw Aug 24, 2026
946a059
Merge branch 'codex/gitoxide-packaged-helper-authority' into codex/m1…
zhiiw Aug 24, 2026
096bfeb
Merge branch 'codex/gitoxide-tree-file-data-plane' into codex/m1-3-gi…
zhiiw Aug 24, 2026
6e0429c
feat(runtime-host): compose Gitoxide managed inspection
zhiiw Aug 23, 2026
5a27697
fix(runtime-host): route managed inspection minimally
zhiiw Aug 24, 2026
26d955b
feat(git): add short-lived Gitoxide admission helper
zhiiw Aug 23, 2026
6f1d6c4
fix(git): classify unsupported repository formats
zhiiw Aug 23, 2026
b1d4e67
feat(git): bind helper artifacts to opaque capabilities
zhiiw Aug 23, 2026
08da1fb
feat(git): own short-lived helper invocations
zhiiw Aug 23, 2026
a45ce4b
feat(git): issue repository admission capabilities
zhiiw Aug 23, 2026
4e5333c
test(git): isolate concurrent helper fixtures
zhiiw Aug 23, 2026
303ce56
feat(git): import admitted source heads
zhiiw Aug 23, 2026
83c5e09
build(git): lock source import dependency
zhiiw Aug 23, 2026
a00d338
fix(git): bound managed tree traversal
zhiiw Aug 24, 2026
c930347
fix(runtime-host): preserve tree policy failures
zhiiw Aug 24, 2026
94ab9af
feat(git): publish exact-base successors
zhiiw Aug 23, 2026
d3f749b
build(git): enable tree editing
zhiiw Aug 23, 2026
081a57e
fix(git): validate complete successor trees
zhiiw Aug 24, 2026
05f0148
feat(runtime-host): prepare owner-bound Gitoxide candidates
zhiiw Aug 23, 2026
8ddc864
feat(runtime-host): persist Gitoxide candidate receipts
zhiiw Aug 23, 2026
eca997b
test(runtime-host): bind candidates to imported baseline
zhiiw Aug 23, 2026
4ebfac7
fix(runtime-host): release candidate ref before CAS
zhiiw Aug 23, 2026
94a021b
fix(runtime-host): close candidate observation before CAS
zhiiw Aug 23, 2026
f88ea9e
fix(gitoxide): publish candidates in one ref transaction
zhiiw Aug 23, 2026
3cc4374
diagnostics(gitoxide): report ref transaction failures
zhiiw Aug 23, 2026
4cc1560
diagnostics(runtime-host): surface helper ref errors
zhiiw Aug 23, 2026
0776977
diagnostics(gitoxide): include ref failure chain
zhiiw Aug 23, 2026
63a064f
fix(gitoxide): create the candidate ref namespace
zhiiw Aug 23, 2026
8881e8b
fix(runtime-host): bound Gitoxide artifact path lengths
zhiiw Aug 23, 2026
71458f2
fix(runtime-host): bind candidate proofs to receipts
zhiiw Aug 24, 2026
aec531f
fix(runtime-host): require candidate storage ownership
zhiiw Aug 24, 2026
051e4ea
style(gitoxide): match pinned Rust formatting
zhiiw Aug 24, 2026
8313bab
fix(gitoxide): make source import restartable
zhiiw Aug 24, 2026
173674f
Merge branch 'codex/m2-2-gitoxide-candidate-owner-v2' into codex/tmp-…
zhiiw Aug 24, 2026
ccdf71b
Merge branch 'codex/m1-3-gitoxide-product-composition-v2' into codex/…
zhiiw Aug 24, 2026
f80f966
feat(runtime-host): accept Gitoxide mutation candidates
zhiiw Aug 23, 2026
ce590ab
feat(runtime): execute managed mutations as Git transforms
zhiiw Aug 23, 2026
7941af2
feat(runtime): hand managed outcome proof to settlement owner
zhiiw Aug 23, 2026
011ec01
feat(storage): bind workspace settlement to execution stores
zhiiw Aug 23, 2026
362b5a2
feat(runtime-host): settle Gitoxide managed mutations
zhiiw Aug 23, 2026
5947189
feat(storage): settle managed no-effect outcomes atomically
zhiiw Aug 23, 2026
18eb976
feat(runtime): close managed mutation terminal states
zhiiw Aug 23, 2026
190fe51
feat(runtime-host): compose Gitoxide managed coding sessions
zhiiw Aug 23, 2026
fb1fe60
test(runtime-host): exercise real Gitoxide managed sessions
zhiiw Aug 23, 2026
ded4911
test(runtime-host): prove successor projection recovery
zhiiw Aug 23, 2026
062b781
docs(runtime): record Gitoxide projection crash proof
zhiiw Aug 23, 2026
55f26b6
fix(runtime-host): align real Gitoxide session contracts
zhiiw Aug 23, 2026
ee94ccf
test(runtime-host): align managed dispatch identity
zhiiw Aug 23, 2026
2a9e4ff
fix(runtime-host): replay promoted Gitoxide candidates
zhiiw Aug 23, 2026
80fb34a
fix(runtime-host): route managed coding through Gitoxide
zhiiw Aug 24, 2026
3422000
fix(runtime-host): preserve managed mutation ownership
zhiiw Aug 24, 2026
5829cdf
docs(runtime): define helper upgrade and crash scope
zhiiw Aug 24, 2026
6ac4a52
fix(runtime-host): bind managed epochs to helper artifact
zhiiw Aug 24, 2026
44759be
fix(runtime-host): close managed mutation recovery authority
zhiiw Aug 24, 2026
8512c78
fix(core): encode frozen durable runtime events
zhiiw Aug 24, 2026
ef9cd83
fix(release): pin Windows upgrade source authority
zhiiw Aug 24, 2026
998774a
fix(runtime-host): close managed mutation recovery
zhiiw Aug 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions .github/workflows/gitoxide-helper-admission.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

name: Gitoxide helper admission

on:
pull_request:
paths:
- '.github/workflows/gitoxide-helper-admission.yml'
- 'native/gitoxide-helper/**'
- 'packages/runtime-host/src/server/gitoxide-helper-*.ts'
- 'packages/runtime-host/src/__tests__/gitoxide-helper-*.test.ts'
- 'packages/runtime-host/src/server/gitoxide-managed-inspection.ts'
- 'packages/runtime-host/src/__tests__/gitoxide-managed-inspection.test.ts'
- 'packages/runtime-host/src/server/gitoxide-managed-*.ts'
- 'packages/runtime-host/src/__tests__/gitoxide-managed-*.test.ts'
- 'packages/runtime-host/src/server/packaged-gitoxide-helper-internal.ts'
- 'packages/runtime-host/src/__tests__/packaged-gitoxide-helper.test.ts'
- 'scripts/prepare-gitoxide-helper*'
- 'scripts/generate-gitoxide-cargo-notices.mjs'
- 'apps/desktop/electron-builder.config.mjs'
- 'docs/architecture/gitoxide-*.md'
push:
branches:
- main
paths:
- '.github/workflows/gitoxide-helper-admission.yml'
- 'native/gitoxide-helper/**'
- 'packages/runtime-host/src/server/gitoxide-helper-*.ts'
- 'packages/runtime-host/src/__tests__/gitoxide-helper-*.test.ts'
- 'packages/runtime-host/src/server/gitoxide-managed-inspection.ts'
- 'packages/runtime-host/src/__tests__/gitoxide-managed-inspection.test.ts'
- 'packages/runtime-host/src/server/gitoxide-managed-*.ts'
- 'packages/runtime-host/src/__tests__/gitoxide-managed-*.test.ts'
- 'packages/runtime-host/src/server/packaged-gitoxide-helper-internal.ts'
- 'packages/runtime-host/src/__tests__/packaged-gitoxide-helper.test.ts'
- 'scripts/prepare-gitoxide-helper*'
- 'scripts/generate-gitoxide-cargo-notices.mjs'
- 'apps/desktop/electron-builder.config.mjs'
- 'docs/architecture/gitoxide-*.md'

permissions:
contents: read

concurrency:
group: gitoxide-helper-admission-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22.19.0
cache: npm
- name: Check Rust formatting
working-directory: native/gitoxide-helper
run: cargo fmt --check
- name: Test the short-lived Gitoxide helper
working-directory: native/gitoxide-helper
run: cargo test --locked
- name: Build the release helper
run: npm run build:gitoxide-helper
- name: Install JavaScript dependencies without packaging hooks
run: npm ci --ignore-scripts
- name: Prepare and license the packaged helper
run: >-
npm run prepare:gitoxide-helper &&
npm run generate:gitoxide-cargo-notices &&
node --test scripts/prepare-gitoxide-helper.test.mjs
- name: Build the helper invocation owner
run: >-
npm --workspace @maka/core run build &&
npm --workspace @maka/storage run build &&
npm --workspace @maka/runtime run build &&
npm --workspace @maka/runtime-host run build
- name: Test the real helper invocation contract
env:
MAKA_GITOXIDE_HELPER_PATH: ${{ github.workspace }}/native/gitoxide-helper/target/debug/maka-gitoxide-helper${{ runner.os == 'Windows' && '.exe' || '' }}
run: >-
node --test
packages/runtime-host/dist/__tests__/gitoxide-helper-artifact-authority-internal.test.js
packages/runtime-host/dist/__tests__/gitoxide-helper-invocation-internal.test.js
packages/runtime-host/dist/__tests__/gitoxide-helper-mutation-candidate-authority-internal.test.js
packages/runtime-host/dist/__tests__/gitoxide-repository-admission-authority-internal.test.js
packages/runtime-host/dist/__tests__/gitoxide-managed-inspection.test.js
packages/runtime-host/dist/__tests__/gitoxide-managed-mutation-admission.test.js
packages/runtime-host/dist/__tests__/gitoxide-managed-mutation-session.test.js
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,15 @@ docs/assets/
apps/desktop/tests/real-window-smoke/
deepseek.key

# Built only by the dedicated Gitoxide helper lane; normal workspace tests do not use Cargo.
/native/gitoxide-helper/target/

# Generated Computer Use executor binary; provenance metadata stays tracked.
apps/desktop/resources/bin/
# Rebuilt from experiments/windows-sandbox by scripts/package-windows-x64.mjs.
apps/desktop/resources/windows-sandbox/
apps/desktop/bundled-git.json
apps/desktop/.generated/bundled-npm/

# Generated desktop release inputs and outputs.
apps/desktop/resources/tools/
Expand Down
24 changes: 24 additions & 0 deletions apps/desktop/electron-builder.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@ export default {
'dist/renderer/computer-use-overlay/**',
],
extraResources: [
{
from: '.generated/bundled-npm/npm',
to: 'npm',
},
{
from: '.generated/bundled-npm/bundled-npm.json',
to: 'bundled-npm.json',
},
{
from: '.generated/gitoxide-helper/gitoxide',
to: 'gitoxide',
},
{
from: '.generated/gitoxide-helper/gitoxide-helper.json',
to: 'gitoxide-helper.json',
},
{
from: '.generated/gitoxide-helper/THIRD_PARTY_NOTICES.txt',
to: 'licenses/gitoxide-helper/THIRD_PARTY_NOTICES.txt',
},
{
from: 'bundled-tools.json',
to: 'bundled-tools.json',
Expand Down Expand Up @@ -105,6 +125,10 @@ export default {
from: '../../LICENSE',
to: 'licenses/maka/LICENSE',
},
{
from: '../../node_modules/npm/LICENSE',
to: 'licenses/npm-cli/LICENSE',
},
{
from: '../../NOTICE',
to: 'licenses/maka/NOTICE',
Expand Down
148 changes: 148 additions & 0 deletions docs/architecture/bundled-npm-runtime-attestation-v1.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->

---
document_status: implementation-contract
status: draft-stacked-foundation
date: 2026-08-24
milestone: M1.3
stack_base: codex/m1-3-managed-npm-producer-rebuild@53721ce09
---

# Bundled npm Runtime Attestation v1

## 1. 本 PR 只证明一个主要不变量

> 在调用方已经取得“来自 Maka 已签名发布物”的 resources-root authority 后,固定 npm producer 只能使用其中完整清单验证通过、且绑定当前受支持 Host Node 的 npm 运行闭包;调用者不能通过伪造结构体、传入任意 executable 或在签发后替换 npm 文件来取得执行权。

本 PR 的 owner 是 Runtime Host package 内部的 bundled npm attestation 模块。它拥有 npm 运行树 manifest 的解码、完整文件清单校验、Host Node 版本与 executable identity、不可伪造 capability 的签发和每次调用前的重新验证。

这里必须区分两层证明:外层应用签名与平台发布链提供 **provenance trust**,本模块的 manifest 提供 **runtime integrity**。manifest 与 npm tree 位于同一资源目录,攻击者若能同时替换二者并重算摘要,本模块本身无法识别;它绝不是自足的密码学信任根。PR 3 的 API 合同因此有一个显式前置条件:`resourcesRoot` 必须已经由后续 packaged-process owner 认证。本 PR 单独只能证明“受权目录在 admission 与每次 invocation 时没有发生未声明变化”,不能证明任意目录来自 Maka。

本 PR 不包含 Desktop/CLI/Runtime Host composition 的生产 consumer。attestation resolver、capability issuer 和固定 npm provision 入口不通过 `@maka/runtime-host/server` 公共 barrel 暴露;后续 Gitoxide product composition 必须在固定 `resourcesPath` owner 中把三者接通。因此本 PR 保持 Draft,不能单独宣称 M1.3 已可用。

## 2. 为什么只 bundled npm,不再 bundled 一份 Node

Maka 已经由 Electron 或当前受控 Runtime Host 携带 Node。再打包第二份 Node 会增加包体、补丁与许可证维护面,并制造“两套 Node authority”。v1 直接绑定当前 Host runtime:

```text
process.execPath canonical path + SHA-256
+ process.versions.node
+ process.versions.modules (ABI)
+ platform / arch
+ 完整 npm tree manifest
= ManagedNpmRuntimeCapability
```

Node 支持范围采用有限 allowlist;未知未来 major 默认拒绝,必须经过 permission-model 兼容验证后显式加入。当前允许:

- Node 22.22.2 及同 major 后续版本;
- Node 24.15.0 及同 major 后续版本;
- Node 26.x;
- 其他 major 全部拒绝。

## 3. 发布闭包与供应链

发布准备从锁定的 `npm@12.0.2` 生成一个 Maka-owned runtime tree,并替换 npm 自带闭包中的四个已知脆弱版本:

| package | npm 原版本 | 发布版本 | 证据 |
| --- | --- | --- | --- |
| `tar` | 7.5.19 | 7.5.22 | GHSA-r292-9mhp-454m |
| `brace-expansion` | 5.0.7 | 5.0.9 | GHSA-mh99-v99m-4gvg;GHSA-rgw5-rvv9-x895 |
| `ip-address` | 10.2.0 | 10.4.0 | 三条 manifest 中固定的 GHSA |
| `undici` | 6.27.0 | 6.28.0 | 三条 manifest 中固定的 GHSA |

准备过程拒绝 symlink/junction,只接受 regular file/directory,输出:

```text
apps/desktop/.generated/bundled-npm/
npm/** 完整 npm runtime tree
bundled-npm.json 每个文件的 path、bytes、sha256
audit/package-lock.json 独立 production audit 视图
```

release gate 对独立 audit lock 执行 `npm audit --omit=dev --audit-level=high`。当前实际生成闭包约 14.6 MB,audit 为 0 vulnerabilities。生成目录不进入 Git;每次打包重新生成并验证。

## 4. 权限边界

`ManagedNpmRuntimeCapability` 的 TypeScript 形状不是权限。真实权限由 Runtime Host 模块内的 `WeakMap` 记录:只有 internal issuer 产生的对象才能通过消费 gate。结构相同的普通对象必须被拒绝。

签发器同样不属于公共 package API。否则任意调用者可以为自建目录生成“合法” capability,变成自认证。PR 4 的 composition owner 只能以打包应用的固定 resources root 调用 internal resolver,不能接受用户或 operation 传入的路径。

每次 npm invocation 前必须重新验证:

1. Host executable canonical path 未变;
2. Host executable digest 未变;
3. npm runtime 仍只含 regular files/directories;
4. 实际文件集合、大小与 SHA-256 完全匹配 manifest;
5. npm `package.json` 仍是 `npm@12.0.2`、`Artistic-2.0`。

任一项失败都在 spawn 前 fail closed。

## 5. 原子性、失败状态与回滚

本 PR 不写用户 workspace,也不产生 durable T1/T2。它的原子边界是“通过全部验证后签发 capability”;验证中途失败不产生 capability。

稳定失败分类:

- `bundled_npm_unavailable`:资源或 Host executable 不可读;
- `bundled_npm_manifest_invalid`:manifest 形状、路径或范围非法;
- `bundled_npm_platform_mismatch`:platform/arch 不匹配;
- `bundled_npm_integrity_mismatch`:文件集合、内容、版本或许可证不匹配;
- `bundled_npm_node_unsupported`:Host Node 不在验证 allowlist。

回滚本 PR 只需移除 npm release resources、manifest preparation 与 internal attestation 模块;PR 1 storage authority 和 PR 2 producer lifecycle 不需要回滚。没有兼容旧 manifest 的承诺:本能力尚无生产 consumer,格式变化应明确断代而不是建设迁移层。

## 6. 平台能力矩阵

| 能力 | Linux | macOS | Windows |
| --- | --- | --- | --- |
| regular-file tree inventory | 支持 | 支持 | 支持 |
| symlink/reparse input | 拒绝 | 拒绝 | 拒绝 junction/reparse |
| Host executable digest binding | 支持 | 支持;签名仍由外层 app 发布链保证 | 支持;Authenticode 仍由外层 app 发布链保证 |
| 每 invocation tree revalidation | 支持 | 支持 | 支持 |
| npm producer permission profile | Node permission model | Node permission model | Node permission model |

manifest 与 npm tree 一起受最终应用签名/发布物保护。macOS 的 trust root 是通过 Gatekeeper/代码签名发布的 app bundle;Windows 的 trust root 是 Authenticode 签名的安装包与已安装应用。Linux v1 没有统一的平台签名验证 API,因此只承诺由官方发布/更新链安装后的完整性检查,不把任意本机目录提升为可信发布物。manifest hash 本身不是独立信任根;如果恶意本机进程已经能替换已安装应用资源、伪造父进程或直接运行修改后的 Maka 代码,本层不声称独立抵抗该攻击。

同理,后续父子进程 bootstrap 只负责把已经取得的 application authority 传给 detached Host,防止普通 CLI 参数或 ambient path 被误当成发布资源;它不是 macOS code-signing/Windows Authenticode 的替代物,也不抵御能够任意创建 Electron 父进程和 fd channel 的同用户恶意进程。若产品威胁模型将该攻击者纳入边界,必须另行引入平台签名验证 owner,不能继续给 bootstrap 增加可伪造字段。

## 7. Crash / tamper matrix

| 时点 | 结果 |
| --- | --- |
| 准备 runtime tree 中途退出 | 生成目录不进入发布物;下一次 preparation 全量重建 |
| manifest 写入前退出 | release verifier 因 manifest 缺失失败 |
| manifest 与 tree 不一致 | runtime admission 拒绝 |
| capability 签发后 npm 文件被修改 | 下一次 invocation 在 spawn 前拒绝 |
| capability 被结构化伪造 | WeakMap gate 拒绝 |
| Host Node 被替换 | canonical path/digest revalidation 拒绝 |
| platform/arch 不一致 | admission 拒绝 |

## 8. Gitoxide product composition 的硬前置

后续 composition 才能增加首个生产 consumer,并必须同时证明:

1. Desktop/Runtime Host 只从固定 packaged `resourcesPath` 解析 npm;
2. Gitoxide admission/import/projection capability、storage authority、producer owner、runtime capability 由同一 composition 生命周期持有,且不得恢复 Git CLI owner;
3. production-shaped 测试使用实际生成的 npm tree,从 hermetic loopback registry 安装一个真实 tarball package,验证解包与 `.bin` 生成后再完成依赖环境 acquire;
4. runtime identity 写入 dependency environment identity,不能由调用者自报;
5. shutdown 顺序先停止新 acquire,再 drain producer,最后关闭 storage authority。

在这五项完成以前,PR 1–3 都只是可独立审查的 stacked foundation,不是用户能力。
54 changes: 54 additions & 0 deletions docs/architecture/gitoxide-fresh-projection-data-plane-v1.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->

# Gitoxide fresh projection 数据面 v1

状态:API-only stacked Draft。该切片不做 canonical-path rotation、quarantine、Desktop/CLI 接线或 Write/Edit 恢复。

## 主要不变量

只有 owner-bound managed-repository capability 可以把其绑定的 exact accepted commit 物化到此前不存在的 staging 目录;只有物化成功后签发的 projection capability 可以重新观察该路径。clean 只表示 projection 中的全部路径、类型、内容和 POSIX executable bit 与 immutable Git tree 完全一致。

## Owner 与原子性边界

- caller 只能选择 owner 管理下的 fresh destination;repository path、commit 与 tree 来自 capability,不能重新提交;
- Gitoxide helper 以 `create_dir` 获得 fresh-root 线性化点,文件使用 `create_new`,不写 `.git`,不创建 linked worktree;
- source import 已拒绝 symlink/submodule、非 UTF-8、大小写/NFC collision、`.git` 与 `.gitattributes`,projection 再次 fail closed 校验这些 entry;
- 每个普通文件有 64 MiB 上限,整棵 tree 有 2 GiB/200k 文件上限;
- observer 使用 bounded read 和 Git blob identity,拒绝缺失、额外、类型变化、内容变化与 POSIX executable-mode drift;打开普通文件时使用 no-follow 标志;
- helper 在响应丢失后遇到已存在目录,只在它仍精确等于 accepted tree 时返回相同 materialization response;partial/drifted 目录不会被静默覆盖。

## 失败状态与回滚

- materialization 中进程退出:staging 可能部分存在,但没有 `.git` 能力、没有 accepted-head 变化;composition owner 必须隔离或删除其私有 staging 后重试;
- destination 已存在且不精确:`projection_destination_not_fresh`;helper 不删除任何用户路径;
- projection drift:返回结构化 `projection_drifted` 与首个确定性 reason/path;不修改 projection;
- power-loss durability 不在 v1 合同内;v1 只证明正常完成和 process-crash 后的 fail-closed/retry 边界。

## 平台能力矩阵

| 平台 | v1 承诺 |
| --- | --- |
| Linux | exact materialization/observation;POSIX executable mode;`O_NOFOLLOW` |
| macOS | 同 Linux;普通 fsync 不提升为 power-loss 承诺 |
| Windows | exact content/path/type;Git executable bit 不映射为 NTFS ACL;reparse-point 路径不作为普通文件读取 |

## 后续消费

M1.3 product composition 将拥有 storage-root、staging 命名、partial staging cleanup、canonical projection publication 与 lifecycle。M2.2/M2.4 只在这套 Gitoxide 数据面完成后重建,不再依赖 system/bundled Git CLI。
Loading
Loading