Skip to content

feat(testing): enforce execution authorization lineage - #839

Merged
wanghuan-520 merged 12 commits into
devfrom
codex/authorization-lineage-receipts
Sep 16, 2026
Merged

wanghuan-520 merged 12 commits into
devfrom
codex/authorization-lineage-receipts

Conversation

@YueZh127

Copy link
Copy Markdown
Collaborator

Summary

This change completes the generic execution-authorization lineage and worker-isolation boundary required by the PQL asset-authoring and read-only trial flow.

  • Defines immutable, digest-bound receipts for profile approval claims, execution preauthorization claims, authenticated grants, execution claims, execution completion, and the final lineage index.
  • Requires a fresh point-of-use authorization decision and durable receipt consumption before every target CLI, HTTP, and browser effect.
  • Keeps machine asset admission non-authorizing and separate from Host execution policy.
  • Isolates worker HOME, workspace, Git configuration, SSH/askpass state, and credential helpers from trusted Host/publisher authority.
  • Adds durable, object-bound workspace/HOME ownership, supervised process launch, crash recovery, cleanup retention evidence, and fail-closed pathname/inode replacement handling.
  • Integrates the lineage through Generic Host, Workflow QA, Environment Factory, Testing Runner, and runtime projection paths.

Authorization Boundary

Machine-admitted test assets carry only audit facts:

human_approval_required = false
authorization_capability = false
execution_authorized = false
promotion_authorized = false

Execution still requires:

Host policy preauthorization
-> run-bound single-use Grant
-> fresh point-of-use authorization receipt
-> immediate receipt consumption
-> target effect

Compatibility does not imply execution authorization. No receipt in the exported lineage is a reusable capability, and asset admission cannot grant execution or promotion authority.

Safety

  • Target repositories remain read-only.
  • Worker processes receive no GitHub, Git, SSH, askpass, or credential-helper authority.
  • Host-only runtime roots and trusted publication authority remain outside worker control.
  • Workspace and worker-HOME publication use durable reservation identity and atomic no-clobber semantics.
  • Pathname, symlink, inode, marker, parent-intent, stale-owner, crash-window, and restart substitutions fail closed.
  • Ambiguous cleanup remains retained with immutable evidence; it is never reported as released.
  • No target-specific Aevatar, Talos, NyxID, or n8n behavior is introduced.
  • No auto-merge or target product mutation is performed.

Validation

Validated at 3a779536eea1b82747b8353ec6d1a0d76d153947 with the repository-pinned FKST engine:

  • Focused worker-HOME ledger test: passed
  • Focused workspace/checkout recovery test: passed
  • Focused Environment Factory Node runtime test: passed
  • Environment Factory package run before the final test-only review fix: 86 passed, 0 failed
  • The checkout integrity failure paths, missing-release-proof paths, generation rollover, cleanup retention, and supervised-reservation non-reuse are covered directly
  • git diff --check: passed
  • Independent security/product review: 0 Critical, 0 High, 0 Medium, 0 Low; final verdict APPROVE
  • Project Pack diff: empty
  • Product-specific, secret, local-path, and conflict-marker added-line scans: clean

The repository-wide runner and a repeated Generic Host example run did not complete in the local validation environment: both became silent in unrelated long-running package/lifecycle stages and were terminated after bounded waits. Neither emitted a test failure before termination. The focused affected tests and independent review above completed at the final head; this Draft remains open for CI and human review rather than claiming a complete local full-suite pass.

Delivery Boundary

This Draft PR does not authorize a production run, mutate a target repository, approve a promotion, merge itself, or create product-specific runtime policy. It supplies the generic testing-package contracts and enforcement needed for a later Host-authorized trial.

@YueZh127
YueZh127 marked this pull request as ready for review September 15, 2026 03:09
@wanghuan-520

Copy link
Copy Markdown
Collaborator

Review 基于 head 3a779536eea1b82747b8353ec6d1a0d76d153947,base 为 4b3de755153e79f6b88a719479ce25a31bb92adc(dev)。发现 3 个已在本地确定性复现的 P2 恢复问题,建议修复后再合并。

  1. [P2] 不同运行配置共用 durable 目录,会导致各自的已完成结果都无法读取。

    位置:fkst-structured-execution-runtime.js:162–167。

    新增的 completedReplayForResult() 遍历共享目录中的所有 replay 记录,先用当前配置的 state_auth_key / state_mac_generation 验证每条记录,之后才筛选请求对应的结果。因此,只要目录内存在另一套合法配置签署的记录,读取当前配置自己的结果也会直接失败。密钥轮换后保留旧记录同样会触发此问题。

    本地通过公开的 dispatch('replay-guard')、dispatch('complete-replay') 和 dispatch('load-result') 复现:先用配置 A 完成运行并成功读取结果,再用不同密钥和 generation 的配置 B 在同一 FKST_DURABLE_ROOT 完成另一个运行;之后 A、B 各自读取自己的结果都会失败:

    First result before second config: passed
    First result after second config: structured execution replay state authentication failed
    Second result after second config: structured execution replay state authentication failed
    

    建议:让结果读取携带可定位对应 claim 的身份,并只对目标记录执行严格认证;或按配置身份隔离 replay 存储。无关运行的记录不应阻断当前运行的结果恢复。

  2. [P2] reservation-only HOME 清理没有重放已有释放证明,二次中断后会永久保留已清理资源。

    位置:common.js:1091–1096。调用方包括 Generic Host 的 worker-home-ledger.js 和 Environment Factory 的 worker-home-resource.js。

    如果 HOME 已创建,但在 lease 写入 ledger 前中断,持久状态只剩 reservation。恢复清理时,releaseWorkerEnvironmentReservation() 可以重建 lease 并成功删除目录,但重建的 lease 没有先持久化。若随后在 ledger 提交前再次中断,下次恢复看到 HOME 不存在就直接返回 false,即使上一轮已经写下准确绑定该对象的释放证明。

    本地复现使用现有 afterEnvironmentCreated hook 模拟首次中断,随后运行真实 cleanup broker,并在删除完成后的 ledger CAS 注入一次失败。观察结果:

    Before retry: homeExists=false, releaseProven=true, ledgerState=reserved
    After retry:  cleaned=false, remaining_count=1, ledgerState=retained
    

    releaseProven=true 来自实际调用 workerEnvironmentReleaseProven(capturedLease)。因此这里已有有效证明,后续重试却仍会使工作流进入 cleanup-blocked。

    建议:先持久化从 reservation 恢复出的 inode-bearing lease,再删除目录;或根据 reservation 的准确身份验证已有 durable release proof,同时继续拒绝没有释放证明的路径消失情况。

  3. [P2] release-proof 删除日志标记的过程不可恢复,中途停止后每次重试都会失败。

    位置:object-bound-cleanup-broker.py:948–949。重试入口在同文件 938–940 行要求三个标记全部存在。

    release_capture_proof() 依次删除 finalized、captured-cleaned、capture.json。如果删除第一个标记后进程中断,目标目录已经删除,quarantine 中只剩部分日志;下一次 release-proof 又要求完整的原始标记集合,因此无法续做。Host 在 common.js 中仍停留在 finalized,无法持久化 released。

    本地执行真实 broker 的 capture-delete → finalize → release-proof,在删除 finalized 后注入中断,再连续重试两次,均得到:

    CleanupBlocked: capture-proof-not-releasable
    target_exists: false
    proof_files: ['capture.json', 'captured-cleaned']
    

    建议:将 proof retirement 设计为可重放的状态转换,让已开始的日志回收能够继续完成,同时保留对 capture 身份和目录对象的验证。这个问题与第 2 项不同:此处 broker 自身尚未完成 proof release;第 2 项中 broker 已完全成功,但 ledger 无法重放其证明。

验证情况:以下现有测试均通过,因此上述复现覆盖的是现有测试未覆盖的状态组合:

  • node examples/generic-host/tests/authorization_lineage_node_validator_test.js
  • node examples/generic-host/tests/worker_home_ledger_test.js
  • node examples/generic-host/tests/workspace_checkout_recovery_test.js
  • node libraries/testing_runtime/tests/structured_execution_runtime_test.js
  • python3 packages/environment-factory/tests/object_bound_cleanup_backend_test.py(4 tests)
  • git diff --check 4b3de75...HEAD

GitHub 当前 head 的 test 和 CodeQL 检查也全部成功。本地没有重跑仓库全量测试。此次 review 没有修改源码。

@wanghuan-520
wanghuan-520 merged commit b00bb7d into dev Sep 16, 2026
5 checks passed
@wanghuan-520
wanghuan-520 deleted the codex/authorization-lineage-receipts branch September 16, 2026 07:33
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