Skip to content

Gate managed workspace execution behind owner-bound authority - #2106

Merged
jackwener merged 4 commits into
apache:mainfrom
zhiiw:codex/managed-workspace-execution-admission-m1
Aug 4, 2026
Merged

Gate managed workspace execution behind owner-bound authority#2106
jackwener merged 4 commits into
apache:mainfrom
zhiiw:codex/managed-workspace-execution-admission-m1

Conversation

@zhiiw

@zhiiw zhiiw commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

This change gates managed-workspace execution behind an owner-bound, short-lived authority scope. Runtime consumers no longer receive a reusable raw worktree path or a transferable receipt; they can only operate through an opaque scope issued after the storage owner revalidates the complete managed-workspace boundary.

The primary invariant is:

A managed workspace execution capability is issued only while the durable storage root, workspace binding, baseline receipt, repository state, worktree lock, and canonical workspace head all describe the same exact Git state; the capability becomes unusable as soon as its callback settles or the owner closes.

What changed

  • Add an internal managed-workspace execution authority owned by ManagedWorkspaceOwner.
  • Replace public raw cwd/binding/receipt exposure with an opaque, revocable execution scope.
  • Re-read and compare the canonical workspace head immediately before scope issuance.
  • Verify the storage-root identity, runtime database identity, binding, receipt, Git HEAD/tree, and worktree ownership lock as one admission proof.
  • Quarantine managed worktrees when final verification detects drift.
  • Support explicitly concurrent read-only (workspaceEffect: none) scopes on the same handle and drain all of them during owner shutdown.
  • Return stable error codes for invalid and expired scopes.
  • Add production-shaped real-Git, crash/reopen, SIGKILL, expiry, drift, shadowing, concurrent-scope, and runtime-database-detach tests.
  • Document the authority owner, admission sequence, failure states, rollback boundary, platform guarantees, and the follow-up worker integration.

Why

The earlier baseline and owner APIs could prove that a managed worktree existed, but they did not provide a narrow execution boundary. A consumer that obtained the raw worktree path could retain or reuse it after the proof became stale. This PR makes execution admission an explicit storage-owned capability and closes that authority leak before managed workspaces are connected to runtime tools.

Ownership and atomicity boundary

  • Owner: ManagedWorkspaceOwner and its storage-internal execution authority.
  • Admission boundary: final canonical-head reread plus exact storage/Git identity verification immediately before scope issuance.
  • Revocation boundary: callback settlement or owner shutdown.
  • Failure state: no scope is issued; drift is fail-closed and, where applicable, the managed worktree is quarantined.
  • Rollback: this slice can be reverted without changing the RuntimeEvent schema or existing Desktop/CLI execution behavior because it has no production runtime-host consumer yet.

This is a detection-and-revocation boundary, not a claim that arbitrary external filesystem writers can be atomically excluded. Stronger process isolation belongs to the subsequent worker/sandbox integration.

Deliberately out of scope

  • Passing the scope into Desktop/CLI/runtime tool execution.
  • A managed-workspace worker protocol or read-only tool allowlist.
  • Mutation admission, checkpoint creation, redo, or workspace publication.
  • Reentrant owner.close() protection from inside an active callback; the worker integration will add an execution-context guard.

Validation

  • npm --workspace @maka/core run build
  • npm --workspace @maka/storage run build
  • Focused storage suites: 45 passed, 0 failed, 6 skipped.
  • The skips are explicit Windows capability gaps for POSIX inode/detach and signal behavior; Windows path and identity behavior remains covered by the applicable tests.
中文说明

概要

本次修改把 managed workspace 的执行入口收敛为由 ManagedWorkspaceOwner 持有的短生命周期授权作用域。调用方不再获得可长期保存的原始 worktree 路径、binding 或 receipt;只有在 storage owner 重新验证完整 managed-workspace 边界后,才能在回调期间拿到一个不透明、可撤销的 scope。

核心不变量是:

只有当 durable storage root、workspace binding、baseline receipt、repository state、worktree ownership lock 与 canonical workspace head 全部指向同一个精确 Git 状态时,系统才签发 managed workspace execution capability;回调结束或 owner 关闭后,该 capability 立即失效。

