@mstar-harness/dsh 3.8.3 → 3.9.0
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.i18n.yaml +2 -2
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/dist/client/panel/locale.d.ts +1 -1
- package/dist/client.js +5 -5
- package/dist/index.js +1293 -955
- package/dist/types.d.ts +2 -2
- package/harness-commands/iteration-drive.md +12 -6
- package/harness-commands/iteration-loop.md +10 -10
- package/harness-commands/iteration-start.md +10 -10
- package/harness-skills/mstar-artifacts/SKILL.md +3 -3
- package/harness-skills/mstar-artifacts/references/status-and-residuals.md +12 -8
- package/harness-skills/mstar-artifacts/templates/plan.main.md +2 -0
- package/harness-skills/mstar-branch-worktree/SKILL.md +69 -28
- package/harness-skills/mstar-branch-worktree/references/parallel-writable-pre-dispatch.md +9 -8
- package/harness-skills/mstar-conventions/SKILL.md +2 -2
- package/harness-skills/mstar-dispatch-gates/SKILL.md +1 -1
- package/harness-skills/mstar-engine-legacy/references/lease-protocol.md +12 -9
- package/harness-skills/mstar-engine-legacy/references/status-field-history.md +3 -3
- package/harness-skills/mstar-host/references/codex.md +6 -4
- package/harness-skills/mstar-host/references/dsh.md +1 -1
- package/harness-skills/mstar-iteration/SKILL.md +18 -12
- package/harness-skills/mstar-iteration/references/command-shared-invariants.md +2 -1
- package/harness-skills/mstar-iteration/references/phase-1-prepare.md +2 -0
- package/harness-skills/mstar-iteration/references/phase-2-worktree-lease.md +70 -46
- package/harness-skills/mstar-iteration/references/phase-3-iteration-close.md +4 -4
- package/harness-skills/mstar-iteration/references/phase-4-5-pr-delivery.md +6 -5
- package/harness-skills/mstar-iteration/references/phase-6-post-merge-close.md +71 -0
- package/harness-skills/mstar-review-qc/SKILL.md +1 -0
- package/harness-skills/mstar-roles/references/project-manager/dispatch-and-assignment.md +10 -8
- package/harness-skills/mstar-roles/references/project-manager.md +3 -2
- package/harness-skills/mstar-roles/references/prompt-engineer.md +1 -1
- package/harness-skills/mstar-roles/references/qa-engineer/acceptance-gate.md +15 -0
- package/harness-skills/mstar-roles/references/qa-engineer.md +3 -1
- package/harness-skills/mstar-sdd/SKILL.md +3 -1
- package/harness-skills/mstar-sdd/references/file-handoffs.md +21 -3
- package/harness-skills/mstar-sdd/references/implementer-continuation-prompt.md +1 -1
- package/harness-skills/mstar-sdd/references/implementer-prompt.md +1 -1
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -278,8 +278,8 @@ export interface MstarHarnessState {
|
|
|
278
278
|
readonly pushPolicy: string | null;
|
|
279
279
|
/** `metadata.worktree_mode`, null when absent. */
|
|
280
280
|
readonly worktreeMode: string | null;
|
|
281
|
-
/** `
|
|
282
|
-
readonly
|
|
281
|
+
/** `integration_worktree_path`, null when absent. */
|
|
282
|
+
readonly integrationWorktreePath: string | null;
|
|
283
283
|
/** Active plan execution leases (holder + worktree). */
|
|
284
284
|
readonly leases: readonly HarnessLeaseView[];
|
|
285
285
|
/** Knowledge index digest (docs count + categories), null when no index. */
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: iteration-drive
|
|
3
|
-
description: Drive the active iteration to completion — Phase 2 Autonomous Execute, Phase 3 iteration-close, Phase 4 Create PR, Phase 5 PR merge-ready loop (prefer babysit/*-babysit; optional greploop when repo has it; else CI fallback) until mergeable. Not Done until Phase
|
|
3
|
+
description: Drive the active iteration to completion — Phase 2 Autonomous Execute, Phase 3 iteration-close, Phase 4 Create PR, Phase 5 PR merge-ready loop (prefer babysit/*-babysit; optional greploop when repo has it; else CI fallback) until mergeable, then Phase 6 post-merge close once the PR is verified merged. Not Done until Phase 6 close completes.
|
|
4
4
|
agent: project-manager
|
|
5
5
|
input: "[no args]"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Drive Iteration
|
|
9
9
|
|
|
10
|
-
Drive the active Morning Star iteration forward. **Boot loads skills; this command sequences Phase 2 → 3 → 4 → 5.** Phase route + gate SSOT → **`mstar-iteration`** Phase route map + **Phase transition gates** table(§2 detail → `references/phase-2-worktree-lease.md`;§3 → `references/phase-3-iteration-close.md`;§4–§5 → `references/phase-4-5-pr-delivery.md`);本 command 仅补充 **可选第三方 helper skill 发现**(Phase 5),不反向写入 `mstar-*`。
|
|
10
|
+
Drive the active Morning Star iteration forward. **Boot loads skills; this command sequences Phase 2 → 3 → 4 → 5 → 6.** Phase route + gate SSOT → **`mstar-iteration`** Phase route map + **Phase transition gates** table(§2 detail → `references/phase-2-worktree-lease.md`;§3 → `references/phase-3-iteration-close.md`;§4–§5 → `references/phase-4-5-pr-delivery.md`;§6 → `references/phase-6-post-merge-close.md`);本 command 仅补充 **可选第三方 helper skill 发现**(Phase 5),不反向写入 `mstar-*`。
|
|
11
11
|
|
|
12
12
|
## Phase flow(禁止跳步)
|
|
13
13
|
|
|
14
|
-
`Phase 2: Autonomous Execute → Phase 3: iteration-close → Phase 4: Create PR → Phase 5: PR merge-ready`。Transition gates(HARD)→ **`mstar-iteration`** **Phase transition gates** table。
|
|
14
|
+
`Phase 2: Autonomous Execute → Phase 3: iteration-close → Phase 4: Create PR → Phase 5: PR merge-ready → Phase 6: post-merge close`。Transition gates(HARD)→ **`mstar-iteration`** **Phase transition gates** table。
|
|
15
15
|
|
|
16
|
-
**Done
|
|
16
|
+
**Done 定义**:Phase 5 §5.5 exit checklist 全 `[x]` **且** PR merged 后 Phase 6 §6.1–§6.4 完成。**Phase 3 close ≠ Done;Phase 4 开 PR ≠ Done;§5.5 exit / PR merged ≠ Done。**
|
|
17
17
|
|
|
18
18
|
## 共享 invariants / preflight / todos / STOP
|
|
19
19
|
|
|
@@ -39,10 +39,16 @@ Execute **`mstar-iteration/references/phase-4-5-pr-delivery.md`** §4:打印 `
|
|
|
39
39
|
|
|
40
40
|
## Phase 5: PR merge-ready(babysit loop)
|
|
41
41
|
|
|
42
|
-
Execute **`mstar-iteration/references/phase-4-5-pr-delivery.md`** §5.0–§5.2(**§5.1a push cadence HARD**)。**§5.5 exit checklist
|
|
42
|
+
Execute **`mstar-iteration/references/phase-4-5-pr-delivery.md`** §5.0–§5.2(**§5.1a push cadence HARD**)。**§5.5 exit checklist 前 5 项全 `[x]` = merge-ready → 进入 Phase 6.**
|
|
43
43
|
|
|
44
44
|
本 command **叠加**可选 helper skill 发现(**non-`mstar-*`**;不写入 `mstar-*` load order)→ **`mstar-iteration/references/phase5-helper-discovery.md`**(babysit / `*-babysit` / greploop / fallback 路径清单;first readable `SKILL.md` wins)。Loop + review fix hygiene + exit checklist → §5.1–§5.2(同上 reference)。
|
|
45
45
|
|
|
46
46
|
**Then** report: iteration id, plans completed, compound summary, PR link, merge-ready evidence(CI snapshot + review resolution + Greptile if applicable)。
|
|
47
47
|
|
|
48
|
-
PR merge itself may still be manual or a separate host action unless user authorized auto-merge.
|
|
48
|
+
PR merge itself may still be manual or a separate host action unless user authorized auto-merge. Merge 完成(手动或授权 auto-merge)→ **立即**进入 Phase 6(下节)。
|
|
49
|
+
|
|
50
|
+
## Phase 6: post-merge close(PR merged 后)
|
|
51
|
+
|
|
52
|
+
PR **已 merge**(verified merged;mergeable ≠ merged)→ 追加 todo `phase-6-post-merge-close` → 打印 **`## Phase 6: post-merge close`** → execute **`mstar-iteration/references/phase-6-post-merge-close.md`** §6.1→§6.4(`mstar status workflow-close --workflow <id>` terminal write → unregister → projections reconcile → cleanup handoff)。**§6.1–§6.4 完成 = 本 command Done**(勾掉 `phase-6-post-merge-close`)。可在后续会话补跑;对已关闭 lifecycle 幂等。
|
|
53
|
+
|
|
54
|
+
**Then** report adds: post-merge close evidence(snapshot `completed` + `ended_at`、根 `status.json` 注销、投影一致)。
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: iteration-loop
|
|
3
|
-
description: "Autonomous full iteration loop for cloud agents — Phase 1 (code-first auto direction lock + compass/plans + Review & Edit chain) through Phase 2–
|
|
3
|
+
description: "Autonomous full iteration loop for cloud agents — Phase 1 (code-first auto direction lock + compass/plans + Review & Edit chain) through Phase 2–6 (execute → close → PR → merge-ready → post-merge close). Optional args: direction, scale (S|M|L|XL, default M). Not Done until the Phase 6 post-merge close completes. Minimal human intervention; no grill-me."
|
|
4
4
|
agent: project-manager
|
|
5
5
|
input: "[direction] [scale]"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Iteration Loop
|
|
9
9
|
|
|
10
|
-
Run a **full** Morning Star iteration with minimal human intervention. **Done = Phase
|
|
10
|
+
Run a **full** Morning Star iteration with minimal human intervention. **Done = Phase 6 post-merge close §6.1–§6.4 完成** — not Phase 1 lock, not Phase 3 close, not Phase 4 PR open, not Phase 5 merge-ready exit.
|
|
11
11
|
|
|
12
12
|
**vs other commands:**
|
|
13
13
|
|
|
14
14
|
| Command | Scope |
|
|
15
|
-
| `iteration-start` | Phase 1 (**grill-me** with user) → **auto-continue** Phase 2→
|
|
16
|
-
| `iteration-drive` | Phase 2→
|
|
17
|
-
| **`iteration-loop`** | Phase 1→
|
|
15
|
+
| `iteration-start` | Phase 1 (**grill-me** with user) → **auto-continue** Phase 2→6(`pause` 止于 Phase 1) |
|
|
16
|
+
| `iteration-drive` | Phase 2→6 re-entry / resume on an already locked iteration |
|
|
17
|
+
| **`iteration-loop`** | Phase 1→6 end-to-end; **autonomous** direction lock |
|
|
18
18
|
|
|
19
19
|
Phase route + gate SSOT → **`mstar-iteration`** **Phase route map** + **Phase transition gates** table. This command is a **consumer**; it does not redefine skill semantics.
|
|
20
20
|
|
|
@@ -42,7 +42,7 @@ Parse: if the last token is exactly `S`/`M`/`L`/`XL` (case-insensitive), treat i
|
|
|
42
42
|
|
|
43
43
|
## Phase flow(禁止跳步)
|
|
44
44
|
|
|
45
|
-
`Phase 1: Autonomous start → Phase 2: Autonomous Execute → Phase 3: close → Phase 4: PR → Phase 5: merge-ready`。Transition gates(HARD)→ **`mstar-iteration`** **Phase transition gates** table。
|
|
45
|
+
`Phase 1: Autonomous start → Phase 2: Autonomous Execute → Phase 3: close → Phase 4: PR → Phase 5: merge-ready → Phase 6: post-merge close`。Transition gates(HARD)→ **`mstar-iteration`** **Phase transition gates** table。
|
|
46
46
|
|
|
47
47
|
## Continuous execution(HARD — Phase 1 lock 后至 Phase 5 exit)
|
|
48
48
|
|
|
@@ -88,12 +88,12 @@ Per **`mstar-iteration/references/phase-2-worktree-lease.md` §2.3**(create fr
|
|
|
88
88
|
|
|
89
89
|
---
|
|
90
90
|
|
|
91
|
-
## Phase 2–
|
|
91
|
+
## Phase 2–6: Execute → close → PR → merge-ready → post-merge close
|
|
92
92
|
|
|
93
|
-
Delegate to **`iteration-drive`**(Phase 2 → §2、Phase 3 → §3 + `references/phase-3-iteration-close.md`、Phase 4/5 → §4–§5 + `references/phase-4-5-pr-delivery.md`、Phase 5 helper discovery → `phase5-helper-discovery.md
|
|
93
|
+
Delegate to **`iteration-drive`**(Phase 2 → §2、Phase 3 → §3 + `references/phase-3-iteration-close.md`、Phase 4/5 → §4–§5 + `references/phase-4-5-pr-delivery.md`、Phase 5 helper discovery → `phase5-helper-discovery.md`、Phase 6 → `references/phase-6-post-merge-close.md` §6.1–§6.4)。**Assignment preflight** per **`command-shared-invariants.md`**。
|
|
94
94
|
|
|
95
|
-
**Loop 特有**:Phase 5 push cadence(HARD)→ **`mstar-iteration/references/phase-4-5-pr-delivery.md`** §5.1a;exit checklist → §5.2(同 reference
|
|
95
|
+
**Loop 特有**:Phase 5 push cadence(HARD)→ **`mstar-iteration/references/phase-4-5-pr-delivery.md`** §5.1a;exit checklist → §5.2(同 reference);Phase 6 → **`mstar-iteration/references/phase-6-post-merge-close.md`** §6.1–§6.4(PR **merged** 后;todo `phase-6-post-merge-close`)。
|
|
96
96
|
|
|
97
|
-
**Then** report: iteration id, locked direction + scale, plans completed, compound summary, PR link, merge-ready evidence
|
|
97
|
+
**Then** report: iteration id, locked direction + scale, plans completed, compound summary, PR link, merge-ready evidence, post-merge close evidence(snapshot `completed` + root unregister)。
|
|
98
98
|
|
|
99
99
|
PR merge itself may remain manual unless user authorized auto-merge.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: iteration-start
|
|
3
|
-
description: "Start a new harness iteration — optional direction hint, research, grill-me, compass/plans, Review & Edit chain (long-lived {SPECS_DIR}/ + {ITERATION_DIR}/<id>/ package; compound promotes package at close only), PM lock, integration branch; then auto-continue Phase 2→
|
|
3
|
+
description: "Start a new harness iteration — optional direction hint, research, grill-me, compass/plans, Review & Edit chain (long-lived {SPECS_DIR}/ + {ITERATION_DIR}/<id>/ package; compound promotes package at close only), PM lock, integration branch; then auto-continue Phase 2→6 (execute → close → PR → merge-ready → post-merge close) unless `pause` arg given."
|
|
4
4
|
agent: project-manager
|
|
5
5
|
input: "[direction] [pause]"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Start Iteration
|
|
9
9
|
|
|
10
|
-
Start a new Morning Star harness iteration. **Phase 1 is not complete until the Review & Edit chain runs via dispatched roles and PM lock — not when compass files are first written.** By default, after Phase 1 lock + integration
|
|
10
|
+
Start a new Morning Star harness iteration. **Phase 1 is not complete until the Review & Edit chain runs via dispatched roles and PM lock — not when compass files are first written.** By default, after Phase 1 lock + integration worktree, **auto-continue into Phase 2→6** (execute → close → PR → merge-ready → post-merge close); pass **`pause`** to stop after Phase 1 and resume later with `/iteration-drive`.
|
|
11
11
|
|
|
12
12
|
## Args
|
|
13
13
|
|
|
@@ -18,7 +18,7 @@ Start a new Morning Star harness iteration. **Phase 1 is not complete until the
|
|
|
18
18
|
| Arg | Meaning | Default |
|
|
19
19
|
|-----|---------|---------|
|
|
20
20
|
| `direction` | Iteration direction hint — constrains §2 candidates and seeds §3 grill-me; **not** a lock (start stays interactive) | Research → grill-me converges with user |
|
|
21
|
-
| `pause` | Stop after Phase 1 (lock + integration
|
|
21
|
+
| `pause` | Stop after Phase 1 (lock + integration worktree); run `/iteration-drive` later to resume | **Auto-continue** into Phase 2→6 |
|
|
22
22
|
|
|
23
23
|
**Parse**: if any token is exactly `pause` (case-insensitive), treat as the `pause` flag; the remaining tokens (joined) are the `direction` hint. `/iteration-start pause` = pause with empty direction.
|
|
24
24
|
|
|
@@ -34,7 +34,7 @@ Start a new Morning Star harness iteration. **Phase 1 is not complete until the
|
|
|
34
34
|
|
|
35
35
|
派发细则 → **`mstar-dispatch-gates`**(specialist review-and-edit dispatch)+ **`mstar-host`**(宿主 invoke 能力)。**不得**在 PM 线程加载其他 role reference 代劳。
|
|
36
36
|
|
|
37
|
-
**Phase 1 完成定义**:compass `status: locked` + 三角色 invoke 已返回 + pre-commit checklist 全 `[x]` — 不是初稿落盘。**Command Done**(§7 auto-continue)= Phase 5 §5.5 exit checklist 全 `[x]
|
|
37
|
+
**Phase 1 完成定义**:compass `status: locked` + 三角色 invoke 已返回 + pre-commit checklist 全 `[x]` — 不是初稿落盘。**Command Done**(§7 auto-continue)= Phase 6 post-merge close 完成(同 `iteration-drive`:Phase 5 §5.5 exit checklist 全 `[x]` **且** PR merged 后 §6.1–§6.4 完成);`pause` 时 = Phase 1 完成。
|
|
38
38
|
|
|
39
39
|
**Phase 2–5 共享 invariants / preflight / todos / STOP** → **`mstar-iteration/references/command-shared-invariants.md`**(不在本命令重复)。
|
|
40
40
|
|
|
@@ -45,7 +45,7 @@ Start a new Morning Star harness iteration. **Phase 1 is not complete until the
|
|
|
45
45
|
| **Cursor Plan mode**(CreatePlan / Plan 会话活跃) | §0 Boot → **§P** — **先**空白 CreatePlan,再 **feedback-driven** 自主改同一份 plan;grill-me **仅**在用户明确结束反馈后、仍有阻塞疑问时;**Build 前不执行** Review 链 / commit / integration 分支 |
|
|
46
46
|
| **其它**(Agent、OpenCode、非 Plan) | §0 Boot → §1–§6(Research → Explore → grill-me → Write → Review → branch) |
|
|
47
47
|
|
|
48
|
-
**Both paths converge at §6**(integration
|
|
48
|
+
**Both paths converge at §6**(integration worktree)。Default → §7 auto-continue Phase 2→6;`pause` → command ends at §6.
|
|
49
49
|
|
|
50
50
|
## 0. Boot
|
|
51
51
|
|
|
@@ -105,18 +105,18 @@ PM must print this block before §6; all `[ ]` must be `[x]`:
|
|
|
105
105
|
- [ ] product-manager / architect / writing-specialist invokes completed — 编辑 compass / plans / specs / **`<iteration-id>/` package**;**未**向 `{KNOWLEDGE_DIR}/` 新增
|
|
106
106
|
- [ ] PM final lock: compass `status: locked`; Prepare gates pass (blocked plans documented)
|
|
107
107
|
- [ ] Branch policy locked: `iteration_base_branch` / `spec_integration_branch` / `target_branch` recorded in compass / `status.json`
|
|
108
|
-
- [ ] **THEN**: commit + push `iteration/<iteration-id>`
|
|
108
|
+
- [ ] **THEN**: transfer reviewed changes + commit + push `iteration/<iteration-id>` **in the integration worktree** (never the primary checkout)
|
|
109
109
|
|
|
110
110
|
## 6. Integration Branch
|
|
111
111
|
|
|
112
|
-
Per **`mstar-iteration/references/phase-2-worktree-lease.md` §2.3**:create
|
|
112
|
+
Per **`mstar-iteration/references/phase-2-worktree-lease.md` §2.3**:create the **integration worktree** — a dedicated linked checkout **distinct from the primary checkout**(`git worktree add <path> -b <spec_integration_branch> <iteration_base_branch>`;primary 分支**不**切换);register `iteration_base_branch` / `spec_integration_branch` / `target_branch` in compass frontmatter **and** `status.json` metadata;record the observed primary branch as **`Main worktree branch`** in the main plan header;**transfer only the reviewed §5 changes** into the integration worktree, commit there, then restore the primary checkout's corresponding uncommitted docs without switching its branch(Phase-1 bounded exception → `phase-1-prepare.md` §1.6;**不得**搬运无关用户改动);push。**STOP** if `iteration_base_branch` / `target_branch` missing — never default `main`/`master`.
|
|
113
113
|
|
|
114
114
|
---
|
|
115
115
|
|
|
116
|
-
## 7. Phase 2–
|
|
116
|
+
## 7. Phase 2–6(auto-continue)
|
|
117
117
|
|
|
118
|
-
**`pause` arg → command ends here**(Phase 1 locked + integration pushed;run `/iteration-drive` later)。**Default(no `pause`)→ auto-continue**:execute **`iteration-drive`**(Phase 2 → **`mstar-iteration/references/phase-2-worktree-lease.md`**;Phase 3 → `references/phase-3-iteration-close.md`;Phase 4/5 → `references/phase-4-5-pr-delivery.md`;Phase 5 helper discovery → `phase5-helper-discovery.md
|
|
118
|
+
**`pause` arg → command ends here**(Phase 1 locked + integration pushed;run `/iteration-drive` later)。**Default(no `pause`)→ auto-continue**:execute **`iteration-drive`**(Phase 2 → **`mstar-iteration/references/phase-2-worktree-lease.md`**;Phase 3 → `references/phase-3-iteration-close.md`;Phase 4/5 → `references/phase-4-5-pr-delivery.md`;Phase 5 helper discovery → `phase5-helper-discovery.md`;Phase 6 post-merge close(PR merged 后)→ `references/phase-6-post-merge-close.md` §6.1–§6.4)。Shared invariants / preflight / STOP → **`mstar-iteration/references/command-shared-invariants.md`**。
|
|
119
119
|
|
|
120
|
-
**Done = Phase 5 §5.5 exit checklist 全 `[x]
|
|
120
|
+
**Done = Phase 6 post-merge close 完成**(同 `iteration-drive`:Phase 5 §5.5 exit checklist 全 `[x]` 且 PR merged 后 §6.1–§6.4 完成 — Phase 5 exit / PR merged 不是 Done)。**Then** report: iteration id, direction lock summary, plans completed, compound summary, PR link, merge-ready evidence(CI snapshot + review resolution + Greptile if applicable), post-merge close evidence(snapshot `completed` + `ended_at`、根 `status.json` 注销、投影一致)。
|
|
121
121
|
|
|
122
122
|
PR merge itself may remain manual unless user authorized auto-merge.
|
|
@@ -22,8 +22,8 @@ description: "Morning Star plan harness artifacts — `{PLAN_DIR}` main plans an
|
|
|
22
22
|
|
|
23
23
|
## `status.json`, workflow snapshots, and open residual (summary)
|
|
24
24
|
|
|
25
|
-
- **`{HARNESS_DIR}/status.json` (v2)**: active-lifecycle register — `{ version: 2, updated_at, workflows[] }`. Each entry points at its snapshot dir (`dir: workflows/<id>`); terminal lifecycles are unregistered after the snapshot write.
|
|
26
|
-
- **`{WORKFLOW_DIR}/<id>/snapshot.json`**: per-lifecycle running state — `plans[]` rows (legacy PlanRow shape verbatim) + per-row `execution_lease` + top-level `integration_merge_lease` / `execution_policy` / `branch` anchors / `
|
|
25
|
+
- **`{HARNESS_DIR}/status.json` (v2)**: active-lifecycle register — `{ version: 2, updated_at, workflows[] }`. Each entry points at its snapshot dir (`dir: workflows/<id>`); terminal lifecycles are unregistered after the snapshot write. The PM-facing close caller is the post-merge `mstar status workflow-close --workflow <id>` (ordering: terminal snapshot write first, root unregister second → `mstar-iteration/references/phase-6-post-merge-close.md` §6.1–§6.2).
|
|
26
|
+
- **`{WORKFLOW_DIR}/<id>/snapshot.json`**: per-lifecycle running state — `plans[]` rows (legacy PlanRow shape verbatim) + per-row `execution_lease` + top-level `integration_merge_lease` / `execution_policy` / `branch` anchors / `integration_worktree_path` (the dedicated integration checkout; the main worktree / control root is derived from Git, never recorded in the snapshot).
|
|
27
27
|
- **`{PROJECT_DIR}/<id>/residuals.json`**: open residual register, `entries[<plan-id>]` arrays — the **open-list SSOT** (severity enum + lifecycle semantics verbatim; project-less flows use `_default`).
|
|
28
28
|
- **Canonical**: register new findings only in the project register (`projects/<id>/residuals.json`); v1 root `residual_findings` is legacy read-only — migrate via `mstar migrate`, do not dual-write.
|
|
29
29
|
|
|
@@ -37,7 +37,7 @@ description: "Morning Star plan harness artifacts — `{PLAN_DIR}` main plans an
|
|
|
37
37
|
> **Engine check (when available):** run `mstar status findings-cleanup <plan-id> [--project <id>] [--mode zero-residual|allow-residual]` (or import `findingsCleanupGate` from `@mstar-harness/engine` in a host hook) to enforce the Findings cleanup mode above against the plan's register entries. On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
38
38
|
|
|
39
39
|
- **`{WORKFLOW_DIR}/<id>/notes.jsonl`**: per-workflow append-only notes ledger (runtime); snapshot plan-row `notes` is the legacy verbatim copy. **Tech-debt rollup**: `mstar status tech-debt <project-dir>` over the project registers — **`references/status-and-residuals.md`**.
|
|
40
|
-
- **Iteration Phase 2 leases** (snapshot: `
|
|
40
|
+
- **Iteration Phase 2 leases** (snapshot: `integration_worktree_path`, `plans[].execution_lease`, top-level `integration_merge_lease`): field semantics → **`references/status-and-residuals.md`** (“Iteration execution leases”); Phase 2 execution checklist → **`mstar-iteration`** `references/phase-2-worktree-lease.md`; full protocol prose (single copy) → **`mstar-engine-legacy`** `references/lease-protocol.md`.
|
|
41
41
|
|
|
42
42
|
> **Engine check (when available):** run `mstar lease verify --workflow <id> [--plan <plan-id>]` or `mstar lease verify-integration --workflow <id>` (or import `validateExecutionLease` / `validateIntegrationMergeLease` from `@mstar-harness/engine` in a host hook) to validate the iteration leases above on the workflow snapshot (execution_lease / integration_merge_lease). On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
43
43
|
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
v3 布局把 v1 的「单文件 `status.json`(根 `plans[]` + 根级 `residual_findings` + `metadata`)」拆成三层。**只使用 v2 地址;v1 地址(根 `plans[]` / 根级 `residual_findings` / `archived/residuals/`)由 `mstar migrate` 一次性迁移,不再读写**。v1 字段形状/历史全文(v1 行表、v1 `metadata` 表、jq/flock 读路径示例)→ **`mstar-engine-legacy`** `references/status-field-history.md`(engine-absent 历史 + fallback);本文件只保留 v2 地址与一次性 legacy 只读警告。
|
|
6
6
|
|
|
7
|
-
- **根 `{HARNESS_DIR}/status.json`(v2)** — 活跃生命周期登记:`{ "version": 2, "updated_at", "workflows": [...] }`。只登记 **active**(`running` / `paused`)lifecycle;terminal 时先写 snapshot 再从根列表移除(removal-at-terminal)。由 engine `validateStatus`(v2)/ `registerWorkflow` / `unregisterWorkflow` 读写。
|
|
8
|
-
- **`{WORKFLOW_DIR}/<id>/snapshot.json`** — 每 lifecycle 的运行态快照(`schema_version: 1`):**`plans[]` 行(legacy PlanRow 形状逐字保留)**、per-row **`execution_lease`**、顶层 **`integration_merge_lease`** / **`execution_policy`** / **`branch` anchors** / **`
|
|
7
|
+
- **根 `{HARNESS_DIR}/status.json`(v2)** — 活跃生命周期登记:`{ "version": 2, "updated_at", "workflows": [...] }`。只登记 **active**(`running` / `paused`)lifecycle;terminal 时先写 snapshot 再从根列表移除(removal-at-terminal)。由 engine `validateStatus`(v2)/ `registerWorkflow` / `unregisterWorkflow` 读写。PM-facing unregister caller:post-merge close `mstar status workflow-close --workflow <id>`(ordering 固定:terminal snapshot → unregister;细序 → `mstar-iteration/references/phase-6-post-merge-close.md` §6.1–§6.2)。
|
|
8
|
+
- **`{WORKFLOW_DIR}/<id>/snapshot.json`** — 每 lifecycle 的运行态快照(`schema_version: 1`):**`plans[]` 行(legacy PlanRow 形状逐字保留)**、per-row **`execution_lease`**、顶层 **`integration_merge_lease`** / **`execution_policy`** / **`branch` anchors** / **`integration_worktree_path`** / `compass_ref`。`<id>` = plan id 或 iteration id。
|
|
9
9
|
- **`{PROJECT_DIR}/<id>/roadmap.md` + `residuals.json`** — 项目层:roadmap frontmatter(machine-checkable)+ residual **register**(`entries[<plan-id>]` 数组;severity 枚举与 lifecycle 语义**逐字保留**)。无项目的流程回落到 `_default` 项目。
|
|
10
10
|
|
|
11
11
|
`status.json`(根)、workflow snapshot 与 project register 都是 **SSOT**:plan 行状态与 lease 在 snapshot,open residual 在 register。
|
|
@@ -85,7 +85,7 @@ Canonical vs legacy residual definitions → **`mstar-artifacts` SKILL.md**("`
|
|
|
85
85
|
"target_branch": "iteration/iter-demo"
|
|
86
86
|
},
|
|
87
87
|
"branch": { "base": "main", "integration": "iteration/iter-demo", "target": "main" },
|
|
88
|
-
"
|
|
88
|
+
"integration_worktree_path": "/abs/repo/.worktrees/iter-demo-integration",
|
|
89
89
|
"legacy_metadata": {},
|
|
90
90
|
"compass_ref": "iterations/iter-demo/delivery-compass.md"
|
|
91
91
|
}
|
|
@@ -95,6 +95,8 @@ Canonical vs legacy residual definitions → **`mstar-artifacts` SKILL.md**("`
|
|
|
95
95
|
|
|
96
96
|
- `plans[]` rows are the **legacy PlanRow shape verbatim** (unknown row fields preserved, never re-bucketed). Per-row `execution_lease` stays on the row; `integration_merge_lease` is **top-level** (the v1 root-`metadata` home is gone).
|
|
97
97
|
- Terminal statuses (`completed` / `failed` / `stopped`) require `ended_at` and no dangling leases.
|
|
98
|
+
- **Completed close (Phase 6)** runs `mstar status workflow-close --workflow <id> [--harness <path>] [--ended-at <date>]`: engine `closeWorkflow` rereads the latest snapshot under the snapshot write lock, refuses any dangling lease / non-`Done` row (fail-loud, bytes unchanged), writes `completed` + `ended_at`, then unregisters the root entry. Unregister failure after the snapshot write is a reported **partial close** — retry finishes unregister without rewriting `ended_at`; a fully closed retry rewrites neither file. An already-terminal `failed` / `stopped` snapshot keeps its actual status (close never fabricates `completed`).
|
|
99
|
+
- **Physical cleanup is out of close's scope**: it is the separate `mstar worktree cleanup --workflow <id> …` verb (dry-run default), run in its own timing lane — same-round after a plan's integration merge (Phase 2) or after §6.1–§6.3 + PR merged (Phase 6). Close and cleanup never release leases — owners release manually before either. Guard/decision codes (`cleanup.keep.*`, `cleanup.refuse.*`, `cleanup.remove.merged`) → **`mstar-branch-worktree`**「Worktree / branch cleanup」.
|
|
98
100
|
- `execution_policy` keys are copied from v1 root `metadata` at migrate; values are accepted-but-opaque this iteration (no semantic gate).
|
|
99
101
|
- `notes`: a plan row's `notes` array is the **legacy verbatim copy** preserved at migrate; the **runtime ledger is `notes.jsonl`** in the workflow dir (see `workflows/<id>/notes.jsonl` below). New notes append to the ledger only — never dual-write the row `notes`.
|
|
100
102
|
|
|
@@ -286,12 +288,14 @@ Optional when a plan is not owned; **required** while a Phase 2 session owns wri
|
|
|
286
288
|
| --- | --- | --- | --- |
|
|
287
289
|
| `holder` | non-empty string | Yes | Opaque cooperative owner identity (recommended `<host>:<stable-session-id>`, e.g. `cursor:bc-1234`). Stable for claim lifetime; **no credentials**; used for ownership comparison — not `session_label`. |
|
|
288
290
|
| `claimed_at` | RFC 3339 UTC (`Z`) | Yes | Acquisition time (audit only; **not** an expiry clock). |
|
|
289
|
-
| `worktree_path` | absolute path string | Yes | Dedicated feature-worktree root; **MUST** differ from `
|
|
291
|
+
| `worktree_path` | absolute path string | Yes | Dedicated feature-worktree root; **MUST** differ from the main worktree (control root) and snapshot `integration_worktree_path`. |
|
|
290
292
|
| `working_branch` | non-empty string | Yes | Feature branch at `worktree_path`; MUST agree with Assignment **`Working branch`**. |
|
|
291
293
|
| `session_label` | string | No | Human display only — **MUST NOT** authorize or compare ownership. |
|
|
292
294
|
|
|
293
295
|
Writers **delete** `execution_lease` on release; `null` and tombstone objects are invalid.
|
|
294
296
|
|
|
297
|
+
**Ownership survives release**: later `mstar worktree cleanup` attributes a released plan row through the retained row `metadata.working_branch` / `metadata.worktree_path` and retained track Assignments — never by branch-name inference. Guard codes and the cleanup contract → **`mstar-branch-worktree`**「Worktree / branch cleanup」.
|
|
298
|
+
|
|
295
299
|
V1: **manual release only** — omit `expires_at`; readers **MUST NOT** treat unknown or draft `expires_at` as authority to steal or release.
|
|
296
300
|
|
|
297
301
|
### Snapshot top-level fields
|
|
@@ -301,7 +305,7 @@ V1: **manual release only** — omit `expires_at`; readers **MUST NOT** treat un
|
|
|
301
305
|
| `integration_merge_lease` | object | While one integration merge is owned; **absent** = unclaimed. Writers **delete** the key on release — never `null` or tombstones |
|
|
302
306
|
| `execution_policy` | object | `plan_parallelism` / `worktree_mode` / `push_policy` — first-class (copied from v1 root `metadata` at migrate; values accepted-but-opaque this iteration) |
|
|
303
307
|
| `branch` | object | Iteration branch anchors: `base` (from `iteration_base_branch`), `integration` (the `spec_integration_branch`), `target` (final PR target) |
|
|
304
|
-
| `
|
|
308
|
+
| `integration_worktree_path` | absolute path string | Iteration Phase 2: canonical **repository root** (not `{HARNESS_DIR}`) of the dedicated integration checkout, on the `branch.integration` branch, **distinct from the main worktree**; sole merge cwd. Canonical writers emit only this key; a raw v1 legacy worktree-path key is a **read-alias** (reader normalizes in memory + medium diagnostic `workflow.snapshot.legacy-control-worktree-path`) — migrate on the next authorized write; both keys present is a high violation, and writes never accept the old key. The main worktree (control root) is **not** a snapshot field — it is derived from Git (`readMainWorktree`). |
|
|
305
309
|
| `compass_ref` | string | Relative pointer to the iteration delivery compass |
|
|
306
310
|
| `legacy_metadata` | object | Catch-all for unmapped v1 root-`metadata` keys at migrate |
|
|
307
311
|
|
|
@@ -314,11 +318,11 @@ V1: **manual release only** — omit `expires_at`; readers **MUST NOT** treat un
|
|
|
314
318
|
|
|
315
319
|
## Iteration execution leases (Phase 2)
|
|
316
320
|
|
|
317
|
-
Leases live in the **workflow snapshot** `{WORKFLOW_DIR}/<id>/snapshot.json` (`plans[].execution_lease` per row; `integration_merge_lease` top-level). Coordination happens through the **control
|
|
321
|
+
Leases live in the **workflow snapshot** `{WORKFLOW_DIR}/<id>/snapshot.json` (`plans[].execution_lease` per row; `integration_merge_lease` top-level). Coordination happens through the **control-root copy** (the primary checkout / main worktree) of that file. This is cooperative, not a distributed lock service — non-cooperating processes are out of scope.
|
|
318
322
|
|
|
319
|
-
**When fields apply:** iteration Phase 2 (after
|
|
323
|
+
**When fields apply:** iteration Phase 2 (after integration-worktree entry). Worktree + lease fields are waived only by explicit current-turn user instruction (`Worktree mode: waived` or equivalent); the process SSOT still lives on the primary checkout in all modes. `Plan parallelism: serial` does **not** waive leases. **`Worktree mode: waived` does not waive the cross-plan parallel safety gate.**
|
|
320
324
|
|
|
321
|
-
**Path SSOT:** Default-gitignored process artifacts — `status.json`, `workflows/`, `projects/`, `plans/`, `iterations/`, `sdd/` — read/write via `<
|
|
325
|
+
**Path SSOT:** Default-gitignored process artifacts — `status.json`, `workflows/`, `projects/`, `plans/`, `iterations/`, `sdd/` — read/write via `<main-repo-root>/{HARNESS_DIR}/…` (absolute; control root = the primary checkout / main worktree). A feature worktree's same-looking `{HARNESS_DIR}` path is **not** the SSOT. Missing plans under a feature checkout (gitignore) is **not** grounds for `Worktree mode: waived` — keep feature worktrees and use control absolute **`Plan Path`** / **`SDD dir`**. The three-domain table (process SSOT / tracked results / product source) → **`mstar-branch-worktree`** 「Harness path SSOT under default gitignore」.
|
|
322
326
|
|
|
323
327
|
**Protocol home (single canonical copy):** the full lease protocol prose — same-host exclusive write lock, hard gate, claim-before-`InProgress`, hold/release/override, integration merge protocol, orphan recovery, lease prohibitions — lives in **`mstar-engine-legacy`** `references/lease-protocol.md` (engine-absent fallback). The Phase 2 iteration-command **execution checklist** → **`mstar-iteration`** `references/phase-2-worktree-lease.md`. This file carries the **field semantics** only (tables below + the lockdir location summary).
|
|
324
328
|
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
**Execution:** mstar-sdd | inline
|
|
12
12
|
|
|
13
|
+
**Main worktree branch:** [recorded residency of the primary checkout (main worktree) — PM observes and records before the lifecycle writes, then passes it unchanged in writable Assignments; never invented at check time, and never `branch.base` (that is a creation/merge anchor, not a residency fact)]
|
|
14
|
+
|
|
13
15
|
## Global Constraints
|
|
14
16
|
|
|
15
17
|
[Project requirements — version floors, naming, exact values — copied verbatim from spec. Every task includes them. Verification scope follows `mstar-harness-core` § 定向执行与验证边界: only changed behavior and direct contracts; no local full suites without explicit user permission.]
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mstar-branch-worktree
|
|
3
|
-
description: "Morning Star 业务仓 Git 功能分支、worktree
|
|
3
|
+
description: "Morning Star 业务仓 Git 功能分支、worktree 隔离与三写域模型(L1 跨 plan:主 checkout control root + iteration integration worktree + 每 plan feature worktree + `execution_lease`,默认 gitignore 下经 control 绝对路径读写进程产物;L2 同 plan:`references/parallel-writable-pre-dispatch.md`,N 次 invoke ≠ 隔离)、Spec 集成分支、QC/QA 检出对齐(`Review cwd` / `Working branch` / `plan_id` / `Review range` / `Diff basis` 三审 + QA 逐字相同)。Read when PM writes `Working branch` / `Branch policy`, iteration/parallel writable dispatch, QC/QA checkout alignment, or guarded post-merge worktree/branch cleanup (`mstar worktree cleanup`) is needed."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
## Load order(必读顺序)
|
|
7
7
|
|
|
8
8
|
**首次 Read 本 skill 前:必须先 Read `mstar-harness-core`(SKILL.md)。** 冲突时 **以 `mstar-harness-core` 为准**。
|
|
9
9
|
|
|
10
|
-
**Spec 多 plan 命名**(`iteration_base_branch`、`spec_integration_branch`、`target_branch` PR 门禁)→ **`mstar-conventions`**。**L1/L2 worktree 分层**(迭代
|
|
10
|
+
**Spec 多 plan 命名**(`iteration_base_branch`、`spec_integration_branch`、`target_branch` PR 门禁)→ **`mstar-conventions`**。**L1/L2 worktree 分层**(迭代 integration worktree vs feature、plan 内并行轨)→ 下文 **「Worktree isolation layers」**;**L2** 同仓并行可写派发前清单 → **`references/parallel-writable-pre-dispatch.md`**;迭代 lease claim/merge 细则 → **`mstar-iteration`** `references/phase-2-worktree-lease.md`(勿在本 skill 重复完整协议表)。merge 后 worktree/分支回收(cleanup)守卫契约 → 下文 **「Worktree / branch cleanup」**。下文为分支、三写域、QC/QA 检出对齐与 merge 后 cleanup 主文。
|
|
11
11
|
|
|
12
12
|
## Scope(摘要)
|
|
13
13
|
|
|
14
14
|
- **仅 PM 决定分支**;其他可写角色不得自行新开分支或切回 `main`。
|
|
15
15
|
- **Assignment 须含其一**:`Working branch: <existing>` | `create <new> from <base>` | `Branch policy: direct on <branch> — <reason>`。
|
|
16
|
-
- **L1(跨 plan / 迭代 Phase 2)**:control worktree(snapshot `
|
|
16
|
+
- **L1(跨 plan / 迭代 Phase 2)**:control root(= **主 checkout / main worktree**,进程 SSOT,Git 派生)+ integration worktree(snapshot `integration_worktree_path`,检出 `spec_integration_branch`,唯一 merge cwd)+ 每 plan 独立 feature worktree(`execution_lease.worktree_path`)+ lease;见 **「Worktree isolation layers」**。
|
|
17
17
|
- **L2(同 plan 内 ≥2 可写并发)**:派发 **前** 完成 **`references/parallel-writable-pre-dispatch.md`**(含 `git worktree`、绝对 **`Worktree path`**;**N 次并行 invoke ≠ 已隔离**)。单 plan 多轨时 **L1 不替代 L2**。
|
|
18
18
|
- **QC/QA 前**:待审提交归并到 **单一 `Working branch` `HEAD`**;三审 + QA 共用一套 **`Review cwd` + `plan_id` + `Review range` / `Diff basis`**(逐字相同)。
|
|
19
19
|
|
|
@@ -106,41 +106,44 @@ Two complementary **worktree** isolation layers coexist. Do **not** conflate the
|
|
|
106
106
|
|
|
107
107
|
| Layer | Scope | When | Mechanism |
|
|
108
108
|
|-------|-------|------|-----------|
|
|
109
|
-
| **L1** | Cross-plan (iteration Phase 2) | Multiple plans may implement concurrently in one iteration | **
|
|
109
|
+
| **L1** | Cross-plan (iteration Phase 2) | Multiple plans may implement concurrently in one iteration | **Main-worktree control root** (process SSOT) + **integration worktree** (`integration_worktree_path`) + per-plan **feature worktrees** + `plans[].execution_lease` (workflow snapshot `workflows/<id>/snapshot.json`) |
|
|
110
110
|
| **L2** | Within-plan | Same `plan_id`, same business repo, **≥2 concurrent writable implement tracks** | **`references/parallel-writable-pre-dispatch.md`** — distinct absolute **`Worktree path`** per track |
|
|
111
111
|
|
|
112
112
|
**Stacking rules**
|
|
113
113
|
|
|
114
114
|
- Default **L1** capacity is **one writable track per plan**. If one plan runs **≥2** concurrent writable tracks, each track **also** satisfies **L2**; L1 does **not** replace L2.
|
|
115
|
-
- **L1** applies under iteration commands with Phase 2
|
|
115
|
+
- **L1** applies under iteration commands with Phase 2 worktree/lease defaults (unless explicit `Worktree mode: waived` this turn). Single-plan waves without iteration leases still require **L2** when **≥2** parallel writable tracks share one repo.
|
|
116
116
|
- Cross-plan **integration merge** into `spec_integration_branch` remains **serial** (snapshot top-level `integration_merge_lease`) even when L1 feature implementation runs in parallel.
|
|
117
117
|
|
|
118
|
-
###
|
|
118
|
+
### Main-worktree control root, integration worktree, feature worktree (iteration / L1)
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
The integration worktree is established at iteration **Phase 2 entry** (Phase 1 Review & Edit may edit uncommitted docs on the primary checkout under the Prepare policy — the bounded exception; the main worktree never switches branch). Normative field names and claim/release/merge protocol → **`mstar-iteration`** `references/phase-2-worktree-lease.md` and maintenance ADR `2026-07-22-iteration-worktree-plan-lease.md`. **Do not invent alternate lease field names in this skill.**
|
|
121
121
|
|
|
122
|
-
|
|
|
123
|
-
|
|
124
|
-
| **Control
|
|
122
|
+
| Checkout | Checked-out branch | Path recorded | Writable role |
|
|
123
|
+
|----------|-------------------|---------------|---------------|
|
|
124
|
+
| **Control root** = the **primary checkout** (main worktree) | the recorded **`Main worktree branch`** from the main plan header (never a lifecycle-owned branch; never switched) | **not in the snapshot** — derived from Git (`readMainWorktree`); the branch is recorded once as `Main worktree branch: <branch>` in the main plan | **Forbidden** for product edits — process-SSOT holder + Git-control cwd only |
|
|
125
|
+
| **Integration worktree** | Resolved `spec_integration_branch` (same across active plans) | `integration_worktree_path` (snapshot top-level) — canonical **repository root** (not `{HARNESS_DIR}`) | Sole merge cwd for serial integration merges (`integration_merge_lease`) + tracked-result close commits (Phase 3 compound); **no product-source edits** — Phase-5 fixes use a feature worktree |
|
|
125
126
|
| **Feature worktree** (per plan) | Plan `Working branch` / feature branch from integration | `plans[].execution_lease.worktree_path` (snapshot plan row) | **Required cwd** for that plan's product/source edits |
|
|
126
127
|
|
|
127
|
-
### Harness path SSOT under default gitignore (L1)
|
|
128
|
+
### Harness path SSOT under default gitignore (L1) — the three-domain table
|
|
128
129
|
|
|
129
|
-
Default process artifacts
|
|
130
|
+
Default process artifacts are **gitignored** (`mstar-conventions`「Git 跟踪策略」); `git worktree add` does **not** copy them into a new checkout. A worktree's `.mstar/` is **not categorically non-writable** — writability is decided per domain. This is the **sole** three-domain table in the skill corpus; other skills point here instead of restating it.
|
|
130
131
|
|
|
131
|
-
|
|
|
132
|
-
|
|
133
|
-
| **
|
|
134
|
-
| **
|
|
135
|
-
| **
|
|
136
|
-
|
|
132
|
+
| Domain | Contents | Home | Writable from a worktree? |
|
|
133
|
+
|---|---|---|---|
|
|
134
|
+
| **Process SSOT** (gitignored) | `status.json`, `workflows/`, `projects/`, `plans/`, `sdd/`, `iterations/`, `archived/` | control root = the **primary checkout** (main worktree) | **No.** Always addressed via absolute control-root paths; a second process-SSOT copy must never be bootstrapped under any worktree. |
|
|
135
|
+
| **Tracked results** (Git-following) | `{KNOWLEDGE_DIR}`, `{SPECS_DIR}`, `{HARNESS_DIR}/AGENTS.md`, `CONCEPTS.md` | whichever checkout holds the target branch | **Yes.** Readable from any worktree; written where the target branch is checked out (iteration Phase 3 compound → the integration worktree), then committed on that branch. |
|
|
136
|
+
| **Product source** | repository code | feature worktree on `Working branch` | feature worktree only. |
|
|
137
|
+
|
|
138
|
+
**Control harness root** = `<main-repo-root>/{HARNESS_DIR}/` — resolved from Git (the main worktree), never from a snapshot field.
|
|
137
139
|
|
|
138
140
|
**Hard rules**
|
|
139
141
|
|
|
140
|
-
- Snapshot `
|
|
141
|
-
-
|
|
142
|
+
- Snapshot `integration_worktree_path` **MUST** differ from the main worktree (control root) and from `execution_lease.worktree_path` — never merge from the main checkout, never product-edit the integration checkout.
|
|
143
|
+
- Main-worktree residency: the main worktree's attached branch must equal the recorded **`Main worktree branch`** from the plan header (recorded before the lifecycle writes; never invented from the current branch at check time) and must not be owned by any non-terminal workflow (integration, plan or track). Never create a branch or switch main to make a residency check pass; `branch.base` is a creation/merge anchor, never a residency fact.
|
|
144
|
+
- A feature worktree's same-looking `{HARNESS_DIR}` path is **not** the SSOT — **never** treat it as the source of plans/status/SDD, and **never** bootstrap a second process-SSOT copy there.
|
|
142
145
|
- Absolute **`Worktree path`** (feature) MUST appear in the writable Assignment and in `execution_lease.worktree_path` before first writable implement dispatch for that plan.
|
|
143
|
-
- When L1 lease gate is active (not `Worktree mode: waived`), Assignment **`Plan Path`** and **`SDD dir`** MUST be **absolute paths under the control harness root** (not relative `.mstar/...` resolved from the feature cwd). Prefer also writing **`Control harness root: <
|
|
146
|
+
- When L1 lease gate is active (not `Worktree mode: waived`), Assignment **`Plan Path`** and **`SDD dir`** MUST be **absolute paths under the control harness root** (not relative `.mstar/...` resolved from the feature cwd). Prefer also writing **`Control harness root: <main-repo-root>/{HARNESS_DIR}`**.
|
|
144
147
|
- Writable dispatch for a plan requires a **verified** `execution_lease` (same read-check-replace-verify discipline as the iteration reference). Full claim tables are **not** duplicated here.
|
|
145
148
|
|
|
146
149
|
**Anti-pattern (forbidden)**
|
|
@@ -149,11 +152,12 @@ Default process artifacts (`plans/`, `iterations/`, `status.json`, `workflows/`,
|
|
|
149
152
|
|
|
150
153
|
**Naming conventions (PM / ops; examples only — paths MUST be canonical absolute)**
|
|
151
154
|
|
|
152
|
-
1. **Control
|
|
153
|
-
2. **
|
|
154
|
-
3. **
|
|
155
|
+
1. **Control root** — always the **primary checkout** (main worktree), derived from Git (`readMainWorktree`); never a PM-designated alternative checkout, never recorded in the snapshot. Its attached branch is recorded once as **`Main worktree branch: <branch>`** in the main plan header before the lifecycle writes, and PM passes it unchanged in writable Assignments. `branch.base` is the creation/merge anchor — not a residency fact.
|
|
156
|
+
2. **Integration worktree** — one dedicated linked checkout on `spec_integration_branch`, distinct from the main worktree, recorded once in snapshot `integration_worktree_path`; sole merge cwd for the iteration.
|
|
157
|
+
3. **Feature worktree (per plan)** — one distinct subdirectory under the workspace root **`.worktrees/`** per active `plan_id` (e.g. `.worktrees/<plan-id>-<slug>`; AGENTS.md「Local scratch layout」), gitignored by the repo convention; Assignment **`Worktree path`** must match lease `worktree_path`.
|
|
158
|
+
4. **L2 track worktrees (within-plan)** — additional distinct directories per parallel implement track under the **same** plan (see **`references/parallel-writable-pre-dispatch.md`**), each with its own PM-approved **`Working branch`**.
|
|
155
159
|
|
|
156
|
-
> **Engine check (when available):** run `mstar worktree check <plan-id> --workflow <id>` (L1) / `mstar worktree check --l2 --tracks <json>` (L2) (or `import { l1PreDispatchCheck, l2PreDispatchCheck, assertControlVsFeaturePath, assertBranchAlignment } from "@mstar-harness/engine"` in a host hook) to verify the L1/L2 isolation rules above (
|
|
160
|
+
> **Engine check (when available):** run `mstar worktree check <plan-id> --workflow <id>` (L1) / `mstar worktree check --l2 --tracks <json>` (L2) (or `import { l1PreDispatchCheck, l2PreDispatchCheck, readMainWorktree, assertMainWorktreeResidency, assertControlVsFeaturePath, assertBranchAlignment } from "@mstar-harness/engine"` in a host hook) to verify the L1/L2 isolation rules above (main residency vs recorded `Main worktree branch`; main/integration/feature pairwise checkout distinctness — lease worktree ≠ main control root ≠ integration; checked-out branch matches `Working branch`). On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
157
161
|
|
|
158
162
|
## 同仓并发写入与 Git worktree(强制)
|
|
159
163
|
|
|
@@ -166,7 +170,7 @@ Default process artifacts (`plans/`, `iterations/`, `status.json`, `workflows/`,
|
|
|
166
170
|
- **PM 须在 Assignment 中写清**各并发写流的 **检出约定**(例如预期 **`Worktree path`** / 命名规则,或「由承接方创建/使用隔离 worktree 并在 Completion Report 回报路径」),避免多代理默认共享同一目录导致互相覆盖、冲突或半写入状态。
|
|
167
171
|
- **同仓、同一 plan、≥2 可写并行轨**:派发各轨实现 Assignment **之前** 确认 **`Branch policy`** 与 plan 集成分支 / topic 分支关系(见下节 **「默认编排」**),并完成 reference 清单中的 worktree 步骤。
|
|
168
172
|
|
|
169
|
-
|
|
173
|
+
**串行不豁免**:并发流全部为只读、或各写入者针对**不同 Git 仓库根**时不存在共享写入面;但**写入串行**(同一时刻仅一个代理持有该仓工作区)**不**豁免隔离——只要本轮存在对同一仓库工作区的可写改动,每条写流都使用独立检出目录(主 checkout 可能被链接的技能/命令消费者读取,任何生命周期分支都不得落到主 worktree)。worktree 默认的唯一豁免通道:本轮显式 **`Worktree mode: waived`** 与 Phase 1 Review & Edit 链的未提交文档例外(`mstar-iteration` §1.6 / §6)。
|
|
170
174
|
|
|
171
175
|
### 并发 subagent 与同仓工作树(对齐)
|
|
172
176
|
|
|
@@ -225,12 +229,49 @@ Default process artifacts (`plans/`, `iterations/`, `status.json`, `workflows/`,
|
|
|
225
229
|
- 证据最窄原则(audit / QA Assignment 场景):选择会在目标回归上失败的**最窄**检查;不因「push 在即」重跑已通过的检查。
|
|
226
230
|
- 本节只管 rewrite / lease / 证据失效面;CI / review 波次 push 门禁(时序)SSOT → `mstar-iteration` §5.1a。
|
|
227
231
|
|
|
232
|
+
## Worktree / branch cleanup(merge 后回收;唯一契约本体)
|
|
233
|
+
|
|
234
|
+
生命周期末端的物理回收(feature/integration worktree、本地/远端分支删除)的 ownership 与守卫规则**只在本节**;两条时序车道的 call site(Phase-2 同轮 / Phase-6 收尾)只引用本节,不复制规则。命令(**dry-run 默认**;无 fetch / prune / 任何写入):
|
|
235
|
+
|
|
236
|
+
```text
|
|
237
|
+
mstar worktree cleanup --workflow <id> [--harness <path>] [--apply] [--remote] [--worktree <path>]
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
- dry-run 逐候选打印 `verdict | kind | ref | reason` 后结束;`--apply` 只执行当前 `remove` 行。Exit:0 = 合法 dry-run / eligible 移除全部成功;1 = 探测/变更失败;2 = usage。失败行**永不扩大范围**;受保护/拒绝行保持可见。
|
|
241
|
+
- `--worktree <path>` 可重复:既收窄 worktree 候选集,也是**操作者所有权断言**——必须匹配记录的生命周期分支与同仓 checkout 身份,不能认领其他 lifecycle 的 worktree。`--remote` 只决定是否纳入 `origin/*` 删除候选;安全探测(integration 证据)无论是否 `--remote` 都会收集。
|
|
242
|
+
- **信任模型**:`--harness <path>` 为操作者提供且受信——dry-run 与 `--apply` 的全部状态事实(snapshot、lease、行归属元数据、protected 锚点)均读自该目录。
|
|
243
|
+
|
|
244
|
+
**Ownership(禁止命名推断)**:候选归属只来自 snapshot 行元数据(`plans[].execution_lease`;lease 释放后为保留的行 `metadata.working_branch` / `metadata.worktree_path` 与 retained track Assignments)或已验证的显式 `--worktree` 断言。归属缺失 / 歧义 / 他属 → `cleanup.refuse.foreign-worktree` / `cleanup.refuse.foreign-branch`。**归属生产者义务(owner=PM)**:设 `Done` 并删除 `execution_lease` 的**同一 locked update** 内,owner 必须把 `metadata.working_branch` + `metadata.worktree_path` 持久化到该 plan 行(值以本轮 Assignment 为准)——这是 lease 释放后 ownership 检查读取的持久归属;缺失时已 merge 的 Done 行也会被 `cleanup.refuse.foreign-*` 拒绝,回收只能靠手工补写快照。
|
|
245
|
+
|
|
246
|
+
**合并证据硬前置**:本地资格 = `git branch --merged <base>` 成员资格,base 取候选自己的锚(plan/track → `branch.integration`;standalone plan / integration 分支 → `branch.target`)。远端证据绑定 {branch, tip, base} **同一分支化身**;当前 harness 无 PR-merged 记录源(`prMerged` 恒为 null)→ 远端仅走 tip-ancestor 历史残留路线。squash-only(tip 非 base 祖先)**保留并报告,绝不 `git branch -D`**;旧 merged PR 不能授权已复用分支的新化身。
|
|
247
|
+
|
|
248
|
+
**Refusals(refuse 行可见、可审计,不是 apply 失败)**:active `execution_lease` / `integration_merge_lease`(按 path 与 branch 匹配,跨**全部**已知 snapshot)→ `cleanup.refuse.active-lease`;分支在**任何** checkout 检出 → `cleanup.refuse.checked-out`;foreign worktree;dirty / locked worktree;protected refs(默认分支、每个 `branch.base`、非终结 integration 分支、非 Done plan/track 行)→ `cleanup.keep.protected-ref` / `cleanup.refuse.non-terminal`。
|
|
249
|
+
|
|
250
|
+
**Done child ≠ active parent**:已 merge 的 Done plan/track 行**即使父迭代仍在运行也 eligible**(时序车道 1)——不存在「父必须终结」的一刀切;反之,非终结 integration 与非 Done 行跨**所有** lifecycle 受保护。standalone plan 即整个 lifecycle:以 `branch.target` 为证据 base,且**先 terminal close** 才清理。
|
|
251
|
+
|
|
252
|
+
**顺序(--apply;worktree 移除 ≠ 分支删除)**:普通 `git worktree remove`(**永不 force**)移除 eligible attached worktree → **重新探测 + 重新规划** → 删除**现已**未检出的分支(`git branch -d`,**永不 `-D`**)→ 远端 expected-OID compare-and-delete(`git push --force-with-lease=refs/heads/<branch>:<observed-oid> origin :refs/heads/<branch>`;ref 已移动 → `cleanup.refuse.facts-changed`,**不**自动用新 OID 重试)。dry-run 打印 worktree `remove` + 其分支 `refuse(checked-out)` 是合法状态。**禁止**全局 `git worktree prune`(会动 foreign 注册);Git 调用默认在 main worktree root,`git branch -d` 在该分支证据 base 的检出处执行(`-d` merged-into-HEAD 语义所需)——任何 Git 调用**永不位于移除候选内**。
|
|
253
|
+
|
|
254
|
+
**Lease 释放是手工 owner 动作、cleanup 范围外**:cleanup(与 close)**从不**释放 lease;owner 先手工释放再清理,释放后归属靠保留的行元数据 / Assignments 维持。
|
|
255
|
+
|
|
256
|
+
**两条时序车道(唯一合法时机)**:
|
|
257
|
+
|
|
258
|
+
1. **Phase-2 同轮**(per-plan):integration merge 成功的**同一轮**回收该 Done plan/track 的 feature worktree + 已合并分支(call site → `mstar-iteration` `references/phase-2-worktree-lease.md`「Same-round plan cleanup」)。
|
|
259
|
+
2. **Phase-6 收尾**(integration 面):只在 valid terminal close(§6.1–§6.3 完成)+ PR **verified merged** 之后回收 integration worktree / 分支 / 远端残留(call site → `mstar-iteration` `references/phase-6-post-merge-close.md` §6.4)。Phase-6 gate 只查本地 state,**不**验证 merged、**不**检查物理清理是否完成。
|
|
260
|
+
|
|
261
|
+
> **Engine check (when available):** dry-run 即机器检查 —— `mstar worktree cleanup --workflow <id>`(或 import `planWorktreeCleanup` from `@mstar-harness/engine`)对当前 facts 输出 remove/keep/refuse 计划,每行带稳定 `cleanup.*` 码。若已知受保护目标(active lease / 非 Done / 非终结 owner)出现 `remove` → STOP:守卫有错,**任何 `--apply` 前先修**。Skill text below remains authoritative when the runtime is absent.
|
|
262
|
+
|
|
228
263
|
## Workflow
|
|
229
264
|
|
|
230
|
-
主链:**PM 唯一分支决策**(`Working branch` / `Branch policy`,写进 Assignment)→ 实现者在 feature worktree 写产品编辑(L1:control worktree 管
|
|
265
|
+
主链:**PM 唯一分支决策**(`Working branch` / `Branch policy`,写进 Assignment)→ 实现者在 feature worktree 写产品编辑(L1:control root(主 checkout)管进程 SSOT、integration worktree 管 merge、feature 管源码)→ **QC 前**全部待审提交归并到**单一 `Working branch` `HEAD`** → 派 QC 三审 / QA 时共用**同一套对齐字段**(`Review cwd` / `Working branch` / `plan_id` / `Review range` / `Diff basis`,逐字相同)→ 集成分支 merge 串行(`integration_merge_lease`,在 integration worktree 执行)。并发写流在派发**前**完成 worktree 隔离(L1 跨 plan / L2 同 plan);主 worktree 驻留分支 = 计划头记录的 **`Main worktree branch`**,全程不切换。
|
|
231
266
|
|
|
232
267
|
## References
|
|
233
268
|
|
|
234
269
|
- 派发与反递归红线 → **`mstar-dispatch-gates`**
|
|
235
270
|
- SDD implement 波次(file handoff / reviewer)→ **`mstar-sdd`**
|
|
236
|
-
- 迭代 Phase 2
|
|
271
|
+
- 迭代 Phase 2 integration worktree + lease 细则 → **`mstar-iteration`** §2(`references/phase-2-worktree-lease.md`)
|
|
272
|
+
|
|
273
|
+
### L1 refusal diagnostics across hosts
|
|
274
|
+
|
|
275
|
+
CLI, dsh, and omp share `worktree.l1.lifecycle-register-unreadable` when the active register cannot be enumerated and `worktree.l1.lifecycle-snapshot-unreadable` when a registered sibling cannot be read/validated. They fail closed; an absent register contributes no siblings. Engine SDD governing-row discovery remains lenient for unreadable siblings (only readable active snapshots contribute), but a governing active snapshot carrying both integration/control path keys refuses instead of becoming standalone. This is an intentional engine-versus-host seam distinction, not equivalent evidence coverage.
|
|
276
|
+
|
|
277
|
+
`worktree.l1.integration-missing` covers required integration inputs not supplied and a supplied integration path absent on disk; an existing unusable checkout is reported by branch/checkout probe failures. A standalone plan with both integration fields omitted has no integration requirement and does not emit this code.
|
|
@@ -6,8 +6,8 @@ This reference is **L2** worktree isolation: **same `plan_id`**, **same business
|
|
|
6
6
|
|
|
7
7
|
**L1 (cross-plan)** is separate and stacks on top when iteration Phase 2 defaults apply:
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
- Each concurrently active plan uses a **distinct feature worktree** (`execution_lease.worktree_path`
|
|
9
|
+
- The **control root** is the primary checkout (main worktree) — the process-SSOT holder whose residency is recorded as **`Main worktree branch`** in the main plan header. The **integration worktree** (`integration_worktree_path`, checked out to `spec_integration_branch`) is the sole merge cwd; status/SDD coordination reads/writes run via absolute control-root paths.
|
|
10
|
+
- Each concurrently active plan uses a **distinct feature worktree** (`execution_lease.worktree_path` ≠ the main worktree ≠ `integration_worktree_path`) with a verified snapshot `plans[].execution_lease` before writable dispatch. **Every** writable track — parallel or serial — is excluded from the main and integration checkouts.
|
|
11
11
|
- Claim/hold/release/merge rules → **`mstar-iteration`** `references/phase-2-worktree-lease.md` (not repeated here).
|
|
12
12
|
|
|
13
13
|
When **one plan** runs **≥2** concurrent writable tracks, **L2 still applies** inside that plan even if L1 leases already isolate plans from each other. Run this checklist **per plan** that has multiple parallel implement tracks.
|
|
@@ -20,7 +20,7 @@ Host dispatch can satisfy **「N Assignments ⇒ N invokes in one message」** w
|
|
|
20
20
|
|
|
21
21
|
## Mode switch (do not carry single-track habits)
|
|
22
22
|
|
|
23
|
-
Serial single-plan waves (one feature branch, one
|
|
23
|
+
Serial single-plan waves (one feature branch, one feature worktree, PM merging via the integration worktree) do **not** authorize multi-writer parallel tracks without re-running this **L2** gate.
|
|
24
24
|
|
|
25
25
|
When the round adds a second **concurrent** writable implement track on the **same business repo** within one plan, treat it as a **mode switch** — even if earlier plans in the iteration were serial or L1 already assigned each plan its own feature worktree.
|
|
26
26
|
|
|
@@ -29,18 +29,19 @@ When the round adds a second **concurrent** writable implement track on the **sa
|
|
|
29
29
|
Before the **first** concurrent writable implement dispatch in a round:
|
|
30
30
|
|
|
31
31
|
1. **Re-read repo parallel rules** — root `AGENTS.md` and `{HARNESS_DIR}/AGENTS.md` for branch / worktree / merge-order constraints not duplicated in harness skills.
|
|
32
|
-
2. **Confirm PM checkout** — PM thread
|
|
32
|
+
2. **Confirm PM checkout** — PM thread operates the **integration worktree** (dedicated checkout on `spec_integration_branch`); the primary checkout (main worktree) keeps its recorded **`Main worktree branch`** and never switches. **Do not** `checkout` topic / feature branches in the PM **primary cwd** to "help" implementers.
|
|
33
33
|
3. **Create isolation** — for each writable track: `git worktree add .worktrees/<track-slug> <branch>` (or host-equivalent) **before** Task invoke. Each Assignment **must** include absolute **`Worktree path`**.
|
|
34
34
|
4. **Verify paths exist** — for each track: directory exists; `git -C <path> branch --show-current` matches Assignment **`Working branch`**.
|
|
35
|
-
5. **
|
|
36
|
-
6. **
|
|
35
|
+
5. **Retain track ownership** — before L2 dispatch, PM records every track's Assignment **`Working branch`** in the governing snapshot plan row **`metadata.track_branches: string[]`**. Retain these branches while the lifecycle is active, including after individual track leases are released; the main-residency check consumes this record.
|
|
36
|
+
6. **Assignment tags** — `Dispatch mode: parallel independent tracks` + `Worktree isolation: required` (`mstar-phase-gates`).
|
|
37
|
+
7. **Merge order** — when tracks may touch overlapping paths (shared packages, migrations, lockfiles), PM assigns **explicit sequential merge order** before dispatch.
|
|
37
38
|
|
|
38
39
|
## PM primary cwd invariants
|
|
39
40
|
|
|
40
41
|
| Allowed (PM thread) | Forbidden (PM thread) |
|
|
41
42
|
|---------------------|----------------------|
|
|
42
|
-
|
|
|
43
|
-
| `git worktree add` / `list` / `remove` | `commit` product code |
|
|
43
|
+
| operate the **integration worktree** (dedicated checkout on `spec_integration_branch`) for merges and tracked-result commits | `git checkout` any branch in the **primary cwd** — the main worktree never leaves its recorded **`Main worktree branch`** |
|
|
44
|
+
| `git worktree add` / `list` / `remove` | `commit` product code in the main or integration checkout (product source → feature worktree) |
|
|
44
45
|
| read-only inspection inside worktrees | switch primary cwd to an implementer feature branch |
|
|
45
46
|
|
|
46
47
|
## Leaf implementer invariants
|
|
@@ -140,7 +140,7 @@ Legacy `.agents/` 项目:将上表路径前缀 `.mstar/` 换为 `.agents/`。
|
|
|
140
140
|
|
|
141
141
|
**v3 运行时目录的 gitignore 说明(文档化;canonical snippet 零改动)**:`workflows/` 与 `projects/` 都位于已被 **`.mstar/**` 默认忽略**的 `{HARNESS_DIR}` 之下——**不需要**在仓库根 `.gitignore` 增加任何条目,也**不新增** re-include 条目(它们不是 tracked 结果)。`projects/_default/` 由 **`scaffoldHarness` / `mstar harness scaffold` 预建**(`roadmap.md` + 空 `residuals.json`);其余 project id 与 `workflows/` 子目录由 **engine writers 按需创建**(`writeWorkflowSnapshot` / `registerWorkflow` / project-register 写入路径),**不是** `scaffoldHarness` 的初始化产物。
|
|
142
142
|
|
|
143
|
-
**多 worktree(iteration L1)**:默认 gitignored 的进程产物**不会**随 `git worktree add`
|
|
143
|
+
**多 worktree(iteration L1)**:默认 gitignored 的进程产物**不会**随 `git worktree add` 进入新检出。进程 SSOT 固定在 **control root = 主 checkout(main worktree)**,读写经 control 绝对路径(`<main-repo-root>/{HARNESS_DIR}/…`);integration 分支检出在专属 integration worktree(snapshot `integration_worktree_path`,唯一 merge cwd);产品代码改在 feature worktree。**Gitignore 策略注**:tracked-results 层(`{KNOWLEDGE_DIR}` / `{SPECS_DIR}` / `{HARNESS_DIR}/AGENTS.md`)随 Git 分支走,在采纳 canonical gitignore snippet 的仓库中对所有 worktree **可见**——本仓库 `.mstar/` 全量 gitignore 属仓库自身 ignore 规则的属性,非契约。三写域模型(process SSOT / tracked results / product source)的 SSOT 表 → **`mstar-branch-worktree`**「Harness path SSOT under default gitignore」;反模式(禁止因 feature 缺 plans 而 `Worktree mode: waived`)同见该表。
|
|
144
144
|
|
|
145
145
|
**Canonical `.gitignore` snippet**(skills 与 CLI `init` 对齐):
|
|
146
146
|
|
|
@@ -175,7 +175,7 @@ Legacy `.agents/` 等价:
|
|
|
175
175
|
|
|
176
176
|
## Spec 驱动的分支模型(多 Plan · 同一 Spec)
|
|
177
177
|
|
|
178
|
-
- **Iteration base branch**:创建 Spec/iteration 集成分支的祖先分支或 ref;必须显式记录,不能默认 `main` / `master
|
|
178
|
+
- **Iteration base branch**:创建 Spec/iteration 集成分支的祖先分支或 ref;必须显式记录,不能默认 `main` / `master`。**`branch.base` 是创建/merge 锚点,不是主 worktree 驻留事实**——主 worktree(control root)的驻留分支在生命周期写入前由 PM 记录为 **`Main worktree branch`**(主 plan 头),全程不切换。
|
|
179
179
|
- **Spec 集成分支**:从 `iteration_base_branch` 创建;各 Plan 实现 merge 回此线后再视为 Spec 在代码侧集成。
|
|
180
180
|
- **Plan 实现分支**:每 `plan_id` 一条(PM 书面)。
|
|
181
181
|
- **PR target**:全部 Plans 与 iteration-close 完成后,向显式 `target_branch` 提 PR(窄例外见 Assignment `Branch policy`)。
|