@fooksky/lodestar 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,109 +1,41 @@
1
1
  # Lodestar
2
2
 
3
- 用于统一个人在 DeepSeek Harness 中的开发工作流程,基于 DSH 原生能力和 Agent Teams。
3
+ Lodestar 是 DeepSeek Harness(DSH)的开发工作流插件,帮助 Agent 确认需求、评审方案、获得实施授权,再执行、验证和交付。项目内的文档与结构化状态让工作可恢复;仅设计任务也能记录设计交付。
4
4
 
5
- 当前开发工作流扩展:skill 负责需求、设计、授权和验收判断;`dev_workflow` 工具维护结构化 change 状态;DSH 原生工具和 Teams 负责执行。[首版设计](docs/design.md) 保留为历史,当前开发中的分支扩展遵循 [分支与 worktree 隔离设计](docs/branch-management.md),面向 `0.2.0`,暂不公开发布。
5
+ ## 提供什么
6
6
 
7
- ## 使用方式
7
+ - **`lodestar` skill**:指导需求澄清、设计取舍、授权判断、任务组织和验收。
8
+ - **`lodestar_change` 工具**:维护 change 的文档版本、决定、验收项、执行引用、验证记录及流程状态,校验阶段前置条件。
9
+ - **可选「Lodestar · 开发工作流」模式**:为会话添加流程提示,复用部署已有工具与 Teams,默认关闭。
8
10
 
9
- 启用核心插件后,在兼容会话中加载 `dev-workflow` skill,以自然语言开始需求、继续 change 或交付。无需切换模式即可使用核心流程。可选“开发工作流”preset 为新会话提供流程入口,配置默认关闭;它复用部署已有的原生工具,不改变默认模式、模型或权限。正在执行的会话不切换 preset。
11
+ 模式是提示适配器,不会安装工具、复制 profile、选择模型或扩大权限。写代码、测试和协作使用 DSH 原生能力;授权的含义与证据是否充分由 Lead 判断。Lodestar 不创建分支、不跨需求调度,也不自动提交、推送或发布。
10
12
 
11
- 本仓库的开发和测试不会把插件安装到本地/profile。安装、启用可选模式和发布分别需要明确操作;模式选择本身不构成实施授权。首版没有自动提交、推送、发布、hook 或第二套任务执行器。
13
+ ## 开始使用
12
14
 
13
- ## 材料与状态
15
+ 通过 DSH 的插件管理安装 `@fooksky/lodestar` 并启用核心插件。需要 Node.js 24+、Git,以及提供文件、工作目录和 subprocess 服务的兼容 DSH 宿主;兼容版本见 [package.json](package.json)。
14
16
 
15
- 材料保存在项目 `.dev-docs/changes/<change-id>/`:`intent.md`、`spec.md`、`plan.md` 由 Lead 按阶段编写,`state.json` 由工具原子更新。复用已有 `.dev-docs/index.md` 与 `knowledge/`。状态仅接受 `schemaVersion: 2`,`workspace` 必填;未知或旧 schema、缺失绑定均拒绝,不自动转换或修复。list 中未受管目录显示缺失或非法 state 错误。
17
+ 在会话中加载 `lodestar` skill,再说明目标:
16
18
 
17
- 一个独立需求默认对应一个 change、一条分支、一个 worktree 和一个 Lead。外部助手或用户负责 Issue 分配、准备 worktree 和启动会话;插件不创建/切换分支、不扫描工作区、不承担跨需求调度。代码、知识、change 材料和需保留的证据全部在本 worktree,知识继承基准提交的快照,不实时读取主 checkout 或共享材料根。
19
+ > 帮我设计并实现这个功能:……
20
+ >
21
+ > 继续 change `20261108-example`,先检查状态和未完成事项。
22
+ >
23
+ > 这次只需要设计方案,先不要实施。
18
24
 
19
- 工具每次显式接收 `projectRoot`;action 为 `workspace/list/get/create/update`。先观察外部已准备的工作区:
25
+ 若需要模式入口,进入侧栏「插件」→「已安装」→ `@fooksky/lodestar` 详情,在「包含的组件」中启用默认关闭的 `dev-workflow-preset`,再于新会话开始前选择「Lodestar · 开发工作流」。已有会话可直接加载 skill;选择模式本身不构成实施授权。支持模式指南的宿主可展示「模式说明 / 如何使用」;旧宿主会忽略指南字段,仍可阅读随包文档。完整步骤、能力要求与恢复方法见 [使用指南:模式说明 / 如何使用](skills/dev-workflow/USER_GUIDE.md)。
20
26
 
21
- ```json
22
- {"action":"workspace","projectRoot":"."}
23
- ```
24
-
25
- Git 项目的 `projectRoot` 与调用 Agent cwd 必须属于同一 checkout,允许项目子目录;不能从需求 worktree 指向主 checkout。普通目录项目根必须存在且位于 cwd 内。detached HEAD 只读,unborn 命名分支可写,bare 仓库拒绝使用;Git/权限/取消/损坏错误不降级为普通目录。创建例:
26
-
27
- ```json
28
- {"action":"create","projectRoot":".","changeId":"20261107-example","title":"示例需求"}
29
- ```
30
-
31
- create 自动生成 schemaVersion 2,绑定当前命名分支或普通目录。Git 绑定保存分支、绑定时的 `baseCommit`(unborn 可为 null)及项目相对 checkout 路径;不保存机器绝对路径或可变 HEAD。每个 action 的顶层 workspace 直接返回实时观察,无 current/status 嵌套;workspace action 不返回 bindingStatus。get 顶层 bindingStatus 仅为 matched/mismatch/detached,binding 为已存绑定;list 有效行的 workspace 为已存绑定并附 bindingStatus。历史 change 合入后不会自动改绑。分支改名、明确接管或普通目录初始化为仓库后,用当前 revision 单独重绑:
27
+ ## 材料与工作区
32
28
 
33
- ```json
34
- {
35
- "action":"update","projectRoot":".","changeId":"20261107-existing","expectedRevision":1,
36
- "operations":[{"type":"bind-workspace","reason":"分支已重命名,确认当前分支继续负责本需求"}]
37
- }
38
- ```
29
+ 默认一个独立需求对应一个 change、一条分支、一个 worktree 和一个 Lead。由用户或外部助手先准备工作区;代码、知识、change 材料和需保留的证据均在本 worktree 内维护。
39
30
 
40
- bind-workspace 只接受 reason,实际分支/路径/提交由工具观察,不得夹带业务变更,也不能修复缺失绑定或非法 schema。重绑在 workspaceHistory 保留旧绑定、原因和时间,每项 previous 必填;相同绑定重试不增加 revision,普通提交/rebase 不要求 HEAD 相等或刷新 baseCommit。工作区不匹配先核对归属,分支重命名或确认接管后才显式重绑。绑定是状态写入保护,不是工作目录或 Lead 所有权锁;运行期间不外部切分支、搬移或清理 worktree。详细规则见 [工作区参考](skills/dev-workflow/references/workspace.md)。
31
+ 材料保存在 `.dev-docs/changes/<change-id>/`:`intent.md` 记录真实需求,`spec.md` 记录方案与验收,实施授权后才创建 `plan.md`;`state.json` 由工具维护版本与关联。仅设计交付不需要实施计划。工具接受 `schemaVersion: 2`,旧格式或损坏记录会报错,不自动迁移或修复。
41
32
 
42
- 正文写好后登记:
33
+ 每次调用 `lodestar_change` 显式传入 `projectRoot`。Git 项目根须与调用 Agent 的工作目录属于同一 checkout,普通目录须位于 Agent 工作目录内。`workspace` 观察工作区,`list` 和 `get` 读取状态,`create` 创建 change,`update` 以 `expectedRevision` 原子提交领域操作。
43
34
 
44
35
  ```json
45
- {
46
- "action":"update","projectRoot":".","changeId":"20261107-example","expectedRevision":1,
47
- "operations":[{"type":"register-document","kind":"intent","classification":"semantic","basedOn":{},"reason":"初次登记"}]
48
- }
49
- ```
50
-
51
- 其他操作和确切字段参见 [工具输入 schema](src/schema.js) 与 [skill](skills/dev-workflow/SKILL.md)。每次更新最多 32 个操作,全部成功才发布。遇到冲突先 get 再合并;未知回执先核对记录,不盲重试。材料链接不作为写入目标;材料目录与文件拒绝符号链接,项目根可以由宿主解析为规范路径。
52
-
53
- 确认引用实际用户表达和材料版本;工具只校验结构与前置条件,不声称能够鉴别用户授权语义。正文变化需重新登记,相关验收失效由 Lead 明确标记。原生 Team 进度仍以宿主任务板为准。
54
-
55
- PR/MR 地址、源/目标分支、评审/合入结果和证据记录在既有 plan/交付材料中,不新增远端生命周期调度器。交付要求合入时,close 前完成合入及集成验证;交付边界是提交 PR 时不声称已合入。需保留的代码、知识与 change 材料随分支提交,经 PR/MR 集成;知识和 state 冲突须核对语义。提交及清理需相应授权,清理前保留未提交材料与证据。worktree 只隔离文件,端口、数据库、账号等外部资源仍须按需求隔离。
56
-
57
- ## 开发与验证
58
-
59
- 需要 Node.js 24+、pnpm(不固定版本)、Git 及宿主 subprocess 服务,核对宿主版本为 DSH `0.2.2-rc.1`;Git 查询遵守调用会话的 sandbox policy,不使用裸 Node child_process 或 shell 绕过宿主。依赖无安装脚本:
60
-
61
- ```sh
62
- pnpm install --frozen-lockfile --ignore-scripts
63
- # prepack 自动执行语法检查和测试,并预览实际发布文件
64
- npm pack --dry-run
65
- ```
66
-
67
- 真实宿主集成测试可使用现有 DSH 安装目录,无需 profile 安装:
68
-
69
- ```sh
70
- DSH_HOST_ROOT=/absolute/path/to/node_modules/@deepseek-ai/dsh pnpm test
36
+ {"action":"workspace","projectRoot":"."}
71
37
  ```
72
38
 
73
- 未提供该路径时宿主集成测试会显式跳过;其余单测独立运行。测试覆盖状态转换、版本关系、并发、损坏状态、目录边界、注册及资源。真实模型的授权理解、Team 协作和中断恢复等行为验收见 [场景清单](tests/scenarios.md);程序测试不能代替这些观察。
74
-
75
- ## 文档
76
-
77
- - [设计](docs/design.md) 与 [提案](docs/proposal.md)
78
- - [Agent 角色调查](docs/research/agent-presets.md) 与 [开发模式调查](docs/research/development-mode.md)
79
- - [工作流调研](docs/research/workflow-survey.md) 与 [会话成本案例](docs/research/labwarden-session-cost.md)
80
-
81
- ## npm 发布与 GitHub Actions
82
-
83
- 包名为 `@fooksky/lodestar`,采用 [MIT 许可证](LICENSE),发布到公共 npm registry。[GitHub 源码仓库](https://github.com/urzz/lodestar) 保持私有,npm 包公开,安装公开包无需 GitHub 仓库权限或 npm 登录。直接分发 ESM 源码、bundle patch、Skill、图标和文档,这些发布文件可被公开下载;无需构建产物,`npm pack` 和 `npm publish` 的 `prepack` 钩子会先执行语法检查与测试。
84
-
85
- [CI](.github/workflows/ci.yml) 在 `main` 分支推送、PR 和发布前运行,使用 Node.js 24 和最新版 pnpm,并安装固定版本的 DSH `0.2.2-rc.1` 执行真实宿主集成测试及打包预览。临时宿主与项目依赖分开安装,不修改任何本机 profile。
86
-
87
- [发布工作流](.github/workflows/publish.yml) 在推送 `v*` 标签时触发,等待完整 CI 通过,然后使用 Node.js 24、pnpm 冻结安装依赖,再通过 npm 11 和 GitHub OIDC Trusted Publishing 发布,无需长期 npm Token。私有源码仓库不支持 npm provenance,因此在 `publishConfig` 中显式关闭,适用于 Actions 和本地发布;仓库无需公开。稳定版本发布到 `latest`,含预发布后缀的版本发布到 `next`;标签必须严格等于包版本的 `v` 前缀形式。
88
-
89
- 首次发布前需要完成:
90
-
91
- 1. GitHub origin 和包元数据 `repository.url` 已指向 `urzz/lodestar`,保持两者与 Trusted Publisher 中配置的仓库一致;GitHub 仓库保持私有。
92
- 2. 使用 npm 账号 `fooksky` 发布公开包 `@fooksky/lodestar`(公开 scoped 包免费)。如果 npm 尚无该包,先在受信任本机通过 `npm login --registry=https://registry.npmjs.org/`、`npm publish --access public --registry=https://registry.npmjs.org/` 完成首次发布,再配置自动发布;不要重复发布同一版本。npm 账号与 GitHub owner `urzz` 可以不同。
93
- 3. 在 npm 包设置中添加 GitHub Actions Trusted Publisher:owner 填 `urzz`,仓库名填 `lodestar`,workflow filename 填 `publish.yml`,允许直接使用 `npm publish`。本工作流没有配置 GitHub Environment,该项留空。无需在 GitHub 配置 `NPM_TOKEN`。
94
-
95
- 后续发布流程:
96
-
97
- ```sh
98
- # 更新版本,再同步 pnpm 锁文件;暂不自动创建提交和标签
99
- npm version patch --no-git-tag-version
100
- pnpm install --lockfile-only --ignore-scripts
101
- # 审阅后提交版本文件,并创建匹配标签;示例版本需替换成实际版本
102
- git add package.json pnpm-lock.yaml
103
- git commit -m "chore: release v0.2.1"
104
- git tag v0.2.1
105
- git push origin main
106
- git push origin v0.2.1
107
- ```
39
+ 流程规则见 [skill](skills/dev-workflow/SKILL.md),工作区规则见 [工作区参考](skills/dev-workflow/references/workspace.md),确切参数见 [工具 schema](src/schema.js)。
108
40
 
109
- 若用 `npm version prerelease --preid=beta --no-git-tag-version` 更新版本,再按上述步骤同步锁文件、提交和打标签,发布工作流会自动选择 `next`。origin 和 npm Trusted Publisher 配置完成前,本地仍可运行 `npm pack --dry-run` 验证分发内容。
41
+ 采用 [MIT 许可证](LICENSE)。[GitHub 源码仓库](https://github.com/urzz/lodestar) 为私有仓库,npm 包公开分发;维护约定、历史设计与测试材料保留在源码仓库,不随包分发。
package/index.js CHANGED
@@ -14,7 +14,7 @@ export async function apply(ctx) {
14
14
  ...references.map(name => readFile(new URL(`references/${name}.md`, resourceDirectory), 'utf8')),
15
15
  ]);
16
16
  const disposeSkill = ctx.skills.register({
17
- name: 'dev-workflow',
17
+ name: 'lodestar',
18
18
  description: 'Guide development changes through confirmed intent, reviewed specification, authorized planning, native execution and evidence-based delivery. Resume changes in .dev-docs without repeating valid confirmations.',
19
19
  source: 'bundled',
20
20
  path: fileURLToPath(new URL('SKILL.md', resourceDirectory)),
package/locale/en.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "name": "Development Workflow",
3
- "description": "Confirmed intent, reviewed design, native execution and evidence-based delivery. Optional development preset; never changes your default mode."
2
+ "name": "Lodestar · 开发工作流",
3
+ "description": "Confirm intent, review designs, reuse available tools and Teams, and deliver with evidence. Supports design-only work. Optional preset; preserves your default mode."
4
4
  }
package/locale/zh.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "name": "开发工作流",
3
- "description": "确认真实需求、审核方案、原生执行与证据交付。可选开发模式,不修改默认模式。"
2
+ "name": "Lodestar · 开发工作流",
3
+ "description": "确认真实需求、评审方案,使用已有工具与 Teams 执行并依据证据交付;支持仅设计。可选模式,不修改默认模式。"
4
4
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fooksky/lodestar",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "license": "MIT",
5
5
  "repository": { "type": "git", "url": "git+https://github.com/urzz/lodestar.git" },
6
6
  "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/", "provenance": false },
@@ -15,7 +15,7 @@
15
15
  "./package.json": "./package.json",
16
16
  "./locale/*.json": "./locale/*.json"
17
17
  },
18
- "files": ["index.js", "src", "cordis.patch.yml", "skills", "locale", "icon.svg", "README.md", "docs/design.md", "docs/branch-management.md", "docs/proposal.md", "docs/research", "tests/scenarios.md", "LICENSE"],
18
+ "files": ["index.js", "src", "cordis.patch.yml", "skills", "locale", "icon.svg", "README.md", "LICENSE"],
19
19
  "scripts": { "test": "node --test tests/*.test.js", "check": "node --check index.js && node --check src/state.js && node --check src/store.js && node --check src/tool.js && node --check src/schema.js && node --check src/workspace.js && node --check src/preset.js", "prepack": "pnpm check && pnpm test" },
20
20
  "icon": "./icon.svg",
21
21
  "dsh": { "bundle": { "patch": "./cordis.patch.yml" } },
@@ -1,4 +1,4 @@
1
- # 开发工作流
1
+ # Lodestar · 开发工作流
2
2
 
3
3
  用于开发变更和恢复既有 change。主线:确认真实意图 → 审核具体方案并获得实施授权 → 生成 plan → 原生执行与验证 → 交付。用户当前明确要求优先;调查、解释或仅设计请求不自动升级为实施。
4
4
 
@@ -6,15 +6,15 @@
6
6
 
7
7
  ## 开始与材料
8
8
 
9
- 先确定用户范围,由用户或外部助手准备隔离 worktree,再读取 references/workspace.md 并调用 workspace 核对实际 projectRoot、分支与绑定。默认一个独立需求对应一个 change、一条分支、一个 worktree 和一个 Lead;插件不负责跨需求调度或创建/切换分支。每次 dev_workflow 调用显式传本 worktree 的 projectRoot,不维护全局当前 change。恢复时读 references/recover.md;新工作按需读 references/intent.md。没有状态工具时明确报告能力缺失,不手工伪造 state.json。
9
+ 先确定用户范围,由用户或外部助手准备隔离 worktree,再读取 references/workspace.md 并调用 workspace 核对实际 projectRoot、分支与绑定。默认一个独立需求对应一个 change、一条分支、一个 worktree 和一个 Lead;插件不负责跨需求调度或创建/切换分支。每次 lodestar_change 调用显式传本 worktree 的 projectRoot,不维护全局当前 change。恢复时读 references/recover.md;新工作按需读 references/intent.md。没有状态工具时明确报告能力缺失,不手工伪造 state.json。
10
10
 
11
11
  新 change 先调用 create 创建 schemaVersion: 2 状态,workspace 必填并自动绑定当前命名分支或普通目录,再按阶段写正文并登记;create 拒绝已存在目录,不自动接管或覆盖。材料位于本 worktree 的 .dev-docs/changes/<change-id>/,ID 用 YYYYMMDD-short-slug,冲突才加短后缀。只复用本 worktree 的 .dev-docs/index.md、knowledge/ 和已有项目文档,不读取其他 checkout 的实时材料或共享材料根。intent.md 在澄清时创建,spec.md 在设计时创建,plan.md 在实施授权后创建;不预建空模板树。正文可短,Markdown 是语义权威,state 是状态与关联权威,DSH 是执行事实权威。
12
12
 
13
- 通过宿主文件工具先写正文,再用 dev_workflow update/register-document 登记;固定正文 SHA-256 仅用于检测变化,不证明语义一致。不得用裸 fs 绕过宿主权限、手改 state、自动覆盖损坏记录或把未经核实的材料当成用户确认。
13
+ 通过宿主文件工具先写正文,再用 lodestar_change update/register-document 登记;固定正文 SHA-256 仅用于检测变化,不证明语义一致。不得用裸 fs 绕过宿主权限、手改 state、自动覆盖损坏记录或把未经核实的材料当成用户确认。
14
14
 
15
15
  ## 授权与阶段
16
16
 
17
- 澄清时可调查,不写业务实现、脚手架或原型。需求确认后进 spec;具体方案审核且实施授权后进 plan;plan 及验收/步骤关联有效后进 execute。只要求设计时交付 spec 并停止,不创建实施 plan 或启动编码 goal。
17
+ 澄清时可调查,不写业务实现、脚手架或原型。需求确认后进 spec;具体方案审核且实施授权后进 plan;plan 及验收/步骤关联有效后进 execute。只要求设计时核对设计验收后以 close 的 delivery: design 从 spec 完成交付,不创建实施 plan 或启动编码 goal。
18
18
 
19
19
  真实用户表达可同时确认需求、审核方案并授权实施,在一次 update 登记多条决定;已授权范围继续推进,不机械重复询问。“设计没问题,先别做”只表示审核。沉默、跳过、工具审批或 goal 续轮不是用户决定。“继续”解除暂停,不补齐缺失的需求/方案决定。source 保存短摘录和可得 session/event 引用;没有事件定位时标为 Agent 记录并说明上下文,不伪造事件号。
20
20
 
@@ -22,7 +22,7 @@
22
22
 
23
23
  ## 工具使用
24
24
 
25
- 工具只有 dev_workflow,action 为 workspace/list/get/create/update。workspace 只读观察当前工作区;get/list 返回实时工作区与绑定状态,list 默认分页 20,get 可按 section 读取且不附正文。create 不覆盖;update 携 expectedRevision 和最多 32 个有类型 operations。领域操作是 bind-workspace、register-document、record-decision、set-acceptance、bind-step、set-step-progress、record-verification、invalidate-verification、set-blocker、set-workflow、close。具体字段以工具 schema 为准,不用 JSON Patch。
25
+ 工具只有 lodestar_change,action 为 workspace/list/get/create/update。workspace 只读观察当前工作区;get/list 返回实时工作区与绑定状态,list 默认分页 20,get 可按 section 读取且不附正文。create 不覆盖;update 携 expectedRevision 和最多 32 个有类型 operations。领域操作是 bind-workspace、register-document、record-decision、set-acceptance、bind-step、set-step-progress、record-verification、invalidate-verification、set-blocker、set-workflow、close。具体字段以工具 schema 为准,不用 JSON Patch。
26
26
 
27
27
  bindingStatus 仅为 matched、mismatch 或 detached。mismatch 先核对工作区和接管依据;分支改名、明确接管或普通目录初始化为仓库后,单独 bind-workspace 并提供 reason,不能夹带业务变更,workspaceHistory 每项的 previous 必填。未知或旧 schema、缺失 workspace 均拒绝,不能用重绑修复。list 不特殊识别未受管目录,缺失或非法 state 显示错误。detached 只读;unborn 命名分支允许 baseCommit 为 null。Git projectRoot 必须与 Agent cwd 属于同一 checkout,普通目录根须位于 cwd 内。写正文前也遵守这些边界,状态绑定不能限制其他文件工具;运行期间不外部切分支或清理工作区。详细规则见 references/workspace.md。
28
28
 
@@ -30,6 +30,8 @@ bindingStatus 仅为 matched、mismatch 或 detached。mismatch 先核对工作
30
30
 
31
31
  ## 完成
32
32
 
33
+ 仅设计关闭使用 close 的 delivery: design,直接从 spec 到 done:当前 intent 已确认、当前 spec 已审核,当前验收索引及 required 项均有有效 passed 证据(无适用项时登记 noApplicableReason),无当前失败与 open blocker,并提供交付 evidenceRefs。已有 plan、执行记录或当前实施授权时不能改标设计交付。省略 delivery 沿用实施交付约束;设计关闭不代表实施完成。
34
+
33
35
  验收编号 A1、A2…稳定且不复用给新含义。所有 required 验收有当前有效 passed、无 open blocker,且真实需求满足时才交付;close 要写交付摘要、需求满足依据和知识处理结论。缺环境只能报告“已实现,验证未完成”。已满足需求、规格和必需验收即收敛,不追加无关优化。
34
36
 
35
37
  委派按需读取 references/delegation.md。浏览器与记忆不是必需依赖,但不能以 fixture 或截图生成冒充真实交互验收。长期知识只写稳定事实,可明确“无稳定知识变化”。完成后保留原 change 路径,不自动归档。
@@ -0,0 +1,62 @@
1
+ # Lodestar 使用指南
2
+
3
+ ## 模式说明
4
+
5
+ 「Lodestar · 开发工作流」是可选的 DSH 会话模式。它加入一段流程入口提示,让 Agent 加载公开技能 `lodestar`,通过 `lodestar_change` 维护开发变更,并复用当前部署已有的文件、终端、会话历史和 Teams 工具。它是提示适配器,不是额外的执行器;不会安装缺失工具、复制完整 profile、切换模型、改变权限或替用户批准实施。
6
+
7
+ 核心插件注册技能和状态工具,可在其他兼容模式中使用;可选 preset 默认关闭。模式内部标识仍为 `dev-workflow`,这是配置标识;用户加载技能时使用 `lodestar`。资源目录保留原名称以稳定随包路径。
8
+
9
+ 流程有两种交付范围:
10
+
11
+ | 范围 | 工作与完成条件 |
12
+ |---|---|
13
+ | 设计并实施 | 确认需求 → 评审具体方案并授权实施 → 计划 → 执行与验证 → 交付。必需验收要有有效通过证据。 |
14
+ | 仅设计 | 确认需求 → 评审方案 → 核对设计验收并交付。记录设计证据,以 `close` 的 `delivery: "design"` 从 spec 完成;不创建实施 plan,不启动编码。 |
15
+
16
+ 选择模式不等于授权实施。只调查或解释的请求按该范围处理,不必把每次问答都建成 change。原生工具的成功回执能证明操作结果,用户真实需求是否满足仍需 Lead 判断。
17
+
18
+ ## 如何使用
19
+
20
+ ### 1. 准备宿主与工作区
21
+
22
+ 需要 Node.js 24+、Git 和兼容 DSH;版本范围见 [包配置](../../package.json)。使用 DSH 的插件管理安装 `@fooksky/lodestar` 并启用核心插件。若需要模式入口,进入侧栏「插件」→「已安装」→ `@fooksky/lodestar` 详情,在「包含的组件」中打开 `dev-workflow-preset` 行的「启用组件」开关;该组件默认关闭。再在新会话开始前选择「Lodestar · 开发工作流」。支持模式指南的宿主可展示本指南的「模式说明 / 如何使用」;旧宿主忽略指南字段,不影响核心技能和随包文档的使用。
23
+
24
+ 核心需要宿主提供技能、工具、文件、工作目录和 subprocess 服务。完整开发模式还使用读写编辑、路径搜索、终端与 job、提问、会话历史及 Teams 能力。preset 仅检查可见工具并在提示中报告缺口,不会提供这些服务。部署缺少实际任务所需能力时,Agent 应说明缺口;浏览器、记忆及普通 subagent 仅在环境提供且任务需要时使用。受委派成员只检查自己的任务包所需能力。
25
+
26
+ 默认由用户或外部助手为每个独立需求准备分支和 worktree。Lodestar 会检查调用 Agent 的实际 cwd 与项目根,并把 change 绑定到工作区;不会创建或切换分支。明确指定在现有工作区执行的授权仍按用户范围处理。
27
+
28
+ ### 2. 进入流程并说明目标
29
+
30
+ 新会话可以选择「Lodestar · 开发工作流」。已有兼容会话可以直接要求加载 `lodestar` skill。
31
+
32
+ 例如:
33
+
34
+ > 加载 lodestar。请先调查登录失败的原因,给出可评审方案;我确认后再实施。
35
+
36
+ > 只设计导出功能,列出数据流、接口和验收要求,不写实现代码。
37
+
38
+ > 需求和方案已经按上述内容确认,授权实施;在已指定工作区继续,不重复询问。
39
+
40
+ Agent 先确认范围、调用 `workspace` 核对工作区,再按需要创建 change。已明确的需求、方案审核和实施授权可复用;「继续」本身不会补齐从未给出的授权。
41
+
42
+ ### 3. 查看材料与结果
43
+
44
+ 项目内 `.dev-docs/changes/<change-id>/` 保存需求 `intent.md`、方案 `spec.md`、实施计划 `plan.md`(授权实施后才创建)及工具状态 `state.json`。正文是语义依据,状态记录版本、决定、验收与证据关联。不要手改状态文件;正文先通过宿主文件工具写入,再登记版本。
45
+
46
+ 实施完成必须核对真实需求、必需验收和交付边界;仅设计完成必须核对当前需求确认、方案审核、设计验收及证据,无未解决阻塞。设计完成后如需实施,应明确新范围,再恢复相应阶段并获得实施授权,不能把设计交付说成已经实现。
47
+
48
+ ### 4. 恢复工作
49
+
50
+ > 加载 lodestar,继续 change `20261108-example`。先核对当前工作区、文档版本和剩余任务,复用仍有效的确认与证据。
51
+
52
+ 若不知道 change ID,可要求列出本工作区候选。Agent 应先读状态和相关材料,再查必要历史,不全量重跑。分支归属不匹配须先核对依据;明确分支改名或接管时单独重绑。detached 工作区仅可读;旧格式、损坏状态和缺失绑定需要报告,不自动修复。
53
+
54
+ ## 能力边界与故障处理
55
+
56
+ - 缺少 `lodestar_change`:检查核心插件是否启用;Agent 不应手工伪造状态。
57
+ - 模式提示缺少能力:补齐部署服务,或按当前任务缩小范围并如实报告未完成项;模式不会扩大权限。
58
+ - revision 冲突:重新读取并合并语义,避免盲重试;写入结果未知时先查已有记录。
59
+ - 缺少必要验证环境:报告具体阻断,不能把编译或 fixture 当作真实交互验收。
60
+ - 提交、推送、发布、安装及清理:依据用户明确授权执行;选择本模式并不授权这些动作。
61
+
62
+ 更细的 Agent 执行规则见 [技能正文](SKILL.md)、[工作区参考](references/workspace.md)、[恢复参考](references/recover.md);工具参数以 [schema](../../src/schema.js) 为准。返回 [README](../../README.md)。
@@ -8,6 +8,8 @@
8
8
 