主要修改

  • 新增由 ManagedWorkspaceOwner 独占的内部 execution authority。
  • 删除公共 API 中原始 cwd、binding、receipt 的直接暴露,改为 opaque execution scope。
  • scope 签发前重新读取并完整比较 canonical workspace head。
  • 在同一个 admission proof 中验证 storage-root identity、runtime database identity、binding、receipt、Git HEAD/tree 与 worktree ownership lock。
  • 最终验证发现漂移时,对 managed worktree 执行 quarantine。
  • 明确定义同一 handle 可以并发持有多个只读(workspaceEffect: none)scope;owner shutdown 会等待所有 scope 收敛。
  • 为 scope invalid/expired 提供稳定错误码。
  • 增加真实 Git、crash/reopen、SIGKILL、scope expiry、drift、method shadowing、并发 scope 和 runtime database detach 等 production-shaped 测试。
  • 更新架构文档,明确 owner、原子性边界、失败状态、回滚方式、平台能力与后续 worker 集成边界。

为什么要做

之前的 baseline/owner API 能证明 managed worktree 存在,但无法形成狭窄的执行授权边界。调用方拿到原始路径后,可以在证明过期后继续保存或复用它。本 PR 在 managed workspace 接入 runtime tools 之前,把执行许可收敛为 storage-owned capability,从 API 权限上关闭这条泄漏路径。

Owner 与原子性边界

  • Owner: ManagedWorkspaceOwner 及其 storage-internal execution authority。
  • Admission boundary: scope 签发前最后一次 canonical head 重读,以及 storage/Git 身份的精确联合验证。
  • Revocation boundary: callback settle 或 owner shutdown。
  • Failure state: 不签发 scope;drift fail-closed,并在适用场景 quarantine worktree。
  • Rollback: 本切片不修改 RuntimeEvent schema,也尚未接入 Desktop/CLI 的生产工具执行,因此可以独立回滚。

这是一条“检测 + 撤销”边界,并不声称能够原子排除任意外部文件系统写入者。更强的进程隔离属于下一阶段 worker/sandbox 集成。

明确不在本 PR 范围内

  • 将 scope 接入 Desktop/CLI/runtime tools。
  • managed-workspace worker protocol 或只读工具 allowlist。
  • mutation admission、checkpoint、redo 或 workspace publication。
  • active callback 内重入调用 owner.close() 的保护;后续 worker 集成将加入 execution-context guard。

验证

  • Core build 通过。
  • Storage build 通过。
  • 聚焦测试:45 passed、0 failed、6 skipped
  • skips 是明确记录的 Windows capability gap,涉及 POSIX inode/detach 与 signal 语义;适用于 Windows 的路径和身份逻辑仍有覆盖。

@zhiiw
zhiiw marked this pull request as ready for review August 4, 2026 08:15
@jackwener

Copy link
Copy Markdown
Member

Review by maka-审美专家 — 通过(对抗性审查,附必须跟进项)

核实结论:授权模型(WeakMap 对象身份 + per-owner token,伪造结构性不可能)、fail-closed 全分支确认(非漂移 Git 错误重抛不吞、无 default-allow)、九个新测试中六个专钉拒绝路径(断言稳定 code 非文案)、包边界收口完整(内部符号不在 index.ts / exports map,且有契约测试钉住缺席)。公共面 dropped binding/receipt、WorkspaceVersionRecordV1 readonly + freeze 关掉调用方篡改向量——这些都值得肯定。PR 描述对自身局限(检测-撤销而非原子互斥)的坦诚与代码一致。

必须跟进(M1.2 动工前)

  1. MEDIUMinspectManagedWorkspaceExecutionScopeInternal(authority-internal.ts:112-129)无 ownerToken 检查,却被 docstring 指定为 M1.2 worker-bridge 的消费缝——任何持有任意 active scope 的 storage 内部代码可解析任意 owner 的 cwd。M1.2 必须新增 requireManagedWorkspaceExecutionScopeInternal(ownerToken, scope) 并把无检查的 inspect* 降级为 test-only;:80-86 的 handle 版 inspect(返回 worktreePath+receipt+live store)同缺口。
  2. LOW:PR 描述称「head 在 scope 签发前 immediately 重读」,实际顺序是 head 重读→慢速 Git 验证→签发,Git 验证窗口内 head 可前进。今天无 head writer 所以无实害,M2 落地前要么换序要么改口径。
  3. LOWassertExecutionCrossPlaneIdentity 首个 JSON.stringify 比较的两个操作数是同一引用(freezeManagedWorkspaceReceipt 用同一 binding 覆盖),永假 = 假保障(真保护在 git-workspace-service.ts:637-643 的磁盘重读)。删掉或改成真比较,且不要用 key-order 敏感的 stringify。
  4. LOW:DB-detach 守卫在 head 读之前执行,顺序与意图不符(有下游兜住,测试过)。

当前无生产消费者、门控 fail-closed、CI 11/11 绿,合入。上述 4 项请开 follow-up issue 挂到 M1.2。

@jackwener
jackwener merged commit 4f3f1d8 into apache:main Aug 4, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants