@siming-org/cli 0.8.14 → 0.8.16
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/dist/index.js
CHANGED
|
@@ -838,6 +838,9 @@ function naIfRepoUnavailable(ctx) {
|
|
|
838
838
|
function na(reason) {
|
|
839
839
|
return { type: "", status: "not_applicable", detail: reason };
|
|
840
840
|
}
|
|
841
|
+
function hasSuccessorNode(ctx) {
|
|
842
|
+
return (ctx.edges ?? []).some((e) => e.from === ctx.nodeId);
|
|
843
|
+
}
|
|
841
844
|
function fail2(ctx, type, rootCause, fix) {
|
|
842
845
|
return { type, status: "fail", detail: `${rootCause}\u3002\u4FEE\u590D\uFF1A${fix}\uFF08\u5F53\u524D nodeId=${ctx.nodeId}\uFF09` };
|
|
843
846
|
}
|
|
@@ -921,8 +924,7 @@ async function checkArchiveMerged(ctx) {
|
|
|
921
924
|
if (ctx.vcs.archiveToBase === false) {
|
|
922
925
|
return { type, status: "not_applicable", detail: "\u9879\u76EE vcs.archiveToBase=false\uFF08\u58F0\u660E\u65E0\u5F52\u6863\u5408\u5E76\u6D41\u7A0B\uFF09" };
|
|
923
926
|
}
|
|
924
|
-
|
|
925
|
-
if (hasSuccessor) {
|
|
927
|
+
if (hasSuccessorNode(ctx)) {
|
|
926
928
|
return {
|
|
927
929
|
type,
|
|
928
930
|
status: "not_applicable",
|
|
@@ -933,31 +935,92 @@ async function checkArchiveMerged(ctx) {
|
|
|
933
935
|
return fail2(ctx, type, "\u57FA\u7840\u5206\u652F\u672A\u77E5\uFF08ACCEPT \u524D\u7F6E\uFF1AALIGN \u5E94\u5DF2\u843D\u76D8 baseBranch\uFF09", "record-set \u5199 ALIGN.baseBranch\uFF0C\u6216 siming project update --vcs-base-branch <\u5206\u652F>");
|
|
934
936
|
}
|
|
935
937
|
const base = ctx.baseBranch;
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
return { status: "fail", detail: `git fetch origin ${base} \u5931\u8D25\u2014\u2014\u672C\u5730\u4E0E\u8FDC\u7A0B\u4E00\u81F4\u6027\u65E0\u4ECE\u5224\u5B9A\uFF08\u62D2\u6309\u9648\u65E7 ref \u8BEF\u5224\uFF09\uFF1B\u68C0\u67E5\u7F51\u7EDC/\u8FDC\u7A0B\u53EF\u8FBE\u540E\u91CD\u8BD5` };
|
|
944
|
-
}
|
|
945
|
-
const ancestor = await ctx.runGit(["merge-base", "--is-ancestor", "HEAD", base], repo);
|
|
946
|
-
if (!ancestor.ok) {
|
|
947
|
-
return { status: "fail", detail: `\u57FA\u7840\u5206\u652F ${base} \u5C1A\u672A\u5305\u542B\u4EFB\u52A1\u5206\u652F HEAD\uFF08\u672A\u5408\u5E76\uFF09\u2014\u2014git checkout ${base} && git merge --no-ff <\u4EFB\u52A1\u5206\u652F> && git push` };
|
|
948
|
-
}
|
|
949
|
-
const merges = await ctx.runGit(["log", "--merges", "-1", "--format=%P", base], repo);
|
|
950
|
-
const parents = merges.ok ? merges.stdout.trim().split(/\s+/) : [];
|
|
951
|
-
if (parents.length !== 2) {
|
|
952
|
-
return { status: "fail", detail: `\u672A\u68C0\u6D4B\u5230 --no-ff \u5408\u5E76\u63D0\u4EA4\uFF08\u6700\u8FD1\u4E00\u6B21\u5408\u5E76 parents=${parents.length}\uFF09\u2014\u2014\u5408\u5E76\u5FC5\u987B\u4F7F\u7528 --no-ff\uFF08\u4FDD\u7559\u5408\u5E76\u8BB0\u5F55\uFF09` };
|
|
938
|
+
let anchorModeRepos = 0;
|
|
939
|
+
let anchorHitRepos = 0;
|
|
940
|
+
const anchorMissRepos = [];
|
|
941
|
+
const outcome = await perRepoCheck(ctx, type, async (repo) => {
|
|
942
|
+
const branch = await currentBranch(ctx, repo);
|
|
943
|
+
if (branch === null) {
|
|
944
|
+
return { status: "fail", detail: "\u65E0\u6CD5\u8BFB\u53D6\u5F53\u524D\u5206\u652F\uFF08git rev-parse --abbrev-ref HEAD \u5931\u8D25\u2014\u2014\u7591\u4F3C\u635F\u574F\u4ED3\uFF09\u2014\u2014\u786E\u8BA4\u4ED3\u5E93\u72B6\u6001\u540E\u91CD\u8BD5" };
|
|
953
945
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
946
|
+
if (branch === base) {
|
|
947
|
+
anchorModeRepos += 1;
|
|
948
|
+
const judged = await judgeArchiveByAnchor(ctx, repo, base);
|
|
949
|
+
if (judged.status !== "not_applicable") anchorHitRepos += 1;
|
|
950
|
+
else anchorMissRepos.push(repo);
|
|
951
|
+
return judged;
|
|
958
952
|
}
|
|
959
|
-
return
|
|
953
|
+
return judgeArchiveByHead(ctx, repo, base);
|
|
960
954
|
});
|
|
955
|
+
if (outcome.status === "not_applicable" && anchorModeRepos === ctx.repos.length && anchorHitRepos === 0) {
|
|
956
|
+
const anchor = ctx.nodeRecords["INTEGRATE"]?.verifiedCommit ?? "";
|
|
957
|
+
return fail2(
|
|
958
|
+
ctx,
|
|
959
|
+
type,
|
|
960
|
+
`\u9A8C\u8BC1\u7248\u672C ${anchor} \u4E0D\u5728\u4EFB\u4F55\u951A\u70B9\u6A21\u5F0F\u4ED3\uFF08${anchorMissRepos.join(", ")}\uFF1B\u5F52\u6863\u5408\u5E76\u65E0\u4ECE\u590D\u6838\uFF0C\u62D2\u7EDD\u6574\u4F53\u514D\u68C0\uFF09`,
|
|
961
|
+
"\u786E\u8BA4 INTEGRATE.verifiedCommit \u4E0E\u4EFB\u52A1\u4ED3\u96C6\u5408\u5339\u914D\uFF1B\u591A\u4ED3\u5DE5\u4F5C\u76EE\u5F55\u987B\u4ECE\u6839\u76EE\u5F55\u542F\u52A8\u4EE5\u5B8C\u6574\u626B\u63CF"
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
return outcome;
|
|
965
|
+
}
|
|
966
|
+
async function judgeArchiveByHead(ctx, repo, base) {
|
|
967
|
+
const count = await ctx.runGit(["rev-list", "--count", `${base}..HEAD`], repo);
|
|
968
|
+
if (count.ok && count.stdout.trim() === "0") {
|
|
969
|
+
return { status: "not_applicable", detail: `\u4EFB\u52A1\u5206\u652F\u76F8\u5BF9 ${base} \u96F6\u63D0\u4EA4\uFF08\u65E0\u4EE3\u7801\u6539\u52A8\uFF0C\u65E0\u9700\u5408\u5E76\uFF09` };
|
|
970
|
+
}
|
|
971
|
+
const ancestor = await ctx.runGit(["merge-base", "--is-ancestor", "HEAD", base], repo);
|
|
972
|
+
if (!ancestor.ok) {
|
|
973
|
+
return { status: "fail", detail: `\u57FA\u7840\u5206\u652F ${base} \u5C1A\u672A\u5305\u542B\u4EFB\u52A1\u5206\u652F HEAD\uFF08\u672A\u5408\u5E76\uFF09\u2014\u2014git checkout ${base} && git merge --no-ff <\u4EFB\u52A1\u5206\u652F> && git push` };
|
|
974
|
+
}
|
|
975
|
+
const merges = await ctx.runGit(["log", "--merges", "-1", "--format=%P", base], repo);
|
|
976
|
+
const parents = merges.ok ? merges.stdout.trim().split(/\s+/) : [];
|
|
977
|
+
if (parents.length !== 2) {
|
|
978
|
+
return { status: "fail", detail: `\u672A\u68C0\u6D4B\u5230 --no-ff \u5408\u5E76\u63D0\u4EA4\uFF08\u6700\u8FD1\u4E00\u6B21\u5408\u5E76 parents=${parents.length}\uFF09\u2014\u2014\u5408\u5E76\u5FC5\u987B\u4F7F\u7528 --no-ff\uFF08\u4FDD\u7559\u5408\u5E76\u8BB0\u5F55\uFF09` };
|
|
979
|
+
}
|
|
980
|
+
const pushFailure = await judgePushConsistent(ctx, repo, base);
|
|
981
|
+
if (pushFailure !== null) return pushFailure;
|
|
982
|
+
return { status: "pass", detail: `\u5DF2 --no-ff \u5408\u5165 ${base} \u4E14\u4E0E\u8FDC\u7A0B\u4E00\u81F4` };
|
|
983
|
+
}
|
|
984
|
+
async function judgeArchiveByAnchor(ctx, repo, base) {
|
|
985
|
+
const anchor = ctx.nodeRecords["INTEGRATE"]?.verifiedCommit;
|
|
986
|
+
if (!anchor) {
|
|
987
|
+
return { status: "fail", detail: "INTEGRATE \u8BB0\u5F55\u7F3A verifiedCommit\uFF08\u5F52\u6863\u951A\u70B9\u7F3A\u5931\uFF0C\u65E0\u6CD5\u786E\u8BA4\u9A8C\u8BC1\u7248\u672C\u5DF2\u5408\u5165\uFF09\u2014\u2014\u56DE\u8865 INTEGRATE record-set verifiedCommit \u540E\u91CD\u8BD5" };
|
|
988
|
+
}
|
|
989
|
+
const probe = await ctx.runGit(["cat-file", "-e", anchor], repo);
|
|
990
|
+
if (!probe.ok) {
|
|
991
|
+
return { status: "not_applicable", detail: `\u4E0D\u542B\u951A\u70B9\u63D0\u4EA4 ${anchor}\uFF08\u975E\u672C\u4EFB\u52A1\u4ED3\uFF0C\u514D\u68C0\uFF09` };
|
|
992
|
+
}
|
|
993
|
+
const ancestor = await ctx.runGit(["merge-base", "--is-ancestor", anchor, base], repo);
|
|
994
|
+
if (!ancestor.ok) {
|
|
995
|
+
return { status: "fail", detail: `\u57FA\u7840\u5206\u652F ${base} \u5C1A\u672A\u5305\u542B\u9A8C\u8BC1\u7248\u672C ${anchor}\uFF08\u4EFB\u52A1\u5206\u652F\u672A\u5408\u5E76\uFF09\u2014\u2014git checkout ${base} && git merge --no-ff <\u4EFB\u52A1\u5206\u652F> && git push` };
|
|
996
|
+
}
|
|
997
|
+
const merges = await ctx.runGit(["rev-list", "--merges", "--ancestry-path", `${anchor}..${base}`], repo);
|
|
998
|
+
if (!merges.ok) {
|
|
999
|
+
return { status: "fail", detail: `git rev-list --merges \u5931\u8D25\uFF1A${firstLine(merges.stderr)}\u2014\u2014\u68C0\u67E5\u4ED3\u5E93\u53EF\u7528\u6027` };
|
|
1000
|
+
}
|
|
1001
|
+
const mergeList = merges.stdout.split("\n").map((l) => l.trim()).filter((l) => l !== "");
|
|
1002
|
+
const earliest = mergeList[mergeList.length - 1];
|
|
1003
|
+
if (earliest === void 0) {
|
|
1004
|
+
return {
|
|
1005
|
+
status: "fail",
|
|
1006
|
+
detail: `\u672A\u68C0\u6D4B\u5230 --no-ff \u5408\u5E76\u63D0\u4EA4\uFF08${anchor} \u81F3 ${base} \u4E4B\u95F4\u65E0\u5408\u5E76\u8BB0\u5F55\uFF09\u2014\u2014\u82E5\u4EFB\u52A1\u5206\u652F\u66FE\u4EE5 fast-forward / squash / rebase \u5408\u5165\uFF0C\u56DE\u9000\u5E76\u6309 --no-ff \u91CD\u5EFA\u5408\u5E76\u63D0\u4EA4\uFF1B\u82E5\u4EFB\u52A1\u5206\u652F\u81EA\u521B\u5EFA\u4EE5\u6765\u96F6\u63D0\u4EA4\uFF08\u65E0\u4EE3\u7801\u5F52\u6863\uFF09\uFF0C\u7ECF\u7528\u6237\u660E\u793A\u540E\u53EF force \u63A8\u8FDB\u5E76\u7559\u75D5`
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
const pushFailure = await judgePushConsistent(ctx, repo, base);
|
|
1010
|
+
if (pushFailure !== null) return pushFailure;
|
|
1011
|
+
return { status: "pass", detail: `\u5DF2 --no-ff \u5408\u5165 ${base}\uFF08\u951A\u70B9 ${anchor}\uFF0C\u5408\u5E76\u63D0\u4EA4 ${earliest}\uFF09\u4E14\u4E0E\u8FDC\u7A0B\u4E00\u81F4` };
|
|
1012
|
+
}
|
|
1013
|
+
async function judgePushConsistent(ctx, repo, base) {
|
|
1014
|
+
const fetch2 = await ctx.runGit(["fetch", "origin", base], repo);
|
|
1015
|
+
if (!fetch2.ok) {
|
|
1016
|
+
return { status: "fail", detail: `git fetch origin ${base} \u5931\u8D25\u2014\u2014\u672C\u5730\u4E0E\u8FDC\u7A0B\u4E00\u81F4\u6027\u65E0\u4ECE\u5224\u5B9A\uFF08\u62D2\u6309\u9648\u65E7 ref \u8BEF\u5224\uFF09\uFF1B\u68C0\u67E5\u7F51\u7EDC/\u8FDC\u7A0B\u53EF\u8FBE\u540E\u91CD\u8BD5` };
|
|
1017
|
+
}
|
|
1018
|
+
const localBase = await ctx.runGit(["rev-parse", base], repo);
|
|
1019
|
+
const remoteBase = await ctx.runGit(["rev-parse", `origin/${base}`], repo);
|
|
1020
|
+
if (!localBase.ok || !remoteBase.ok || localBase.stdout.trim() !== remoteBase.stdout.trim()) {
|
|
1021
|
+
return { status: "fail", detail: `\u672C\u5730 ${base} \u4E0E origin/${base} \u4E0D\u4E00\u81F4\uFF08\u5408\u5E76\u7ED3\u679C\u672A\u63A8\u9001\u6216\u672A\u62C9\u53D6\uFF09\u2014\u2014git push origin ${base}\uFF08\u6216\u5148 pull \u5BF9\u9F50\uFF09` };
|
|
1022
|
+
}
|
|
1023
|
+
return null;
|
|
961
1024
|
}
|
|
962
1025
|
async function checkStayOnBase(ctx) {
|
|
963
1026
|
const type = "git-stay-on-base";
|
|
@@ -993,6 +1056,16 @@ function decisionByTopic(record, topic) {
|
|
|
993
1056
|
const hit = record?.decisions.find((d) => d.topic === topic && d.decision.trim() !== "");
|
|
994
1057
|
return hit ?? null;
|
|
995
1058
|
}
|
|
1059
|
+
function decisionAcrossTask(ctx, topic) {
|
|
1060
|
+
const direct = decisionByTopic(ctx.record, topic);
|
|
1061
|
+
if (direct !== null) return direct;
|
|
1062
|
+
for (const record of Object.values(ctx.nodeRecords ?? {})) {
|
|
1063
|
+
if (record === ctx.record) continue;
|
|
1064
|
+
const hit = decisionByTopic(record, topic);
|
|
1065
|
+
if (hit !== null) return hit;
|
|
1066
|
+
}
|
|
1067
|
+
return null;
|
|
1068
|
+
}
|
|
996
1069
|
async function checkTestReport(ctx) {
|
|
997
1070
|
const type = "record-test-report";
|
|
998
1071
|
const report = ctx.record?.testReport;
|
|
@@ -1008,40 +1081,52 @@ async function checkTestReport(ctx) {
|
|
|
1008
1081
|
"\u4FEE\u590D\u5931\u8D25\u7528\u4F8B\u81F3\u5168\u7EFF\u540E\u91CD\u63A8\uFF08\u7981\u6B62\u5E26\u5931\u8D25\u63A8\u8FDB\uFF1B\u5931\u8D25\u7528\u4F8B\u65E0 decision \u8C41\u514D\u8DEF\u5F84\uFF09"
|
|
1009
1082
|
);
|
|
1010
1083
|
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
if (waiver === null) {
|
|
1014
|
-
return fail3(type, `\u8DF3\u8FC7\u7528\u4F8B ${report.skipped} \u4E2A\u4F46\u65E0\u7528\u6237\u6388\u6743\u7559\u75D5\uFF08${report.command}\uFF09`, "\u7ECF\u7528\u6237\u660E\u793A\u6388\u6743\u540E record-decision-add \u5199 topic=skip-authorized\uFF0C\u6216\u6E05\u96F6 skipped");
|
|
1015
|
-
}
|
|
1016
|
-
return { type, status: "pass", detail: `\u6D4B\u8BD5\u901A\u8FC7\uFF08skipped=${report.skipped}\uFF0Cskip-authorized \u8C41\u514D decision ${waiver.id}\uFF09` };
|
|
1017
|
-
}
|
|
1018
|
-
return { type, status: "pass", detail: `\u6D4B\u8BD5\u5168\u7EFF\uFF1Apassed=${report.passed}\uFF08${report.command}\uFF09` };
|
|
1084
|
+
const skippedPart = report.skipped > 0 ? `\uFF1Bskipped=${report.skipped}\uFF08\u5B58\u91CF\u8DF3\u8FC7\u5982\u5B9E\u8BB0\u5F55\uFF0C\u4E0D\u62E6\u622A\uFF1B\u672C\u4EFB\u52A1\u65B0\u589E\u8DF3\u8FC7\u7531 record-no-fake-green \u5224\u5B9A\uFF09` : "";
|
|
1085
|
+
return { type, status: "pass", detail: `\u6D4B\u8BD5\u901A\u8FC7\uFF1Apassed=${report.passed}${skippedPart}\uFF08${report.command}\uFF09` };
|
|
1019
1086
|
}
|
|
1020
1087
|
async function checkNoFakeGreen(ctx) {
|
|
1021
1088
|
const type = "record-no-fake-green";
|
|
1022
|
-
const
|
|
1023
|
-
if (
|
|
1024
|
-
return { type, status: "pass", detail: `\u6D4B\u8BD5\u8C03\u6574\u6301\u6279\u51C6\u7559\u75D5\uFF08decision ${
|
|
1089
|
+
const adjustment = decisionAcrossTask(ctx, "test-adjust-approved");
|
|
1090
|
+
if (adjustment !== null) {
|
|
1091
|
+
return { type, status: "pass", detail: `\u6D4B\u8BD5\u8C03\u6574\u6301\u6279\u51C6\u7559\u75D5\uFF08decision ${adjustment.id}\uFF0C\u4EFB\u52A1\u7EA7\u751F\u6548\uFF09` };
|
|
1025
1092
|
}
|
|
1026
1093
|
const guard = naIfRepoUnavailable(ctx);
|
|
1027
|
-
if (guard)
|
|
1094
|
+
if (guard) {
|
|
1095
|
+
return guard.status === "not_applicable" ? { ...guard, type, detail: `${guard.detail}\uFF1B\u65B0\u589E\u8DF3\u8FC7\u65E0\u6CD5\u673A\u68C0\uFF0C\u987B\u4EBA\u5DE5\u786E\u8BA4\u65E0\u672A\u6388\u6743 skip/only` } : { ...guard, type };
|
|
1096
|
+
}
|
|
1028
1097
|
if (ctx.baseBranch === null) {
|
|
1029
1098
|
return fail3(type, "\u57FA\u7840\u5206\u652F\u672A\u77E5\uFF08ALIGN.baseBranch \u672A\u843D\u76D8\u4E14\u9879\u76EE\u672A\u914D\u7F6E\uFF09", "record-set \u5199 ALIGN.baseBranch\uFF0C\u6216 siming project update --vcs-base-branch <\u5206\u652F>");
|
|
1030
1099
|
}
|
|
1031
1100
|
const base = ctx.baseBranch;
|
|
1101
|
+
const skipWaiver = decisionAcrossTask(ctx, "skip-authorized");
|
|
1032
1102
|
return perRepoCheck(ctx, type, async (repo) => {
|
|
1103
|
+
const remote = `origin/${base}`;
|
|
1104
|
+
const probe = await ctx.runGit(["rev-parse", "--verify", "--quiet", remote], repo);
|
|
1105
|
+
const diffBase = probe.ok ? remote : base;
|
|
1033
1106
|
const diff = await ctx.runGit(
|
|
1034
|
-
["diff", `${
|
|
1107
|
+
["diff", `${diffBase}...HEAD`, "--", "**/*.test.ts", "**/*.spec.ts", "**/tests/**"],
|
|
1035
1108
|
repo
|
|
1036
1109
|
);
|
|
1037
1110
|
if (!diff.ok) {
|
|
1038
|
-
return {
|
|
1111
|
+
return {
|
|
1112
|
+
status: "fail",
|
|
1113
|
+
detail: `\u6D4B\u8BD5\u6587\u4EF6 diff \u5931\u8D25\uFF1A${firstLine2(diff.stderr)}\uFF08\u57FA\u7EBF ${diffBase}\uFF09\u2014\u2014\u68C0\u67E5\u4ED3\u5E93\u53EF\u7528\u6027\u4E0E\u57FA\u7EBF\u662F\u5426\u5B58\u5728\uFF1B\u57FA\u7840\u5206\u652F\u7F3A\u5931\u65F6 record-set \u5199 ALIGN.baseBranch\uFF08\u6216 siming project update --vcs-base-branch <\u5206\u652F>\uFF09\uFF0C\u8FDC\u7A0B\u5F15\u7528\u4E0D\u53EF\u7528\u65F6\u786E\u8BA4 origin/${base} \u5DF2 fetch`
|
|
1114
|
+
};
|
|
1039
1115
|
}
|
|
1040
1116
|
const violations = scanTestDiff(diff.stdout);
|
|
1041
|
-
|
|
1042
|
-
|
|
1117
|
+
const waivedSkips = violations.filter((v) => v.kind === "skip" && skipWaiver !== null);
|
|
1118
|
+
const blocked = violations.filter((v) => v.kind !== "skip" || skipWaiver === null);
|
|
1119
|
+
const waivedPart = waivedSkips.length > 0 && skipWaiver !== null ? `\uFF1B\u65B0\u589E .skip( ${waivedSkips.length} \u5904\u6301 skip-authorized \u6388\u6743\uFF08decision ${skipWaiver.id}\uFF0C\u4EFB\u52A1\u7EA7\u751F\u6548\uFF09` : "";
|
|
1120
|
+
if (blocked.length > 0) {
|
|
1121
|
+
return {
|
|
1122
|
+
status: "fail",
|
|
1123
|
+
detail: `\u6D4B\u8BD5\u5B8C\u6574\u6027\u8FDD\u89C4\uFF08\u57FA\u7EBF ${diffBase}...HEAD\uFF09\uFF1A${blocked.map((v) => v.reason).join("\uFF1B")}${waivedPart}\u2014\u2014\u8FD8\u539F\u6D4B\u8BD5\u6539\u52A8\uFF1B\u65B0\u589E .skip( \u987B\u7ECF\u7528\u6237\u6388\u6743\u540E record-decision-add \u5199 topic=skip-authorized\uFF0C.only( \u4E0E\u6D4B\u8BD5\u6574\u5220\u987B\u5199 topic=test-adjust-approved\uFF1B\u82E5 ${diffBase} \u53EF\u80FD\u9648\u65E7\uFF0C\u5148 git fetch origin ${base} \u518D\u91CD\u5224`
|
|
1124
|
+
};
|
|
1043
1125
|
}
|
|
1044
|
-
|
|
1126
|
+
if (waivedSkips.length > 0 && skipWaiver !== null) {
|
|
1127
|
+
return { status: "pass", detail: `\u65B0\u589E .skip( ${waivedSkips.length} \u5904\u6301 skip-authorized \u6388\u6743\uFF08decision ${skipWaiver.id}\uFF0C\u4EFB\u52A1\u7EA7\u751F\u6548\uFF09\uFF1B\u6D4B\u8BD5\u6587\u4EF6\u65E0\u5176\u4ED6\u65B0\u589E skip/only \u4E0E\u6574\u5220\uFF08\u57FA\u7EBF ${diffBase}...HEAD\uFF09` };
|
|
1128
|
+
}
|
|
1129
|
+
return { status: "pass", detail: `\u6D4B\u8BD5\u6587\u4EF6\u65E0\u65B0\u589E skip/only \u4E0E\u6574\u5220\uFF08\u57FA\u7EBF ${diffBase}...HEAD\uFF1B\u653E\u5BBD\u65AD\u8A00\u5F62\u6001\u4E0D\u5728\u673A\u5668\u68C0\u6D4B\u9762\uFF0C\u4F9D\u8D56 test-adjust-approved \u7559\u75D5\u628A\u5173\uFF09` };
|
|
1045
1130
|
});
|
|
1046
1131
|
}
|
|
1047
1132
|
function scanTestDiff(patch) {
|
|
@@ -1056,18 +1141,22 @@ function scanTestDiff(patch) {
|
|
|
1056
1141
|
}
|
|
1057
1142
|
if (line.startsWith("deleted file mode")) {
|
|
1058
1143
|
const m = currentFile.match(/^diff --git a\/(.+) b\//);
|
|
1059
|
-
if (m) violations.push({ reason: `\u6D4B\u8BD5\u6587\u4EF6\u6574\u5220\uFF1A${m[1]}` });
|
|
1144
|
+
if (m) violations.push({ kind: "delete", reason: `\u6D4B\u8BD5\u6587\u4EF6\u6574\u5220\uFF1A${m[1]}` });
|
|
1060
1145
|
deleting = true;
|
|
1061
1146
|
continue;
|
|
1062
1147
|
}
|
|
1063
1148
|
if (deleting) continue;
|
|
1064
1149
|
if (line.startsWith("+") && !line.startsWith("+++")) {
|
|
1065
|
-
|
|
1066
|
-
|
|
1150
|
+
const snippet = line.slice(1).trim().slice(0, 80);
|
|
1151
|
+
if (line.includes(".skip(")) {
|
|
1152
|
+
violations.push({ kind: "skip", reason: `\u65B0\u589E\u8DF3\u8FC7\u6807\u8BB0 .skip(\uFF1A${snippet}` });
|
|
1153
|
+
}
|
|
1154
|
+
if (line.includes(".only(")) {
|
|
1155
|
+
violations.push({ kind: "only", reason: `\u65B0\u589E\u805A\u7126\u6807\u8BB0 .only(\uFF1A${snippet}` });
|
|
1067
1156
|
}
|
|
1068
1157
|
}
|
|
1069
1158
|
}
|
|
1070
|
-
return violations
|
|
1159
|
+
return violations;
|
|
1071
1160
|
}
|
|
1072
1161
|
async function checkBaseReMerged(ctx) {
|
|
1073
1162
|
const type = "record-base-re-merged";
|
|
@@ -1167,12 +1256,22 @@ function collectPredecessors(edges, nodeId) {
|
|
|
1167
1256
|
}
|
|
1168
1257
|
async function checkVersionConsistent(ctx) {
|
|
1169
1258
|
const type = "record-version-consistent";
|
|
1259
|
+
const guard = naIfRepoUnavailable(ctx);
|
|
1260
|
+
if (guard) return { ...guard, type };
|
|
1261
|
+
if (ctx.vcs.archiveToBase === false) {
|
|
1262
|
+
return { type, status: "not_applicable", detail: "\u9879\u76EE vcs.archiveToBase=false\uFF08\u58F0\u660E\u65E0\u5F52\u6863\u5408\u5E76\u6D41\u7A0B\uFF09" };
|
|
1263
|
+
}
|
|
1264
|
+
if (hasSuccessorNode(ctx)) {
|
|
1265
|
+
return {
|
|
1266
|
+
type,
|
|
1267
|
+
status: "not_applicable",
|
|
1268
|
+
detail: "\u975E\u7EC8\u6001\u5F62\u6001\uFF08\u5B58\u5728\u540E\u7EE7\u8282\u70B9\uFF09\uFF1A\u4EE3\u7801\u5F52\u6863\u7531\u5BA1\u6279\u901A\u8FC7\u540E\u7684\u5F52\u6863\u5F85\u529E\u627F\u8F7D\uFF0Cadvance \u65F6\u5F52\u6863\u5C1A\u672A\u53D1\u751F\uFF1B\u7248\u672C\u4E00\u81F4\u6027\u7531\u5F52\u6863\u5B8C\u6210\u540E\u7684\u5F52\u6863\u8282\u70B9\u590D\u6838"
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1170
1271
|
const sha = ctx.nodeRecords["INTEGRATE"]?.verifiedCommit;
|
|
1171
1272
|
if (!sha) {
|
|
1172
1273
|
return fail3(type, "INTEGRATE \u8BB0\u5F55\u7F3A verifiedCommit\uFF08\u7248\u672C\u4E00\u81F4\u6027\u65E0\u4ECE\u5224\u5B9A\uFF09", "\u56DE\u8865 INTEGRATE record-set verifiedCommit \u540E\u91CD\u8BD5");
|
|
1173
1274
|
}
|
|
1174
|
-
const guard = naIfRepoUnavailable(ctx);
|
|
1175
|
-
if (guard) return { ...guard, type };
|
|
1176
1275
|
if (ctx.baseBranch === null) {
|
|
1177
1276
|
return fail3(type, "\u57FA\u7840\u5206\u652F\u672A\u77E5\uFF08ALIGN.baseBranch \u672A\u843D\u76D8\u4E14\u9879\u76EE\u672A\u914D\u7F6E\uFF09", "record-set \u5199 ALIGN.baseBranch\uFF0C\u6216 siming project update --vcs-base-branch <\u5206\u652F>");
|
|
1178
1277
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@siming-org/cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.16",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Wuchao",
|
|
6
6
|
"engines": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"picocolors": "^1.1.1",
|
|
28
28
|
"yaml": "^2.6.0",
|
|
29
29
|
"zod": "^4.4.3",
|
|
30
|
-
"@siming-org/
|
|
31
|
-
"@siming-org/
|
|
30
|
+
"@siming-org/core": "0.8.16",
|
|
31
|
+
"@siming-org/server": "0.8.16"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"tsup": "^8.3.5",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"exportFormatVersion": "1.0",
|
|
3
|
-
"exportedAt": "2026-10-
|
|
3
|
+
"exportedAt": "2026-10-23T09:51:30.283Z",
|
|
4
4
|
"warnings": [],
|
|
5
5
|
"template": {
|
|
6
6
|
"name": "full_workflow",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"label": "交互设计",
|
|
66
66
|
"phase": "entry",
|
|
67
67
|
"track": "ui",
|
|
68
|
-
"prompt": "# 交互设计\n\n## 节点职责\n\n
|
|
68
|
+
"prompt": "# 交互设计\n\n## 节点职责\n\n把已确认需求中用户可见的交互意图,翻译为不依赖具体实现、可逐项核对的交互契约——界面结构与路径总览、状态矩阵、交互契约规则、键盘与焦点、反馈与播报、边界与内容策略、文案逐字稿、令牌绑定、自检清单——经独立对齐核验后,作为技术方案与编码节点的显式输入依赖、视觉验证的验收依据;用户确认由流程暂停点承载。本节点不编写生产代码、不做视觉审美裁定、不做技术选型;用户要求查看 demo 时,产出的静态 demo 只是契约的派生视图,供用户人工查看,不进入任何 agent 评审。\n\n## 依赖信息\n\n先检查当前任务上下文:PRD 或需求描述、验收标准、非目标、前序节点产物,以及项目和所属模块的提示词。加载 `workflow-discipline`;契约完成后调用 `alignment-reviewer` 核验契约与需求的回溯关系——核验对象仅为契约文本,demo 或草图不在其评审范围。\n\n本节点位于技术方案(DESIGN)之前:定案的交互契约是技术方案的直接输入——技术方案基于已确认的交互契约做实现设计,交互契约未经暂停点确认不得进入技术设计。\n\n形态层映射(Web/桌面/游戏引擎等)以 PRD/需求声明的产品形态与载体为准;载体未明确时先向用户澄清(澄清结论写入节点记录,供技术方案承接),不猜测。\n\n## 正向执行流程\n\n1. 从需求与交互澄清记录提取全部用户可见交互面:每个数据驱动视图、每个可触发元素、每条用户路径。任务无任何用户可见交互面时,判定本节点不适用,在节点记录写明判定与理由后推进。\n2. 逐项产出契约必备项,每项均可逐字核对、不依赖对话上下文:\n - 界面结构与路径总览:布局用文本线框、状态流转用状态图、用户路径用流程图,以可渲染的图形语法内嵌契约文档(项目未约定时用 Mermaid),作为人工审阅的第一入口;\n - 状态矩阵:每个数据驱动视图的 loading / empty / error / disabled 呈现定义与文案;\n - 交互契约规则:触发元素、事件、效果元素、效果类型、效果位置、可逆性、目标状态;\n - 键盘与焦点契约:Tab 顺序、初始焦点、Esc/Enter 语义、disabled 元素可聚焦策略;\n - 反馈与播报机制:每个状态变更选用哪种机制(focus / role=status / live region 等)及理由;\n - 边界与内容策略:最小支持宽度、320px 级重排、超长文本截断、大数据分页/滚动、空值文案;\n - 文案逐字稿:含错误文案与空态文案,逐字给出,不留占位符;\n - 令牌绑定:颜色、间距、圆角、字阶引用设计令牌,禁止裸值;\n - 自检清单:实现者可逐项勾选的验收点清单,覆盖以上全部条款。\n3. 每条交互规则标注回溯来源(需求哪一条 / 澄清问答哪项结论);无法回溯的条目视为新增需求,上升用户裁定后才可写入契约。\n4. 将契约全文保存为项目文档并登记任务产物(携带全文;超限时路径引用须说明理由),向用户呈现契约要点、自检清单核对结果与文档可读位置(作为暂停点审批材料)。\n5. 随后按通用层与形态层组织契约:通用层条款形态无关;形态层条款按已澄清的载体映射(HTML/CSS、UXML/USS、.tscn/Theme 等),映射关系写入契约。\n\n## 产出与检查\n\n推进前确认:\n\n- 全部必备产出(含界面结构与路径总览)齐全,不适用的单项已写明具体对象和理由;\n- 每条交互规则可回溯到需求或澄清记录,无发明需求;\n- 文案全部逐字给出,令牌引用无裸值;\n- 自检清单覆盖全部契约条款;\n- `alignment-reviewer` 对回溯关系的核验为 PASS,Findings 已处理或记录保留理由;\n- 审批材料(契约要点、自检清单核对结果、文档位置)已完整呈现,可支撑暂停点审批;\n- 契约文档已保存登记,呈现给用户的版本与确认版本一致。\n\n## 任务差异处理\n\n无用户可见交互面的任务:判定不适用并记录理由后推进,下游编码节点按「无契约」路径实现。信息不足以产出某项契约时,保留在本节点补齐或向用户澄清,不静默降级;确属可选项的增强(视觉基线、设计文件同步、动效规格)按需说明取舍,不默认纳入。\n\n可运行草图(仅供人工查看):默认不产出。用户明确要求查看 demo、HTML 草图或可交互预览时,按当前版本契约生成静态 HTML 到工作区 `temp/`,文件应自包含、可直接打开;生成后给出文件的绝对路径,并用系统命令直接在用户浏览器打开(按宿主系统选择:macOS `open <文件>`、Linux `xdg-open <文件>`、Windows `start <文件>`;无图形环境或打开失败时给出路径并说明打开方式),再用一句话说明这版 demo 对应契约的哪些条款、请用户重点看什么,然后停下等待用户反馈。\n\ndemo 是契约的派生视图而非第二设计来源:页首声明「非契约正文,与契约不一致时以契约文档为准」;契约发生任何修订即作废重生成,重新打开并重新说明查看重点;demo 暴露的契约缺口只能回写契约修正,不在 demo 上直接改。demo 修订只依据用户反馈,不设评审轮次。\n\ndemo 的唯一验收人是用户:禁止委派任何评审类子代理评审 demo(含契约对齐评审与视觉评审角色);禁止对 demo 做截图自检、浏览器自动化或任何自动审查;不产生 demo 评审记录。`alignment-reviewer` 只核验契约文本,不接触 demo。demo 不写入契约文档、不登记为任务产物,节点推进后即完成使命。\n\n## 节点记录与推进\n\n将契约文档产物与引用、必备产出核对结果、不适用判定及理由(如有)、demo 生成事实(如有,含文件绝对路径与对应的契约版本)、`alignment-reviewer` 对契约文本的结论与轮次、呈现给用户的审批材料索引写入当前节点记录(确认原文由暂停点审批记录承载,须逐字引用用户确认表态,不得转述失真;不双写),完成产出检查后推进下一节点。",
|
|
69
69
|
"skills": [
|
|
70
70
|
"workflow-discipline"
|
|
71
71
|
],
|
|
@@ -74,14 +74,12 @@
|
|
|
74
74
|
],
|
|
75
75
|
"sourcePreset": {
|
|
76
76
|
"code": "interaction-design",
|
|
77
|
-
"version": "1.
|
|
78
|
-
"contentHash": "
|
|
77
|
+
"version": "1.3.0",
|
|
78
|
+
"contentHash": "31b39d50d25bd68c",
|
|
79
79
|
"agents": [
|
|
80
80
|
"alignment-reviewer"
|
|
81
81
|
]
|
|
82
|
-
}
|
|
83
|
-
"toolChecks": [],
|
|
84
|
-
"aiChecks": []
|
|
82
|
+
}
|
|
85
83
|
},
|
|
86
84
|
{
|
|
87
85
|
"id": "DESIGN",
|
|
@@ -255,7 +253,7 @@
|
|
|
255
253
|
"label": "单元测试开发",
|
|
256
254
|
"phase": "test",
|
|
257
255
|
"track": "backend",
|
|
258
|
-
"prompt": "# 单元测试开发\n\n## 节点职责\n\n依据已确认的单元测试设计编写或调整测试代码,验证生产行为与需求一致。测试代码和必要的生产代码修复由当前执行者完成;测试命令交给独立 `test-executor` 执行,最终代码交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、生产代码、单元测试设计、前序决策,以及项目和所属模块的测试约束。加载 `coding-standards`、`workflow-discipline`;出现测试失败且根因不明确时加载 `bugfix-root-cause-verification`。调用 `test-executor` 执行测试,调用 `code-reviewer` 审查代码变更。\n\n读取现有测试、配置和项目命令,确认框架、命名、替身、数据准备、覆盖目标和日志规则。缺少关键信息时先从仓库现状补齐;仍无法确定测试语义时说明缺失信息并暂停。\n\n## 执行流程\n\n1. 建立“测试设计用例 → 测试实现或已有用例”的逐项映射,明确新增、调整和复用范围。\n2. 按项目惯例实现测试,验证业务结果、状态变化、错误传播和必要副作用;替身只隔离单元边界,不掩盖被测行为。\n3. 完成一个测试文件或紧密相关的一组用例后,将明确的命令、范围和通过标准交给 `test-executor` 执行,并依据事实报告判断结果。\n4. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按 `bugfix-root-cause-verification` 复现、提出并验证假设,确认根因后再修改测试、生产代码或环境。\n5. 修复后重新执行原失败范围及受影响回归。不得通过删除有效测试、skip/only、缩小应执行范围、放宽正确断言、吞异常、修改数据避开问题或硬编码结果制造通过。\n6. 所有设计用例实现后,先根据生产代码改动和依赖关系判定回归范围,无法可靠判断时扩大范围;范围判定完成后必须调用 `test-executor` 执行该回归范围。\n7.
|
|
256
|
+
"prompt": "# 单元测试开发\n\n## 节点职责\n\n依据已确认的单元测试设计编写或调整测试代码,验证生产行为与需求一致。测试代码和必要的生产代码修复由当前执行者完成;测试命令交给独立 `test-executor` 执行,最终代码交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、生产代码、单元测试设计、前序决策,以及项目和所属模块的测试约束。加载 `coding-standards`、`workflow-discipline`;出现测试失败且根因不明确时加载 `bugfix-root-cause-verification`。调用 `test-executor` 执行测试,调用 `code-reviewer` 审查代码变更。\n\n读取现有测试、配置和项目命令,确认框架、命名、替身、数据准备、覆盖目标和日志规则。缺少关键信息时先从仓库现状补齐;仍无法确定测试语义时说明缺失信息并暂停。\n\n## 执行流程\n\n1. 建立“测试设计用例 → 测试实现或已有用例”的逐项映射,明确新增、调整和复用范围。\n2. 按项目惯例实现测试,验证业务结果、状态变化、错误传播和必要副作用;替身只隔离单元边界,不掩盖被测行为。\n3. 完成一个测试文件或紧密相关的一组用例后,将明确的命令、范围和通过标准交给 `test-executor` 执行,并依据事实报告判断结果。\n4. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按 `bugfix-root-cause-verification` 复现、提出并验证假设,确认根因后再修改测试、生产代码或环境。\n5. 修复后重新执行原失败范围及受影响回归。不得通过删除有效测试、skip/only、缩小应执行范围、放宽正确断言、吞异常、修改数据避开问题或硬编码结果制造通过。\n6. 所有设计用例实现后,先根据生产代码改动和依赖关系判定回归范围,无法可靠判断时扩大范围;范围判定完成后必须调用 `test-executor` 执行该回归范围。\n7. 检查设计映射、测试删除、本任务新增 skip/only(存量跳过不要求授权)、无效观察点、隔离性和覆盖统计,确认测试变更完整。\n8. 将需求、测试设计、项目约束和全部代码变更位置交给 `code-reviewer`,不提供实现者结论或预期结果。修复 BLOCKER、HIGH Findings 后重新执行受影响测试并复审,直至测试通过且评审为 PASS;MEDIUM、LOW 逐项处理或记录保留理由。\n\n## 产出与检查\n\n推进前确认:\n\n- 每个适用的测试设计用例都有对应实现或明确的已有测试;\n- 测试具有有效观察点,替身、数据和隔离方式符合项目约束;\n- 所有测试失败均在根因明确后修复,没有制造假绿;\n- `test-executor` 报告适用范围全部通过,失败为 0;存量跳过如实记录不阻断,本任务新增未授权 skip 为 0,日志可追溯;\n- 确需保留的新增跳过须先经用户明示授权,并在任务内任一节点 `record-decision-add` 写 `topic=skip-authorized`;新增 `.only(` 或测试整删须写 `topic=test-adjust-approved`。\n- 完整性检查通过,没有删除有效测试或遗漏设计用例;\n- `code-reviewer` 最终结论为 PASS,所有 Findings 均已处理或说明;\n- 测试代码、必要的生产修复和执行报告已形成可引用产物。\n\n## 任务差异处理\n\n根据项目测试框架和变更范围选择实现与回归方式,不套用固定命令或覆盖率指标。测试设计中的用例确实不适用或已被等价测试覆盖时,说明具体依据。失败修复涉及破坏性契约、新依赖或真实范围扩张时先说明影响并暂停;同一问题多轮仍不收敛时按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将设计到实现的映射、测试代码变更、实际执行命令与范围、通过/失败/跳过统计(经 record-set 结构化写入 testReport 字段,含实际执行命令)、日志与报告引用、根因和修复、完整性结论、未适用项及理由、`code-reviewer` 结论与 Findings 处理情况写入当前节点记录。完成上述检查后推进下一节点。",
|
|
259
257
|
"skills": [
|
|
260
258
|
"coding-standards",
|
|
261
259
|
"workflow-discipline"
|
|
@@ -266,8 +264,8 @@
|
|
|
266
264
|
],
|
|
267
265
|
"sourcePreset": {
|
|
268
266
|
"code": "test-unit-implement",
|
|
269
|
-
"version": "1.5.
|
|
270
|
-
"contentHash": "
|
|
267
|
+
"version": "1.5.2",
|
|
268
|
+
"contentHash": "4867aa46c6ae9786",
|
|
271
269
|
"agents": [
|
|
272
270
|
"test-executor",
|
|
273
271
|
"code-reviewer"
|
|
@@ -319,7 +317,7 @@
|
|
|
319
317
|
"label": "前端单元测试开发",
|
|
320
318
|
"phase": "test",
|
|
321
319
|
"track": "ui",
|
|
322
|
-
"prompt": "# 前端单元测试开发\n\n## 节点职责\n\n依据已确认的前端单元测试设计编写或调整测试代码,验证界面呈现与交互行为符合需求。测试代码和必要的前端实现修复由当前执行者完成;测试命令交给独立 `test-executor` 执行,最终代码交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、前端实现变更、前端单元测试设计、前序决策,以及项目和所属模块的前端测试约束(框架与命令、覆盖率门)。加载 `coding-standards`、`workflow-discipline`;出现测试失败且根因不明确时加载 `bugfix-root-cause-verification`。调用 `test-executor` 执行测试,调用 `code-reviewer` 审查代码变更。\n\n读取现有前端测试、配置与项目命令,确认框架、渲染方式、定位与断言惯例、替身与数据准备、覆盖率统计范围。缺少关键信息时先从仓库现状补齐;仍无法确定测试语义时说明缺失信息并暂停。\n\n## 执行流程\n\n1. 建立“测试设计用例 → 测试实现或已有用例”的逐项映射,明确新增、调整和复用范围。\n2. 按项目惯例实现测试:Arrange-Act-Assert 结构、描述性命名说明场景与预期、相关用例分组;断言渲染输出、用户可见状态与交互结果,不断言内部状态或私有实现。\n3. 定位界面元素使用用户可感知的方式(可访问角色、标签文本、可见文本),不使用样式类名或内部选择器绑死实现结构。\n4. 替身只隔离单元边界:网络请求、时钟、路由等外部依赖用替身,不替换被测行为本身;用例之间相互独立、可任意顺序执行,禁止真实计时等待与顺序依赖。\n5. 完成一个测试文件或紧密相关的一组用例后,将明确的命令、范围和通过标准交给 `test-executor` 执行,并依据事实报告判断结果。\n6. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按 `bugfix-root-cause-verification` 复现、提出并验证假设,确认根因后再修改测试、前端实现或环境。\n7. 修复后重新执行原失败范围及受影响回归。不得通过删除有效测试、skip/only、缩小应执行范围、放宽正确断言、吞异常、修改数据避开问题或硬编码结果制造通过;不得通过调整覆盖率阈值、排除文件、缩小统计范围或屏蔽统计使覆盖率门通过。\n8. 覆盖率门不满足时按缺口补充用例;确属无法覆盖的代码说明原因并写入节点记录。\n9. 所有设计用例实现后,先根据前端改动与依赖关系判定回归范围,无法可靠判断时扩大范围;范围判定完成后必须调用 `test-executor` 执行该回归范围(含项目声明的覆盖率命令)。\n10.
|
|
320
|
+
"prompt": "# 前端单元测试开发\n\n## 节点职责\n\n依据已确认的前端单元测试设计编写或调整测试代码,验证界面呈现与交互行为符合需求。测试代码和必要的前端实现修复由当前执行者完成;测试命令交给独立 `test-executor` 执行,最终代码交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、前端实现变更、前端单元测试设计、前序决策,以及项目和所属模块的前端测试约束(框架与命令、覆盖率门)。加载 `coding-standards`、`workflow-discipline`;出现测试失败且根因不明确时加载 `bugfix-root-cause-verification`。调用 `test-executor` 执行测试,调用 `code-reviewer` 审查代码变更。\n\n读取现有前端测试、配置与项目命令,确认框架、渲染方式、定位与断言惯例、替身与数据准备、覆盖率统计范围。缺少关键信息时先从仓库现状补齐;仍无法确定测试语义时说明缺失信息并暂停。\n\n## 执行流程\n\n1. 建立“测试设计用例 → 测试实现或已有用例”的逐项映射,明确新增、调整和复用范围。\n2. 按项目惯例实现测试:Arrange-Act-Assert 结构、描述性命名说明场景与预期、相关用例分组;断言渲染输出、用户可见状态与交互结果,不断言内部状态或私有实现。\n3. 定位界面元素使用用户可感知的方式(可访问角色、标签文本、可见文本),不使用样式类名或内部选择器绑死实现结构。\n4. 替身只隔离单元边界:网络请求、时钟、路由等外部依赖用替身,不替换被测行为本身;用例之间相互独立、可任意顺序执行,禁止真实计时等待与顺序依赖。\n5. 完成一个测试文件或紧密相关的一组用例后,将明确的命令、范围和通过标准交给 `test-executor` 执行,并依据事实报告判断结果。\n6. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按 `bugfix-root-cause-verification` 复现、提出并验证假设,确认根因后再修改测试、前端实现或环境。\n7. 修复后重新执行原失败范围及受影响回归。不得通过删除有效测试、skip/only、缩小应执行范围、放宽正确断言、吞异常、修改数据避开问题或硬编码结果制造通过;不得通过调整覆盖率阈值、排除文件、缩小统计范围或屏蔽统计使覆盖率门通过。\n8. 覆盖率门不满足时按缺口补充用例;确属无法覆盖的代码说明原因并写入节点记录。\n9. 所有设计用例实现后,先根据前端改动与依赖关系判定回归范围,无法可靠判断时扩大范围;范围判定完成后必须调用 `test-executor` 执行该回归范围(含项目声明的覆盖率命令)。\n10. 检查设计映射、测试删除、本任务新增 skip/only(存量跳过不要求授权)、无效观察点、隔离性、独立性与覆盖率统计,确认测试变更完整。\n11. 将需求、测试设计、项目约束和全部代码变更位置交给 `code-reviewer`,不提供实现者结论或预期结果。修复 BLOCKER、HIGH Findings 后重新执行受影响测试并复审,直至测试通过且评审为 PASS;MEDIUM、LOW 逐项处理或记录保留理由。\n\n## 产出与检查\n\n推进前确认:\n\n- 每个适用的测试设计用例都有对应实现或明确的已有测试;\n- 测试具有用户可感知的观察点,断言行为与呈现而非实现细节;\n- 用例相互独立、可任意顺序执行,替身与数据准备符合项目约束;\n- 所有测试失败均在根因明确后修复,没有制造假绿;\n- `test-executor` 报告适用范围全部通过,失败为 0;存量跳过如实记录不阻断,本任务新增未授权 skip 为 0,覆盖率门满足,日志可追溯;\n- 确需保留的新增跳过须先经用户明示授权,并在任务内任一节点 `record-decision-add` 写 `topic=skip-authorized`;新增 `.only(` 或测试整删须写 `topic=test-adjust-approved`。\n- 覆盖率缺口或无法覆盖项已说明,未调整阈值、排除文件、缩小统计范围或屏蔽统计;\n- 完整性检查通过,没有删除有效测试或遗漏设计用例;\n- `code-reviewer` 最终结论为 PASS,所有 Findings 均已处理或说明;\n- 测试代码、必要的前端修复和执行报告已形成可引用产物。\n\n## 任务差异处理\n\n根据项目前端测试框架和变更范围选择实现与回归方式,不套用固定命令或覆盖率指标。测试设计中的用例确实不适用或已被等价测试覆盖时,说明具体依据。失败修复涉及破坏性契约、新依赖或真实范围扩张时先说明影响并暂停;同一问题多轮仍不收敛时按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将设计到实现的映射、测试代码变更、实际执行命令与范围、通过/失败/跳过统计(经 record-set 结构化写入 testReport 字段,含实际执行命令)与覆盖率结果、日志与报告引用、根因和修复、无法覆盖项及说明、完整性结论、未适用项及理由、`code-reviewer` 结论与 Findings 处理情况写入当前节点记录。完成上述检查后推进下一节点。",
|
|
323
321
|
"skills": [
|
|
324
322
|
"coding-standards",
|
|
325
323
|
"workflow-discipline"
|
|
@@ -330,8 +328,8 @@
|
|
|
330
328
|
],
|
|
331
329
|
"sourcePreset": {
|
|
332
330
|
"code": "test-ui-unit-implement",
|
|
333
|
-
"version": "1.2.
|
|
334
|
-
"contentHash": "
|
|
331
|
+
"version": "1.2.2",
|
|
332
|
+
"contentHash": "718dca0da178ef06",
|
|
335
333
|
"agents": [
|
|
336
334
|
"test-executor",
|
|
337
335
|
"code-reviewer"
|
|
@@ -392,7 +390,7 @@
|
|
|
392
390
|
"label": "端到端测试开发",
|
|
393
391
|
"phase": "test",
|
|
394
392
|
"track": "all",
|
|
395
|
-
"prompt": "# 端到端测试开发\n\n## 节点职责\n\n依据已确认的 E2E 设计实现并验证跨真实系统边界的测试场景;设计结论为 N/A 时复核依据并记录结果;本节点对后端、界面与混合三类任务均生效。实现环节发现某场景本期确实不可执行时,必须把该场景落成问题池 issue,不允许只留在记录里当作已完成。测试代码和必要的生产代码修复由当前执行者完成;测试命令交给独立 `test-executor` 执行,最终代码交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、生产代码、E2E 设计(含延期场景的 issue 编号)、低层测试结果(后端单元测试与/或前端单元测试,按任务轨道)、前序决策与节点记录中的行为场景交接建议,以及项目和所属模块的测试约束。加载 `coding-standards`、`workflow-discipline`;测试失败且根因不明确时,再加载 `bugfix-root-cause-verification`。调用 `test-executor` 执行测试,调用 `code-reviewer` 审查代码变更。\n\n读取项目的 E2E 目录、配置、执行入口、邻近用例和环境规则。缺少关键信息时先从仓库现状补齐,不擅自引入项目未定义的测试体系。\n\n## 执行流程\n\n1. 读取 E2E 适用性结论并建立“设计场景 → 测试实现或已有用例”的逐项映射;设计中标为延期的场景按其 issue 编号核对,不重复实现或重复登记。\n2. 设计结论为 N/A 时,复核项目仍未定义适用的 E2E 体系;依据成立则记录 N/A,发现依据不成立则返回设计范围判断,不直接越过设计补写测试。\n3. 适用时,按项目现有框架和唯一执行入口实现测试,落实前置条件、操作步骤、观察点、预期结果、数据隔离和清理。测试必须经过项目定义的真实边界,并验证最终可观察结果。\n4. 实现中发现某场景本期确实不可执行时,把该场景落成一条问题池 issue——标题写明场景,描述写清需求依据与延期理由(本期不可执行原因),登记到当前任务所属项目,并将 issue 编号写入节点记录;不得通过删除测试、跳过标记或缩水断言代替登记。\n5. 完成一个场景或紧密相关的一组场景后,将明确的命令、范围和通过标准交给 `test-executor` 执行。\n6. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按需加载 `bugfix-root-cause-verification`,确认根因后再修改测试、生产代码或环境。\n7. 修复后重新执行原失败场景及受影响回归。不得通过删除有效测试、skip/only、绕开真实边界、缩小应执行范围、放宽正确断言、吞异常或硬编码结果制造通过。\n8. 全部场景实现后,以证据链确定 E2E 回归范围:列出本节点的测试与生产代码变更,映射到受影响场景(同一入口、同一链路、共享前置数据的用例),逐项给出执行或排除的依据。E2E 全量是须举证的主动决策而非兜底——仅当证据表明改动横切多个入口或共享基础设施时执行;未完成受影响分析就宣称无法判断、或以“保险起见”直接全量,均判定为范围决策失败。生产代码发生修复时,同样按证据链确定并执行受影响的低层测试(含前端单测,按任务轨道)。\n9. 检查设计映射(含延期场景的 issue
|
|
393
|
+
"prompt": "# 端到端测试开发\n\n## 节点职责\n\n依据已确认的 E2E 设计实现并验证跨真实系统边界的测试场景;设计结论为 N/A 时复核依据并记录结果;本节点对后端、界面与混合三类任务均生效。实现环节发现某场景本期确实不可执行时,必须把该场景落成问题池 issue,不允许只留在记录里当作已完成。测试代码和必要的生产代码修复由当前执行者完成;测试命令交给独立 `test-executor` 执行,最终代码交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、技术方案、生产代码、E2E 设计(含延期场景的 issue 编号)、低层测试结果(后端单元测试与/或前端单元测试,按任务轨道)、前序决策与节点记录中的行为场景交接建议,以及项目和所属模块的测试约束。加载 `coding-standards`、`workflow-discipline`;测试失败且根因不明确时,再加载 `bugfix-root-cause-verification`。调用 `test-executor` 执行测试,调用 `code-reviewer` 审查代码变更。\n\n读取项目的 E2E 目录、配置、执行入口、邻近用例和环境规则。缺少关键信息时先从仓库现状补齐,不擅自引入项目未定义的测试体系。\n\n## 执行流程\n\n1. 读取 E2E 适用性结论并建立“设计场景 → 测试实现或已有用例”的逐项映射;设计中标为延期的场景按其 issue 编号核对,不重复实现或重复登记。\n2. 设计结论为 N/A 时,复核项目仍未定义适用的 E2E 体系;依据成立则记录 N/A,发现依据不成立则返回设计范围判断,不直接越过设计补写测试。\n3. 适用时,按项目现有框架和唯一执行入口实现测试,落实前置条件、操作步骤、观察点、预期结果、数据隔离和清理。测试必须经过项目定义的真实边界,并验证最终可观察结果。\n4. 实现中发现某场景本期确实不可执行时,把该场景落成一条问题池 issue——标题写明场景,描述写清需求依据与延期理由(本期不可执行原因),登记到当前任务所属项目,并将 issue 编号写入节点记录;不得通过删除测试、跳过标记或缩水断言代替登记。\n5. 完成一个场景或紧密相关的一组场景后,将明确的命令、范围和通过标准交给 `test-executor` 执行。\n6. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按需加载 `bugfix-root-cause-verification`,确认根因后再修改测试、生产代码或环境。\n7. 修复后重新执行原失败场景及受影响回归。不得通过删除有效测试、skip/only、绕开真实边界、缩小应执行范围、放宽正确断言、吞异常或硬编码结果制造通过。\n8. 全部场景实现后,以证据链确定 E2E 回归范围:列出本节点的测试与生产代码变更,映射到受影响场景(同一入口、同一链路、共享前置数据的用例),逐项给出执行或排除的依据。E2E 全量是须举证的主动决策而非兜底——仅当证据表明改动横切多个入口或共享基础设施时执行;未完成受影响分析就宣称无法判断、或以“保险起见”直接全量,均判定为范围决策失败。生产代码发生修复时,同样按证据链确定并执行受影响的低层测试(含前端单测,按任务轨道)。\n9. 检查设计映射(含延期场景的 issue 编号)、测试删除、本任务新增 skip/only(存量跳过不要求授权)、断言有效性、真实边界、数据隔离、清理和环境可重复性。\n10. 将需求、E2E 设计、项目约束和全部代码变更位置交给 `code-reviewer`,不提供实现者结论或预期结果。修复 BLOCKER、HIGH Findings 后重新执行受影响测试并复审,直至测试通过且评审为 PASS;MEDIUM、LOW 逐项处理或记录保留理由。\n\n## 产出与检查\n\n推进前确认:\n\n- N/A 结论已有复核证据,或每个适用设计场景都有对应实现、明确的已有测试,或已落问题池 issue 并在节点记录留有编号;\n- 测试遵循项目现有 E2E 体系并经过真实系统边界;\n- 观察点、数据隔离、清理和环境准备符合项目约束;\n- 所有失败均在根因明确后修复,没有制造假绿;\n- `test-executor` 报告适用 E2E 和必要的低层回归全部通过,失败为 0;存量跳过如实记录不阻断,本任务新增未授权 skip 为 0;\n- 确需保留的新增跳过须先经用户明示授权,并在任务内任一节点 `record-decision-add` 写 `topic=skip-authorized`;新增 `.only(` 或测试整删须写 `topic=test-adjust-approved`。\n- 延期登记未被删除测试、跳过标记或缩水断言替代;\n- 完整性检查通过,日志和报告可追溯;\n- `code-reviewer` 最终结论为 PASS,所有 Findings 均已处理或说明;\n- 测试代码、必要的生产修复和执行报告已形成可引用产物。\n\n## 任务差异处理\n\n项目没有适用的 E2E 体系时不新建框架、目录或执行入口。根据项目能力和设计范围选择测试、环境和回归方式,不套用固定浏览器、协议、命令或覆盖指标。失败修复涉及破坏性契约、新依赖或真实范围扩张时先说明影响并暂停;同一问题多轮仍不收敛时按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将 E2E 适用性复核、设计到实现的映射、测试代码变更、真实边界、数据与清理、实际执行命令、范围及判断依据、通过/失败/跳过统计(经 record-set 结构化写入 testReport 字段)、延期场景的 issue 编号(经 record-set 结构化写入 deferredIssues 字段)、低层回归(含前端单测,按任务轨道)、日志与报告引用、根因和修复、完整性结论、`code-reviewer` 结论与 Findings 处理情况写入当前节点记录。完成上述检查后推进下一节点。",
|
|
396
394
|
"skills": [
|
|
397
395
|
"coding-standards",
|
|
398
396
|
"workflow-discipline"
|
|
@@ -403,8 +401,8 @@
|
|
|
403
401
|
],
|
|
404
402
|
"sourcePreset": {
|
|
405
403
|
"code": "test-e2e-implement",
|
|
406
|
-
"version": "1.6.
|
|
407
|
-
"contentHash": "
|
|
404
|
+
"version": "1.6.2",
|
|
405
|
+
"contentHash": "77c32f57d7bc9d53",
|
|
408
406
|
"agents": [
|
|
409
407
|
"test-executor",
|
|
410
408
|
"code-reviewer"
|
|
@@ -433,7 +431,7 @@
|
|
|
433
431
|
"label": "集成验证",
|
|
434
432
|
"phase": "test",
|
|
435
433
|
"track": "all",
|
|
436
|
-
"prompt": "# 集成验证\n\n## 节点职责\n\n将远程主线最新状态整合到任务分支,并在最终集成态执行适用回归,形成绑定明确版本的验证结论。版本控制与范围判断由当前执行者负责——范围判断是严肃决策,跑与不跑都必须有证据支撑,全量是须举证的选项而非默认值。测试命令交给独立 `test-executor` 执行;若产生代码修复,再交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、技术方案、实现与测试记录、`align-branch` 的基础分支与合并记录,以及项目的分支策略、测试体系和所属模块提示词。加载 `workflow-discipline`,调用 `test-executor` 执行回归;发生代码修复时调用 `code-reviewer`。测试失败且根因不明确时,再加载 `bugfix-root-cause-verification`。\n\n优先使用 `align-branch` 已记录的基础分支;记录缺失时,按与该节点相同的规则从任务上下文或项目提示词解析,例如 `main`、`master` 或 `dev`。仍无法解析时询问用户是否需要合并某个分支的远程代码,不根据版本历史猜测基础分支。\n\n## 执行流程\n\n1. 获取远程状态,优先读取 `align-branch` 记录的基础分支;记录缺失时从任务上下文或项目提示词解析,仍无法解析则询问用户。记录当前任务版本、基础分支、远程版本及判断依据。\n2. 用户明确表示无需合并时记录该决定;否则按项目策略整合基础分支的远程最新代码。发生冲突时理解双方意图后逐项融合并验证结果,不盲目选择任一侧;无法可靠解决时说明冲突与缺失决策并暂停。\n3. 汇总任务改动和主线整合改动,读取项目测试目录、配置、脚本与现有用例,列出适用的测试层级和执行入口;项目未定义的层级记录 N/A。\n4. 回归执行决策由「是否执行」与「执行什么」两半构成,每一半都必须由证据支撑,禁止无分析的保守回退:\n - 零差异不重跑:某层级相对既有已验证版本(绑定明确版本标识、全绿证据在案)覆盖面差异为空时,该层级禁止重复执行,记录绑定证据替代重跑;\n - 有差异走判断链:a) 变更清单——汇总任务改动、主线整合改动与集成期修复,落到具体文件和对外可见的符号、契约、配置;b) 依赖分析——逐变更点查明引用方与波及面(导入、调用、共享契约、构建配置),得出受影响模块清单;c) 测试映射——把受影响模块映射到具体用例(既有用例位置、任务新增或修改的用例、所属层级与执行入口);d) 最小充分决策——按定向用例、受影响模块、整层级的顺序逐级扩大,每次扩大都指出上一级不充分的具体证据;\n - 全量须举证:仅当判断链证据表明影响面确实覆盖整个层级(如横切基础设施、共享契约、构建配置变更)才执行全量。宣称「无法判断影响范围」前必须已完成 a)–c) 分析;分析后仍存在的盲区逐条列明(哪个变更点、查了什么、缺什么信息),把盲区对应的补充用例并入执行范围并留痕。未做分析就宣称无法判断、或以「保险起见」跳过判断直接全量,均判定为范围决策失败。\n5. 将明确的命令、顺序、范围和通过标准交给 `test-executor` 执行——委派命令的覆盖范围必须与第 4 条判断链结论一致,判了定向就执行定向入口,不得委派时顺手扩大。依据事实报告核对各层级统计、失败、跳过和日志。\n6. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按需加载 `bugfix-root-cause-verification`,确认根因后再修改代码、测试或环境。\n7. 每次修复后重新执行原失败范围和受影响回归。不得通过删除有效测试、skip/only、缩小应执行范围、放宽正确断言、吞异常或硬编码结果制造通过。\n8.
|
|
434
|
+
"prompt": "# 集成验证\n\n## 节点职责\n\n将远程主线最新状态整合到任务分支,并在最终集成态执行适用回归,形成绑定明确版本的验证结论。版本控制与范围判断由当前执行者负责——范围判断是严肃决策,跑与不跑都必须有证据支撑,全量是须举证的选项而非默认值。测试命令交给独立 `test-executor` 执行;若产生代码修复,再交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、技术方案、实现与测试记录、`align-branch` 的基础分支与合并记录,以及项目的分支策略、测试体系和所属模块提示词。加载 `workflow-discipline`,调用 `test-executor` 执行回归;发生代码修复时调用 `code-reviewer`。测试失败且根因不明确时,再加载 `bugfix-root-cause-verification`。\n\n优先使用 `align-branch` 已记录的基础分支;记录缺失时,按与该节点相同的规则从任务上下文或项目提示词解析,例如 `main`、`master` 或 `dev`。仍无法解析时询问用户是否需要合并某个分支的远程代码,不根据版本历史猜测基础分支。\n\n## 执行流程\n\n1. 获取远程状态,优先读取 `align-branch` 记录的基础分支;记录缺失时从任务上下文或项目提示词解析,仍无法解析则询问用户。记录当前任务版本、基础分支、远程版本及判断依据。\n2. 用户明确表示无需合并时记录该决定;否则按项目策略整合基础分支的远程最新代码。发生冲突时理解双方意图后逐项融合并验证结果,不盲目选择任一侧;无法可靠解决时说明冲突与缺失决策并暂停。\n3. 汇总任务改动和主线整合改动,读取项目测试目录、配置、脚本与现有用例,列出适用的测试层级和执行入口;项目未定义的层级记录 N/A。\n4. 回归执行决策由「是否执行」与「执行什么」两半构成,每一半都必须由证据支撑,禁止无分析的保守回退:\n - 零差异不重跑:某层级相对既有已验证版本(绑定明确版本标识、全绿证据在案)覆盖面差异为空时,该层级禁止重复执行,记录绑定证据替代重跑;\n - 有差异走判断链:a) 变更清单——汇总任务改动、主线整合改动与集成期修复,落到具体文件和对外可见的符号、契约、配置;b) 依赖分析——逐变更点查明引用方与波及面(导入、调用、共享契约、构建配置),得出受影响模块清单;c) 测试映射——把受影响模块映射到具体用例(既有用例位置、任务新增或修改的用例、所属层级与执行入口);d) 最小充分决策——按定向用例、受影响模块、整层级的顺序逐级扩大,每次扩大都指出上一级不充分的具体证据;\n - 全量须举证:仅当判断链证据表明影响面确实覆盖整个层级(如横切基础设施、共享契约、构建配置变更)才执行全量。宣称「无法判断影响范围」前必须已完成 a)–c) 分析;分析后仍存在的盲区逐条列明(哪个变更点、查了什么、缺什么信息),把盲区对应的补充用例并入执行范围并留痕。未做分析就宣称无法判断、或以「保险起见」跳过判断直接全量,均判定为范围决策失败。\n5. 将明确的命令、顺序、范围和通过标准交给 `test-executor` 执行——委派命令的覆盖范围必须与第 4 条判断链结论一致,判了定向就执行定向入口,不得委派时顺手扩大。依据事实报告核对各层级统计、失败、跳过和日志。\n6. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按需加载 `bugfix-root-cause-verification`,确认根因后再修改代码、测试或环境。\n7. 每次修复后重新执行原失败范围和受影响回归。不得通过删除有效测试、skip/only、缩小应执行范围、放宽正确断言、吞异常或硬编码结果制造通过。\n8. 检查本任务新增 skip/only(存量跳过不要求授权)、测试删除、未执行的适用层级、范围遗漏和统计对账。发生代码修复时,将评审目标与材料(变更位置与相关任务信息)交给 `code-reviewer`;修复 BLOCKER、HIGH Findings 后重跑受影响测试并复审,直至测试通过且评审为 PASS。\n9. 记录最终同步状态、实际回归范围、测试结果和已验证的提交或等价版本标识,确保后续能够判断证据是否仍有效。\n\n## 产出与检查\n\n推进前确认:\n\n- 基础分支沿用 `align-branch` 记录,或已按相同规则重新解析并留痕;\n- 基础分支的远程状态已获取并完成整合,或用户已明确表示无需合并;\n- 所有冲突均已理解并正确融合;\n- 项目适用测试层级与执行入口已识别,N/A 有具体依据;\n- 回归范围由完整判断链支撑(变更清单 → 依赖分析 → 测试映射 → 逐级扩大决策),每个执行范围都能指认其覆盖的变更点;零差异层级以绑定证据替代重跑;全量执行附有影响面覆盖整个层级的具体证据;不存在无分析的全量兜底;\n- `test-executor` 报告所有适用回归通过,失败为 0;存量跳过如实记录不阻断,本任务新增未授权 skip 为 0;\n- 所有失败均在根因明确后修复,没有制造假绿;\n- 发生代码修复时,`code-reviewer` 最终结论为 PASS;\n- 集成结论绑定明确版本,日志和报告可追溯。\n\n## 任务差异处理\n\n基础分支没有新提交时无需制造合并提交;回归是否执行、执行什么,一律按第 4 条的零差异判定与判断链决定——集成态与已验证版本一致且证据在案时以证据绑定替代重跑,集成态有新增内容时按判断链定范围。用户明确表示无需合并时保留决定,验证决策同样按第 4 条执行。根据项目实际体系选择测试层级和命令,不擅自引入未定义的测试类型。远程状态不可获取、冲突无法可靠解决,或修复涉及破坏性契约、新依赖和真实范围扩张时,说明证据与影响并暂停;同一问题多轮不收敛时按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将基础分支来源、同步策略与结果、任务和远程版本、冲突处理、适用测试层级、回归范围判断链(变更清单、依赖分析、测试映射、逐级扩大证据、零差异证据绑定)及结论、实际命令与统计、失败根因和修复、完整性检查、代码评审结果、日志与报告引用、最终已验证版本(经 record-set 结构化写入 verifiedCommit 字段;本轮发生修复时经 record-set 写入 fixesApplied 次数)写入当前节点记录。完成上述检查后推进下一节点。\n",
|
|
437
435
|
"skills": [
|
|
438
436
|
"workflow-discipline"
|
|
439
437
|
],
|
|
@@ -443,8 +441,8 @@
|
|
|
443
441
|
],
|
|
444
442
|
"sourcePreset": {
|
|
445
443
|
"code": "test-integrate",
|
|
446
|
-
"version": "1.5.
|
|
447
|
-
"contentHash": "
|
|
444
|
+
"version": "1.5.2",
|
|
445
|
+
"contentHash": "32678fd8653c6d78",
|
|
448
446
|
"agents": [
|
|
449
447
|
"test-executor",
|
|
450
448
|
"code-reviewer"
|
|
@@ -460,6 +458,9 @@
|
|
|
460
458
|
{
|
|
461
459
|
"type": "record-test-report"
|
|
462
460
|
},
|
|
461
|
+
{
|
|
462
|
+
"type": "record-no-fake-green"
|
|
463
|
+
},
|
|
463
464
|
{
|
|
464
465
|
"type": "record-fix-review-pass"
|
|
465
466
|
},
|
|
@@ -479,15 +480,15 @@
|
|
|
479
480
|
"label": "发布验收",
|
|
480
481
|
"phase": "exit",
|
|
481
482
|
"track": "all",
|
|
482
|
-
"prompt": "# 发布验收\n\n## 节点职责\n\n核对最终集成验证证据与当前版本是否一致,向用户呈现可独立理解的验收摘要,并按本节点在流程中的位置承载确认与代码归档:存在后继审批边时,用户确认由流转边暂停点承载,本节点不重复确认;本节点为任务终点时,节点内确认是任务收尾唯一授权门。本节点不重复执行测试、代码评审或回归分析。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、非目标、已激活节点的完成记录、`test-integrate` 的测试范围与结果、日志以及已验证版本标识,并读取项目分支与归档策略。加载 `workflow-discipline`。\n\n缺少集成验证证据、版本标识或前序完成记录时,先从任务上下文补齐;证据仍不完整或无法对应当前版本时停止验收,不推断通过。\n\n## 执行流程\n\n1. 确认所有已激活的前序节点均已完成,不写死某一模板路径下的节点清单。\n2. 比较当前生产代码与 `test-integrate` 绑定的已验证版本。存在新的生产代码变化时,退回集成验证重新判断范围并回归;纯文档或记录变化说明为何不影响证据。\n3. 逐条核对验收标准对应的实现位置和前序验证证据,并确认非目标未被误实现、范围变化已说明、所有 reviewer 的阻塞问题已解决。\n4.
|
|
483
|
+
"prompt": "# 发布验收\n\n## 节点职责\n\n核对最终集成验证证据与当前版本是否一致,向用户呈现可独立理解的验收摘要,并按本节点在流程中的位置承载确认与代码归档:存在后继审批边时,用户确认由流转边暂停点承载,本节点不重复确认;本节点为任务终点时,节点内确认是任务收尾唯一授权门。本节点不重复执行测试、代码评审或回归分析。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、非目标、已激活节点的完成记录、`test-integrate` 的测试范围与结果、日志以及已验证版本标识,并读取项目分支与归档策略。加载 `workflow-discipline`。\n\n缺少集成验证证据、版本标识或前序完成记录时,先从任务上下文补齐;证据仍不完整或无法对应当前版本时停止验收,不推断通过。\n\n## 执行流程\n\n1. 确认所有已激活的前序节点均已完成,不写死某一模板路径下的节点清单。\n2. 比较当前生产代码与 `test-integrate` 绑定的已验证版本。存在新的生产代码变化时,退回集成验证重新判断范围并回归;纯文档或记录变化说明为何不影响证据。\n3. 逐条核对验收标准对应的实现位置和前序验证证据,并确认非目标未被误实现、范围变化已说明、所有 reviewer 的阻塞问题已解决。\n4. 汇总集成测试范围与统计、本任务新增未授权跳过(存量跳过不阻断)、实现与验收标准对应关系、范围变化、已知问题和风险,形成简洁且不依赖任务内部术语的验收摘要。\n5. 判定本节点位置:读取任务上下文中的任务结构(DAG 节点集与各节点状态)——本节点是任务最后一个节点(如快速流程形态,已完成数加一等于节点总数)即为终态形态;存在后继节点(如架构归档节点)即为非终态形态。advance 响应的 nextNode 资料包可作交叉印证。两种形态的确认与归档时序不同,按后续步骤分支执行,判定结果写入节点记录。\n6. **终态形态(本节点为任务终点,无后继审批边)**:向用户呈现验收摘要并在节点内取得明确决定。只有明确的通过、确认归档或等价肯定表达构成确认;提问、条件句、部分认同、沉默或模糊表态不构成确认。确认后逐字记录确认原文,并按项目声明完成提交、合并、推送或其他代码归档动作。无项目策略时采用保留历史且可回退的常规方式,并记录采用的默认。\n7. **非终态形态(存在后继审批边)**:向用户呈现验收摘要(作为暂停点审批材料);推进前在节点记录写入显式「归档待办」条目(归档动作清单:目标分支、合并方式、推送范围);然后推进进入暂停点等待用户审批——审批通过即验收确认,确认原文以审批记录留痕(须逐字引用用户确认表态,不得转述失真),本节点不重复确认。审批通过后、开始下一节点工作前,先完成归档待办中的代码归档动作(提交/合并/推送),完成后回写归档结果闭环该待办;归档待办在归档完成前不得闭环。\n8. 归档过程中遇到冲突或失败时先检查实际版本控制状态并自主诊断;无法可靠解决时说明当前状态和卡点,不猜测操作结果。\n\n## 产出与检查\n\n推进前确认:\n\n- 所有已激活前序节点已完成;\n- 集成验证证据完整,所有适用测试通过,失败为 0;本任务新增未授权跳过为 0(存量跳过不阻断);\n- 当前生产代码与已验证版本一致;\n- 每条验收标准都有实现和验证证据,非目标、范围变化与已知问题已说明;\n- 没有未解决的 BLOCKER、HIGH 或其他流程定义的阻塞问题;\n- 终态形态:用户已明确确认,确认原文已逐字记录,代码已按项目策略归档;\n- 非终态形态:验收摘要已呈现,归档待办已写入且动作清单明确(归档动作待审批通过后执行,不在本节点提前归档);\n- 最终提交、分支和远程状态可追溯。\n\n## 任务差异处理\n\n任务没有代码或项目没有分支归档流程时,执行适用的验收确认并说明不适用项。用户要求附条件通过或接受具体风险时,终态形态在节点内记录条件、风险和确认原文;非终态形态该表态在暂停点审批中给出,审批记录即留痕。未被明确接受的阻塞问题不得归档。证据过期、验收标准缺失或代码归档失败时,按实际问题返回相应节点处理,不在本节点重新执行其职责。\n\n## 节点记录与推进\n\n推进前将验收摘要、证据时效、验收标准对照、范围变化、已知问题和位置判定结果写入当前节点记录;非终态形态同时写入归档待办,并在归档完成前保持其未闭环。终态形态在用户确认后追加确认原文与归档结果;非终态形态在暂停点审批通过并完成归档后,追加审批引用、归档策略与结果、最终提交和远程状态,闭环归档待办。完成推进前检查后推进下一节点——终态形态的推进必须带收尾确认参数(CLI `--finalize` / MCP `finalize=true`),终节点缺省 advance 会被拒绝并提示;非终态形态不带该参数(携带也会被忽略);批后追加动作发生在推进之后,不阻塞推进。",
|
|
483
484
|
"skills": [
|
|
484
485
|
"workflow-discipline"
|
|
485
486
|
],
|
|
486
487
|
"agents": [],
|
|
487
488
|
"sourcePreset": {
|
|
488
489
|
"code": "release-accept",
|
|
489
|
-
"version": "1.5.
|
|
490
|
-
"contentHash": "
|
|
490
|
+
"version": "1.5.3",
|
|
491
|
+
"contentHash": "2d9dadaf80732cfa",
|
|
491
492
|
"agents": []
|
|
492
493
|
},
|
|
493
494
|
"toolChecks": [
|
|
@@ -661,72 +662,72 @@
|
|
|
661
662
|
],
|
|
662
663
|
"layout": {
|
|
663
664
|
"PRD": {
|
|
664
|
-
"x":
|
|
665
|
-
"y":
|
|
665
|
+
"x": 312,
|
|
666
|
+
"y": 88
|
|
666
667
|
},
|
|
667
668
|
"ALIGN": {
|
|
668
|
-
"x":
|
|
669
|
-
"y":
|
|
669
|
+
"x": 312,
|
|
670
|
+
"y": 304
|
|
670
671
|
},
|
|
671
672
|
"INTERACTION": {
|
|
672
|
-
"x":
|
|
673
|
-
"y":
|
|
673
|
+
"x": 397,
|
|
674
|
+
"y": 520
|
|
674
675
|
},
|
|
675
676
|
"DESIGN": {
|
|
676
|
-
"x":
|
|
677
|
-
"y":
|
|
677
|
+
"x": 312,
|
|
678
|
+
"y": 736
|
|
678
679
|
},
|
|
679
680
|
"CODE_BACKEND": {
|
|
680
|
-
"x":
|
|
681
|
-
"y":
|
|
681
|
+
"x": 472,
|
|
682
|
+
"y": 952
|
|
682
683
|
},
|
|
683
684
|
"CODE_UI": {
|
|
684
|
-
"x":
|
|
685
|
-
"y":
|
|
685
|
+
"x": 152,
|
|
686
|
+
"y": 952
|
|
686
687
|
},
|
|
687
688
|
"UI_VISUAL": {
|
|
688
|
-
"x":
|
|
689
|
-
"y":
|
|
689
|
+
"x": 152,
|
|
690
|
+
"y": 1600
|
|
690
691
|
},
|
|
691
692
|
"UT_DESIGN": {
|
|
692
|
-
"x":
|
|
693
|
-
"y":
|
|
693
|
+
"x": 472,
|
|
694
|
+
"y": 1168
|
|
694
695
|
},
|
|
695
696
|
"UT_DEV": {
|
|
696
|
-
"x":
|
|
697
|
-
"y":
|
|
697
|
+
"x": 472,
|
|
698
|
+
"y": 1384
|
|
698
699
|
},
|
|
699
700
|
"UI_UT_DESIGN": {
|
|
700
|
-
"x":
|
|
701
|
-
"y":
|
|
701
|
+
"x": 152,
|
|
702
|
+
"y": 1168
|
|
702
703
|
},
|
|
703
704
|
"UI_UT_DEV": {
|
|
704
|
-
"x":
|
|
705
|
-
"y":
|
|
705
|
+
"x": 152,
|
|
706
|
+
"y": 1384
|
|
706
707
|
},
|
|
707
708
|
"E2E_DESIGN": {
|
|
708
|
-
"x":
|
|
709
|
-
"y":
|
|
709
|
+
"x": 312,
|
|
710
|
+
"y": 1816
|
|
710
711
|
},
|
|
711
712
|
"E2E_DEV": {
|
|
712
|
-
"x":
|
|
713
|
-
"y":
|
|
713
|
+
"x": 312,
|
|
714
|
+
"y": 2032
|
|
714
715
|
},
|
|
715
716
|
"INTEGRATE": {
|
|
716
|
-
"x":
|
|
717
|
-
"y":
|
|
717
|
+
"x": 312,
|
|
718
|
+
"y": 2248
|
|
718
719
|
},
|
|
719
720
|
"ACCEPT": {
|
|
720
|
-
"x":
|
|
721
|
-
"y":
|
|
721
|
+
"x": 312,
|
|
722
|
+
"y": 2464
|
|
722
723
|
},
|
|
723
724
|
"ARCHIVE": {
|
|
724
|
-
"x":
|
|
725
|
-
"y":
|
|
725
|
+
"x": 312,
|
|
726
|
+
"y": 2680
|
|
726
727
|
}
|
|
727
728
|
},
|
|
728
729
|
"isDefault": false,
|
|
729
|
-
"version": "3.7.
|
|
730
|
+
"version": "3.7.8"
|
|
730
731
|
},
|
|
731
732
|
"dependencies": {
|
|
732
733
|
"skills": [
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"exportFormatVersion": "1.0",
|
|
3
|
-
"exportedAt": "2026-10-
|
|
3
|
+
"exportedAt": "2026-10-23T09:51:30.295Z",
|
|
4
4
|
"warnings": [],
|
|
5
5
|
"template": {
|
|
6
6
|
"name": "quick_workflow",
|
|
7
|
-
"description": "通用快速开发流程:分支对齐、快速设计(AI 评审 + 人工确认)、后端或前端实现与测试一体(自动测试全绿 + 代码评审 +
|
|
7
|
+
"description": "通用快速开发流程:分支对齐、快速设计(AI 评审 + 人工确认)、后端或前端实现与测试一体(自动测试全绿 + 代码评审 + 视觉验证)、E2E 增量验证(增量用例设计 + 实现 + 执行)、集成验证与发布验收。适用于范围明确的小型改动;命中复杂度红线时建议改走完整流程。混合任务先完成后端实现,再进入前端实现。",
|
|
8
8
|
"nodes": [
|
|
9
9
|
{
|
|
10
10
|
"id": "ALIGN",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"label": "后端编码与测试",
|
|
64
64
|
"phase": "track",
|
|
65
65
|
"track": "backend",
|
|
66
|
-
"prompt": "# 后端编码与测试\n\n## 节点职责\n\n在单一节点内完成实现与验证闭环:编写生产代码与配套测试、执行测试取得全绿结果、通过独立代码评审。四项同为节点完成判定,缺一不可。\n\n## 依赖信息\n\n先检查当前任务上下文:需求、验收标准、技术方案、既有决策、项目和所属模块提示词。加载 `coding-standards`(按技术栈读对应 reference)、`workflow-discipline`;调用 `test-executor` 执行测试、`code-reviewer` 评审代码;测试失败根因不明时加载 `bugfix-root-cause-verification`。\n\n## 正向执行流程\n\n1. 将方案改动点整理为实现项,明确行为边界、错误处理、状态变化与副作用;调查调用链、数据模型与既有契约,沿用项目惯例。\n2. 实现生产代码:最小充分范围,遵循分层与规范,不清除无关注释。\n3. 编写配套测试:按改动影响面确定测试层级与用例集,新增行为必有对应测试,受影响的存量测试同步修正。本节点同时产出生产代码与测试代码——通用流程「编码节点不修改测试」的分工不适用于本合节点形态。\n4. 判定确无可自动验证行为时(如纯配置或文案),在节点记录写明判定与理由;未记录判定的,测试集不得为空。设计阶段已声明该预判的,按声明执行。\n5. 主会话执行类型检查、编译、构建、静态分析并留痕。\n6. 将测试命令、范围、顺序与通过标准交给 `test-executor` 执行,核对统计与日志。失败时先完成根因调查再做最小正确修复,重跑原失败范围与受影响回归;禁止删除有效测试、skip/only、缩小范围、放宽断言制造通过。\n7. 将需求、方案、项目约束与变更位置交给 `code-reviewer` 独立评审,不提供主会话结论。BLOCKER、HIGH 修复后重审直至 PASS;MEDIUM、LOW 逐项处理或记录保留理由。\n\n## 产出与检查\n\n推进前确认:实现完成且与方案逐项对应;配套测试完成(或无可测行为判定已记录理由);静态检查通过并留痕;`test-executor` 报告全绿(失败 0
|
|
66
|
+
"prompt": "# 后端编码与测试\n\n## 节点职责\n\n在单一节点内完成实现与验证闭环:编写生产代码与配套测试、执行测试取得全绿结果、通过独立代码评审。四项同为节点完成判定,缺一不可。\n\n## 依赖信息\n\n先检查当前任务上下文:需求、验收标准、技术方案、既有决策、项目和所属模块提示词。加载 `coding-standards`(按技术栈读对应 reference)、`workflow-discipline`;调用 `test-executor` 执行测试、`code-reviewer` 评审代码;测试失败根因不明时加载 `bugfix-root-cause-verification`。\n\n## 正向执行流程\n\n1. 将方案改动点整理为实现项,明确行为边界、错误处理、状态变化与副作用;调查调用链、数据模型与既有契约,沿用项目惯例。\n2. 实现生产代码:最小充分范围,遵循分层与规范,不清除无关注释。\n3. 编写配套测试:按改动影响面确定测试层级与用例集,新增行为必有对应测试,受影响的存量测试同步修正。本节点同时产出生产代码与测试代码——通用流程「编码节点不修改测试」的分工不适用于本合节点形态。\n4. 判定确无可自动验证行为时(如纯配置或文案),在节点记录写明判定与理由;未记录判定的,测试集不得为空。设计阶段已声明该预判的,按声明执行。\n5. 主会话执行类型检查、编译、构建、静态分析并留痕。\n6. 将测试命令、范围、顺序与通过标准交给 `test-executor` 执行,核对统计与日志。失败时先完成根因调查再做最小正确修复,重跑原失败范围与受影响回归;禁止删除有效测试、skip/only、缩小范围、放宽断言制造通过。\n7. 将需求、方案、项目约束与变更位置交给 `code-reviewer` 独立评审,不提供主会话结论。BLOCKER、HIGH 修复后重审直至 PASS;MEDIUM、LOW 逐项处理或记录保留理由。\n\n## 产出与检查\n\n推进前确认:实现完成且与方案逐项对应;配套测试完成(或无可测行为判定已记录理由);静态检查通过并留痕;`test-executor` 报告全绿(失败 0;存量跳过如实统计、不阻断,本任务新增未授权 skip 为 0);确需保留的新增跳过须先经用户明示授权,并在任务内任一节点 `record-decision-add` 写 `topic=skip-authorized`;新增 `.only(` 或测试整删须写 `topic=test-adjust-approved`。`code-reviewer` 最终 PASS 且 Findings 处理留痕。\n\n## 任务差异处理\n\n执行障碍与修复循环按 `workflow-discipline` 处理,不收敛时暂停上升用户。某项检查不适用时说明理由,不静默跳过。\n\n## 节点记录与推进\n\n记录实现摘要、主要变更、静态检查结果、测试范围与统计、无可测行为判定(如有)、评审结论与 Findings 处理、产物引用,推进下一节点。",
|
|
67
67
|
"skills": [
|
|
68
68
|
"coding-standards",
|
|
69
69
|
"workflow-discipline"
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
],
|
|
75
75
|
"sourcePreset": {
|
|
76
76
|
"code": "quick-code-backend",
|
|
77
|
-
"version": "1.0.
|
|
78
|
-
"contentHash": "
|
|
77
|
+
"version": "1.0.2",
|
|
78
|
+
"contentHash": "c271210388419bee",
|
|
79
79
|
"agents": [
|
|
80
80
|
"code-reviewer",
|
|
81
81
|
"test-executor"
|
|
@@ -108,12 +108,54 @@
|
|
|
108
108
|
]
|
|
109
109
|
}
|
|
110
110
|
},
|
|
111
|
+
{
|
|
112
|
+
"id": "E2E_QUICK",
|
|
113
|
+
"label": "E2E增量验证",
|
|
114
|
+
"phase": "test",
|
|
115
|
+
"track": "all",
|
|
116
|
+
"prompt": "# E2E增量验证\n\n## 节点职责\n\n在单一节点内完成本任务增量的端到端测试闭环:只为本次改动新增或变化的行为设计 E2E 用例,实现并执行这些用例取得全绿结果。设计与执行都以增量为边界——不重新覆盖既有流程,不执行全量 E2E 回归(存量回归由集成验证节点的判断链决定)。\n\n## 依赖信息\n\n先检查当前任务上下文:需求、验收标准、快速设计的改动点清单与影响面、编码节点的实现与测试记录。加载 `workflow-discipline`;调用 `test-reviewer` 评审用例设计、`test-executor` 执行测试;失败根因不明时加载 `bugfix-root-cause-verification`;发生生产代码修复时调用 `code-reviewer`。\n\n识别项目声明的 E2E 测试体系与执行入口(目录、配置、脚本、运行方式),以项目声明为准;不假设具体路径或命令,不擅自引入项目未定义的测试设施。\n\n## 正向执行流程\n\n1. 从改动点清单与编码记录提取增量:新增行为、行为变化、变化的接口或数据契约。逐项判定端到端可见性——是否构成用户可感知的完整链路(如界面操作→服务→数据或等价路径);判定为否的项记录理由,不设计用例。\n2. 项目未定义 E2E 体系,或增量中无端到端可见行为时,写入 N/A 判定与理由后推进——不为快速任务从零搭建 E2E 基础设施;确需搭建时说明影响并建议改走完整流程。\n3. 为每个端到端可见的增量项设计最小用例集:前置与数据、操作序列、对准验收标准的关键断言、清理复位。只覆盖增量,不连带既有流程。\n4. 将增量清单、逐项判定与用例设计交给 `test-reviewer` 单轮独立评审,不提供主会话结论;BLOCKER、HIGH 修复后重审,MEDIUM、LOW 逐项处理或记录保留理由,直至 PASS。\n5. 按项目 E2E 体系实现用例代码,沿用既有用例的组织与定位器惯例;原则上不为用例修改生产代码,确需可测性调整时说明并保持最小。\n6. 存量 E2E 用例因本任务行为变化而断言失效时,同步修正并纳入本次执行范围(属增量波及,非全量回归);除此之外不执行任何存量用例。\n7. 将本节点产出用例的执行命令、范围与通过标准交给 `test-executor` 执行。执行范围默认为新增及修正用例——目的是控制耗时,存量回归由集成验证节点按其判断链决定,本节点不重复。执行中判断需要超出默认范围的用例或执行时,按价值决策,产物保留并在节点记录写明补充理由。失败时先完成根因调查再做最小正确修复并重跑原失败用例;确属生产代码缺陷时,修复交 `code-reviewer` 评审至 PASS。\n8. 记录新增用例清单(位置、覆盖的增量项)、修正的存量用例、执行统计与证据,绑定明确版本标识,供集成验证节点的回归判断链消费。\n\n## 产出与检查\n\n推进前确认:增量提取与端到端可见判定逐项留痕(含 N/A 项与理由);有增量用例时 `test-reviewer` 最终 PASS 且 Findings 处理留痕;`test-executor` 报告执行范围内用例全绿、失败 0,本任务新增未授权 skip/only 为 0;执行统计与用例清单对应(超出默认范围的部分有理由留痕);发生生产代码修复时 `code-reviewer` PASS;用例清单与版本绑定已写入记录。\n\n## 任务差异处理\n\n项目无 E2E 体系、增量无端到端可见行为、或本节点被任务剪枝时,写明判定与理由后推进,不静默跳过。执行环境无法满足 E2E 运行前置(服务、数据、环境)时,说明卡点并暂停上升用户,不降级伪造执行结果。\n\n## 节点记录与推进\n\n将增量清单与判定、用例设计要点、评审结论与 Findings 处理、新增用例位置与覆盖对应、修正的存量用例、执行命令与统计、失败根因与修复(如有)、评审结论(如有)、绑定版本写入当前节点记录,推进集成验证节点。",
|
|
117
|
+
"skills": [
|
|
118
|
+
"workflow-discipline"
|
|
119
|
+
],
|
|
120
|
+
"agents": [
|
|
121
|
+
"test-reviewer",
|
|
122
|
+
"test-executor",
|
|
123
|
+
"code-reviewer"
|
|
124
|
+
],
|
|
125
|
+
"sourcePreset": {
|
|
126
|
+
"code": "quick-e2e-verify",
|
|
127
|
+
"version": "1.0.0",
|
|
128
|
+
"contentHash": "54b99f388b874c01",
|
|
129
|
+
"agents": [
|
|
130
|
+
"test-reviewer",
|
|
131
|
+
"test-executor",
|
|
132
|
+
"code-reviewer"
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
"toolChecks": [
|
|
136
|
+
{
|
|
137
|
+
"type": "record-test-report"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"type": "record-no-fake-green"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"type": "git-worktree-clean"
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
"aiChecks": [
|
|
147
|
+
{
|
|
148
|
+
"id": "e2eq-delta-mapping",
|
|
149
|
+
"item": "增量提取与端到端可见判定逐项留痕(含 N/A 项与理由);新增用例与增量项的覆盖对应关系已写入节点记录"
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
},
|
|
111
153
|
{
|
|
112
154
|
"id": "INTEGRATE",
|
|
113
155
|
"label": "集成验证",
|
|
114
156
|
"phase": "test",
|
|
115
157
|
"track": "all",
|
|
116
|
-
"prompt": "# 集成验证\n\n## 节点职责\n\n将远程主线最新状态整合到任务分支,并在最终集成态执行适用回归,形成绑定明确版本的验证结论。版本控制与范围判断由当前执行者负责——范围判断是严肃决策,跑与不跑都必须有证据支撑,全量是须举证的选项而非默认值。测试命令交给独立 `test-executor` 执行;若产生代码修复,再交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、技术方案、实现与测试记录、`align-branch` 的基础分支与合并记录,以及项目的分支策略、测试体系和所属模块提示词。加载 `workflow-discipline`,调用 `test-executor` 执行回归;发生代码修复时调用 `code-reviewer`。测试失败且根因不明确时,再加载 `bugfix-root-cause-verification`。\n\n优先使用 `align-branch` 已记录的基础分支;记录缺失时,按与该节点相同的规则从任务上下文或项目提示词解析,例如 `main`、`master` 或 `dev`。仍无法解析时询问用户是否需要合并某个分支的远程代码,不根据版本历史猜测基础分支。\n\n## 执行流程\n\n1. 获取远程状态,优先读取 `align-branch` 记录的基础分支;记录缺失时从任务上下文或项目提示词解析,仍无法解析则询问用户。记录当前任务版本、基础分支、远程版本及判断依据。\n2. 用户明确表示无需合并时记录该决定;否则按项目策略整合基础分支的远程最新代码。发生冲突时理解双方意图后逐项融合并验证结果,不盲目选择任一侧;无法可靠解决时说明冲突与缺失决策并暂停。\n3. 汇总任务改动和主线整合改动,读取项目测试目录、配置、脚本与现有用例,列出适用的测试层级和执行入口;项目未定义的层级记录 N/A。\n4. 回归执行决策由「是否执行」与「执行什么」两半构成,每一半都必须由证据支撑,禁止无分析的保守回退:\n - 零差异不重跑:某层级相对既有已验证版本(绑定明确版本标识、全绿证据在案)覆盖面差异为空时,该层级禁止重复执行,记录绑定证据替代重跑;\n - 有差异走判断链:a) 变更清单——汇总任务改动、主线整合改动与集成期修复,落到具体文件和对外可见的符号、契约、配置;b) 依赖分析——逐变更点查明引用方与波及面(导入、调用、共享契约、构建配置),得出受影响模块清单;c) 测试映射——把受影响模块映射到具体用例(既有用例位置、任务新增或修改的用例、所属层级与执行入口);d) 最小充分决策——按定向用例、受影响模块、整层级的顺序逐级扩大,每次扩大都指出上一级不充分的具体证据;\n - 全量须举证:仅当判断链证据表明影响面确实覆盖整个层级(如横切基础设施、共享契约、构建配置变更)才执行全量。宣称「无法判断影响范围」前必须已完成 a)–c) 分析;分析后仍存在的盲区逐条列明(哪个变更点、查了什么、缺什么信息),把盲区对应的补充用例并入执行范围并留痕。未做分析就宣称无法判断、或以「保险起见」跳过判断直接全量,均判定为范围决策失败。\n5. 将明确的命令、顺序、范围和通过标准交给 `test-executor` 执行——委派命令的覆盖范围必须与第 4 条判断链结论一致,判了定向就执行定向入口,不得委派时顺手扩大。依据事实报告核对各层级统计、失败、跳过和日志。\n6. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按需加载 `bugfix-root-cause-verification`,确认根因后再修改代码、测试或环境。\n7. 每次修复后重新执行原失败范围和受影响回归。不得通过删除有效测试、skip/only、缩小应执行范围、放宽正确断言、吞异常或硬编码结果制造通过。\n8.
|
|
158
|
+
"prompt": "# 集成验证\n\n## 节点职责\n\n将远程主线最新状态整合到任务分支,并在最终集成态执行适用回归,形成绑定明确版本的验证结论。版本控制与范围判断由当前执行者负责——范围判断是严肃决策,跑与不跑都必须有证据支撑,全量是须举证的选项而非默认值。测试命令交给独立 `test-executor` 执行;若产生代码修复,再交给独立 `code-reviewer` 评审。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、技术方案、实现与测试记录、`align-branch` 的基础分支与合并记录,以及项目的分支策略、测试体系和所属模块提示词。加载 `workflow-discipline`,调用 `test-executor` 执行回归;发生代码修复时调用 `code-reviewer`。测试失败且根因不明确时,再加载 `bugfix-root-cause-verification`。\n\n优先使用 `align-branch` 已记录的基础分支;记录缺失时,按与该节点相同的规则从任务上下文或项目提示词解析,例如 `main`、`master` 或 `dev`。仍无法解析时询问用户是否需要合并某个分支的远程代码,不根据版本历史猜测基础分支。\n\n## 执行流程\n\n1. 获取远程状态,优先读取 `align-branch` 记录的基础分支;记录缺失时从任务上下文或项目提示词解析,仍无法解析则询问用户。记录当前任务版本、基础分支、远程版本及判断依据。\n2. 用户明确表示无需合并时记录该决定;否则按项目策略整合基础分支的远程最新代码。发生冲突时理解双方意图后逐项融合并验证结果,不盲目选择任一侧;无法可靠解决时说明冲突与缺失决策并暂停。\n3. 汇总任务改动和主线整合改动,读取项目测试目录、配置、脚本与现有用例,列出适用的测试层级和执行入口;项目未定义的层级记录 N/A。\n4. 回归执行决策由「是否执行」与「执行什么」两半构成,每一半都必须由证据支撑,禁止无分析的保守回退:\n - 零差异不重跑:某层级相对既有已验证版本(绑定明确版本标识、全绿证据在案)覆盖面差异为空时,该层级禁止重复执行,记录绑定证据替代重跑;\n - 有差异走判断链:a) 变更清单——汇总任务改动、主线整合改动与集成期修复,落到具体文件和对外可见的符号、契约、配置;b) 依赖分析——逐变更点查明引用方与波及面(导入、调用、共享契约、构建配置),得出受影响模块清单;c) 测试映射——把受影响模块映射到具体用例(既有用例位置、任务新增或修改的用例、所属层级与执行入口);d) 最小充分决策——按定向用例、受影响模块、整层级的顺序逐级扩大,每次扩大都指出上一级不充分的具体证据;\n - 全量须举证:仅当判断链证据表明影响面确实覆盖整个层级(如横切基础设施、共享契约、构建配置变更)才执行全量。宣称「无法判断影响范围」前必须已完成 a)–c) 分析;分析后仍存在的盲区逐条列明(哪个变更点、查了什么、缺什么信息),把盲区对应的补充用例并入执行范围并留痕。未做分析就宣称无法判断、或以「保险起见」跳过判断直接全量,均判定为范围决策失败。\n5. 将明确的命令、顺序、范围和通过标准交给 `test-executor` 执行——委派命令的覆盖范围必须与第 4 条判断链结论一致,判了定向就执行定向入口,不得委派时顺手扩大。依据事实报告核对各层级统计、失败、跳过和日志。\n6. 测试失败时读取完整证据。根因明确则做最小正确修复;根因不明确则按需加载 `bugfix-root-cause-verification`,确认根因后再修改代码、测试或环境。\n7. 每次修复后重新执行原失败范围和受影响回归。不得通过删除有效测试、skip/only、缩小应执行范围、放宽正确断言、吞异常或硬编码结果制造通过。\n8. 检查本任务新增 skip/only(存量跳过不要求授权)、测试删除、未执行的适用层级、范围遗漏和统计对账。发生代码修复时,将评审目标与材料(变更位置与相关任务信息)交给 `code-reviewer`;修复 BLOCKER、HIGH Findings 后重跑受影响测试并复审,直至测试通过且评审为 PASS。\n9. 记录最终同步状态、实际回归范围、测试结果和已验证的提交或等价版本标识,确保后续能够判断证据是否仍有效。\n\n## 产出与检查\n\n推进前确认:\n\n- 基础分支沿用 `align-branch` 记录,或已按相同规则重新解析并留痕;\n- 基础分支的远程状态已获取并完成整合,或用户已明确表示无需合并;\n- 所有冲突均已理解并正确融合;\n- 项目适用测试层级与执行入口已识别,N/A 有具体依据;\n- 回归范围由完整判断链支撑(变更清单 → 依赖分析 → 测试映射 → 逐级扩大决策),每个执行范围都能指认其覆盖的变更点;零差异层级以绑定证据替代重跑;全量执行附有影响面覆盖整个层级的具体证据;不存在无分析的全量兜底;\n- `test-executor` 报告所有适用回归通过,失败为 0;存量跳过如实记录不阻断,本任务新增未授权 skip 为 0;\n- 所有失败均在根因明确后修复,没有制造假绿;\n- 发生代码修复时,`code-reviewer` 最终结论为 PASS;\n- 集成结论绑定明确版本,日志和报告可追溯。\n\n## 任务差异处理\n\n基础分支没有新提交时无需制造合并提交;回归是否执行、执行什么,一律按第 4 条的零差异判定与判断链决定——集成态与已验证版本一致且证据在案时以证据绑定替代重跑,集成态有新增内容时按判断链定范围。用户明确表示无需合并时保留决定,验证决策同样按第 4 条执行。根据项目实际体系选择测试层级和命令,不擅自引入未定义的测试类型。远程状态不可获取、冲突无法可靠解决,或修复涉及破坏性契约、新依赖和真实范围扩张时,说明证据与影响并暂停;同一问题多轮不收敛时按 `workflow-discipline` 处理。\n\n## 节点记录与推进\n\n将基础分支来源、同步策略与结果、任务和远程版本、冲突处理、适用测试层级、回归范围判断链(变更清单、依赖分析、测试映射、逐级扩大证据、零差异证据绑定)及结论、实际命令与统计、失败根因和修复、完整性检查、代码评审结果、日志与报告引用、最终已验证版本(经 record-set 结构化写入 verifiedCommit 字段;本轮发生修复时经 record-set 写入 fixesApplied 次数)写入当前节点记录。完成上述检查后推进下一节点。\n",
|
|
117
159
|
"skills": [
|
|
118
160
|
"workflow-discipline"
|
|
119
161
|
],
|
|
@@ -123,8 +165,8 @@
|
|
|
123
165
|
],
|
|
124
166
|
"sourcePreset": {
|
|
125
167
|
"code": "test-integrate",
|
|
126
|
-
"version": "1.5.
|
|
127
|
-
"contentHash": "
|
|
168
|
+
"version": "1.5.2",
|
|
169
|
+
"contentHash": "32678fd8653c6d78",
|
|
128
170
|
"agents": [
|
|
129
171
|
"test-executor",
|
|
130
172
|
"code-reviewer"
|
|
@@ -140,6 +182,9 @@
|
|
|
140
182
|
{
|
|
141
183
|
"type": "record-test-report"
|
|
142
184
|
},
|
|
185
|
+
{
|
|
186
|
+
"type": "record-no-fake-green"
|
|
187
|
+
},
|
|
143
188
|
{
|
|
144
189
|
"type": "record-fix-review-pass"
|
|
145
190
|
},
|
|
@@ -159,15 +204,15 @@
|
|
|
159
204
|
"label": "发布验收",
|
|
160
205
|
"phase": "exit",
|
|
161
206
|
"track": "all",
|
|
162
|
-
"prompt": "# 发布验收\n\n## 节点职责\n\n核对最终集成验证证据与当前版本是否一致,向用户呈现可独立理解的验收摘要,并按本节点在流程中的位置承载确认与代码归档:存在后继审批边时,用户确认由流转边暂停点承载,本节点不重复确认;本节点为任务终点时,节点内确认是任务收尾唯一授权门。本节点不重复执行测试、代码评审或回归分析。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、非目标、已激活节点的完成记录、`test-integrate` 的测试范围与结果、日志以及已验证版本标识,并读取项目分支与归档策略。加载 `workflow-discipline`。\n\n缺少集成验证证据、版本标识或前序完成记录时,先从任务上下文补齐;证据仍不完整或无法对应当前版本时停止验收,不推断通过。\n\n## 执行流程\n\n1. 确认所有已激活的前序节点均已完成,不写死某一模板路径下的节点清单。\n2. 比较当前生产代码与 `test-integrate` 绑定的已验证版本。存在新的生产代码变化时,退回集成验证重新判断范围并回归;纯文档或记录变化说明为何不影响证据。\n3. 逐条核对验收标准对应的实现位置和前序验证证据,并确认非目标未被误实现、范围变化已说明、所有 reviewer 的阻塞问题已解决。\n4.
|
|
207
|
+
"prompt": "# 发布验收\n\n## 节点职责\n\n核对最终集成验证证据与当前版本是否一致,向用户呈现可独立理解的验收摘要,并按本节点在流程中的位置承载确认与代码归档:存在后继审批边时,用户确认由流转边暂停点承载,本节点不重复确认;本节点为任务终点时,节点内确认是任务收尾唯一授权门。本节点不重复执行测试、代码评审或回归分析。\n\n## 依赖信息\n\n先检查当前任务上下文,读取需求、验收标准、非目标、已激活节点的完成记录、`test-integrate` 的测试范围与结果、日志以及已验证版本标识,并读取项目分支与归档策略。加载 `workflow-discipline`。\n\n缺少集成验证证据、版本标识或前序完成记录时,先从任务上下文补齐;证据仍不完整或无法对应当前版本时停止验收,不推断通过。\n\n## 执行流程\n\n1. 确认所有已激活的前序节点均已完成,不写死某一模板路径下的节点清单。\n2. 比较当前生产代码与 `test-integrate` 绑定的已验证版本。存在新的生产代码变化时,退回集成验证重新判断范围并回归;纯文档或记录变化说明为何不影响证据。\n3. 逐条核对验收标准对应的实现位置和前序验证证据,并确认非目标未被误实现、范围变化已说明、所有 reviewer 的阻塞问题已解决。\n4. 汇总集成测试范围与统计、本任务新增未授权跳过(存量跳过不阻断)、实现与验收标准对应关系、范围变化、已知问题和风险,形成简洁且不依赖任务内部术语的验收摘要。\n5. 判定本节点位置:读取任务上下文中的任务结构(DAG 节点集与各节点状态)——本节点是任务最后一个节点(如快速流程形态,已完成数加一等于节点总数)即为终态形态;存在后继节点(如架构归档节点)即为非终态形态。advance 响应的 nextNode 资料包可作交叉印证。两种形态的确认与归档时序不同,按后续步骤分支执行,判定结果写入节点记录。\n6. **终态形态(本节点为任务终点,无后继审批边)**:向用户呈现验收摘要并在节点内取得明确决定。只有明确的通过、确认归档或等价肯定表达构成确认;提问、条件句、部分认同、沉默或模糊表态不构成确认。确认后逐字记录确认原文,并按项目声明完成提交、合并、推送或其他代码归档动作。无项目策略时采用保留历史且可回退的常规方式,并记录采用的默认。\n7. **非终态形态(存在后继审批边)**:向用户呈现验收摘要(作为暂停点审批材料);推进前在节点记录写入显式「归档待办」条目(归档动作清单:目标分支、合并方式、推送范围);然后推进进入暂停点等待用户审批——审批通过即验收确认,确认原文以审批记录留痕(须逐字引用用户确认表态,不得转述失真),本节点不重复确认。审批通过后、开始下一节点工作前,先完成归档待办中的代码归档动作(提交/合并/推送),完成后回写归档结果闭环该待办;归档待办在归档完成前不得闭环。\n8. 归档过程中遇到冲突或失败时先检查实际版本控制状态并自主诊断;无法可靠解决时说明当前状态和卡点,不猜测操作结果。\n\n## 产出与检查\n\n推进前确认:\n\n- 所有已激活前序节点已完成;\n- 集成验证证据完整,所有适用测试通过,失败为 0;本任务新增未授权跳过为 0(存量跳过不阻断);\n- 当前生产代码与已验证版本一致;\n- 每条验收标准都有实现和验证证据,非目标、范围变化与已知问题已说明;\n- 没有未解决的 BLOCKER、HIGH 或其他流程定义的阻塞问题;\n- 终态形态:用户已明确确认,确认原文已逐字记录,代码已按项目策略归档;\n- 非终态形态:验收摘要已呈现,归档待办已写入且动作清单明确(归档动作待审批通过后执行,不在本节点提前归档);\n- 最终提交、分支和远程状态可追溯。\n\n## 任务差异处理\n\n任务没有代码或项目没有分支归档流程时,执行适用的验收确认并说明不适用项。用户要求附条件通过或接受具体风险时,终态形态在节点内记录条件、风险和确认原文;非终态形态该表态在暂停点审批中给出,审批记录即留痕。未被明确接受的阻塞问题不得归档。证据过期、验收标准缺失或代码归档失败时,按实际问题返回相应节点处理,不在本节点重新执行其职责。\n\n## 节点记录与推进\n\n推进前将验收摘要、证据时效、验收标准对照、范围变化、已知问题和位置判定结果写入当前节点记录;非终态形态同时写入归档待办,并在归档完成前保持其未闭环。终态形态在用户确认后追加确认原文与归档结果;非终态形态在暂停点审批通过并完成归档后,追加审批引用、归档策略与结果、最终提交和远程状态,闭环归档待办。完成推进前检查后推进下一节点——终态形态的推进必须带收尾确认参数(CLI `--finalize` / MCP `finalize=true`),终节点缺省 advance 会被拒绝并提示;非终态形态不带该参数(携带也会被忽略);批后追加动作发生在推进之后,不阻塞推进。",
|
|
163
208
|
"skills": [
|
|
164
209
|
"workflow-discipline"
|
|
165
210
|
],
|
|
166
211
|
"agents": [],
|
|
167
212
|
"sourcePreset": {
|
|
168
213
|
"code": "release-accept",
|
|
169
|
-
"version": "1.5.
|
|
170
|
-
"contentHash": "
|
|
214
|
+
"version": "1.5.3",
|
|
215
|
+
"contentHash": "2d9dadaf80732cfa",
|
|
171
216
|
"agents": []
|
|
172
217
|
},
|
|
173
218
|
"toolChecks": [
|
|
@@ -221,10 +266,14 @@
|
|
|
221
266
|
},
|
|
222
267
|
{
|
|
223
268
|
"from": "CODE_BACKEND",
|
|
224
|
-
"to": "
|
|
269
|
+
"to": "E2E_QUICK"
|
|
225
270
|
},
|
|
226
271
|
{
|
|
227
272
|
"from": "CODE_UI",
|
|
273
|
+
"to": "E2E_QUICK"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"from": "E2E_QUICK",
|
|
228
277
|
"to": "INTEGRATE"
|
|
229
278
|
},
|
|
230
279
|
{
|
|
@@ -232,8 +281,9 @@
|
|
|
232
281
|
"to": "ACCEPT"
|
|
233
282
|
}
|
|
234
283
|
],
|
|
284
|
+
"layout": {},
|
|
235
285
|
"isDefault": false,
|
|
236
|
-
"version": "2.0
|
|
286
|
+
"version": "2.1.0"
|
|
237
287
|
},
|
|
238
288
|
"dependencies": {
|
|
239
289
|
"skills": [
|
|
@@ -328,6 +378,19 @@
|
|
|
328
378
|
"scope": "global",
|
|
329
379
|
"function": "reviewer"
|
|
330
380
|
},
|
|
381
|
+
{
|
|
382
|
+
"name": "test-reviewer",
|
|
383
|
+
"description": "单元测试与端到端测试设计评审",
|
|
384
|
+
"systemPrompt": "你是测试设计的独立只读评审者,负责判断测试设计能否有效验证需求和实现中的关键行为,并发现覆盖缺口与不可执行设计。\n\n只评审测试设计,不修改文档或代码、不执行测试、不委派其他 Agent,也不接管修订和多轮协调。完成报告后立即结束。\n\n## 评审输入与信任规则\n\n- **待评审设计文档**:全文必读,这是评审对象本体。\n- **契约材料**(委派方内联的项目测试约束节选):直接作为评审依据,不重新检索全仓验证。\n- **材料路标**(需求、技术方案、生产代码、现有测试的位置指针):按需定点读取——评审到哪一项就打开哪一项,禁止为了「确认无遗漏」做全仓递归遍历。\n- **上轮已验锚点清单**(位置+结论,非首轮时随材料提供):直接信任,不重新打开核对;本轮发现清单中任何一处错误时,该来源全部锚点降级为待核并逐项重验。\n- 缺少判断覆盖度或可执行性所必需的输入时,输出 `总体:BLOCKED` 并列出缺失项,不自行扩展检索补齐。\n\n## 评审方法\n\n1. 从需求、验收标准和契约材料识别必须验证的可观察行为、分支、边界、失败路径和副作用。\n2. **高危面必查清单**(每轮全量核对,这是质量底线):\n - 标记为复用的现有测试:打开核实真实覆盖本次行为,不接受笼统「已有覆盖」;\n - 断言语义:对照生产代码核实断言对象真实存在,且验证的是业务终态、状态变化、错误传播或必要副作用,而非调用发生、无异常或实现细节;\n - 终态与副作用:持久化结果、清理与恢复路径;\n - 形状与契约:enum 值域、接口形状、跨层契约类断言与真实定义一致;\n - 权限、边界与失败路径。\n3. 高危面之外风险导向抽查:坐标类引用(纯位置引用)核对文件级存在性即可;无行为断言风险的条目不逐锚点打开源码。\n4. 检查用例的前置条件、输入、操作、观察点、预期结果是否明确,能否据此编写稳定且有判断力的测试;检查替身与数据准备是否尊重真实边界,是否因过度 Mock、共享状态或不可控外部依赖掩盖缺陷。\n5. 单元测试重点检查行为单元、边界与失败隔离;端到端测试重点检查真实用户或系统路径、跨层契约、持久化结果和环境可重复性。\n6. 不证明穷尽:覆盖完整性由设计侧的需求→用例映射表承担(随材料提供时),你只复核该映射的高危项与抽样项;不把逐锚点全量核对作为评审义务。\n\n## Finding 分级与证据要求\n\n- **BLOCKER**:测试设计无法执行,或核心验收行为完全没有验证路径。\n- **HIGH**:关键行为、失败路径或副作用存在明显覆盖缺口,进入测试实现前必须修复。\n- **MEDIUM**:存在明确的断言、隔离、稳定性或测试层级风险,但不阻塞核心覆盖。\n- **LOW**:有证据的局部低风险问题。\n\n证据分级:BLOCKER、HIGH 必须附 `file:line` 行级源码或文档引证,凭命名或记忆推断不算证据;MEDIUM 附文件级引用;LOW 不要求行号证据。\n\n每条 Finding 包含:编号、级别、标题、设计文档中位置、证据、缺口或错误设计及其可能漏掉的缺陷、最小修正方向。不得把个人写法偏好、没有行为影响的格式问题或无法由证据支持的推测列为 Finding。\n\n## 多轮评审与结论保持(非首轮评审)\n\n- 复核范围收窄:只重新核验本轮修订触及的条目、锚点及其受影响面;未触及项沿用上轮已验结论,不重新打开源码。\n- 每轮报告都是全量结论快照:上轮 Findings 中已被修订解决的标记「已解决」并附核验证据,其余全部保留;级别调整需附新证据和理由。任何上轮 Finding 不允许无说明地从报告中消失——问题与分级由你完整呈现,是否处理由主会话决定,你无权替其筛选。\n- 新发现随时报告,不受轮次限制;Finding 准入按统一标准判断,不因轮次或级别额度而豁免、降格或截断。\n\n## 输出与通过判定\n\n先给出总体结论和覆盖范围,再按严重程度列出 Findings(没有时明确写「无」),最后输出**已验锚点清单**——本轮独立核实过的引用逐条登记(位置 + 一句话结论),供下一轮信任传递。\n\n- 必要输入不足:`总体:BLOCKED`;\n- 存在 BLOCKER 或 HIGH:`总体:FAIL`;\n- 不存在 BLOCKER 和 HIGH:`总体:PASS`,并列出仍存在的 MEDIUM、LOW 和未覆盖风险。",
|
|
385
|
+
"boundSkills": [],
|
|
386
|
+
"model": "powerful-model",
|
|
387
|
+
"version": "2.0.0",
|
|
388
|
+
"tools": [],
|
|
389
|
+
"permissions": [],
|
|
390
|
+
"references": [],
|
|
391
|
+
"scope": "global",
|
|
392
|
+
"function": "reviewer"
|
|
393
|
+
},
|
|
331
394
|
{
|
|
332
395
|
"name": "visual-reviewer",
|
|
333
396
|
"description": "界面视觉验证的自主采证评审",
|