9
9
  视觉检查分有界小包及时记结论;要求全量覆盖时不能静默抽样。缺浏览器等必需环境就报告具体阻断。测试通过但真实需求不足仍不得 close。
10
10
 
11
- 进入 deliver 需 required 当前有效 passed 且无 open blocker;close 再记录交付说明、需求满足依据、必需验收关联、知识处理结论。稳定知识只更新本 worktree 的现有主题并引用已有 README/架构,不读取其他 checkout 的实时知识、不保存调试流水账。可写“无稳定知识变化”。达到范围即收敛;未完成明确差距,不用“已实现”冒充全部验收通过。
11
+ 实施交付进入 deliver 需 required 当前有效 passed 且无 open blocker;close 再记录交付说明、需求满足依据、必需验收关联、知识处理结论。稳定知识只更新本 worktree 的现有主题并引用已有 README/架构,不读取其他 checkout 的实时知识、不保存调试流水账。可写“无稳定知识变化”。达到范围即收敛;未完成明确差距,不用“已实现”冒充全部验收通过。
12
+
13
+ 仅设计交付不经过实施 deliver:在 spec 使用 close 的 delivery: design,核对当前 intent 确认、spec 审核、验收及设计证据,提供非空 evidenceRefs,并确保无当前失败和 open blocker。不得已有 plan、执行记录或当前实施授权。它只证明设计交付;省略 delivery 的 close 仍按实施约束执行。
12
14
 
13
15
  PR/MR 地址、源/目标分支、评审与合入结果及证据写入既有 plan/交付材料;若合入是必需交付条件,close 前完成合入与集成验证;若边界是提交 PR,不声称已经合入。PR 反馈按原有阶段退回、版本和局部证据失效规则处理。需要保留的代码、知识与 change 材料随分支提交并经 PR/MR 集成,同一知识文件或 state 冲突需核对语义,文本合并成功不能代替验收。提交及 worktree 清理按明确授权执行,清理前保留未提交材料与证据;数据库、端口、账号及外部资源仍须单独隔离。
@@ -10,4 +10,4 @@
10
10
 
11
11
  同会话查询仍在写的成员和原生任务。跨会话旧 Team 不可达时核对成果,仅为剩余部分建新任务,通过 bind-step 为同一 P 编号重新绑定时提供 reason,previousBindings 保留旧引用和替代关系;旧成员写入归属不明时先解决,不能重复抢写相同路径。
12
12
 
13
- 读取状态不会触发全量重验。证据仍有效则沿用;必需证据丢失才补验。done 后独立新需求另建 change;原交付问题可记录原因退回对应阶段。暂停、等待、阻断保留阶段,不靠切模式或重建 change 绕过缺口。
13
+ 读取状态不会触发全量重验。证据仍有效则沿用;必需证据丢失才补验。done 后独立新需求另建 change;原交付问题可记录原因退回对应阶段。closure.delivery 为 design 时仅代表设计交付,省略则按既有实施交付理解。设计后明确要求继续实施,可通过 set-workflow 退回 spec(移除 closure),确认当前方案与实施授权后再登记 plan;不能把旧设计证据当作实现验收。暂停、等待、阻断保留阶段,不靠切模式或重建 change 绕过缺口。
@@ -4,6 +4,6 @@ spec 引用已确认 intent,说明预期行为、影响范围、职责/数据
4
4
 
5
5
  验收使用稳定 A 编号;删除的编号不复用。覆盖真实用户需求,不能只证明代码符合自己的方案。明确 required 项、实际被测对象与环境;确无适用验收时,在已审核 spec 中说明并登记显式依据,不以空集合绕过验收。
6
6
 
7
- 正文写入后登记 register-document,spec basedOn 当前 intent;set-acceptance 显式更新当前版本索引。来源明确、范围匹配且未撤回的审核可复用;“先别做”不是实施授权。仅设计请求到此交付并停止。
7
+ 正文写入后登记 register-document,spec basedOn 当前 intent;set-acceptance 显式更新当前版本索引。来源明确、范围匹配且未撤回的审核可复用;“先别做”不是实施授权。仅设计请求在当前 intent 确认、spec 审核和验收证据齐备后,用 close 的 delivery: design 从 spec 直接关闭到 done,附交付 evidenceRefs、summary、satisfaction 和 knowledge。required 项须当前有效 passed,无当前失败或 open blocker;无适用验收须登记 noApplicableReason。已有 plan、执行记录或当前实施授权时不能以 design 关闭;不为设计交付创建实施计划。
8
8
 
