Skip to content

Commit bfc4509

Browse files
committed
feat: add transactional incremental skill binding
1 parent 45b2021 commit bfc4509

12 files changed

Lines changed: 3274 additions & 8 deletions

README-CN.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ Workspace 是可选的:存在 `.tfd/` 时,TFD 会校验并恢复;不存在
121121

122122
Workspace v1 增加项目本地、可持久恢复的 `.tfd/` 控制面。初始化采用 proposal-first approval:`init-propose` 只读执行 Gate 0–5 分析,`init-apply` 只接受完全一致的 proposal digest 和具名批准人。初始化不会启动 Agent 或 Worker。
123123

124+
每个项目只拥有一份随项目成长的持久 `.tfd` Workspace。临时任务 worktree 不复制、也不创建第二份 Workspace;worktree 只服务具体任务,完成后可清理。
125+
124126
初始化摘要批准只授权完全一致的初始化应用。后续任务执行仍须分别满足授权边界、当前任务、权限、授权授予以及任何必要批准。
125127

126128
批准前,proposal-time alignment validation 会把用户结果、共同成功标准、完整当前阶段和每位参与者的贡献绑定到拟议任务。对话式批准时,用户只会看到短的人类可读指纹。Coordinator 在内部保留完整的 canonical digest。变更、陈旧、过期、不匹配或含糊的方案必须重新展示,并获得重新确认。
@@ -131,11 +133,17 @@ Workspace v1 增加项目本地、可持久恢复的 `.tfd/` 控制面。初始
131133

132134
Skill 审查明确区分已安装的 `BIND`、复制到项目缓存的 `INSTALL`,以及 Agent 本地的 `project_custom`。批准的 Git 来源必须已经是本地 commit-pinned checkout;v1 不会 clone 或 fetch。context-free recovery 仅依据项目内权威文件按固定顺序恢复,不依赖对话记忆。
133135

136+
既有 Workspace 可通过只读 `skill-bind-propose` 与原子 `skill-bind-apply` 增量授予已审查的 installed `BIND` Skill。Apply 需要完整 proposal digest 与当前具名用户,保留无关授权,使用普通 runtime packet 路径证明就绪,但仍不授权 dispatch。该服务不能安装 Skill、扩展权限、创建成员或任务,也不能授予网络、外部或付费权限。`plugins/tfd/scripts/fixtures/` 下的 Creave 命名 fixture 只是仓库内消费示例,不依赖任何 Creave 代码。
137+
138+
若 apply 无法证明精确回滚,它会记录 `.tfd/.skill-bind-recovery.yaml`;在经授权的恢复流程完成事故核对前,后续绑定、Skill 校验与 runtime preparation 全部 fail closed。该标记不构成直接编辑 `.tfd` 修复的授权。
139+
134140
Workspace 属于 local-only v1 边界:不包含 GitHub 或 Linear 工作流联动、网络编排、部署、发布和外部消息。命令、schema、批准边界、恢复与拒绝 payload 详见 [运维参考](plugins/tfd/references/workspace-protocol.md)。以下命令需在 `plugins/tfd/` 中执行:
135141

136142
```bash
137143
python3 -m scripts.tfd_workspace.cli init-propose --project-root /path/to/project --request request.json
138144
python3 -m scripts.tfd_workspace.cli init-apply --project-root /path/to/project --proposal - --approval-digest sha256:... --approver user:id
145+
python3 -m scripts.tfd_workspace.cli skill-bind-propose --project-root /path/to/project --request skill-bind.json --at 2026-07-26T01:00:00Z
146+
python3 -m scripts.tfd_workspace.cli skill-bind-apply --project-root /path/to/project --proposal skill-bind-proposal.json --approval-digest sha256:... --approver user:id --at 2026-07-26T01:01:00Z
139147
python3 -m scripts.tfd_workspace.cli validate --project-root /path/to/project
140148
python3 -m scripts.tfd_workspace.cli task-attest --project-root /path/to/project --task-id TFD-0001 --task-revision 4 --candidate-digest sha256:... --signer-id reviewer --signer-type reviewer --decision PASS
141149
```

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ Workspace is optional. When `.tfd/` exists, TFD validates and recovers it. When
130130

131131
Workspace v1 adds a local, persistent `.tfd/` control plane. Initialization is proposal-first: `init-propose` performs a read-only Gate 0–5 analysis, then `init-apply` accepts only the exact proposal digest and named approver. Initialization does not start Agents or Workers.
132132

133+
Each project owns exactly one durable `.tfd` Workspace that follows the project. A temporary task worktree does not receive a copied or second Workspace; worktrees remain task-scoped and disposable.
134+
133135
The approved initialization digest authorizes only that exact initialization application. Later task execution remains separately governed by the authority envelope, current task, permissions, grants, and any required approval.
134136

135137
Before approval, proposal-time alignment validation binds the user's outcome, shared success criteria, complete current phase, and each participant's contribution to the proposed task. Users see only a short human fingerprint during conversational approval. The Coordinator retains the complete canonical digest internally. A changed, stale, expired, mismatched, or ambiguous proposal must be presented again and receive renewed confirmation.
@@ -140,11 +142,17 @@ Authoritative project, authority, roster, identity, Skill, permission, task, wor
140142

141143
Skill review distinguishes installed `BIND`, project-cached `INSTALL`, and Agent-local `project_custom` packages. An approved Git source must already exist as a local commit-pinned checkout; v1 does not clone or fetch it. Context-free recovery reconstructs continuation solely from project-local authority in a fixed order, without conversation memory.
142144

145+
Existing Workspaces can add reviewed installed `BIND` Skills with the read-only `skill-bind-propose` and atomic `skill-bind-apply` services. Apply requires the complete proposal digest and exact named user, preserves unrelated authority, proves ordinary runtime packet readiness, and still does not authorize dispatch. It cannot install Skills, expand permissions, create roster members or Tasks, or grant network/external/paid authority. The Creave-named fixture under `plugins/tfd/scripts/fixtures/` is a repository-only consumer example and has no Creave code dependency.
146+
147+
If exact rollback cannot be proved, apply records `.tfd/.skill-bind-recovery.yaml`; subsequent binding, Skill verification, and runtime preparation fail closed until an authorized recovery procedure reconciles the incident. The marker is not permission to repair `.tfd` by direct editing.
148+
143149
Workspace is a local-only v1 boundary: it has no GitHub or Linear workflow integration, network orchestration, deployment, publishing, or external messaging. See [the operator reference](plugins/tfd/references/workspace-protocol.md) for commands, schemas, approval boundaries, recovery, and denial payloads. Run the following commands from `plugins/tfd/`:
144150

