@mstar-harness/opencode 0.6.0 → 0.6.2
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/harness-skills/mstar-plan-artifacts/SKILL.md +19 -18
- package/harness-skills/mstar-plan-artifacts/references/status-and-residuals.md +164 -220
- package/harness-skills/mstar-plan-artifacts/scripts/tech-debt-rollup.sh +115 -0
- package/harness-skills/mstar-plan-artifacts/templates/README.md +1 -1
- package/harness-skills/mstar-roles/references/project-manager/routing-and-dev-allocation.md +17 -11
- package/harness-skills/mstar-roles/references/project-manager.md +8 -0
- package/harness-skills/pm/SKILL.md +14 -2
- package/package.json +1 -1
|
@@ -3,29 +3,30 @@ name: mstar-plan-artifacts
|
|
|
3
3
|
description: Morning Star plan harness artifacts — `{PLAN_DIR}` main plans and `reports/`, `{KNOWLEDGE_DIR}` / `{ITERATION_DIR}` indexes, Done compaction, plus `{HARNESS_DIR}/status.json` and root `residual_findings` (severity SSOT, open/archived lifecycle, `notes.json`). Read when writing plans or QC reports, maintaining knowledge/iteration indexes, reading or writing `status.json` / R#, Done compaction, or mapping QC severity to JSON. Required for `@project-manager` on status, residuals, and InReview/QC waves; `@qc-specialist*` before `reports/**/*.md`; `@qa-engineer` before closing R#. Verdict rules in `mstar-review-qc`; paths in `mstar-plan-conventions`.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
## Load order
|
|
6
|
+
## Load order
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
**Before first Read of this skill: Read `mstar-harness-core` (SKILL.md), and `mstar-plan-conventions` when path symbols matter.** Git branch / worktree / QC checkout → **`mstar-branch-worktree`**. On conflict, **`mstar-harness-core` wins**.
|
|
9
9
|
|
|
10
|
-
## Scope
|
|
10
|
+
## Scope (plan directory artifacts)
|
|
11
11
|
|
|
12
|
-
| Topic |
|
|
13
|
-
|
|
14
|
-
|
|
|
15
|
-
| knowledge / iterations / specs
|
|
16
|
-
| Done
|
|
17
|
-
| `status.json
|
|
18
|
-
|
|
|
12
|
+
| Topic | See |
|
|
13
|
+
|-------|-----|
|
|
14
|
+
| Main plan, reports naming, QC waves, residual and plan index order | `references/plan-files-and-reports.md` |
|
|
15
|
+
| knowledge / iterations / specs boundaries and indexes | `references/knowledge-and-designs.md` |
|
|
16
|
+
| Done row compaction Profile A/B | `references/done-compaction.md` |
|
|
17
|
+
| `status.json`, residual severity, lifecycle, `jq` | `references/status-and-residuals.md` |
|
|
18
|
+
| Empty-repo `status.json` / `notes.json` templates | `templates/status.empty.json`, `templates/notes.empty.json` (`templates/README.md`) |
|
|
19
|
+
| Tech-debt rollup (read-only) | `scripts/tech-debt-rollup.sh` |
|
|
19
20
|
|
|
20
|
-
**Out of scope:**
|
|
21
|
+
**Out of scope:** branch and QC/QA checkout alignment → **`mstar-branch-worktree`**; QC checklist and verdict → **`mstar-review-qc`**; `{HARNESS_DIR}` discovery and init → **`mstar-plan-conventions`**.
|
|
21
22
|
|
|
22
|
-
## `status.json`
|
|
23
|
+
## `status.json` and open residual (summary)
|
|
23
24
|
|
|
24
|
-
- **`{HARNESS_DIR}/status.json
|
|
25
|
-
- **Canonical
|
|
26
|
-
-
|
|
27
|
-
- **`notes.json
|
|
25
|
+
- **`{HARNESS_DIR}/status.json`**: `plans[]` row status + root **`residual_findings[<plan-id>]`** (open list **SSOT**).
|
|
26
|
+
- **Canonical**: register new findings only at root `residual_findings`; **`metadata.residual_findings`** is legacy read-only — **do not** dual-write.
|
|
27
|
+
- **Lifecycle**: open → verified close → **`archived/residuals/<plan-id>.json`**; machine **`severity`** enum in reference.
|
|
28
|
+
- **`notes.json`**, optional **`tech_debt_summary`** (rollup view; compute via **`scripts/tech-debt-rollup.sh`**).
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
Field semantics, severity mapping, archive flow, and `jq` examples → **`references/status-and-residuals.md`**.
|
|
30
31
|
|
|
31
|
-
**Templates
|
|
32
|
+
**Templates (this skill):** `templates/status.empty.json`, `templates/notes.empty.json` — copy into `{HARNESS_DIR}/` (`templates/README.md`).
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
# `{HARNESS_DIR}/status.json`
|
|
1
|
+
# `{HARNESS_DIR}/status.json` and Residual Findings (Morning Star)
|
|
2
2
|
|
|
3
|
-
> **Load order
|
|
3
|
+
> **Load order (same as other `mstar-*` skills):** Before changing SSOT / residual fields using this reference, Read **`mstar-harness-core`** (SKILL.md; same-repo branches and worktrees → **`mstar-branch-worktree`**). On conflict, **`mstar-harness-core` wins**; skill index in that SKILL.md.
|
|
4
4
|
|
|
5
|
-
`status.json`
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
`status.json` lives at **`{HARNESS_DIR}/status.json`**. It is the **single source of truth (SSOT)** for **`plans[]` row status** and **open residual findings**.
|
|
6
|
+
Canonical vs legacy residual definitions → **`mstar-plan-artifacts` SKILL.md** (“`status.json` and open residual (summary)”); this file covers **fields, severity, lifecycle, archive, and `jq` examples**.
|
|
7
|
+
**Closed** residuals should not accumulate here long-term; authoritative archive → **`{HARNESS_DIR}/archived/residuals/<plan-id>.json`** (see “Residual findings lifecycle”).
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**Why this matters:** The open list and `archived/residuals/` are the **cross-session handoff surface** for risk and decisions. Non-blocking conclusions that stay only in chat or a single QC report **without SSOT** cannot be inherited reliably; `Done` drifts from visible known debt. **`@project-manager`** should register trackable open items soon after review closure; **`@qa-engineer`** and PM should close and archive after verification or explicit waiver — flexible timing, but **not** “said in chat is enough.”
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Basic structure
|
|
12
12
|
|
|
13
13
|
```json
|
|
14
14
|
{
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"plans": [
|
|
18
18
|
{
|
|
19
19
|
"id": "plan-id",
|
|
20
|
-
"title": "
|
|
20
|
+
"title": "Plan title",
|
|
21
21
|
"file": "{PLAN_DIR}/plan-id-feature-name.md",
|
|
22
22
|
"status": "Todo | InProgress | InReview | Blocked | Done",
|
|
23
23
|
"owner": "@project-manager",
|
|
@@ -51,184 +51,156 @@
|
|
|
51
51
|
}
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
**Empty-repo templates:** **`templates/status.empty.json`**; optional **`templates/notes.empty.json`** → `{HARNESS_DIR}/notes.json`. See **`templates/README.md`**.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
**Closed entries** add: `lifecycle`, `closed_at`, `closure_note`; optional `closure_evidence`, `superseded_by`. See “Residual findings lifecycle”.
|
|
57
57
|
|
|
58
|
-
**Open
|
|
58
|
+
**Open `detail_doc` (optional):** repo-relative path under **`{PLAN_DIR}/residuals/<plan-id>/`** matching **`id`** (e.g. `R1`); omit if prose layer unused (`knowledge-and-designs.md`).
|
|
59
59
|
|
|
60
|
-
## Residual findings
|
|
60
|
+
## Residual findings: `severity` (SSOT, machine field)
|
|
61
61
|
|
|
62
|
-
`residual_findings[<plan-id>][]`
|
|
62
|
+
Each `residual_findings[<plan-id>][]` entry’s **`severity`** must be from this enum (legacy read paths → **`jq` examples** at end). QC report Markdown **Critical / Warning / Suggestion** are **section titles** — **do not** copy them verbatim into JSON `severity`.
|
|
63
63
|
|
|
64
|
-
### 1.
|
|
64
|
+
### 1. Allowed values
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
Only these five, **lowercase English**:
|
|
67
67
|
|
|
68
|
-
`critical
|
|
68
|
+
`critical`, `high`, `medium`, `low`, `nit`
|
|
69
69
|
|
|
70
|
-
### 2.
|
|
70
|
+
### 2. Total order (heavy → light)
|
|
71
71
|
|
|
72
|
-
`critical`
|
|
72
|
+
`critical` > `high` > `medium` > `low` > `nit`
|
|
73
73
|
|
|
74
|
-
-
|
|
75
|
-
-
|
|
74
|
+
- **`nit` is always lighter than `low`** — never invert or equate.
|
|
75
|
+
- **Forbidden** in JSON: `warning`, `Major`, non-English, or any value not listed.
|
|
76
76
|
|
|
77
|
-
### 3.
|
|
77
|
+
### 3. Meaning and gate relationship
|
|
78
78
|
|
|
79
|
+
| `severity` | Meaning |
|
|
80
|
+
| ---------- | ------- |
|
|
81
|
+
| `critical` | Merge-blocking; maps to QC **Critical** findings. |
|
|
82
|
+
| `high` | Not blocking but high impact (security, correctness, data, significant tech debt); fix, escalate, or open residual with PM follow-up. |
|
|
83
|
+
| `medium` | Should address this or next milestone; may be open residual. |
|
|
84
|
+
| `low` | Small impact, cheap fix; may be open residual. |
|
|
85
|
+
| `nit` | Style, naming, wording, non-behavior doc nits; **lighter than `low`**. PM may omit from `residual_findings` if no tracking needed. |
|
|
79
86
|
|
|
80
|
-
|
|
81
|
-
| ---------- | ------------------------------------------------------------------------ |
|
|
82
|
-
| `critical` | 合并阻断级;与 QC 报告 **Critical** findings 对应。 |
|
|
83
|
-
| `high` | 非阻断但影响大(安全、正确性、数据、显著技术债);须修复、显式升级决策,或 open residual 并由 PM 明确跟进。 |
|
|
84
|
-
| `medium` | 当前或下一里程碑应处理;可 open residual。 |
|
|
85
|
-
| `low` | 影响面小、修复成本低;可 open residual。 |
|
|
86
|
-
| `nit` | 最低档:风格、命名偏好、措辞、非行为文档笔误等;**轻于 `low`**。PM 判断无需跟踪时可不写入 `residual_findings`。 |
|
|
87
|
+
Summary vs `mstar-review-qc`: unresolved **`critical`** → usually `Request Changes`; **`high`** often “fix or explicit decision before merge”; **`medium` / `low` / `nit`** may ship with residual tracking (final **Verdict** = PM consolidation).
|
|
87
88
|
|
|
89
|
+
### 4. QC report section → JSON `severity`
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
When registering into root **`residual_findings`** (template in `mstar-review-qc`):
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
| Report Findings section | JSON `severity` |
|
|
94
|
+
| ----------------------- | --------------- |
|
|
95
|
+
| **Critical** | Default `critical`. PM may record `high` if “not blocking this merge but follow up soon” — state reason in `title`/`scope`. |
|
|
96
|
+
| **Warning** | `high` or `medium`: security/correctness/data → `high`; other substantive non-blocking → `medium`; **when unsure, use `high`**. |
|
|
97
|
+
| **Suggestion** | `low` or `nit`: substantive improvement → `low`; pure style/optional → `nit`. |
|
|
92
98
|
|
|
93
|
-
|
|
99
|
+
**Common mistake:** report **Warning** is not a valid `severity` string; there is no `warning` in the enum (see legacy below).
|
|
94
100
|
|
|
101
|
+
### 5. Legacy `"severity": "warning"`
|
|
95
102
|
|
|
96
|
-
|
|
97
|
-
| -------------- | --------------------------------------------------------------------------- |
|
|
98
|
-
| **Critical** | 默认 `critical`。若 PM 明确记录「本次不阻断但须尽快跟进」,可记 `high` 并在 `title`/`scope` 写清理由。 |
|
|
99
|
-
| **Warning** | `high` 或 `medium`:偏安全/正确性/数据 → `high`;其它实质性非阻断 → `medium`;**不确定时取 `high`**。 |
|
|
100
|
-
| **Suggestion** | `low` 或 `nit`:有实质改进 → `low`;纯风格/可有可无 → `nit`。 |
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
**易错点**:报告里的 **Warning** 不是合法 `severity` 字符串;合法值里**没有** `warning`(见第 5 节历史兼容)。
|
|
104
|
-
|
|
105
|
-
### 5. 历史数据中的 `"severity": "warning"`
|
|
106
|
-
|
|
107
|
-
旧 JSON 若出现 `**"severity": "warning"`**:读取、汇总、`tech_debt_summary` 统计时**一律视为 `low`**。**禁止**在新条目中使用该值。
|
|
103
|
+
In old JSON, **`"severity": "warning"`** is read and rolled up as **`low`**. **Forbidden** on new entries.
|
|
108
104
|
|
|
109
105
|
---
|
|
110
106
|
|
|
111
|
-
## `plans[].metadata`
|
|
112
|
-
|
|
113
|
-
与业务仓库实践对齐的推荐键(均为可选;项目可只选子集):
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
| 键 | 类型 | 用途 |
|
|
117
|
-
| --------------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
118
|
-
| `working_branch` | string | 本 plan 实现所用分支名,与 Assignment `**Working branch`** 对齐(SSOT) |
|
|
119
|
-
| `spec_integration_branch` | string | (多 Plan 同源 **Spec** 时推荐)该 Spec 对应的 **集成分支** 名;各 Plan 实现分支收口时应 merge 回此线,而非默认直接进 `main`(见 `mstar-plan-conventions` SKILL.md「Spec 文档驱动的分支模型」) |
|
|
120
|
-
| `merge_target` | string | 本 plan 成果 **下一跳** 预期合并到的分支:多 Plan + Spec 模型下 **通常为 `spec_integration_branch`**;最终进 `main` 仍走 **PR**(同 skill)。单 plan / 无 Spec 集成线时可为 `main` 或团队约定名 |
|
|
121
|
-
| `branch_policy` | string | 与 `mstar-harness-core` 一致的一行策略说明(如 `direct on main — <reason>` 或 `create feature/x from main`) |
|
|
122
|
-
| `phase` | string | 程序/路线图阶段标签(如 `Phase 0`、`v1.0`) |
|
|
123
|
-
| `priority` | `high` | `medium` | `low` | PM 编排优先级 |
|
|
124
|
-
| `description` / `scope` | string | 一句话范围或目标;**同一仓库内择一**为主,避免两键长期混填不同内容 |
|
|
125
|
-
| `gates` | object | 门禁结果摘要;**推荐子键**(按需):`qc`、`qa`、`typecheck`、`tests`、`lint`… 值为短字符串(如 `PASS (…)`、`FAIL — see report`) |
|
|
126
|
-
| `blocked_since` | `YYYY-MM-DD` | 当 `status` 为 `Blocked` 时建议填写 |
|
|
127
|
-
| `blocked_reason` | string | 阻塞原因(可与顶层 `notes` 互引,metadata 便于机器过滤) |
|
|
128
|
-
| `blocked_by_plan_id` | string | 若阻塞来自另一计划,填对方 `**plans[].id`** |
|
|
129
|
-
| `dependency` | string | 其它依赖说明(接口、外部团队);与 `blocked_by_plan_id` 互补 |
|
|
130
|
-
| `next_action` | string | 当前解锁后或审查后的下一步(给谁、做什么) |
|
|
131
|
-
| `primary_spec` | string | 主规格/设计文档路径(仓库内相对路径;**常为** `{KNOWLEDGE_DIR}/...` 或 `{SPECS_DIR}/...`,其中 `{SPECS_DIR}` 支持 `specs/` 与 `designs/`);多文档可用 `spec_refs`(string[]) |
|
|
132
|
-
| `iteration_compass` | string | 可选:本轮依赖的迭代/版本 compass(`{ITERATION_DIR}/...`) |
|
|
133
|
-
| `iteration_refs` | string[] | 可选:多个迭代 compass 或 program 快照路径 |
|
|
134
|
-
| `qc_status` / `tests` / `commits` | string | **InReview / Done** 前后的可验证快照(结论摘要、测试统计、commit 提示),**非**替代正式报告文件 |
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
### 建议补充:交付型状态账本(phase + batches + verification)
|
|
107
|
+
## `plans[].metadata` standard optional fields
|
|
138
108
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
| 键 | 类型 | 用途 |
|
|
109
|
+
| Key | Type | Purpose |
|
|
142
110
|
| --- | --- | --- |
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
111
|
+
| `working_branch` | string | Implementation branch; aligns with Assignment **`Working branch`** (SSOT) |
|
|
112
|
+
| `spec_integration_branch` | string | (Multi-plan same **Spec**) integration branch name; plan branches merge here before `main` (`mstar-plan-conventions`) |
|
|
113
|
+
| `merge_target` | string | Next merge target; multi-plan + Spec → usually `spec_integration_branch`; `main` via PR |
|
|
114
|
+
| `branch_policy` | string | One-line policy per `mstar-harness-core` |
|
|
115
|
+
| `phase` | string | Program/roadmap label |
|
|
116
|
+
| `priority` | `high` \| `medium` \| `low` | PM scheduling |
|
|
117
|
+
| `description` / `scope` | string | One-line scope; pick one key per repo |
|
|
118
|
+
| `gates` | object | Gate summary (`qc`, `qa`, `typecheck`, `tests`, `lint`, …) |
|
|
119
|
+
| `blocked_since` | `YYYY-MM-DD` | When `status` is `Blocked` |
|
|
120
|
+
| `blocked_reason` | string | Block reason |
|
|
121
|
+
| `blocked_by_plan_id` | string | Blocking **`plans[].id`** |
|
|
122
|
+
| `dependency` | string | Other dependencies |
|
|
123
|
+
| `next_action` | string | Next step after unblock/review |
|
|
124
|
+
| `primary_spec` | string | Main spec path (`{KNOWLEDGE_DIR}/…`, `{SPECS_DIR}/…`) |
|
|
125
|
+
| `iteration_compass` | string | Optional `{ITERATION_DIR}/…` |
|
|
126
|
+
| `iteration_refs` | string[] | Optional multiple compass paths |
|
|
127
|
+
| `qc_status` / `tests` / `commits` | string | InReview/Done snapshots; not a substitute for `{PLAN_DIR}/reports/` |
|
|
128
|
+
|
|
129
|
+
### Optional delivery ledger (`phase` + `batches` + `verification`)
|
|
130
|
+
|
|
131
|
+
For multi-batch or multi-role plans:
|
|
132
|
+
|
|
133
|
+
| Key | Type | Purpose |
|
|
134
|
+
| --- | --- | --- |
|
|
135
|
+
| `phase` | string | Delivery phase label |
|
|
136
|
+
| `batches` | array\<object\> | Per-batch task coverage, owner, status, commits, self-audit |
|
|
137
|
+
| `verification` | object | Command-level verification snapshot |
|
|
162
138
|
|
|
163
|
-
|
|
164
|
-
- `{HARNESS_DIR}/notes.json`:跨 plan 程序里程碑。
|
|
139
|
+
Recommended `batches[]` subfields: `index`, `covers`, `status`, `owner`, `commits`, `a2_self_audit` (or synonym), `verification`.
|
|
165
140
|
|
|
166
|
-
|
|
141
|
+
> `batches` / `verification` are evidence indexes — not replacements for `{PLAN_DIR}/reports/` or root `residual_findings`.
|
|
167
142
|
|
|
168
|
-
|
|
143
|
+
### `plans[].notes` vs `{HARNESS_DIR}/notes.json`
|
|
169
144
|
|
|
170
|
-
|
|
145
|
+
- `plans[].notes`: per-plan timeline (string array recommended).
|
|
146
|
+
- `{HARNESS_DIR}/notes.json`: cross-plan program milestones.
|
|
171
147
|
|
|
148
|
+
Legacy string `plans[].notes` is OK; new repos should use arrays with time + event + evidence anchor.
|
|
172
149
|
|
|
173
|
-
|
|
174
|
-
| --------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------- |
|
|
175
|
-
| `versioning` | object | 跨 plan 约定,如 `phase_1_branch_prefix`、`release` 等(自由键,团队自定) |
|
|
176
|
-
| `notes` | array | **遗留/不推荐**:曾用于程序级时间线;**新仓库请用** `**{HARNESS_DIR}/notes.json`**,以免 `status.json` 随日志变长。若仍存在,可与 `notes.json` 并存直至迁出 |
|
|
177
|
-
| `residual_findings_history` | object | **遗留/不推荐**:同型剪切区;**新归档请用** `{HARNESS_DIR}/archived/residuals/<plan-id>.json` |
|
|
178
|
-
| `tech_debt_summary` | object | **可选**:技术债**一览/rollup**,与 `**residual_findings` 互补**(见下专节);由 `**@project-manager`** 维护 |
|
|
150
|
+
## Root `metadata` standard optional fields
|
|
179
151
|
|
|
152
|
+
| Key | Type | Purpose |
|
|
153
|
+
| --- | --- | --- |
|
|
154
|
+
| `versioning` | object | Cross-plan conventions (team-defined) |
|
|
155
|
+
| `notes` | array | **Legacy** — prefer **`{HARNESS_DIR}/notes.json`** |
|
|
156
|
+
| `residual_findings_history` | object | **Legacy** — prefer **`archived/residuals/<plan-id>.json`** |
|
|
157
|
+
| `tech_debt_summary` | object | Optional rollup over open R#; maintain via script (below) |
|
|
180
158
|
|
|
181
|
-
##
|
|
159
|
+
## General constraints
|
|
182
160
|
|
|
183
|
-
-
|
|
184
|
-
-
|
|
185
|
-
-
|
|
186
|
-
-
|
|
187
|
-
-
|
|
161
|
+
- Each `plans[]` row may include optional **`metadata`** (`{}` or omit).
|
|
162
|
+
- Init with `"residual_findings": {}`; **no dual-write** with legacy side (see SKILL.md). Program timeline → **`notes.json`**, not long `metadata.notes` in `status.json`.
|
|
163
|
+
- **`plans[].id`** keys must align with root **`residual_findings`** keys (and `reports/<plan-id>/`). Do not store `residual_findings_plan_id`.
|
|
164
|
+
- **Empty `plan-id` key:** when no open items remain, **delete** the key from root **`residual_findings`** (and legacy side if present) — no `"plan-id": []`. Whether **`plans[]`** keeps the row is separate (`done-compaction.md`).
|
|
165
|
+
- **`residual_summary` (optional):** one-line human summary of **open** items only.
|
|
188
166
|
|
|
189
167
|
---
|
|
190
168
|
|
|
191
|
-
## Residual findings
|
|
192
|
-
|
|
193
|
-
本节约定技术债条目在**已修复、已豁免、被替代或误登**之后如何更新 JSON,与「登记」流程闭环。
|
|
169
|
+
## Residual findings lifecycle (close, archive, remove)
|
|
194
170
|
|
|
195
|
-
###
|
|
171
|
+
### `lifecycle` (optional; default open)
|
|
196
172
|
|
|
173
|
+
| `lifecycle` | Meaning | `closure_note` should explain |
|
|
174
|
+
| ----------- | ------- | ----------------------------- |
|
|
175
|
+
| `open` | Not closed (omit field = open) | — |
|
|
176
|
+
| `resolved` | Fixed in code/config/docs and **verified** | What changed; how verified |
|
|
177
|
+
| `waived` | Explicit decision not to fix | Who decided; why; optional `tracking` Issue |
|
|
178
|
+
| `superseded` | Replaced by new finding/spec/refactor | `superseded_by` |
|
|
179
|
+
| `duplicate` | Duplicate of another R# | Canonical `id` or mistake note |
|
|
197
180
|
|
|
198
|
-
|
|
199
|
-
| ------------ | ------------------------------ | ----------------------------------- |
|
|
200
|
-
| `open` | 未关闭(**省略该字段时按 open 处理**,兼容旧数据) | — |
|
|
201
|
-
| `resolved` | 已在代码/配置/文档中解决,且**已验证** | 改了什么、如何验证(可与 `closure_evidence` 互指) |
|
|
202
|
-
| `waived` | 经明确决策**不修复**(承担风险或产品接受) | 谁决策、为何不修、是否登记 `tracking` Issue |
|
|
203
|
-
| `superseded` | 被新 finding、新规格或重构方案取代 | 指向 `superseded_by`(另一条 `id` 或知识库路径) |
|
|
204
|
-
| `duplicate` | 重复录入或与另一 R# 实质相同 | 指向 canonical 的 `id` 或说明误登 |
|
|
181
|
+
**On close:** set **`closed_at`** (`YYYY-MM-DD`) and **`closure_note`**; recommend **`closure_evidence`** (PR, commit, test, doc anchor).
|
|
205
182
|
|
|
183
|
+
### Who updates when
|
|
206
184
|
|
|
207
|
-
|
|
185
|
+
| Action | Owner | When |
|
|
186
|
+
| ------ | ----- | ---- |
|
|
187
|
+
| Implement fix | `@fullstack-dev` / assignee | Completion Report cites R# + evidence |
|
|
188
|
+
| Verify | `@qa-engineer` | Regression / acceptance |
|
|
189
|
+
| Write `status.json` | **`@project-manager`** or **`@qa-engineer`** | After verification; waivers after PM + user/architect alignment |
|
|
208
190
|
|
|
209
|
-
|
|
191
|
+
Do not claim “R3 fixed” in chat/plan only without SSOT update.
|
|
210
192
|
|
|
193
|
+
PM should register open items after **`Approve with residuals`**; QA should state each related R# (open / resolved this round / needs waiver).
|
|
211
194
|
|
|
212
|
-
|
|
213
|
-
| ---------------- | ---------------------------------------------------------- | ------------------------------------ |
|
|
214
|
-
| 实现修复 | `@fullstack-dev` / 对应 owner | Completion Report 中说明对应 R# 与证据 |
|
|
215
|
-
| 验证 | `@qa-engineer` | 回归或验收中确认 R# 已满足 |
|
|
216
|
-
| 写回 `status.json` | `**@project-manager**` 或 `**@qa-engineer**`(与 Done 收口权限一致) | 验证通过后同一提交或紧随其后;豁免/替代由 PM 与用户或架构对齐后写回 |
|
|
195
|
+
### Recommended: archive to `archived/residuals/<plan-id>.json`
|
|
217
196
|
|
|
197
|
+
After **`closed_at`**, **`closure_note`**, and PM/QA confirm close:
|
|
218
198
|
|
|
219
|
-
|
|
199
|
+
1. **Append** to **`{HARNESS_DIR}/archived/residuals/<plan-id>.json`**.
|
|
200
|
+
2. **Remove** from open list (root **`residual_findings[<plan-id>]`**; legacy side if used). Delete empty **`plan-id`** keys.
|
|
201
|
+
3. Update root **`updated_at`**; optional milestone in **`notes.json`**.
|
|
220
202
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
### 推荐策略:关闭后迁入 `archived/residuals/<plan-id>.json`(控制 `status.json` 体积)
|
|
224
|
-
|
|
225
|
-
为避免 `**status.json` 随已关闭 R# 无限膨胀**,在 `**closed_at` / `closure_note`(及推荐 `closure_evidence`)已齐备** 且 `**@qa-engineer`** 或 `**@project-manager**` 已确认可关闭后:
|
|
226
|
-
|
|
227
|
-
1. **追加**到 `**{HARNESS_DIR}/archived/residuals/<plan-id>.json`**(文件名与 `**plans[].id**` 一致;遗留同目录布局下全路径可能为 `**plans/archived/residuals/<plan-id>.json**` 等,视解析结果而定)。
|
|
228
|
-
2. 从 **open 列表**(根级 **`residual_findings[<plan-id>]`**,条目若仅存于 legacy 侧则从该处)**删除**该条(主列表**只保留 open**)。若删除后该数组为空,**删除**对应的 `**plan-id` 键(见上文「空键」约定)。
|
|
229
|
-
3. 更新根级 `**updated_at`**;可选在 `**{HARNESS_DIR}/notes.json**` 追加一条里程碑(**优先**于根级 `metadata.notes`,见「`notes.json`」专节)。
|
|
230
|
-
|
|
231
|
-
**归档文件格式**(每个 `plan-id` 一个 JSON 文件,可多次追加 `entries`):
|
|
203
|
+
Archive file shape (append to `entries`):
|
|
232
204
|
|
|
233
205
|
```json
|
|
234
206
|
{
|
|
@@ -237,14 +209,7 @@ QC 报告模板见 `mstar-review-qc`。把 finding 登记进根级 `**residual_f
|
|
|
237
209
|
"entries": [
|
|
238
210
|
{
|
|
239
211
|
"id": "R1",
|
|
240
|
-
"title": "…",
|
|
241
212
|
"severity": "medium",
|
|
242
|
-
"source": "QC-#1",
|
|
243
|
-
"scope": "…",
|
|
244
|
-
"decision": "defer",
|
|
245
|
-
"owner": "@fullstack-dev",
|
|
246
|
-
"target": "…",
|
|
247
|
-
"tracking": null,
|
|
248
213
|
"lifecycle": "resolved",
|
|
249
214
|
"closed_at": "2026-04-06",
|
|
250
215
|
"closure_note": "…",
|
|
@@ -255,100 +220,88 @@ QC 报告模板见 `mstar-review-qc`。把 finding 登记进根级 `**residual_f
|
|
|
255
220
|
}
|
|
256
221
|
```
|
|
257
222
|
|
|
258
|
-
-
|
|
259
|
-
-
|
|
260
|
-
-
|
|
261
|
-
- **一览**:若使用 `**metadata.tech_debt_summary`**,批量归档或关闭后应**刷新**聚合数字,与仍 open 的 R# 对齐(见「`metadata.tech_debt_summary`」专节)。
|
|
262
|
-
|
|
263
|
-
### 临时原位关闭(仅短过渡)
|
|
223
|
+
- Each archived entry needs **`archived_at`** (`YYYY-MM-DD`).
|
|
224
|
+
- Closed records live in archive + QC `reports/`; not in open list.
|
|
225
|
+
- After batch archive/close, **refresh `tech_debt_summary`** (script below).
|
|
264
226
|
|
|
265
|
-
|
|
227
|
+
### Short in-place close (transition only)
|
|
266
228
|
|
|
267
|
-
|
|
229
|
+
May set `lifecycle` / `closed_*` in open list for one PR; **same milestone** move to archive + delete from open list.
|
|
268
230
|
|
|
269
|
-
|
|
231
|
+
### Legacy `metadata.residual_findings_history`
|
|
270
232
|
|
|
271
|
-
|
|
233
|
+
Prefer **`archived/residuals/`**; migrate and delete history key when possible.
|
|
272
234
|
|
|
273
|
-
|
|
274
|
-
- 已归档条目**不要**从 `archived/residuals/*.json` **删除**;错关时追加更正说明条目或新开 R# 引用原 `id`。
|
|
275
|
-
- 仅**误登且未进入任何留档**时,经 `**@project-manager`** 可从 `residual_findings` 删除;更稳妥为标 `**duplicate**` 后走关闭归档流程。
|
|
235
|
+
### Hard delete
|
|
276
236
|
|
|
277
|
-
|
|
237
|
+
- **Forbidden** for **open** entries.
|
|
238
|
+
- Do not delete archived entries; correct via new entry or new R# referencing old `id`.
|
|
239
|
+
- Mistaken open-only entry: PM may delete or mark **`duplicate`** then close/archive.
|
|
278
240
|
|
|
279
|
-
|
|
241
|
+
### Query open and archived (examples)
|
|
280
242
|
|
|
281
243
|
```bash
|
|
244
|
+
# Replace .agents with your resolved {HARNESS_DIR}.
|
|
282
245
|
jq '.residual_findings["01-data-infrastructure"] // .metadata.residual_findings["01-data-infrastructure"]' .agents/status.json
|
|
283
246
|
jq '.entries[] | select(.id == "R1")' .agents/archived/residuals/01-data-infrastructure.json
|
|
284
|
-
|
|
247
|
+
bash skills/mstar-plan-artifacts/scripts/tech-debt-rollup.sh .agents/status.json
|
|
285
248
|
```
|
|
286
249
|
|
|
287
|
-
|
|
250
|
+
(`//` right-hand side = legacy read path.)
|
|
288
251
|
|
|
289
|
-
|
|
252
|
+
---
|
|
290
253
|
|
|
291
|
-
|
|
254
|
+
## `{HARNESS_DIR}/notes.json` (optional program timeline)
|
|
292
255
|
|
|
293
|
-
|
|
256
|
+
Append-only log for merge closure, batch archive, `tech_debt_summary` refresh, etc. Does not compete with **`plans[].status`** / open residual SSOT.
|
|
294
257
|
|
|
295
258
|
```json
|
|
296
259
|
{
|
|
297
260
|
"schema_version": 1,
|
|
298
261
|
"updated_at": "YYYY-MM-DD",
|
|
299
262
|
"entries": [
|
|
300
|
-
{
|
|
301
|
-
"at": "2026-04-08",
|
|
302
|
-
"message": "Short milestone description",
|
|
303
|
-
"plan_id": "01-data-infrastructure"
|
|
304
|
-
}
|
|
263
|
+
{ "at": "2026-04-08", "message": "Short milestone", "plan_id": "01-data-infrastructure" }
|
|
305
264
|
]
|
|
306
265
|
}
|
|
307
266
|
```
|
|
308
267
|
|
|
309
|
-
- `**
|
|
310
|
-
-
|
|
311
|
-
- **维护**:`**@project-manager`**(与写回 `status.json` 同权限节奏)。**禁止**为「改历史叙述」而重写已提交条目正文;更正走**新 `entries` 条**说明勘误。
|
|
312
|
-
- **与 `plans[].notes`**:`plans[].notes` 仍是**单条计划**的短字符串(可选);本文件承载**跨计划 / 跨里程碑**的日志,二者不重复长文。
|
|
268
|
+
- **`@project-manager`** maintains; do not rewrite past `entries` — add correction as new entry.
|
|
269
|
+
- **`plans[].notes`**: per-plan; **`notes.json`**: cross-plan.
|
|
313
270
|
|
|
314
271
|
---
|
|
315
272
|
|
|
316
|
-
## `metadata.tech_debt_summary
|
|
273
|
+
## `metadata.tech_debt_summary` (optional rollup)
|
|
317
274
|
|
|
318
|
-
|
|
275
|
+
**Role:** Cross-plan aggregate over **open** R# in root **`residual_findings`** (and legacy read path if present). Does **not** replace per-entry SSOT.
|
|
319
276
|
|
|
320
|
-
|
|
277
|
+
**Compute (canonical):** run the read-only script (do **not** hand-count):
|
|
321
278
|
|
|
322
|
-
|
|
279
|
+
```bash
|
|
280
|
+
# From repo root; pass path to status.json if not .agents/status.json
|
|
281
|
+
bash skills/mstar-plan-artifacts/scripts/tech-debt-rollup.sh .agents/status.json
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
- Prints computed `total_open`, `by_severity`, `by_target`, `by_plan`.
|
|
285
|
+
- Prints **PASS** / **DRIFT** vs stored `metadata.tech_debt_summary`.
|
|
286
|
+
- Script **does not write** `status.json` — PM copies computed values into `metadata.tech_debt_summary` after DRIFT or milestone refresh.
|
|
287
|
+
|
|
288
|
+
**When to refresh:** after QC waves, batch archive of resolved items, or release freeze. Optional `notes.json` entry: “refreshed tech_debt_summary”.
|
|
289
|
+
|
|
290
|
+
**Recommended stored shape** (`cross_cutting` optional; script does not compute `cross_cutting` — maintain manually if used):
|
|
323
291
|
|
|
324
292
|
```json
|
|
325
293
|
{
|
|
326
294
|
"tech_debt_summary": {
|
|
327
295
|
"updated_at": "YYYY-MM-DD",
|
|
328
296
|
"total_open": 29,
|
|
329
|
-
"by_severity": {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
"medium": 10,
|
|
333
|
-
"low": 5,
|
|
334
|
-
"nit": 1
|
|
335
|
-
},
|
|
336
|
-
"by_target": {
|
|
337
|
-
"V1.0": 5,
|
|
338
|
-
"V1.1": 18
|
|
339
|
-
},
|
|
340
|
-
"by_plan": {
|
|
341
|
-
"domain-models": 4,
|
|
342
|
-
"cli-daemon-foundation": 11,
|
|
343
|
-
"cross-cutting": 1
|
|
344
|
-
},
|
|
297
|
+
"by_severity": { "critical": 0, "high": 10, "medium": 10, "low": 5, "nit": 1 },
|
|
298
|
+
"by_target": { "V1.0": 5, "V1.1": 18 },
|
|
299
|
+
"by_plan": { "domain-models": 4, "cli-daemon-foundation": 11 },
|
|
345
300
|
"cross_cutting": [
|
|
346
301
|
{
|
|
347
302
|
"id": "DEBT-X1",
|
|
348
|
-
"title": "
|
|
303
|
+
"title": "Cross-plan theme",
|
|
349
304
|
"severity": "high",
|
|
350
|
-
"scope": "crates/foo, crates/bar",
|
|
351
|
-
"target": "V1.1 — unified strategy",
|
|
352
305
|
"relates_to": ["CLI-R9", "SYNC-R4"]
|
|
353
306
|
}
|
|
354
307
|
]
|
|
@@ -356,39 +309,30 @@ jq '.metadata.tech_debt_summary' .agents/status.json
|
|
|
356
309
|
}
|
|
357
310
|
```
|
|
358
311
|
|
|
359
|
-
- `**
|
|
360
|
-
-
|
|
361
|
-
- `**cross_cutting`**:用于**跨多 plan / 多条 R#** 的主题债(架构层、重复实现等);`**relates_to`** 列出对应 `**id**`(与 `residual_findings` 内 R# 对齐),避免与单条 R# 重复叙述时可只在此处保留总述。
|
|
312
|
+
- **`by_plan`** keys: short labels or `plans[].id` prefixes per repo convention.
|
|
313
|
+
- **`cross_cutting`**: themes spanning plans/R#; explain intentional count differences in `notes.json` or here.
|
|
362
314
|
|
|
363
315
|
---
|
|
364
316
|
|
|
365
|
-
##
|
|
317
|
+
## Pre-merge: `status.json` should match reality
|
|
366
318
|
|
|
367
|
-
|
|
319
|
+
Before merge/PR, **`@project-manager`** (or delegate) should verify: `plans[].status`, `metadata.gates`, root **`residual_findings`** (no accidental dual-write), **`tech_debt_summary`** (if used — run script), **`notes.json`** (if used), vs review/CI.
|
|
368
320
|
|
|
369
|
-
|
|
321
|
+
**Common gaps:**
|
|
370
322
|
|
|
371
|
-
-
|
|
372
|
-
-
|
|
373
|
-
-
|
|
323
|
+
- R# added/closed but **`tech_debt_summary` not refreshed** (script shows DRIFT).
|
|
324
|
+
- Finding only in **`plans[].notes`** or chat, not in **`residual_findings[<plan-id>]`**.
|
|
325
|
+
- Major milestone with no **`notes.json`** entry when team uses program timeline.
|
|
374
326
|
|
|
375
|
-
##
|
|
327
|
+
## Compatibility: plan key names
|
|
376
328
|
|
|
377
|
-
|
|
329
|
+
- Read: accept `id` or `plan_id`.
|
|
330
|
+
- Write: one canonical key (prefer `id`).
|
|
331
|
+
- Document canonical key in `.agents/AGENTS.md` if migrating.
|
|
378
332
|
|
|
379
|
-
|
|
380
|
-
- 写回时只写一种(推荐 `id`);
|
|
381
|
-
- 与目录键(如 `reports/<plan-id>/`、`residual_findings[<plan-id>]`)保持同一 canonical 值。
|
|
382
|
-
|
|
383
|
-
若短期不迁移,至少在仓库的 `.agents/AGENTS.md` 写清“canonical key 使用哪一个”,避免多 agent 混写。
|
|
384
|
-
|
|
385
|
-
## 常用查询示例
|
|
386
|
-
|
|
387
|
-
第二条 `jq` 中 `//` 右侧含义见上文「**查询 open 项与已归档(示例)**」。
|
|
333
|
+
## Common queries
|
|
388
334
|
|
|
389
335
|
```bash
|
|
390
|
-
# Replace .agents with your resolved {HARNESS_DIR} if different.
|
|
391
336
|
jq '.plans[] | select(.id == "01-data-infrastructure")' .agents/status.json
|
|
392
337
|
jq '.residual_findings["01-data-infrastructure"] // .metadata.residual_findings["01-data-infrastructure"]' .agents/status.json
|
|
393
338
|
```
|
|
394
|
-
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Read-only rollup of open residual_findings into tech_debt_summary aggregates.
|
|
3
|
+
# Does not write status.json — PM applies output manually.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
STATUS_FILE="${1:-.agents/status.json}"
|
|
7
|
+
|
|
8
|
+
if [[ ! -f "$STATUS_FILE" ]]; then
|
|
9
|
+
echo "error: status file not found: $STATUS_FILE" >&2
|
|
10
|
+
exit 1
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
14
|
+
echo "error: jq is required" >&2
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# Merge canonical + legacy maps (canonical keys win). Legacy "warning" -> low.
|
|
19
|
+
# Skip entries with lifecycle != open (default open when omitted).
|
|
20
|
+
read -r -d '' JQ_FILTER <<'JQEOF' || true
|
|
21
|
+
def norm_sev:
|
|
22
|
+
if . == "warning" then "low"
|
|
23
|
+
elif . == null or . == "" then "medium"
|
|
24
|
+
else .
|
|
25
|
+
end;
|
|
26
|
+
|
|
27
|
+
def is_open:
|
|
28
|
+
(.lifecycle // "open") == "open";
|
|
29
|
+
|
|
30
|
+
(.residual_findings // {}) as $canon
|
|
31
|
+
| (.metadata.residual_findings // {}) as $legacy
|
|
32
|
+
| ($canon + $legacy) as $merged
|
|
33
|
+
| [
|
|
34
|
+
$merged
|
|
35
|
+
| to_entries[]
|
|
36
|
+
| .key as $plan
|
|
37
|
+
| .value[]
|
|
38
|
+
| select(is_open)
|
|
39
|
+
| . + { _plan_id: $plan }
|
|
40
|
+
] as $items
|
|
41
|
+
| {
|
|
42
|
+
total_open: ($items | length),
|
|
43
|
+
by_severity: (
|
|
44
|
+
["critical", "high", "medium", "low", "nit"]
|
|
45
|
+
| map(. as $s
|
|
46
|
+
| { ($s): ([$items[] | select((.severity | norm_sev) == $s)] | length) })
|
|
47
|
+
| add
|
|
48
|
+
),
|
|
49
|
+
by_target: (
|
|
50
|
+
$items
|
|
51
|
+
| map(.target // "unspecified")
|
|
52
|
+
| group_by(.)
|
|
53
|
+
| map({ key: .[0], value: length })
|
|
54
|
+
| from_entries
|
|
55
|
+
),
|
|
56
|
+
by_plan: (
|
|
57
|
+
$items
|
|
58
|
+
| group_by(._plan_id)
|
|
59
|
+
| map({ key: .[0]._plan_id, value: length })
|
|
60
|
+
| from_entries
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
JQEOF
|
|
64
|
+
|
|
65
|
+
COMPUTED=$(jq -c "$JQ_FILTER" "$STATUS_FILE")
|
|
66
|
+
STORED=$(jq -c '.metadata.tech_debt_summary // null' "$STATUS_FILE")
|
|
67
|
+
|
|
68
|
+
echo "=== tech_debt_summary (computed from open residual_findings) ==="
|
|
69
|
+
echo "$COMPUTED" | jq '.'
|
|
70
|
+
|
|
71
|
+
echo ""
|
|
72
|
+
echo "=== stored metadata.tech_debt_summary ==="
|
|
73
|
+
if [[ "$STORED" == "null" ]]; then
|
|
74
|
+
echo "(none)"
|
|
75
|
+
else
|
|
76
|
+
echo "$STORED" | jq '.'
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
echo ""
|
|
80
|
+
echo "=== consistency check ==="
|
|
81
|
+
|
|
82
|
+
compare_field() {
|
|
83
|
+
local field="$1"
|
|
84
|
+
local computed stored
|
|
85
|
+
computed=$(echo "$COMPUTED" | jq -c ".$field")
|
|
86
|
+
if [[ "$STORED" == "null" ]]; then
|
|
87
|
+
echo "DRIFT: no stored tech_debt_summary (computed $field = $computed)"
|
|
88
|
+
return 1
|
|
89
|
+
fi
|
|
90
|
+
stored=$(echo "$STORED" | jq -c ".$field // null")
|
|
91
|
+
if [[ "$computed" == "$stored" ]]; then
|
|
92
|
+
echo "PASS: $field"
|
|
93
|
+
return 0
|
|
94
|
+
fi
|
|
95
|
+
echo "DRIFT: $field"
|
|
96
|
+
echo " computed: $computed"
|
|
97
|
+
echo " stored: $stored"
|
|
98
|
+
return 1
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
FAIL=0
|
|
102
|
+
compare_field total_open || FAIL=1
|
|
103
|
+
compare_field by_severity || FAIL=1
|
|
104
|
+
compare_field by_target || FAIL=1
|
|
105
|
+
compare_field by_plan || FAIL=1
|
|
106
|
+
|
|
107
|
+
if [[ "$FAIL" -eq 0 ]]; then
|
|
108
|
+
echo ""
|
|
109
|
+
echo "OVERALL: PASS"
|
|
110
|
+
exit 0
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
echo ""
|
|
114
|
+
echo "OVERALL: DRIFT — refresh metadata.tech_debt_summary in status.json"
|
|
115
|
+
exit 1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Plan harness file templates
|
|
2
2
|
|
|
3
|
-
Copy these into `{HARNESS_DIR}` when bootstrapping a project. Path symbols (`{HARNESS_DIR}`, `{PLAN_DIR}`, …) → **`mstar-plan-conventions`**. Field semantics and residual lifecycle → **`mstar-plan-artifacts/references/status-and-residuals.md`**.
|
|
3
|
+
Copy these into `{HARNESS_DIR}` when bootstrapping a project. Path symbols (`{HARNESS_DIR}`, `{PLAN_DIR}`, …) → **`mstar-plan-conventions`**. Field semantics and residual lifecycle → **`mstar-plan-artifacts/references/status-and-residuals.md`**. Optional rollup: **`../scripts/tech-debt-rollup.sh`** (read-only; see that reference).
|
|
4
4
|
|
|
5
5
|
| File | Copy to | Notes |
|
|
6
6
|
|------|---------|--------|
|
|
@@ -37,35 +37,41 @@ When multiple routes apply, set one `Primary` route in Assignment and treat othe
|
|
|
37
37
|
|
|
38
38
|
## Dev Triangle Balance (`fullstack-dev` / `fullstack-dev-2` / `frontend-dev`)
|
|
39
39
|
|
|
40
|
+
### Default: spread backend/fullstack work across both tracks
|
|
41
|
+
|
|
42
|
+
When **>=2 independent** backend/fullstack units exist (on the task board or across sequential batches):
|
|
43
|
+
|
|
44
|
+
- **Parallel (preferred)** when units are parallelizable: dispatch **`fullstack-dev` + `fullstack-dev-2`** with explicit module boundaries and branch/worktree isolation.
|
|
45
|
+
- **Sequential rotation** when work is not concurrent: alternate `Execute as` between `fullstack-dev` and `fullstack-dev-2` by task/batch order (round-robin).
|
|
46
|
+
|
|
47
|
+
**Independence gate:** do **not** split genuinely dependent or sequential work across two dev IDs just to use both tracks.
|
|
48
|
+
|
|
49
|
+
**Single-id path needs justification:** collapsing >=2 independent units onto one backend-capable dev id requires `Dev owner tie-break: single id — <reason>` and Pre-Implement `single_stream_justified: yes` with that reason.
|
|
50
|
+
|
|
40
51
|
### When `frontend-dev` is required
|
|
41
52
|
|
|
42
53
|
- Task category is `visual`, or acceptance depends on page/component/interaction/a11y/frontend performance.
|
|
43
54
|
- UI-bearing fullstack work defaults to split ownership (`frontend-dev` for UI, `fullstack-dev` for API/domain).
|
|
44
55
|
|
|
45
|
-
### When `fullstack-dev-2` is required
|
|
56
|
+
### When `fullstack-dev-2` is required (concurrent dual-track)
|
|
46
57
|
|
|
47
58
|
Use a second implementation track when **any** applies:
|
|
48
59
|
|
|
49
60
|
- Task board has >=2 independently parallelizable implementation units.
|
|
50
61
|
- Medium+ fullstack scope and PM/user expects wall-clock acceleration.
|
|
51
|
-
-
|
|
62
|
+
- One fullstack track is overloaded while another independent module exists.
|
|
52
63
|
|
|
53
64
|
### `single-stream` clarification
|
|
54
65
|
|
|
55
|
-
`Dev routing: single-stream` means no concurrent multi-write dev tracks in this round
|
|
66
|
+
`Dev routing: single-stream` means no concurrent multi-write dev tracks **in this round**.
|
|
56
67
|
It does **not** force all future batches to one fixed developer ID.
|
|
57
68
|
|
|
58
|
-
###
|
|
59
|
-
|
|
60
|
-
If multiple equivalent non-UI units can be assigned to either `fullstack-dev` or `fullstack-dev-2`,
|
|
61
|
-
default owner tie-break is round-robin by task order unless there is a documented override reason.
|
|
62
|
-
|
|
63
|
-
Allowed override reasons:
|
|
69
|
+
### Allowed override to single backend-capable dev id
|
|
64
70
|
|
|
65
71
|
- User explicitly locks owner
|
|
66
|
-
- Module ownership/continuity
|
|
72
|
+
- Module ownership / continuity on one track
|
|
67
73
|
- Hotfix stop-bleeding
|
|
68
|
-
- Only one active write track in this round
|
|
74
|
+
- Only one active write track in this round (true dependency, not preference)
|
|
69
75
|
|
|
70
76
|
Document override as `Dev owner tie-break: single id — <reason>`.
|
|
71
77
|
|
|
@@ -73,6 +73,8 @@ Pick one `Primary` route per Assignment; attach additional gates as needed.
|
|
|
73
73
|
Detailed conflict priority and dev allocation:
|
|
74
74
|
`references/project-manager/routing-and-dev-allocation.md`.
|
|
75
75
|
|
|
76
|
+
**Dev spread default:** when the task board has **>=2 independent** backend/fullstack units, prefer **`fullstack-dev` + `fullstack-dev-2`** (parallel with boundaries) or **round-robin** owners across sequential batches. Using a single backend-capable dev id for multiple independent units requires documented justification (`single_stream_justified` in Pre-Implement Gate Check).
|
|
77
|
+
|
|
76
78
|
---
|
|
77
79
|
|
|
78
80
|
## Non-Bypass Constraints
|
|
@@ -129,6 +131,10 @@ Before first implement dispatch (non-hotfix):
|
|
|
129
131
|
|
|
130
132
|
If any fail -> do not dispatch implement.
|
|
131
133
|
|
|
134
|
+
### Autonomous Execute (sessions entered via `/pm`)
|
|
135
|
+
|
|
136
|
+
After first **implement** dispatch with **GO**, continuously drive the **active iteration** backlog (possibly **multiple** `plan_id`s) through implement → InReview → Done. Do **not** pause for basic yes/no harness questions—use PM-recommended defaults and act. Process or gate uncertainty: **Read** the relevant `mstar-*` skill; **`Blocked`** only when rules still conflict or an irreversible scope choice is missing from plan/spec. Full rules: `skills/pm/SKILL.md` § **Autonomous Execute push**.
|
|
137
|
+
|
|
132
138
|
---
|
|
133
139
|
|
|
134
140
|
## Phase Routing Pre-Flight (Mandatory)
|
|
@@ -170,6 +176,7 @@ Anti-patterns:
|
|
|
170
176
|
- Q10: Is Delegation consistent with Superpowers usage?
|
|
171
177
|
- Q11: For non-trivial plan, is PM Task Board published with coverage?
|
|
172
178
|
- Q12: In invoke-based hosts, were matching invokes actually issued?
|
|
179
|
+
- Q13: With **>=2 independent** backend/fullstack units, are owners spread across `fullstack-dev` and `fullstack-dev-2` (parallel or rotated), or is `single_stream_justified: yes` recorded with a real reason?
|
|
173
180
|
|
|
174
181
|
---
|
|
175
182
|
|
|
@@ -202,6 +209,7 @@ Hard block when:
|
|
|
202
209
|
- Non-trivial plan has required field = `no`
|
|
203
210
|
- Harness-active non-hotfix flow lacks on-disk main plan or status registration
|
|
204
211
|
- `Task category: quick` is used on non-trivial work
|
|
212
|
+
- **>=2 independent** backend/fullstack units on the task board but `single_stream_justified: no` with no spread across `fullstack-dev` / `fullstack-dev-2` and no documented single-id override
|
|
205
213
|
|
|
206
214
|
---
|
|
207
215
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pm
|
|
3
|
-
description: "Force
|
|
3
|
+
description: "Force Morning Star PM mode (`/pm`): load `mstar-harness-core`, run as `project-manager`, and after Execute starts continuously drive one iteration's pending work (possibly multiple plans) with PM-default decisions—no basic yes/no prompts; resolve process rules from `mstar-*` skills. Read `mstar-review-qc` before any QC dispatch."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Project-Manager Force Entry (`/pm`)
|
|
@@ -23,10 +23,22 @@ If this session runs in Cursor **Plan mode**:
|
|
|
23
23
|
3. **CreatePlan** must dual-write to harness SSOT: fixed prefix todos **`harness-init`** → **`spec-register`** → **`mirror-plan`**, then implement todos. Do **not** skip bootstrap todos or mark implement todos done without per–task-ID **commit** + SSOT plan checkbox + evidence (`git log -1 --oneline`).
|
|
24
24
|
4. Before **SwitchMode → Agent**, verify mirror plan file and `status.json` `plan_id` registration per the bridge reference.
|
|
25
25
|
|
|
26
|
+
## Autonomous Execute push (iteration driver)
|
|
27
|
+
|
|
28
|
+
Once **Execute** has started (`plan` locked, `tasks` ready, **Pre-implement Gate Check** = `GO`):
|
|
29
|
+
|
|
30
|
+
1. **Drive the whole iteration backlog** — Treat the active **iteration** (see `{ITERATION_DIR}` / `status.json` `iteration_*` when present) as the unit of forward motion. **Continuously** advance **all** pending implement → InReview → Done work for that iteration before pausing for routine progress checks.
|
|
31
|
+
2. **Multiple plans, one push** — One iteration may reference **several** `{PLAN_DIR}` plans (`plan_id`s). Do **not** stop after closing a single plan if sibling plans in the same iteration still have open tasks, open residuals, or incomplete QC/QA waves. Use **`mstar-plan-artifacts`** + **`references/project-manager/plan-management.md`** for status/residual sync across plans.
|
|
32
|
+
3. **Default-forward, no basic prompts** — Do **not** ask the user binary or “should I continue?” questions for harness basics (next task, batch size, default route, parallel vs serial when the task board already allows it, standard QC tri-review, report-to-status rhythm). **Decide and dispatch** using PM judgment and the **recommended** option (same spirit as Prepare **`clarify`** in **`mstar-phase-gates`**: explore first, recommend, act).
|
|
33
|
+
4. **Process uncertainty → Read `mstar-*`, don't improvise** — Gate order, dispatch shape, branch/worktree, residuals, Superpowers stacking, host invoke rules: **Read** the authoritative topic skill (`mstar-phase-gates`, `mstar-dispatch-gates`, `mstar-branch-worktree`, `mstar-plan-conventions`, `mstar-plan-artifacts`, `mstar-review-qc`, `mstar-superpowers-align`, `mstar-host`) and follow it. Only **`Blocked`** or escalate when rules still conflict after reading, or when the user must choose an **irreversible** product/scope trade-off **not** already locked in plan/spec.
|
|
34
|
+
5. **Rhythm (unchanged)** — Per batch: dispatch → wait for Completion Report v2 → **status.json** + plan sync → next dispatch. Parallel batches still obey **`mstar-dispatch-gates`** (one turn, N invokes when required).
|
|
35
|
+
|
|
36
|
+
**Still ask the user** when: explicit user stop/redirect; true **`Blocked`** after harness lookup; missing secrets/credentials; or a high-impact ambiguity that **cannot** be resolved from repo/spec/plan and would change acceptance materially.
|
|
37
|
+
|
|
26
38
|
## Operating baseline
|
|
27
39
|
|
|
28
40
|
- Prefer **`specify → clarify → plan → tasks → delegate`** (align with `mstar-phase-gates`; do not skip `specify`).
|
|
29
|
-
-
|
|
41
|
+
- After Execute starts, follow **Autonomous Execute push** above — coordinate and **keep dispatching** until the iteration backlog is done or legitimately **`Blocked`**.
|
|
30
42
|
- Before dispatching any QC task, read `mstar-review-qc` (and relevant references) in the current round.
|
|
31
43
|
- Require evidence before completion claims.
|
|
32
44
|
- Treat `mstar-harness-core` as SSOT for gates, routing, and delivery loop.
|