@sanity/ailf 5.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/airbyte/ai_literacy_framework.connector.yaml +276 -0
- package/config/bigquery/views/synthesis_parse_failure_rate_7d.sql +42 -0
- package/config/diagnosis-cards.ts +318 -0
- package/config/models.ts +12 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/agent-harness.d.ts +13 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/agent-harness.js +16 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/common.d.ts +14 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/common.js +18 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/index.d.ts +45 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/index.js +109 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/knowledge-probe.d.ts +13 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/knowledge-probe.js +17 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/literacy.d.ts +13 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/literacy.js +17 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/mcp.d.ts +13 -0
- package/dist/_vendor/ailf-core/grader/failure-modes/mcp.js +17 -0
- package/dist/_vendor/ailf-core/index.d.ts +1 -0
- package/dist/_vendor/ailf-core/index.js +4 -0
- package/dist/_vendor/ailf-core/ports/context.d.ts +12 -0
- package/dist/_vendor/ailf-core/schemas/eval-config.d.ts +7 -0
- package/dist/_vendor/ailf-core/schemas/eval-config.js +8 -0
- package/dist/_vendor/ailf-core/services/diagnosis/card-validators.d.ts +41 -0
- package/dist/_vendor/ailf-core/services/diagnosis/card-validators.js +40 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/__tests__/area-summary.test.d.ts +7 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/__tests__/area-summary.test.js +131 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/__tests__/failure-mode-summary.test.d.ts +7 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/__tests__/failure-mode-summary.test.js +230 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/__tests__/no-issues.test.d.ts +7 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/__tests__/no-issues.test.js +155 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/area-summary.d.ts +17 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/area-summary.js +43 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/doc-attribution-spotlight.d.ts +46 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/doc-attribution-spotlight.js +108 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/failure-mode-summary.d.ts +28 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/failure-mode-summary.js +140 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/index.d.ts +49 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/index.js +65 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/low-confidence-attribution.d.ts +27 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/low-confidence-attribution.js +93 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/no-issues.d.ts +32 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/no-issues.js +71 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/regression-vs-baseline.d.ts +44 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/regression-vs-baseline.js +130 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/top-recommendations.d.ts +41 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/top-recommendations.js +111 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/weakest-area.d.ts +43 -0
- package/dist/_vendor/ailf-core/services/diagnosis/cards/weakest-area.js +118 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompt-builders.d.ts +72 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompt-builders.js +286 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/doc-attribution-spotlight.system.d.ts +17 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/doc-attribution-spotlight.system.js +58 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/index.d.ts +10 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/index.js +10 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/low-confidence-attribution.system.d.ts +15 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/low-confidence-attribution.system.js +53 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/regression-vs-baseline.system.d.ts +14 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/regression-vs-baseline.system.js +63 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/top-recommendations.system.d.ts +16 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/top-recommendations.system.js +78 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/weakest-area.system.d.ts +18 -0
- package/dist/_vendor/ailf-core/services/diagnosis/prompts/weakest-area.system.js +74 -0
- package/dist/_vendor/ailf-core/services/diagnosis/registry.d.ts +10 -0
- package/dist/_vendor/ailf-core/services/diagnosis/registry.js +10 -0
- package/dist/_vendor/ailf-core/services/diagnosis-runner.d.ts +119 -2
- package/dist/_vendor/ailf-core/services/diagnosis-runner.js +136 -2
- package/dist/_vendor/ailf-core/services/index.d.ts +5 -1
- package/dist/_vendor/ailf-core/services/index.js +15 -2
- package/dist/_vendor/ailf-core/services/llm-client-factory.d.ts +64 -0
- package/dist/_vendor/ailf-core/services/llm-client-factory.js +54 -0
- package/dist/_vendor/ailf-core/types/diagnosis.d.ts +115 -10
- package/dist/_vendor/ailf-core/types/diagnosis.js +3 -1
- package/dist/_vendor/ailf-core/types/index.d.ts +8 -1
- package/dist/_vendor/ailf-core/types/repo-config.d.ts +16 -0
- package/dist/_vendor/ailf-core/types/synthesis-telemetry.d.ts +101 -0
- package/dist/_vendor/ailf-core/types/synthesis-telemetry.js +18 -0
- package/dist/adapters/config-sources/file-config-adapter.js +8 -6
- package/dist/adapters/llm/fake-llm-client.d.ts +20 -0
- package/dist/adapters/llm/fake-llm-client.js +38 -1
- package/dist/adapters/llm/index.d.ts +1 -1
- package/dist/adapters/llm/index.js +1 -1
- package/dist/adapters/llm/openai-llm-client.js +59 -5
- package/dist/adapters/llm/retry.d.ts +18 -0
- package/dist/adapters/llm/retry.js +21 -0
- package/dist/adapters/synthesis/synthesis-telemetry-schema.d.ts +49 -0
- package/dist/adapters/synthesis/synthesis-telemetry-schema.js +55 -0
- package/dist/adapters/task-sources/content-lake-task-source.js +10 -5
- package/dist/adapters/task-sources/repo-schemas.d.ts +7 -0
- package/dist/adapters/task-sources/repo-schemas.js +10 -0
- package/dist/cli-program.js +3 -0
- package/dist/commands/interpret.d.ts +70 -0
- package/dist/commands/interpret.js +221 -0
- package/dist/commands/pipeline-action.d.ts +44 -0
- package/dist/commands/pipeline-action.js +193 -1
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.js +2 -0
- package/dist/composition-root.d.ts +21 -23
- package/dist/composition-root.js +107 -41
- package/dist/config/diagnosis-cards.ts +318 -0
- package/dist/config/models.ts +12 -0
- package/dist/grader/agent-harness.d.ts +5 -10
- package/dist/grader/agent-harness.js +5 -13
- package/dist/grader/common.d.ts +5 -13
- package/dist/grader/common.js +5 -17
- package/dist/grader/index.d.ts +15 -29
- package/dist/grader/index.js +15 -66
- package/dist/grader/knowledge-probe.d.ts +5 -10
- package/dist/grader/knowledge-probe.js +5 -14
- package/dist/grader/literacy.d.ts +5 -9
- package/dist/grader/literacy.js +5 -13
- package/dist/grader/mcp.d.ts +5 -10
- package/dist/grader/mcp.js +5 -14
- package/dist/orchestration/pipeline-orchestrator.js +3 -0
- package/dist/report-store.d.ts +26 -0
- package/dist/report-store.js +63 -0
- package/package.json +2 -2
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-harness failure modes — valid for the `agent-harness` dimension
|
|
3
|
+
* family (process-quality, agent-output, tool-usage).
|
|
4
|
+
*
|
|
5
|
+
* Relocated from packages/eval/src/grader/agent-harness.ts to @sanity/ailf-core
|
|
6
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
7
|
+
* them without violating the core→eval import direction rule (D-05).
|
|
8
|
+
*
|
|
9
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
10
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283).
|
|
11
|
+
*/
|
|
12
|
+
export declare const AGENT_FAILURE_MODES: readonly ["tool-misuse", "chaotic-process", "missing-recovery"];
|
|
13
|
+
export type AgentFailureMode = (typeof AGENT_FAILURE_MODES)[number];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-harness failure modes — valid for the `agent-harness` dimension
|
|
3
|
+
* family (process-quality, agent-output, tool-usage).
|
|
4
|
+
*
|
|
5
|
+
* Relocated from packages/eval/src/grader/agent-harness.ts to @sanity/ailf-core
|
|
6
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
7
|
+
* them without violating the core→eval import direction rule (D-05).
|
|
8
|
+
*
|
|
9
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
10
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283).
|
|
11
|
+
*/
|
|
12
|
+
export const AGENT_FAILURE_MODES = [
|
|
13
|
+
"tool-misuse", // assistant calls tools incorrectly or with wrong args
|
|
14
|
+
"chaotic-process", // assistant flails — undirected exploration, no plan
|
|
15
|
+
"missing-recovery", // assistant doesn't recover from a tool error
|
|
16
|
+
];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-cutting failure modes — valid for any dimension family.
|
|
3
|
+
*
|
|
4
|
+
* Relocated from packages/eval/src/grader/common.ts to @sanity/ailf-core
|
|
5
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
6
|
+
* them without violating the core→eval import direction rule (D-05).
|
|
7
|
+
*
|
|
8
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
9
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283 — the v0 lists)
|
|
10
|
+
* @see docs/decisions/D0005-grader-model-separation.md — single grader model;
|
|
11
|
+
* taxonomies travel with the rubric prompt for reproducibility.
|
|
12
|
+
*/
|
|
13
|
+
export declare const COMMON_FAILURE_MODES: readonly ["api-error", "model-limitation", "false-floor", "unclassified"];
|
|
14
|
+
export type CommonFailureMode = (typeof COMMON_FAILURE_MODES)[number];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-cutting failure modes — valid for any dimension family.
|
|
3
|
+
*
|
|
4
|
+
* Relocated from packages/eval/src/grader/common.ts to @sanity/ailf-core
|
|
5
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
6
|
+
* them without violating the core→eval import direction rule (D-05).
|
|
7
|
+
*
|
|
8
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
9
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283 — the v0 lists)
|
|
10
|
+
* @see docs/decisions/D0005-grader-model-separation.md — single grader model;
|
|
11
|
+
* taxonomies travel with the rubric prompt for reproducibility.
|
|
12
|
+
*/
|
|
13
|
+
export const COMMON_FAILURE_MODES = [
|
|
14
|
+
"api-error", // infrastructure failure, not a docs problem
|
|
15
|
+
"model-limitation", // high ceiling, model can't reach it
|
|
16
|
+
"false-floor", // model already knew the answer; docs added no value
|
|
17
|
+
"unclassified", // grader could not pick a mode (low-confidence fallback)
|
|
18
|
+
];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-dimension failure-mode taxonomy barrel — relocated to @sanity/ailf-core.
|
|
3
|
+
*
|
|
4
|
+
* Previously lived in packages/eval/src/grader/index.ts. Moved here (D-05)
|
|
5
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
6
|
+
* `failureModesForDimension` without violating the core→eval import rule.
|
|
7
|
+
*
|
|
8
|
+
* Named re-exports only (W0124 — never `export *`).
|
|
9
|
+
*
|
|
10
|
+
* The eval-side packages/eval/src/grader/index.ts now re-exports from here,
|
|
11
|
+
* keeping all existing eval-side callers working without source changes.
|
|
12
|
+
*
|
|
13
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
14
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283).
|
|
15
|
+
* @see docs/decisions/D0005-grader-model-separation.md — single grader model;
|
|
16
|
+
* taxonomies travel with the rubric prompt for reproducibility.
|
|
17
|
+
*/
|
|
18
|
+
export { COMMON_FAILURE_MODES, type CommonFailureMode } from "./common.js";
|
|
19
|
+
export { LITERACY_FAILURE_MODES, type LiteracyFailureMode } from "./literacy.js";
|
|
20
|
+
export { MCP_FAILURE_MODES, type MCPFailureMode } from "./mcp.js";
|
|
21
|
+
export { KP_FAILURE_MODES, type KPFailureMode } from "./knowledge-probe.js";
|
|
22
|
+
export { AGENT_FAILURE_MODES, type AgentFailureMode } from "./agent-harness.js";
|
|
23
|
+
/**
|
|
24
|
+
* Return the legal failure-mode list for a given rubric dimension.
|
|
25
|
+
*
|
|
26
|
+
* Accepts both family-level keys (`mcp-behavior`, `knowledge-probe`,
|
|
27
|
+
* `agent-harness`) and the per-template `dimension` strings used in
|
|
28
|
+
* `config/rubrics.ts` (`task-completion`, `input-validation`,
|
|
29
|
+
* `factual-correctness`, `process-quality`, …). The cross-cutting
|
|
30
|
+
* `COMMON_FAILURE_MODES` is always included.
|
|
31
|
+
*
|
|
32
|
+
* Unknown dimensions fall through to `COMMON_FAILURE_MODES` only — safe
|
|
33
|
+
* default, the grader can still pick `unclassified`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function failureModesForDimension(dimension: string): readonly string[];
|
|
36
|
+
/**
|
|
37
|
+
* Flat list of all dimension names recognized by `failureModesForDimension`.
|
|
38
|
+
* Used by card-validators and test calibration.
|
|
39
|
+
*/
|
|
40
|
+
export declare const CANONICAL_DIMENSIONS: readonly string[];
|
|
41
|
+
/**
|
|
42
|
+
* Returns `true` when `mode` appears in the failure-mode list of any
|
|
43
|
+
* canonical dimension family.
|
|
44
|
+
*/
|
|
45
|
+
export declare function isCanonicalFailureMode(mode: string): boolean;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-dimension failure-mode taxonomy barrel — relocated to @sanity/ailf-core.
|
|
3
|
+
*
|
|
4
|
+
* Previously lived in packages/eval/src/grader/index.ts. Moved here (D-05)
|
|
5
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
6
|
+
* `failureModesForDimension` without violating the core→eval import rule.
|
|
7
|
+
*
|
|
8
|
+
* Named re-exports only (W0124 — never `export *`).
|
|
9
|
+
*
|
|
10
|
+
* The eval-side packages/eval/src/grader/index.ts now re-exports from here,
|
|
11
|
+
* keeping all existing eval-side callers working without source changes.
|
|
12
|
+
*
|
|
13
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
14
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283).
|
|
15
|
+
* @see docs/decisions/D0005-grader-model-separation.md — single grader model;
|
|
16
|
+
* taxonomies travel with the rubric prompt for reproducibility.
|
|
17
|
+
*/
|
|
18
|
+
export { COMMON_FAILURE_MODES } from "./common.js";
|
|
19
|
+
export { LITERACY_FAILURE_MODES } from "./literacy.js";
|
|
20
|
+
export { MCP_FAILURE_MODES } from "./mcp.js";
|
|
21
|
+
export { KP_FAILURE_MODES } from "./knowledge-probe.js";
|
|
22
|
+
export { AGENT_FAILURE_MODES } from "./agent-harness.js";
|
|
23
|
+
import { COMMON_FAILURE_MODES } from "./common.js";
|
|
24
|
+
import { LITERACY_FAILURE_MODES } from "./literacy.js";
|
|
25
|
+
import { MCP_FAILURE_MODES } from "./mcp.js";
|
|
26
|
+
import { KP_FAILURE_MODES } from "./knowledge-probe.js";
|
|
27
|
+
import { AGENT_FAILURE_MODES } from "./agent-harness.js";
|
|
28
|
+
/**
|
|
29
|
+
* Return the legal failure-mode list for a given rubric dimension.
|
|
30
|
+
*
|
|
31
|
+
* Accepts both family-level keys (`mcp-behavior`, `knowledge-probe`,
|
|
32
|
+
* `agent-harness`) and the per-template `dimension` strings used in
|
|
33
|
+
* `config/rubrics.ts` (`task-completion`, `input-validation`,
|
|
34
|
+
* `factual-correctness`, `process-quality`, …). The cross-cutting
|
|
35
|
+
* `COMMON_FAILURE_MODES` is always included.
|
|
36
|
+
*
|
|
37
|
+
* Unknown dimensions fall through to `COMMON_FAILURE_MODES` only — safe
|
|
38
|
+
* default, the grader can still pick `unclassified`.
|
|
39
|
+
*/
|
|
40
|
+
export function failureModesForDimension(dimension) {
|
|
41
|
+
switch (dimension) {
|
|
42
|
+
// ── Literacy family ──────────────────────────────────────
|
|
43
|
+
case "task-completion":
|
|
44
|
+
case "code-correctness":
|
|
45
|
+
case "doc-coverage":
|
|
46
|
+
return [...COMMON_FAILURE_MODES, ...LITERACY_FAILURE_MODES];
|
|
47
|
+
// ── MCP family ───────────────────────────────────────────
|
|
48
|
+
case "mcp-behavior":
|
|
49
|
+
case "input-validation":
|
|
50
|
+
case "output-correctness":
|
|
51
|
+
case "error-handling":
|
|
52
|
+
case "security":
|
|
53
|
+
return [...COMMON_FAILURE_MODES, ...MCP_FAILURE_MODES];
|
|
54
|
+
// ── Knowledge-probe family ───────────────────────────────
|
|
55
|
+
case "knowledge-probe":
|
|
56
|
+
case "factual-correctness":
|
|
57
|
+
case "completeness":
|
|
58
|
+
case "currency":
|
|
59
|
+
return [...COMMON_FAILURE_MODES, ...KP_FAILURE_MODES];
|
|
60
|
+
// ── Agent-harness family ─────────────────────────────────
|
|
61
|
+
case "agent-harness":
|
|
62
|
+
case "process-quality":
|
|
63
|
+
case "agent-output":
|
|
64
|
+
case "tool-usage":
|
|
65
|
+
return [...COMMON_FAILURE_MODES, ...AGENT_FAILURE_MODES];
|
|
66
|
+
default:
|
|
67
|
+
return COMMON_FAILURE_MODES;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Flat list of all dimension names recognized by `failureModesForDimension`.
|
|
72
|
+
* Used by card-validators and test calibration.
|
|
73
|
+
*/
|
|
74
|
+
export const CANONICAL_DIMENSIONS = [
|
|
75
|
+
// Literacy family
|
|
76
|
+
"task-completion",
|
|
77
|
+
"code-correctness",
|
|
78
|
+
"doc-coverage",
|
|
79
|
+
// MCP family
|
|
80
|
+
"mcp-behavior",
|
|
81
|
+
"input-validation",
|
|
82
|
+
"output-correctness",
|
|
83
|
+
"error-handling",
|
|
84
|
+
"security",
|
|
85
|
+
// Knowledge-probe family
|
|
86
|
+
"knowledge-probe",
|
|
87
|
+
"factual-correctness",
|
|
88
|
+
"completeness",
|
|
89
|
+
"currency",
|
|
90
|
+
// Agent-harness family
|
|
91
|
+
"agent-harness",
|
|
92
|
+
"process-quality",
|
|
93
|
+
"agent-output",
|
|
94
|
+
"tool-usage",
|
|
95
|
+
];
|
|
96
|
+
/**
|
|
97
|
+
* Returns `true` when `mode` appears in the failure-mode list of any
|
|
98
|
+
* canonical dimension family.
|
|
99
|
+
*/
|
|
100
|
+
export function isCanonicalFailureMode(mode) {
|
|
101
|
+
const allModes = new Set([
|
|
102
|
+
...COMMON_FAILURE_MODES,
|
|
103
|
+
...LITERACY_FAILURE_MODES,
|
|
104
|
+
...MCP_FAILURE_MODES,
|
|
105
|
+
...KP_FAILURE_MODES,
|
|
106
|
+
...AGENT_FAILURE_MODES,
|
|
107
|
+
]);
|
|
108
|
+
return allModes.has(mode);
|
|
109
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge-probe failure modes — valid for the `knowledge-probe` dimension
|
|
3
|
+
* family (factual-correctness, completeness, currency).
|
|
4
|
+
*
|
|
5
|
+
* Relocated from packages/eval/src/grader/knowledge-probe.ts to @sanity/ailf-core
|
|
6
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
7
|
+
* them without violating the core→eval import direction rule (D-05).
|
|
8
|
+
*
|
|
9
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
10
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283).
|
|
11
|
+
*/
|
|
12
|
+
export declare const KP_FAILURE_MODES: readonly ["factual-error", "incompleteness", "currency-violation", "hallucination"];
|
|
13
|
+
export type KPFailureMode = (typeof KP_FAILURE_MODES)[number];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge-probe failure modes — valid for the `knowledge-probe` dimension
|
|
3
|
+
* family (factual-correctness, completeness, currency).
|
|
4
|
+
*
|
|
5
|
+
* Relocated from packages/eval/src/grader/knowledge-probe.ts to @sanity/ailf-core
|
|
6
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
7
|
+
* them without violating the core→eval import direction rule (D-05).
|
|
8
|
+
*
|
|
9
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
10
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283).
|
|
11
|
+
*/
|
|
12
|
+
export const KP_FAILURE_MODES = [
|
|
13
|
+
"factual-error", // assistant asserts something demonstrably false
|
|
14
|
+
"incompleteness", // assistant covers part of the answer; misses key piece
|
|
15
|
+
"currency-violation", // assistant cites stale facts beyond doc currency horizon
|
|
16
|
+
"hallucination", // assistant invents details not present in any doc
|
|
17
|
+
];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Literacy failure modes — valid for `task-completion`, `code-correctness`,
|
|
3
|
+
* `doc-coverage` (the literacy dimension family).
|
|
4
|
+
*
|
|
5
|
+
* Relocated from packages/eval/src/grader/literacy.ts to @sanity/ailf-core
|
|
6
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
7
|
+
* them without violating the core→eval import direction rule (D-05).
|
|
8
|
+
*
|
|
9
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
10
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283).
|
|
11
|
+
*/
|
|
12
|
+
export declare const LITERACY_FAILURE_MODES: readonly ["missing-docs", "outdated-docs", "incorrect-docs", "poor-structure"];
|
|
13
|
+
export type LiteracyFailureMode = (typeof LITERACY_FAILURE_MODES)[number];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Literacy failure modes — valid for `task-completion`, `code-correctness`,
|
|
3
|
+
* `doc-coverage` (the literacy dimension family).
|
|
4
|
+
*
|
|
5
|
+
* Relocated from packages/eval/src/grader/literacy.ts to @sanity/ailf-core
|
|
6
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
7
|
+
* them without violating the core→eval import direction rule (D-05).
|
|
8
|
+
*
|
|
9
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
10
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283).
|
|
11
|
+
*/
|
|
12
|
+
export const LITERACY_FAILURE_MODES = [
|
|
13
|
+
"missing-docs", // relevant doc didn't exist
|
|
14
|
+
"outdated-docs", // doc reflects an older API/version
|
|
15
|
+
"incorrect-docs", // doc states something factually wrong
|
|
16
|
+
"poor-structure", // doc exists but is hard to find or follow
|
|
17
|
+
];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP failure modes — valid for the `mcp-behavior` dimension family
|
|
3
|
+
* (input-validation, output-correctness, error-handling, security).
|
|
4
|
+
*
|
|
5
|
+
* Relocated from packages/eval/src/grader/mcp.ts to @sanity/ailf-core
|
|
6
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
7
|
+
* them without violating the core→eval import direction rule (D-05).
|
|
8
|
+
*
|
|
9
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
10
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283).
|
|
11
|
+
*/
|
|
12
|
+
export declare const MCP_FAILURE_MODES: readonly ["spec-mismatch", "missing-error-handling", "over-privileged", "missing-docs"];
|
|
13
|
+
export type MCPFailureMode = (typeof MCP_FAILURE_MODES)[number];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP failure modes — valid for the `mcp-behavior` dimension family
|
|
3
|
+
* (input-validation, output-correctness, error-handling, security).
|
|
4
|
+
*
|
|
5
|
+
* Relocated from packages/eval/src/grader/mcp.ts to @sanity/ailf-core
|
|
6
|
+
* so card files in packages/core/src/services/diagnosis/cards/ can import
|
|
7
|
+
* them without violating the core→eval import direction rule (D-05).
|
|
8
|
+
*
|
|
9
|
+
* @see docs/design-docs/actionability-ladder/03-structured-grader-judgments.md
|
|
10
|
+
* §"Per-dimension failure-mode taxonomies" (lines 239-283).
|
|
11
|
+
*/
|
|
12
|
+
export const MCP_FAILURE_MODES = [
|
|
13
|
+
"spec-mismatch", // tool/server output doesn't match published MCP spec
|
|
14
|
+
"missing-error-handling", // tool failure path under-documented or absent
|
|
15
|
+
"over-privileged", // tool exposes operations the doc didn't sanction
|
|
16
|
+
"missing-docs", // re-export from literacy (cross-cutting)
|
|
17
|
+
];
|
|
@@ -23,3 +23,4 @@ export type { PricingEntry, PromptEntry, SourceEntry, } from "./config-helpers.j
|
|
|
23
23
|
export { env } from "./env-helper.js";
|
|
24
24
|
export { NoOpArtifactWriter, NotImplementedError, } from "./ports/artifact-writer.js";
|
|
25
25
|
export { assoc, resolveVariantMode, splitTaskVariant, type AssocContext, type TaskVariantSplit, } from "./artifact-capture/association.js";
|
|
26
|
+
export { AGENT_FAILURE_MODES, CANONICAL_DIMENSIONS, COMMON_FAILURE_MODES, KP_FAILURE_MODES, LITERACY_FAILURE_MODES, MCP_FAILURE_MODES, failureModesForDimension, isCanonicalFailureMode, type AgentFailureMode, type CommonFailureMode, type KPFailureMode, type LiteracyFailureMode, type MCPFailureMode, } from "./grader/failure-modes/index.js";
|
|
@@ -25,3 +25,7 @@ export { defineCanaryTasks, defineConfig, defineFeatures, defineModeBase, define
|
|
|
25
25
|
export { env } from "./env-helper.js";
|
|
26
26
|
export { NoOpArtifactWriter, NotImplementedError, } from "./ports/artifact-writer.js";
|
|
27
27
|
export { assoc, resolveVariantMode, splitTaskVariant, } from "./artifact-capture/association.js";
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Phase 5 — failure-mode taxonomy (D-05 hoist)
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
export { AGENT_FAILURE_MODES, CANONICAL_DIMENSIONS, COMMON_FAILURE_MODES, KP_FAILURE_MODES, LITERACY_FAILURE_MODES, MCP_FAILURE_MODES, failureModesForDimension, isCanonicalFailureMode, } from "./grader/failure-modes/index.js";
|
|
@@ -237,6 +237,14 @@ export interface ResolvedConfig {
|
|
|
237
237
|
* Sourced from AILF_ARTIFACT_UPLOAD env var or `artifactUpload` in ailf.config.ts.
|
|
238
238
|
*/
|
|
239
239
|
artifactUpload?: boolean;
|
|
240
|
+
/**
|
|
241
|
+
* Post-run diagnosis summary policy (Phase 6 / DIAG-06). Carried from
|
|
242
|
+
* `.ailf/config.yaml` summary.onRun via RepoConfigSchema (CLI path) or
|
|
243
|
+
* EvalConfigSchema (file-config path). Precedence resolution is deferred to
|
|
244
|
+
* shouldRunPostSummary() at execution time — this field carries only the
|
|
245
|
+
* config-file signal.
|
|
246
|
+
*/
|
|
247
|
+
summaryOnRun?: "auto" | "always" | "never";
|
|
240
248
|
}
|
|
241
249
|
/**
|
|
242
250
|
* Application context — the complete dependency carrier.
|
|
@@ -331,6 +339,10 @@ export interface ReportStorePort {
|
|
|
331
339
|
findComparableBaseline(query: unknown): Promise<null | unknown>;
|
|
332
340
|
/** Write a report to the store */
|
|
333
341
|
write(report: unknown): Promise<unknown>;
|
|
342
|
+
/** Read a report by its ID (used by the post-run diagnosis hook). */
|
|
343
|
+
read(id: string): Promise<null | unknown>;
|
|
344
|
+
/** Patch synthesis telemetry onto a published report (Phase 6 / DIAG-06). */
|
|
345
|
+
patchSynthesis(id: string, telemetry: unknown): Promise<void>;
|
|
334
346
|
}
|
|
335
347
|
/**
|
|
336
348
|
* Minimal report sink interface used by AppContext.
|
|
@@ -88,6 +88,13 @@ export declare const EvalConfigSchema: z.ZodObject<{
|
|
|
88
88
|
skipEval: z.ZodOptional<z.ZodBoolean>;
|
|
89
89
|
skipFetch: z.ZodOptional<z.ZodBoolean>;
|
|
90
90
|
source: z.ZodOptional<z.ZodString>;
|
|
91
|
+
summary: z.ZodOptional<z.ZodObject<{
|
|
92
|
+
onRun: z.ZodOptional<z.ZodEnum<{
|
|
93
|
+
never: "never";
|
|
94
|
+
always: "always";
|
|
95
|
+
auto: "auto";
|
|
96
|
+
}>>;
|
|
97
|
+
}, z.core.$strip>>;
|
|
91
98
|
tasks: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
92
99
|
urls: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
93
100
|
presets: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -175,6 +175,14 @@ export const EvalConfigSchema = z
|
|
|
175
175
|
skipFetch: z.boolean().optional(),
|
|
176
176
|
/** Documentation source name */
|
|
177
177
|
source: z.string().optional(),
|
|
178
|
+
/**
|
|
179
|
+
* Post-run diagnosis summary policy (Phase 6 / DIAG-06). Mirrors
|
|
180
|
+
* `RepoConfigSchema`'s `summary` block for `--config <path>` parity.
|
|
181
|
+
* Precedence resolved at the CLI layer by `shouldRunPostSummary()`.
|
|
182
|
+
*/
|
|
183
|
+
summary: z
|
|
184
|
+
.object({ onRun: z.enum(["auto", "always", "never"]).optional() })
|
|
185
|
+
.optional(),
|
|
178
186
|
/** Task ID filter */
|
|
179
187
|
tasks: z.array(z.string()).optional(),
|
|
180
188
|
/** Doc source URL overrides */
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Zod `.refine()` helpers for diagnosis card body schemas (D-05).
|
|
3
|
+
*
|
|
4
|
+
* Card body schemas that mention failure modes MUST encode `dimension` AND
|
|
5
|
+
* call `.refine(buildFailureModeRefinement())` to prevent cross-dimension
|
|
6
|
+
* hallucinations from passing Zod (CONTEXT D-05). The refinement turns a
|
|
7
|
+
* "Zod-passes, semantically wrong" LLM output into a `parseFailed: true`
|
|
8
|
+
* degraded card, which the budget logic then absorbs.
|
|
9
|
+
*
|
|
10
|
+
* This file is a sibling of cards/ (NOT inside cards/), so it is NOT inside
|
|
11
|
+
* the D0045 trust-boundary scan root. It is a pure utility, not a boundary
|
|
12
|
+
* parser.
|
|
13
|
+
*
|
|
14
|
+
* @see packages/core/src/grader/failure-modes/index.ts
|
|
15
|
+
* @see .planning/phases/05-diagnosis-engine-cli-llm-cards/05-CONTEXT.md (D-05)
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Returns `true` when the `failureMode` in `body` is in the canonical
|
|
19
|
+
* taxonomy for `body.dimension`. Used directly and via `buildFailureModeRefinement`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isFailureModeInDimensionTaxonomy(body: {
|
|
22
|
+
dimension: string;
|
|
23
|
+
failureMode: string;
|
|
24
|
+
}): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Returns a Zod `.refine()` predicate that approves canonical
|
|
27
|
+
* (dimension, failureMode) pairs and rejects cross-dimension pairs.
|
|
28
|
+
*
|
|
29
|
+
* Usage:
|
|
30
|
+
* ```ts
|
|
31
|
+
* export const FailureModeSummaryBodySchema = z
|
|
32
|
+
* .object({ dimension: z.string(), failureMode: z.string(), ... })
|
|
33
|
+
* .refine(buildFailureModeRefinement(), {
|
|
34
|
+
* message: "failureMode not in canonical taxonomy for this dimension",
|
|
35
|
+
* }) satisfies z.ZodType<FailureModeSummaryBody>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function buildFailureModeRefinement<TBody extends {
|
|
39
|
+
dimension: string;
|
|
40
|
+
failureMode: string;
|
|
41
|
+
}>(): (body: TBody) => boolean;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Zod `.refine()` helpers for diagnosis card body schemas (D-05).
|
|
3
|
+
*
|
|
4
|
+
* Card body schemas that mention failure modes MUST encode `dimension` AND
|
|
5
|
+
* call `.refine(buildFailureModeRefinement())` to prevent cross-dimension
|
|
6
|
+
* hallucinations from passing Zod (CONTEXT D-05). The refinement turns a
|
|
7
|
+
* "Zod-passes, semantically wrong" LLM output into a `parseFailed: true`
|
|
8
|
+
* degraded card, which the budget logic then absorbs.
|
|
9
|
+
*
|
|
10
|
+
* This file is a sibling of cards/ (NOT inside cards/), so it is NOT inside
|
|
11
|
+
* the D0045 trust-boundary scan root. It is a pure utility, not a boundary
|
|
12
|
+
* parser.
|
|
13
|
+
*
|
|
14
|
+
* @see packages/core/src/grader/failure-modes/index.ts
|
|
15
|
+
* @see .planning/phases/05-diagnosis-engine-cli-llm-cards/05-CONTEXT.md (D-05)
|
|
16
|
+
*/
|
|
17
|
+
import { failureModesForDimension } from "../../grader/failure-modes/index.js";
|
|
18
|
+
/**
|
|
19
|
+
* Returns `true` when the `failureMode` in `body` is in the canonical
|
|
20
|
+
* taxonomy for `body.dimension`. Used directly and via `buildFailureModeRefinement`.
|
|
21
|
+
*/
|
|
22
|
+
export function isFailureModeInDimensionTaxonomy(body) {
|
|
23
|
+
return failureModesForDimension(body.dimension).includes(body.failureMode);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns a Zod `.refine()` predicate that approves canonical
|
|
27
|
+
* (dimension, failureMode) pairs and rejects cross-dimension pairs.
|
|
28
|
+
*
|
|
29
|
+
* Usage:
|
|
30
|
+
* ```ts
|
|
31
|
+
* export const FailureModeSummaryBodySchema = z
|
|
32
|
+
* .object({ dimension: z.string(), failureMode: z.string(), ... })
|
|
33
|
+
* .refine(buildFailureModeRefinement(), {
|
|
34
|
+
* message: "failureMode not in canonical taxonomy for this dimension",
|
|
35
|
+
* }) satisfies z.ZodType<FailureModeSummaryBody>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function buildFailureModeRefinement() {
|
|
39
|
+
return (body) => isFailureModeInDimensionTaxonomy(body);
|
|
40
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* area-summary.test.ts — Tests 1-4 for the deterministic area-summary card.
|
|
3
|
+
*
|
|
4
|
+
* D0042: vitest only, no node:test.
|
|
5
|
+
* D0045: AreaSummaryBodySchema satisfies z.ZodType<AreaSummaryBody> compile-time gate.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, expect, it } from "vitest";
|
|
8
|
+
import { AreaSummaryBodySchema, generateAreaSummary } from "../area-summary.js";
|
|
9
|
+
// Test 1: schema satisfies compile-time gate
|
|
10
|
+
const _satisfiesCheck = AreaSummaryBodySchema;
|
|
11
|
+
const silentLogger = {
|
|
12
|
+
debug: () => { },
|
|
13
|
+
info: () => { },
|
|
14
|
+
warn: () => { },
|
|
15
|
+
error: () => { },
|
|
16
|
+
step: () => { },
|
|
17
|
+
section: () => { },
|
|
18
|
+
table: () => { },
|
|
19
|
+
};
|
|
20
|
+
const noopProgress = {
|
|
21
|
+
phaseStart: () => { },
|
|
22
|
+
phaseProgress: () => { },
|
|
23
|
+
phaseComplete: () => { },
|
|
24
|
+
};
|
|
25
|
+
function makeCtx() {
|
|
26
|
+
return {
|
|
27
|
+
llm: undefined,
|
|
28
|
+
model: "anthropic:claude-sonnet-4-6",
|
|
29
|
+
logger: silentLogger,
|
|
30
|
+
progress: noopProgress,
|
|
31
|
+
versions: {
|
|
32
|
+
graderJudgmentsVersion: "1.0.0",
|
|
33
|
+
ensembleVersion: "1.0.0",
|
|
34
|
+
diagnosisVersion: "0.1.0",
|
|
35
|
+
cardVersion: "1.0.0",
|
|
36
|
+
},
|
|
37
|
+
runId: "run-001",
|
|
38
|
+
reportId: "report-001",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function makeReportWithScores(scores) {
|
|
42
|
+
return {
|
|
43
|
+
id: "report-001",
|
|
44
|
+
completedAt: "2026-01-01T00:00:00Z",
|
|
45
|
+
durationMs: 1000,
|
|
46
|
+
provenance: {
|
|
47
|
+
runId: "run-001",
|
|
48
|
+
mode: "standard",
|
|
49
|
+
areas: [],
|
|
50
|
+
taskIds: [],
|
|
51
|
+
models: [],
|
|
52
|
+
graderModel: "gpt-4o",
|
|
53
|
+
source: "local",
|
|
54
|
+
evalFingerprint: "",
|
|
55
|
+
trigger: "manual",
|
|
56
|
+
git: undefined,
|
|
57
|
+
},
|
|
58
|
+
summary: {
|
|
59
|
+
belowCritical: [],
|
|
60
|
+
lowestArea: "groq",
|
|
61
|
+
lowestScore: Math.min(...(scores.length ? scores : [0])),
|
|
62
|
+
overall: {
|
|
63
|
+
avgCeilingScore: 80,
|
|
64
|
+
avgScore: 75,
|
|
65
|
+
avgDocLift: 5,
|
|
66
|
+
avgDocQualityGap: 20,
|
|
67
|
+
avgFloorScore: 70,
|
|
68
|
+
negativeDocLiftCount: 0,
|
|
69
|
+
},
|
|
70
|
+
scores: scores.map((s, i) => ({
|
|
71
|
+
feature: `area-${i + 1}`,
|
|
72
|
+
ceilingScore: 80,
|
|
73
|
+
codeCorrectness: s,
|
|
74
|
+
docCoverage: s,
|
|
75
|
+
docLift: 5,
|
|
76
|
+
docQualityGap: 20,
|
|
77
|
+
floorScore: s - 5,
|
|
78
|
+
negativeDocLift: false,
|
|
79
|
+
taskCompletion: s,
|
|
80
|
+
testCount: 10,
|
|
81
|
+
totalCost: 0.05,
|
|
82
|
+
totalScore: s,
|
|
83
|
+
})),
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
describe("AreaSummaryBodySchema (Test 1)", () => {
|
|
88
|
+
it("satisfies z.ZodType<AreaSummaryBody> (compile-time check assigned above)", () => {
|
|
89
|
+
// Runtime check: valid payload parses successfully
|
|
90
|
+
const result = AreaSummaryBodySchema.safeParse({ summary: "test summary" });
|
|
91
|
+
expect(result.success).toBe(true);
|
|
92
|
+
// The _satisfiesCheck assignment above is the actual compile-time gate
|
|
93
|
+
expect(_satisfiesCheck).toBeDefined();
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
describe("generateAreaSummary (Test 2)", () => {
|
|
97
|
+
it("returns a ready card with summary including area count and mean score for 3 areas at [80, 60, 70]", async () => {
|
|
98
|
+
const report = makeReportWithScores([80, 60, 70]);
|
|
99
|
+
const card = await generateAreaSummary(report, makeCtx());
|
|
100
|
+
expect(card.status).toBe("ready");
|
|
101
|
+
if (card.status === "ready") {
|
|
102
|
+
expect(card.cardType).toBe("area-summary");
|
|
103
|
+
expect(card.meta.cardVersion).toBe("area-summary@0.1.0");
|
|
104
|
+
expect(card.meta.generatedAt).toBeTruthy();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe("generateAreaSummary — summary content (Test 3)", () => {
|
|
109
|
+
it("summary includes BOTH the area count AND mean score to one decimal", async () => {
|
|
110
|
+
const report = makeReportWithScores([80, 60, 70]);
|
|
111
|
+
const card = await generateAreaSummary(report, makeCtx());
|
|
112
|
+
expect(card.status).toBe("ready");
|
|
113
|
+
if (card.status === "ready") {
|
|
114
|
+
const body = card.body;
|
|
115
|
+
// Mean of [80, 60, 70] = 70.0
|
|
116
|
+
expect(body.summary).toContain("3");
|
|
117
|
+
expect(body.summary).toContain("70.0");
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
describe("generateAreaSummary — zero areas guard (Test 4)", () => {
|
|
122
|
+
it("returns missing card with 'report has no areas' reason for zero-area report", async () => {
|
|
123
|
+
const report = makeReportWithScores([]);
|
|
124
|
+
const card = await generateAreaSummary(report, makeCtx());
|
|
125
|
+
expect(card.status).toBe("missing");
|
|
126
|
+
if (card.status === "missing") {
|
|
127
|
+
expect(card.cardType).toBe("area-summary");
|
|
128
|
+
expect(card.reason).toContain("no areas");
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
});
|