@dailephd/my-frontend-observer 0.8.1
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/CHANGELOG.md +397 -0
- package/LICENSE +21 -0
- package/README.md +255 -0
- package/dist/application/browserCaptureService.d.ts +11 -0
- package/dist/application/browserCaptureService.js +12 -0
- package/dist/application/browserCaptureService.js.map +1 -0
- package/dist/application/comparisonService.d.ts +56 -0
- package/dist/application/comparisonService.js +77 -0
- package/dist/application/comparisonService.js.map +1 -0
- package/dist/application/externalReferencePersistenceService.d.ts +75 -0
- package/dist/application/externalReferencePersistenceService.js +182 -0
- package/dist/application/externalReferencePersistenceService.js.map +1 -0
- package/dist/application/frontendContractEvaluationService.d.ts +49 -0
- package/dist/application/frontendContractEvaluationService.js +112 -0
- package/dist/application/frontendContractEvaluationService.js.map +1 -0
- package/dist/application/frontendContractPersistenceService.d.ts +56 -0
- package/dist/application/frontendContractPersistenceService.js +91 -0
- package/dist/application/frontendContractPersistenceService.js.map +1 -0
- package/dist/application/observationPersistence.d.ts +59 -0
- package/dist/application/observationPersistence.js +79 -0
- package/dist/application/observationPersistence.js.map +1 -0
- package/dist/application/projectCheckService.d.ts +3 -0
- package/dist/application/projectCheckService.js +169 -0
- package/dist/application/projectCheckService.js.map +1 -0
- package/dist/application/projectWorkflowService.d.ts +46 -0
- package/dist/application/projectWorkflowService.js +92 -0
- package/dist/application/projectWorkflowService.js.map +1 -0
- package/dist/application/referenceFidelityEvaluationService.d.ts +28 -0
- package/dist/application/referenceFidelityEvaluationService.js +45 -0
- package/dist/application/referenceFidelityEvaluationService.js.map +1 -0
- package/dist/artifacts/artifactReader.d.ts +19 -0
- package/dist/artifacts/artifactReader.js +36 -0
- package/dist/artifacts/artifactReader.js.map +1 -0
- package/dist/artifacts/artifactWriter.d.ts +25 -0
- package/dist/artifacts/artifactWriter.js +68 -0
- package/dist/artifacts/artifactWriter.js.map +1 -0
- package/dist/artifacts/comparisonArtifactReader.d.ts +18 -0
- package/dist/artifacts/comparisonArtifactReader.js +35 -0
- package/dist/artifacts/comparisonArtifactReader.js.map +1 -0
- package/dist/artifacts/comparisonArtifactWriter.d.ts +41 -0
- package/dist/artifacts/comparisonArtifactWriter.js +67 -0
- package/dist/artifacts/comparisonArtifactWriter.js.map +1 -0
- package/dist/artifacts/externalReferenceArtifactReader.d.ts +18 -0
- package/dist/artifacts/externalReferenceArtifactReader.js +35 -0
- package/dist/artifacts/externalReferenceArtifactReader.js.map +1 -0
- package/dist/artifacts/externalReferenceArtifactWriter.d.ts +44 -0
- package/dist/artifacts/externalReferenceArtifactWriter.js +77 -0
- package/dist/artifacts/externalReferenceArtifactWriter.js.map +1 -0
- package/dist/artifacts/frontendContractArtifactReader.d.ts +24 -0
- package/dist/artifacts/frontendContractArtifactReader.js +47 -0
- package/dist/artifacts/frontendContractArtifactReader.js.map +1 -0
- package/dist/artifacts/frontendContractArtifactWriter.d.ts +34 -0
- package/dist/artifacts/frontendContractArtifactWriter.js +70 -0
- package/dist/artifacts/frontendContractArtifactWriter.js.map +1 -0
- package/dist/artifacts/frontendContractEvaluationArtifactReader.d.ts +17 -0
- package/dist/artifacts/frontendContractEvaluationArtifactReader.js +34 -0
- package/dist/artifacts/frontendContractEvaluationArtifactReader.js.map +1 -0
- package/dist/artifacts/frontendContractEvaluationArtifactWriter.d.ts +32 -0
- package/dist/artifacts/frontendContractEvaluationArtifactWriter.js +58 -0
- package/dist/artifacts/frontendContractEvaluationArtifactWriter.js.map +1 -0
- package/dist/artifacts/types.d.ts +17 -0
- package/dist/artifacts/types.js +2 -0
- package/dist/artifacts/types.js.map +1 -0
- package/dist/browser/chromiumAdapter.d.ts +21 -0
- package/dist/browser/chromiumAdapter.js +204 -0
- package/dist/browser/chromiumAdapter.js.map +1 -0
- package/dist/browser/evidenceCapture.d.ts +62 -0
- package/dist/browser/evidenceCapture.js +500 -0
- package/dist/browser/evidenceCapture.js.map +1 -0
- package/dist/browser/scrollCapture.d.ts +32 -0
- package/dist/browser/scrollCapture.js +163 -0
- package/dist/browser/scrollCapture.js.map +1 -0
- package/dist/browser/types.d.ts +24 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +2411 -0
- package/dist/cli.js.map +1 -0
- package/dist/domain/boundedAgentContext.d.ts +226 -0
- package/dist/domain/boundedAgentContext.js +355 -0
- package/dist/domain/boundedAgentContext.js.map +1 -0
- package/dist/domain/boundedAgentContextCorrelation.d.ts +74 -0
- package/dist/domain/boundedAgentContextCorrelation.js +441 -0
- package/dist/domain/boundedAgentContextCorrelation.js.map +1 -0
- package/dist/domain/boundedAgentContextIdentity.d.ts +26 -0
- package/dist/domain/boundedAgentContextIdentity.js +69 -0
- package/dist/domain/boundedAgentContextIdentity.js.map +1 -0
- package/dist/domain/boundedAgentContextProjection.d.ts +71 -0
- package/dist/domain/boundedAgentContextProjection.js +477 -0
- package/dist/domain/boundedAgentContextProjection.js.map +1 -0
- package/dist/domain/comparison.d.ts +220 -0
- package/dist/domain/comparison.js +350 -0
- package/dist/domain/comparison.js.map +1 -0
- package/dist/domain/comparisonEngine.d.ts +76 -0
- package/dist/domain/comparisonEngine.js +734 -0
- package/dist/domain/comparisonEngine.js.map +1 -0
- package/dist/domain/comparisonIdentity.d.ts +13 -0
- package/dist/domain/comparisonIdentity.js +46 -0
- package/dist/domain/comparisonIdentity.js.map +1 -0
- package/dist/domain/completion.d.ts +30 -0
- package/dist/domain/completion.js +22 -0
- package/dist/domain/completion.js.map +1 -0
- package/dist/domain/diagnostics.d.ts +17 -0
- package/dist/domain/diagnostics.js +77 -0
- package/dist/domain/diagnostics.js.map +1 -0
- package/dist/domain/evidence.d.ts +29 -0
- package/dist/domain/evidence.js +59 -0
- package/dist/domain/evidence.js.map +1 -0
- package/dist/domain/explicitState.d.ts +40 -0
- package/dist/domain/explicitState.js +54 -0
- package/dist/domain/explicitState.js.map +1 -0
- package/dist/domain/externalReference.d.ts +158 -0
- package/dist/domain/externalReference.js +167 -0
- package/dist/domain/externalReference.js.map +1 -0
- package/dist/domain/externalReferenceApplicability.d.ts +43 -0
- package/dist/domain/externalReferenceApplicability.js +52 -0
- package/dist/domain/externalReferenceApplicability.js.map +1 -0
- package/dist/domain/externalReferenceCompatibility.d.ts +40 -0
- package/dist/domain/externalReferenceCompatibility.js +48 -0
- package/dist/domain/externalReferenceCompatibility.js.map +1 -0
- package/dist/domain/externalReferenceFidelity.d.ts +171 -0
- package/dist/domain/externalReferenceFidelity.js +419 -0
- package/dist/domain/externalReferenceFidelity.js.map +1 -0
- package/dist/domain/externalReferenceIdentity.d.ts +38 -0
- package/dist/domain/externalReferenceIdentity.js +70 -0
- package/dist/domain/externalReferenceIdentity.js.map +1 -0
- package/dist/domain/externalReferenceImage.d.ts +35 -0
- package/dist/domain/externalReferenceImage.js +160 -0
- package/dist/domain/externalReferenceImage.js.map +1 -0
- package/dist/domain/externalReferenceRegionRelationships.d.ts +63 -0
- package/dist/domain/externalReferenceRegionRelationships.js +98 -0
- package/dist/domain/externalReferenceRegionRelationships.js.map +1 -0
- package/dist/domain/externalReferenceRegions.d.ts +65 -0
- package/dist/domain/externalReferenceRegions.js +105 -0
- package/dist/domain/externalReferenceRegions.js.map +1 -0
- package/dist/domain/externalReferenceRequirementIdentity.d.ts +12 -0
- package/dist/domain/externalReferenceRequirementIdentity.js +35 -0
- package/dist/domain/externalReferenceRequirementIdentity.js.map +1 -0
- package/dist/domain/externalReferenceRequirements.d.ts +215 -0
- package/dist/domain/externalReferenceRequirements.js +401 -0
- package/dist/domain/externalReferenceRequirements.js.map +1 -0
- package/dist/domain/externalReferenceRuntimeBinding.d.ts +146 -0
- package/dist/domain/externalReferenceRuntimeBinding.js +183 -0
- package/dist/domain/externalReferenceRuntimeBinding.js.map +1 -0
- package/dist/domain/frontendContractEvaluation.d.ts +57 -0
- package/dist/domain/frontendContractEvaluation.js +454 -0
- package/dist/domain/frontendContractEvaluation.js.map +1 -0
- package/dist/domain/frontendContractEvaluationArtifact.d.ts +65 -0
- package/dist/domain/frontendContractEvaluationArtifact.js +108 -0
- package/dist/domain/frontendContractEvaluationArtifact.js.map +1 -0
- package/dist/domain/frontendContractIdentity.d.ts +39 -0
- package/dist/domain/frontendContractIdentity.js +70 -0
- package/dist/domain/frontendContractIdentity.js.map +1 -0
- package/dist/domain/frontendContracts.d.ts +188 -0
- package/dist/domain/frontendContracts.js +260 -0
- package/dist/domain/frontendContracts.js.map +1 -0
- package/dist/domain/identity.d.ts +21 -0
- package/dist/domain/identity.js +47 -0
- package/dist/domain/identity.js.map +1 -0
- package/dist/domain/referenceCorrectionIdentity.d.ts +40 -0
- package/dist/domain/referenceCorrectionIdentity.js +77 -0
- package/dist/domain/referenceCorrectionIdentity.js.map +1 -0
- package/dist/domain/referenceCorrectionWorkflow.d.ts +160 -0
- package/dist/domain/referenceCorrectionWorkflow.js +165 -0
- package/dist/domain/referenceCorrectionWorkflow.js.map +1 -0
- package/dist/domain/referenceFidelityProjection.d.ts +65 -0
- package/dist/domain/referenceFidelityProjection.js +135 -0
- package/dist/domain/referenceFidelityProjection.js.map +1 -0
- package/dist/domain/relationships.d.ts +210 -0
- package/dist/domain/relationships.js +352 -0
- package/dist/domain/relationships.js.map +1 -0
- package/dist/domain/schema.d.ts +269 -0
- package/dist/domain/schema.js +442 -0
- package/dist/domain/schema.js.map +1 -0
- package/dist/domain/scrollEvidence.d.ts +51 -0
- package/dist/domain/scrollEvidence.js +134 -0
- package/dist/domain/scrollEvidence.js.map +1 -0
- package/dist/index.d.ts +114 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/dist/projectWorkflow/aliasCatalog.d.ts +21 -0
- package/dist/projectWorkflow/aliasCatalog.js +67 -0
- package/dist/projectWorkflow/aliasCatalog.js.map +1 -0
- package/dist/projectWorkflow/checkAcceptance.d.ts +25 -0
- package/dist/projectWorkflow/checkAcceptance.js +55 -0
- package/dist/projectWorkflow/checkAcceptance.js.map +1 -0
- package/dist/projectWorkflow/checkResult.d.ts +85 -0
- package/dist/projectWorkflow/checkResult.js +101 -0
- package/dist/projectWorkflow/checkResult.js.map +1 -0
- package/dist/projectWorkflow/projectConfig.d.ts +43 -0
- package/dist/projectWorkflow/projectConfig.js +84 -0
- package/dist/projectWorkflow/projectConfig.js.map +1 -0
- package/dist/projectWorkflow/projectDiscovery.d.ts +9 -0
- package/dist/projectWorkflow/projectDiscovery.js +20 -0
- package/dist/projectWorkflow/projectDiscovery.js.map +1 -0
- package/dist/projectWorkflow/projectPaths.d.ts +8 -0
- package/dist/projectWorkflow/projectPaths.js +23 -0
- package/dist/projectWorkflow/projectPaths.js.map +1 -0
- package/dist/request/paths.d.ts +14 -0
- package/dist/request/paths.js +33 -0
- package/dist/request/paths.js.map +1 -0
- package/dist/request/request.d.ts +111 -0
- package/dist/request/request.js +464 -0
- package/dist/request/request.js.map +1 -0
- package/dist/safety/policy.d.ts +14 -0
- package/dist/safety/policy.js +81 -0
- package/dist/safety/policy.js.map +1 -0
- package/dist/viewer/assets/index-CN_yb9Uf.css +1 -0
- package/dist/viewer/assets/index-D98S1_2d.js +9 -0
- package/dist/viewer/icons/icon-192.png +0 -0
- package/dist/viewer/icons/icon-512.png +0 -0
- package/dist/viewer/index.html +15 -0
- package/dist/viewer/manifest.webmanifest +1 -0
- package/dist/viewer/registerSW.js +1 -0
- package/dist/viewer/sw.js +1 -0
- package/dist/viewer/workbox-9c191d2f.js +1 -0
- package/dist/viewerServer/context.d.ts +48 -0
- package/dist/viewerServer/context.js +60 -0
- package/dist/viewerServer/context.js.map +1 -0
- package/dist/viewerServer/evidence/classify.d.ts +59 -0
- package/dist/viewerServer/evidence/classify.js +124 -0
- package/dist/viewerServer/evidence/classify.js.map +1 -0
- package/dist/viewerServer/evidence/comparisonView.d.ts +28 -0
- package/dist/viewerServer/evidence/comparisonView.js +43 -0
- package/dist/viewerServer/evidence/comparisonView.js.map +1 -0
- package/dist/viewerServer/evidence/contextSourceView.d.ts +25 -0
- package/dist/viewerServer/evidence/contextSourceView.js +20 -0
- package/dist/viewerServer/evidence/contextSourceView.js.map +1 -0
- package/dist/viewerServer/evidence/discovery.d.ts +31 -0
- package/dist/viewerServer/evidence/discovery.js +78 -0
- package/dist/viewerServer/evidence/discovery.js.map +1 -0
- package/dist/viewerServer/evidence/evaluationView.d.ts +32 -0
- package/dist/viewerServer/evidence/evaluationView.js +50 -0
- package/dist/viewerServer/evidence/evaluationView.js.map +1 -0
- package/dist/viewerServer/evidence/handles.d.ts +21 -0
- package/dist/viewerServer/evidence/handles.js +43 -0
- package/dist/viewerServer/evidence/handles.js.map +1 -0
- package/dist/viewerServer/evidence/index.d.ts +41 -0
- package/dist/viewerServer/evidence/index.js +82 -0
- package/dist/viewerServer/evidence/index.js.map +1 -0
- package/dist/viewerServer/evidence/limits.d.ts +27 -0
- package/dist/viewerServer/evidence/limits.js +28 -0
- package/dist/viewerServer/evidence/limits.js.map +1 -0
- package/dist/viewerServer/evidence/linkedEvidence.d.ts +43 -0
- package/dist/viewerServer/evidence/linkedEvidence.js +151 -0
- package/dist/viewerServer/evidence/linkedEvidence.js.map +1 -0
- package/dist/viewerServer/evidence/mediaResolver.d.ts +16 -0
- package/dist/viewerServer/evidence/mediaResolver.js +85 -0
- package/dist/viewerServer/evidence/mediaResolver.js.map +1 -0
- package/dist/viewerServer/evidence/observationView.d.ts +29 -0
- package/dist/viewerServer/evidence/observationView.js +46 -0
- package/dist/viewerServer/evidence/observationView.js.map +1 -0
- package/dist/viewerServer/evidence/pathSafety.d.ts +11 -0
- package/dist/viewerServer/evidence/pathSafety.js +31 -0
- package/dist/viewerServer/evidence/pathSafety.js.map +1 -0
- package/dist/viewerServer/evidence/projection.d.ts +55 -0
- package/dist/viewerServer/evidence/projection.js +152 -0
- package/dist/viewerServer/evidence/projection.js.map +1 -0
- package/dist/viewerServer/evidence/referenceView.d.ts +133 -0
- package/dist/viewerServer/evidence/referenceView.js +169 -0
- package/dist/viewerServer/evidence/referenceView.js.map +1 -0
- package/dist/viewerServer/httpServer.d.ts +27 -0
- package/dist/viewerServer/httpServer.js +381 -0
- package/dist/viewerServer/httpServer.js.map +1 -0
- package/dist/viewerServer/openBrowser.d.ts +7 -0
- package/dist/viewerServer/openBrowser.js +32 -0
- package/dist/viewerServer/openBrowser.js.map +1 -0
- package/dist/viewerServer/port.d.ts +16 -0
- package/dist/viewerServer/port.js +19 -0
- package/dist/viewerServer/port.js.map +1 -0
- package/dist/viewerServer/viewerService.d.ts +62 -0
- package/dist/viewerServer/viewerService.js +88 -0
- package/dist/viewerServer/viewerService.js.map +1 -0
- package/docs/ARCHITECTURE.md +1286 -0
- package/docs/CI_CD.md +250 -0
- package/docs/COMMANDS.md +972 -0
- package/docs/CONTRACTS.md +1856 -0
- package/docs/CURRENT_STATE.md +1049 -0
- package/docs/DEVELOPMENT.md +202 -0
- package/docs/DOCUMENTATION_PRESERVATION_POLICY.md +50 -0
- package/docs/PROJECT_DESCRIPTION.md +2221 -0
- package/docs/PROJECT_MILESTONES.md +2526 -0
- package/docs/PROJECT_OVERVIEW.md +150 -0
- package/docs/QUICKSTART.md +83 -0
- package/docs/RELEASE.md +27 -0
- package/docs/ROADMAP.md +641 -0
- package/docs/SECURITY.md +218 -0
- package/docs/WORKFLOWS.md +642 -0
- package/docs/plans/v0.8-implementation-plan.md +655 -0
- package/docs/plans/v0.8.1-cli-usability-patch-plan.md +505 -0
- package/docs/reports/v0.7-bounded-fidelity-context-prompt7.md +243 -0
- package/docs/reports/v0.7-implementation-completeness-documentation-reconciliation.md +497 -0
- package/docs/reports/v0.7-pre-release-readiness.md +337 -0
- package/docs/reports/v0.7-reference-binding-prompt5.md +223 -0
- package/docs/reports/v0.7-reference-compatibility-prompt4.md +234 -0
- package/docs/reports/v0.7-reference-correction-workflow-prompt8.md +222 -0
- package/docs/reports/v0.7-reference-fidelity-prompt6.md +216 -0
- package/docs/reports/v0.7-reference-foundation-prompt1.md +151 -0
- package/docs/reports/v0.7-reference-regions-prompt2.md +195 -0
- package/docs/reports/v0.7-reference-requirements-prompt3.md +217 -0
- package/docs/reports/v0.7-release-prep.md +423 -0
- package/docs/reports/v0.8-binding-fidelity-interaction-batch6.md +279 -0
- package/docs/reports/v0.8-bounded-context-correlation-batch7.md +233 -0
- package/docs/reports/v0.8-comparison-contract-inspection-batch4.md +279 -0
- package/docs/reports/v0.8-evidence-index-readers-batch2.md +247 -0
- package/docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md +741 -0
- package/docs/reports/v0.8-integrated-viewer-acceptance-batch8.md +128 -0
- package/docs/reports/v0.8-observation-svg-inspection-batch3.md +223 -0
- package/docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md +687 -0
- package/docs/reports/v0.8-reference-candidate-inspection-batch5.md +232 -0
- package/docs/reports/v0.8-viewer-runtime-pwa-batch1.md +278 -0
- package/docs/reports/v0.8.1-check-orchestration-prompt2.md +69 -0
- package/docs/reports/v0.8.1-implementation-completeness-documentation-reconciliation.md +114 -0
- package/docs/reports/v0.8.1-prerelease-readiness-cross-platform-security-code-rot.md +170 -0
- package/docs/reports/v0.8.1-project-workflow-foundation-prompt1.md +66 -0
- package/package.json +58 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v0.5 Batch 3 minimal additive persistence envelope for
|
|
3
|
+
* `frontendContractEvaluation.ts#evaluateFrontendContract`'s output. Batch 1
|
|
4
|
+
* froze the evaluation-result vocabulary (`ClauseEvaluationResult`,
|
|
5
|
+
* `OverallVerdict`) and Batch 2 froze the evaluator itself, but neither froze
|
|
6
|
+
* a persistable artifact envelope (identity, provenance, schema ownership,
|
|
7
|
+
* source-evidence references) - this module adds exactly that and nothing
|
|
8
|
+
* else. It reuses the frozen result types unchanged, contains no evaluation
|
|
9
|
+
* logic, and never imports/calls `evaluateFrontendContract`.
|
|
10
|
+
*
|
|
11
|
+
* Independent artifact family from observation (`1.2.0`), comparison
|
|
12
|
+
* (`1.0.0`), and the frontend-contract family (`1.0.0`) - never reuses
|
|
13
|
+
* `ARTIFACT_KIND`/`COMPARISON_ARTIFACT_KIND`/`CONTRACT_ARTIFACT_KIND`.
|
|
14
|
+
*/
|
|
15
|
+
import { isValidEvidenceReference } from './relationships.js';
|
|
16
|
+
import { PRODUCER_NAME, SCHEMA_VERSION as OBSERVATION_SCHEMA_VERSION } from './schema.js';
|
|
17
|
+
import { isValidClauseEvaluationResult, OVERALL_VERDICTS, isValidFrontendContractObservationReference } from './frontendContracts.js';
|
|
18
|
+
import { DIFFERENCE_KINDS } from './comparison.js';
|
|
19
|
+
function isPlainObject(value) {
|
|
20
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
21
|
+
}
|
|
22
|
+
function isNonEmptyString(value) {
|
|
23
|
+
return typeof value === 'string' && value.length > 0;
|
|
24
|
+
}
|
|
25
|
+
export const EVALUATION_ARTIFACT_KIND = 'my-frontend-observer/frontend-contract-evaluation';
|
|
26
|
+
export const EVALUATION_SCHEMA_VERSION = '1.0.0';
|
|
27
|
+
function isValidFrontendContractEvaluationSourceReference(value) {
|
|
28
|
+
return isPlainObject(value) && isNonEmptyString(value.baselineId) && isNonEmptyString(value.contractId);
|
|
29
|
+
}
|
|
30
|
+
function isValidUnexpectedChangeResult(value) {
|
|
31
|
+
if (!isPlainObject(value))
|
|
32
|
+
return false;
|
|
33
|
+
if (value.classification !== 'unexpected')
|
|
34
|
+
return false;
|
|
35
|
+
if (typeof value.differenceKind !== 'string' || !DIFFERENCE_KINDS.includes(value.differenceKind))
|
|
36
|
+
return false;
|
|
37
|
+
if (!isPlainObject(value.subject) || typeof value.subject.type !== 'string')
|
|
38
|
+
return false;
|
|
39
|
+
return Array.isArray(value.supportingEvidence) && value.supportingEvidence.every((e) => isValidEvidenceReference(e));
|
|
40
|
+
}
|
|
41
|
+
export function isValidFrontendContractEvaluationArtifact(value) {
|
|
42
|
+
if (!isPlainObject(value))
|
|
43
|
+
return { valid: false, reason: 'artifact must be an object' };
|
|
44
|
+
if (value.artifactKind !== EVALUATION_ARTIFACT_KIND)
|
|
45
|
+
return { valid: false, reason: 'artifactKind mismatch' };
|
|
46
|
+
if (value.schemaVersion !== EVALUATION_SCHEMA_VERSION)
|
|
47
|
+
return { valid: false, reason: 'schemaVersion mismatch' };
|
|
48
|
+
if (!isNonEmptyString(value.evaluationId))
|
|
49
|
+
return { valid: false, reason: 'evaluationId must be a non-empty string' };
|
|
50
|
+
if (!isNonEmptyString(value.evaluationRequestId))
|
|
51
|
+
return { valid: false, reason: 'evaluationRequestId must be a non-empty string' };
|
|
52
|
+
if (!isPlainObject(value.producer) || value.producer.name !== PRODUCER_NAME || !isNonEmptyString(value.producer.version)) {
|
|
53
|
+
return { valid: false, reason: 'producer must be { name: "my-frontend-observer", version: string }' };
|
|
54
|
+
}
|
|
55
|
+
if (!isPlainObject(value.provenance) || !isNonEmptyString(value.provenance.evaluatedAt)) {
|
|
56
|
+
return { valid: false, reason: 'provenance.evaluatedAt must be a non-empty string' };
|
|
57
|
+
}
|
|
58
|
+
if (!isValidFrontendContractEvaluationSourceReference(value.contracts))
|
|
59
|
+
return { valid: false, reason: 'contracts reference is invalid' };
|
|
60
|
+
if (!isValidFrontendContractObservationReference(value.before))
|
|
61
|
+
return { valid: false, reason: 'before source observation reference is invalid' };
|
|
62
|
+
if (!isValidFrontendContractObservationReference(value.after))
|
|
63
|
+
return { valid: false, reason: 'after source observation reference is invalid' };
|
|
64
|
+
if (value.before.observationSchemaVersion !== OBSERVATION_SCHEMA_VERSION || value.after.observationSchemaVersion !== OBSERVATION_SCHEMA_VERSION) {
|
|
65
|
+
return { valid: false, reason: 'source observation references must carry the current observation schema version' };
|
|
66
|
+
}
|
|
67
|
+
if (!isNonEmptyString(value.comparisonId))
|
|
68
|
+
return { valid: false, reason: 'comparisonId must be a non-empty string' };
|
|
69
|
+
if (!isNonEmptyString(value.comparisonRequestId))
|
|
70
|
+
return { valid: false, reason: 'comparisonRequestId must be a non-empty string' };
|
|
71
|
+
if (typeof value.overallVerdict !== 'string' || !OVERALL_VERDICTS.includes(value.overallVerdict)) {
|
|
72
|
+
return { valid: false, reason: 'overallVerdict must be "PASS" or "FAIL"' };
|
|
73
|
+
}
|
|
74
|
+
if (!Array.isArray(value.activeBaselineClauseIds) || !value.activeBaselineClauseIds.every((id) => isNonEmptyString(id))) {
|
|
75
|
+
return { valid: false, reason: 'activeBaselineClauseIds must be an array of non-empty strings' };
|
|
76
|
+
}
|
|
77
|
+
if (!Array.isArray(value.supersededBaselineClauseIds) || !value.supersededBaselineClauseIds.every((id) => isNonEmptyString(id))) {
|
|
78
|
+
return { valid: false, reason: 'supersededBaselineClauseIds must be an array of non-empty strings' };
|
|
79
|
+
}
|
|
80
|
+
if (!Array.isArray(value.clauseResults) || !value.clauseResults.every((r) => isValidClauseEvaluationResult(r))) {
|
|
81
|
+
return { valid: false, reason: 'clauseResults must be an array of valid ClauseEvaluationResult values' };
|
|
82
|
+
}
|
|
83
|
+
if (!Array.isArray(value.unexpectedChanges) || !value.unexpectedChanges.every((u) => isValidUnexpectedChangeResult(u))) {
|
|
84
|
+
return { valid: false, reason: 'unexpectedChanges must be an array of valid UnexpectedChangeResult values' };
|
|
85
|
+
}
|
|
86
|
+
return { valid: true };
|
|
87
|
+
}
|
|
88
|
+
export function buildFrontendContractEvaluationArtifact(input) {
|
|
89
|
+
return {
|
|
90
|
+
artifactKind: EVALUATION_ARTIFACT_KIND,
|
|
91
|
+
schemaVersion: EVALUATION_SCHEMA_VERSION,
|
|
92
|
+
evaluationId: input.evaluationId,
|
|
93
|
+
evaluationRequestId: input.evaluationRequestId,
|
|
94
|
+
producer: { name: PRODUCER_NAME, version: input.producerVersion },
|
|
95
|
+
provenance: { evaluatedAt: input.evaluatedAt },
|
|
96
|
+
contracts: { baselineId: input.baselineId, contractId: input.contractId },
|
|
97
|
+
before: input.before,
|
|
98
|
+
after: input.after,
|
|
99
|
+
comparisonId: input.comparisonId,
|
|
100
|
+
comparisonRequestId: input.comparisonRequestId,
|
|
101
|
+
overallVerdict: input.overallVerdict,
|
|
102
|
+
activeBaselineClauseIds: input.activeBaselineClauseIds,
|
|
103
|
+
supersededBaselineClauseIds: input.supersededBaselineClauseIds,
|
|
104
|
+
clauseResults: input.clauseResults,
|
|
105
|
+
unexpectedChanges: input.unexpectedChanges,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=frontendContractEvaluationArtifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontendContractEvaluationArtifact.js","sourceRoot":"","sources":["../../src/domain/frontendContractEvaluationArtifact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ContractPrimitive, ContractTolerance } from './frontendContracts.js';
|
|
2
|
+
interface ContractRequestIdentityClauseInput {
|
|
3
|
+
primitive: ContractPrimitive;
|
|
4
|
+
tolerance?: ContractTolerance;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Pure function of {sourceObservationId, clause primitives/tolerances (order
|
|
8
|
+
* preserved), sorted supersedes ids} only. Never includes a filesystem path,
|
|
9
|
+
* output location, a captured timestamp, or clauseId (clauseId is itself
|
|
10
|
+
* derived from primitive/tolerance, so including it would be redundant with -
|
|
11
|
+
* and could desynchronize from - the content it names).
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildFrontendContractRequestIdentity(sourceObservationId: string, clauses: readonly ContractRequestIdentityClauseInput[], supersedesIds: readonly string[]): string;
|
|
14
|
+
/**
|
|
15
|
+
* Fresh, opaque per-authored-instance identity - never derived from a
|
|
16
|
+
* timestamp alone, never collides even when called twice with the same
|
|
17
|
+
* requestIdentity within the same millisecond.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildFrontendContractInstanceIdentity(requestIdentity: string): string;
|
|
20
|
+
/** Deterministic identity of a single clause's own semantic content - independent of authoring order or the contract it belongs to. */
|
|
21
|
+
export declare function buildClauseIdentity(primitive: ContractPrimitive, tolerance?: ContractTolerance): string;
|
|
22
|
+
/**
|
|
23
|
+
* Batch 3 addition (additive only - does not change any Batch 1 identity
|
|
24
|
+
* function's behavior): pure function of {baselineId, contractId,
|
|
25
|
+
* beforeObservationId, afterObservationId, comparisonRequestId} only, in the
|
|
26
|
+
* same canonicalize+sha256 style as `buildFrontendContractRequestIdentity`.
|
|
27
|
+
* Deliberately takes `comparisonRequestId` (comparison's own deterministic
|
|
28
|
+
* identity), never `comparisonId` (comparison's fresh per-execution instance
|
|
29
|
+
* id, per `comparisonIdentity.ts#buildComparisonIdentity`) - using the
|
|
30
|
+
* instance id here would make semantically identical evaluations of the same
|
|
31
|
+
* before/after pair never share an identity. Never includes a filesystem
|
|
32
|
+
* path, output location, or captured timestamp. Two evaluations of the same
|
|
33
|
+
* baseline/contract/observation-pair/comparison-request combination share
|
|
34
|
+
* this identity even if run from different operational locations;
|
|
35
|
+
* `buildFrontendContractInstanceIdentity` (already generic) is reused
|
|
36
|
+
* unchanged to derive the fresh per-execution `evaluationId` from it.
|
|
37
|
+
*/
|
|
38
|
+
export declare function buildFrontendContractEvaluationRequestIdentity(baselineId: string, contractId: string, beforeObservationId: string, afterObservationId: string, comparisonRequestId: string): string;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Deliberately duplicated from domain/comparisonIdentity.ts#canonicalize (itself
|
|
4
|
+
* duplicated from domain/identity.ts#canonicalize) rather than imported - each
|
|
5
|
+
* identity module owns its own private canonicalize per existing repository
|
|
6
|
+
* convention. Same algorithm (sorted object keys, order-preserving arrays).
|
|
7
|
+
*/
|
|
8
|
+
function canonicalize(value) {
|
|
9
|
+
if (Array.isArray(value))
|
|
10
|
+
return value.map(canonicalize);
|
|
11
|
+
if (value !== null && typeof value === 'object') {
|
|
12
|
+
const entries = Object.entries(value)
|
|
13
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
14
|
+
.map(([key, entryValue]) => [key, canonicalize(entryValue)]);
|
|
15
|
+
return Object.fromEntries(entries);
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Pure function of {sourceObservationId, clause primitives/tolerances (order
|
|
21
|
+
* preserved), sorted supersedes ids} only. Never includes a filesystem path,
|
|
22
|
+
* output location, a captured timestamp, or clauseId (clauseId is itself
|
|
23
|
+
* derived from primitive/tolerance, so including it would be redundant with -
|
|
24
|
+
* and could desynchronize from - the content it names).
|
|
25
|
+
*/
|
|
26
|
+
export function buildFrontendContractRequestIdentity(sourceObservationId, clauses, supersedesIds) {
|
|
27
|
+
const semanticView = {
|
|
28
|
+
sourceObservationId,
|
|
29
|
+
clauses: clauses.map((clause) => ({ primitive: clause.primitive, tolerance: clause.tolerance ?? null })),
|
|
30
|
+
supersedes: [...supersedesIds].sort(),
|
|
31
|
+
};
|
|
32
|
+
const serialized = JSON.stringify(canonicalize(semanticView));
|
|
33
|
+
return createHash('sha256').update(serialized).digest('hex');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Fresh, opaque per-authored-instance identity - never derived from a
|
|
37
|
+
* timestamp alone, never collides even when called twice with the same
|
|
38
|
+
* requestIdentity within the same millisecond.
|
|
39
|
+
*/
|
|
40
|
+
export function buildFrontendContractInstanceIdentity(requestIdentity) {
|
|
41
|
+
const nonce = randomBytes(16).toString('hex');
|
|
42
|
+
return `${requestIdentity}-${nonce}`;
|
|
43
|
+
}
|
|
44
|
+
/** Deterministic identity of a single clause's own semantic content - independent of authoring order or the contract it belongs to. */
|
|
45
|
+
export function buildClauseIdentity(primitive, tolerance) {
|
|
46
|
+
const serialized = JSON.stringify(canonicalize({ primitive, tolerance: tolerance ?? null }));
|
|
47
|
+
return createHash('sha256').update(serialized).digest('hex');
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Batch 3 addition (additive only - does not change any Batch 1 identity
|
|
51
|
+
* function's behavior): pure function of {baselineId, contractId,
|
|
52
|
+
* beforeObservationId, afterObservationId, comparisonRequestId} only, in the
|
|
53
|
+
* same canonicalize+sha256 style as `buildFrontendContractRequestIdentity`.
|
|
54
|
+
* Deliberately takes `comparisonRequestId` (comparison's own deterministic
|
|
55
|
+
* identity), never `comparisonId` (comparison's fresh per-execution instance
|
|
56
|
+
* id, per `comparisonIdentity.ts#buildComparisonIdentity`) - using the
|
|
57
|
+
* instance id here would make semantically identical evaluations of the same
|
|
58
|
+
* before/after pair never share an identity. Never includes a filesystem
|
|
59
|
+
* path, output location, or captured timestamp. Two evaluations of the same
|
|
60
|
+
* baseline/contract/observation-pair/comparison-request combination share
|
|
61
|
+
* this identity even if run from different operational locations;
|
|
62
|
+
* `buildFrontendContractInstanceIdentity` (already generic) is reused
|
|
63
|
+
* unchanged to derive the fresh per-execution `evaluationId` from it.
|
|
64
|
+
*/
|
|
65
|
+
export function buildFrontendContractEvaluationRequestIdentity(baselineId, contractId, beforeObservationId, afterObservationId, comparisonRequestId) {
|
|
66
|
+
const semanticView = { baselineId, contractId, beforeObservationId, afterObservationId, comparisonRequestId };
|
|
67
|
+
const serialized = JSON.stringify(canonicalize(semanticView));
|
|
68
|
+
return createHash('sha256').update(serialized).digest('hex');
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=frontendContractIdentity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontendContractIdentity.js","sourceRoot":"","sources":["../../src/domain/frontendContractIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGtD;;;;;GAKG;AACH,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACzD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC;aAC7D,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aAChD,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,YAAY,CAAC,UAAU,CAAC,CAAU,CAAC,CAAC;QACxE,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAOD;;;;;;GAMG;AACH,MAAM,UAAU,oCAAoC,CAClD,mBAA2B,EAC3B,OAAsD,EACtD,aAAgC;IAEhC,MAAM,YAAY,GAAG;QACnB,mBAAmB;QACnB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC;QACxG,UAAU,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,IAAI,EAAE;KACtC,CAAC;IACF,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC;IAC9D,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qCAAqC,CAAC,eAAuB;IAC3E,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,GAAG,eAAe,IAAI,KAAK,EAAE,CAAC;AACvC,CAAC;AAED,uIAAuI;AACvI,MAAM,UAAU,mBAAmB,CAAC,SAA4B,EAAE,SAA6B;IAC7F,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7F,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,8CAA8C,CAC5D,UAAkB,EAClB,UAAkB,EAClB,mBAA2B,EAC3B,kBAA0B,EAC1B,mBAA2B;IAE3B,MAAM,YAAY,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,CAAC;IAC9G,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC;IAC9D,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v0.5 Batch 1 frontend contract / change-scope contract. Frozen here as
|
|
3
|
+
* pure types/constants/structural validators only - downstream of the v0.4
|
|
4
|
+
* observation/comparison/relationship system (src/domain/comparison.ts,
|
|
5
|
+
* src/domain/relationships.ts, src/domain/schema.ts). This batch implements
|
|
6
|
+
* neither contract evaluation, unexpected-change classification, PASS/FAIL
|
|
7
|
+
* computation, nor persistence - see docs/ARCHITECTURE.md.
|
|
8
|
+
*
|
|
9
|
+
* Contract and observation/comparison are different evidence products: this
|
|
10
|
+
* module never reuses ARTIFACT_KIND (observation) or COMPARISON_ARTIFACT_KIND,
|
|
11
|
+
* and adds no field to ComparisonConfig/ComparisonArtifact.
|
|
12
|
+
*/
|
|
13
|
+
import type { EvidenceReference, PairwiseRelationshipKind, PageLevelRelationshipKind } from './relationships.js';
|
|
14
|
+
import type { DependencyProperty } from './comparison.js';
|
|
15
|
+
import { PRODUCER_NAME, SCHEMA_VERSION as OBSERVATION_SCHEMA_VERSION } from './schema.js';
|
|
16
|
+
export declare const CONTRACT_ARTIFACT_KIND: "my-frontend-observer/frontend-contract";
|
|
17
|
+
export declare const CONTRACT_SCHEMA_VERSION: "1.0.0";
|
|
18
|
+
/** The authored per-change contract has exactly these 4 intent categories - `'unexpected'` is never a member. */
|
|
19
|
+
export declare const AUTHORED_CHANGE_SCOPE_CATEGORIES: readonly ["requested", "expected-dependent", "protected", "preserved"];
|
|
20
|
+
export type AuthoredChangeScopeCategory = (typeof AUTHORED_CHANGE_SCOPE_CATEGORIES)[number];
|
|
21
|
+
export declare function isAuthoredChangeScopeCategory(value: unknown): value is AuthoredChangeScopeCategory;
|
|
22
|
+
/**
|
|
23
|
+
* Full derived classification vocabulary, kept structurally separate from
|
|
24
|
+
* AUTHORED_CHANGE_SCOPE_CATEGORIES - `'unexpected'` is a classification a
|
|
25
|
+
* future evaluator produces, never an authored permission. No function in
|
|
26
|
+
* this module converts between the two vocabularies.
|
|
27
|
+
*/
|
|
28
|
+
export declare const CHANGE_SCOPE_CLASSIFICATIONS: readonly ["requested", "expected-dependent", "protected", "preserved", "unexpected"];
|
|
29
|
+
export type ChangeScopeClassification = (typeof CHANGE_SCOPE_CLASSIFICATIONS)[number];
|
|
30
|
+
export declare const EXPECTED_DEPENDENT_MODES: readonly ["required", "permitted"];
|
|
31
|
+
export type ExpectedDependentMode = (typeof EXPECTED_DEPENDENT_MODES)[number];
|
|
32
|
+
export declare function isValidExpectedDependentMode(value: unknown): value is ExpectedDependentMode;
|
|
33
|
+
/** Independently declared from GEOMETRY_TOLERANCE_*_PX (src/domain/relationships.ts): comparison tolerance suppresses insignificant geometry noise and is never contract authorization. */
|
|
34
|
+
export declare const CONTRACT_TOLERANCE_ABSOLUTE_PX_MIN = 0;
|
|
35
|
+
export declare const CONTRACT_TOLERANCE_ABSOLUTE_PX_MAX = 100;
|
|
36
|
+
export declare const CONTRACT_TOLERANCE_PERCENT_MIN = 0;
|
|
37
|
+
export declare const CONTRACT_TOLERANCE_PERCENT_MAX = 100;
|
|
38
|
+
export type ContractTolerance = {
|
|
39
|
+
kind: 'exact';
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'absolute-px';
|
|
42
|
+
amount: number;
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'percent';
|
|
45
|
+
amount: number;
|
|
46
|
+
};
|
|
47
|
+
export declare function isValidContractTolerance(value: unknown): value is ContractTolerance;
|
|
48
|
+
/** Every contract primitive kind this batch freezes - deliberately bounded, never a generic rule/expression language. */
|
|
49
|
+
export declare const CONTRACT_PRIMITIVE_KINDS: readonly ["target-visible", "target-not-clipped", "target-width-within-bound", "targets-do-not-overlap", "target-wider-than", "target-follows-vertically", "target-fits-inside", "document-width-fits-viewport", "scroll-owner-is-document", "target-does-not-own-scroll", "target-begins-below-initial-viewport", "relationship-unchanged", "property-unchanged-within-tolerance", "property-increases", "property-decreases"];
|
|
50
|
+
export type ContractPrimitiveKind = (typeof CONTRACT_PRIMITIVE_KINDS)[number];
|
|
51
|
+
/** `target-fits-inside` mirrors relationships.ts's GEOMETRIC_FIT_RELATIONSHIPS ('fits-inside') - geometric fit, explicitly distinct from schema.ts's TargetContainment (DOM containment). */
|
|
52
|
+
export type ContractPrimitive = {
|
|
53
|
+
kind: 'target-visible';
|
|
54
|
+
target: string;
|
|
55
|
+
} | {
|
|
56
|
+
kind: 'target-not-clipped';
|
|
57
|
+
target: string;
|
|
58
|
+
axis?: 'horizontal' | 'vertical' | 'both';
|
|
59
|
+
} | {
|
|
60
|
+
kind: 'target-width-within-bound';
|
|
61
|
+
target: string;
|
|
62
|
+
minPx?: number;
|
|
63
|
+
maxPx?: number;
|
|
64
|
+
} | {
|
|
65
|
+
kind: 'targets-do-not-overlap';
|
|
66
|
+
targetA: string;
|
|
67
|
+
targetB: string;
|
|
68
|
+
} | {
|
|
69
|
+
kind: 'target-wider-than';
|
|
70
|
+
targetA: string;
|
|
71
|
+
targetB: string;
|
|
72
|
+
} | {
|
|
73
|
+
kind: 'target-follows-vertically';
|
|
74
|
+
targetA: string;
|
|
75
|
+
targetB: string;
|
|
76
|
+
} | {
|
|
77
|
+
kind: 'target-fits-inside';
|
|
78
|
+
target: string;
|
|
79
|
+
container: string;
|
|
80
|
+
} | {
|
|
81
|
+
kind: 'document-width-fits-viewport';
|
|
82
|
+
} | {
|
|
83
|
+
kind: 'scroll-owner-is-document';
|
|
84
|
+
} | {
|
|
85
|
+
kind: 'target-does-not-own-scroll';
|
|
86
|
+
target: string;
|
|
87
|
+
} | {
|
|
88
|
+
kind: 'target-begins-below-initial-viewport';
|
|
89
|
+
target: string;
|
|
90
|
+
} | {
|
|
91
|
+
kind: 'relationship-unchanged';
|
|
92
|
+
relationshipKind: PairwiseRelationshipKind | PageLevelRelationshipKind;
|
|
93
|
+
subjectTarget?: string;
|
|
94
|
+
relatedTarget?: string;
|
|
95
|
+
} | {
|
|
96
|
+
kind: 'property-unchanged-within-tolerance';
|
|
97
|
+
target: string;
|
|
98
|
+
property: DependencyProperty;
|
|
99
|
+
tolerance: ContractTolerance;
|
|
100
|
+
} | {
|
|
101
|
+
kind: 'property-increases';
|
|
102
|
+
target: string;
|
|
103
|
+
property: DependencyProperty;
|
|
104
|
+
minimumDeltaPx?: number;
|
|
105
|
+
} | {
|
|
106
|
+
kind: 'property-decreases';
|
|
107
|
+
target: string;
|
|
108
|
+
property: DependencyProperty;
|
|
109
|
+
minimumDeltaPx?: number;
|
|
110
|
+
};
|
|
111
|
+
export declare function isValidContractPrimitive(value: unknown): value is ContractPrimitive;
|
|
112
|
+
export interface FrontendContractClauseBase {
|
|
113
|
+
clauseId: string;
|
|
114
|
+
primitive: ContractPrimitive;
|
|
115
|
+
supportingEvidence: EvidenceReference[];
|
|
116
|
+
}
|
|
117
|
+
export type BaselineClause = FrontendContractClauseBase;
|
|
118
|
+
export declare function isValidBaselineClause(value: unknown): value is BaselineClause;
|
|
119
|
+
export interface PerChangeClause extends FrontendContractClauseBase {
|
|
120
|
+
category: AuthoredChangeScopeCategory;
|
|
121
|
+
expectedDependentMode?: ExpectedDependentMode;
|
|
122
|
+
/** Explicit supersession of baseline clause identities - never inferred from same-target/same-property overlap. Non-empty when present. */
|
|
123
|
+
supersedesBaselineClauseIds?: string[];
|
|
124
|
+
}
|
|
125
|
+
export declare function isValidPerChangeClause(value: unknown): value is PerChangeClause;
|
|
126
|
+
/** Enough logical identity to trace a contract back to its authoritative source observation without embedding the full ObservationArtifact. */
|
|
127
|
+
export interface FrontendContractObservationReference {
|
|
128
|
+
observationId: string;
|
|
129
|
+
requestId: string;
|
|
130
|
+
producer: {
|
|
131
|
+
name: typeof PRODUCER_NAME;
|
|
132
|
+
version: string;
|
|
133
|
+
};
|
|
134
|
+
observationSchemaVersion: typeof OBSERVATION_SCHEMA_VERSION;
|
|
135
|
+
}
|
|
136
|
+
export declare function isValidFrontendContractObservationReference(value: unknown): value is FrontendContractObservationReference;
|
|
137
|
+
export interface PersistentBaselineContract {
|
|
138
|
+
artifactKind: typeof CONTRACT_ARTIFACT_KIND;
|
|
139
|
+
schemaVersion: typeof CONTRACT_SCHEMA_VERSION;
|
|
140
|
+
contractClass: 'baseline';
|
|
141
|
+
baselineId: string;
|
|
142
|
+
/** Explicit, append-based supersession - never rewrites/removes the prior baseline value. */
|
|
143
|
+
supersedesBaselineId?: string;
|
|
144
|
+
sourceObservation: FrontendContractObservationReference;
|
|
145
|
+
clauses: BaselineClause[];
|
|
146
|
+
provenance: {
|
|
147
|
+
approvedAt: string;
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
export type FrontendContractValidationResult = {
|
|
151
|
+
valid: true;
|
|
152
|
+
} | {
|
|
153
|
+
valid: false;
|
|
154
|
+
reason: string;
|
|
155
|
+
};
|
|
156
|
+
export declare function isValidPersistentBaselineContract(value: unknown): FrontendContractValidationResult;
|
|
157
|
+
export interface PerChangeContract {
|
|
158
|
+
artifactKind: typeof CONTRACT_ARTIFACT_KIND;
|
|
159
|
+
schemaVersion: typeof CONTRACT_SCHEMA_VERSION;
|
|
160
|
+
contractClass: 'change';
|
|
161
|
+
contractId: string;
|
|
162
|
+
contractRequestId: string;
|
|
163
|
+
activeBaselineIds: string[];
|
|
164
|
+
clauses: PerChangeClause[];
|
|
165
|
+
}
|
|
166
|
+
export declare function isValidPerChangeContract(value: unknown): FrontendContractValidationResult;
|
|
167
|
+
export declare const CLAUSE_RESULT_STATUSES: readonly ["pass", "fail", "unavailable", "conflict"];
|
|
168
|
+
export type ClauseResultStatus = (typeof CLAUSE_RESULT_STATUSES)[number];
|
|
169
|
+
export type ClauseEvaluationResult = {
|
|
170
|
+
clauseId: string;
|
|
171
|
+
status: 'pass' | 'fail';
|
|
172
|
+
supportingEvidence: EvidenceReference[];
|
|
173
|
+
} | {
|
|
174
|
+
clauseId: string;
|
|
175
|
+
status: 'unavailable';
|
|
176
|
+
reason: string;
|
|
177
|
+
supportingEvidence: EvidenceReference[];
|
|
178
|
+
} | {
|
|
179
|
+
clauseId: string;
|
|
180
|
+
status: 'conflict';
|
|
181
|
+
conflictingClauseIds: string[];
|
|
182
|
+
reason: string;
|
|
183
|
+
supportingEvidence: EvidenceReference[];
|
|
184
|
+
};
|
|
185
|
+
/** Honest per-clause result vocabulary: `'unavailable'` requires a non-empty reason (never fabricated pass/fail); `'conflict'` requires at least 2 conflicting clause ids. */
|
|
186
|
+
export declare function isValidClauseEvaluationResult(value: unknown): value is ClauseEvaluationResult;
|
|
187
|
+
export declare const OVERALL_VERDICTS: readonly ["PASS", "FAIL"];
|
|
188
|
+
export type OverallVerdict = (typeof OVERALL_VERDICTS)[number];
|