9
9
  语义改变时先暂停受影响成员,同次状态更新退回 spec 并使旧版本决定不再适用。用户已明确批准差异就引用该表达登记新版本决定,无需再问。排版变化有理由即可,不自动撤回确认;程序摘要不判断语义,Lead 负责分类。
@@ -1,6 +1,6 @@
1
1
  # 工作区与分支绑定
2
2
 
3
- 开始新需求或恢复前调用 `dev_workflow` 的 `workspace` action,显式传当前 worktree 内的 `projectRoot`。默认一个独立需求对应一个 change、一条分支、一个 worktree 和一个 Lead。外部助手或用户负责领取 Issue、跨需求分配、创建/选择 worktree 和启动会话;插件只维护当前分支内的流程与状态,不创建/切换/删除分支、不扫描其他工作区、不调度需求、不自动提交或调用 PR API。
3
+ 开始新需求或恢复前调用 `lodestar_change` 的 `workspace` action,显式传当前 worktree 内的 `projectRoot`。默认一个独立需求对应一个 change、一条分支、一个 worktree 和一个 Lead。外部助手或用户负责领取 Issue、跨需求分配、创建/选择 worktree 和启动会话;插件只维护当前分支内的流程与状态,不创建/切换/删除分支、不扫描其他工作区、不调度需求、不自动提交或调用 PR API。
4
4
 
5
5
  代码、`.dev-docs/knowledge/`、change 正文、state 和需保留的证据全部位于本 worktree。新工作区继承基准提交的知识快照,之后只读写本地材料;不使用共享材料根、符号链接或主 checkout 的实时知识。材料以当前 worktree 为唯一权威,不能复制后两处继续写;插件不自动搬移或提交。
6
6
 
package/src/preset.js CHANGED
@@ -1,18 +1,26 @@
1
+ import { readFile } from 'node:fs/promises';
2
+
3
+ const guideText = await readFile(new URL('../skills/dev-workflow/USER_GUIDE.md', import.meta.url), 'utf8');
4
+ // Inline host Markdown has no package-relative URL base; keep labels for local links.
5
+ const inlineGuide = guideText.replace(/\[([^\]]+)\]\((?!https?:\/\/)[^)]+\)/g, '$1');
6
+ const [explanation, usage] = inlineGuide.split('\n## 如何使用\n');
7
+
1
8
  export const name = 'dev-workflow-preset';
2
9
  export const inject = ['tools', 'agentPresets', 'systemPrompt'];
3
10
 
4
11
  // Reuse the deployment's native services and visible tools, without cloning a profile.
5
12
  export const requiredTools = [
6
- 'dev_workflow', 'read', 'write', 'edit', 'glob', 'grep', 'bash',
13
+ 'lodestar_change', 'read', 'write', 'edit', 'glob', 'grep', 'bash',
7
14
  'job_output', 'job_list', 'job_kill', 'skill', 'ask_user_question',
8
15
  'session_search', 'session_event_search', 'session_event_read',
9
16
  'team_task_list', 'team_task_get', 'team_task_update', 'team_task_create',
10
17
  'spawn_teammate', 'send_message', 'list_agents',
11
18
  ];
12
- export const modeText = '本会话采用开发工作流。开发变更先加载 dev-workflow,定位或创建 change,按当前阶段继续。只调查、解释或设计时遵守该范围;选择模式不构成实施、提交、发布或安装授权。受委派成员执行任务包并向 Lead 回报,不重复启动 Lead 需求确认流程。浏览器、记忆和普通 subagent 仅在部署提供且任务需要时使用。';
19
+ export const modeText = '本会话采用开发工作流。开发变更先加载 lodestar,定位或创建 change,按当前阶段继续。只调查、解释或设计时遵守该范围;选择模式不构成实施、提交、发布或安装授权。受委派成员执行任务包并向 Lead 回报,不重复启动 Lead 需求确认流程。浏览器、记忆和普通 subagent 仅在部署提供且任务需要时使用。';
13
20
  export const definition = {
14
- id: 'dev-workflow', name: '开发工作流',
15
- description: 'Confirmed intent, reviewed design and evidence-based development using native Teams.',
21
+ id: 'dev-workflow', name: 'Lodestar · 开发工作流',
22
+ description: '确认真实需求、评审方案,使用已有工具与 Teams 执行,并依据证据交付;也支持仅设计。',
23
+ guide: { explanation, usage },
16
24
  plugins: [{ id: 'dev-workflow-entry', name: '@fooksky/lodestar/preset', config: { entry: true } }],
17
25
  };