145151
```bash
146152
python3 -m scripts.tfd_workspace.cli init-propose --project-root /path/to/project --request request.json
147153
python3 -m scripts.tfd_workspace.cli init-apply --project-root /path/to/project --proposal - --approval-digest sha256:... --approver user:id
154+
python3 -m scripts.tfd_workspace.cli skill-bind-propose --project-root /path/to/project --request skill-bind.json --at 2026-07-26T01:00:00Z
155+
python3 -m scripts.tfd_workspace.cli skill-bind-apply --project-root /path/to/project --proposal skill-bind-proposal.json --approval-digest sha256:... --approver user:id --at 2026-07-26T01:01:00Z
148156
python3 -m scripts.tfd_workspace.cli validate --project-root /path/to/project
149157
python3 -m scripts.tfd_workspace.cli task-attest --project-root /path/to/project --task-id TFD-0001 --task-revision 4 --candidate-digest sha256:... --signer-id reviewer --signer-type reviewer --decision PASS
150158
```
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# TFD Incremental Skill Binding Implementation Plan
2+
3+
> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:executing-plans` to implement this plan task-by-task. Do not use `subagent-driven-development`; the approved TFD roster and TaskPacket require inline execution by `developer-tooling`.
4+
5+
**Goal:** Add read-only proposal and atomic apply services that incrementally BIND reviewed installed Skills to existing ACTIVE Agents without broadening permissions or bypassing ordinary runtime preparation.
6+
7+
**Architecture:** A focused `skill_binding.py` service strictly decodes requests, pins every authority-bearing input, revalidates installed package provenance, derives a complete deterministic poststate, and seals it with a full canonical digest. Apply holds the existing re-entrant Workspace transaction across revalidation, publication, ordinary runtime preparation, immutable event recording, generated-view rebuild, final verification, and exact rollback. Existing `AgentSkillGrant`, full Skill Store assembly, runtime, event kind, and Workspace schemas remain unchanged.
8+
9+
**Tech Stack:** Python 3 standard library, frozen dataclasses, existing TFD YAML/schema/Skill Store/runtime/event/view services, `unittest`.
10+
11+
## Global Constraints
12+
13+
- Follow `docs/superpowers/specs/2026-07-26-tfd-incremental-skill-bind-design.md` exactly.
14+
- Only reviewed installed Skills with `requested_decision == decision == BIND` may be incrementally bound.
15+
- Preserve default denial, exact Task/Agent/Skill/purpose/expiry/termination checks, and ordinary `prepare_task_packet` strength.
16+
- Do not expand `AgentSkillGrant` or any Workspace schema.
17+
- Proposal is byte-for-byte read-only; apply has one outer rollback boundary and no external effect.
18+
- The durable project `.tfd` is singular and is never copied into this worktree.
19+
- Do not modify Creave code or Workspace; the Creave-named artifact is a repository-only JSON fixture.
20+
- No Agent creation/start, permission grant, install, network, paid call, external write, credential, push, PR, tag, release, deploy, reinstall, or local commit.
21+
22+
---
23+
24+
### Task 1: Strict proposal model and read-only vertical slice
25+
26+
**Files:**
27+
- Create: `plugins/tfd/scripts/tfd_workspace/skill_binding.py`
28+
- Create: `plugins/tfd/scripts/test_workspace_skill_binding.py`
29+
- Modify: `plugins/tfd/scripts/tfd_workspace/__init__.py`
30+
31+
**Interfaces:**
32+
- Consumes: persisted Workspace documents, `SkillReview`, `CapabilityContract`, `SourceTrustPolicy`, `AgentSkillGrant`, `validate_skill_review_snapshot`, `verify_skill_lock`, `prepare_task_packet`.
33+
- Produces: `SkillBindRequestEntry`, `SkillBindRequest`, `SkillBindProposal`, `SkillBindResult`, `build_skill_bind_proposal(project_root, request, at)`.
34+
35+
- [ ] **Step 1: Write the failing vertical-slice proposal test**
36+
37+
Build a real temporary Workspace from the existing Skill Store fixture conventions, snapshot every file and directory entry, call `build_skill_bind_proposal`, and assert `PASS`, a full `sha256:` seal, canonical root, exact named approver, exact normalized binding, and an unchanged tree inventory/byte snapshot.
38+
39+
- [ ] **Step 2: Run the focused test to verify RED**
40+
41+
Run: `python3 -m unittest plugins.tfd.scripts.test_workspace_skill_binding.SkillBindingTests.test_propose_is_read_only_and_seals_exact_binding -v`
42+
43+
Expected: import failure because `skill_binding` does not exist.
44+
45+
- [ ] **Step 3: Implement strict request validation and proposal derivation**
46+
47+
Add frozen request/proposal/result dataclasses. Validate exact schemas and canonical IDs, timestamps, full digests, one Task scope, one normalized purpose, unique grants/Agent-Skill pairs/purposes, explicit expiry, `task_completion`, named-user identity, ACTIVE roster/source identity, exact non-terminal owned and assigned Task revision/candidate/required Skill, BIND review provenance, complete review risk fields, permission non-expansion, and existing authority conflicts. Seal pinned prestate and installed package identities; derive deterministic approval/lock/review/grant poststate and expected event IDs without writing.
48+
49+
- [ ] **Step 4: Run focused proposal test to verify GREEN**
50+
51+
Run the command from Step 2 and require one passing test with an unchanged tree.
52+
53+
### Task 2: Atomic apply, runtime proof, idempotency, and CLI
54+
55+
**Files:**
56+
- Modify: `plugins/tfd/scripts/tfd_workspace/skill_binding.py`
57+
- Modify: `plugins/tfd/scripts/tfd_workspace/cli.py`
58+
- Modify: `plugins/tfd/scripts/tfd_workspace/__init__.py`
59+
- Modify: `plugins/tfd/scripts/test_workspace_skill_binding.py`
60+
- Modify: `plugins/tfd/scripts/test_workspace_cli.py`
61+
62+
**Interfaces:**
63+
- Produces: `SkillBindApproval`, `apply_skill_bind_proposal(project_root, proposal, approval, at)`, CLI `skill-bind-propose` and `skill-bind-apply`.
64+
- Apply returns `PASS/applied`, `PASS/already_applied`, or `BLOCKER` with one stable fail-closed issue code.
65+
66+
- [ ] **Step 1: Write failing success/apply/runtime/CLI tests**
67+
68+
Assert that apply adds exactly one grant, updates or creates the exact authority/lock/review fragments, records the deterministic `skill_grant_changed` event, rebuilds projections, passes `verify_skill_lock`, and allows ordinary `prepare_task_packet`. Assert a second exact apply changes no bytes or event count. Assert CLI accepts only a complete digest and emits one JSON object.
69+
70+
- [ ] **Step 2: Run the new tests to verify RED**
71+
72+
Run the individual service and CLI test methods; expect missing apply/CLI behavior failures.
73+
74+
- [ ] **Step 3: Implement one-boundary publication**
75+
76+
Validate the proposal seal and named approval, acquire `workspace_transaction`, check idempotent exact postcondition before prestate staleness, revalidate prestate/package/Agent/Task/Skill/grant/event availability, pin all mutated authority/event/view targets, atomically publish the deterministic merge, run `verify_skill_lock`, call ordinary `prepare_task_packet` for every Agent/Task group, record exact immutable events, rebuild every projection, rerun complete validation, fsync, and release. On any failure restore exact bytes, modes, and existence and return a stable blocker; surface `recovery_required` if exact restoration cannot be proved.
77+
78+
- [ ] **Step 4: Run the service and CLI tests to verify GREEN**
79+
80+
Require success, idempotency, runtime packet, and CLI tests to pass.
81+
82+
### Task 3: Fail-closed matrix and rollback
83+
84+
**Files:**
85+
- Modify: `plugins/tfd/scripts/test_workspace_skill_binding.py`
86+
- Modify: `plugins/tfd/scripts/tfd_workspace/skill_binding.py`
87+
88+
**Interfaces:**
89+
- Consumes: `_SKILL_BIND_FAULT_HOOK` test-only injection boundary.
90+
- Produces: stable issue codes from the design table and exact rollback behavior.
91+
92+
- [ ] **Step 1: Add failing table-driven rejection tests**
93+
94+
Cover malformed/short/wrong digest, expiry/future issuance/completed Task, approver mismatch, prestate and installed source/catalog/package/review drift, Agent/roster/Task/permission drift, conflicting authority/event, missing/symlinked/ambiguous/unreviewed/non-BIND Skill, wrong owner/scope/required Skill/purpose, and proposed network/external/credential/dependency/permission expansion.
95+
96+
- [ ] **Step 2: Run rejection tests to verify RED**
97+
98+
Run the exact new test methods and confirm each fails on the missing validation branch, not fixture setup.
99+
100+
- [ ] **Step 3: Add minimal fail-closed mappings**
101+
102+
Revalidate each sealed identity at apply time and map secret-safe failures to the stable codes in the design. Never include installed Skill bodies, absolute package paths, full approval digests, credentials, or raw exceptions.
103+
104+
- [ ] **Step 4: Add and verify concurrent/fault rollback tests**
105+
106+
Race two divergent proposals and require one winner. Inject a fault after each authority write, review, lock, Agent grant, runtime gate, event, and generated view; compare complete inventories, bytes, and modes with the exact preimage.
107+
108+
- [ ] **Step 5: Run the complete focused module to GREEN**
109+
110+
Run: `python3 -m unittest plugins.tfd.scripts.test_workspace_skill_binding -v`
111+
112+
### Task 4: Creave consumer fixture, documentation, and regression verification
113+
114+
**Files:**
115+
- Create: `plugins/tfd/scripts/fixtures/creave-incremental-skill-bind.json`
116+
- Modify: `plugins/tfd/scripts/test_workspace_skill_binding.py`
117+
- Modify: `plugins/tfd/references/workspace-protocol.md`
118+
- Modify: `README.md`
119+
- Modify: `README-CN.md`
120+
121+
**Interfaces:**
122+
- Fixture contains exactly the nine approved role/Skill/purpose mappings from the design and no Coordinator or `subagent-driven-development` grant.
123+
124+
- [ ] **Step 1: Add failing fixture consumption test**
125+
126+
Materialize temporary installed packages and an isolated temporary Workspace from the JSON fixture, propose/apply the mappings, and assert exact role mapping, no Coordinator output Skill, and denial of `subagent-driven-development`.
127+
128+
- [ ] **Step 2: Run fixture test to verify RED**
129+
130+
Expect failure because the fixture does not yet exist.
131+
132+
- [ ] **Step 3: Add fixture and protocol/CLI documentation**
133+
134+
Document the proposal/apply commands, full-digest named approval, read-only/atomic/idempotent behavior, runtime re-prepare requirement, project-singleton Workspace/worktree rule, exclusions, and the tested Creave consumer boundary.
135+
136+
- [ ] **Step 4: Run fixture and focused tests to GREEN**
137+
138+
Run the fixture method and complete `test_workspace_skill_binding` module.
139+
140+
- [ ] **Step 5: Run related and full offline verification**
141+
142+
Run focused CLI, Skill Store, runtime/policy, schema, events, views, recovery, initialization, and contract modules; then run the repository's full documented Python suite plus formatting/static/release-preflight commands discovered from the current repository. Record exact pass/fail counts and preserve any host-isolation, real-Creave productivity, model-role advantage, and production execution claims as `UNVERIFIED`.
143+
144+
## Self-review
145+
146+
- Spec coverage: Tasks 1–3 cover proposal, named approval, delta preservation, idempotency, concurrency, source drift, runtime strength, and exact rollback; Task 4 covers the required consumer mapping, protocol/CLI docs, regressions, and explicit UNVERIFIED boundaries.
147+
- Placeholder scan: no implementation step contains TBD/TODO, “similar to”, or unspecified error handling.
148+
- Type consistency: the request, proposal, approval, and result symbols named in Tasks 1–3 are the only new service boundary; durable grants continue to use existing `AgentSkillGrant`.
149+
- Execution selection: the approved TFD TaskPacket already selects inline `superpowers:executing-plans`; no additional user choice or commit step is permitted.

0 commit comments

Comments
 (0)