mirror of
https://github.com/aiclientproxy/proxycast.git
synced 2026-10-24 01:58:23 +08:00
1599 lines
51 KiB
TypeScript
1599 lines
51 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
|
||
import {
|
||
assertGeneratedSlopReportContract,
|
||
buildGeneratedSlopReport,
|
||
renderGeneratedSlopMarkdown,
|
||
} from "./generated-slop-report-core.mjs";
|
||
|
||
describe("generated-slop-report-core", () => {
|
||
it("应把 trend seed 与活跃 legacy surface 转成治理建议", () => {
|
||
const report = buildGeneratedSlopReport({
|
||
repoRoot: "/tmp/lime",
|
||
trendReport: {
|
||
sampleCount: 1,
|
||
delta: {
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 1,
|
||
currentObservabilityGapCaseCount: 1,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
readyRate: 0,
|
||
},
|
||
signals: ["样本数不足 2,当前仅形成 trend seed,还不能判断长期退化。"],
|
||
baseline: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
latest: {
|
||
totals: {
|
||
needsHumanReviewCount: 1,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 1,
|
||
currentObservabilityGapCaseCount: 1,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
classificationDeltas: {
|
||
failureModes: [
|
||
{
|
||
name: "pending_request",
|
||
baseline: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 1,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 1,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
suiteTags: [
|
||
{
|
||
name: "conversation-runtime",
|
||
baseline: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 1,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 1,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
reviewDecisionStatuses: [
|
||
{
|
||
name: "pending_review",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 0,
|
||
invalidCount: 1,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 1,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 0,
|
||
invalidCount: 1,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 1,
|
||
},
|
||
},
|
||
],
|
||
reviewRiskLevels: [
|
||
{
|
||
name: "high",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 0,
|
||
invalidCount: 1,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 1,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 0,
|
||
invalidCount: 1,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 1,
|
||
},
|
||
},
|
||
],
|
||
observabilitySignals: [
|
||
{
|
||
name: "artifactValidator:known_gap",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
observabilityVerificationOutcomes: [
|
||
{
|
||
name: "browserVerification:failure",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
{
|
||
name: "artifactValidator:repaired",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
currentObservabilityVerificationOutcomes: [
|
||
{
|
||
name: "browserVerification:failure",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
{
|
||
name: "artifactValidator:repaired",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
degradedObservabilityVerificationOutcomes: [],
|
||
},
|
||
},
|
||
governanceReport: {
|
||
summary: {
|
||
zeroReferenceCandidates: [],
|
||
classificationDriftCandidates: [],
|
||
violations: [],
|
||
},
|
||
importResults: [
|
||
{
|
||
id: "settings-api-server-page-entry",
|
||
classification: "dead-candidate",
|
||
description: "deleted settings page entry",
|
||
existingTargets: ["src/components/api-server/ApiServerPage.tsx"],
|
||
references: [],
|
||
testReferences: [],
|
||
violations: [],
|
||
},
|
||
],
|
||
commandResults: [],
|
||
frontendTextResults: [
|
||
{
|
||
id: "migration-setting-key-leak",
|
||
classification: "deprecated",
|
||
description: "migration keys",
|
||
references: ["src-tauri/crates/core/src/database/migration/foo.rs"],
|
||
testReferences: [],
|
||
violations: [],
|
||
},
|
||
],
|
||
rustTextResults: [],
|
||
rustTextCountResults: [],
|
||
},
|
||
docFreshnessReport: {
|
||
summary: {
|
||
monitoredDocumentCount: 10,
|
||
existingDocumentCount: 10,
|
||
issueCount: 0,
|
||
missingDocumentCount: 0,
|
||
missingRequiredReferenceCount: 0,
|
||
brokenMarkdownLinkCount: 0,
|
||
brokenCodePathReferenceCount: 0,
|
||
deletedSurfaceReferenceCount: 0,
|
||
},
|
||
issues: [],
|
||
},
|
||
sources: {
|
||
trend: { kind: "generated-current" },
|
||
docFreshness: { kind: "live-scan" },
|
||
governance: { kind: "live-scan" },
|
||
},
|
||
});
|
||
|
||
expect(report.summary.trend.isSeed).toBe(true);
|
||
expect(report.summary.trend.reviewDecisionBacklogCount).toBe(1);
|
||
expect(report.summary.trend.latestObservabilityGapCaseCount).toBe(1);
|
||
expect(report.summary.verificationOutcomes).toMatchObject({
|
||
failureFocusCount: 1,
|
||
recoveredFocusCount: 1,
|
||
failureCaseCount: 1,
|
||
blockingFailureFocusCount: 1,
|
||
advisoryFailureFocusCount: 0,
|
||
blockingFailureCaseCount: 1,
|
||
advisoryFailureCaseCount: 0,
|
||
recoveredCaseCount: 1,
|
||
topFailureOutcomes: ["browserVerification:failure"],
|
||
topBlockingFailureOutcomes: ["browserVerification:failure"],
|
||
topAdvisoryFailureOutcomes: [],
|
||
topRecoveredOutcomes: ["artifactValidator:repaired"],
|
||
current: expect.objectContaining({
|
||
blockingFailureCaseCount: 1,
|
||
advisoryFailureCaseCount: 0,
|
||
recoveredCaseCount: 1,
|
||
}),
|
||
degraded: expect.objectContaining({
|
||
blockingFailureCaseCount: 0,
|
||
advisoryFailureCaseCount: 0,
|
||
}),
|
||
});
|
||
expect(report.summary.docFreshness.issueCount).toBe(0);
|
||
expect(report.focus.failureModes[0].name).toBe("pending_request");
|
||
expect(report.focus.reviewDecisionStatuses[0].name).toBe("pending_review");
|
||
expect(report.focus.reviewRiskLevels[0].name).toBe("high");
|
||
expect(report.focus.observabilitySignals).toEqual(
|
||
expect.arrayContaining([
|
||
expect.objectContaining({
|
||
signal: "artifactValidator",
|
||
status: "known_gap",
|
||
}),
|
||
]),
|
||
);
|
||
expect(report.focus.observabilityVerificationOutcomes).toEqual(
|
||
expect.arrayContaining([
|
||
expect.objectContaining({
|
||
signal: "browserVerification",
|
||
outcome: "failure",
|
||
}),
|
||
]),
|
||
);
|
||
expect(report.focus.currentObservabilityVerificationOutcomes).toEqual(
|
||
expect.arrayContaining([
|
||
expect.objectContaining({
|
||
signal: "browserVerification",
|
||
outcome: "failure",
|
||
}),
|
||
]),
|
||
);
|
||
expect(report.focus.degradedObservabilityVerificationOutcomes).toEqual([]);
|
||
expect(report.focus.governanceSurfaces[0].id).toBe(
|
||
"migration-setting-key-leak",
|
||
);
|
||
expect(report.recommendations.map((entry) => entry.id)).toEqual(
|
||
expect.arrayContaining([
|
||
"promote-high-value-replay",
|
||
"replay-and-smoke-follow-up",
|
||
"review-decision-follow-up",
|
||
"observability-evidence-follow-up",
|
||
"recovered-baseline-follow-up",
|
||
"governance-cleanup-priority",
|
||
"doc-freshness-review",
|
||
]),
|
||
);
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "review-decision-follow-up",
|
||
)?.focusReviewRiskLevels,
|
||
).toContain("high");
|
||
expect(
|
||
report.recommendations.find((entry) => entry.id === "doc-freshness-review")
|
||
?.commands,
|
||
).toContain("npm run harness:doc-freshness");
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "observability-evidence-follow-up",
|
||
)?.focusVerificationFailureOutcomes,
|
||
).toContain("browserVerification (failure)");
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "observability-evidence-follow-up",
|
||
),
|
||
).not.toHaveProperty("focusObservabilityVerificationOutcomes");
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "replay-and-smoke-follow-up",
|
||
)?.priority,
|
||
).toBe("P0");
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "replay-and-smoke-follow-up",
|
||
)?.commands,
|
||
).not.toContain("npm run verify:gui-smoke");
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "replay-and-smoke-follow-up",
|
||
)?.backlogTools,
|
||
).toContain(
|
||
"回看 browser replay / browser verification 失败样本,并把失败断言回挂到受影响主路径。",
|
||
);
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "replay-and-smoke-follow-up",
|
||
)?.rationale,
|
||
).toContain(
|
||
"current 样本已出现 browserVerification:failure,应先回看 browser replay / verification 失败样本,把失败断言回挂到受影响主路径。",
|
||
);
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "observability-evidence-follow-up",
|
||
)?.priority,
|
||
).toBe("P1");
|
||
expect(report.summary.trend.latestCurrentObservabilityGapCaseCount).toBe(1);
|
||
expect(report.summary.trend.latestDegradedObservabilityGapCaseCount).toBe(0);
|
||
expect(report.signals).toContain(
|
||
"当前 verification failure outcome 焦点:browserVerification (failure)。",
|
||
);
|
||
expect(report.signals).toContain(
|
||
"当前 verification failure 聚焦 1 类 outcome,共 1 个 case。",
|
||
);
|
||
expect(report.signals).toContain(
|
||
"当前 current 样本里有 1 个 blocking verification failure。",
|
||
);
|
||
expect(report.signals).toContain(
|
||
"当前没有额外的 advisory verification failure。",
|
||
);
|
||
expect(report.signals).toContain(
|
||
"当前 current recovered verification baseline:artifactValidator (repaired)。",
|
||
);
|
||
expect(report.signals).toContain(
|
||
"当前 verification recovered 聚焦 1 类 outcome,共 1 个 case。",
|
||
);
|
||
});
|
||
|
||
it("应把 current guiSmoke failed 回挂成显式 GUI smoke 动作", () => {
|
||
const report = buildGeneratedSlopReport({
|
||
repoRoot: "/tmp/lime",
|
||
trendReport: {
|
||
sampleCount: 2,
|
||
delta: {
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
readyRate: 0,
|
||
},
|
||
signals: ["当前没有检测到明显退化信号。"],
|
||
baseline: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
latest: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
classificationDeltas: {
|
||
failureModes: [],
|
||
suiteTags: [],
|
||
reviewDecisionStatuses: [],
|
||
reviewRiskLevels: [],
|
||
observabilitySignals: [],
|
||
observabilityVerificationOutcomes: [
|
||
{
|
||
name: "guiSmoke:failed",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
currentObservabilityVerificationOutcomes: [
|
||
{
|
||
name: "guiSmoke:failed",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
degradedObservabilityVerificationOutcomes: [],
|
||
},
|
||
},
|
||
governanceReport: {
|
||
summary: {
|
||
zeroReferenceCandidates: [],
|
||
classificationDriftCandidates: [],
|
||
violations: [],
|
||
},
|
||
importResults: [],
|
||
commandResults: [],
|
||
frontendTextResults: [],
|
||
rustTextResults: [],
|
||
rustTextCountResults: [],
|
||
},
|
||
docFreshnessReport: {
|
||
summary: {
|
||
monitoredDocumentCount: 10,
|
||
existingDocumentCount: 10,
|
||
issueCount: 0,
|
||
missingDocumentCount: 0,
|
||
missingRequiredReferenceCount: 0,
|
||
brokenMarkdownLinkCount: 0,
|
||
brokenCodePathReferenceCount: 0,
|
||
deletedSurfaceReferenceCount: 0,
|
||
},
|
||
issues: [],
|
||
},
|
||
sources: {
|
||
trend: { kind: "input-json" },
|
||
docFreshness: { kind: "input-json" },
|
||
governance: { kind: "input-json" },
|
||
},
|
||
});
|
||
|
||
const recommendation = report.recommendations.find(
|
||
(entry) => entry.id === "replay-and-smoke-follow-up",
|
||
);
|
||
|
||
expect(recommendation?.priority).toBe("P0");
|
||
expect(recommendation?.commands).toEqual(
|
||
expect.arrayContaining([
|
||
"npm run harness:eval",
|
||
"npm run harness:eval:trend",
|
||
"npm run verify:gui-smoke",
|
||
]),
|
||
);
|
||
expect(recommendation?.backlogTools).toContain(
|
||
"优先收敛 GUI 壳 / DevBridge / Workspace 主路径,再复跑 `npm run verify:gui-smoke`。",
|
||
);
|
||
expect(recommendation?.rationale).toContain(
|
||
"current 样本已出现 guiSmoke:failed,先恢复 GUI 壳 / DevBridge / Workspace 主路径的最小可启动性。",
|
||
);
|
||
});
|
||
|
||
it("应把 current advisory verification outcome 回挂成具体补证据动作", () => {
|
||
const report = buildGeneratedSlopReport({
|
||
repoRoot: "/tmp/lime",
|
||
trendReport: {
|
||
sampleCount: 2,
|
||
delta: {
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
readyRate: 0,
|
||
},
|
||
signals: ["当前没有检测到明显退化信号。"],
|
||
baseline: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
latest: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
classificationDeltas: {
|
||
failureModes: [],
|
||
suiteTags: [],
|
||
reviewDecisionStatuses: [],
|
||
reviewRiskLevels: [],
|
||
observabilitySignals: [],
|
||
observabilityVerificationOutcomes: [
|
||
{
|
||
name: "artifactValidator:issues_present",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
{
|
||
name: "browserVerification:unknown",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
currentObservabilityVerificationOutcomes: [
|
||
{
|
||
name: "artifactValidator:issues_present",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
{
|
||
name: "browserVerification:unknown",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
degradedObservabilityVerificationOutcomes: [],
|
||
},
|
||
},
|
||
governanceReport: {
|
||
summary: {
|
||
zeroReferenceCandidates: [],
|
||
classificationDriftCandidates: [],
|
||
violations: [],
|
||
},
|
||
importResults: [],
|
||
commandResults: [],
|
||
frontendTextResults: [],
|
||
rustTextResults: [],
|
||
rustTextCountResults: [],
|
||
},
|
||
docFreshnessReport: {
|
||
summary: {
|
||
monitoredDocumentCount: 10,
|
||
existingDocumentCount: 10,
|
||
issueCount: 0,
|
||
missingDocumentCount: 0,
|
||
missingRequiredReferenceCount: 0,
|
||
brokenMarkdownLinkCount: 0,
|
||
brokenCodePathReferenceCount: 0,
|
||
deletedSurfaceReferenceCount: 0,
|
||
},
|
||
issues: [],
|
||
},
|
||
sources: {
|
||
trend: { kind: "input-json" },
|
||
docFreshness: { kind: "input-json" },
|
||
governance: { kind: "input-json" },
|
||
},
|
||
});
|
||
|
||
const recommendation = report.recommendations.find(
|
||
(entry) => entry.id === "observability-evidence-follow-up",
|
||
);
|
||
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "replay-and-smoke-follow-up",
|
||
),
|
||
).toBeUndefined();
|
||
expect(recommendation?.priority).toBe("P1");
|
||
expect(recommendation?.commands).toEqual(
|
||
expect.arrayContaining([
|
||
"npm run harness:eval",
|
||
"npm run harness:eval:trend",
|
||
"npm run harness:cleanup-report",
|
||
]),
|
||
);
|
||
expect(recommendation?.commands).not.toContain("npm run verify:gui-smoke");
|
||
expect(recommendation?.backlogTools).toContain(
|
||
"回看 artifact validator issue 明细,并收敛 evidence pack / artifacts.json / analysis handoff 的 artifact 字段。",
|
||
);
|
||
expect(recommendation?.backlogTools).toContain(
|
||
"回看 browser verification 导出链,确保 evidence pack / replay / analysis handoff 写出明确 success 或 failure,而不是 unknown。",
|
||
);
|
||
expect(recommendation?.rationale).toContain(
|
||
"current 样本已出现 artifactValidator:issues_present,应先回看 validator issue 明细,再收敛 artifact 导出字段。",
|
||
);
|
||
expect(recommendation?.rationale).toContain(
|
||
"current 样本已出现 browserVerification:unknown,需要先把浏览器验证结果收敛成明确 outcome,再继续扩大分析。",
|
||
);
|
||
});
|
||
|
||
it("应把 current recovered verification outcome 固化成正向基线建议", () => {
|
||
const report = buildGeneratedSlopReport({
|
||
repoRoot: "/tmp/lime",
|
||
trendReport: {
|
||
sampleCount: 2,
|
||
delta: {
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
readyRate: 0,
|
||
},
|
||
signals: ["当前没有检测到明显退化信号。"],
|
||
baseline: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
latest: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
classificationDeltas: {
|
||
failureModes: [],
|
||
suiteTags: [],
|
||
reviewDecisionStatuses: [],
|
||
reviewRiskLevels: [],
|
||
observabilitySignals: [],
|
||
observabilityVerificationOutcomes: [
|
||
{
|
||
name: "artifactValidator:repaired",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
{
|
||
name: "browserVerification:success",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
{
|
||
name: "guiSmoke:passed",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
currentObservabilityVerificationOutcomes: [
|
||
{
|
||
name: "artifactValidator:repaired",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
{
|
||
name: "browserVerification:success",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
{
|
||
name: "guiSmoke:passed",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
currentRecoveredObservabilityVerificationOutcomes: [
|
||
{
|
||
name: "artifactValidator:repaired",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
{
|
||
name: "browserVerification:success",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
{
|
||
name: "guiSmoke:passed",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
degradedObservabilityVerificationOutcomes: [],
|
||
},
|
||
},
|
||
governanceReport: {
|
||
summary: {
|
||
zeroReferenceCandidates: [],
|
||
classificationDriftCandidates: [],
|
||
violations: [],
|
||
},
|
||
importResults: [],
|
||
commandResults: [],
|
||
frontendTextResults: [],
|
||
rustTextResults: [],
|
||
rustTextCountResults: [],
|
||
},
|
||
docFreshnessReport: {
|
||
summary: {
|
||
monitoredDocumentCount: 10,
|
||
existingDocumentCount: 10,
|
||
issueCount: 0,
|
||
missingDocumentCount: 0,
|
||
missingRequiredReferenceCount: 0,
|
||
brokenMarkdownLinkCount: 0,
|
||
brokenCodePathReferenceCount: 0,
|
||
deletedSurfaceReferenceCount: 0,
|
||
},
|
||
issues: [],
|
||
},
|
||
sources: {
|
||
trend: { kind: "input-json" },
|
||
docFreshness: { kind: "input-json" },
|
||
governance: { kind: "input-json" },
|
||
},
|
||
});
|
||
|
||
const recommendation = report.recommendations.find(
|
||
(entry) => entry.id === "recovered-baseline-follow-up",
|
||
);
|
||
|
||
expect(report.summary.verificationOutcomes.recoveredCaseCount).toBe(3);
|
||
expect(report.summary.verificationOutcomes.recoveredFocusCount).toBe(3);
|
||
expect(report.summary.verificationOutcomes.topRecoveredOutcomes).toEqual(
|
||
expect.arrayContaining([
|
||
"artifactValidator:repaired",
|
||
"browserVerification:success",
|
||
"guiSmoke:passed",
|
||
]),
|
||
);
|
||
expect(report.summary.verificationOutcomes.current.recoveredCaseCount).toBe(3);
|
||
expect(
|
||
report.focus.currentRecoveredObservabilityVerificationOutcomes,
|
||
).toEqual(
|
||
expect.arrayContaining([
|
||
expect.objectContaining({
|
||
signal: "artifactValidator",
|
||
outcome: "repaired",
|
||
}),
|
||
expect.objectContaining({
|
||
signal: "browserVerification",
|
||
outcome: "success",
|
||
}),
|
||
expect.objectContaining({
|
||
signal: "guiSmoke",
|
||
outcome: "passed",
|
||
}),
|
||
]),
|
||
);
|
||
expect(recommendation?.priority).toBe("P2");
|
||
expect(recommendation?.focusVerificationRecoveredOutcomes).toEqual(
|
||
expect.arrayContaining([
|
||
"artifactValidator (repaired)",
|
||
"browserVerification (success)",
|
||
"guiSmoke (passed)",
|
||
]),
|
||
);
|
||
expect(recommendation).not.toHaveProperty(
|
||
"focusObservabilityVerificationOutcomes",
|
||
);
|
||
expect(recommendation?.commands).toEqual(
|
||
expect.arrayContaining([
|
||
"npm run harness:eval",
|
||
"npm run harness:eval:trend",
|
||
"npm run verify:gui-smoke",
|
||
]),
|
||
);
|
||
expect(recommendation?.backlogTools).toContain(
|
||
"把 browser verification 成功样本固定进 current replay 基线,后续 failure 或 unknown 直接对比这条正向路径。",
|
||
);
|
||
expect(recommendation?.backlogTools).toContain(
|
||
"主路径变更时优先复跑 `npm run verify:gui-smoke`,确认 GUI 壳 / DevBridge / Workspace 不从 passed 回退。",
|
||
);
|
||
expect(recommendation?.rationale).toContain(
|
||
"current 样本已出现 browserVerification:success,可把浏览器验证成功样本固化成主路径正向基线。",
|
||
);
|
||
expect(recommendation?.rationale).toContain(
|
||
"current 样本已出现 guiSmoke:passed,可继续把 GUI smoke 通过链路当成桌面主路径的正向守卫。",
|
||
);
|
||
expect(report.signals).toContain(
|
||
"当前 current recovered verification baseline:artifactValidator (repaired)、browserVerification (success)、guiSmoke (passed)。",
|
||
);
|
||
expect(report.signals).toContain(
|
||
"当前 verification recovered 聚焦 3 类 outcome,共 3 个 case。",
|
||
);
|
||
});
|
||
|
||
it("仅 degraded observability gap 不应触发主线补证据建议", () => {
|
||
const report = buildGeneratedSlopReport({
|
||
repoRoot: "/tmp/lime",
|
||
trendReport: {
|
||
sampleCount: 2,
|
||
delta: {
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
readyRate: 0,
|
||
},
|
||
signals: ["当前没有检测到明显退化信号。"],
|
||
baseline: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 1,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 1,
|
||
},
|
||
},
|
||
latest: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 1,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 1,
|
||
},
|
||
},
|
||
classificationDeltas: {
|
||
failureModes: [],
|
||
suiteTags: [],
|
||
reviewDecisionStatuses: [],
|
||
reviewRiskLevels: [],
|
||
observabilitySignals: [
|
||
{
|
||
name: "requestTelemetry:known_gap",
|
||
baseline: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
observabilityVerificationOutcomes: [],
|
||
currentObservabilityVerificationOutcomes: [],
|
||
degradedObservabilityVerificationOutcomes: [
|
||
{
|
||
name: "guiSmoke:failed",
|
||
baseline: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
},
|
||
},
|
||
governanceReport: {
|
||
summary: {
|
||
zeroReferenceCandidates: [],
|
||
classificationDriftCandidates: [],
|
||
violations: [],
|
||
},
|
||
importResults: [],
|
||
commandResults: [],
|
||
frontendTextResults: [],
|
||
rustTextResults: [],
|
||
rustTextCountResults: [],
|
||
},
|
||
docFreshnessReport: {
|
||
summary: {
|
||
monitoredDocumentCount: 10,
|
||
existingDocumentCount: 10,
|
||
issueCount: 0,
|
||
missingDocumentCount: 0,
|
||
missingRequiredReferenceCount: 0,
|
||
brokenMarkdownLinkCount: 0,
|
||
brokenCodePathReferenceCount: 0,
|
||
deletedSurfaceReferenceCount: 0,
|
||
},
|
||
issues: [],
|
||
},
|
||
sources: {
|
||
trend: { kind: "input-json" },
|
||
docFreshness: { kind: "input-json" },
|
||
governance: { kind: "input-json" },
|
||
},
|
||
});
|
||
|
||
expect(report.summary.trend.latestObservabilityGapCaseCount).toBe(1);
|
||
expect(report.summary.trend.latestCurrentObservabilityGapCaseCount).toBe(0);
|
||
expect(report.summary.trend.latestDegradedObservabilityGapCaseCount).toBe(1);
|
||
expect(report.summary.verificationOutcomes.failureCaseCount).toBe(1);
|
||
expect(report.summary.verificationOutcomes.blockingFailureCaseCount).toBe(1);
|
||
expect(report.summary.verificationOutcomes.advisoryFailureCaseCount).toBe(0);
|
||
expect(report.summary.verificationOutcomes.recoveredCaseCount).toBe(0);
|
||
expect(report.summary.verificationOutcomes.degraded.blockingFailureCaseCount).toBe(1);
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "observability-evidence-follow-up",
|
||
),
|
||
).toBeUndefined();
|
||
expect(
|
||
report.recommendations.find(
|
||
(entry) => entry.id === "replay-and-smoke-follow-up",
|
||
),
|
||
).toBeUndefined();
|
||
expect(report.signals).toContain(
|
||
"当前 current 样本没有额外的 observability 证据缺口。",
|
||
);
|
||
expect(report.signals).toContain(
|
||
"当前保留 1 个 degraded blocking verification failure 样本作为诊断基线。",
|
||
);
|
||
expect(report.signals).toContain(
|
||
"当前保留 1 个 degraded observability gap 样本作为诊断基线。",
|
||
);
|
||
const markdown = renderGeneratedSlopMarkdown(report);
|
||
expect(markdown).toContain("## Observability Gap 角色");
|
||
expect(markdown).toContain("| current | 0 | 0 |");
|
||
expect(markdown).toContain("| degraded | 1 | 0 |");
|
||
});
|
||
|
||
it("应把 governance 违规提升为 P0 守卫动作", () => {
|
||
const report = buildGeneratedSlopReport({
|
||
repoRoot: "/tmp/lime",
|
||
trendReport: {
|
||
sampleCount: 2,
|
||
delta: {
|
||
invalidCount: 1,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
readyRate: -0.5,
|
||
},
|
||
signals: ["invalid case 增加 1,存在回归候选。"],
|
||
baseline: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
latest: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
classificationDeltas: {
|
||
failureModes: [],
|
||
suiteTags: [],
|
||
reviewDecisionStatuses: [],
|
||
reviewRiskLevels: [],
|
||
observabilitySignals: [],
|
||
observabilityVerificationOutcomes: [],
|
||
},
|
||
},
|
||
governanceReport: {
|
||
summary: {
|
||
zeroReferenceCandidates: [],
|
||
classificationDriftCandidates: [],
|
||
violations: ["chat-compat -> src/foo.ts"],
|
||
},
|
||
importResults: [],
|
||
commandResults: [
|
||
{
|
||
id: "chat-compat-command",
|
||
classification: "deprecated",
|
||
description: "legacy command",
|
||
referencesByCommand: {
|
||
chat_create_session: ["src/lib/api/legacy.ts"],
|
||
},
|
||
testReferencesByCommand: {},
|
||
violations: ["chat_create_session -> src/lib/api/legacy.ts"],
|
||
},
|
||
],
|
||
frontendTextResults: [],
|
||
rustTextResults: [],
|
||
rustTextCountResults: [],
|
||
},
|
||
docFreshnessReport: {
|
||
summary: {
|
||
monitoredDocumentCount: 10,
|
||
existingDocumentCount: 9,
|
||
issueCount: 2,
|
||
missingDocumentCount: 0,
|
||
missingRequiredReferenceCount: 1,
|
||
brokenMarkdownLinkCount: 0,
|
||
brokenCodePathReferenceCount: 1,
|
||
deletedSurfaceReferenceCount: 0,
|
||
},
|
||
issues: [
|
||
{
|
||
kind: "missing-required-reference",
|
||
documentPath: "docs/tech/harness/entropy-governance-workflow.md",
|
||
detail: "harness-evals.md",
|
||
},
|
||
{
|
||
kind: "broken-code-path-reference",
|
||
documentPath: "docs/tech/harness/tooling-roadmap.md",
|
||
detail: "scripts/missing-tool.mjs",
|
||
},
|
||
],
|
||
},
|
||
sources: {
|
||
trend: { kind: "input-json" },
|
||
docFreshness: { kind: "input-json" },
|
||
governance: { kind: "input-json" },
|
||
},
|
||
});
|
||
|
||
expect(report.recommendations[0].id).toBe("contracts-and-boundary-guards");
|
||
expect(report.recommendations[0].priority).toBe("P0");
|
||
expect(report.signals).toContain("doc freshness 发现 2 个问题。");
|
||
expect(report.focus.docFreshness.issueKinds[0]).toEqual({
|
||
kind: "broken-code-path-reference",
|
||
count: 1,
|
||
});
|
||
expect(report.recommendations[0].commands).toEqual(
|
||
expect.arrayContaining([
|
||
"npm run governance:legacy-report",
|
||
"npm run test:contracts",
|
||
]),
|
||
);
|
||
expect(
|
||
report.recommendations.find((entry) => entry.id === "doc-freshness-review")
|
||
?.priority,
|
||
).toBe("P1");
|
||
});
|
||
|
||
it("应把旧 requestTelemetry:unlinked 样本折叠成 known_gap", () => {
|
||
const report = buildGeneratedSlopReport({
|
||
repoRoot: "/tmp/lime",
|
||
trendReport: {
|
||
sampleCount: 2,
|
||
delta: {
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 1,
|
||
currentObservabilityGapCaseCount: 1,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
readyRate: 0,
|
||
},
|
||
signals: ["request telemetry 仍有旧样本待清理。"],
|
||
baseline: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 0,
|
||
currentObservabilityGapCaseCount: 0,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
latest: {
|
||
totals: {
|
||
needsHumanReviewCount: 0,
|
||
reviewDecisionRecordedCount: 0,
|
||
observabilityGapCaseCount: 1,
|
||
currentObservabilityGapCaseCount: 1,
|
||
degradedObservabilityGapCaseCount: 0,
|
||
},
|
||
},
|
||
classificationDeltas: {
|
||
failureModes: [],
|
||
suiteTags: [],
|
||
reviewDecisionStatuses: [],
|
||
reviewRiskLevels: [],
|
||
observabilitySignals: [
|
||
{
|
||
name: "requestTelemetry:unlinked",
|
||
baseline: {
|
||
caseCount: 0,
|
||
readyCount: 0,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
latest: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
delta: {
|
||
caseCount: 1,
|
||
readyCount: 1,
|
||
invalidCount: 0,
|
||
pendingRequestCaseCount: 0,
|
||
needsHumanReviewCount: 0,
|
||
},
|
||
},
|
||
],
|
||
observabilityVerificationOutcomes: [],
|
||
currentObservabilityVerificationOutcomes: [],
|
||
degradedObservabilityVerificationOutcomes: [],
|
||
currentRecoveredObservabilityVerificationOutcomes: [],
|
||
},
|
||
},
|
||
docFreshnessReport: {
|
||
summary: {
|
||
monitoredDocumentCount: 0,
|
||
existingDocumentCount: 0,
|
||
issueCount: 0,
|
||
missingDocumentCount: 0,
|
||
missingRequiredReferenceCount: 0,
|
||
brokenMarkdownLinkCount: 0,
|
||
brokenCodePathReferenceCount: 0,
|
||
deletedSurfaceReferenceCount: 0,
|
||
},
|
||
issues: [],
|
||
},
|
||
governanceReport: {
|
||
summary: {
|
||
compatibilityCount: 0,
|
||
},
|
||
},
|
||
});
|
||
|
||
expect(report.focus.observabilitySignals).toEqual(
|
||
expect.arrayContaining([
|
||
expect.objectContaining({
|
||
name: "requestTelemetry:known_gap",
|
||
signal: "requestTelemetry",
|
||
status: "known_gap",
|
||
}),
|
||
]),
|
||
);
|
||
expect(report.recommendations).toEqual(
|
||
expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: "observability-evidence-follow-up",
|
||
priority: "P1",
|
||
}),
|
||
]),
|
||
);
|
||
});
|
||
|
||
it("应拒绝 recommendation 回流旧 verification outcome 字段", () => {
|
||
expect(() =>
|
||
assertGeneratedSlopReportContract({
|
||
recommendations: [
|
||
{
|
||
id: "legacy-outcome-field",
|
||
title: "旧字段示例",
|
||
priority: "P1",
|
||
rationale: ["示例"],
|
||
commands: [],
|
||
backlogTools: [],
|
||
focusFailureModes: [],
|
||
focusSuiteTags: [],
|
||
focusReviewDecisionStatuses: [],
|
||
focusReviewRiskLevels: [],
|
||
focusVerificationFailureOutcomes: [],
|
||
focusVerificationRecoveredOutcomes: [],
|
||
focusSurfaceIds: [],
|
||
focusObservabilityVerificationOutcomes: [
|
||
"browserVerification (failure)",
|
||
],
|
||
},
|
||
],
|
||
focus: {
|
||
observabilityVerificationOutcomes: [],
|
||
},
|
||
}),
|
||
).toThrow(/focusObservabilityVerificationOutcomes/);
|
||
});
|
||
});
|