@mstar-harness/opencode 1.8.8 → 2.0.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/CHANGELOG.md +30 -2
- package/README.md +10 -0
- package/dist/mstar.js +561 -0
- package/harness-commands/iteration-drive.md +18 -2
- package/harness-commands/iteration-loop.md +16 -0
- package/harness-commands/iteration-start.md +16 -0
- package/harness-skills/mstar-audit/SKILL.md +2 -0
- package/harness-skills/mstar-branch-worktree/SKILL.md +4 -0
- package/harness-skills/mstar-coding-behavior/SKILL.md +5 -0
- package/harness-skills/mstar-compound/SKILL.md +2 -0
- package/harness-skills/mstar-compound-refresh/SKILL.md +2 -0
- package/harness-skills/mstar-design-md/SKILL.md +2 -0
- package/harness-skills/mstar-design-md/templates/DESIGN.dark.md.template +5 -0
- package/harness-skills/mstar-design-md/templates/DESIGN.md.template +5 -0
- package/harness-skills/mstar-dispatch-gates/SKILL.md +6 -0
- package/harness-skills/mstar-host/SKILL.md +4 -0
- package/harness-skills/mstar-iteration/SKILL.md +14 -5
- package/harness-skills/mstar-iteration/references/phase-2-worktree-lease.md +2 -0
- package/harness-skills/mstar-iteration/references/phase-4-5-pr-delivery.md +5 -2
- package/harness-skills/mstar-phase-gates/SKILL.md +2 -0
- package/harness-skills/mstar-plan-artifacts/SKILL.md +13 -2
- package/harness-skills/mstar-plan-artifacts/references/plan-quality-bar.md +1 -1
- package/harness-skills/mstar-plan-artifacts/references/status-and-residuals.md +12 -13
- package/harness-skills/mstar-plan-artifacts/templates/README.md +1 -1
- package/harness-skills/mstar-plan-conventions/SKILL.md +9 -1
- package/harness-skills/mstar-plan-conventions/references/harness-bootstrap-and-agents-layering.md +1 -1
- package/harness-skills/mstar-review-qc/SKILL.md +2 -0
- package/harness-skills/mstar-roles/SKILL.md +2 -0
- package/harness-skills/mstar-roles/references/project-manager/dispatch-and-assignment.md +1 -1
- package/harness-skills/mstar-sdd/SKILL.md +18 -14
- package/harness-skills/mstar-sdd/references/file-handoffs.md +8 -8
- package/harness-skills/mstar-sdd/references/sticky-implementer-session.md +2 -2
- package/harness-skills/mstar-skill-authoring/SKILL.md +4 -0
- package/harness-skills/mstar-strategy/SKILL.md +2 -0
- package/package.json +6 -2
- package/harness-skills/mstar-plan-artifacts/scripts/tech-debt-rollup.sh +0 -115
- package/harness-skills/mstar-sdd/scripts/review-package +0 -43
- package/harness-skills/mstar-sdd/scripts/sdd-workspace +0 -90
- package/harness-skills/mstar-sdd/scripts/task-brief +0 -40
package/harness-skills/mstar-plan-conventions/references/harness-bootstrap-and-agents-layering.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
1. 创建 `{HARNESS_DIR}`(推荐 `.mstar/`)与 `{PLAN_DIR}`(推荐 `.mstar/plans/`)。
|
|
16
16
|
2. 初始化 `status.json`:从 **`mstar-plan-artifacts/templates/status.empty.json`** 复制;residual canonical 见 **`mstar-plan-artifacts` SKILL.md**;字段与生命周期见 **`mstar-plan-artifacts/references/status-and-residuals.md`**。
|
|
17
|
-
3. 初始化可选 `notes.json`(**`mstar-plan-artifacts/templates/notes.empty.json`**);`sdd/` 空目录占位(per-plan 子目录由
|
|
17
|
+
3. 初始化可选 `notes.json`(**`mstar-plan-artifacts/templates/notes.empty.json`**);`sdd/` 空目录占位(per-plan 子目录由 **`mstar-sdd`** → `mstar sdd workspace <plan-id>` 创建)。
|
|
18
18
|
4. 项目根 `.gitignore` 追加 Morning Star **进程产物**忽略集(canonical snippet → `mstar-plan-conventions` SKILL.md「Git 跟踪策略」;legacy `.agents/` 有等价表)。
|
|
19
19
|
5. **Profile B**(统一 Done 压缩)时另建 `{HARNESS_DIR}/archived/plans/` 与 `archived/plans-done.json`(自 **`mstar-plan-artifacts/templates/plans-done.empty.json`** 复制;schema 仅 `{ "plans": [] }`,见 **`mstar-plan-artifacts/references/done-compaction.md`**)。
|
|
20
20
|
6. 可选:创建 `{ITERATION_DIR}`(`iterations/` + `README.md`)与 `{KNOWLEDGE_DIR}`(`knowledge/` + `README.md`);`{HARNESS_DIR}/specs/`(解析后的 `{SPECS_DIR}` 默认落点);内容边界见 `mstar-plan-conventions` SKILL.md 与 `references/knowledge-and-designs.md`。
|
|
@@ -24,6 +24,8 @@ description: "Morning Star QC orchestration — **SDD mandatory plan QC tri-revi
|
|
|
24
24
|
- **After `Request Changes` (default)**:**Targeted re-review** — PM dispatches only seats that **raised** blocking findings; each updates **the same** `{SDD_DIR}/review/qcN.md` (`## Revalidation`, update verdict). **Do not** spawn `qcN-rev2.md` for targeted re-review. Naming → **`mstar-plan-artifacts/references/plan-files-and-reports.md`** § QC 三审触发时机.
|
|
25
25
|
- **Full tri re-review (exception)**:Assignment **`QC re-review: full tri-review`** → new basenames (`qc1-rev2.md` …); PM marks **active wave** in consolidated decision.
|
|
26
26
|
|
|
27
|
+
> **Engine check (when available):** run `mstar review seats <assignment-file> [--mode sdd|inline|targeted] [--reviewers <role1,role2,...>]` (or `import { executionModeToN, assertTriIdentity } from "@mstar-harness/engine"` in a host hook) to map `Execution mode` to its QC seat count N above and assert tri identity. On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
28
|
+
|
|
27
29
|
## 三审身份与模型独立性门禁(PM 强制)
|
|
28
30
|
|
|
29
31
|
在 PM 发出 **initial** QC 三审后、进入汇总前:
|
|
@@ -74,6 +74,8 @@ Role `references/*.md` files include explicit **`NEVER`** sections (anti-recursi
|
|
|
74
74
|
|
|
75
75
|
PM consolidated (tri mode): `{SDD_DIR}/review/qc-consolidated.md` (same folder; no `<plan-id>` basename prefix) + durable main-plan summary. Naming SSOT: `mstar-plan-artifacts/references/plan-files-and-reports.md`.
|
|
76
76
|
|
|
77
|
+
> **Engine check (when available):** import `validateRoleMapping` / `lintLoadOrder` from `@mstar-harness/engine` in a host hook to validate the mapping and parameter tables above against the on-disk `references/*.md` layout (shared families included) and lint the load-order declarations (no CLI form yet). On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
78
|
+
|
|
77
79
|
## Maintenance Rules
|
|
78
80
|
|
|
79
81
|
- Edit behavior in `references/*.md`.
|
|
@@ -137,7 +137,7 @@ When `metadata.control_worktree_path` is set and worktree mode is **not** waived
|
|
|
137
137
|
| **`Worktree path`** | Absolute **feature** checkout (`execution_lease.worktree_path`) — product/source edits only |
|
|
138
138
|
| **`Control harness root`** | Absolute `<control_worktree_path>/{HARNESS_DIR}` |
|
|
139
139
|
| **`Plan Path`** | Absolute under control harness (not relative from feature cwd) |
|
|
140
|
-
| **`SDD dir`** | Absolute under control harness; run
|
|
140
|
+
| **`SDD dir`** | Absolute under control harness; run `mstar sdd workspace <plan-id>` with `MSTAR_CONTROL_ROOT=<control_worktree_path>` when cwd is the feature tree |
|
|
141
141
|
|
|
142
142
|
Do **not** waive worktree because default-gitignored `plans/` are missing under the feature checkout — see `mstar-branch-worktree` 「Harness path SSOT under default gitignore」.
|
|
143
143
|
## Completion Report Template
|
|
@@ -23,6 +23,8 @@ If you were dispatched as an SDD implementer or task reviewer, skip PM orchestra
|
|
|
23
23
|
|
|
24
24
|
**Optional:** **`SDD implementer session: sticky`** — same implementer subagent across sequential tasks on one plan/branch; **task reviewers stay fresh per task**. SSOT → **`references/sticky-implementer-session.md`**.
|
|
25
25
|
|
|
26
|
+
> **Engine check (when available):** import `implementerSessionStickyRules` from `@mstar-harness/engine` in a host hook to validate the sticky resume decision above (no CLI form yet). On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
27
|
+
|
|
26
28
|
**Narration:** at most one short line between tool calls — ledger and file paths carry the record.
|
|
27
29
|
|
|
28
30
|
**Continuous execution:** do not check in with the human between tasks. Stop only for BLOCKED, genuine ambiguity, or all tasks complete.
|
|
@@ -39,12 +41,12 @@ Batch all findings for the human in one message. If clean, proceed silently.
|
|
|
39
41
|
## Per-task loop (PM only)
|
|
40
42
|
|
|
41
43
|
1. Record `BASE_SHA` (never use `HEAD~1` later)
|
|
42
|
-
2.
|
|
43
|
-
3. `
|
|
44
|
+
2. `mstar sdd workspace <plan-id>` → `SDD_DIR`(iteration L1 从 feature cwd 调用时:`MSTAR_CONTROL_ROOT=<control_worktree_path>` 或 `mstar sdd workspace <plan-id> <control_worktree_path>`;缺 status.json 的 linked worktree 会 fail closed)
|
|
45
|
+
3. `mstar sdd task-brief <plan> N` → brief file
|
|
44
46
|
4. Dispatch implementer:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
5. On `DONE`: `
|
|
47
|
+
- **`SDD implementer session: fresh`** (default) — new subagent; templates: `references/implementer-prompt.md`
|
|
48
|
+
- **`SDD implementer session: sticky`** — first task: same as fresh + write `{SDD_DIR}/implementer-session.json` with `host_agent_id`; later tasks: host **resume** + `references/implementer-continuation-prompt.md` (see **`references/sticky-implementer-session.md`**)
|
|
49
|
+
5. On `DONE`: `mstar sdd review-package BASE HEAD` → diff file
|
|
48
50
|
6. Dispatch **fresh** task reviewer — role **`generalPurpose`** (L2; **not** `qc-specialist*`; host role field → `mstar-host` C5) — brief, report, diff, Global Constraints — `references/task-reviewer-prompt.md` — **never** sticky resume for reviewers
|
|
49
51
|
7. Fix loop for Critical/Important; re-review until approved
|
|
50
52
|
8. Append `progress.md`; update `status.json` `task_commits[]` and `implementer-session.json` `last_task` if sticky
|
|
@@ -54,6 +56,8 @@ Batch all findings for the human in one message. If clean, proceed silently.
|
|
|
54
56
|
|
|
55
57
|
Detail: **`references/file-handoffs.md`**.
|
|
56
58
|
|
|
59
|
+
> **Engine check (when available):** run `mstar sdd workspace <plan-id>` / `mstar sdd task-brief <plan-file> <task-number>` / `mstar sdd review-package <base> <head>` (or `import { assertBaseSha, sddWorkspace, taskBrief, reviewPackage } from "@mstar-harness/engine"` in a host hook) to drive the loop steps above. On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
60
|
+
|
|
57
61
|
## Implementer statuses
|
|
58
62
|
|
|
59
63
|
| Status | PM action |
|
|
@@ -81,7 +85,7 @@ Host mapping → **`mstar-host`** references (`model` / Task field).
|
|
|
81
85
|
|
|
82
86
|
## After all tasks
|
|
83
87
|
|
|
84
|
-
1. `
|
|
88
|
+
1. `mstar sdd review-package MERGE_BASE HEAD` → branch diff in `{SDD_DIR}/review/`
|
|
85
89
|
2. PM dispatches **plan QC tri-review (L3)** — **`QC mode: full tri-review`**, **N=3** — with branch review-package path and report paths under `{SDD_DIR}/review/` → **`mstar-review-qc`** · **`mstar-dispatch-gates`**. Layer SSOT → **`mstar-review-qc/references/review-responsibility-boundaries.md`**. PM writes `{SDD_DIR}/review/qc-consolidated.md` and durable main-plan gate summary. **Mandatory whenever `Execution mode: sdd`** (single-plan or iteration).
|
|
86
90
|
3. Critical/Important QC findings → **one** fix dispatch (full list), then targeted re-review
|
|
87
91
|
4. QA gate → **`mstar-harness-core`** Done rules; PM **`mstar-roles/references/project-manager/qa-trigger-matrix.md`**
|
|
@@ -94,6 +98,8 @@ Append on clean review: `Task N: complete (<base>..<head>, review clean)`.
|
|
|
94
98
|
|
|
95
99
|
Minor findings → `## Minor (for plan QC)` section in same file.
|
|
96
100
|
|
|
101
|
+
> **Engine check (when available):** import `readProgressLedger` from `@mstar-harness/engine` in a host hook to read the ledger above (no CLI form yet). On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
102
|
+
|
|
97
103
|
## Red flags (NEVER)
|
|
98
104
|
|
|
99
105
|
- Parallel implementer dispatches
|
|
@@ -107,17 +113,15 @@ Minor findings → `## Minor (for plan QC)` section in same file.
|
|
|
107
113
|
- Sticky **resume** for task reviewers
|
|
108
114
|
- Resume implementer without `host_agent_id` in `implementer-session.json`
|
|
109
115
|
|
|
110
|
-
##
|
|
111
|
-
|
|
112
|
-
Scripts live under this skill: **`mstar-sdd`** → `scripts/<name>`.
|
|
116
|
+
## CLI
|
|
113
117
|
|
|
114
|
-
|
|
118
|
+
The SDD helpers are engine-backed commands under **`mstar sdd`**(引擎 CLI;原 bash 脚本已移除,行为语义不变)。Run the `mstar` binary from any checkout; env vars `MSTAR_CONTROL_ROOT` / `MSTAR_HARNESS_DIR` / `SDD_DIR` are honored exactly as before.
|
|
115
119
|
|
|
116
|
-
|
|
|
120
|
+
| Command | Usage |
|
|
117
121
|
|--------|--------|
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
122
|
+
| `mstar sdd workspace` | `PLAN_ID [CONTROL_ROOT]` → creates `{SDD_DIR}` under control harness when set (`MSTAR_CONTROL_ROOT` or 2nd arg); fail closed on linked worktree without `status.json` |
|
|
123
|
+
| `mstar sdd task-brief` | `PLAN_FILE TASK_N [OUTFILE]` |
|
|
124
|
+
| `mstar sdd review-package` | `BASE HEAD [OUTFILE]` |
|
|
121
125
|
|
|
122
126
|
## References
|
|
123
127
|
|
|
@@ -4,14 +4,14 @@ PM and subagents move artifacts as **files**, not pasted text. Pasted content st
|
|
|
4
4
|
|
|
5
5
|
## Before implementer dispatch
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Run the SDD helpers through the engine CLI **`mstar sdd …`** (engine-backed; the former bash scripts are removed — semantics unchanged).
|
|
8
8
|
|
|
9
|
-
1. `export SDD_DIR=$(
|
|
10
|
-
- Iteration L1 (implementer cwd = feature worktree):
|
|
11
|
-
`export MSTAR_CONTROL_ROOT=<control_worktree_path>`
|
|
12
|
-
or `sdd
|
|
9
|
+
1. `export SDD_DIR=$(mstar sdd workspace <plan-id>)`
|
|
10
|
+
- Iteration L1 (implementer cwd = feature worktree):
|
|
11
|
+
`export MSTAR_CONTROL_ROOT=<control_worktree_path>`
|
|
12
|
+
or `mstar sdd workspace <plan-id> <control_worktree_path>`
|
|
13
13
|
so `{SDD_DIR}` lands on the control harness (default-gitignored plans/status/sdd). Do not create a second SDD tree under the feature checkout.
|
|
14
|
-
2.
|
|
14
|
+
2. `mstar sdd task-brief <plan-file> <N> "$SDD_DIR/task-N-brief.md"`
|
|
15
15
|
3. Record `BASE_SHA` (`git rev-parse HEAD` before dispatch).
|
|
16
16
|
4. Dispatch implementer with:
|
|
17
17
|
- One line scene-setting (where task fits)
|
|
@@ -33,7 +33,7 @@ Implementer writes full report to `task-N-report.md`. Return to PM only:
|
|
|
33
33
|
## After implementer DONE
|
|
34
34
|
|
|
35
35
|
1. `HEAD_SHA=$(git rev-parse HEAD)`
|
|
36
|
-
2.
|
|
36
|
+
2. `mstar sdd review-package "$BASE_SHA" "$HEAD_SHA" "$SDD_DIR/review-....diff"`
|
|
37
37
|
3. Dispatch task reviewer with: brief path, report path, diff path, Global Constraints (verbatim from plan).
|
|
38
38
|
|
|
39
39
|
**Never use `HEAD~1` as BASE** — multi-commit tasks truncate.
|
|
@@ -65,7 +65,7 @@ After all tasks:
|
|
|
65
65
|
```bash
|
|
66
66
|
MERGE_BASE=$(git merge-base <target-branch> HEAD)
|
|
67
67
|
mkdir -p "$SDD_DIR/review"
|
|
68
|
-
|
|
68
|
+
mstar sdd review-package "$MERGE_BASE" HEAD "$SDD_DIR/review/branch-review-....diff"
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
Pass **branch** diff path and bundle report paths (`$SDD_DIR/review/qc1.md` …) to QC dispatch — not task-level diffs. Raw QC/QA files stay in the gitignored review bundle; PM records durable summary and open residuals in **local** plan/`status.json` (session SSOT) and promotes cross-clone decisions into tracked knowledge/specs/`AGENTS.md` per `mstar-plan-conventions` git policy.
|
|
@@ -52,12 +52,12 @@ After each completed task review, PM sets `last_task` to N. **Do not** resume if
|
|
|
52
52
|
|
|
53
53
|
Same as default SDD for artifacts and L2 review; only implementer dispatch differs:
|
|
54
54
|
|
|
55
|
-
1. `task-brief` → `{SDD_DIR}/task-N-brief.md`
|
|
55
|
+
1. `mstar sdd task-brief` → `{SDD_DIR}/task-N-brief.md`
|
|
56
56
|
2. Record `BASE_SHA`
|
|
57
57
|
3. **Implementer dispatch**
|
|
58
58
|
- **First task** (`fresh` or sticky start): normal Task/subagent invoke → save `host_agent_id` to ledger
|
|
59
59
|
- **Next tasks** (`sticky`): host **resume** with same `host_agent_id` + continuation prompt (`implementer-prompt.md` § Continuation)
|
|
60
|
-
4. On `DONE` → `review-package` → **fresh** task reviewer (never resume reviewer)
|
|
60
|
+
4. On `DONE` → `mstar sdd review-package` → **fresh** task reviewer (never resume reviewer)
|
|
61
61
|
5. Append `progress.md`; update ledger `last_task`
|
|
62
62
|
6. Next task
|
|
63
63
|
|
|
@@ -70,6 +70,8 @@ description: Use when...
|
|
|
70
70
|
Bad:`Explains how to write plans with steps, tests, commits, and review gates.`
|
|
71
71
|
Better:`Use when a non-trivial task has a spec or requirements and needs a written implementation plan before code changes.`
|
|
72
72
|
|
|
73
|
+
> **Engine check (when available):** run `mstar skill lint <skill-dir>` (or `import { lintFrontmatter, lintFiveQuestion } from "@mstar-harness/engine"` in a host hook) to lint the frontmatter contract and the five-question body contract above. On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
74
|
+
|
|
73
75
|
## 默认 Body 结构
|
|
74
76
|
|
|
75
77
|
```markdown
|
|
@@ -97,6 +99,8 @@ Agents 按 **skill 名** 发现 skill;文档若给出完整仓内相对路径
|
|
|
97
99
|
|
|
98
100
|
在本 harness:解析方式见 **`mstar-host`** § Resolve loaded skill root(omp `skill://`、各宿主插件挂载等)。其它环境按当地 skill 安装约定解析。
|
|
99
101
|
|
|
102
|
+
> **Engine check (when available):** import `resolveAssetPath` from `@mstar-harness/engine` in a host hook to resolve a skill-relative asset per the convention above (no CLI form yet). On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
103
|
+
|
|
100
104
|
## Progressive Disclosure
|
|
101
105
|
|
|
102
106
|
1. Frontmatter:仅触发
|
|
@@ -58,6 +58,8 @@ A good strategy document is opinionated and concise. It should fit in one screen
|
|
|
58
58
|
<Major past decisions with context — why, not just what>
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
> **Engine check (when available):** run `mstar lint <STRATEGY.md>` (or `import { lintStrategySections } from "@mstar-harness/engine"` in a host hook) to check the six required sections above (Vision, What we build, What we don't build, Guiding Principles, Technology Direction, Decision Log). On `fail` -> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
|
|
62
|
+
|
|
61
63
|
### Optional sections
|
|
62
64
|
|
|
63
65
|
- **Current Focus** — what the team is working on now
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mstar-harness/opencode",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Morning Star harness OpenCode plugin
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Morning Star harness OpenCode plugin — skills bootstrap + engine-backed runtime hooks (status lint, dispatch validation, Enforcement: hard gates).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"scripts": {
|
|
24
24
|
"bundle-assets": "bun run scripts/bundle-harness-assets.ts",
|
|
25
25
|
"build": "bun run bundle-assets && rm -rf dist && bun build src/mstar.ts --target node --outfile dist/mstar.js",
|
|
26
|
+
"test": "bun test",
|
|
26
27
|
"prepublishOnly": "bun run build"
|
|
27
28
|
},
|
|
28
29
|
"engines": {
|
|
@@ -33,5 +34,8 @@
|
|
|
33
34
|
},
|
|
34
35
|
"publishConfig": {
|
|
35
36
|
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@mstar-harness/engine": "2.0.0"
|
|
36
40
|
}
|
|
37
41
|
}
|
|
@@ -1,115 +0,0 @@
|
|
|
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:-.mstar/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,43 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Write commit list, stat summary, and diff to a file for reviewer Read.
|
|
3
|
-
# Usage: review-package BASE HEAD [OUTFILE]
|
|
4
|
-
# Never use HEAD~1 as BASE for multi-commit tasks.
|
|
5
|
-
set -euo pipefail
|
|
6
|
-
|
|
7
|
-
if [ $# -lt 2 ] || [ $# -gt 3 ]; then
|
|
8
|
-
echo "usage: review-package BASE HEAD [OUTFILE]" >&2
|
|
9
|
-
exit 2
|
|
10
|
-
fi
|
|
11
|
-
|
|
12
|
-
base=$1
|
|
13
|
-
head=$2
|
|
14
|
-
|
|
15
|
-
git rev-parse --verify --quiet "$base" >/dev/null || { echo "bad BASE: $base" >&2; exit 2; }
|
|
16
|
-
git rev-parse --verify --quiet "$head" >/dev/null || { echo "bad HEAD: $head" >&2; exit 2; }
|
|
17
|
-
|
|
18
|
-
if [ $# -eq 3 ]; then
|
|
19
|
-
out=$3
|
|
20
|
-
else
|
|
21
|
-
if [ -z "${SDD_DIR:-}" ]; then
|
|
22
|
-
echo "review-package: set SDD_DIR or pass OUTFILE" >&2
|
|
23
|
-
exit 2
|
|
24
|
-
fi
|
|
25
|
-
mkdir -p "$SDD_DIR"
|
|
26
|
-
out="$SDD_DIR/review-$(git rev-parse --short "$base")..$(git rev-parse --short "$head").diff"
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
{
|
|
30
|
-
echo "# Review package: ${base}..${head}"
|
|
31
|
-
echo
|
|
32
|
-
echo "## Commits"
|
|
33
|
-
git log --oneline "${base}..${head}"
|
|
34
|
-
echo
|
|
35
|
-
echo "## Files changed"
|
|
36
|
-
git diff --stat "${base}..${head}"
|
|
37
|
-
echo
|
|
38
|
-
echo "## Diff"
|
|
39
|
-
git diff -U10 "${base}..${head}"
|
|
40
|
-
} > "$out"
|
|
41
|
-
|
|
42
|
-
commits=$(git rev-list --count "${base}..${head}" 2>/dev/null || echo 0)
|
|
43
|
-
echo "wrote ${out}: ${commits} commit(s), $(wc -c < "$out" | tr -d ' ') bytes"
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Resolve and ensure {SDD_DIR} for Morning Star SDD artifacts.
|
|
3
|
-
# Usage: sdd-workspace PLAN_ID [CONTROL_ROOT]
|
|
4
|
-
# CONTROL_ROOT — optional absolute repo root of the control worktree
|
|
5
|
-
# (or set MSTAR_CONTROL_ROOT). Required when cwd is a linked feature
|
|
6
|
-
# worktree that lacks harness status.json (default gitignore).
|
|
7
|
-
# Prints absolute path to {HARNESS_DIR}/sdd/<plan-id>/ (or legacy .agents/sdd/).
|
|
8
|
-
set -euo pipefail
|
|
9
|
-
|
|
10
|
-
if [ $# -lt 1 ] || [ $# -gt 2 ]; then
|
|
11
|
-
echo "usage: sdd-workspace PLAN_ID [CONTROL_ROOT]" >&2
|
|
12
|
-
echo " Set MSTAR_CONTROL_ROOT=<control_worktree_path> when running from a feature worktree." >&2
|
|
13
|
-
exit 2
|
|
14
|
-
fi
|
|
15
|
-
|
|
16
|
-
plan_id=$1
|
|
17
|
-
control_root="${2:-${MSTAR_CONTROL_ROOT:-}}"
|
|
18
|
-
|
|
19
|
-
abs_dir() {
|
|
20
|
-
(cd "$1" && pwd -P)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if [ -n "$control_root" ]; then
|
|
24
|
-
if [ ! -d "$control_root" ]; then
|
|
25
|
-
echo "sdd-workspace: CONTROL_ROOT / MSTAR_CONTROL_ROOT is not a directory: $control_root" >&2
|
|
26
|
-
exit 1
|
|
27
|
-
fi
|
|
28
|
-
root=$(abs_dir "$control_root")
|
|
29
|
-
else
|
|
30
|
-
root=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
31
|
-
root=$(abs_dir "$root")
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
resolve_harness_with_status() {
|
|
35
|
-
local r=$1
|
|
36
|
-
if [ -f "$r/.mstar/status.json" ]; then
|
|
37
|
-
printf '%s\n' "$r/.mstar"
|
|
38
|
-
return 0
|
|
39
|
-
fi
|
|
40
|
-
if [ -f "$r/.agents/status.json" ]; then
|
|
41
|
-
printf '%s\n' "$r/.agents"
|
|
42
|
-
return 0
|
|
43
|
-
fi
|
|
44
|
-
return 1
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
# Linked worktree from `git worktree add`: --git-dir ≠ --git-common-dir
|
|
48
|
-
is_linked_worktree() {
|
|
49
|
-
local r=$1
|
|
50
|
-
local git_dir common
|
|
51
|
-
git_dir=$(git -C "$r" rev-parse --git-dir 2>/dev/null) || return 1
|
|
52
|
-
common=$(git -C "$r" rev-parse --git-common-dir 2>/dev/null) || return 1
|
|
53
|
-
case "$git_dir" in
|
|
54
|
-
/*) ;;
|
|
55
|
-
*) git_dir="$r/$git_dir" ;;
|
|
56
|
-
esac
|
|
57
|
-
case "$common" in
|
|
58
|
-
/*) ;;
|
|
59
|
-
*) common="$r/$common" ;;
|
|
60
|
-
esac
|
|
61
|
-
# Path contains /worktrees/ → definitely linked
|
|
62
|
-
case "$git_dir" in
|
|
63
|
-
*/.git/worktrees/*|*/worktrees/*) return 0 ;;
|
|
64
|
-
esac
|
|
65
|
-
local gd_parent cm_abs
|
|
66
|
-
gd_parent=$(abs_dir "$(dirname "$git_dir")")
|
|
67
|
-
cm_abs=$(abs_dir "$common")
|
|
68
|
-
[ "$gd_parent/$(basename "$git_dir")" != "$cm_abs" ] && [ "$git_dir" != "$cm_abs" ]
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if harness=$(resolve_harness_with_status "$root"); then
|
|
72
|
-
:
|
|
73
|
-
elif [ -z "$control_root" ] && is_linked_worktree "$root"; then
|
|
74
|
-
echo "sdd-workspace: linked worktree at $root has no {HARNESS_DIR}/status.json (default gitignore)." >&2
|
|
75
|
-
echo " Refusing to create a second SDD tree under the feature checkout." >&2
|
|
76
|
-
echo " Re-run with MSTAR_CONTROL_ROOT=<control_worktree_path> or: sdd-workspace $plan_id <control_worktree_path>" >&2
|
|
77
|
-
echo " See mstar-branch-worktree «Harness path SSOT under default gitignore»." >&2
|
|
78
|
-
exit 1
|
|
79
|
-
elif [ -d "$root/.mstar" ]; then
|
|
80
|
-
harness="$root/.mstar"
|
|
81
|
-
elif [ -d "$root/.agents" ]; then
|
|
82
|
-
harness="$root/.agents"
|
|
83
|
-
else
|
|
84
|
-
harness="$root/.mstar"
|
|
85
|
-
fi
|
|
86
|
-
|
|
87
|
-
dir="$harness/sdd/$plan_id"
|
|
88
|
-
mkdir -p "$dir"
|
|
89
|
-
printf '*\n' > "$dir/.gitignore"
|
|
90
|
-
cd "$dir" && pwd
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Extract one task's full text from a plan into a file for the implementer.
|
|
3
|
-
# Usage: task-brief PLAN_FILE TASK_NUMBER [OUTFILE]
|
|
4
|
-
# Default OUTFILE: {SDD_DIR}/task-N-brief.md (SDD_DIR from env or second arg via sdd-workspace)
|
|
5
|
-
set -euo pipefail
|
|
6
|
-
|
|
7
|
-
if [ $# -lt 2 ] || [ $# -gt 3 ]; then
|
|
8
|
-
echo "usage: task-brief PLAN_FILE TASK_NUMBER [OUTFILE]" >&2
|
|
9
|
-
exit 2
|
|
10
|
-
fi
|
|
11
|
-
|
|
12
|
-
plan=$1
|
|
13
|
-
n=$2
|
|
14
|
-
[ -f "$plan" ] || { echo "no such plan file: $plan" >&2; exit 2; }
|
|
15
|
-
|
|
16
|
-
if [ $# -eq 3 ]; then
|
|
17
|
-
out=$3
|
|
18
|
-
else
|
|
19
|
-
if [ -z "${SDD_DIR:-}" ]; then
|
|
20
|
-
echo "task-brief: set SDD_DIR or pass OUTFILE (run sdd-workspace PLAN_ID first)" >&2
|
|
21
|
-
exit 2
|
|
22
|
-
fi
|
|
23
|
-
mkdir -p "$SDD_DIR"
|
|
24
|
-
out="$SDD_DIR/task-${n}-brief.md"
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
awk -v n="$n" '
|
|
28
|
-
/^```/ { infence = !infence }
|
|
29
|
-
!infence && /^#+[ \t]+Task[ \t]+[0-9]+/ {
|
|
30
|
-
intask = ($0 ~ ("^#+[ \t]+Task[ \t]+" n "([^0-9]|$)"))
|
|
31
|
-
}
|
|
32
|
-
intask { print }
|
|
33
|
-
' "$plan" > "$out"
|
|
34
|
-
|
|
35
|
-
if [ ! -s "$out" ]; then
|
|
36
|
-
echo "task ${n} not found in ${plan} (no heading matching Task ${n})" >&2
|
|
37
|
-
exit 3
|
|
38
|
-
fi
|
|
39
|
-
|
|
40
|
-
echo "wrote ${out}: $(wc -l < "$out" | tr -d ' ') lines"
|