project-tiny-context-harness 0.8.4 → 0.8.6
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 +394 -363
- package/assets/README.md +570 -514
- package/assets/README.zh-CN.md +331 -300
- package/assets/agents/.gitkeep +1 -1
- package/assets/agents/AGENTS_CORE.md +45 -25
- package/assets/context_templates/architecture.md +26 -25
- package/assets/context_templates/area.md +32 -31
- package/assets/context_templates/context.toml +30 -24
- 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 +31 -30
- 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 +155 -122
- 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 +99 -79
- package/assets/skills/context_surface_contract/SKILL.md +191 -191
- package/assets/skills/context_uiux_design/SKILL.md +171 -171
- package/assets/skills/design-resource-authoring/SKILL.md +86 -84
- package/assets/skills/design-resource-authoring/references/downstream-handoff.md +138 -123
- package/assets/skills/design-resource-authoring/references/open-design-provider.md +132 -127
- package/assets/skills/design-resource-authoring/references/resource-selection.md +181 -154
- 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 +98 -92
- package/assets/skills/long-task-workflow/agents/openai.yaml +3 -1
- package/assets/skills/long-task-workflow/references/authority-lifecycle.md +72 -72
- package/assets/skills/long-task-workflow/references/contract-authoring.md +122 -101
- package/assets/skills/long-task-workflow/references/evidence-design.md +82 -61
- package/assets/skills/long-task-workflow/references/source-authoring.md +109 -90
- package/assets/skills/source-plan-authoring/SKILL.md +14 -14
- package/assets/tools/validate_context.py +442 -442
- package/dist/commands/long-task-authoring.js +27 -2
- package/dist/lib/context-default-footprint.js +2 -0
- package/dist/lib/context-manifest.js +6 -0
- package/dist/lib/context-templates.js +1 -1
- package/dist/lib/design-resource-fact-enums.d.ts +20 -0
- package/dist/lib/design-resource-fact-enums.js +170 -0
- package/dist/lib/design-resource-fact-locator-extractors.d.ts +8 -0
- package/dist/lib/design-resource-fact-locator-extractors.js +108 -0
- package/dist/lib/design-resource-fact-locator-resolver.d.ts +3 -0
- package/dist/lib/design-resource-fact-locator-resolver.js +112 -0
- package/dist/lib/design-resource-fact-locator-validation.d.ts +5 -0
- package/dist/lib/design-resource-fact-locator-validation.js +16 -0
- package/dist/lib/design-resource-fact-manifest-catalog.d.ts +4 -0
- package/dist/lib/design-resource-fact-manifest-catalog.js +249 -0
- package/dist/lib/design-resource-fact-manifest-model.d.ts +91 -0
- package/dist/lib/design-resource-fact-manifest-model.js +21 -0
- package/dist/lib/design-resource-fact-manifest-shape-axes.d.ts +6 -0
- package/dist/lib/design-resource-fact-manifest-shape-axes.js +159 -0
- package/dist/lib/design-resource-fact-manifest-shape-evidence.d.ts +4 -0
- package/dist/lib/design-resource-fact-manifest-shape-evidence.js +59 -0
- package/dist/lib/design-resource-fact-manifest-shape-facts.d.ts +4 -0
- package/dist/lib/design-resource-fact-manifest-shape-facts.js +109 -0
- package/dist/lib/design-resource-fact-manifest-shape-inspector.d.ts +5 -0
- package/dist/lib/design-resource-fact-manifest-shape-inspector.js +144 -0
- package/dist/lib/design-resource-fact-manifest-shape.d.ts +7 -0
- package/dist/lib/design-resource-fact-manifest-shape.js +75 -0
- package/dist/lib/design-resource-fact-manifest-types.d.ts +3 -0
- package/dist/lib/design-resource-fact-manifest-types.js +3 -0
- package/dist/lib/design-resource-fact-manifest-universe.d.ts +5 -0
- package/dist/lib/design-resource-fact-manifest-universe.js +50 -0
- package/dist/lib/design-resource-fact-manifest-validation.d.ts +3 -0
- package/dist/lib/design-resource-fact-manifest-validation.js +106 -0
- package/dist/lib/design-resource-fact-policy.d.ts +18 -0
- package/dist/lib/design-resource-fact-policy.js +72 -1
- package/dist/lib/design-resource-fact-property-methods.d.ts +3 -0
- package/dist/lib/design-resource-fact-property-methods.js +158 -0
- package/dist/lib/design-resource-fact-shape-primitives.d.ts +3 -0
- package/dist/lib/design-resource-fact-shape-primitives.js +18 -0
- package/dist/lib/design-resource-fact-types.d.ts +164 -0
- package/dist/lib/design-resource-fact-types.js +1 -0
- package/dist/lib/design-resource-fact-universe-assets.d.ts +4 -0
- package/dist/lib/design-resource-fact-universe-assets.js +71 -0
- package/dist/lib/design-resource-fact-universe-catalog.d.ts +4 -0
- package/dist/lib/design-resource-fact-universe-catalog.js +151 -0
- package/dist/lib/design-resource-fact-universe-conditions.d.ts +2 -0
- package/dist/lib/design-resource-fact-universe-conditions.js +92 -0
- package/dist/lib/design-resource-fact-universe-facts.d.ts +4 -0
- package/dist/lib/design-resource-fact-universe-facts.js +108 -0
- package/dist/lib/design-resource-fact-universe-helpers.d.ts +30 -0
- package/dist/lib/design-resource-fact-universe-helpers.js +167 -0
- package/dist/lib/design-resource-fact-universe-inspector.d.ts +7 -0
- package/dist/lib/design-resource-fact-universe-inspector.js +119 -0
- package/dist/lib/design-resource-fact-universe-proof.d.ts +4 -0
- package/dist/lib/design-resource-fact-universe-proof.js +113 -0
- package/dist/lib/design-resource-fact-universe-subjects.d.ts +5 -0
- package/dist/lib/design-resource-fact-universe-subjects.js +97 -0
- package/dist/lib/design-resource-fact-universe-variations.d.ts +2 -0
- package/dist/lib/design-resource-fact-universe-variations.js +75 -0
- package/dist/lib/design-resource-fact-value-validation.d.ts +2 -0
- package/dist/lib/design-resource-fact-value-validation.js +80 -0
- package/dist/lib/design-resource-handoff-file-primitives.js +2 -0
- package/dist/lib/design-resource-handoff-file-validation.js +13 -100
- package/dist/lib/design-resource-handoff-policy.d.ts +1 -0
- package/dist/lib/design-resource-handoff-policy.js +118 -11
- package/dist/lib/design-resource-handoff-shape-evidence.js +46 -3
- package/dist/lib/design-resource-handoff-shape-primitives.d.ts +5 -0
- package/dist/lib/design-resource-handoff-shape-primitives.js +28 -0
- package/dist/lib/design-resource-handoff-shape-structure.js +143 -22
- package/dist/lib/design-resource-handoff-shape.js +25 -0
- package/dist/lib/design-resource-handoff-types.d.ts +97 -21
- package/dist/lib/design-resource-handoff-types.js +22 -0
- package/dist/lib/design-resource-handoff-validation-coverage.d.ts +1 -1
- package/dist/lib/design-resource-handoff-validation-coverage.js +145 -118
- package/dist/lib/design-resource-handoff-validation-fact-cells.d.ts +2 -0
- package/dist/lib/design-resource-handoff-validation-fact-cells.js +60 -0
- package/dist/lib/design-resource-handoff-validation-fact-records.d.ts +2 -0
- package/dist/lib/design-resource-handoff-validation-fact-records.js +90 -0
- package/dist/lib/design-resource-handoff-validation-facts.js +10 -94
- package/dist/lib/design-resource-handoff-validation-proofs.d.ts +2 -0
- package/dist/lib/design-resource-handoff-validation-proofs.js +67 -0
- package/dist/lib/design-resource-handoff-validation-resource-closure.d.ts +3 -0
- package/dist/lib/design-resource-handoff-validation-resource-closure.js +88 -0
- package/dist/lib/design-resource-handoff-validation-structure.js +43 -14
- package/dist/lib/design-resource-handoff-validation.js +32 -0
- package/dist/lib/design-resource-handoff-web-dependency-validation.d.ts +2 -1
- package/dist/lib/design-resource-handoff-web-dependency-validation.js +67 -7
- package/dist/lib/execution-target-capabilities.d.ts +1 -1
- package/dist/lib/execution-target-capabilities.js +14 -0
- package/dist/lib/long-task-activation-validation.js +6 -2
- package/dist/lib/long-task-applicability-shape.js +3 -3
- package/dist/lib/long-task-authoring-authority-preview.js +1 -0
- package/dist/lib/long-task-authority-policy.d.ts +1 -0
- package/dist/lib/long-task-authority-policy.js +1 -0
- package/dist/lib/long-task-authority.js +13 -0
- package/dist/lib/long-task-claim-definitions.js +13 -1
- package/dist/lib/long-task-claims.js +23 -1
- package/dist/lib/long-task-contract-types.d.ts +3 -0
- package/dist/lib/long-task-delivery-compiler.js +1 -0
- package/dist/lib/long-task-delivery-parser.js +11 -1
- package/dist/lib/long-task-delivery-types.d.ts +1 -0
- package/dist/lib/long-task-delivery-types.js +1 -0
- package/dist/lib/long-task-delivery-validation.js +17 -0
- package/dist/lib/long-task-design-resource-handoff.js +62 -38
- package/dist/lib/long-task-design-target-capabilities.d.ts +14 -0
- package/dist/lib/long-task-design-target-capabilities.js +126 -0
- package/dist/lib/long-task-evidence-capability-codec.d.ts +94 -0
- package/dist/lib/long-task-evidence-capability-codec.js +395 -22
- package/dist/lib/long-task-evidence-capability-policy.js +18 -0
- package/dist/lib/long-task-evidence-capability-runtime.js +78 -0
- package/dist/lib/long-task-evidence-capability-types.d.ts +114 -1
- package/dist/lib/long-task-outcome-parser.js +4 -0
- package/dist/lib/long-task-playwright-capability-records.d.ts +5 -0
- package/dist/lib/long-task-playwright-capability-records.js +146 -0
- package/dist/lib/long-task-playwright-case-evidence.d.ts +3 -2
- package/dist/lib/long-task-playwright-case-evidence.js +10 -79
- package/dist/lib/long-task-playwright-case-primitives.d.ts +28 -0
- package/dist/lib/long-task-playwright-case-primitives.js +143 -0
- package/dist/lib/long-task-playwright-evidence.d.ts +1 -1
- package/dist/lib/long-task-playwright-evidence.js +10 -75
- package/dist/lib/long-task-runner-freeze.d.ts +2 -2
- package/dist/lib/long-task-runner-freeze.js +15 -1
- package/dist/lib/long-task-runtime-types.d.ts +4 -1
- package/dist/lib/long-task-semantic-contract-types.d.ts +1 -1
- package/dist/lib/long-task-semantic-drift-migration.js +2 -2
- package/dist/lib/long-task-semantic-fact-binding-types.d.ts +57 -0
- package/dist/lib/long-task-semantic-fact-binding-types.js +1 -0
- package/dist/lib/long-task-semantic-fact-closure-primitives.d.ts +5 -0
- package/dist/lib/long-task-semantic-fact-closure-primitives.js +43 -0
- package/dist/lib/long-task-semantic-fact-closure.d.ts +13 -0
- package/dist/lib/long-task-semantic-fact-closure.js +48 -0
- package/dist/lib/long-task-semantic-fact-contract-closure.d.ts +4 -0
- package/dist/lib/long-task-semantic-fact-contract-closure.js +24 -0
- package/dist/lib/long-task-semantic-fact-contract-facts.d.ts +4 -0
- package/dist/lib/long-task-semantic-fact-contract-facts.js +30 -0
- package/dist/lib/long-task-semantic-fact-contract-proofs.d.ts +4 -0
- package/dist/lib/long-task-semantic-fact-contract-proofs.js +97 -0
- package/dist/lib/long-task-semantic-fact-evidence.d.ts +21 -0
- package/dist/lib/long-task-semantic-fact-evidence.js +165 -0
- package/dist/lib/long-task-semantic-fact-input-closure.d.ts +4 -0
- package/dist/lib/long-task-semantic-fact-input-closure.js +101 -0
- package/dist/lib/long-task-semantic-fact-provenance-closure.d.ts +4 -0
- package/dist/lib/long-task-semantic-fact-provenance-closure.js +140 -0
- package/dist/lib/long-task-semantic-fact-shape.d.ts +3 -0
- package/dist/lib/long-task-semantic-fact-shape.js +89 -0
- package/dist/lib/long-task-semantic-fact-value-closure.d.ts +3 -0
- package/dist/lib/long-task-semantic-fact-value-closure.js +110 -0
- package/dist/lib/long-task-shape-primitives.d.ts +2 -1
- package/dist/lib/long-task-shape-primitives.js +7 -0
- package/dist/lib/long-task-source-item-parser.js +25 -6
- package/dist/lib/long-task-source-target-continuity.js +4 -1
- package/dist/lib/long-task-source-target-index.d.ts +1 -1
- package/dist/lib/long-task-source-target-index.js +5 -1
- package/dist/lib/long-task-ui-design-policy.js +8 -4
- package/dist/lib/long-task-ui-surface-shape.js +83 -1
- package/dist/lib/long-task-ui-surface-types.d.ts +29 -0
- package/dist/lib/modularity.js +7 -1
- package/dist/lib/semantic-fact-base-types.d.ts +14 -0
- package/dist/lib/semantic-fact-base-types.js +1 -0
- package/dist/lib/semantic-fact-catalog.d.ts +8 -0
- package/dist/lib/semantic-fact-catalog.js +191 -0
- package/dist/lib/semantic-fact-condition-shape.d.ts +48 -0
- package/dist/lib/semantic-fact-condition-shape.js +111 -0
- package/dist/lib/semantic-fact-input-shape.d.ts +34 -0
- package/dist/lib/semantic-fact-input-shape.js +111 -0
- package/dist/lib/semantic-fact-inventory-types.d.ts +147 -0
- package/dist/lib/semantic-fact-inventory-types.js +1 -0
- package/dist/lib/semantic-fact-manifest-shape.d.ts +4 -0
- package/dist/lib/semantic-fact-manifest-shape.js +135 -0
- package/dist/lib/semantic-fact-manifest-types.d.ts +58 -0
- package/dist/lib/semantic-fact-manifest-types.js +19 -0
- package/dist/lib/semantic-fact-policy-authority.d.ts +8 -0
- package/dist/lib/semantic-fact-policy-authority.js +79 -0
- package/dist/lib/semantic-fact-policy-census.d.ts +2 -0
- package/dist/lib/semantic-fact-policy-census.js +80 -0
- package/dist/lib/semantic-fact-policy-condition-references.d.ts +7 -0
- package/dist/lib/semantic-fact-policy-condition-references.js +19 -0
- package/dist/lib/semantic-fact-policy-conditions.d.ts +2 -0
- package/dist/lib/semantic-fact-policy-conditions.js +105 -0
- package/dist/lib/semantic-fact-policy-facts.d.ts +3 -0
- package/dist/lib/semantic-fact-policy-facts.js +73 -0
- package/dist/lib/semantic-fact-policy-primitives.d.ts +26 -0
- package/dist/lib/semantic-fact-policy-primitives.js +169 -0
- package/dist/lib/semantic-fact-policy-proofs.d.ts +2 -0
- package/dist/lib/semantic-fact-policy-proofs.js +75 -0
- package/dist/lib/semantic-fact-policy-properties.d.ts +3 -0
- package/dist/lib/semantic-fact-policy-properties.js +84 -0
- package/dist/lib/semantic-fact-policy-units.d.ts +4 -0
- package/dist/lib/semantic-fact-policy-units.js +103 -0
- package/dist/lib/semantic-fact-policy.d.ts +17 -0
- package/dist/lib/semantic-fact-policy.js +41 -0
- package/dist/lib/semantic-fact-proof-shape.d.ts +51 -0
- package/dist/lib/semantic-fact-proof-shape.js +121 -0
- package/dist/lib/semantic-fact-proof-types.d.ts +74 -0
- package/dist/lib/semantic-fact-proof-types.js +1 -0
- package/dist/lib/semantic-fact-property-shape.d.ts +29 -0
- package/dist/lib/semantic-fact-property-shape.js +77 -0
- package/dist/lib/semantic-fact-shape-constants.d.ts +3 -0
- package/dist/lib/semantic-fact-shape-constants.js +38 -0
- package/dist/lib/semantic-fact-shape-primitives.d.ts +15 -0
- package/dist/lib/semantic-fact-shape-primitives.js +68 -0
- package/dist/lib/semantic-fact-source-parser.d.ts +9 -0
- package/dist/lib/semantic-fact-source-parser.js +46 -0
- package/dist/lib/semantic-fact-support-shape.d.ts +21 -0
- package/dist/lib/semantic-fact-support-shape.js +59 -0
- package/dist/lib/semantic-fact-types.d.ts +5 -0
- package/dist/lib/semantic-fact-types.js +5 -0
- package/dist/lib/semantic-fact-unit-shape.d.ts +34 -0
- package/dist/lib/semantic-fact-unit-shape.js +89 -0
- package/dist/lib/semantic-fact-value-shape.d.ts +12 -0
- package/dist/lib/semantic-fact-value-shape.js +39 -0
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +1339 -131
- package/migrations/README.md +15 -15
- package/package.json +84 -84
- package/source-mappings.yaml +25 -25
|
@@ -20,6 +20,16 @@ export function generateClaims(outcome) {
|
|
|
20
20
|
claims.push(claim(outcome.key, `non_completing.${item.key}`, "non_completing", [], item.applicability_refs, "negative"));
|
|
21
21
|
for (const item of outcome.technical.obligations)
|
|
22
22
|
claims.push(claim(outcome.key, `obligation.${item.key}`, "obligation", item.required_proof_surfaces, item.applicability_refs));
|
|
23
|
+
for (const binding of outcome.semantic_fact_bindings?.facts ?? []) {
|
|
24
|
+
const requiredSurfaces = [
|
|
25
|
+
...new Set((outcome.semantic_fact_bindings?.proofs ?? [])
|
|
26
|
+
.filter((proof) => proof.fact_ref === binding.fact_ref)
|
|
27
|
+
.map((proof) => proof.proof_surface)),
|
|
28
|
+
];
|
|
29
|
+
claims.push(claim(outcome.key, binding.claim_ref, "semantic_fact", requiredSurfaces, [
|
|
30
|
+
binding.applicability_ref,
|
|
31
|
+
]));
|
|
32
|
+
}
|
|
23
33
|
for (const item of outcome.technical.forbidden_shortcuts)
|
|
24
34
|
claims.push(claim(outcome.key, `forbidden_shortcut.${item.key}`, "forbidden_shortcut", [], item.applicability_refs, "negative"));
|
|
25
35
|
return claims;
|
|
@@ -38,7 +48,9 @@ export function validateGlobalProofPolarity(claim, proof) {
|
|
|
38
48
|
export function validateProofSurface(claim, proof, outcomeKey) {
|
|
39
49
|
if (proof.polarity !== claim.required_polarity)
|
|
40
50
|
fail("claim_proof_polarity_mismatch", `${outcomeKey}:${claim.local_key}:${proof.polarity}:${claim.required_polarity}`);
|
|
41
|
-
if ((claim.kind === "requirement" ||
|
|
51
|
+
if ((claim.kind === "requirement" ||
|
|
52
|
+
claim.kind === "obligation" ||
|
|
53
|
+
claim.kind === "semantic_fact") &&
|
|
42
54
|
claim.required_proof_surfaces.length > 0 &&
|
|
43
55
|
!claim.required_proof_surfaces.includes(proof.proof_surface))
|
|
44
56
|
fail(`${claim.kind}_proof_surface_mismatch`, `${outcomeKey}:${claim.local_key}:${proof.proof_surface}`);
|
|
@@ -105,7 +105,8 @@ function compileOutcomeScope(contract, outcomeKey, claims, profiles, outcomeKeys
|
|
|
105
105
|
if (proof.assertion.observation === "playwright.passed" &&
|
|
106
106
|
(claim.kind === "requirement" ||
|
|
107
107
|
claim.kind === "control" ||
|
|
108
|
-
claim.kind === "control_relation"
|
|
108
|
+
claim.kind === "control_relation" ||
|
|
109
|
+
claim.kind === "semantic_fact"))
|
|
109
110
|
fail("fine_grained_claim_requires_ac_observation", `${outcomeKey}:${claim.local_key}`);
|
|
110
111
|
const applicabilityRef = validateAssertionApplicability(claim.applicability_refs, proof, profiles, outcomeKey);
|
|
111
112
|
const claimProof = {
|
|
@@ -119,6 +120,27 @@ function compileOutcomeScope(contract, outcomeKey, claims, profiles, outcomeKeys
|
|
|
119
120
|
validateClaimAssertionOperator(claim, proof.assertion, proof.check.proof_surface, outcomeKey, proof.check.key);
|
|
120
121
|
addProof(proofs, claimKey, claimProof);
|
|
121
122
|
}
|
|
123
|
+
for (const binding of outcome.semantic_fact_bindings.proofs) {
|
|
124
|
+
if (binding.authority !== "external_confirmation")
|
|
125
|
+
continue;
|
|
126
|
+
const factBinding = outcome.semantic_fact_bindings.facts.find((item) => item.fact_ref === binding.fact_ref);
|
|
127
|
+
if (!factBinding)
|
|
128
|
+
fail("semantic_fact_external_fact_binding_missing", `${outcomeKey}:${binding.proof_ref}:${binding.fact_ref}`);
|
|
129
|
+
const claim = claimMap.get(factBinding.claim_ref);
|
|
130
|
+
if (!claim)
|
|
131
|
+
fail("semantic_fact_external_claim_unknown", `${outcomeKey}:${factBinding.claim_ref}`);
|
|
132
|
+
const confirmation = contract.global.acceptance.external_confirmations.find((item) => item.key === binding.confirmation_ref);
|
|
133
|
+
const fullClaim = `${outcomeKey}.${factBinding.claim_ref}`;
|
|
134
|
+
if (!confirmation || !confirmation.impact_claims.includes(fullClaim))
|
|
135
|
+
fail("semantic_fact_external_confirmation_invalid", `${outcomeKey}:${binding.confirmation_ref}:${fullClaim}`);
|
|
136
|
+
addProof(proofs, factBinding.claim_ref, {
|
|
137
|
+
check_key: `EXTERNAL.${binding.confirmation_ref}`,
|
|
138
|
+
assertion_key: null,
|
|
139
|
+
polarity: "positive",
|
|
140
|
+
proof_surface: binding.proof_surface,
|
|
141
|
+
applicability_ref: factBinding.applicability_ref,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
122
144
|
validatePopulationReferences(outcome, claimMap);
|
|
123
145
|
validateCounterfactualReferences(outcome, claimMap);
|
|
124
146
|
validateProfileUse(outcomeKey, profiles, claims);
|
|
@@ -3,6 +3,7 @@ import type { CounterfactualControlV2, GlobalCounterfactualControlV2 } from "./l
|
|
|
3
3
|
import type { DeliveryControlFieldNameV2 } from "./long-task-control-types.js";
|
|
4
4
|
import type { ApplicableKeyedStatementV2, CheckExecutionTargetV2, ClaimApplicabilityV2, DeliveryJourneyRoleV2, DeliveryScenarioV2, DeliveryStageV2, EvidenceCapabilityV2, ExecutionTargetV2, ExternalConfirmationKindV2, KeyedStatementV2, TargetProfileV2 } from "./long-task-semantic-contract-types.js";
|
|
5
5
|
import type { DeliverySurfaceBindingV2 } from "./long-task-ui-surface-types.js";
|
|
6
|
+
import type { SemanticFactManifestRefV2, SemanticFactOutcomeBindingsV2 } from "./semantic-fact-types.js";
|
|
6
7
|
export type SourceClaimDispositionV2 = {
|
|
7
8
|
type: "claim";
|
|
8
9
|
refs: string[];
|
|
@@ -195,6 +196,7 @@ export interface DeliveryOutcomeV2 {
|
|
|
195
196
|
stage: string;
|
|
196
197
|
depends_on: string[];
|
|
197
198
|
applicability: ClaimApplicabilityV2[];
|
|
199
|
+
semantic_fact_bindings: SemanticFactOutcomeBindingsV2;
|
|
198
200
|
product: {
|
|
199
201
|
observable_result: string;
|
|
200
202
|
result_applicability_refs: string[];
|
|
@@ -226,6 +228,7 @@ export interface DeliveryOutcomeV2 {
|
|
|
226
228
|
}
|
|
227
229
|
export interface DeliveryContractV2 {
|
|
228
230
|
schema_version: "long-task-delivery-v2";
|
|
231
|
+
semantic_fact_manifest: SemanticFactManifestRefV2;
|
|
229
232
|
task: {
|
|
230
233
|
id: string;
|
|
231
234
|
title: string;
|
|
@@ -129,6 +129,7 @@ export async function compileDeliveryContract(workdirInput, projectRootInput = p
|
|
|
129
129
|
authority_materials: authorityMaterials,
|
|
130
130
|
authority_revision: authorityRevision,
|
|
131
131
|
claim_coverage: claims.summary,
|
|
132
|
+
semantic_fact_manifest: contract.semantic_fact_manifest,
|
|
132
133
|
task: contract.task,
|
|
133
134
|
risk: contract.risk,
|
|
134
135
|
source_claims: contract.source_claims,
|
|
@@ -6,6 +6,7 @@ import { parseOutcome, parseOutcomeFragment, safeFragmentPath, } from "./long-ta
|
|
|
6
6
|
import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
|
|
7
7
|
import { array, literal, object, parseSourceClaims, strings, } from "./long-task-delivery-shape.js";
|
|
8
8
|
import { parseGlobal, parseRisk, parseStages, parseTask, } from "./long-task-root-shape.js";
|
|
9
|
+
import { parseSemanticFactManifestRef } from "./long-task-semantic-fact-shape.js";
|
|
9
10
|
import { repositoryRoot } from "./long-task-workspace.js";
|
|
10
11
|
import { assertNoSemanticDriftMigration, semanticDriftMigrationFields, } from "./long-task-semantic-drift-migration.js";
|
|
11
12
|
export const DELIVERY_CONTRACT_FILE = "delivery-contract.yaml";
|
|
@@ -77,12 +78,21 @@ function parseRoot(raw, bundle) {
|
|
|
77
78
|
"long-task-delivery-v1")
|
|
78
79
|
throw new Error("long_task_delivery_v1_retired_use_v2");
|
|
79
80
|
assertNoSemanticDriftMigration(semanticDriftMigrationFields(decoded));
|
|
80
|
-
return object(decoded, "$", [
|
|
81
|
+
return object(decoded, "$", [
|
|
82
|
+
"schema_version",
|
|
83
|
+
"semantic_fact_manifest",
|
|
84
|
+
"task",
|
|
85
|
+
"source_claims",
|
|
86
|
+
"stages",
|
|
87
|
+
"risk",
|
|
88
|
+
"global",
|
|
89
|
+
], bundle ? ["outcomes", "outcome_files"] : ["outcomes"]);
|
|
81
90
|
}
|
|
82
91
|
function parseContractRoot(root, outcomes) {
|
|
83
92
|
literal(root.schema_version, ["long-task-delivery-v2"], "schema_version");
|
|
84
93
|
return {
|
|
85
94
|
schema_version: "long-task-delivery-v2",
|
|
95
|
+
semantic_fact_manifest: parseSemanticFactManifestRef(root.semantic_fact_manifest, "semantic_fact_manifest"),
|
|
86
96
|
task: parseTask(root.task),
|
|
87
97
|
source_claims: parseSourceClaims(root.source_claims, "source_claims"),
|
|
88
98
|
stages: parseStages(root.stages),
|
|
@@ -76,6 +76,23 @@ function validateUniqueKeys(contract, report) {
|
|
|
76
76
|
...contract.global.technical.forbidden_shortcuts,
|
|
77
77
|
].map((item) => item.key), "global_constraint_key_duplicate", report);
|
|
78
78
|
for (const outcome of contract.outcomes) {
|
|
79
|
+
if (outcome.semantic_fact_bindings.manifest_ref !==
|
|
80
|
+
contract.semantic_fact_manifest.key)
|
|
81
|
+
issue(report, "semantic_fact_manifest_ref_mismatch", outcome.key);
|
|
82
|
+
if (!outcome.semantic_fact_bindings.facts.length)
|
|
83
|
+
issue(report, "semantic_fact_binding_required", outcome.key);
|
|
84
|
+
if (!outcome.semantic_fact_bindings.proofs.length)
|
|
85
|
+
issue(report, "semantic_fact_proof_binding_required", outcome.key);
|
|
86
|
+
unique(outcome.semantic_fact_bindings.facts.map((item) => item.fact_ref), `semantic_fact_ref_duplicate:${outcome.key}`, report);
|
|
87
|
+
unique(outcome.semantic_fact_bindings.facts.map((item) => item.claim_ref), `semantic_fact_claim_duplicate:${outcome.key}`, report);
|
|
88
|
+
unique(outcome.semantic_fact_bindings.proofs.map((item) => item.proof_ref), `semantic_fact_proof_duplicate:${outcome.key}`, report);
|
|
89
|
+
const semanticFacts = new Set(outcome.semantic_fact_bindings.facts.map((item) => item.fact_ref));
|
|
90
|
+
for (const proof of outcome.semantic_fact_bindings.proofs)
|
|
91
|
+
if (!semanticFacts.has(proof.fact_ref))
|
|
92
|
+
issue(report, "semantic_fact_proof_fact_unknown", `${outcome.key}:${proof.proof_ref}:${proof.fact_ref}`);
|
|
93
|
+
for (const fact of semanticFacts)
|
|
94
|
+
if (!outcome.semantic_fact_bindings.proofs.some((proof) => proof.fact_ref === fact))
|
|
95
|
+
issue(report, "semantic_fact_proof_required", `${outcome.key}:${fact}`);
|
|
79
96
|
unique(outcome.acceptance.checks.map((check) => check.key), `check_key_duplicate:${outcome.key}`, report);
|
|
80
97
|
unique(outcome.product.requirements.map((item) => item.key), `requirement_key_duplicate:${outcome.key}`, report);
|
|
81
98
|
unique(outcome.product.controls.map((control) => control.key), `control_key_duplicate:${outcome.key}`, report);
|
|
@@ -2,6 +2,7 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { containsDesignResourceHandoff } from "./design-resource-handoff-parser.js";
|
|
4
4
|
import { preflightDesignResourceHandoff } from "./design-resource-handoff-validation.js";
|
|
5
|
+
import { validateLongTaskDesignTargetCapabilities } from "./long-task-design-target-capabilities.js";
|
|
5
6
|
import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
|
|
6
7
|
export async function validateLongTaskDesignResourceHandoffs(contract, repository) {
|
|
7
8
|
const handoffs = await loadHandoffs(contract, repository);
|
|
@@ -18,7 +19,7 @@ export async function validateLongTaskDesignResourceHandoffs(contract, repositor
|
|
|
18
19
|
invalid("target_handoff_missing", contractTarget.target.key);
|
|
19
20
|
consumed.add(contractTarget.target.key);
|
|
20
21
|
validateTargetIdentity(contractTarget, indexedTarget);
|
|
21
|
-
|
|
22
|
+
validateLongTaskDesignTargetCapabilities(contract, contractTarget, indexedTarget);
|
|
22
23
|
validateCoverageClaims(contract, contractTarget, indexedTarget);
|
|
23
24
|
validateBlockerBindings(contract, contractTarget, indexedTarget);
|
|
24
25
|
}
|
|
@@ -68,6 +69,8 @@ function validateCoverageClaims(contract, contractTarget, indexed) {
|
|
|
68
69
|
if (!rows.length)
|
|
69
70
|
invalid("target_covered_claims_required", target.key);
|
|
70
71
|
const facts = indexed.preflight.handoff.facts.filter((fact) => fact.target_ref === target.key);
|
|
72
|
+
const factRefs = new Set(facts.map((fact) => fact.key));
|
|
73
|
+
const proofs = indexed.preflight.handoff.proof_obligations.filter((proof) => factRefs.has(proof.fact_ref));
|
|
71
74
|
if (!facts.length)
|
|
72
75
|
invalid("target_facts_required", target.key);
|
|
73
76
|
const claimsBySourceItem = new Map();
|
|
@@ -76,7 +79,7 @@ function validateCoverageClaims(contract, contractTarget, indexed) {
|
|
|
76
79
|
const localClaims = designSourceItemClaims(contract, contractTarget, indexed, sourceItemRef, claims);
|
|
77
80
|
claimsBySourceItem.set(sourceItemRef, localClaims);
|
|
78
81
|
}
|
|
79
|
-
validateVerificationMethodBindings(target, check, facts, claimsBySourceItem);
|
|
82
|
+
validateVerificationMethodBindings(target, check, facts, proofs, indexed, claimsBySourceItem);
|
|
80
83
|
}
|
|
81
84
|
function validateBlockerBindings(contract, contractTarget, indexed) {
|
|
82
85
|
const bound = new Map(contractTarget.binding.acceptance_blockers.map((item) => [item.key, item]));
|
|
@@ -140,8 +143,8 @@ function designSourceItemClaims(contract, contractTarget, indexed, sourceItemRef
|
|
|
140
143
|
return claimRef.slice(prefix.length);
|
|
141
144
|
});
|
|
142
145
|
}
|
|
143
|
-
function validateVerificationMethodBindings(target, check, facts, claimsBySourceItem) {
|
|
144
|
-
const expectedMethods = new Set(
|
|
146
|
+
function validateVerificationMethodBindings(target, check, facts, proofs, indexed, claimsBySourceItem) {
|
|
147
|
+
const expectedMethods = new Set(proofs.map((proof) => proof.method));
|
|
145
148
|
const bindings = target.verification_method_bindings;
|
|
146
149
|
assertSameSet(bindings.map((item) => item.method), [...expectedMethods], "verification_methods_mismatch", target.key);
|
|
147
150
|
const assertionRefs = bindings.map((item) => item.assertion_ref);
|
|
@@ -155,7 +158,7 @@ function validateVerificationMethodBindings(target, check, facts, claimsBySource
|
|
|
155
158
|
if (!assertion)
|
|
156
159
|
invalid("verification_method_assertion_unknown", `${target.key}:${binding.method}:${binding.assertion_ref}`);
|
|
157
160
|
const sourceItems = new Set(facts
|
|
158
|
-
.filter((fact) => fact.
|
|
161
|
+
.filter((fact) => proofs.some((proof) => proof.fact_ref === fact.key && proof.method === binding.method))
|
|
159
162
|
.flatMap((fact) => fact.source_item_refs));
|
|
160
163
|
for (const sourceItemRef of sourceItems)
|
|
161
164
|
for (const claimRef of claimsBySourceItem.get(sourceItemRef) ?? [])
|
|
@@ -167,15 +170,67 @@ function validateVerificationMethodBindings(target, check, facts, claimsBySource
|
|
|
167
170
|
assertSameSet(binding.evidence_artifacts.map((item) => item.condition_key), target.condition_keys, "verification_method_evidence_conditions_mismatch", `${target.key}:${binding.method}`);
|
|
168
171
|
for (const artifact of binding.evidence_artifacts) {
|
|
169
172
|
const expectedFactRefs = facts
|
|
170
|
-
.filter((fact) => fact.
|
|
171
|
-
fact.condition_ref === artifact.condition_key)
|
|
173
|
+
.filter((fact) => proofs.some((proof) => proof.fact_ref === fact.key && proof.method === binding.method) && fact.condition_ref === artifact.condition_key)
|
|
172
174
|
.map((fact) => fact.key);
|
|
173
175
|
assertSameSet(artifact.fact_refs, expectedFactRefs, "design_method_fact_refs_mismatch", `${target.key}:${binding.method}:${artifact.condition_key}`);
|
|
176
|
+
const expectedFactExpectations = proofs
|
|
177
|
+
.filter((proof) => proof.method === binding.method &&
|
|
178
|
+
facts.some((fact) => fact.key === proof.fact_ref &&
|
|
179
|
+
fact.condition_ref === artifact.condition_key))
|
|
180
|
+
.map((proof) => designFactExpectation(indexed, proof.fact_ref, proof.key));
|
|
181
|
+
assertSameSet(artifact.fact_expectations.map((item) => item.fact_ref), expectedFactRefs, "design_method_fact_expectation_refs_mismatch", `${target.key}:${binding.method}:${artifact.condition_key}`);
|
|
182
|
+
assertCanonicalRows(artifact.fact_expectations, expectedFactExpectations, "design_method_fact_expectations_mismatch", `${target.key}:${binding.method}:${artifact.condition_key}`);
|
|
174
183
|
boundFactRefs.push(...artifact.fact_refs);
|
|
175
184
|
}
|
|
176
185
|
}
|
|
177
186
|
assertSameSet(boundFactRefs, facts.map((fact) => fact.key), "design_method_fact_refs_mismatch", target.key);
|
|
178
187
|
}
|
|
188
|
+
function designFactExpectation(indexed, factRef, proofRef) {
|
|
189
|
+
const handoff = indexed.preflight.handoff;
|
|
190
|
+
const fact = handoff.facts.find((item) => item.key === factRef);
|
|
191
|
+
const proof = handoff.proof_obligations.find((item) => item.key === proofRef);
|
|
192
|
+
const oracle = handoff.oracles.find((item) => item.key === proof.oracle_ref);
|
|
193
|
+
const environment = handoff.environments.find((item) => item.key === proof.environment_ref);
|
|
194
|
+
return {
|
|
195
|
+
fact_ref: fact.key,
|
|
196
|
+
subject_ref: fact.subject_ref,
|
|
197
|
+
variation_ref: fact.variation_ref,
|
|
198
|
+
property_ref: fact.property_ref,
|
|
199
|
+
observation_sensitivity: fact.observation_sensitivity,
|
|
200
|
+
expected: fact.value,
|
|
201
|
+
comparison: proof.comparison,
|
|
202
|
+
oracle: {
|
|
203
|
+
key: oracle.key,
|
|
204
|
+
trust: oracle.trust,
|
|
205
|
+
identity: oracle.identity,
|
|
206
|
+
version: oracle.version,
|
|
207
|
+
sha256: oracle.sha256,
|
|
208
|
+
},
|
|
209
|
+
environment: {
|
|
210
|
+
key: environment.key,
|
|
211
|
+
identity: environment.identity,
|
|
212
|
+
definition: environment.definition,
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function assertCanonicalRows(actual, expected, code, detail) {
|
|
217
|
+
const left = new Map(actual.map((item) => [item.fact_ref, canonicalJson(item)]));
|
|
218
|
+
const right = new Map(expected.map((item) => [item.fact_ref, canonicalJson(item)]));
|
|
219
|
+
assertSameSet([...left.keys()], [...right.keys()], code, detail);
|
|
220
|
+
for (const [key, value] of right)
|
|
221
|
+
if (left.get(key) !== value)
|
|
222
|
+
invalid(code, `${detail}:${key}`);
|
|
223
|
+
}
|
|
224
|
+
function canonicalJson(value) {
|
|
225
|
+
if (Array.isArray(value))
|
|
226
|
+
return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
|
|
227
|
+
if (value && typeof value === "object")
|
|
228
|
+
return `{${Object.entries(value)
|
|
229
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
230
|
+
.map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`)
|
|
231
|
+
.join(",")}}`;
|
|
232
|
+
return JSON.stringify(value);
|
|
233
|
+
}
|
|
179
234
|
function requiredCapabilities(method) {
|
|
180
235
|
if (method === "interaction_trace")
|
|
181
236
|
return ["design_method", "interaction_trace", "target_runtime"];
|
|
@@ -188,37 +243,6 @@ function requiredCapabilities(method) {
|
|
|
188
243
|
];
|
|
189
244
|
return ["design_method", "design_conformance", "target_runtime"];
|
|
190
245
|
}
|
|
191
|
-
function validateTargetCapabilities(contract, contractTarget, indexed) {
|
|
192
|
-
const executionTarget = contract.task.execution_targets.find((item) => item.key === contractTarget.binding.target_ref);
|
|
193
|
-
if (!executionTarget)
|
|
194
|
-
invalid("execution_target_unknown", `${contractTarget.target.key}:${contractTarget.binding.target_ref}`);
|
|
195
|
-
const required = new Set();
|
|
196
|
-
for (const method of contractTarget.target.verification_method_bindings.map((item) => item.method)) {
|
|
197
|
-
if (method === "responsive_reflow")
|
|
198
|
-
required.add("viewport-control");
|
|
199
|
-
if (method === "motion_timeline")
|
|
200
|
-
required.add("motion-observation");
|
|
201
|
-
if (method === "accessibility_semantics")
|
|
202
|
-
required.add("assistive-technology");
|
|
203
|
-
}
|
|
204
|
-
for (const conditionRef of indexed.target.condition_refs) {
|
|
205
|
-
const condition = indexed.preflight.handoff.conditions.find((item) => item.key === conditionRef);
|
|
206
|
-
const input = condition.input_methods[0].toLowerCase();
|
|
207
|
-
if (["mouse", "pointer", "trackpad"].includes(input))
|
|
208
|
-
required.add("pointer-input");
|
|
209
|
-
if (input === "keyboard")
|
|
210
|
-
required.add("keyboard-input");
|
|
211
|
-
if (["touch", "pen", "stylus"].includes(input))
|
|
212
|
-
required.add("touch-input");
|
|
213
|
-
if (["screen-reader", "voice-control", "switch-control"].includes(input))
|
|
214
|
-
required.add("assistive-technology");
|
|
215
|
-
if (condition.motion === "reduced")
|
|
216
|
-
required.add("reduced-motion");
|
|
217
|
-
}
|
|
218
|
-
for (const capability of required)
|
|
219
|
-
if (!executionTarget.capabilities.includes(capability))
|
|
220
|
-
invalid("execution_target_capability_missing", `${contractTarget.target.key}:${executionTarget.key}:${capability}`);
|
|
221
|
-
}
|
|
222
246
|
function assertSameSet(actual, expected, code, detail) {
|
|
223
247
|
const left = [...new Set(actual)].sort();
|
|
224
248
|
const right = [...new Set(expected)].sort();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DesignResourceHandoffPreflightV1, DesignResourceHandoffTargetV1 } from "./design-resource-handoff-types.js";
|
|
2
|
+
import type { DeliveryContractV2 } from "./long-task-delivery-types.js";
|
|
3
|
+
type ContractDesignTarget = DeliveryContractV2["outcomes"][number]["product"]["surface_bindings"][number]["design_targets"][number];
|
|
4
|
+
type ContractSurfaceBinding = DeliveryContractV2["outcomes"][number]["product"]["surface_bindings"][number];
|
|
5
|
+
interface ContractDesignTargetBinding {
|
|
6
|
+
binding: ContractSurfaceBinding;
|
|
7
|
+
target: ContractDesignTarget;
|
|
8
|
+
}
|
|
9
|
+
interface IndexedHandoffTarget {
|
|
10
|
+
preflight: DesignResourceHandoffPreflightV1;
|
|
11
|
+
target: DesignResourceHandoffTargetV1;
|
|
12
|
+
}
|
|
13
|
+
export declare function validateLongTaskDesignTargetCapabilities(contract: DeliveryContractV2, contractTarget: ContractDesignTargetBinding, indexed: IndexedHandoffTarget): void;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const METHOD_CAPABILITIES = {
|
|
2
|
+
responsive_reflow: "viewport-control",
|
|
3
|
+
motion_timeline: "motion-observation",
|
|
4
|
+
accessibility_semantics: "assistive-technology",
|
|
5
|
+
accessibility_navigation: "assistive-technology",
|
|
6
|
+
accessibility_visual: "assistive-technology",
|
|
7
|
+
localization: "localization-control",
|
|
8
|
+
system_ui: "system-ui-observation",
|
|
9
|
+
haptic_feedback: "haptic-output",
|
|
10
|
+
sound_feedback: "audio-output",
|
|
11
|
+
};
|
|
12
|
+
const INPUT_CAPABILITIES = {
|
|
13
|
+
mouse: "pointer-input",
|
|
14
|
+
pointer: "pointer-input",
|
|
15
|
+
trackpad: "pointer-input",
|
|
16
|
+
keyboard: "keyboard-input",
|
|
17
|
+
touch: "touch-input",
|
|
18
|
+
pen: "touch-input",
|
|
19
|
+
stylus: "touch-input",
|
|
20
|
+
"screen-reader": "assistive-technology",
|
|
21
|
+
"voice-control": "assistive-technology",
|
|
22
|
+
"switch-control": "assistive-technology",
|
|
23
|
+
};
|
|
24
|
+
const CONDITION_RULES = [
|
|
25
|
+
{
|
|
26
|
+
capability: "assistive-technology",
|
|
27
|
+
applies: (item) => item.assistive_technology !== "not-applicable",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
capability: "reduced-motion",
|
|
31
|
+
applies: (item) => item.motion === "reduced",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
capability: "reduced-transparency",
|
|
35
|
+
applies: (item) => item.transparency === "reduced",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
capability: "increased-contrast",
|
|
39
|
+
applies: (item) => item.contrast === "increased",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
capability: "bold-text-control",
|
|
43
|
+
applies: (item) => item.bold_text === "enabled",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
capability: "button-shapes-control",
|
|
47
|
+
applies: (item) => item.button_shapes === "enabled",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
capability: "system-ui-observation",
|
|
51
|
+
applies: (item) => item.system_ui !== "not-applicable",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
capability: "ime-control",
|
|
55
|
+
applies: (item) => item.ime !== "not-applicable",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
capability: "permission-control",
|
|
59
|
+
applies: (item) => item.permission !== "not-applicable",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
capability: "network-state-control",
|
|
63
|
+
applies: (item) => item.connectivity !== "not-applicable",
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
capability: "lifecycle-control",
|
|
67
|
+
applies: (item) => item.lifecycle !== "not-applicable",
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
export function validateLongTaskDesignTargetCapabilities(contract, contractTarget, indexed) {
|
|
71
|
+
const executionTarget = contract.task.execution_targets.find((item) => item.key === contractTarget.binding.target_ref);
|
|
72
|
+
if (!executionTarget)
|
|
73
|
+
invalid("execution_target_unknown", `${contractTarget.target.key}:${contractTarget.binding.target_ref}`);
|
|
74
|
+
const required = requiredTargetCapabilities(contractTarget.target, indexed);
|
|
75
|
+
for (const capability of required)
|
|
76
|
+
if (!executionTarget.capabilities.includes(capability))
|
|
77
|
+
invalid("execution_target_capability_missing", `${contractTarget.target.key}:${executionTarget.key}:${capability}`);
|
|
78
|
+
}
|
|
79
|
+
function requiredTargetCapabilities(target, indexed) {
|
|
80
|
+
const required = new Set();
|
|
81
|
+
addMethodCapabilities(required, target);
|
|
82
|
+
const conditions = indexed.target.condition_refs.map((conditionRef) => indexed.preflight.handoff.conditions.find((item) => item.key === conditionRef));
|
|
83
|
+
addVaryingConditionCapabilities(required, conditions);
|
|
84
|
+
addPerConditionCapabilities(required, conditions);
|
|
85
|
+
return required;
|
|
86
|
+
}
|
|
87
|
+
function addMethodCapabilities(required, target) {
|
|
88
|
+
for (const binding of target.verification_method_bindings) {
|
|
89
|
+
const capability = METHOD_CAPABILITIES[binding.method];
|
|
90
|
+
if (capability)
|
|
91
|
+
required.add(capability);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function addVaryingConditionCapabilities(required, conditions) {
|
|
95
|
+
addIfVaries(required, conditions, "viewport-control", (item) => item.viewport.key);
|
|
96
|
+
addIfSome(required, conditions, "pixel-density-observation", (item) => item.density.key !== "not-applicable");
|
|
97
|
+
addIfSome(required, conditions, "safe-area-observation", (item) => item.safe_area.key !== "not-applicable");
|
|
98
|
+
addIfVaries(required, conditions, "color-scheme-control", (item) => item.color_scheme);
|
|
99
|
+
addIfVaries(required, conditions, "text-scale-control", (item) => item.text_scale.key);
|
|
100
|
+
addIfVaries(required, conditions, "localization-control", (item) => item.locale);
|
|
101
|
+
addIfSome(required, conditions, "rtl-control", (item) => item.direction === "rtl");
|
|
102
|
+
addIfVaries(required, conditions, "device-orientation", (item) => item.orientation);
|
|
103
|
+
addIfVaries(required, conditions, "window-state-control", (item) => item.window_state);
|
|
104
|
+
addIfVaries(required, conditions, "fold-state-control", (item) => item.fold_state);
|
|
105
|
+
}
|
|
106
|
+
function addPerConditionCapabilities(required, conditions) {
|
|
107
|
+
for (const condition of conditions) {
|
|
108
|
+
const inputCapability = INPUT_CAPABILITIES[condition.input_method.toLowerCase()];
|
|
109
|
+
if (inputCapability)
|
|
110
|
+
required.add(inputCapability);
|
|
111
|
+
for (const rule of CONDITION_RULES)
|
|
112
|
+
if (rule.applies(condition))
|
|
113
|
+
required.add(rule.capability);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function addIfVaries(required, conditions, capability, value) {
|
|
117
|
+
if (new Set(conditions.map(value)).size > 1)
|
|
118
|
+
required.add(capability);
|
|
119
|
+
}
|
|
120
|
+
function addIfSome(required, conditions, capability, predicate) {
|
|
121
|
+
if (conditions.some(predicate))
|
|
122
|
+
required.add(capability);
|
|
123
|
+
}
|
|
124
|
+
function invalid(code, detail) {
|
|
125
|
+
throw new Error(`delivery_contract_invalid:design_resource_${code}:${detail}`);
|
|
126
|
+
}
|
|
@@ -1,2 +1,96 @@
|
|
|
1
1
|
import type { EvidenceCapabilityRecordV2 } from "./long-task-delivery-types.js";
|
|
2
2
|
export declare function decodeEvidenceCapabilityRecords(value: unknown): EvidenceCapabilityRecordV2[];
|
|
3
|
+
export declare function decodeDesignFactResults(value: unknown, label: string): {
|
|
4
|
+
fact_ref: string;
|
|
5
|
+
subject_ref: string;
|
|
6
|
+
variation_ref: string;
|
|
7
|
+
property_ref: string;
|
|
8
|
+
actual_observation: {
|
|
9
|
+
artifact_path: string;
|
|
10
|
+
artifact_sha256: string;
|
|
11
|
+
locator: {
|
|
12
|
+
kind: "asset_ref" | "custom" | "image_region" | "json_pointer" | "semantic_node" | "timeline_sample" | "trace_event";
|
|
13
|
+
value: string;
|
|
14
|
+
};
|
|
15
|
+
value_sha256: string;
|
|
16
|
+
sensitivity: "plain" | "protected";
|
|
17
|
+
redaction: {
|
|
18
|
+
policy_ref: string;
|
|
19
|
+
representation: "digest_only" | "redacted_structured";
|
|
20
|
+
raw_persisted: false;
|
|
21
|
+
} | null;
|
|
22
|
+
};
|
|
23
|
+
actual_environment: {
|
|
24
|
+
artifact_path: string;
|
|
25
|
+
artifact_sha256: string;
|
|
26
|
+
locator: {
|
|
27
|
+
kind: "asset_ref" | "custom" | "image_region" | "json_pointer" | "semantic_node" | "timeline_sample" | "trace_event";
|
|
28
|
+
value: string;
|
|
29
|
+
};
|
|
30
|
+
value_sha256: string;
|
|
31
|
+
};
|
|
32
|
+
expected: {
|
|
33
|
+
locator: {
|
|
34
|
+
resource_ref: string;
|
|
35
|
+
kind: "css_custom_property" | "css_declaration" | "css_selector" | "html_attribute" | "html_inner_html" | "html_selector" | "javascript_export" | "json_pointer" | "markdown_anchor" | "svg_attribute" | "svg_inner_xml" | "svg_selector" | "whole_resource";
|
|
36
|
+
value: string;
|
|
37
|
+
};
|
|
38
|
+
sha256: string;
|
|
39
|
+
};
|
|
40
|
+
comparison: {
|
|
41
|
+
artifact_path: string;
|
|
42
|
+
artifact_sha256: string;
|
|
43
|
+
locator: {
|
|
44
|
+
kind: "asset_ref" | "custom" | "image_region" | "json_pointer" | "semantic_node" | "timeline_sample" | "trace_event";
|
|
45
|
+
value: string;
|
|
46
|
+
};
|
|
47
|
+
result_sha256: string;
|
|
48
|
+
comparator: string;
|
|
49
|
+
mode: "exact" | "tolerance";
|
|
50
|
+
parameters: {
|
|
51
|
+
locator: {
|
|
52
|
+
resource_ref: string;
|
|
53
|
+
kind: "css_custom_property" | "css_declaration" | "css_selector" | "html_attribute" | "html_inner_html" | "html_selector" | "javascript_export" | "json_pointer" | "markdown_anchor" | "svg_attribute" | "svg_inner_xml" | "svg_selector" | "whole_resource";
|
|
54
|
+
value: string;
|
|
55
|
+
};
|
|
56
|
+
sha256: string;
|
|
57
|
+
};
|
|
58
|
+
tolerance: {
|
|
59
|
+
locator: {
|
|
60
|
+
resource_ref: string;
|
|
61
|
+
kind: "css_custom_property" | "css_declaration" | "css_selector" | "html_attribute" | "html_inner_html" | "html_selector" | "javascript_export" | "json_pointer" | "markdown_anchor" | "svg_attribute" | "svg_inner_xml" | "svg_selector" | "whole_resource";
|
|
62
|
+
value: string;
|
|
63
|
+
};
|
|
64
|
+
sha256: string;
|
|
65
|
+
} | null;
|
|
66
|
+
mask: {
|
|
67
|
+
locator: {
|
|
68
|
+
resource_ref: string;
|
|
69
|
+
kind: "css_custom_property" | "css_declaration" | "css_selector" | "html_attribute" | "html_inner_html" | "html_selector" | "javascript_export" | "json_pointer" | "markdown_anchor" | "svg_attribute" | "svg_inner_xml" | "svg_selector" | "whole_resource";
|
|
70
|
+
value: string;
|
|
71
|
+
};
|
|
72
|
+
sha256: string;
|
|
73
|
+
} | null;
|
|
74
|
+
passed: boolean;
|
|
75
|
+
};
|
|
76
|
+
verdict: "failed" | "passed";
|
|
77
|
+
oracle: {
|
|
78
|
+
key: string;
|
|
79
|
+
trust: "frozen_executable" | "named_external_tcb";
|
|
80
|
+
identity: string;
|
|
81
|
+
version: string;
|
|
82
|
+
sha256: string | null;
|
|
83
|
+
};
|
|
84
|
+
environment: {
|
|
85
|
+
key: string;
|
|
86
|
+
identity: string;
|
|
87
|
+
definition: {
|
|
88
|
+
locator: {
|
|
89
|
+
resource_ref: string;
|
|
90
|
+
kind: "css_custom_property" | "css_declaration" | "css_selector" | "html_attribute" | "html_inner_html" | "html_selector" | "javascript_export" | "json_pointer" | "markdown_anchor" | "svg_attribute" | "svg_inner_xml" | "svg_selector" | "whole_resource";
|
|
91
|
+
value: string;
|
|
92
|
+
};
|
|
93
|
+
sha256: string;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
}[];
|