Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,29 @@ jobs:
run: npm ci --ignore-scripts --no-audit --no-fund
- name: Prove cross-UID model worker cannot read Host key or SQLite DB
run: node tests/security/host-isolation.mjs
- name: Verify the disposable Linux Host profile
if: ${{ matrix.node == '24.22.1' }}
run: sudo -n "$(command -v node)" tests/security/secure-host-linux.mjs
- name: Prove M6 Host and isolated worker integration
env:
FLOWKIT_M6_ISOLATION: '1'
run: node --test tests/integration/m6-e2e.test.mjs

host-security-windows-profile:
name: Host OS-user isolation / Windows
runs-on: windows-2025
timeout-minutes: 8
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: '24.22.1'
- name: Verify the disposable Windows Host profile
shell: powershell
run: .\tests\security\secure-host-windows.ps1 -Node (Get-Command node.exe).Source -DisposableRunner

website:
runs-on: ubuntu-24.04
timeout-minutes: 15
Expand Down
49 changes: 49 additions & 0 deletions docs/evidence/p0a-g01-20261112/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# G01 — P0-A 正式契约审查

**审查已执行;符合性未通过,待独立复审。** 已完整读取三份确认原件,逐项核对 [追踪表](./traceability.md) 中的 34 T / 22 R / 14 S / 31 计划任务及下文 §§1–18。结论是发现明确缺口、契约差异和未证明的场景。此阶段只交证据,没有修改 Core、ABI、Store、SDK 或 Standard,也没有进入 G04。