18
26
  export async function apply(ctx, config = {}) {
package/src/schema.js CHANGED
@@ -51,13 +51,23 @@ export function validateRelations(s, code = 'INVALID_STATE') {
51
51
  const decision = (kind, keys) => s.decisions.some(d => d.kind === kind && !removed.has(d.id) && current(d.subjects) && keys.every(k => d.subjects[k] && d.subjects[k] === s.documents[k]?.version));
52
52
  const level = ['intent','spec','plan','execute','deliver','done'].indexOf(s.workflow.phase);
53
53
  if (level >= 1) check(decision('intent-confirmation', ['intent']), 'Missing current intent confirmation');
54
- if (level >= 2) check(s.documents.spec && current(s.documents.spec.basedOn) && decision('spec-review', ['intent','spec']) && decision('implementation-authorization', ['intent','spec']), 'Missing current spec approval/authorization');
54
+ const design = s.closure?.delivery === 'design';
55
+ if (level >= 2) {
56
+ check(s.documents.spec && current(s.documents.spec.basedOn) && decision('spec-review', ['intent','spec']), 'Missing current spec approval');
57
+ if (!design) check(decision('implementation-authorization', ['intent','spec']), 'Missing current implementation authorization');
58
+ }
59
+ if (design) {
60
+ check(!s.documents.plan && !s.execution.length && !decision('implementation-authorization', ['intent','spec']), 'Design closure cannot replace implementation delivery');
61
+ check(s.closure.evidenceRefs.length > 0, 'Design closure requires evidence');
62
+ }
55
63
  if (level >= 3) {
56
- check(s.documents.plan && current(s.documents.plan.basedOn), 'Invalid current plan');
57
64
  check(s.acceptance?.specVersion === s.documents.spec.version, 'Missing current acceptance');
58
65
  check(s.acceptance.items.some(a => a.required) || s.acceptance.noApplicableReason, 'Empty required acceptance without rationale');
59
- check(s.execution.length || s.acceptance.noApplicableReason, 'Missing execution steps');
60
- check(s.acceptance.items.filter(a => a.required).every(a => s.execution.some(p => p.acceptanceIds.includes(a.id))), 'Missing acceptance step coverage');
66
+ if (!design) {
67
+ check(s.documents.plan && current(s.documents.plan.basedOn), 'Invalid current plan');
68
+ check(s.execution.length || s.acceptance.noApplicableReason, 'Missing execution steps');
69
+ check(s.acceptance.items.filter(a => a.required).every(a => s.execution.some(p => p.acceptanceIds.includes(a.id))), 'Missing acceptance step coverage');
70
+ }
61
71
  }
62
72
  if (level >= 4) {
63
73
  check(!s.blockers.some(b => b.status === 'open'), 'Open blockers prevent delivery');
@@ -88,7 +98,7 @@ const step = z.discriminatedUnion('mode', [
88
98
  const verification = z.object({ id, acceptanceIds: z.array(id).min(1), specVersion: version, outcome: z.enum(['passed', 'failed', 'not-run', 'not-applicable', 'stale']), method: text, subject: text, environment: text, evidenceRefs: z.array(text), summary: text, supersedes: id.optional(), carriedFrom: id.optional(), carryReason: text.optional(), observedAt: z.iso.datetime().optional() }).strict();
89
99
  const blocker = z.object({ id, description: text, status: z.enum(['open', 'resolved']), resolution: text.optional() }).strict();
90
100
  const workflow = z.object({ phase: phaseSchema, status, reason: text, nextAction: text }).strict();
91
- const closure = z.object({ summary: text, acceptanceIds: z.array(id), satisfaction: text, knowledge: text, evidenceRefs: z.array(text) }).strict();
101
+ const closure = z.object({ delivery: z.enum(['implementation', 'design']).optional(), summary: text, acceptanceIds: z.array(id), satisfaction: text, knowledge: text, evidenceRefs: z.array(text) }).strict();
92
102
  const op = (type, shape) => z.object({ type: z.literal(type), ...shape }).strict();
93
103
  export const workspaceSchema = z.discriminatedUnion('kind', [
94
104
  z.object({ kind: z.literal('directory') }).strict(),
package/src/state.js CHANGED
@@ -130,7 +130,7 @@ export function applyOperations(state, operations, { expectedRevision, documents
130
130
  requireThat(s.acceptance?.items.filter(a => a.required).every(a => op.acceptanceIds.includes(a.id)), 'Closure must cover all required acceptance');
131
131
  const { type, ...closure } = op;
132
132
  s.closure = { ...closure, recordedAt: at };
133
- s.workflow = { phase: 'done', status: 'active', reason: op.summary, nextAction: 'Delivered' }; break;
133
+ s.workflow = { phase: 'done', status: 'active', reason: op.summary, nextAction: op.delivery === 'design' ? 'Design delivered' : 'Delivered' }; break;
134
134
  }
135
135
  }
136
136
  summary.push(op.type);
package/src/tool.js CHANGED
@@ -21,8 +21,8 @@ export function hostSchema(schema) {
21
21
 
22
22
  export function createTool(ctx) {
23
23
  return {
24
- name: 'dev_workflow',
25
- description: 'Inspect the current workspace and atomically maintain branch-local change state in .dev-docs. projectRoot must belong to the calling Agent checkout. Load dev-workflow for workflow semantics. create binds the current branch; get/list expose bindingStatus; an intentional branch rename or reassignment uses a separate update with bind-workspace and reason. User decisions require real sources. This tool does not authorize implementation or schedule tasks. On revision conflicts, get and merge before retrying.',
24
+ name: 'lodestar_change',
25
+ description: 'Inspect the current workspace and manage branch-local development changes, including document versions, decisions, acceptance criteria, execution references, verification records, and lifecycle constraints. State updates in .dev-docs are atomic. projectRoot must belong to the calling Agent checkout. Load lodestar for workflow semantics. Design-only completion uses close with delivery: design from spec after review and design evidence, without an implementation plan. create binds the current branch; get/list expose bindingStatus; an intentional branch rename or reassignment uses a separate update with bind-workspace and reason. User decisions require real sources. This tool does not authorize implementation or schedule tasks. On revision conflicts, get and merge before retrying.',
26
26
  parameters: { type: 'object', ...hostSchema(inputSchema) },
27
27
  output: {
28
28
  schema: hostSchema(outputSchema),
@@ -32,11 +32,11 @@ export function createTool(ctx) {
32
32
  const parsed = inputSchema.safeParse(raw);
33
33
  if (!parsed.success) throw new DomainError('INVALID_STATE', parsed.error.message);
34
34
  const args = parsed.data;
35
- if (!exec.agent) throw new Error('dev_workflow requires a calling Agent and session.');
35
+ if (!exec.agent) throw new Error('lodestar_change requires a calling Agent and session.');
36
36
  exec.signal?.throwIfAborted();
37
37
  const cwd = await ctx.workingDirectory.ensure(exec.agent, exec.signal);
38
38
  const policyService = ctx.get('sandboxPolicy');
39
- if (ctx.fs.sandboxMode !== undefined && !policyService) throw new Error('dev_workflow: sandboxed filesystem requires sandboxPolicy.');
39
+ if (ctx.fs.sandboxMode !== undefined && !policyService) throw new Error('lodestar_change: sandboxed filesystem requires sandboxPolicy.');
40
40
  const sandboxPolicy = policyService?.resolve({ session: exec.agent.session });
41
41
  try {
42
42
  const workspace = await inspectWorkspace(ctx, { cwd, projectRoot: args.projectRoot, signal: exec.signal, sandboxPolicy });
package/src/workspace.js CHANGED
@@ -42,7 +42,10 @@ export async function inspectWorkspace(ctx, { cwd, projectRoot, signal, sandboxP
42
42
  const identify = async target => {
43
43
  const directory = fs.processPath(target);
44
44
  const probe = await query(directory, ['rev-parse', '--is-bare-repository']);
45
- if (probe.code === 128 && probe.err === 'fatal: not a git repository (or any of the parent directories): .git') return { kind: 'directory' };
45
+ if (probe.code === 128 && (
46
+ probe.err === 'fatal: not a git repository (or any of the parent directories): .git'
47
+ || /^fatal: not a git repository \(or any parent up to mount point .+\)\r?\nStopping at filesystem boundary \(GIT_DISCOVERY_ACROSS_FILESYSTEM not set\)\.$/.test(probe.err)
48
+ )) return { kind: 'directory' };
46
49
  const bare = checked(probe);
47
50
  if (bare === 'true') fail('INVALID_WORKSPACE', 'A bare repository has no development checkout.');
48
51
  if (bare !== 'false') fail('GIT_QUERY_FAILED', 'Unexpected Git repository probe output.');
@@ -1,60 +0,0 @@
1
- # 分支与 worktree 隔离设计
2
-
3
- 日期:2026-11-07。用户已确认完整 worktree 隔离、PR/MR 集成冲突和插件不承担调度,并明确授权在无新增待决事项时继续实现。本文把这些决定细化为实现契约;不包含安装、提交或推送授权。
4
-
5
- ## 1. 边界
6
-
7
- 一个独立需求默认对应一个 change、一条分支、一个 worktree 和一个 Lead。代码、`.dev-docs/knowledge/`、change 正文、state 和需要保留的证据全部位于当前 worktree。创建工作区继承基准提交中的知识快照,后续不实时读取其他 checkout 的材料,不使用共享材料根或符号链接。
8
-
9
- 外部助手负责 Issue 领取、跨需求分配、创建/选择 worktree 和启动会话。本插件只负责当前分支内的流程与状态;不新增调度器、跨工作区扫描、全局 current change、分支创建/切换/删除、自动 Git 提交或 PR API。既有工作区由用户/外部助手通过 DSH 原生能力准备。同一需求内部仍可用原生 Teams,Lead 单 owner 写主材料。
10
-
11
- ## 2. 当前工作区观察
12
-
13
- `dev_workflow` 增加只读 `action: workspace`。每个 action 在调用 Agent 的实际 cwd 和显式 projectRoot 上识别当前 Git checkout,返回有界 workspace 信息。Git 查询经宿主 subprocess 和调用会话的 sandbox policy 执行;不使用 Node child_process 或 shell,也不绕过文件 backend。Git 是运行依赖,缺少 Git/宿主服务、取消、权限拒绝、仓库损坏均保持错误,不伪装成非 Git。
14
-
15
- 通过 Git 的明确“not a git repository”诊断识别普通目录;固定查询语言并清除改变仓库发现的 Git 环境变量。普通目录继续支持工作流。bare 仓库拒绝使用。Git 支持标准 checkout、linked worktree、子模块与项目子目录;projectRoot 必须存在。
16
-
17
- 运行时信息包括实际 projectRoot、checkoutRoot、项目相对 checkout 的路径、分支和当前 HEAD。detached HEAD 可读不可写;unborn 命名分支允许使用,HEAD 为 null。分支和 HEAD 每次读取实际 Git 事实,不用 state 代替。
18
-
19
- Git 项目要求 Agent cwd 与 projectRoot 属于同一 checkout,不能从需求 worktree 指向主 checkout 的材料,即使会话有跨目录写权限。普通目录要求 projectRoot 位于 Agent cwd 内;cwd 可以是现有项目下任意目录,但 Git 情形仍按同一 checkout 判定。路径通过宿主 fs 规范化和 contains 比较,避免字符串路径别名绕过。
20
-
21
- ## 3. 持久绑定与版本
22
-
23
- 状态格式仅接受 `schemaVersion: 2`,`workspace` 必填,是以下二者之一:
24
-
25
- - Git:`{ kind: 'git', branch, baseCommit, projectPath }`。baseCommit 为首次绑定/重新绑定时的 HEAD,可为 null;它只记录来源,不参与 HEAD 相等或祖先检查。
26
- - 普通目录:`{ kind: 'directory' }`。
27
-
28
- 不把机器绝对路径、session owner 或可变当前 HEAD 存入版本化 state;移动/重新检出到其他机器或目录无需重写绑定。changeId 保持需求身份,branch 只是工作区关联。相同分支名不构成跨仓库身份或安全证明,复制材料不自动表示已经接管需求。
29
-
30
- 未知或旧 schema、缺失 workspace 均拒绝,不自动转换。list 不区分未受管目录;缺失或非法 state 的条目显示对应错误,不自动初始化或修复。
31
-
32
- `bind-workspace` 参数只有 reason,实际绑定由工具观察,不接受模型填写分支/路径/提交。用于命名分支重命名、确认后的分支接管、普通目录初始化为仓库后的显式重绑,不能修复缺失绑定或非法 schema。绑定作为独立 update,不能夹带业务变更;已有绑定替换时在 workspaceHistory 保留旧绑定、原因及时间,每项的 previous 必填。相同绑定重试不增加 revision;普通提交/rebase 后重复绑定同一分支和项目路径也不更新 baseCommit。
33
-
34
- ## 4. 读写规则
35
-
36
- 每个 action 的顶层 workspace 直接返回当前工作区观察,不嵌套 current/status;workspace action 不返回 bindingStatus。get 顶层 bindingStatus 仅为 matched、mismatch、detached,并以 binding 返回已存绑定;list 有效行 workspace 为已存绑定,同时返回 bindingStatus,顶层 workspace 仍为当前观察。历史 change 合入 main 后仍可 get/list,但不会自动把来源分支改为 main。
37
-
38
- create 自动绑定当前命名分支或普通目录。常规 update 在读 state 后、读取/发布业务变更前检查绑定。branch、项目相对路径或工作区种类不匹配时拒绝;缺失绑定的状态非法;detached 拒绝所有写入。绑定操作依然遵守 expectedRevision 和宿主 replaceIfVersion。
39
-
40
- 绑定是状态工具自身的写入保护,不是 Git/工作目录锁,也不能限制其他文件工具。运行期间禁止外部切分支、搬移目录或清理 worktree;同一 checkout 不安排不同需求并发切换分支。同一 change 的多 Lead 业务所有权仍由明确交接保证,CAS 不充当任务锁。
41
-
42
- ## 5. 工作流
43
-
44
- 先由外部选择隔离 worktree,再查询 workspace、创建 change;只有做普通解释/调查时可以不建 change。材料始终以当前 worktree 为唯一权威,不能复制后两处继续写。本插件不自动搬移或提交。
45
-
46
- 计划和委派包使用当前 worktree 的 projectRoot、changeId、预期分支和工作目录。知识只读写该分支的本地快照;跨需求依赖通过明确的 Git 集成引入。恢复先核对 workspace 和 change 绑定,再复用当前材料与授权;分支漂移不按相同 HEAD 猜测归属。分支重命名需要有理由的显式绑定,合入后的历史记录默认只读,不批量重绑。
47
-
48
- PR/MR 地址、源/目标分支、待评审/待合入结果及相关证据写入既有 plan/交付材料;状态机不接管远端 PR 生命周期。close 仍按本需求的验收契约:若合入是必需交付条件,合入及集成验证必须先满足;若交付边界是提交 PR,则 close 不声称已合入。PR 反馈修订沿用既有阶段退回、材料版本和证据失效机制。
49
-
50
- 需要保留的代码、知识与 change 材料随分支提交,通过 PR/MR 集成;同一知识文件和 state 的冲突必须核对语义,不能把文本合并成功当验收通过。worktree 清理前保留未提交材料及证据,清理属于外部明确操作。数据库、端口、测试账号和外部资源按需求隔离,Git worktree 只隔离文件。
51
-
52
- ## 6. 验证
53
-
54
- - 真实 Git 仓库建立两个 linked worktree,相同 change ID 各自保存、更新、知识修改互不影响;不读取主 checkout 实时知识。
55
- - 从 feature worktree 显式指向 main 材料根被拒绝;子目录项目在同一 checkout 可以使用。
56
- - 切分支后读显示 mismatch,普通写拒绝;显式绑定保留历史;分支正常提交或 rebase 不误锁。
57
- - detached 可读不可写,unborn 可写,bare/损坏仓库/缺少 Git/取消/权限错误不降级为普通目录。
58
- - 仅接受 schemaVersion: 2 且 workspace 必填;未知或旧 schema、缺失绑定拒绝,未受管目录在 list 中显示缺失或非法 state 错误;重绑历史 previous 必填,CAS 失败不发布。
59
- - 合并包含 change 材料后,目标分支可读历史且不会自动改其归属;移动工作区仍可按分支恢复。
60
- - 使用实际 DSH 文件、subprocess、sandbox 与注册服务测试;不安装到 profile。模型在真实 Issues/PR/Teams 中的长期行为另列为待观察,不用程序测试冒充。