@mstar-harness/dsh 3.6.3 → 3.7.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.md +4 -6
- package/README.zh.md +3 -3
- package/dist/client/panel/PanelView.d.ts +8 -11
- package/dist/client/panel/TabNav.d.ts +2 -2
- package/dist/client/panel/graph/event-log.d.ts +5 -9
- package/dist/client/panel/graph/project-graph.d.ts +53 -72
- package/dist/client/panel/graph/schema.d.ts +31 -37
- package/dist/client/panel/locale.d.ts +19 -19
- package/dist/client/panel/pages/AgentCanvasPage.d.ts +40 -58
- package/dist/client/panel/pages/EventLogPage.d.ts +6 -6
- package/dist/client/panel/pages/IterationInfoSection.d.ts +9 -11
- package/dist/client/panel/pages/IterationTaskPage.d.ts +3 -3
- package/dist/client/panel/plan-sort.d.ts +3 -6
- package/dist/client/panel/state-section.d.ts +1 -1
- package/dist/client/panel/zones/Legend.d.ts +2 -2
- package/dist/client/panel/zones/ProjectRollup.d.ts +1 -2
- package/dist/client/panel/zones/TaskBoard.d.ts +1 -2
- package/dist/gates/_shared.d.ts +7 -10
- package/dist/gates/adapter.d.ts +6 -9
- package/dist/gates/agent-flow.d.ts +49 -59
- package/dist/gates/agent-personas.d.ts +1 -2
- package/dist/gates/catalog.d.ts +2 -5
- package/dist/gates/dispatch.d.ts +9 -11
- package/dist/gates/fallbacks-advisory.d.ts +2 -3
- package/dist/gates/fallbacks-probe.d.ts +2 -2
- package/dist/gates/fallbacks-seeds.d.ts +1 -1
- package/dist/gates/fallbacks-structural.d.ts +1 -1
- package/dist/gates/goal-bridge.d.ts +6 -9
- package/dist/gates/role-persona.d.ts +2 -3
- package/dist/gates/skill-lint.d.ts +19 -2
- package/dist/gates/system-prompt.d.ts +7 -11
- package/dist/gates/tools.d.ts +1 -1
- package/dist/gates/workflow-ledger.d.ts +21 -28
- package/dist/gates/workflow-policy.d.ts +15 -19
- package/dist/gates/workflow-selection.d.ts +3 -3
- package/dist/index.js +215 -33
- package/dist/types.d.ts +4 -7
- package/harness-commands/iteration-drive.md +6 -6
- package/harness-commands/iteration-loop.md +7 -7
- package/harness-commands/iteration-start.md +8 -8
- package/harness-skills/mstar-coding-behavior/SKILL.md +3 -20
- package/harness-skills/mstar-dispatch-gates/SKILL.md +7 -13
- package/harness-skills/mstar-dispatch-gates/references/leaf-executor-checklist.md +1 -1
- package/harness-skills/mstar-harness-core/SKILL.md +9 -53
- package/harness-skills/mstar-host/references/zcode.md +1 -0
- package/harness-skills/mstar-iteration/SKILL.md +32 -318
- package/harness-skills/mstar-iteration/references/command-shared-invariants.md +1 -1
- package/harness-skills/mstar-iteration/references/phase-1-prepare.md +155 -0
- package/harness-skills/mstar-iteration/references/phase-2-worktree-lease.md +113 -3
- package/harness-skills/mstar-iteration/references/phase5-helper-discovery.md +1 -1
- package/harness-skills/mstar-roles/SKILL.md +14 -12
- package/harness-skills/mstar-roles/references/_shared/leaf-executor-core.md +5 -6
- package/harness-skills/mstar-roles/references/architect.md +1 -1
- package/harness-skills/mstar-roles/references/code-reviewer.md +11 -1
- package/harness-skills/mstar-roles/references/frontend-dev.md +1 -1
- package/harness-skills/mstar-roles/references/fullstack-dev-shared.md +1 -1
- package/harness-skills/mstar-roles/references/ops-engineer.md +1 -1
- package/harness-skills/mstar-roles/references/product-manager.md +1 -1
- package/harness-skills/mstar-roles/references/project-manager/dispatch-and-assignment.md +4 -0
- package/harness-skills/mstar-roles/references/project-manager.md +6 -4
- package/harness-skills/mstar-roles/references/prompt-engineer.md +1 -1
- package/harness-skills/mstar-roles/references/qa-engineer.md +1 -1
- package/harness-skills/mstar-roles/references/qc-specialist-shared.md +1 -1
- package/harness-skills/mstar-roles/references/writing-specialist.md +1 -1
- package/harness-skills/mstar-sdd/references/file-handoffs.md +40 -7
- package/harness-skills/mstar-sdd/references/implementer-continuation-prompt.md +9 -0
- package/harness-skills/mstar-sdd/references/implementer-prompt.md +9 -0
- package/harness-skills/mstar-sdd/references/task-reviewer-prompt.md +7 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1149,11 +1149,11 @@ import { dirname as dirname4, join as join7, resolve as resolve5, sep } from "no
|
|
|
1149
1149
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
1150
1150
|
import { existsSync as existsSync7 } from "node:fs";
|
|
1151
1151
|
import { isAbsolute as isAbsolute5, resolve as resolve8 } from "node:path";
|
|
1152
|
-
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
1152
|
+
import { execFileSync as execFileSync3, spawn } from "node:child_process";
|
|
1153
1153
|
import { mkdirSync as mkdirSync6, readdirSync as readdirSync6, readFileSync as readFileSync7, realpathSync as realpathSync3, statSync as statSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
1154
|
-
import { basename as basename4, dirname as dirname6, isAbsolute as isAbsolute6, join as join10, resolve as resolve9 } from "node:path";
|
|
1154
|
+
import { basename as basename4, dirname as dirname6, isAbsolute as isAbsolute6, join as join10, relative as relative3, resolve as resolve9 } from "node:path";
|
|
1155
1155
|
import { existsSync as existsSync9, readdirSync as readdirSync9, readFileSync as readFileSync10 } from "node:fs";
|
|
1156
|
-
import { basename as basename6, isAbsolute as isAbsolute8, join as join13, relative as
|
|
1156
|
+
import { basename as basename6, isAbsolute as isAbsolute8, join as join13, relative as relative5, resolve as resolve12, sep as sep4 } from "node:path";
|
|
1157
1157
|
import { existsSync as existsSync10 } from "node:fs";
|
|
1158
1158
|
import { join as join14 } from "node:path";
|
|
1159
1159
|
var SEVERITY_ORDER = ["critical", "high", "medium", "low", "nit"];
|
|
@@ -2467,6 +2467,25 @@ function assertSafePathComponent(value, what) {
|
|
|
2467
2467
|
throw new Error(`${what} must be a single safe path component ([A-Za-z0-9._-]+; not "", ".", "..", or containing "/" or "\\") — got ${JSON.stringify(value)}`);
|
|
2468
2468
|
}
|
|
2469
2469
|
}
|
|
2470
|
+
function canonicalizeNearestExisting(path) {
|
|
2471
|
+
const abs = resolve7(path);
|
|
2472
|
+
let dir = abs;
|
|
2473
|
+
const tail = [];
|
|
2474
|
+
for (;; ) {
|
|
2475
|
+
if (existsSync6(dir)) {
|
|
2476
|
+
try {
|
|
2477
|
+
return join9(realpathSync2(dir), ...tail);
|
|
2478
|
+
} catch {
|
|
2479
|
+
return abs;
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
const parent = dirname5(dir);
|
|
2483
|
+
if (parent === dir)
|
|
2484
|
+
return abs;
|
|
2485
|
+
tail.unshift(basename3(dir));
|
|
2486
|
+
dir = parent;
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2470
2489
|
function resolveSddDir(harnessDir, planId) {
|
|
2471
2490
|
assertSafePathComponent(planId, "planId");
|
|
2472
2491
|
const base = resolve7(harnessDir);
|
|
@@ -2626,6 +2645,16 @@ function l2PreDispatchCheck(input, opts = {}) {
|
|
|
2626
2645
|
});
|
|
2627
2646
|
return gate(violations);
|
|
2628
2647
|
}
|
|
2648
|
+
function assertBranchAlignment(worktreePath, expectedBranch, opts = {}) {
|
|
2649
|
+
const violations = [];
|
|
2650
|
+
const probe = probeBranch(worktreePath, opts);
|
|
2651
|
+
if ("error" in probe) {
|
|
2652
|
+
violations.push(violation7("high", "worktree.branch-probe-failed", `cannot probe branch at "${worktreePath}": ${probe.error}`, "verify the path is a git worktree checkout on the expected branch (not detached)"));
|
|
2653
|
+
} else if (probe.branch !== expectedBranch) {
|
|
2654
|
+
violations.push(violation7("high", "worktree.branch-mismatch", `worktree "${worktreePath}" is on branch "${probe.branch}", expected "${expectedBranch}" (Assignment Working branch)`, `checkout ${expectedBranch} in that worktree`));
|
|
2655
|
+
}
|
|
2656
|
+
return gate(violations);
|
|
2657
|
+
}
|
|
2629
2658
|
class SddScriptError extends Error {
|
|
2630
2659
|
exitCode;
|
|
2631
2660
|
constructor(message, exitCode) {
|
|
@@ -2763,6 +2792,16 @@ function taskBrief(planFile, taskN, outFile, opts = {}) {
|
|
|
2763
2792
|
if (!planFile || !Number.isInteger(taskN) || taskN < 1) {
|
|
2764
2793
|
throw new SddScriptError("usage: mstar sdd task-brief PLAN_FILE TASK_NUMBER [OUTFILE]", 2);
|
|
2765
2794
|
}
|
|
2795
|
+
const bound = opts.context;
|
|
2796
|
+
const observedCwd = opts.cwd ?? process.cwd();
|
|
2797
|
+
if (bound) {
|
|
2798
|
+
const inputPlan = canonicalizeNearestExisting(resolve9(observedCwd, planFile));
|
|
2799
|
+
if (inputPlan !== canonicalizeNearestExisting(bound.planFile)) {
|
|
2800
|
+
throwGateFail([
|
|
2801
|
+
contextViolation("high", "sdd.context.plan-file-mismatch", `plan file "${planFile}" does not match the bound context plan file "${bound.planFile}" — ` + "bound mode extracts only the resolved context's plan; refused before any read or write")
|
|
2802
|
+
]);
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2766
2805
|
let content;
|
|
2767
2806
|
try {
|
|
2768
2807
|
content = readFileSync7(planFile, "utf8");
|
|
@@ -2770,8 +2809,12 @@ function taskBrief(planFile, taskN, outFile, opts = {}) {
|
|
|
2770
2809
|
throw new SddScriptError(`no such plan file: ${planFile}`, 2);
|
|
2771
2810
|
}
|
|
2772
2811
|
let out;
|
|
2812
|
+
let mkdirAfterGate = null;
|
|
2773
2813
|
if (outFile) {
|
|
2774
|
-
out = outFile;
|
|
2814
|
+
out = bound ? resolve9(observedCwd, outFile) : outFile;
|
|
2815
|
+
} else if (bound) {
|
|
2816
|
+
out = join10(bound.sddDir, `task-${taskN}-brief.md`);
|
|
2817
|
+
mkdirAfterGate = bound.sddDir;
|
|
2775
2818
|
} else {
|
|
2776
2819
|
const sddDir = opts.sddDir ?? process.env.SDD_DIR;
|
|
2777
2820
|
if (!sddDir) {
|
|
@@ -2780,6 +2823,13 @@ function taskBrief(planFile, taskN, outFile, opts = {}) {
|
|
|
2780
2823
|
mkdirSync6(sddDir, { recursive: true });
|
|
2781
2824
|
out = join10(sddDir, `task-${taskN}-brief.md`);
|
|
2782
2825
|
}
|
|
2826
|
+
if (bound) {
|
|
2827
|
+
const gate2 = checkSddAction(bound, { kind: "artifact", cwd: observedCwd, target: out });
|
|
2828
|
+
if (!gate2.ok)
|
|
2829
|
+
throwGateFail(gate2.violations);
|
|
2830
|
+
if (mkdirAfterGate !== null)
|
|
2831
|
+
mkdirSync6(mkdirAfterGate, { recursive: true });
|
|
2832
|
+
}
|
|
2783
2833
|
const records = content.endsWith(`
|
|
2784
2834
|
`) ? content.split(`
|
|
2785
2835
|
`).slice(0, -1) : content.split(`
|
|
@@ -2804,7 +2854,98 @@ function taskBrief(planFile, taskN, outFile, opts = {}) {
|
|
|
2804
2854
|
if (printed.length === 0) {
|
|
2805
2855
|
throw new SddScriptError(`task ${taskN} not found in ${planFile} (no heading matching Task ${taskN})`, 3);
|
|
2806
2856
|
}
|
|
2807
|
-
return out;
|
|
2857
|
+
return bound ? resolve9(observedCwd, out) : out;
|
|
2858
|
+
}
|
|
2859
|
+
function isInside(child, ancestor) {
|
|
2860
|
+
const rel = relative3(ancestor, child);
|
|
2861
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute6(rel);
|
|
2862
|
+
}
|
|
2863
|
+
function canonicalDir(path) {
|
|
2864
|
+
try {
|
|
2865
|
+
return statSync4(path).isDirectory() ? realpathSync3(path) : null;
|
|
2866
|
+
} catch {
|
|
2867
|
+
return null;
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
function contextViolation(severity, code, message, fix) {
|
|
2871
|
+
return { ok: false, severity, code, message, fix };
|
|
2872
|
+
}
|
|
2873
|
+
function throwGateFail(violations) {
|
|
2874
|
+
const detail = violations.map((v) => `${v.code}: ${v.message}${v.fix ? ` (fix: ${v.fix})` : ""}`).join(`
|
|
2875
|
+
`);
|
|
2876
|
+
throw new SddScriptError(`SDD execution context rejected:
|
|
2877
|
+
${detail}`, 1);
|
|
2878
|
+
}
|
|
2879
|
+
function checkSddAction(context, action) {
|
|
2880
|
+
const violations = [];
|
|
2881
|
+
const add = (code, message, fix) => {
|
|
2882
|
+
violations.push(contextViolation("high", code, message, fix));
|
|
2883
|
+
};
|
|
2884
|
+
if (action.kind !== "source" && action.kind !== "artifact" && action.kind !== "launch") {
|
|
2885
|
+
add("sdd.context.kind-unknown", `unknown action kind ${JSON.stringify(action.kind)} — expected "source" | "artifact" | "launch"`);
|
|
2886
|
+
return { ok: false, violations };
|
|
2887
|
+
}
|
|
2888
|
+
if (typeof action.cwd !== "string" || action.cwd.trim() === "") {
|
|
2889
|
+
add("sdd.context.cwd-missing", "action.cwd (the observed invocation cwd) is required — never an Assignment echo");
|
|
2890
|
+
return { ok: false, violations };
|
|
2891
|
+
}
|
|
2892
|
+
const featureReal = canonicalDir(context.featureCwd);
|
|
2893
|
+
const canonicalSddDir = canonicalizeNearestExisting(context.sddDir);
|
|
2894
|
+
const canonicalPlanFile = canonicalizeNearestExisting(context.planFile);
|
|
2895
|
+
const cwdResolved = resolve9(action.cwd);
|
|
2896
|
+
const checkTarget = (baseDir, target, kind) => {
|
|
2897
|
+
if (featureReal === null)
|
|
2898
|
+
return;
|
|
2899
|
+
const targetAbs = resolve9(baseDir, target);
|
|
2900
|
+
const canonical = canonicalizeNearestExisting(targetAbs);
|
|
2901
|
+
if (!isInside(canonical, featureReal)) {
|
|
2902
|
+
const declaredPrefix = targetAbs === featureReal || targetAbs.startsWith(`${featureReal}/`);
|
|
2903
|
+
if (declaredPrefix) {
|
|
2904
|
+
add("sdd.context.target-symlink-escape", `${kind} target "${target}" canonicalizes to "${canonical}", outside the feature worktree — symlink escape refused before mutation`);
|
|
2905
|
+
} else {
|
|
2906
|
+
add(`sdd.context.${kind}-target-outside-feature`, `${kind} target "${target}" resolves to "${targetAbs}", outside the feature worktree "${featureReal}" — refused before mutation`);
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
};
|
|
2910
|
+
if (action.kind === "source") {
|
|
2911
|
+
const cwdReal = canonicalDir(cwdResolved);
|
|
2912
|
+
if (cwdReal === null) {
|
|
2913
|
+
add("sdd.context.cwd-missing", `observed source cwd "${action.cwd}" does not exist or is not a directory`);
|
|
2914
|
+
return { ok: false, violations };
|
|
2915
|
+
}
|
|
2916
|
+
if (featureReal === null || !isInside(cwdReal, featureReal)) {
|
|
2917
|
+
add("sdd.context.source-cwd-outside-feature", `observed source cwd "${cwdReal}" is outside the feature worktree "${context.featureCwd}" — a declared-correct context does not make a wrong-checkout write safe (A3)`, `run the source action from inside ${context.featureCwd}`);
|
|
2918
|
+
return { ok: false, violations };
|
|
2919
|
+
}
|
|
2920
|
+
if (action.target !== undefined)
|
|
2921
|
+
checkTarget(cwdReal, action.target, "source");
|
|
2922
|
+
} else if (action.kind === "artifact") {
|
|
2923
|
+
if (typeof action.target !== "string" || action.target.trim() === "") {
|
|
2924
|
+
add("sdd.context.target-missing", "artifact checks require the destination target");
|
|
2925
|
+
return { ok: false, violations };
|
|
2926
|
+
}
|
|
2927
|
+
const targetAbs = resolve9(cwdResolved, action.target);
|
|
2928
|
+
const canonical = canonicalizeNearestExisting(targetAbs);
|
|
2929
|
+
if (!isInside(canonical, canonicalSddDir) && canonical !== canonicalPlanFile) {
|
|
2930
|
+
const rawSddDir = resolve9(context.sddDir);
|
|
2931
|
+
const declaredPrefix = targetAbs === rawSddDir || targetAbs.startsWith(`${rawSddDir}/`) || targetAbs === canonicalSddDir || targetAbs.startsWith(`${canonicalSddDir}/`) || targetAbs === canonicalPlanFile;
|
|
2932
|
+
if (declaredPrefix) {
|
|
2933
|
+
add("sdd.context.artifact-symlink-escape", `artifact target "${targetAbs}" canonicalizes to "${canonical}", outside the plan's control sddDir — symlink escape refused before write`);
|
|
2934
|
+
} else {
|
|
2935
|
+
add("sdd.context.artifact-outside-plan", `artifact target "${targetAbs}" is outside the plan's control sddDir "${context.sddDir}" and is not the declared planFile "${context.planFile}" — legitimate control artifact edits stay inside the plan's artifacts; arbitrary control source edits are not allowed (A3)`);
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
} else {
|
|
2939
|
+
if (featureReal === null) {
|
|
2940
|
+
add("sdd.context.launch-cwd-missing", `feature worktree "${context.featureCwd}" does not exist or is not a directory — cannot bind the child's starting cwd`);
|
|
2941
|
+
} else {
|
|
2942
|
+
violations.push(...assertBranchAlignment(featureReal, context.workingBranch).violations);
|
|
2943
|
+
}
|
|
2944
|
+
if (action.target !== undefined && action.target.trim() !== "" && featureReal !== null) {
|
|
2945
|
+
checkTarget(featureReal, action.target, "launch");
|
|
2946
|
+
}
|
|
2947
|
+
}
|
|
2948
|
+
return { ok: violations.length === 0, violations };
|
|
2808
2949
|
}
|
|
2809
2950
|
function violation8(severity, code, message, fix) {
|
|
2810
2951
|
return { ok: false, severity, code, message, fix };
|
|
@@ -3590,7 +3731,7 @@ function collectKnowledgeDocs(dir) {
|
|
|
3590
3731
|
if (entry.isDirectory()) {
|
|
3591
3732
|
stack.push(full);
|
|
3592
3733
|
} else if (entry.name.endsWith(".md") && entry.name !== "README.md" && entry.name !== "index.md") {
|
|
3593
|
-
docs.push(
|
|
3734
|
+
docs.push(relative5(dir, full).split(sep4).join("/"));
|
|
3594
3735
|
}
|
|
3595
3736
|
}
|
|
3596
3737
|
}
|
|
@@ -3847,6 +3988,14 @@ function validateRoleMapping(rolesDir, options = {}) {
|
|
|
3847
3988
|
return { ok: violations.length === 0, violations };
|
|
3848
3989
|
}
|
|
3849
3990
|
var LOAD_ORDER_HEADING_RE = /^#{1,6}\s+[^\r\n]*\b(?:load[\s-]*order|first\s+action)\b[^\r\n]*$/i;
|
|
3991
|
+
var HUB_BOOTSTRAP_ASSERTIONS = [
|
|
3992
|
+
{ marker: "identity-first", why: "identity boundary before any skill list" },
|
|
3993
|
+
{ marker: "skill presets", why: "Assignment Skill presets decision field" },
|
|
3994
|
+
{ marker: "none", why: "explicit none => identity only, no optional topic preset" },
|
|
3995
|
+
{ marker: "standard", why: "omitted on a substantive round => standard preset" },
|
|
3996
|
+
{ marker: "role-owned", why: "role-owned methods / evidence obligations load regardless of preset" },
|
|
3997
|
+
{ marker: "unknown preset", why: "unknown preset / missing identity => Needs Context / Blocked, never infer PM" }
|
|
3998
|
+
];
|
|
3850
3999
|
function extractLoadOrderSection(text) {
|
|
3851
4000
|
const lines = text.split(/\r?\n/);
|
|
3852
4001
|
let start = -1;
|
|
@@ -3880,11 +4029,22 @@ function lintLoadOrder(skillTexts) {
|
|
|
3880
4029
|
continue;
|
|
3881
4030
|
const section = extractLoadOrderSection(text);
|
|
3882
4031
|
if (section === null) {
|
|
3883
|
-
violations.push(violation12("medium", "roles.loadorder.section.missing", `skill "${name}" has no Load Order / First action section — every mstar-* topic skill must declare its first read (mstar-harness-core §
|
|
4032
|
+
violations.push(violation12("medium", "roles.loadorder.section.missing", `skill "${name}" has no Load Order / First action section — every mstar-* topic skill must declare its first read (mstar-harness-core § 加载契约; mstar-roles § Load Order = single load-selection authority)`, `add a "## Load Order" section: topics name mstar-harness-core first; mstar-roles declares the Skill presets decision matrix`));
|
|
4033
|
+
continue;
|
|
4034
|
+
}
|
|
4035
|
+
if (name === "mstar-roles") {
|
|
4036
|
+
const lower = section.toLowerCase();
|
|
4037
|
+
const missing = HUB_BOOTSTRAP_ASSERTIONS.filter((a) => !lower.includes(a.marker.toLowerCase()));
|
|
4038
|
+
if (missing.length > 0) {
|
|
4039
|
+
violations.push(violation12("medium", "roles.loadorder.hub.bootstrap.missing", `skill "${name}" Load Order section is missing the hub bootstrap decision matrix: ${missing.map((m) => `"${m.marker}" (${m.why})`).join("; ")} (mstar-roles § Load Order = single load-selection authority)`, "declare identity-first, the Skill presets none/standard decision, role-owned methods, and the unknown-preset / missing-identity refusal in the Load Order section"));
|
|
4040
|
+
}
|
|
4041
|
+
if (!section.includes("mstar-harness-core")) {
|
|
4042
|
+
violations.push(violation12("medium", "roles.loadorder.core.missing", `skill "${name}" Load Order section does not point at mstar-harness-core — the hub bootstrap is exempt from core-first, but core remains the lifecycle/authorization conflict authority and global entry whenever loaded`, "keep the conditional mstar-harness-core pointer (global entry / conflict authority) in the Load Order section"));
|
|
4043
|
+
}
|
|
3884
4044
|
continue;
|
|
3885
4045
|
}
|
|
3886
4046
|
if (!section.includes("mstar-harness-core")) {
|
|
3887
|
-
violations.push(violation12("medium", "roles.loadorder.core.missing", `skill "${name}" Load Order section does not declare mstar-harness-core as its first dependency (mstar-harness-core §
|
|
4047
|
+
violations.push(violation12("medium", "roles.loadorder.core.missing", `skill "${name}" Load Order section does not declare mstar-harness-core as its first dependency (mstar-harness-core § 加载契约: directly-invoked topics keep core as first dependency; the mstar-roles hub bootstrap is the only exception)`, "name mstar-harness-core first in the Load Order section"));
|
|
3888
4048
|
}
|
|
3889
4049
|
}
|
|
3890
4050
|
return { ok: violations.length === 0, violations };
|
|
@@ -3920,6 +4080,17 @@ var FIVE_QUESTION_SECTIONS = [
|
|
|
3920
4080
|
{ key: "evidence", label: "Evidence", question: "what a correct result looks like (success criteria / evidence)" },
|
|
3921
4081
|
{ key: "references", label: "References", question: "additional resources to open when the main path is not enough" }
|
|
3922
4082
|
];
|
|
4083
|
+
function stripFrontmatter(text) {
|
|
4084
|
+
const lines = text.replace(/^\uFEFF/, "").split(/\r?\n/);
|
|
4085
|
+
if (lines.length === 0 || lines[0].trim() !== "---")
|
|
4086
|
+
return text;
|
|
4087
|
+
for (let i = 1;i < lines.length; i++) {
|
|
4088
|
+
if (lines[i].trim() === "---")
|
|
4089
|
+
return lines.slice(i + 1).join(`
|
|
4090
|
+
`);
|
|
4091
|
+
}
|
|
4092
|
+
return text;
|
|
4093
|
+
}
|
|
3923
4094
|
var HEADING_RE = /^#{1,6}\s+[^\r\n]+$/;
|
|
3924
4095
|
function collectHeadings(bodyText) {
|
|
3925
4096
|
const headings = [];
|
|
@@ -3935,6 +4106,16 @@ function collectHeadings(bodyText) {
|
|
|
3935
4106
|
}
|
|
3936
4107
|
return headings;
|
|
3937
4108
|
}
|
|
4109
|
+
function classifySkillLint(skillId) {
|
|
4110
|
+
const id = skillId ?? "";
|
|
4111
|
+
if (id === "mstar-harness-core")
|
|
4112
|
+
return { kind: "core", mode: null };
|
|
4113
|
+
if (id === "mstar-skill-authoring")
|
|
4114
|
+
return { kind: "authoring", mode: "authoring" };
|
|
4115
|
+
if (id.startsWith("mstar-"))
|
|
4116
|
+
return { kind: "runtime", mode: "runtime" };
|
|
4117
|
+
return { kind: "authoring", mode: "authoring" };
|
|
4118
|
+
}
|
|
3938
4119
|
var RUNTIME_HEADING_ALIASES = {
|
|
3939
4120
|
workflow: ["process", "playbook"],
|
|
3940
4121
|
"decision-rules": [
|
|
@@ -4176,7 +4357,7 @@ import { basename as basename2, join as join5, resolve as resolve6 } from "node:
|
|
|
4176
4357
|
|
|
4177
4358
|
// src/gates/workflow-selection.ts
|
|
4178
4359
|
import { existsSync as existsSync5, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
|
|
4179
|
-
import { dirname as dirname7, join as join3, relative as
|
|
4360
|
+
import { dirname as dirname7, join as join3, relative as relative4 } from "node:path";
|
|
4180
4361
|
var TERMINAL_STATUS_CACHE_MAX = 64;
|
|
4181
4362
|
var terminalStatusCache = new Map;
|
|
4182
4363
|
function terminalStatusOf(snapshotPath) {
|
|
@@ -4298,7 +4479,7 @@ function resolveReadWorkflow(harnessDir) {
|
|
|
4298
4479
|
if (verdict === undefined || !verdict.terminal)
|
|
4299
4480
|
continue;
|
|
4300
4481
|
if (best === undefined || verdict.mtimeMs > best.mtimeMs) {
|
|
4301
|
-
best = { workflowId: entry.name, dir: join3(
|
|
4482
|
+
best = { workflowId: entry.name, dir: join3(relative4(harnessDir, workflowsDir), entry.name), mtimeMs: verdict.mtimeMs };
|
|
4302
4483
|
}
|
|
4303
4484
|
}
|
|
4304
4485
|
for (const cachedPath of terminalStatusCache.keys()) {
|
|
@@ -5923,14 +6104,14 @@ function agentDigestKey(agent, cwd) {
|
|
|
5923
6104
|
|
|
5924
6105
|
// src/gates/status.ts
|
|
5925
6106
|
import { existsSync as existsSync14, readdirSync as readdirSync7 } from "node:fs";
|
|
5926
|
-
import { basename as basename5, join as join11, relative as
|
|
6107
|
+
import { basename as basename5, join as join11, relative as relative6, resolve as resolve10 } from "node:path";
|
|
5927
6108
|
var LOGGER_NAME = "mstar/status-gate";
|
|
5928
6109
|
function harnessDocKindOfTarget(harnessDir, targetPath) {
|
|
5929
6110
|
const resolved = resolve10(targetPath);
|
|
5930
6111
|
const name = basename5(resolved);
|
|
5931
6112
|
if (name !== STATUS_FILE && name !== WORKFLOW_SNAPSHOT_FILE && name !== PROJECT_REGISTER_FILE)
|
|
5932
6113
|
return null;
|
|
5933
|
-
const rel =
|
|
6114
|
+
const rel = relative6(harnessDir, resolved);
|
|
5934
6115
|
if (name === STATUS_FILE && rel === STATUS_FILE)
|
|
5935
6116
|
return "status";
|
|
5936
6117
|
let workflowDir;
|
|
@@ -5942,9 +6123,9 @@ function harnessDocKindOfTarget(harnessDir, targetPath) {
|
|
|
5942
6123
|
workflowDir = join11(harnessDir, "workflows");
|
|
5943
6124
|
projectDir = join11(harnessDir, "projects");
|
|
5944
6125
|
}
|
|
5945
|
-
if (name === WORKFLOW_SNAPSHOT_FILE && /^[^/]+\/snapshot\.json$/.test(
|
|
6126
|
+
if (name === WORKFLOW_SNAPSHOT_FILE && /^[^/]+\/snapshot\.json$/.test(relative6(workflowDir, resolved)))
|
|
5946
6127
|
return "snapshot";
|
|
5947
|
-
if (name === PROJECT_REGISTER_FILE && /^[^/]+\/residuals\.json$/.test(
|
|
6128
|
+
if (name === PROJECT_REGISTER_FILE && /^[^/]+\/residuals\.json$/.test(relative6(projectDir, resolved)))
|
|
5948
6129
|
return "register";
|
|
5949
6130
|
return null;
|
|
5950
6131
|
}
|
|
@@ -6093,17 +6274,6 @@ ${violations.map(formatViolation).join(`
|
|
|
6093
6274
|
this.violations = violations;
|
|
6094
6275
|
}
|
|
6095
6276
|
}
|
|
6096
|
-
function stripFrontmatter(text) {
|
|
6097
|
-
const lines = text.replace(/^\uFEFF/, "").split(/\r?\n/);
|
|
6098
|
-
if (lines.length === 0 || lines[0].trim() !== "---")
|
|
6099
|
-
return text;
|
|
6100
|
-
for (let i = 1;i < lines.length; i++) {
|
|
6101
|
-
if (lines[i].trim() === "---")
|
|
6102
|
-
return lines.slice(i + 1).join(`
|
|
6103
|
-
`);
|
|
6104
|
-
}
|
|
6105
|
-
return text;
|
|
6106
|
-
}
|
|
6107
6277
|
var EPHEMERAL_CODES = {
|
|
6108
6278
|
"task-artifact": "skill.ephemeral.task-artifact",
|
|
6109
6279
|
"sdd-deeplink": "skill.ephemeral.sdd-deeplink"
|
|
@@ -6116,19 +6286,23 @@ function ephemeralViolation(citation) {
|
|
|
6116
6286
|
message: `ephemeral citation \`${citation.match}\` on line ${citation.line} — durable skill text must reference in-repo artifacts only (knowledge conventions/skill-content-porting-discipline.md §3)`
|
|
6117
6287
|
};
|
|
6118
6288
|
}
|
|
6119
|
-
function lintSkillDoc(doc) {
|
|
6289
|
+
function lintSkillDoc(doc, options = {}) {
|
|
6120
6290
|
const violations = [];
|
|
6121
6291
|
const frontmatter = lintSkillFrontmatter(doc);
|
|
6122
6292
|
if (!frontmatter.ok)
|
|
6123
6293
|
violations.push(...frontmatter.violations);
|
|
6124
|
-
const
|
|
6125
|
-
if (
|
|
6126
|
-
|
|
6294
|
+
const profile = classifySkillLint(options.skillId);
|
|
6295
|
+
if (profile.mode !== null) {
|
|
6296
|
+
const body = lintFiveQuestion(stripFrontmatter(doc), profile.mode);
|
|
6297
|
+
if (!body.ok)
|
|
6298
|
+
violations.push(...body.violations);
|
|
6299
|
+
}
|
|
6127
6300
|
violations.push(...findEphemeralCitations(doc).map(ephemeralViolation));
|
|
6128
6301
|
return violations.length === 0 ? { ok: true, violations } : { ok: false, violations };
|
|
6129
6302
|
}
|
|
6130
6303
|
function lintSkillWrite(doc, options) {
|
|
6131
|
-
const
|
|
6304
|
+
const skillId = basename7(dirname9(resolve13(options.target)));
|
|
6305
|
+
const result = lintSkillDoc(doc, { skillId });
|
|
6132
6306
|
if (options.hard && !result.ok) {
|
|
6133
6307
|
throw new SkillLintVetoError(options.target, result.violations);
|
|
6134
6308
|
}
|
|
@@ -6176,7 +6350,7 @@ function gateSkillIntent(ctx, harnessDir, config, target) {
|
|
|
6176
6350
|
});
|
|
6177
6351
|
return;
|
|
6178
6352
|
}
|
|
6179
|
-
const result = lintSkillDoc(doc);
|
|
6353
|
+
const result = lintSkillDoc(doc, { skillId: basename7(dirname9(skillPath)) });
|
|
6180
6354
|
if (result.ok)
|
|
6181
6355
|
return;
|
|
6182
6356
|
const hard = resolveSeamHard(harnessDir, config);
|
|
@@ -8368,9 +8542,17 @@ function packagedCommandsDir() {
|
|
|
8368
8542
|
return;
|
|
8369
8543
|
}
|
|
8370
8544
|
}
|
|
8545
|
+
var FRONTMATTER_FIELD_RE = /^[ \t]*:[ \t]*(.+)$/;
|
|
8371
8546
|
function commandFrontmatterField(frontmatter, label) {
|
|
8372
|
-
|
|
8373
|
-
|
|
8547
|
+
for (const line of frontmatter.split(`
|
|
8548
|
+
`)) {
|
|
8549
|
+
if (!line.startsWith(label))
|
|
8550
|
+
continue;
|
|
8551
|
+
const match = FRONTMATTER_FIELD_RE.exec(line.slice(label.length));
|
|
8552
|
+
if (match)
|
|
8553
|
+
return match[1].trim();
|
|
8554
|
+
}
|
|
8555
|
+
return;
|
|
8374
8556
|
}
|
|
8375
8557
|
function unquote2(value) {
|
|
8376
8558
|
return value.length >= 2 && value.startsWith('"') && value.endsWith('"') ? value.slice(1, -1) : value;
|
package/dist/types.d.ts
CHANGED
|
@@ -108,8 +108,7 @@ export interface HarnessPlanView {
|
|
|
108
108
|
readonly doneAt: string | null;
|
|
109
109
|
/**
|
|
110
110
|
* The `status.json` plan row `metadata.iteration_refs` (array of iteration
|
|
111
|
-
* ids the plan is registered under). ALWAYS-present array
|
|
112
|
-
* `20260813-panel-quick-fixes` Task 2): a missing/non-array value projects
|
|
111
|
+
* ids the plan is registered under). ALWAYS-present array: a missing/non-array value projects
|
|
113
112
|
* to `[]` — the empty default, never an omitted field (lossless JSON).
|
|
114
113
|
*/
|
|
115
114
|
readonly iterationRefs: string[];
|
|
@@ -204,8 +203,7 @@ export interface MstarHarnessState {
|
|
|
204
203
|
* projected loose (`string`) like `HarnessPlanView.status`. ALWAYS-present
|
|
205
204
|
* nullable scalar (lossless JSON, never omitted): missing/empty → `null`;
|
|
206
205
|
* `null` on selection error (no snapshot read). Added for the slim
|
|
207
|
-
* `mstar:engine-status` digest
|
|
208
|
-
*/
|
|
206
|
+
* `mstar:engine-status` digest. */
|
|
209
207
|
readonly workflowType: string | null;
|
|
210
208
|
/**
|
|
211
209
|
* The selected workflow snapshot's top-level lifecycle `status`
|
|
@@ -269,8 +267,7 @@ export interface MstarHarnessState {
|
|
|
269
267
|
}
|
|
270
268
|
/**
|
|
271
269
|
* One agent-flow ledger event in the catalog view. Optional fields (dispatch/
|
|
272
|
-
* settle + the W-B2 `workflow-*` kinds — plan `
|
|
273
|
-
* Task 2) are OMITTED (never `undefined`-valued properties — `Session.append`
|
|
270
|
+
* settle + the W-B2 `workflow-*` kinds — plan ) are OMITTED (never `undefined`-valued properties — `Session.append`
|
|
274
271
|
* rejects non-lossless JSON) using the `iterationViolationView` omit pattern.
|
|
275
272
|
*/
|
|
276
273
|
export interface AgentFlowEventView {
|
|
@@ -292,7 +289,7 @@ export interface AgentFlowEventView {
|
|
|
292
289
|
/** Settle duration in ms (settle events only, when recorded). */
|
|
293
290
|
readonly durationMs?: number | null;
|
|
294
291
|
/**
|
|
295
|
-
* Settle rows only
|
|
292
|
+
* Settle rows only : true when
|
|
296
293
|
* the settle carries the PAIRED dispatch's identity (`role`/`planId`/
|
|
297
294
|
* `taskId` — same fields + semantics as the dispatch event) — the client
|
|
298
295
|
* pairs exactly on that identity. ABSENT on unpaired (legacy) settles →
|
|
@@ -7,7 +7,7 @@ input: "[no args]"
|
|
|
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 gate SSOT → **`mstar-iteration`**
|
|
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-*`。
|
|
11
11
|
|
|
12
12
|
## Phase flow(禁止跳步)
|
|
13
13
|
|
|
@@ -21,25 +21,25 @@ Phase 2–5 共享内容(PM invariants、assignment preflight、session todos
|
|
|
21
21
|
|
|
22
22
|
## Boot
|
|
23
23
|
|
|
24
|
-
按 **`mstar-iteration`** Load order 加载(`mstar-harness-core` → `mstar-roles` → `references/project-manager.md` → `mstar-iteration
|
|
24
|
+
按 **`mstar-iteration`** Load order 加载(`mstar-harness-core` → `mstar-roles` → `references/project-manager.md` → `mstar-iteration`(按当前 Phase 查 route map,只加载一行 detail)+ `command-shared-invariants.md` → `mstar-compound` → `mstar-dispatch-gates` + host reference → **`mstar-sdd`**(first implement dispatch 前)→ `mstar-review-qc`(first QC 前)→ `mstar-artifacts` / `mstar-conventions` / `mstar-branch-worktree` → **`mstar-iteration/references/phase-2-worktree-lease.md`**)。完整 load list → **`mstar-roles`**。
|
|
25
25
|
|
|
26
26
|
## Phase 2: Autonomous Execute
|
|
27
27
|
|
|
28
|
-
Execute **`mstar-iteration
|
|
28
|
+
Execute **`mstar-iteration/references/phase-2-worktree-lease.md`** §2.0–§2.5 exactly(§2.0 五道闸 → §2.1 session todos → §2.2 backlog → §2.3 integration branch + control worktree → §2.4 per-plan loop(lease-gated;SDD per-task;QC tri N=3 + QA;serial merge)→ §2.5 dispatch-first;§2.6 push 纪律 → main skill `## 2.6`)。全部 plan `Done` → **STOP** → 打印 `## Phase 3: iteration-close`。
|
|
29
29
|
|
|
30
30
|
**Assignment preflight**:每次 implement/QC/QA 派发前按 **`mstar-iteration/references/command-shared-invariants.md`** 执行。
|
|
31
31
|
|
|
32
32
|
## Phase 3: iteration-close
|
|
33
33
|
|
|
34
|
-
当 **every** plan 为 `Done`:**STOP** per-plan loop → 打印 **`## Phase 3: iteration-close`** → execute **`mstar-iteration
|
|
34
|
+
当 **every** plan 为 `Done`:**STOP** per-plan loop → 打印 **`## Phase 3: iteration-close`** → execute **`mstar-iteration/references/phase-3-iteration-close.md`** §3.0→§3.5(§3.1 entry checklist HARD GATE;§3.2 compound + package promotion;§3.4 `status: completed` + `end_date`)→ §3.5 exit 全 `[x]` 后打印 **`## Phase 4: Create PR`**。
|
|
35
35
|
|
|
36
36
|
## Phase 4: Create PR
|
|
37
37
|
|
|
38
|
-
Execute **`mstar-iteration
|
|
38
|
+
Execute **`mstar-iteration/references/phase-4-5-pr-delivery.md`** §4:打印 `## Phase 4: Create PR` → resolve `metadata.target_branch`(缺失 → **STOP**,never default `main`/`master`)→ 创建 PR `spec_integration_branch` → `target_branch` → 记录 PR URL + number → 勾掉 `phase-4-create-pr` → **Immediately** 打印 **`## Phase 5: PR merge-ready`**(**禁止**在此停止或汇报 Done)。
|
|
39
39
|
|
|
40
40
|
## Phase 5: PR merge-ready(babysit loop)
|
|
41
41
|
|
|
42
|
-
Execute **`mstar-iteration
|
|
42
|
+
Execute **`mstar-iteration/references/phase-4-5-pr-delivery.md`** §5.0–§5.2(**§5.1a push cadence HARD**)。**§5.5 exit checklist 全 `[x]` = 本 command Done.**
|
|
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
|
|
|
@@ -16,7 +16,7 @@ Run a **full** Morning Star iteration with minimal human intervention. **Done =
|
|
|
16
16
|
| `iteration-drive` | Phase 2→5 re-entry / resume on an already locked iteration |
|
|
17
17
|
| **`iteration-loop`** | Phase 1→5 end-to-end; **autonomous** direction lock |
|
|
18
18
|
|
|
19
|
-
Phase gate SSOT → **`mstar-iteration`**
|
|
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
|
|
|
21
21
|
## Args(最多 2 个)
|
|
22
22
|
|
|
@@ -29,7 +29,7 @@ Phase gate SSOT → **`mstar-iteration`** §1–§5. This command is a **consume
|
|
|
29
29
|
| `direction` | Iteration direction / feedback constraint (free text) | Code-first research → **auto-lock recommended** |
|
|
30
30
|
| `scale` | `S` \| `M` \| `L` \| `XL` | **`M`** |
|
|
31
31
|
|
|
32
|
-
**Scale budget**(写入 compass;约束 **业务** plan 数量)→ **`mstar-iteration`** §1.2 + `references/autonomous-direction-lock.md`:
|
|
32
|
+
**Scale budget**(写入 compass;约束 **业务** plan 数量)→ **`mstar-iteration/references/phase-1-prepare.md`** §1.2 + `references/autonomous-direction-lock.md`:
|
|
33
33
|
|
|
34
34
|
- **S** → 1 business plan
|
|
35
35
|
- **M** → 2–3 business plans
|
|
@@ -52,7 +52,7 @@ Execute **`mstar-iteration` §2.6**(Continuous execution SSOT)+ **`mstar-ite
|
|
|
52
52
|
|
|
53
53
|
## Boot
|
|
54
54
|
|
|
55
|
-
按 **`mstar-iteration`** Load order 加载(`mstar-harness-core` → `mstar-roles` → `references/project-manager.md` → `mstar-iteration
|
|
55
|
+
按 **`mstar-iteration`** Load order 加载(`mstar-harness-core` → `mstar-roles` → `references/project-manager.md` → `mstar-iteration`(按当前 Phase 查 route map,只加载一行 detail)+ `command-shared-invariants.md` → `mstar-dispatch-gates` → `mstar-phase-gates` → `mstar-conventions` / `mstar-artifacts` → `mstar-host` → `mstar-compound`(Phase 3 前)→ **`mstar-sdd`**(first implement 前)→ `mstar-review-qc`(first QC 前)→ `mstar-branch-worktree` → **`mstar-iteration/references/phase-2-worktree-lease.md`**)。完整 load list → **`mstar-roles`**。
|
|
56
56
|
|
|
57
57
|
**Session todos(loop 专属;Phase 2–5 共享 rows → `command-shared-invariants.md`)**:
|
|
58
58
|
|
|
@@ -62,7 +62,7 @@ Execute **`mstar-iteration` §2.6**(Continuous execution SSOT)+ **`mstar-ite
|
|
|
62
62
|
|
|
63
63
|
## Phase 1: Autonomous start
|
|
64
64
|
|
|
65
|
-
Execute **`mstar-iteration
|
|
65
|
+
Execute **`mstar-iteration/references/phase-1-prepare.md`**(§1.1–§1.6;**autonomous** direction lock + scale budget + branch resolve SSOT → `references/autonomous-direction-lock.md`):
|
|
66
66
|
|
|
67
67
|
### 1–4. Research → Explore → Lock → Write
|
|
68
68
|
|
|
@@ -70,7 +70,7 @@ Survey structured harness dirs(`{HARNESS_DIR}/status.json`、`{ITERATION_DIR}/
|
|
|
70
70
|
|
|
71
71
|
### 5. Review & Edit Chain(HARD GATE)
|
|
72
72
|
|
|
73
|
-
Execute **`mstar-iteration` §1.6**:`product-manager` → `architect` → `writing-specialist` 顺序 invoke(**禁止** `{KNOWLEDGE_DIR}/` 新增;corpus hygiene)→ PM lock。**Assignment preflight** per **`command-shared-invariants.md`**。
|
|
73
|
+
Execute **`mstar-iteration/references/phase-1-prepare.md` §1.6**:`product-manager` → `architect` → `writing-specialist` 顺序 invoke(**禁止** `{KNOWLEDGE_DIR}/` 新增;corpus hygiene)→ PM lock。**Assignment preflight** per **`command-shared-invariants.md`**。
|
|
74
74
|
|
|
75
75
|
**Pre-commit checklist**(print before §6;all `[x]`):
|
|
76
76
|
|
|
@@ -84,7 +84,7 @@ Execute **`mstar-iteration` §1.6**:`product-manager` → `architect` → `wri
|
|
|
84
84
|
|
|
85
85
|
### 6. Integration Branch
|
|
86
86
|
|
|
87
|
-
Per **`mstar-iteration` §2.3**(create from `iteration_base_branch`;register branch fields;commit docs;push)。**STOP** if base/target missing。**Immediately** print `## Phase 2: Autonomous Execute` → continue(勾掉 `phase-1-autonomous-start`)。
|
|
87
|
+
Per **`mstar-iteration/references/phase-2-worktree-lease.md` §2.3**(create from `iteration_base_branch`;register branch fields;commit docs;push)。**STOP** if base/target missing。**Immediately** print `## Phase 2: Autonomous Execute` → continue(勾掉 `phase-1-autonomous-start`)。
|
|
88
88
|
|
|
89
89
|
---
|
|
90
90
|
|
|
@@ -92,7 +92,7 @@ Per **`mstar-iteration` §2.3**(create from `iteration_base_branch`;register
|
|
|
92
92
|
|
|
93
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`)。**Assignment preflight** per **`command-shared-invariants.md`**。
|
|
94
94
|
|
|
95
|
-
**Loop 特有**:Phase 5 push cadence(HARD)→ **`mstar-iteration
|
|
95
|
+
**Loop 特有**:Phase 5 push cadence(HARD)→ **`mstar-iteration/references/phase-4-5-pr-delivery.md`** §5.1a;exit checklist → §5.2(同 reference)。
|
|
96
96
|
|
|
97
97
|
**Then** report: iteration id, locked direction + scale, plans completed, compound summary, PR link, merge-ready evidence。
|
|
98
98
|
|
|
@@ -30,7 +30,7 @@ Start a new Morning Star harness iteration. **Phase 1 is not complete until the
|
|
|
30
30
|
|-----------------|------------------------|
|
|
31
31
|
| 自己 Edit compass/plans/specs 冒充 product-manager / architect / writing-specialist 的审查编辑 | §5.1 → §5.2 → §5.3 **顺序**各 **1 次 invoke**;上一角色返回后再派发下一角色 |
|
|
32
32
|
| 只写 `## Assignment` 或 checklist 就声称 review chain 完成 | **几条角色 ⇒ 几条 invoke**;零 invoke = `dispatch incomplete`(`mstar-dispatch-gates`) |
|
|
33
|
-
| §5 完成前 commit / 创建 integration 分支 | 5.4 PM lock 在 subagent 返回且磁盘产物已修订之后(`mstar-iteration` §1.6) |
|
|
33
|
+
| §5 完成前 commit / 创建 integration 分支 | 5.4 PM lock 在 subagent 返回且磁盘产物已修订之后(`mstar-iteration/references/phase-1-prepare.md` §1.6) |
|
|
34
34
|
|
|
35
35
|
派发细则 → **`mstar-dispatch-gates`**(specialist review-and-edit dispatch)+ **`mstar-host`**(宿主 invoke 能力)。**不得**在 PM 线程加载其他 role reference 代劳。
|
|
36
36
|
|
|
@@ -49,7 +49,7 @@ Start a new Morning Star harness iteration. **Phase 1 is not complete until the
|
|
|
49
49
|
|
|
50
50
|
## 0. Boot
|
|
51
51
|
|
|
52
|
-
按 **`mstar-iteration`** Load order 加载(`mstar-harness-core` → `mstar-roles` → `references/project-manager.md` → `mstar-iteration
|
|
52
|
+
按 **`mstar-iteration`** Load order 加载(`mstar-harness-core` → `mstar-roles` → `references/project-manager.md` → `mstar-iteration`(route map:start → **`references/phase-1-prepare.md`**)+ `mstar-phase-gates` + `mstar-dispatch-gates` + `mstar-conventions/artifacts` + `mstar-host` → active host reference)。Cursor Plan mode 另读 **`cursor-plan-mode-bridge.md`**(`mstar-iteration` Phase 1 in Plan mode)。完整 load list → **`mstar-roles`**。
|
|
53
53
|
|
|
54
54
|
**若 Cursor Plan mode 活跃 → 进入 §P;否则继续 §1。**
|
|
55
55
|
|
|
@@ -76,17 +76,17 @@ Scope **2–4** candidates targeting **product completeness**(default to defer
|
|
|
76
76
|
|
|
77
77
|
> **非 Plan 路径**。Cursor Plan mode 用 §P feedback loop + deferred grill(主路径不是 grill)。
|
|
78
78
|
|
|
79
|
-
**Direction lock mode: `interactive`**(`mstar-iteration` §1.2 默认;本命令不使用 `autonomous`)。This command bundles a **non-`mstar-*`** skill at `skills/grill-me/SKILL.md` — **only this command step** references it.
|
|
79
|
+
**Direction lock mode: `interactive`**(`mstar-iteration/references/phase-1-prepare.md` §1.2 默认;本命令不使用 `autonomous`)。This command bundles a **non-`mstar-*`** skill at `skills/grill-me/SKILL.md` — **only this command step** references it.
|
|
80
80
|
|
|
81
|
-
**Before this step:** Read `skills/grill-me/SKILL.md`. Run **grill-me** to stress-test candidate directions with the user: walk through trade-offs, converge on a **single iteration direction** with shared understanding, document locked direction + success criteria + non-goals。**If `direction` arg given** — seed grill-me with it (still interactive; the hint does **not** skip grill-me)。Confirm delivery branch policy(`iteration_base_branch` / `target_branch`)per **`mstar-iteration` §1.2** — **Do not default to `main`/`master` just because those names exist.**
|
|
81
|
+
**Before this step:** Read `skills/grill-me/SKILL.md`. Run **grill-me** to stress-test candidate directions with the user: walk through trade-offs, converge on a **single iteration direction** with shared understanding, document locked direction + success criteria + non-goals。**If `direction` arg given** — seed grill-me with it (still interactive; the hint does **not** skip grill-me)。Confirm delivery branch policy(`iteration_base_branch` / `target_branch`)per **`mstar-iteration/references/phase-1-prepare.md` §1.2** — **Do not default to `main`/`master` just because those names exist.**
|
|
82
82
|
|
|
83
83
|
## 4. Write Compass & Plans
|
|
84
84
|
|
|
85
|
-
Produce harness artifacts per **`mstar-iteration` §1.3–§1.5**(template: `mstar-iteration/references/iteration-compass-template.md`):compass(frontmatter **must** include `iteration_base_branch`、`target_branch`、`status: active`)、plans、`status.json` 登记(§1.5)、`{ITERATION_DIR}/README.md` 索引(一行 = 一次迭代)、package dirs(`{ITERATION_DIR}/<iteration-id>/{guides,specs}/`)。
|
|
85
|
+
Produce harness artifacts per **`mstar-iteration/references/phase-1-prepare.md` §1.3–§1.5**(template: `mstar-iteration/references/iteration-compass-template.md`):compass(frontmatter **must** include `iteration_base_branch`、`target_branch`、`status: active`)、plans、`status.json` 登记(§1.5)、`{ITERATION_DIR}/README.md` 索引(一行 = 一次迭代)、package dirs(`{ITERATION_DIR}/<iteration-id>/{guides,specs}/`)。
|
|
86
86
|
|
|
87
87
|
## 5. Review & Edit Chain(HARD GATE — do not commit before this)
|
|
88
88
|
|
|
89
|
-
Execute **`mstar-iteration` §1.6**(SSOT):顺序 `product-manager` → `architect` → `writing-specialist` → PM lock(**禁止**并行三 roles;OpenCode plain role id — `mstar-host/references/opencode.md`);**禁止** `{KNOWLEDGE_DIR}/` 新增;writing-specialist corpus hygiene(`iteration-artifact-boundaries.md` + `iteration-corpus-hygiene.md`)。Tool rule → **`mstar-dispatch-gates`** specialist review-and-edit(每 role 1 invoke,等磁盘修订返回)。Exception: user explicitly waives subagent dispatch ("PM-only review").
|
|
89
|
+
Execute **`mstar-iteration/references/phase-1-prepare.md` §1.6**(SSOT):顺序 `product-manager` → `architect` → `writing-specialist` → PM lock(**禁止**并行三 roles;OpenCode plain role id — `mstar-host/references/opencode.md`);**禁止** `{KNOWLEDGE_DIR}/` 新增;writing-specialist corpus hygiene(`iteration-artifact-boundaries.md` + `iteration-corpus-hygiene.md`)。Tool rule → **`mstar-dispatch-gates`** specialist review-and-edit(每 role 1 invoke,等磁盘修订返回)。Exception: user explicitly waives subagent dispatch ("PM-only review").
|
|
90
90
|
|
|
91
91
|
**Assignment preflight**:每次 invoke 前按 **`mstar-iteration/references/command-shared-invariants.md`** 执行(warn-only + `enforcement: hard` fail-fast;bin 缺失静默跳过)。
|
|
92
92
|
|
|
@@ -109,13 +109,13 @@ PM must print this block before §6; all `[ ]` must be `[x]`:
|
|
|
109
109
|
|
|
110
110
|
## 6. Integration Branch
|
|
111
111
|
|
|
112
|
-
Per **`mstar-iteration` §2.3**:create `spec_integration_branch` from `iteration_base_branch`(`git fetch` → `git checkout -b <spec_integration_branch> <iteration_base_branch>`);register `iteration_base_branch` / `spec_integration_branch` / `target_branch` in compass frontmatter **and** `status.json` metadata;commit docs;push。**STOP** if `iteration_base_branch` / `target_branch` missing — never default `main`/`master`.
|
|
112
|
+
Per **`mstar-iteration/references/phase-2-worktree-lease.md` §2.3**:create `spec_integration_branch` from `iteration_base_branch`(`git fetch` → `git checkout -b <spec_integration_branch> <iteration_base_branch>`);register `iteration_base_branch` / `spec_integration_branch` / `target_branch` in compass frontmatter **and** `status.json` metadata;commit docs;push。**STOP** if `iteration_base_branch` / `target_branch` missing — never default `main`/`master`.
|
|
113
113
|
|
|
114
114
|
---
|
|
115
115
|
|
|
116
116
|
## 7. Phase 2–5(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
|
|
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`)。Shared invariants / preflight / STOP → **`mstar-iteration/references/command-shared-invariants.md`**。
|
|
119
119
|
|
|
120
120
|
**Done = Phase 5 §5.5 exit checklist 全 `[x]`**(同 `iteration-drive`)。**Then** report: iteration id, direction lock summary, plans completed, compound summary, PR link, merge-ready evidence(CI snapshot + review resolution + Greptile if applicable)。
|
|
121
121
|
|