审查基线:`21b02e785cacf703c359d7d4f853b8196aa17b19`,树 `3beb2ef618d1061b184ddb774512c4d827783db7`,与合并 [G02 PR #21](https://github.com/devcodex-labs/flowkit/pull/21) 后的 main `5a82a88160e01b0e9e2e457dea6af1e3db2c54e0` 同树。[Draft PR #22](https://github.com/devcodex-labs/flowkit/pull/22) 是唯一交付 PR。[基线 Actions 43233955173](https://github.com/devcodex-labs/flowkit/actions/runs/43233955173) 七项成功;本机 Windows / Node 24.22.2,`npm ci` 与 `npm run verify` 均退出 0,395/395、0 跳过。CF-08 另行复现,结果见下。独立复审包有原始 stdout/stderr、真实命令、SHA-256 和精确增量 diff;新证据提交的 CI 状态在独立清单中记录。

| 冻结原件(实际读完) | 字节 | SHA-256 | 取证来源 |
|---|---:|---|---|
| Requirements V0.3 | 56883 | `3a0adc3edb41869a6309bae29ec5496df00970c815f8dc16330a90cbf26e703e` | 本地 Grok 交接 ZIP 原始条目,与冻结登记一致 |
| Technical Design V0.6-R5 | 114621 | `09f3a5698e238d10b80efb8e26d1c41e51b663ca620efa70815dd7b52f2106ba` | 本地 R5 确认交接 ZIP 原始条目,与冻结登记一致 |
| P0-A Plan V0.1 | 42988 | `0ac8719f204aae274e64abc30d02caa637fc55a5f1751a6884341f05117e02c0` | ChatGPT Library 原始下载,与冻结登记一致 |

校验采用原始文件字节(未重编码)。范围 V0.3 全 710 行、R5 全 1128 行、计划全 319 行。R5 §18 将技术冻结与实施授权区分;计划的确认页和已确认交接决定给出 V0.1 实施范围。计划 §14 尾句留有“待用户确认”的旧措辞,保留原样;此处依据确认页、后续交接与用户本轮指示执行 G01/G03。R1/R2 仅作历史问题索引,审查结论直接取自原件和固定代码。下表的 D 是 `types/interactive.d.ts`。

| 发现 | 严重度 / 裁决 | 原件 → 当前行为 → 最小验证/修复候选(未执行) |
|---|---|---|
| CF-01 | P1,确认 P0-A 缺口 | R5 §§1.1/3.6/4–5/16、计划 A-M5-02/04/S12-A 要求独立受权 `adminTerminate`、无可用 Program 时仍能管理、原子墓碑和审计。公开入口、Coordinator/Trusted Host、类型中均无此能力;`src/interactive/index.mjs:2`、`coordinator.mjs:220/659`、`types/interactive.d.ts:183/254`。候选:独立管理凭据与单事务 CAS;验无 Program、普通模型输入拒绝、业务终态竞态及旧回执不能恢复运行。P0-B 的业务 cancel 不替代它。 |
| CF-02 | P1,DESIGN-QUESTION(确认差异,待裁决) | V0.3 §7.1 是示意;R5 §4 指向 §5 唯一规范签名、计划 A-M4-05 要求顶层 `start/complete/resume`。现为 `createInteractiveCoordinator`/`createTrustedInteractiveHost` 实例方法,签名也不同(入口第 2 行、D:161/183/254)。实际能力存在,未查得已批准用 factory 替代冻结顶层接口。先确认获批记录或向后兼容路径,再以发布包 ESM/TS 消费者验证;不直接加别名或撤旧接口。 |
| CF-05 | P1,确认 P0-A 投影缺口 | R5 §§4–5/7/11/16 与 A-M5-01 要求公开 Frame 用 `resultRef` 等有限信息,完整 State 走单独 `result:read` 可信读取。当前终态 `asPublicFrame` 包含 State(`coordinator.mjs:144`、D:83),受信 Host start/resume/load 转发(`trusted-host.mjs:147/159/163`);`getPublicAgentTask` 有授权和字段限制(:175、测试 :99/117)。证实 SDK 角色未分离,未证真实模型泄漏。候选:拆分公开投影和受权读取;分别验证私密数据不会随模型/stdout 发送、跨租户和错误角色拒绝、合法读取成功。 |
| CF-06 | P1,DESIGN-QUESTION(确认差异,待裁决) | R5 §§5/8.1 冻结五个 Promise 操作 `createIfAbsent/load/compareAndSwap/loadTransition/loadReceipt` 与独立 Registry;§13.2 允许 SQLite 内部 DatabaseSync。当前 D:106、`coordinator.mjs:220/247/332`、`sqlite-store.mjs:290/340` 是同步 Store+Registry,冻结五操作单独提供时不能接入。现有 SQLite 原子测试有效。先找授权的差异或评审适配方案;适配必须保住原子 CAS、Receipt/Journal、历史查询和丢 ACK 后线性化判断,另验非线性化读不会导致派发。 |
| CF-08 | P2,基线实测复现 | R5 R04、计划 A-M1-02/A-M2-02 的稳定快照/阶段门禁。 `compile.mjs:37–44` 首次 await 后重新读取原 `options.featureStage`。`probe-cf08.mjs`:稳定 P0-A 编译 7,634 B;调用后改原选项到 P0-B,产物 0 B,`FK_I_UNSUPPORTED_GRAPH`。探针退出 0 表示成功复现问题;没有绕过阶段门禁。候选:统一使用已校验快照,再用同一负例保证产物与对照一致。 |
| ABI-01 | DESIGN-QUESTION,静态差异 | R5 §§3/5/8 的 transitionId 使用规范化事件/Program/Proposal;`coordinator.mjs:29` 实际以 namespace/run/revision/block/kind 构造带前缀 ID。:54/92 检查当前 Block 与部分 Proposal 字段,并不能据测试证明冻结判别联合所有未知键/非法字段都拒绝。D:83/93 的 Frame/Pending 形态也不同。先独立确认已持久历史、支持版本及升级风险;不改计算、字段或 schema。 |

CF-07(与 CF-08 分开)由 `606d055d5f02451fea0b30294889d740ef370d49` 修复,基线 `coordinator.test.mjs:407/421` 两项通过。CF-03 仍缺原生 Grok 可验证来源与真实 Host/Model 隔离;G03 仅能力 PoC。CF-04 维持已批准范围:Action/Human/Loop/业务 cancel 属 P0-B、Parallel all_succeeded 属 P1、any 留待 P2 专项裁决。

## V0.6-R5 §§1–18 正文审查

| § / 原件起始行 | 对照和裁决 |
|---|---|
| 1 / 27 | 产品链路仍为用户意图→可执行 JS→程序控制 Agent。G02 已合并有实际 JS/Pending,根入口 `src/index.mjs` 及包契约不扩张;本次不重跑 G02。Standard 与 Interactive 分层,无必需 FlowKit 服务。 |
| 2 / 60 | `compile.mjs:37`、`src/compiler/interactive/{lower,validate-ir,emit}.mjs` 与 `load.mjs:54` 落地 Standard 前端复用、真实 JS、同字节加载;程序决策和宿主持久化分离。ABI-01 留审。 |
| 3 / 142 | `coordinator.mjs:332/451/567/659`、crash 测试证明主要阶段/接纳屏障和无空 waiting;全故障矩阵 T29 部分,独立管理终止 CF-01。 |
| 4 / 226 | 实际子路径与公开 SDK/权限/可信读取对应 CF-01/02/05;R5 §5 是唯一规范声明,不能以 V0.3 示意代替。 |
| 5 / 264 | `types/interactive.d.ts:83/93/106/161/183/254` 和 `coordinator.mjs:29/92`:可执行 A 子集、显式形态差异 CF-02/05/06、ABI-01;未批准改 ABI。 |
| 6 / 509 | `sqlite-store.mjs:139/150/163/178` 的不可变字节、引用 FK、`coordinator.mjs:247` 固定旧 Program;m6:340 和 cache 测试成立,跨 SDK/CP 升级未实测。 |
| 7 / 547 | `trusted-host.mjs:175/221` 最小任务、可信回执可测;CF-05,Human 通道延期;实际模型和 Host 权限隔离未证。 |
| 8 / 592 | `sqlite-store.mjs:290/340` Genesis/CAS 和历史回执;R03/R11 仍缺、CF-06 的外部五操作未符合。 |
| 9 / 628 | 当前 SQL `sqlite-store.mjs:75/92–130/196/212/290/340` 对比 §9:WAL/FULL/外键、本地事务和 Journal/Receipt 索引有实测;实际四张 `fk_i_*` 表以 run→artifact FK 保留 Program,与参考 retain 结构不同;admin/outbox/墓碑与更广保留策略未证明。物理名字差异不单独判失败;不做迁移。 |
| 10 / 710 | 已落地 Condition/Terminal/基础 Agent;`feature-gate.mjs` 阻止提前扩张,P0-B/P1/P2 依原件。 |
| 11 / 787 | `canonical.mjs:34/111/115`、`trusted-host.mjs:175/221` 和 SQLite namespace,P 级测试通过;跨语言 JCS/完整文本重复键边界、目标 Grok 账户/ACL 及原生来源未证明。 |
| 12 / 820 | 基础错误已实测(FK_R002/FK_R004/容量/权限),运行期 `FK_I_INVALID_CHECKPOINT` 等实际分类与冻结词表须逐项核销;不扩大固定 Standard 61 码。 |
| 13 / 866 | 容量、预算、历史回执有界缓存已测,R12 长期样本缺;JS 不可用时真实拒绝记录缺(T11),G03 文件入口不能等同 FlowKit 2 MiB 安全验收。 |
| 14 / 901 | m6:171/250/293/365 证明 A 子集、状态与预算的对照。JSON 边界/缺失与 null 区别是已登记差异;B/P1/P2 不推断。 |
| 15 / 924 | 追踪表覆盖全部 T/R/S;原件的「未执行」是设计时状态,本轮证据逐项分级。 |
| 16 / 1030 | P0-A 与后续阶段区分;管理终止、可信读取、宿主能力是缺口或阻断,不能提前宣称 M5/M6 合格。 |
| 17 / 1084 | R5-01–10 是设计裁决,测试仅覆盖具体断言;远端 Store/升级/运维/宿主来源按剩余门禁处理。 |
| 18 / 1118 | 冻结授权与实施授权独立;依据本轮授权只做 G01/G03、同一个 Draft PR,停于独立复审。 |

**退出状态:提交审查记录,冻结契约符合性未通过。** G04 依赖独立复审与对争议契约的裁决;T11、T27/S13 原生可信宿主、R03/R11/R12、跨版本、部分故障与完整 ABI/诊断仍待对应证据。证据等级:P 是现有流程运行,M 是真实模型实际消费 FlowKit Pending,T 是受保护观察链,N 是原生端到端可信验收,V 是可独立验证的 provider 证明;本次 G01 不产生新的 M/T/N/V。
21 changes: 21 additions & 0 deletions docs/evidence/p0a-g01-20261112/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# G01 执行与复现

PowerShell;命令从本次工作区运行,日志随本文件分发。审查用 detached worktree 对象为 `21b02e785cacf703c359d7d4f853b8196aa17b19`。

```powershell
git ls-remote https://github.com/devcodex-labs/flowkit.git refs/heads/main refs/heads/feat/p0a-interactive-20261112
git -C D:/Worker/flowkit -c core.longpaths=true worktree add --detach <worktree> 21b02e785cacf703c359d7d4f853b8196aa17b19
Get-ChildItem work/frozen-originals -File | Get-FileHash -Algorithm SHA256
Get-Content -LiteralPath <original-path> -Encoding UTF8
```

进入审查 worktree,实际依次运行 `npm ci` 与 `npm run verify`,各自重定向 stdout/stderr 并记录 `$LASTEXITCODE`。两条命令输出分别见 `npm-ci.*` 和 `npm-verify.*`;探针调用如下:

```powershell
$audit = Resolve-Path outputs/flowkit-p0a-review/G01
$repo = Resolve-Path work/flowkit-pr22
node (Join-Path $audit 'probe-cf08.mjs') $repo 1> (Join-Path $audit 'cf08.stdout') 2> (Join-Path $audit 'cf08.stderr')
$LASTEXITCODE | Set-Content (Join-Path $audit 'cf08.exit')
```

正式原件包身份:`FlowKit-Interactive-Development-Handoff-For-Grok-2026-11-10.zip` = `8a2f679a796234383b5108d58db16c1016a35c6110301bc4eb7e091ee2ed5826`;`FlowKit-Interactive-V0.6-R5-Confirmed-Handoff.zip` = `2deb5b3fa60ed3b7c2d29f028e33835c47aaa0a976e947de717128caf7326549`。计划见 [Library 原始条目](https://chatgpt.com/space/file/libfile_de7a4fcb51c881919e942f9348ccd935)。读取各自原始文件的 SHA-256 和长度见 `verified-inputs.txt`。ZIP 原始条目解压后校验的是条目字节,未保存为重编码版本。
22 changes: 22 additions & 0 deletions docs/evidence/p0a-g01-20261112/probe-cf08.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import assert from 'node:assert/strict';
import {mkdtemp, writeFile} from 'node:fs/promises';
import {tmpdir} from 'node:os';
import {join, resolve} from 'node:path';
import {pathToFileURL} from 'node:url';

const repo = resolve(process.argv[2]);
const {compileInteractive} = await import(pathToFileURL(join(repo,'src/interactive/compile.mjs')));
const projectRoot = await mkdtemp(join(tmpdir(), 'flowkit-g01-cf08-'));
const file = join(projectRoot, 'cf08.workflow.js');
await writeFile(file, "import {defineWorkflow,terminal} from '@devcodex-labs/flowkit/dsl';\n" +
"export default defineWorkflow({id:'cf08',version:'1.0.0',name:'CF08',nodes:[terminal('done',{name:'Done',status:'succeeded'})]});\n");
const opts = () => ({output:'memory',featureStage:'P0-A',projectRoot});
const control = await compileInteractive(file, opts());
const options = opts();
const pending = compileInteractive(file, options);
options.featureStage = 'P0-B';
const raced = await pending;
console.log(JSON.stringify({node:process.version, file, controlBytes:Buffer.byteLength(control.code), racedBytes:Buffer.byteLength(raced.code), diagnostics:raced.diagnostics}, null, 2));
assert.ok(control.code.length);
assert.equal(raced.code, '');
assert.ok(raced.diagnostics.some(d=>d.message.includes('P0-B')));
14 changes: 14 additions & 0 deletions docs/evidence/p0a-g01-20261112/sha256.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
13bf7b3039c63bf5a50491fa3cfd8eb4e699d1ba1436315aef9cbe5711530354 cf08.exit
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 cf08.stderr
29b364604f36f6d29d8ff7685867f86e389ab943c9afc00151c316c8c0700f02 cf08.stdout
0ed9115fdd627b14aa67b3e87706aa47f87d4aeee32e7abf5aecb3117d3afa51 commands.md
13bf7b3039c63bf5a50491fa3cfd8eb4e699d1ba1436315aef9cbe5711530354 npm-ci.exit
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 npm-ci.stderr
ebbc3b8201ebd2d3248fb714b906556f5447e3c046672586c902d0dba9599dfa npm-ci.stdout
13bf7b3039c63bf5a50491fa3cfd8eb4e699d1ba1436315aef9cbe5711530354 npm-verify.exit
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 npm-verify.stderr
328458367d798b68574509c7e928405475ca2eda13b8235bcb1ed65427e6dafb npm-verify.stdout
383d49b1b3d5da71276cee80b779d394029168c262d9a84137fb69f7802b2561 probe-cf08.mjs
059985a7d17927148ffd85069a671f202f215d5718ddb7b7e1290c47d4bff986 README.md
f17fd767459098b431d8d79a308b88b6a25ea2b9df44fa040703d93d8256d9f3 traceability.md
e016df07605e9b03444794754851ebabe3619b2e09d429f3607641b240c5c033 verified-inputs.txt
Loading