





















@@ -93,6 +93,41 @@ const qaScenarioGatewayRuntimeSchema = z.object({
9393forwardHostHome: z.boolean().optional(),
9494});
959596+function isOpenClawGitHubIssueOrPullUrl(value: string): boolean {
97+try {
98+const parsed = new URL(value);
99+return (
100+parsed.hostname === "github.com" &&
101+/^\/openclaw\/openclaw\/(?:issues|pull)\/[1-9]\d*$/.test(parsed.pathname)
102+);
103+} catch {
104+return false;
105+}
106+}
107+108+const qaScenarioEvidenceGithubUrlSchema = z
109+.string()
110+.trim()
111+.url()
112+.refine(isOpenClawGitHubIssueOrPullUrl, {
113+message: "evidence.github entries must be openclaw/openclaw issue or PR URLs",
114+});
115+116+const qaScenarioEvidenceSchema = z
117+.object({
118+github: z.array(qaScenarioEvidenceGithubUrlSchema).min(1).optional(),
119+})
120+.superRefine((evidence, ctx) => {
121+if (evidence.github?.length) {
122+return;
123+}
124+ctx.addIssue({
125+code: z.ZodIssueCode.custom,
126+path: ["github"],
127+message: "evidence.github must include at least one URL",
128+});
129+});
130+96131export const QA_RUNTIME_PARITY_TIERS = ["standard", "optional", "live-only", "soak"] as const;
97132const qaRuntimeParityTierSchema = z.enum(QA_RUNTIME_PARITY_TIERS);
98133@@ -181,6 +216,7 @@ const qaSeedScenarioSchema = z.object({
181216category: z.string().trim().min(1).optional(),
182217runtimeParityTier: qaRuntimeParityTierSchema.optional(),
183218coverage: qaScenarioCoverageSchema.optional(),
219+evidence: qaScenarioEvidenceSchema.optional(),
184220surfaces: z.array(z.string().trim().min(1)).min(1).optional(),
185221risk: z.enum(["low", "medium", "high"]).optional(),
186222capabilities: z.array(z.string().trim().min(1)).optional(),
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。