project-tiny-context-harness 0.8.2 → 0.8.3
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/LICENSE +21 -21
- package/README.md +387 -387
- package/assets/README.md +553 -553
- package/assets/README.zh-CN.md +331 -331
- package/assets/agents/.gitkeep +1 -1
- package/assets/agents/AGENTS_CORE.md +69 -69
- package/assets/context_templates/architecture.md +28 -28
- package/assets/context_templates/area.md +34 -34
- package/assets/context_templates/context.toml +30 -30
- package/assets/context_templates/deployment.md +35 -35
- package/assets/context_templates/global.md +57 -57
- package/assets/context_templates/product-surface-contract.md +70 -70
- package/assets/context_templates/screen-contract.md +189 -189
- package/assets/context_templates/verification.md +32 -32
- package/assets/github/.gitkeep +1 -1
- package/assets/github/harness.yml +39 -39
- package/assets/make/.gitkeep +1 -1
- package/assets/make/ty-context.mk +48 -48
- package/assets/skills/context_development_engineer/SKILL.md +137 -137
- package/assets/skills/context_full_project_export/SKILL.md +28 -28
- package/assets/skills/context_harness_upgrade/SKILL.md +60 -60
- package/assets/skills/context_product_plan/SKILL.md +88 -88
- package/assets/skills/context_surface_contract/SKILL.md +191 -191
- package/assets/skills/context_uiux_design/SKILL.md +172 -172
- package/assets/skills/design-resource-authoring/SKILL.md +86 -85
- package/assets/skills/design-resource-authoring/references/downstream-handoff.md +138 -135
- package/assets/skills/design-resource-authoring/references/open-design-provider.md +135 -135
- package/assets/skills/design-resource-authoring/references/resource-selection.md +174 -173
- package/assets/skills/design-system-authoring/SKILL.md +57 -57
- package/assets/skills/design-system-authoring/agents/openai.yaml +6 -6
- package/assets/skills/design-system-authoring/references/authority-adoption.md +48 -48
- package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +110 -110
- package/assets/skills/long-task-workflow/SKILL.md +93 -93
- package/assets/skills/long-task-workflow/references/authority-lifecycle.md +69 -69
- package/assets/skills/long-task-workflow/references/contract-authoring.md +111 -111
- package/assets/skills/long-task-workflow/references/evidence-design.md +68 -68
- package/assets/skills/long-task-workflow/references/source-authoring.md +95 -95
- package/assets/skills/source-plan-authoring/SKILL.md +14 -14
- package/assets/tools/validate_context.py +442 -442
- package/dist/commands/design-resource.js +2 -2
- package/dist/commands/index.js +26 -26
- package/dist/commands/long-task.js +15 -15
- package/dist/lib/design-resource-fact-policy.d.ts +25 -0
- package/dist/lib/design-resource-fact-policy.js +35 -0
- package/dist/lib/design-resource-handoff-shape-evidence.d.ts +3 -1
- package/dist/lib/design-resource-handoff-shape-evidence.js +57 -0
- package/dist/lib/design-resource-handoff-shape.js +5 -1
- package/dist/lib/design-resource-handoff-types.d.ts +27 -0
- package/dist/lib/design-resource-handoff-validation-coverage.d.ts +1 -1
- package/dist/lib/design-resource-handoff-validation-coverage.js +41 -14
- package/dist/lib/design-resource-handoff-validation-facts.d.ts +2 -0
- package/dist/lib/design-resource-handoff-validation-facts.js +97 -0
- package/dist/lib/design-resource-handoff-validation.js +10 -1
- package/dist/lib/long-task-design-resource-handoff.js +19 -6
- package/dist/lib/long-task-evidence-capability-codec.js +10 -0
- package/dist/lib/long-task-evidence-capability-runtime.js +3 -0
- package/dist/lib/long-task-evidence-capability-types.d.ts +1 -0
- package/dist/lib/long-task-playwright-evidence.js +1 -0
- package/dist/lib/long-task-semantic-drift-migration.js +1 -1
- package/dist/lib/long-task-ui-design-policy.js +7 -0
- package/dist/lib/long-task-ui-surface-shape.js +12 -1
- package/dist/lib/long-task-ui-surface-types.d.ts +1 -0
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +3 -1
- package/migrations/README.md +15 -15
- package/package.json +83 -83
- package/source-mappings.yaml +25 -25
|
@@ -26,7 +26,7 @@ export async function designResource(args) {
|
|
|
26
26
|
console.log(`Acceptance blockers: ${result.counts.acceptance_blockers}`);
|
|
27
27
|
}
|
|
28
28
|
function help() {
|
|
29
|
-
console.log(`ty-context design-resource commands:
|
|
30
|
-
preflight <handoff.md> [--json]
|
|
29
|
+
console.log(`ty-context design-resource commands:
|
|
30
|
+
preflight <handoff.md> [--json]
|
|
31
31
|
Validate one selected implementation handoff`);
|
|
32
32
|
}
|
package/dist/commands/index.js
CHANGED
|
@@ -36,32 +36,32 @@ export const commands = {
|
|
|
36
36
|
package: packageSource,
|
|
37
37
|
};
|
|
38
38
|
export function help() {
|
|
39
|
-
console.log(`ty-context commands:
|
|
40
|
-
init [--adopt] [--harness-folder <path>]
|
|
41
|
-
Initialize/adopt a project; without --harness-folder, choose target agent first
|
|
42
|
-
enable long-task Install Long-Task Skill, Source Plan pointer, Stop Hook and templates
|
|
43
|
-
disable long-task Remove only package-owned long-task profile assets
|
|
44
|
-
sync Refresh managed assets; does not run migrations
|
|
45
|
-
upgrade [--check] [--json]
|
|
46
|
-
Run safe migrations, sync managed assets and doctor
|
|
47
|
-
doctor Diagnose project configuration and drift
|
|
48
|
-
check-modularity --touched|--file <path>|--base <ref> [--limit 300] [--fail-on-warning]
|
|
49
|
-
Warn when selected handwritten source files exceed a line-count limit
|
|
50
|
-
export-context --full|--code|--all|--source-pack|--code-index|--task-context
|
|
51
|
-
Export temporary Context, code snapshot or bounded Source Pack artifacts
|
|
52
|
-
validate <gate> Run a Harness validation gate
|
|
53
|
-
validate-context Validate Minimal Context fact-source recoverability
|
|
54
|
-
validate-code-modularity
|
|
55
|
-
Enforce touched handwritten source file modularity
|
|
56
|
-
validate-harness Run validate-context and validate-code-modularity
|
|
57
|
-
design-resource <subcommand>
|
|
58
|
-
Validate a selected design-resource implementation handoff
|
|
59
|
-
long-task <subcommand>
|
|
60
|
-
Manage one Canonical Delivery Contract in the current workspace
|
|
61
|
-
delivery-set <subcommand>
|
|
62
|
-
Retired; use one complete Contract with semantic Outcomes
|
|
63
|
-
composite-long-task Retired command; use ty-context long-task
|
|
64
|
-
composite-campaign Retired command; use ty-context long-task
|
|
39
|
+
console.log(`ty-context commands:
|
|
40
|
+
init [--adopt] [--harness-folder <path>]
|
|
41
|
+
Initialize/adopt a project; without --harness-folder, choose target agent first
|
|
42
|
+
enable long-task Install Long-Task Skill, Source Plan pointer, Stop Hook and templates
|
|
43
|
+
disable long-task Remove only package-owned long-task profile assets
|
|
44
|
+
sync Refresh managed assets; does not run migrations
|
|
45
|
+
upgrade [--check] [--json]
|
|
46
|
+
Run safe migrations, sync managed assets and doctor
|
|
47
|
+
doctor Diagnose project configuration and drift
|
|
48
|
+
check-modularity --touched|--file <path>|--base <ref> [--limit 300] [--fail-on-warning]
|
|
49
|
+
Warn when selected handwritten source files exceed a line-count limit
|
|
50
|
+
export-context --full|--code|--all|--source-pack|--code-index|--task-context
|
|
51
|
+
Export temporary Context, code snapshot or bounded Source Pack artifacts
|
|
52
|
+
validate <gate> Run a Harness validation gate
|
|
53
|
+
validate-context Validate Minimal Context fact-source recoverability
|
|
54
|
+
validate-code-modularity
|
|
55
|
+
Enforce touched handwritten source file modularity
|
|
56
|
+
validate-harness Run validate-context and validate-code-modularity
|
|
57
|
+
design-resource <subcommand>
|
|
58
|
+
Validate a selected design-resource implementation handoff
|
|
59
|
+
long-task <subcommand>
|
|
60
|
+
Manage one Canonical Delivery Contract in the current workspace
|
|
61
|
+
delivery-set <subcommand>
|
|
62
|
+
Retired; use one complete Contract with semantic Outcomes
|
|
63
|
+
composite-long-task Retired command; use ty-context long-task
|
|
64
|
+
composite-campaign Retired command; use ty-context long-task
|
|
65
65
|
package <subcommand> Maintain package canonical source`);
|
|
66
66
|
}
|
|
67
67
|
async function withLongTaskProfile(args, handler) {
|
|
@@ -124,20 +124,20 @@ async function finalGate(workdir, args) {
|
|
|
124
124
|
process.exitCode = 1;
|
|
125
125
|
}
|
|
126
126
|
function help() {
|
|
127
|
-
console.log(`ty-context long-task commands:
|
|
128
|
-
init <workdir>
|
|
129
|
-
preflight <workdir>
|
|
130
|
-
compile <workdir>
|
|
131
|
-
compile <workdir> --revise
|
|
132
|
-
diagnose-revision <workdir> [--outcome <key>] [--check <key>]
|
|
133
|
-
approve-authority-revision <workdir> --revision <sha>
|
|
134
|
-
explain <workdir>
|
|
135
|
-
verify <workdir> [--outcome <key>] [--check <key>] [--explain]
|
|
136
|
-
status <workdir>
|
|
137
|
-
resume <workdir>
|
|
138
|
-
doctor <workdir>
|
|
139
|
-
final-gate <workdir>
|
|
140
|
-
stop-check <workdir> [--message <text>]
|
|
141
|
-
close <workdir>
|
|
127
|
+
console.log(`ty-context long-task commands:
|
|
128
|
+
init <workdir>
|
|
129
|
+
preflight <workdir>
|
|
130
|
+
compile <workdir>
|
|
131
|
+
compile <workdir> --revise
|
|
132
|
+
diagnose-revision <workdir> [--outcome <key>] [--check <key>]
|
|
133
|
+
approve-authority-revision <workdir> --revision <sha>
|
|
134
|
+
explain <workdir>
|
|
135
|
+
verify <workdir> [--outcome <key>] [--check <key>] [--explain]
|
|
136
|
+
status <workdir>
|
|
137
|
+
resume <workdir>
|
|
138
|
+
doctor <workdir>
|
|
139
|
+
final-gate <workdir>
|
|
140
|
+
stop-check <workdir> [--message <text>]
|
|
141
|
+
close <workdir>
|
|
142
142
|
abandon <workdir> [--force-corrupt-state]`);
|
|
143
143
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DesignResourceDimension, DesignResourceEvidenceKind, DesignResourceVerificationMethod } from "./design-resource-handoff-types.js";
|
|
2
|
+
export declare const DESIGN_RESOURCE_FACT_INVARIANTS: Readonly<{
|
|
3
|
+
readonly complete_observable_design_fact_delivery: true;
|
|
4
|
+
readonly resource_fact_inventory_closure_required: true;
|
|
5
|
+
readonly exact_target_visual_pixel_required: true;
|
|
6
|
+
readonly exact_fact_set_conservation_required: true;
|
|
7
|
+
readonly design_fact_expression_boundary: true;
|
|
8
|
+
readonly unsupported_design_fact_blocks: true;
|
|
9
|
+
readonly control_granularity_is_not_design_fact_granularity: true;
|
|
10
|
+
readonly public_design_fact_guidance_required: true;
|
|
11
|
+
readonly design_fact_values_stay_in_canonical_resources: true;
|
|
12
|
+
readonly no_second_design_fact_authority: true;
|
|
13
|
+
readonly fact_inventory_required: true;
|
|
14
|
+
readonly contract_evidence_fact_binding_required: true;
|
|
15
|
+
readonly selected_design_fact_antidegradation_required: true;
|
|
16
|
+
readonly design_fact_distribution_context_cost: true;
|
|
17
|
+
readonly forbidden_design_fact_shortcuts_absent: true;
|
|
18
|
+
readonly preflight_is_not_production_conformance: true;
|
|
19
|
+
readonly unsupported_facts_block: true;
|
|
20
|
+
readonly control_relations_unchanged: true;
|
|
21
|
+
}>;
|
|
22
|
+
export declare const EXACT_TARGET_FULL_TARGET_METHODS: readonly ["layout_geometry", "visual_pixel"];
|
|
23
|
+
export declare function assertDesignResourceFactPolicyEnabled(): void;
|
|
24
|
+
export declare function designFactMethodIsCompatible(dimension: DesignResourceDimension, method: DesignResourceVerificationMethod): boolean;
|
|
25
|
+
export declare function designFactEvidenceIsCompatible(dimension: DesignResourceDimension, kind: DesignResourceEvidenceKind): boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DESIGN_RESOURCE_EVIDENCE_BY_DIMENSION, DESIGN_RESOURCE_METHODS_BY_DIMENSION, } from "./design-resource-handoff-policy.js";
|
|
2
|
+
export const DESIGN_RESOURCE_FACT_INVARIANTS = Object.freeze({
|
|
3
|
+
complete_observable_design_fact_delivery: true,
|
|
4
|
+
resource_fact_inventory_closure_required: true,
|
|
5
|
+
exact_target_visual_pixel_required: true,
|
|
6
|
+
exact_fact_set_conservation_required: true,
|
|
7
|
+
design_fact_expression_boundary: true,
|
|
8
|
+
unsupported_design_fact_blocks: true,
|
|
9
|
+
control_granularity_is_not_design_fact_granularity: true,
|
|
10
|
+
public_design_fact_guidance_required: true,
|
|
11
|
+
design_fact_values_stay_in_canonical_resources: true,
|
|
12
|
+
no_second_design_fact_authority: true,
|
|
13
|
+
fact_inventory_required: true,
|
|
14
|
+
contract_evidence_fact_binding_required: true,
|
|
15
|
+
selected_design_fact_antidegradation_required: true,
|
|
16
|
+
design_fact_distribution_context_cost: true,
|
|
17
|
+
forbidden_design_fact_shortcuts_absent: true,
|
|
18
|
+
preflight_is_not_production_conformance: true,
|
|
19
|
+
unsupported_facts_block: true,
|
|
20
|
+
control_relations_unchanged: true,
|
|
21
|
+
});
|
|
22
|
+
export const EXACT_TARGET_FULL_TARGET_METHODS = [
|
|
23
|
+
"layout_geometry",
|
|
24
|
+
"visual_pixel",
|
|
25
|
+
];
|
|
26
|
+
export function assertDesignResourceFactPolicyEnabled() {
|
|
27
|
+
if (Object.values(DESIGN_RESOURCE_FACT_INVARIANTS).some((enabled) => enabled !== true))
|
|
28
|
+
throw new Error("design_resource_fact_policy_disabled");
|
|
29
|
+
}
|
|
30
|
+
export function designFactMethodIsCompatible(dimension, method) {
|
|
31
|
+
return DESIGN_RESOURCE_METHODS_BY_DIMENSION[dimension].includes(method);
|
|
32
|
+
}
|
|
33
|
+
export function designFactEvidenceIsCompatible(dimension, kind) {
|
|
34
|
+
return DESIGN_RESOURCE_EVIDENCE_BY_DIMENSION[dimension].includes(kind);
|
|
35
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { DesignResourceHandoffBlockerV1, DesignResourceHandoffCoverageV1, DesignResourceHandoffEvidenceV1 } from "./design-resource-handoff-types.js";
|
|
1
|
+
import type { DesignResourceHandoffBlockerV1, DesignResourceHandoffCoverageV1, DesignResourceHandoffEvidenceV1, DesignResourceHandoffFactV1, DesignResourceHandoffResourceFactClosureV1 } from "./design-resource-handoff-types.js";
|
|
2
2
|
export declare function parseDesignResourceHandoffEvidence(value: unknown): DesignResourceHandoffEvidenceV1[];
|
|
3
3
|
export declare function parseDesignResourceHandoffCoverage(value: unknown): DesignResourceHandoffCoverageV1[];
|
|
4
|
+
export declare function parseDesignResourceHandoffFacts(value: unknown): DesignResourceHandoffFactV1[];
|
|
5
|
+
export declare function parseDesignResourceHandoffResourceFactClosure(value: unknown): DesignResourceHandoffResourceFactClosureV1[];
|
|
4
6
|
export declare function parseDesignResourceHandoffBlockers(value: unknown): DesignResourceHandoffBlockerV1[];
|
|
@@ -36,6 +36,7 @@ export function parseDesignResourceHandoffCoverage(value) {
|
|
|
36
36
|
"target_refs",
|
|
37
37
|
"condition_refs",
|
|
38
38
|
"evidence_refs",
|
|
39
|
+
"fact_refs",
|
|
39
40
|
"source_item_refs",
|
|
40
41
|
"verification_methods",
|
|
41
42
|
"rationale",
|
|
@@ -54,12 +55,68 @@ export function parseDesignResourceHandoffCoverage(value) {
|
|
|
54
55
|
target_refs: contractKeys(row.target_refs, `${label}.target_refs`),
|
|
55
56
|
condition_refs: contractKeys(row.condition_refs, `${label}.condition_refs`),
|
|
56
57
|
evidence_refs: stableKeys(row.evidence_refs, `${label}.evidence_refs`),
|
|
58
|
+
fact_refs: stableKeys(row.fact_refs, `${label}.fact_refs`),
|
|
57
59
|
source_item_refs: sourceItemKeys(row.source_item_refs, `${label}.source_item_refs`),
|
|
58
60
|
verification_methods: verificationMethods(row.verification_methods, `${label}.verification_methods`),
|
|
59
61
|
rationale: string(row.rationale, `${label}.rationale`),
|
|
60
62
|
};
|
|
61
63
|
});
|
|
62
64
|
}
|
|
65
|
+
export function parseDesignResourceHandoffFacts(value) {
|
|
66
|
+
return array(value, "design_resource_handoff.facts").map((item, index) => {
|
|
67
|
+
const label = `design_resource_handoff.facts[${index}]`;
|
|
68
|
+
const row = object(item, label, [
|
|
69
|
+
"key",
|
|
70
|
+
"subject_ref",
|
|
71
|
+
"target_ref",
|
|
72
|
+
"condition_ref",
|
|
73
|
+
"dimension",
|
|
74
|
+
"observation_scope",
|
|
75
|
+
"evidence_refs",
|
|
76
|
+
"source_item_refs",
|
|
77
|
+
"verification_method",
|
|
78
|
+
]);
|
|
79
|
+
return {
|
|
80
|
+
key: stableKey(row.key, `${label}.key`),
|
|
81
|
+
subject_ref: stableKey(row.subject_ref, `${label}.subject_ref`),
|
|
82
|
+
target_ref: contractKey(row.target_ref, `${label}.target_ref`),
|
|
83
|
+
condition_ref: contractKey(row.condition_ref, `${label}.condition_ref`),
|
|
84
|
+
dimension: literal(row.dimension, DESIGN_RESOURCE_DIMENSIONS, `${label}.dimension`),
|
|
85
|
+
observation_scope: literal(row.observation_scope, ["subject", "full_target"], `${label}.observation_scope`),
|
|
86
|
+
evidence_refs: stableKeys(row.evidence_refs, `${label}.evidence_refs`),
|
|
87
|
+
source_item_refs: sourceItemKeys(row.source_item_refs, `${label}.source_item_refs`),
|
|
88
|
+
verification_method: verificationMethods([row.verification_method], `${label}.verification_method`)[0],
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
export function parseDesignResourceHandoffResourceFactClosure(value) {
|
|
93
|
+
return array(value, "design_resource_handoff.resource_fact_closure").map((item, index) => {
|
|
94
|
+
const label = `design_resource_handoff.resource_fact_closure[${index}]`;
|
|
95
|
+
const row = object(item, label, [
|
|
96
|
+
"key",
|
|
97
|
+
"resource_ref",
|
|
98
|
+
"disposition",
|
|
99
|
+
"fact_refs",
|
|
100
|
+
"inspection",
|
|
101
|
+
"rationale",
|
|
102
|
+
]);
|
|
103
|
+
const inspection = object(row.inspection, `${label}.inspection`, [
|
|
104
|
+
"status",
|
|
105
|
+
"inspector",
|
|
106
|
+
]);
|
|
107
|
+
return {
|
|
108
|
+
key: stableKey(row.key, `${label}.key`),
|
|
109
|
+
resource_ref: stableKey(row.resource_ref, `${label}.resource_ref`),
|
|
110
|
+
disposition: literal(row.disposition, ["material_with_facts", "supporting_only"], `${label}.disposition`),
|
|
111
|
+
fact_refs: stableKeys(row.fact_refs, `${label}.fact_refs`),
|
|
112
|
+
inspection: {
|
|
113
|
+
status: literal(inspection.status, ["complete"], `${label}.inspection.status`),
|
|
114
|
+
inspector: string(inspection.inspector, `${label}.inspection.inspector`),
|
|
115
|
+
},
|
|
116
|
+
rationale: string(row.rationale, `${label}.rationale`),
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
}
|
|
63
120
|
export function parseDesignResourceHandoffBlockers(value) {
|
|
64
121
|
return array(value, "design_resource_handoff.acceptance_blockers").map((item, index) => {
|
|
65
122
|
const label = `design_resource_handoff.acceptance_blockers[${index}]`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseDesignResourceHandoffBlockers, parseDesignResourceHandoffCoverage, parseDesignResourceHandoffEvidence, } from "./design-resource-handoff-shape-evidence.js";
|
|
1
|
+
import { parseDesignResourceHandoffBlockers, parseDesignResourceHandoffCoverage, parseDesignResourceHandoffEvidence, parseDesignResourceHandoffFacts, parseDesignResourceHandoffResourceFactClosure, } from "./design-resource-handoff-shape-evidence.js";
|
|
2
2
|
import { contractKey, stableKeys, } from "./design-resource-handoff-shape-primitives.js";
|
|
3
3
|
import { parseDesignResourceHandoffConditions, parseDesignResourceHandoffResources, parseDesignResourceHandoffSubjects, parseDesignResourceHandoffTargets, } from "./design-resource-handoff-shape-structure.js";
|
|
4
4
|
import { literal, object, repositoryFile, string, strings, } from "./long-task-shape-primitives.js";
|
|
@@ -13,6 +13,8 @@ export function parseDesignResourceHandoffShape(value) {
|
|
|
13
13
|
"subjects",
|
|
14
14
|
"targets",
|
|
15
15
|
"evidence",
|
|
16
|
+
"facts",
|
|
17
|
+
"resource_fact_closure",
|
|
16
18
|
"coverage",
|
|
17
19
|
"acceptance_blockers",
|
|
18
20
|
"proposal",
|
|
@@ -64,6 +66,8 @@ export function parseDesignResourceHandoffShape(value) {
|
|
|
64
66
|
subjects: parseDesignResourceHandoffSubjects(root.subjects),
|
|
65
67
|
targets: parseDesignResourceHandoffTargets(root.targets),
|
|
66
68
|
evidence: parseDesignResourceHandoffEvidence(root.evidence),
|
|
69
|
+
facts: parseDesignResourceHandoffFacts(root.facts),
|
|
70
|
+
resource_fact_closure: parseDesignResourceHandoffResourceFactClosure(root.resource_fact_closure),
|
|
67
71
|
coverage: parseDesignResourceHandoffCoverage(root.coverage),
|
|
68
72
|
acceptance_blockers: parseDesignResourceHandoffBlockers(root.acceptance_blockers),
|
|
69
73
|
proposal: {
|
|
@@ -34,6 +34,8 @@ export interface DesignResourceHandoffV1 {
|
|
|
34
34
|
subjects: DesignResourceHandoffSubjectV1[];
|
|
35
35
|
targets: DesignResourceHandoffTargetV1[];
|
|
36
36
|
evidence: DesignResourceHandoffEvidenceV1[];
|
|
37
|
+
facts: DesignResourceHandoffFactV1[];
|
|
38
|
+
resource_fact_closure: DesignResourceHandoffResourceFactClosureV1[];
|
|
37
39
|
coverage: DesignResourceHandoffCoverageV1[];
|
|
38
40
|
acceptance_blockers: DesignResourceHandoffBlockerV1[];
|
|
39
41
|
proposal: {
|
|
@@ -97,6 +99,28 @@ export interface DesignResourceHandoffEvidenceV1 {
|
|
|
97
99
|
};
|
|
98
100
|
condition_refs: string[];
|
|
99
101
|
}
|
|
102
|
+
export interface DesignResourceHandoffFactV1 {
|
|
103
|
+
key: string;
|
|
104
|
+
subject_ref: string;
|
|
105
|
+
target_ref: string;
|
|
106
|
+
condition_ref: string;
|
|
107
|
+
dimension: DesignResourceDimension;
|
|
108
|
+
observation_scope: "subject" | "full_target";
|
|
109
|
+
evidence_refs: string[];
|
|
110
|
+
source_item_refs: string[];
|
|
111
|
+
verification_method: DesignResourceVerificationMethod;
|
|
112
|
+
}
|
|
113
|
+
export interface DesignResourceHandoffResourceFactClosureV1 {
|
|
114
|
+
key: string;
|
|
115
|
+
resource_ref: string;
|
|
116
|
+
disposition: "material_with_facts" | "supporting_only";
|
|
117
|
+
fact_refs: string[];
|
|
118
|
+
inspection: {
|
|
119
|
+
status: "complete";
|
|
120
|
+
inspector: string;
|
|
121
|
+
};
|
|
122
|
+
rationale: string;
|
|
123
|
+
}
|
|
100
124
|
export interface DesignResourceHandoffCoverageV1 {
|
|
101
125
|
key: string;
|
|
102
126
|
subject_refs: string[];
|
|
@@ -105,6 +129,7 @@ export interface DesignResourceHandoffCoverageV1 {
|
|
|
105
129
|
target_refs: string[];
|
|
106
130
|
condition_refs: string[];
|
|
107
131
|
evidence_refs: string[];
|
|
132
|
+
fact_refs: string[];
|
|
108
133
|
source_item_refs: string[];
|
|
109
134
|
verification_methods: DesignResourceVerificationMethod[];
|
|
110
135
|
rationale: string;
|
|
@@ -135,6 +160,8 @@ export interface DesignResourceHandoffPreflightV1 extends ParsedDesignResourceHa
|
|
|
135
160
|
subjects: number;
|
|
136
161
|
targets: number;
|
|
137
162
|
evidence: number;
|
|
163
|
+
facts: number;
|
|
164
|
+
resource_fact_closure: number;
|
|
138
165
|
coverage: number;
|
|
139
166
|
acceptance_blockers: number;
|
|
140
167
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type DesignResourceHandoffV1 } from "./design-resource-handoff-types.js";
|
|
2
|
-
export declare function validateDesignResourceCoverage(handoff: DesignResourceHandoffV1, subjects: Map<string, unknown>, targets: Map<string, DesignResourceHandoffV1["targets"][number]>, conditions: Map<string, unknown>, evidence: Map<string, DesignResourceHandoffV1["evidence"][number]>, sourceItems: Map<string, string>): void;
|
|
2
|
+
export declare function validateDesignResourceCoverage(handoff: DesignResourceHandoffV1, subjects: Map<string, unknown>, targets: Map<string, DesignResourceHandoffV1["targets"][number]>, conditions: Map<string, unknown>, evidence: Map<string, DesignResourceHandoffV1["evidence"][number]>, facts: Map<string, DesignResourceHandoffV1["facts"][number]>, sourceItems: Map<string, string>): void;
|
|
3
3
|
export declare function validateDesignResourceBlockers(handoff: DesignResourceHandoffV1, subjects: Map<string, unknown>, targets: Map<string, unknown>, sourceItems: Map<string, string>): void;
|
|
4
4
|
export declare function validateDesignResourceReachability(handoff: DesignResourceHandoffV1): void;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { DESIGN_RESOURCE_EVIDENCE_BY_DIMENSION, DESIGN_RESOURCE_METHODS_BY_DIMENSION, } from "./design-resource-handoff-policy.js";
|
|
2
2
|
import { DESIGN_RESOURCE_DIMENSIONS, } from "./design-resource-handoff-types.js";
|
|
3
3
|
import { invalidDesignResourceHandoff, requireDesignSourceItemKind, requireKnownDesignResourceRef, requireNonemptyDesignResourceValues, requireUniqueDesignResourceValues, } from "./design-resource-handoff-validation-primitives.js";
|
|
4
|
-
export function validateDesignResourceCoverage(handoff, subjects, targets, conditions, evidence, sourceItems) {
|
|
4
|
+
export function validateDesignResourceCoverage(handoff, subjects, targets, conditions, evidence, facts, sourceItems) {
|
|
5
5
|
const cells = new Set();
|
|
6
|
+
const referencedFacts = new Set();
|
|
6
7
|
const unresolved = [];
|
|
7
8
|
for (const row of handoff.coverage) {
|
|
8
9
|
requireNonemptyDesignResourceValues(row.subject_refs, `coverage_subject_refs_required:${row.key}`);
|
|
@@ -12,6 +13,7 @@ export function validateDesignResourceCoverage(handoff, subjects, targets, condi
|
|
|
12
13
|
["target_ref", row.target_refs],
|
|
13
14
|
["condition_ref", row.condition_refs],
|
|
14
15
|
["evidence_ref", row.evidence_refs],
|
|
16
|
+
["fact_ref", row.fact_refs],
|
|
15
17
|
["source_item_ref", row.source_item_refs],
|
|
16
18
|
["verification_method", row.verification_methods],
|
|
17
19
|
])
|
|
@@ -24,12 +26,12 @@ export function validateDesignResourceCoverage(handoff, subjects, targets, condi
|
|
|
24
26
|
}
|
|
25
27
|
validateCoverageApplicability(row, handoff, targets, conditions, cells);
|
|
26
28
|
if (row.disposition === "covered")
|
|
27
|
-
validateCoveredRow(row, targets, conditions, evidence);
|
|
28
|
-
else
|
|
29
|
-
validateNoncoveredRow(row);
|
|
30
|
-
if (row.disposition === "decision_required" ||
|
|
29
|
+
validateCoveredRow(row, handoff, targets, conditions, evidence, facts, referencedFacts);
|
|
30
|
+
else if (row.disposition === "decision_required" ||
|
|
31
31
|
row.disposition === "unavailable")
|
|
32
32
|
unresolved.push(row.key);
|
|
33
|
+
else
|
|
34
|
+
validateNoncoveredRow(row);
|
|
33
35
|
}
|
|
34
36
|
for (const subject of handoff.subjects)
|
|
35
37
|
for (const targetRef of subject.target_refs) {
|
|
@@ -43,6 +45,9 @@ export function validateDesignResourceCoverage(handoff, subjects, targets, condi
|
|
|
43
45
|
}
|
|
44
46
|
if (unresolved.length)
|
|
45
47
|
invalidDesignResourceHandoff("unresolved_coverage", unresolved.sort().join(","));
|
|
48
|
+
for (const fact of handoff.facts)
|
|
49
|
+
if (!referencedFacts.has(fact.key))
|
|
50
|
+
invalidDesignResourceHandoff("design_resource_fact_unreferenced", fact.key);
|
|
46
51
|
}
|
|
47
52
|
function validateCoverageApplicability(row, handoff, targets, conditions, cells) {
|
|
48
53
|
requireNonemptyDesignResourceValues(row.target_refs, `coverage_target_refs_required:${row.key}`);
|
|
@@ -126,11 +131,12 @@ export function validateDesignResourceReachability(handoff) {
|
|
|
126
131
|
if (!coverageEvidence.has(item.key))
|
|
127
132
|
invalidDesignResourceHandoff("evidence_unreferenced", item.key);
|
|
128
133
|
}
|
|
129
|
-
function validateCoveredRow(row, targets, conditions, evidence) {
|
|
134
|
+
function validateCoveredRow(row, handoff, targets, conditions, evidence, facts, referencedFacts) {
|
|
130
135
|
for (const [name, values] of [
|
|
131
136
|
["target_refs", row.target_refs],
|
|
132
137
|
["condition_refs", row.condition_refs],
|
|
133
138
|
["evidence_refs", row.evidence_refs],
|
|
139
|
+
["fact_refs", row.fact_refs],
|
|
134
140
|
["verification_methods", row.verification_methods],
|
|
135
141
|
])
|
|
136
142
|
requireNonemptyDesignResourceValues(values, `coverage_${name}_required:${row.key}`);
|
|
@@ -140,6 +146,12 @@ function validateCoveredRow(row, targets, conditions, evidence) {
|
|
|
140
146
|
requireKnownDesignResourceRef(conditions, ref, "condition");
|
|
141
147
|
for (const ref of row.evidence_refs)
|
|
142
148
|
requireKnownDesignResourceRef(evidence, ref, "evidence");
|
|
149
|
+
for (const ref of row.fact_refs) {
|
|
150
|
+
requireKnownDesignResourceRef(facts, ref, "fact");
|
|
151
|
+
if (referencedFacts.has(ref))
|
|
152
|
+
invalidDesignResourceHandoff("coverage_fact_ref_duplicate", `${row.key}:${ref}`);
|
|
153
|
+
referencedFacts.add(ref);
|
|
154
|
+
}
|
|
143
155
|
const allowedEvidence = new Set(DESIGN_RESOURCE_EVIDENCE_BY_DIMENSION[row.dimension]);
|
|
144
156
|
const allowedMethods = new Set(DESIGN_RESOURCE_METHODS_BY_DIMENSION[row.dimension]);
|
|
145
157
|
for (const ref of row.evidence_refs) {
|
|
@@ -150,20 +162,35 @@ function validateCoveredRow(row, targets, conditions, evidence) {
|
|
|
150
162
|
for (const method of row.verification_methods)
|
|
151
163
|
if (!allowedMethods.has(method))
|
|
152
164
|
invalidDesignResourceHandoff("coverage_verification_method_incompatible", `${row.key}:${row.dimension}:${method}`);
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
165
|
+
const expectedFacts = handoff.facts.filter((fact) => fact.dimension === row.dimension &&
|
|
166
|
+
row.subject_refs.includes(fact.subject_ref) &&
|
|
167
|
+
row.target_refs.includes(fact.target_ref) &&
|
|
168
|
+
row.condition_refs.includes(fact.condition_ref));
|
|
169
|
+
assertSameSet(row.fact_refs, expectedFacts.map((fact) => fact.key), "coverage_fact_refs_mismatch", row.key);
|
|
170
|
+
assertSameSet(row.evidence_refs, expectedFacts.flatMap((fact) => fact.evidence_refs), "coverage_fact_evidence_refs_mismatch", row.key);
|
|
171
|
+
assertSameSet(row.source_item_refs, expectedFacts.flatMap((fact) => fact.source_item_refs), "coverage_fact_source_item_refs_mismatch", row.key);
|
|
172
|
+
assertSameSet(row.verification_methods, expectedFacts.map((fact) => fact.verification_method), "coverage_fact_verification_methods_mismatch", row.key);
|
|
173
|
+
for (const subjectRef of row.subject_refs)
|
|
174
|
+
for (const targetRef of row.target_refs)
|
|
175
|
+
for (const conditionRef of row.condition_refs)
|
|
176
|
+
if (!expectedFacts.some((fact) => fact.subject_ref === subjectRef &&
|
|
177
|
+
fact.target_ref === targetRef &&
|
|
178
|
+
fact.condition_ref === conditionRef))
|
|
179
|
+
invalidDesignResourceHandoff("coverage_cell_without_fact", `${row.key}:${subjectRef}:${targetRef}:${conditionRef}`);
|
|
161
180
|
}
|
|
162
181
|
function validateNoncoveredRow(row) {
|
|
163
182
|
for (const [name, values] of [
|
|
164
183
|
["evidence_refs", row.evidence_refs],
|
|
184
|
+
["fact_refs", row.fact_refs],
|
|
165
185
|
["verification_methods", row.verification_methods],
|
|
166
186
|
])
|
|
167
187
|
if (values.length)
|
|
168
188
|
invalidDesignResourceHandoff("noncovered_binding_forbidden", `${row.key}:${row.disposition}:${name}`);
|
|
169
189
|
}
|
|
190
|
+
function assertSameSet(actual, expected, code, detail) {
|
|
191
|
+
const left = [...new Set(actual)].sort();
|
|
192
|
+
const right = [...new Set(expected)].sort();
|
|
193
|
+
if (left.length !== right.length ||
|
|
194
|
+
left.some((item, index) => item !== right[index]))
|
|
195
|
+
invalidDesignResourceHandoff(code, `${detail}:${left.join(",")}:${right.join(",")}`);
|
|
196
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { DesignResourceHandoffV1 } from "./design-resource-handoff-types.js";
|
|
2
|
+
export declare function validateDesignResourceFacts(handoff: DesignResourceHandoffV1, resources: Map<string, DesignResourceHandoffV1["resources"][number]>, conditions: Map<string, DesignResourceHandoffV1["conditions"][number]>, subjects: Map<string, DesignResourceHandoffV1["subjects"][number]>, targets: Map<string, DesignResourceHandoffV1["targets"][number]>, evidence: Map<string, DesignResourceHandoffV1["evidence"][number]>, sourceItems: Map<string, string>): void;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { assertDesignResourceFactPolicyEnabled, designFactEvidenceIsCompatible, designFactMethodIsCompatible, EXACT_TARGET_FULL_TARGET_METHODS, } from "./design-resource-fact-policy.js";
|
|
2
|
+
import { invalidDesignResourceHandoff, requireDesignSourceItemKind, requireKnownDesignResourceRef, requireNonemptyDesignResourceValues, requireUniqueDesignResourceValues, } from "./design-resource-handoff-validation-primitives.js";
|
|
3
|
+
export function validateDesignResourceFacts(handoff, resources, conditions, subjects, targets, evidence, sourceItems) {
|
|
4
|
+
assertDesignResourceFactPolicyEnabled();
|
|
5
|
+
for (const fact of handoff.facts) {
|
|
6
|
+
requireNonemptyDesignResourceValues(fact.evidence_refs, `fact_evidence_refs_required:${fact.key}`);
|
|
7
|
+
requireNonemptyDesignResourceValues(fact.source_item_refs, `fact_source_item_refs_required:${fact.key}`);
|
|
8
|
+
requireUniqueDesignResourceValues(fact.evidence_refs, `fact_evidence_ref_duplicate:${fact.key}`);
|
|
9
|
+
requireUniqueDesignResourceValues(fact.source_item_refs, `fact_source_item_ref_duplicate:${fact.key}`);
|
|
10
|
+
requireKnownDesignResourceRef(subjects, fact.subject_ref, "subject");
|
|
11
|
+
requireKnownDesignResourceRef(targets, fact.target_ref, "target");
|
|
12
|
+
requireKnownDesignResourceRef(conditions, fact.condition_ref, "condition");
|
|
13
|
+
const subject = subjects.get(fact.subject_ref);
|
|
14
|
+
const target = targets.get(fact.target_ref);
|
|
15
|
+
if (!subject.target_refs.includes(fact.target_ref))
|
|
16
|
+
invalidDesignResourceHandoff("fact_target_outside_subject", `${fact.key}:${fact.subject_ref}:${fact.target_ref}`);
|
|
17
|
+
if (!target.condition_refs.includes(fact.condition_ref))
|
|
18
|
+
invalidDesignResourceHandoff("fact_condition_outside_target", `${fact.key}:${fact.target_ref}:${fact.condition_ref}`);
|
|
19
|
+
if (fact.observation_scope === "full_target" &&
|
|
20
|
+
(subject.kind !== "surface" ||
|
|
21
|
+
!subject.stable_keys.some((key) => handoff.scope.surface_keys.includes(key))))
|
|
22
|
+
invalidDesignResourceHandoff("full_target_fact_surface_required", `${fact.key}:${fact.subject_ref}`);
|
|
23
|
+
if (!designFactMethodIsCompatible(fact.dimension, fact.verification_method))
|
|
24
|
+
invalidDesignResourceHandoff("fact_verification_method_incompatible", `${fact.key}:${fact.dimension}:${fact.verification_method}`);
|
|
25
|
+
for (const sourceItemRef of fact.source_item_refs) {
|
|
26
|
+
requireKnownDesignResourceRef(sourceItems, sourceItemRef, "source_item");
|
|
27
|
+
requireDesignSourceItemKind(sourceItems, sourceItemRef);
|
|
28
|
+
}
|
|
29
|
+
let exactResourceEvidence = false;
|
|
30
|
+
for (const evidenceRef of fact.evidence_refs) {
|
|
31
|
+
requireKnownDesignResourceRef(evidence, evidenceRef, "evidence");
|
|
32
|
+
const item = evidence.get(evidenceRef);
|
|
33
|
+
if (!target.resource_refs.includes(item.resource_ref))
|
|
34
|
+
invalidDesignResourceHandoff("fact_evidence_outside_target", `${fact.key}:${evidenceRef}:${fact.target_ref}`);
|
|
35
|
+
if (!item.condition_refs.includes(fact.condition_ref))
|
|
36
|
+
invalidDesignResourceHandoff("fact_evidence_condition_mismatch", `${fact.key}:${evidenceRef}:${fact.condition_ref}`);
|
|
37
|
+
if (!designFactEvidenceIsCompatible(fact.dimension, item.kind))
|
|
38
|
+
invalidDesignResourceHandoff("fact_evidence_kind_incompatible", `${fact.key}:${fact.dimension}:${evidenceRef}:${item.kind}`);
|
|
39
|
+
if (resources.get(item.resource_ref)?.role === "exact_target")
|
|
40
|
+
exactResourceEvidence = true;
|
|
41
|
+
}
|
|
42
|
+
if (fact.observation_scope === "full_target" && !exactResourceEvidence)
|
|
43
|
+
invalidDesignResourceHandoff("full_target_fact_exact_resource_required", fact.key);
|
|
44
|
+
}
|
|
45
|
+
validateExactTargetFacts(handoff);
|
|
46
|
+
validateResourceFactClosure(handoff, resources, evidence);
|
|
47
|
+
}
|
|
48
|
+
function validateExactTargetFacts(handoff) {
|
|
49
|
+
for (const target of handoff.targets) {
|
|
50
|
+
if (target.interpretation !== "exact_target")
|
|
51
|
+
continue;
|
|
52
|
+
for (const conditionRef of target.condition_refs)
|
|
53
|
+
for (const method of EXACT_TARGET_FULL_TARGET_METHODS)
|
|
54
|
+
if (!handoff.facts.some((fact) => fact.target_ref === target.key &&
|
|
55
|
+
fact.condition_ref === conditionRef &&
|
|
56
|
+
fact.observation_scope === "full_target" &&
|
|
57
|
+
fact.verification_method === method))
|
|
58
|
+
invalidDesignResourceHandoff("exact_target_full_target_fact_missing", `${target.key}:${conditionRef}:${method}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function validateResourceFactClosure(handoff, resources, evidence) {
|
|
62
|
+
const closuresByResource = new Map();
|
|
63
|
+
for (const closure of handoff.resource_fact_closure) {
|
|
64
|
+
requireKnownDesignResourceRef(resources, closure.resource_ref, "resource_fact_closure_resource");
|
|
65
|
+
if (closuresByResource.has(closure.resource_ref))
|
|
66
|
+
invalidDesignResourceHandoff("resource_fact_closure_duplicate", closure.resource_ref);
|
|
67
|
+
closuresByResource.set(closure.resource_ref, closure.key);
|
|
68
|
+
requireUniqueDesignResourceValues(closure.fact_refs, `resource_fact_closure_fact_ref_duplicate:${closure.key}`);
|
|
69
|
+
const expected = handoff.facts
|
|
70
|
+
.filter((fact) => fact.evidence_refs.some((evidenceRef) => evidence.get(evidenceRef)?.resource_ref === closure.resource_ref))
|
|
71
|
+
.map((fact) => fact.key);
|
|
72
|
+
for (const factRef of closure.fact_refs)
|
|
73
|
+
if (!handoff.facts.some((fact) => fact.key === factRef))
|
|
74
|
+
invalidDesignResourceHandoff("resource_fact_closure_fact_unknown", `${closure.key}:${factRef}`);
|
|
75
|
+
assertSameSet(closure.fact_refs, expected, "resource_fact_closure_mismatch", closure.resource_ref);
|
|
76
|
+
const resource = resources.get(closure.resource_ref);
|
|
77
|
+
if (closure.disposition === "material_with_facts" &&
|
|
78
|
+
closure.fact_refs.length === 0)
|
|
79
|
+
invalidDesignResourceHandoff("resource_fact_closure_facts_required", closure.key);
|
|
80
|
+
if (closure.disposition === "supporting_only" &&
|
|
81
|
+
closure.fact_refs.length > 0)
|
|
82
|
+
invalidDesignResourceHandoff("supporting_only_resource_fact_forbidden", closure.key);
|
|
83
|
+
if (resource.role !== "supporting" &&
|
|
84
|
+
closure.disposition !== "material_with_facts")
|
|
85
|
+
invalidDesignResourceHandoff("target_resource_fact_closure_required", `${closure.key}:${resource.role}`);
|
|
86
|
+
}
|
|
87
|
+
for (const resource of handoff.resources)
|
|
88
|
+
if (!closuresByResource.has(resource.key))
|
|
89
|
+
invalidDesignResourceHandoff("resource_fact_closure_missing", resource.key);
|
|
90
|
+
}
|
|
91
|
+
function assertSameSet(actual, expected, code, detail) {
|
|
92
|
+
const left = [...new Set(actual)].sort();
|
|
93
|
+
const right = [...new Set(expected)].sort();
|
|
94
|
+
if (left.length !== right.length ||
|
|
95
|
+
left.some((item, index) => item !== right[index]))
|
|
96
|
+
invalidDesignResourceHandoff(code, `${detail}:${left.join(",")}:${right.join(",")}`);
|
|
97
|
+
}
|
|
@@ -2,6 +2,7 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { parseDesignResourceHandoffMarkdown } from "./design-resource-handoff-parser.js";
|
|
4
4
|
import { validateDesignResourceFiles } from "./design-resource-handoff-file-validation.js";
|
|
5
|
+
import { validateDesignResourceFacts } from "./design-resource-handoff-validation-facts.js";
|
|
5
6
|
import { validateDesignResourceBlockers, validateDesignResourceCoverage, validateDesignResourceReachability, } from "./design-resource-handoff-validation-coverage.js";
|
|
6
7
|
import { indexDesignResourceItems, invalidDesignResourceHandoff, requireNonemptyDesignResourceValues, requireUniqueDesignResourceObjects, requireUniqueDesignResourceValues, } from "./design-resource-handoff-validation-primitives.js";
|
|
7
8
|
import { validateDesignResourceConditions, validateDesignResourceEvidence, validateDesignResourceScope, validateDesignResourceSubjects, validateDesignResourceTargets, } from "./design-resource-handoff-validation-structure.js";
|
|
@@ -25,6 +26,8 @@ export async function preflightDesignResourceHandoff(repository, handoffPath) {
|
|
|
25
26
|
subjects: handoff.subjects.length,
|
|
26
27
|
targets: handoff.targets.length,
|
|
27
28
|
evidence: handoff.evidence.length,
|
|
29
|
+
facts: handoff.facts.length,
|
|
30
|
+
resource_fact_closure: handoff.resource_fact_closure.length,
|
|
28
31
|
coverage: handoff.coverage.length,
|
|
29
32
|
acceptance_blockers: handoff.acceptance_blockers.length,
|
|
30
33
|
},
|
|
@@ -38,6 +41,8 @@ export function validateDesignResourceHandoffSemantics(parsed) {
|
|
|
38
41
|
requireNonemptyDesignResourceValues(handoff.subjects, "subjects_required");
|
|
39
42
|
requireNonemptyDesignResourceValues(handoff.targets, "targets_required");
|
|
40
43
|
requireNonemptyDesignResourceValues(handoff.evidence, "evidence_required");
|
|
44
|
+
requireNonemptyDesignResourceValues(handoff.facts, "facts_required");
|
|
45
|
+
requireNonemptyDesignResourceValues(handoff.resource_fact_closure, "resource_fact_closure_required");
|
|
41
46
|
requireNonemptyDesignResourceValues(handoff.coverage, "coverage_required");
|
|
42
47
|
requireUniqueDesignResourceValues(handoff.scope.surface_keys, "scope_surface_key_duplicate");
|
|
43
48
|
requireUniqueDesignResourceObjects(handoff.resources, "resource_key_duplicate");
|
|
@@ -46,6 +51,8 @@ export function validateDesignResourceHandoffSemantics(parsed) {
|
|
|
46
51
|
requireUniqueDesignResourceObjects(handoff.subjects, "subject_key_duplicate");
|
|
47
52
|
requireUniqueDesignResourceObjects(handoff.targets, "target_key_duplicate");
|
|
48
53
|
requireUniqueDesignResourceObjects(handoff.evidence, "evidence_key_duplicate");
|
|
54
|
+
requireUniqueDesignResourceObjects(handoff.facts, "fact_key_duplicate");
|
|
55
|
+
requireUniqueDesignResourceObjects(handoff.resource_fact_closure, "resource_fact_closure_key_duplicate");
|
|
49
56
|
requireUniqueDesignResourceObjects(handoff.coverage, "coverage_key_duplicate");
|
|
50
57
|
requireUniqueDesignResourceObjects(handoff.acceptance_blockers, "acceptance_blocker_key_duplicate");
|
|
51
58
|
const resources = indexDesignResourceItems(handoff.resources);
|
|
@@ -53,13 +60,15 @@ export function validateDesignResourceHandoffSemantics(parsed) {
|
|
|
53
60
|
const subjects = indexDesignResourceItems(handoff.subjects);
|
|
54
61
|
const targets = indexDesignResourceItems(handoff.targets);
|
|
55
62
|
const evidence = indexDesignResourceItems(handoff.evidence);
|
|
63
|
+
const facts = indexDesignResourceItems(handoff.facts);
|
|
56
64
|
const sourceItems = new Map(Object.entries(parsed.source_item_kinds));
|
|
57
65
|
validateDesignResourceScope(handoff);
|
|
58
66
|
validateDesignResourceConditions(handoff);
|
|
59
67
|
validateDesignResourceSubjects(handoff, targets);
|
|
60
68
|
validateDesignResourceTargets(handoff, resources, conditions);
|
|
61
69
|
validateDesignResourceEvidence(handoff, resources, conditions);
|
|
62
|
-
validateDesignResourceCoverage(handoff, subjects, targets, conditions, evidence, sourceItems);
|
|
70
|
+
validateDesignResourceCoverage(handoff, subjects, targets, conditions, evidence, facts, sourceItems);
|
|
71
|
+
validateDesignResourceFacts(handoff, resources, conditions, subjects, targets, evidence, sourceItems);
|
|
63
72
|
validateDesignResourceBlockers(handoff, subjects, targets, sourceItems);
|
|
64
73
|
validateDesignResourceReachability(handoff);
|
|
65
74
|
}
|