my-frontend-observer 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/README.md +39 -11
- 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/artifacts/comparisonArtifactReader.d.ts +18 -0
- package/dist/artifacts/comparisonArtifactReader.js +35 -0
- package/dist/artifacts/comparisonArtifactReader.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/cli.js +496 -6
- package/dist/cli.js.map +1 -1
- 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/index.d.ts +22 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/docs/ARCHITECTURE.md +98 -1
- package/docs/CI_CD.md +47 -0
- package/docs/COMMANDS.md +162 -0
- package/docs/CONTRACTS.md +175 -3
- package/docs/CURRENT_STATE.md +92 -10
- package/docs/DEVELOPMENT.md +58 -10
- package/docs/PROJECT_OVERVIEW.md +19 -13
- package/docs/QUICKSTART.md +5 -0
- package/docs/RELEASE.md +17 -10
- package/docs/ROADMAP.md +6 -0
- package/docs/SECURITY.md +13 -1
- package/docs/WORKFLOWS.md +65 -8
- package/package.json +1 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v0.5 Batch 2 canonical pure frontend contract evaluation engine. Consumes
|
|
3
|
+
* already-loaded evidence (before/after ObservationArtifact, ComparisonArtifact,
|
|
4
|
+
* PersistentBaselineContract, PerChangeContract - all frozen by v0.4/Batch 1) and
|
|
5
|
+
* derives per-clause results plus one overall PASS/FAIL verdict. Pure and
|
|
6
|
+
* synchronous: no Chromium, no filesystem, no target re-resolution, no
|
|
7
|
+
* reimplementation of v0.4 comparison/relationship/clipping/scroll-owner logic.
|
|
8
|
+
* Mutates none of its inputs. This module owns no persistence, no CLI, and no
|
|
9
|
+
* unexpected-change *authoring* semantics - `unexpected` remains a derived
|
|
10
|
+
* classification only, never an authored category (see domain/frontendContracts.ts).
|
|
11
|
+
*/
|
|
12
|
+
import type { EvidenceReference } from './relationships.js';
|
|
13
|
+
import type { ObservationArtifact } from './schema.js';
|
|
14
|
+
import type { ComparisonArtifact, ComparisonDifferenceSubject, DifferenceKind } from './comparison.js';
|
|
15
|
+
import type { PersistentBaselineContract, PerChangeContract, ClauseEvaluationResult, OverallVerdict } from './frontendContracts.js';
|
|
16
|
+
export interface FrontendContractEvaluationInput {
|
|
17
|
+
before: ObservationArtifact;
|
|
18
|
+
after: ObservationArtifact;
|
|
19
|
+
comparison: ComparisonArtifact;
|
|
20
|
+
baseline: PersistentBaselineContract;
|
|
21
|
+
change: PerChangeContract;
|
|
22
|
+
}
|
|
23
|
+
/** A meaningful rendered difference not accounted for by any active authored clause - derived only, never authorable. */
|
|
24
|
+
export interface UnexpectedChangeResult {
|
|
25
|
+
classification: 'unexpected';
|
|
26
|
+
subject: ComparisonDifferenceSubject;
|
|
27
|
+
differenceKind: DifferenceKind;
|
|
28
|
+
supportingEvidence: EvidenceReference[];
|
|
29
|
+
}
|
|
30
|
+
export interface FrontendContractEvaluationResult {
|
|
31
|
+
overallVerdict: OverallVerdict;
|
|
32
|
+
activeBaselineClauseIds: string[];
|
|
33
|
+
supersededBaselineClauseIds: string[];
|
|
34
|
+
clauseResults: ClauseEvaluationResult[];
|
|
35
|
+
unexpectedChanges: UnexpectedChangeResult[];
|
|
36
|
+
}
|
|
37
|
+
export type EvaluateFrontendContractResult = {
|
|
38
|
+
ok: true;
|
|
39
|
+
evaluation: FrontendContractEvaluationResult;
|
|
40
|
+
} | {
|
|
41
|
+
ok: false;
|
|
42
|
+
reason: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* The one canonical pure v0.5 contract-evaluation entry point:
|
|
46
|
+
* `active persistent baseline contracts + current per-change contract + actual
|
|
47
|
+
* before/after runtime evidence -> PASS | FAIL` with full clause-level
|
|
48
|
+
* evidence. Deterministic given identical inputs; never mutates
|
|
49
|
+
* before/after/comparison/baseline/change.
|
|
50
|
+
*
|
|
51
|
+
* NOTE: `comparison.differences` already includes one `ComparisonDifference`
|
|
52
|
+
* per `RelationshipChangeRecord` (see `comparisonEngine.ts#relationshipChangesToDifferences`),
|
|
53
|
+
* so unexpected-change derivation consumes `differences` only - iterating
|
|
54
|
+
* `relationshipChanges` separately would double-count the same logical
|
|
55
|
+
* transition.
|
|
56
|
+
*/
|
|
57
|
+
export declare function evaluateFrontendContract(input: FrontendContractEvaluationInput): EvaluateFrontendContractResult;
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import { HORIZONTAL_ORDER_RELATIONSHIPS, VERTICAL_ORDER_RELATIONSHIPS, AREA_OVERLAP_RELATIONSHIPS, RELATIVE_WIDTH_RELATIONSHIPS, GEOMETRIC_FIT_RELATIONSHIPS, VERTICAL_SEQUENCE_RELATIONSHIPS, PAGE_WIDTH_RELATIONSHIPS, PAGE_LEVEL_RELATIONSHIP_KINDS, deriveTargetClipping, } from './relationships.js';
|
|
2
|
+
import { isValidObservationArtifact } from './schema.js';
|
|
3
|
+
import { evidenceValue } from './evidence.js';
|
|
4
|
+
import { isValidComparisonArtifact } from './comparison.js';
|
|
5
|
+
import { isValidPersistentBaselineContract, isValidPerChangeContract } from './frontendContracts.js';
|
|
6
|
+
function targetGeometry(observation, target) {
|
|
7
|
+
const record = observation.targetEvidence[target];
|
|
8
|
+
return record ? evidenceValue(record.geometry) : undefined;
|
|
9
|
+
}
|
|
10
|
+
function targetVisible(observation, target) {
|
|
11
|
+
const record = observation.targetEvidence[target];
|
|
12
|
+
const visibility = record ? evidenceValue(record.visibility) : undefined;
|
|
13
|
+
return visibility?.visible;
|
|
14
|
+
}
|
|
15
|
+
function targetClipping(observation, target) {
|
|
16
|
+
const record = observation.targetEvidence[target];
|
|
17
|
+
return record ? deriveTargetClipping(record) : { horizontal: 'unavailable', vertical: 'unavailable' };
|
|
18
|
+
}
|
|
19
|
+
function findPairwiseKind(graph, subjectTarget, relatedTarget, family) {
|
|
20
|
+
return graph.pairwiseRelationships.find((r) => r.subjectTarget === subjectTarget && r.relatedTarget === relatedTarget && family.includes(r.kind))?.kind;
|
|
21
|
+
}
|
|
22
|
+
function scrollOwnerOf(observation) {
|
|
23
|
+
return observation.scrollScenarioEvidence ? evidenceValue(observation.scrollScenarioEvidence.scrollOwner) : undefined;
|
|
24
|
+
}
|
|
25
|
+
function initialViewportRelation(observation, target) {
|
|
26
|
+
const state = observation.scrollScenarioEvidence?.initial.targets[target];
|
|
27
|
+
const relation = state ? evidenceValue(state.viewportRelation) : undefined;
|
|
28
|
+
return relation?.vertical;
|
|
29
|
+
}
|
|
30
|
+
function readProperty(observation, target, property) {
|
|
31
|
+
const geometry = targetGeometry(observation, target);
|
|
32
|
+
return geometry ? geometry[property] : undefined;
|
|
33
|
+
}
|
|
34
|
+
/** Contract tolerance is independent of v0.4's comparison geometry noise tolerance (never reused as authorization). Percent denominator is the absolute before-value, the standard "may vary by up to N%" reading. */
|
|
35
|
+
function toleranceToPx(tolerance, beforeValue) {
|
|
36
|
+
switch (tolerance.kind) {
|
|
37
|
+
case 'exact':
|
|
38
|
+
return 0;
|
|
39
|
+
case 'absolute-px':
|
|
40
|
+
return tolerance.amount;
|
|
41
|
+
case 'percent':
|
|
42
|
+
return (tolerance.amount / 100) * Math.abs(beforeValue);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const RELATIONSHIP_FAMILY_GROUPS = [
|
|
46
|
+
HORIZONTAL_ORDER_RELATIONSHIPS,
|
|
47
|
+
VERTICAL_ORDER_RELATIONSHIPS,
|
|
48
|
+
AREA_OVERLAP_RELATIONSHIPS,
|
|
49
|
+
RELATIVE_WIDTH_RELATIONSHIPS,
|
|
50
|
+
GEOMETRIC_FIT_RELATIONSHIPS,
|
|
51
|
+
VERTICAL_SEQUENCE_RELATIONSHIPS,
|
|
52
|
+
PAGE_WIDTH_RELATIONSHIPS,
|
|
53
|
+
];
|
|
54
|
+
function familyOf(kind) {
|
|
55
|
+
return RELATIONSHIP_FAMILY_GROUPS.find((family) => family.includes(kind));
|
|
56
|
+
}
|
|
57
|
+
function sameFamily(a, b) {
|
|
58
|
+
const family = familyOf(a);
|
|
59
|
+
return family ? family.includes(b) : false;
|
|
60
|
+
}
|
|
61
|
+
// --- state-checkable primitive evaluation (evaluated against one observation + its relationship graph) --
|
|
62
|
+
const STATE_PRIMITIVE_KINDS = new Set([
|
|
63
|
+
'target-visible',
|
|
64
|
+
'target-not-clipped',
|
|
65
|
+
'target-width-within-bound',
|
|
66
|
+
'targets-do-not-overlap',
|
|
67
|
+
'target-wider-than',
|
|
68
|
+
'target-follows-vertically',
|
|
69
|
+
'target-fits-inside',
|
|
70
|
+
'document-width-fits-viewport',
|
|
71
|
+
'scroll-owner-is-document',
|
|
72
|
+
'target-does-not-own-scroll',
|
|
73
|
+
'target-begins-below-initial-viewport',
|
|
74
|
+
]);
|
|
75
|
+
function isStatePrimitiveKind(kind) {
|
|
76
|
+
return STATE_PRIMITIVE_KINDS.has(kind);
|
|
77
|
+
}
|
|
78
|
+
function evaluateStatePrimitive(primitive, observation, graph) {
|
|
79
|
+
switch (primitive.kind) {
|
|
80
|
+
case 'target-visible': {
|
|
81
|
+
const visible = targetVisible(observation, primitive.target);
|
|
82
|
+
return visible === undefined ? 'unavailable' : visible ? 'pass' : 'fail';
|
|
83
|
+
}
|
|
84
|
+
case 'target-not-clipped': {
|
|
85
|
+
const clip = targetClipping(observation, primitive.target);
|
|
86
|
+
const axis = primitive.axis ?? 'both';
|
|
87
|
+
const checkHorizontal = axis === 'horizontal' || axis === 'both';
|
|
88
|
+
const checkVertical = axis === 'vertical' || axis === 'both';
|
|
89
|
+
if ((checkHorizontal && clip.horizontal === 'unavailable') || (checkVertical && clip.vertical === 'unavailable'))
|
|
90
|
+
return 'unavailable';
|
|
91
|
+
const clipped = (checkHorizontal && clip.horizontal === 'clipped') || (checkVertical && clip.vertical === 'clipped');
|
|
92
|
+
return clipped ? 'fail' : 'pass';
|
|
93
|
+
}
|
|
94
|
+
case 'target-width-within-bound': {
|
|
95
|
+
const geometry = targetGeometry(observation, primitive.target);
|
|
96
|
+
if (!geometry)
|
|
97
|
+
return 'unavailable';
|
|
98
|
+
if (primitive.minPx !== undefined && geometry.width < primitive.minPx)
|
|
99
|
+
return 'fail';
|
|
100
|
+
if (primitive.maxPx !== undefined && geometry.width > primitive.maxPx)
|
|
101
|
+
return 'fail';
|
|
102
|
+
return 'pass';
|
|
103
|
+
}
|
|
104
|
+
case 'targets-do-not-overlap': {
|
|
105
|
+
const kind = findPairwiseKind(graph, primitive.targetA, primitive.targetB, AREA_OVERLAP_RELATIONSHIPS) ??
|
|
106
|
+
findPairwiseKind(graph, primitive.targetB, primitive.targetA, AREA_OVERLAP_RELATIONSHIPS);
|
|
107
|
+
if (!kind)
|
|
108
|
+
return 'unavailable';
|
|
109
|
+
return kind === 'does-not-overlap' ? 'pass' : 'fail';
|
|
110
|
+
}
|
|
111
|
+
case 'target-wider-than': {
|
|
112
|
+
const direct = findPairwiseKind(graph, primitive.targetA, primitive.targetB, RELATIVE_WIDTH_RELATIONSHIPS);
|
|
113
|
+
if (direct)
|
|
114
|
+
return direct === 'wider-than' ? 'pass' : 'fail';
|
|
115
|
+
const reversed = findPairwiseKind(graph, primitive.targetB, primitive.targetA, RELATIVE_WIDTH_RELATIONSHIPS);
|
|
116
|
+
if (reversed)
|
|
117
|
+
return reversed === 'narrower-than' ? 'pass' : 'fail';
|
|
118
|
+
return 'unavailable';
|
|
119
|
+
}
|
|
120
|
+
case 'target-follows-vertically': {
|
|
121
|
+
const kind = findPairwiseKind(graph, primitive.targetA, primitive.targetB, VERTICAL_SEQUENCE_RELATIONSHIPS);
|
|
122
|
+
if (kind)
|
|
123
|
+
return 'pass';
|
|
124
|
+
const bothResolvable = targetGeometry(observation, primitive.targetA) !== undefined && targetGeometry(observation, primitive.targetB) !== undefined;
|
|
125
|
+
return bothResolvable ? 'fail' : 'unavailable';
|
|
126
|
+
}
|
|
127
|
+
case 'target-fits-inside': {
|
|
128
|
+
const kind = findPairwiseKind(graph, primitive.target, primitive.container, GEOMETRIC_FIT_RELATIONSHIPS);
|
|
129
|
+
if (!kind)
|
|
130
|
+
return 'unavailable';
|
|
131
|
+
return kind === 'fits-inside' ? 'pass' : 'fail';
|
|
132
|
+
}
|
|
133
|
+
case 'document-width-fits-viewport': {
|
|
134
|
+
const kind = graph.pageRelationships[0]?.kind;
|
|
135
|
+
if (!kind)
|
|
136
|
+
return 'unavailable';
|
|
137
|
+
return kind === 'document-width-fits-viewport' ? 'pass' : 'fail';
|
|
138
|
+
}
|
|
139
|
+
case 'scroll-owner-is-document': {
|
|
140
|
+
const owner = scrollOwnerOf(observation);
|
|
141
|
+
if (!owner)
|
|
142
|
+
return 'unavailable';
|
|
143
|
+
return owner.kind === 'document' ? 'pass' : 'fail';
|
|
144
|
+
}
|
|
145
|
+
case 'target-does-not-own-scroll': {
|
|
146
|
+
const owner = scrollOwnerOf(observation);
|
|
147
|
+
if (!owner)
|
|
148
|
+
return 'unavailable';
|
|
149
|
+
return owner.kind === 'target' && owner.target === primitive.target ? 'fail' : 'pass';
|
|
150
|
+
}
|
|
151
|
+
case 'target-begins-below-initial-viewport': {
|
|
152
|
+
const relation = initialViewportRelation(observation, primitive.target);
|
|
153
|
+
if (!relation)
|
|
154
|
+
return 'unavailable';
|
|
155
|
+
return relation === 'below' ? 'pass' : 'fail';
|
|
156
|
+
}
|
|
157
|
+
default:
|
|
158
|
+
return 'unavailable';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// --- diff-based primitive evaluation (compares before vs after) -----------------
|
|
162
|
+
function evaluateRelationshipUnchanged(primitive, ctx) {
|
|
163
|
+
const { relationshipKind, subjectTarget, relatedTarget } = primitive;
|
|
164
|
+
const isPageLevel = PAGE_LEVEL_RELATIONSHIP_KINDS.includes(relationshipKind);
|
|
165
|
+
if (isPageLevel) {
|
|
166
|
+
const changed = ctx.comparison.relationshipChanges.some((r) => r.scope === 'page');
|
|
167
|
+
if (changed)
|
|
168
|
+
return 'fail';
|
|
169
|
+
const afterKind = ctx.comparison.relationshipsAfter.pageRelationships[0]?.kind;
|
|
170
|
+
return afterKind === relationshipKind ? 'pass' : 'unavailable';
|
|
171
|
+
}
|
|
172
|
+
if (!subjectTarget || !relatedTarget)
|
|
173
|
+
return 'unavailable';
|
|
174
|
+
const changed = ctx.comparison.relationshipChanges.some((r) => r.scope === 'pairwise' && r.subjectTarget === subjectTarget && r.relatedTarget === relatedTarget && sameFamily(r.kind, relationshipKind));
|
|
175
|
+
if (changed)
|
|
176
|
+
return 'fail';
|
|
177
|
+
const family = familyOf(relationshipKind);
|
|
178
|
+
if (!family)
|
|
179
|
+
return 'unavailable';
|
|
180
|
+
const afterKind = findPairwiseKind(ctx.comparison.relationshipsAfter, subjectTarget, relatedTarget, family);
|
|
181
|
+
return afterKind === relationshipKind ? 'pass' : 'unavailable';
|
|
182
|
+
}
|
|
183
|
+
function evaluatePropertyUnchanged(primitive, ctx) {
|
|
184
|
+
const before = readProperty(ctx.before, primitive.target, primitive.property);
|
|
185
|
+
const after = readProperty(ctx.after, primitive.target, primitive.property);
|
|
186
|
+
if (before === undefined || after === undefined)
|
|
187
|
+
return 'unavailable';
|
|
188
|
+
const toleranceAmount = toleranceToPx(primitive.tolerance, before);
|
|
189
|
+
return Math.abs(after - before) <= toleranceAmount ? 'pass' : 'fail';
|
|
190
|
+
}
|
|
191
|
+
/** `permitted` relaxes "must occur" to "may occur": no change and compliant change both pass; only the strictly-opposite direction fails. */
|
|
192
|
+
function evaluatePropertyDirectional(primitive, ctx, permitted) {
|
|
193
|
+
const before = readProperty(ctx.before, primitive.target, primitive.property);
|
|
194
|
+
const after = readProperty(ctx.after, primitive.target, primitive.property);
|
|
195
|
+
if (before === undefined || after === undefined)
|
|
196
|
+
return 'unavailable';
|
|
197
|
+
const delta = after - before;
|
|
198
|
+
const magnitude = primitive.minimumDeltaPx ?? 0;
|
|
199
|
+
const increases = primitive.kind === 'property-increases';
|
|
200
|
+
const compliant = increases ? delta > magnitude : delta < -magnitude;
|
|
201
|
+
if (compliant)
|
|
202
|
+
return 'pass';
|
|
203
|
+
if (!permitted)
|
|
204
|
+
return 'fail';
|
|
205
|
+
const contradictory = increases ? delta < 0 : delta > 0;
|
|
206
|
+
return contradictory ? 'fail' : 'pass';
|
|
207
|
+
}
|
|
208
|
+
function evaluatePrimitiveResult(primitive, mode, ctx) {
|
|
209
|
+
switch (primitive.kind) {
|
|
210
|
+
case 'relationship-unchanged':
|
|
211
|
+
return evaluateRelationshipUnchanged(primitive, ctx);
|
|
212
|
+
case 'property-unchanged-within-tolerance':
|
|
213
|
+
return evaluatePropertyUnchanged(primitive, ctx);
|
|
214
|
+
case 'property-increases':
|
|
215
|
+
case 'property-decreases':
|
|
216
|
+
return evaluatePropertyDirectional(primitive, ctx, mode === 'permitted');
|
|
217
|
+
default:
|
|
218
|
+
return evaluateStatePrimitive(primitive, ctx.after, ctx.comparison.relationshipsAfter);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// --- clause-level evaluation (adds the preserved baseline-truth pre-check) ------
|
|
222
|
+
function clauseMode(category, dependentMode) {
|
|
223
|
+
if (category === 'expected-dependent')
|
|
224
|
+
return dependentMode === 'permitted' ? 'permitted' : 'required';
|
|
225
|
+
if (category === 'preserved')
|
|
226
|
+
return 'preserved';
|
|
227
|
+
return 'default';
|
|
228
|
+
}
|
|
229
|
+
function toClauseResult(clauseId, status, supportingEvidence) {
|
|
230
|
+
if (status === 'unavailable') {
|
|
231
|
+
return { clauseId, status: 'unavailable', reason: 'required evidence to evaluate this contract clause is unavailable', supportingEvidence };
|
|
232
|
+
}
|
|
233
|
+
return { clauseId, status, supportingEvidence };
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* `mode === 'preserved'` additionally proves the invariant already held in
|
|
237
|
+
* `before` (using the same before-evidence + `comparison.relationshipsBefore`
|
|
238
|
+
* the v0.4 comparison engine already derived - never re-derived here). An
|
|
239
|
+
* invariant that never held in the baseline cannot be truthfully evaluated as
|
|
240
|
+
* "preserved" or silently redefined as a new regression, per the frozen
|
|
241
|
+
* Batch 1 honesty requirement - reported `unavailable`, never `pass`/`fail`.
|
|
242
|
+
*/
|
|
243
|
+
function evaluateClause(clauseId, primitive, mode, ctx, supportingEvidence) {
|
|
244
|
+
if (mode === 'preserved' && isStatePrimitiveKind(primitive.kind)) {
|
|
245
|
+
const baselineStatus = evaluateStatePrimitive(primitive, ctx.before, ctx.comparison.relationshipsBefore);
|
|
246
|
+
if (baselineStatus === 'fail') {
|
|
247
|
+
return {
|
|
248
|
+
clauseId,
|
|
249
|
+
status: 'unavailable',
|
|
250
|
+
reason: 'asserted preserved invariant does not hold in the baseline (before) evidence, so preservation cannot be truthfully evaluated',
|
|
251
|
+
supportingEvidence,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const status = evaluatePrimitiveResult(primitive, mode, ctx);
|
|
256
|
+
return toClauseResult(clauseId, status, supportingEvidence);
|
|
257
|
+
}
|
|
258
|
+
// --- bounded, deterministic conflict detection -----------------------------------
|
|
259
|
+
function primitiveTargetProperty(p) {
|
|
260
|
+
if (p.kind === 'property-unchanged-within-tolerance' || p.kind === 'property-increases' || p.kind === 'property-decreases') {
|
|
261
|
+
return { target: p.target, property: p.property };
|
|
262
|
+
}
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
function directionOf(p) {
|
|
266
|
+
if (p.kind === 'property-unchanged-within-tolerance')
|
|
267
|
+
return 'unchanged';
|
|
268
|
+
if (p.kind === 'property-increases')
|
|
269
|
+
return 'increase';
|
|
270
|
+
if (p.kind === 'property-decreases')
|
|
271
|
+
return 'decrease';
|
|
272
|
+
return undefined;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Bounded to structurally-provable contradictions on the same (target, property)
|
|
276
|
+
* pair (e.g. "unchanged" vs "increases", or "increases" vs "decreases") - never a
|
|
277
|
+
* general constraint solver. Two clauses whose contradiction cannot be established
|
|
278
|
+
* this way from their structured form are evaluated independently, per governing
|
|
279
|
+
* scope (Section 8).
|
|
280
|
+
*/
|
|
281
|
+
function primitivesConflict(a, b) {
|
|
282
|
+
const at = primitiveTargetProperty(a);
|
|
283
|
+
const bt = primitiveTargetProperty(b);
|
|
284
|
+
if (!at || !bt)
|
|
285
|
+
return false;
|
|
286
|
+
if (at.target !== bt.target || at.property !== bt.property)
|
|
287
|
+
return false;
|
|
288
|
+
const ad = directionOf(a);
|
|
289
|
+
const bd = directionOf(b);
|
|
290
|
+
return ad !== undefined && bd !== undefined && ad !== bd;
|
|
291
|
+
}
|
|
292
|
+
// --- difference-to-scope matching (deterministic, structural identity only) -----
|
|
293
|
+
function relationshipDiffMatchesPair(diff, family, a, b) {
|
|
294
|
+
if (diff.subject.type !== 'relationship')
|
|
295
|
+
return false;
|
|
296
|
+
if (!family.includes(diff.subject.kind))
|
|
297
|
+
return false;
|
|
298
|
+
const { subjectTarget, relatedTarget } = diff.subject;
|
|
299
|
+
return (subjectTarget === a && relatedTarget === b) || (subjectTarget === b && relatedTarget === a);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* One authored clause "accounts for" a raw `ComparisonDifference` only when
|
|
303
|
+
* their structural subject/kind identity matches (never array position, prose,
|
|
304
|
+
* or fuzzy name matching). `target-begins-below-initial-viewport` is
|
|
305
|
+
* state-only and never accounts for any before/after difference. DOM
|
|
306
|
+
* containment (`containment-changed`) is deliberately never accounted for by
|
|
307
|
+
* any frozen primitive - the vocabulary only models geometric fit
|
|
308
|
+
* (`target-fits-inside`), a distinct concept - so a containment change is
|
|
309
|
+
* always `unexpected`, by design.
|
|
310
|
+
*/
|
|
311
|
+
function primitiveAccountsForDifference(primitive, diff) {
|
|
312
|
+
switch (primitive.kind) {
|
|
313
|
+
case 'target-visible':
|
|
314
|
+
return diff.subject.type === 'target' && diff.subject.target === primitive.target && (diff.kind === 'visibility-changed' || diff.kind === 'appeared' || diff.kind === 'disappeared');
|
|
315
|
+
case 'target-not-clipped':
|
|
316
|
+
return (diff.subject.type === 'target' &&
|
|
317
|
+
diff.subject.target === primitive.target &&
|
|
318
|
+
(diff.kind === 'clipping-changed' || diff.kind === 'horizontal-overflow-changed' || diff.kind === 'vertical-overflow-changed'));
|
|
319
|
+
case 'target-width-within-bound':
|
|
320
|
+
return diff.subject.type === 'target' && diff.subject.target === primitive.target && diff.kind === 'resized';
|
|
321
|
+
case 'property-unchanged-within-tolerance':
|
|
322
|
+
case 'property-increases':
|
|
323
|
+
case 'property-decreases': {
|
|
324
|
+
if (diff.subject.type !== 'target' || diff.subject.target !== primitive.target)
|
|
325
|
+
return false;
|
|
326
|
+
const isPositionProperty = primitive.property === 'x' || primitive.property === 'y';
|
|
327
|
+
return isPositionProperty ? diff.kind === 'moved' : diff.kind === 'resized';
|
|
328
|
+
}
|
|
329
|
+
case 'targets-do-not-overlap':
|
|
330
|
+
return relationshipDiffMatchesPair(diff, AREA_OVERLAP_RELATIONSHIPS, primitive.targetA, primitive.targetB);
|
|
331
|
+
case 'target-wider-than':
|
|
332
|
+
return relationshipDiffMatchesPair(diff, RELATIVE_WIDTH_RELATIONSHIPS, primitive.targetA, primitive.targetB);
|
|
333
|
+
case 'target-follows-vertically':
|
|
334
|
+
return relationshipDiffMatchesPair(diff, VERTICAL_SEQUENCE_RELATIONSHIPS, primitive.targetA, primitive.targetB);
|
|
335
|
+
case 'target-fits-inside':
|
|
336
|
+
return relationshipDiffMatchesPair(diff, GEOMETRIC_FIT_RELATIONSHIPS, primitive.target, primitive.container);
|
|
337
|
+
case 'relationship-unchanged': {
|
|
338
|
+
if (diff.subject.type !== 'relationship')
|
|
339
|
+
return false;
|
|
340
|
+
if (!sameFamily(diff.subject.kind, primitive.relationshipKind))
|
|
341
|
+
return false;
|
|
342
|
+
if (primitive.subjectTarget && diff.subject.subjectTarget !== primitive.subjectTarget)
|
|
343
|
+
return false;
|
|
344
|
+
if (primitive.relatedTarget && diff.subject.relatedTarget !== primitive.relatedTarget)
|
|
345
|
+
return false;
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
case 'document-width-fits-viewport':
|
|
349
|
+
return diff.kind === 'page-size-changed' || (diff.subject.type === 'relationship' && PAGE_WIDTH_RELATIONSHIPS.includes(diff.subject.kind));
|
|
350
|
+
case 'scroll-owner-is-document':
|
|
351
|
+
case 'target-does-not-own-scroll':
|
|
352
|
+
return diff.kind === 'scroll-owner-changed';
|
|
353
|
+
case 'target-begins-below-initial-viewport':
|
|
354
|
+
return false;
|
|
355
|
+
default:
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
function toUnexpectedChangeResult(diff) {
|
|
360
|
+
return { classification: 'unexpected', subject: diff.subject, differenceKind: diff.kind, supportingEvidence: diff.evidence };
|
|
361
|
+
}
|
|
362
|
+
// --- canonical entry point --------------------------------------------------------
|
|
363
|
+
/**
|
|
364
|
+
* The one canonical pure v0.5 contract-evaluation entry point:
|
|
365
|
+
* `active persistent baseline contracts + current per-change contract + actual
|
|
366
|
+
* before/after runtime evidence -> PASS | FAIL` with full clause-level
|
|
367
|
+
* evidence. Deterministic given identical inputs; never mutates
|
|
368
|
+
* before/after/comparison/baseline/change.
|
|
369
|
+
*
|
|
370
|
+
* NOTE: `comparison.differences` already includes one `ComparisonDifference`
|
|
371
|
+
* per `RelationshipChangeRecord` (see `comparisonEngine.ts#relationshipChangesToDifferences`),
|
|
372
|
+
* so unexpected-change derivation consumes `differences` only - iterating
|
|
373
|
+
* `relationshipChanges` separately would double-count the same logical
|
|
374
|
+
* transition.
|
|
375
|
+
*/
|
|
376
|
+
export function evaluateFrontendContract(input) {
|
|
377
|
+
const { before, after, comparison, baseline, change } = input;
|
|
378
|
+
const beforeValidation = isValidObservationArtifact(before);
|
|
379
|
+
if (!beforeValidation.valid)
|
|
380
|
+
return { ok: false, reason: `before ObservationArtifact is invalid: ${beforeValidation.reason}` };
|
|
381
|
+
const afterValidation = isValidObservationArtifact(after);
|
|
382
|
+
if (!afterValidation.valid)
|
|
383
|
+
return { ok: false, reason: `after ObservationArtifact is invalid: ${afterValidation.reason}` };
|
|
384
|
+
const comparisonValidation = isValidComparisonArtifact(comparison);
|
|
385
|
+
if (!comparisonValidation.valid)
|
|
386
|
+
return { ok: false, reason: `ComparisonArtifact is invalid: ${comparisonValidation.reason}` };
|
|
387
|
+
const baselineValidation = isValidPersistentBaselineContract(baseline);
|
|
388
|
+
if (!baselineValidation.valid)
|
|
389
|
+
return { ok: false, reason: `PersistentBaselineContract is invalid: ${baselineValidation.reason}` };
|
|
390
|
+
const changeValidation = isValidPerChangeContract(change);
|
|
391
|
+
if (!changeValidation.valid)
|
|
392
|
+
return { ok: false, reason: `PerChangeContract is invalid: ${changeValidation.reason}` };
|
|
393
|
+
if (comparison.before.observationId !== before.observationId) {
|
|
394
|
+
return { ok: false, reason: 'comparison.before.observationId does not match the supplied before observation' };
|
|
395
|
+
}
|
|
396
|
+
if (comparison.after.observationId !== after.observationId) {
|
|
397
|
+
return { ok: false, reason: 'comparison.after.observationId does not match the supplied after observation' };
|
|
398
|
+
}
|
|
399
|
+
const baselineClauseIds = new Set(baseline.clauses.map((c) => c.clauseId));
|
|
400
|
+
const supersededIds = new Set();
|
|
401
|
+
for (const c of change.clauses) {
|
|
402
|
+
for (const id of c.supersedesBaselineClauseIds ?? []) {
|
|
403
|
+
if (baselineClauseIds.has(id))
|
|
404
|
+
supersededIds.add(id);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
const activeBaseline = baseline.clauses.filter((c) => !supersededIds.has(c.clauseId));
|
|
408
|
+
const activeBaselineClauseIds = activeBaseline.map((c) => c.clauseId);
|
|
409
|
+
if (comparison.comparability.state === 'incomparable') {
|
|
410
|
+
const clauseResults = [
|
|
411
|
+
...activeBaseline.map((c) => toClauseResult(c.clauseId, 'unavailable', c.supportingEvidence)),
|
|
412
|
+
...change.clauses.map((c) => toClauseResult(c.clauseId, 'unavailable', c.supportingEvidence)),
|
|
413
|
+
].map((r) => (r.status === 'unavailable' ? { ...r, reason: 'comparison is incomparable; frontend contract clauses cannot be evaluated' } : r));
|
|
414
|
+
return {
|
|
415
|
+
ok: true,
|
|
416
|
+
evaluation: { overallVerdict: 'FAIL', activeBaselineClauseIds, supersededBaselineClauseIds: [...supersededIds], clauseResults, unexpectedChanges: [] },
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
const ctx = { before, after, comparison };
|
|
420
|
+
const clauseResults = [];
|
|
421
|
+
for (const c of activeBaseline) {
|
|
422
|
+
const conflictingChange = change.clauses.find((cc) => !(cc.supersedesBaselineClauseIds ?? []).includes(c.clauseId) && primitivesConflict(c.primitive, cc.primitive));
|
|
423
|
+
if (conflictingChange) {
|
|
424
|
+
const reason = `baseline clause "${c.clauseId}" and per-change clause "${conflictingChange.clauseId}" impose contradictory requirements on the same property without explicit supersession`;
|
|
425
|
+
clauseResults.push({ clauseId: c.clauseId, status: 'conflict', reason, conflictingClauseIds: [c.clauseId, conflictingChange.clauseId], supportingEvidence: c.supportingEvidence });
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
clauseResults.push(evaluateClause(c.clauseId, c.primitive, 'preserved', ctx, c.supportingEvidence));
|
|
429
|
+
}
|
|
430
|
+
for (const c of change.clauses) {
|
|
431
|
+
const unknownRefs = (c.supersedesBaselineClauseIds ?? []).filter((id) => !baselineClauseIds.has(id));
|
|
432
|
+
if (unknownRefs.length > 0) {
|
|
433
|
+
const reason = `per-change clause "${c.clauseId}" supersedesBaselineClauseIds references unknown baseline clause id(s): ${unknownRefs.join(', ')}`;
|
|
434
|
+
clauseResults.push({ clauseId: c.clauseId, status: 'conflict', reason, conflictingClauseIds: [c.clauseId, ...unknownRefs], supportingEvidence: c.supportingEvidence });
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
const conflictingBaseline = activeBaseline.find((b) => !(c.supersedesBaselineClauseIds ?? []).includes(b.clauseId) && primitivesConflict(b.primitive, c.primitive));
|
|
438
|
+
if (conflictingBaseline) {
|
|
439
|
+
const reason = `per-change clause "${c.clauseId}" and baseline clause "${conflictingBaseline.clauseId}" impose contradictory requirements on the same property without explicit supersession`;
|
|
440
|
+
clauseResults.push({ clauseId: c.clauseId, status: 'conflict', reason, conflictingClauseIds: [conflictingBaseline.clauseId, c.clauseId], supportingEvidence: c.supportingEvidence });
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
const mode = clauseMode(c.category, c.expectedDependentMode);
|
|
444
|
+
clauseResults.push(evaluateClause(c.clauseId, c.primitive, mode, ctx, c.supportingEvidence));
|
|
445
|
+
}
|
|
446
|
+
const authoredPrimitives = [...activeBaseline.map((c) => c.primitive), ...change.clauses.map((c) => c.primitive)];
|
|
447
|
+
const unexpectedChanges = comparison.differences.filter((d) => !authoredPrimitives.some((p) => primitiveAccountsForDifference(p, d))).map(toUnexpectedChangeResult);
|
|
448
|
+
const overallVerdict = clauseResults.every((r) => r.status === 'pass') && unexpectedChanges.length === 0 ? 'PASS' : 'FAIL';
|
|
449
|
+
return {
|
|
450
|
+
ok: true,
|
|
451
|
+
evaluation: { overallVerdict, activeBaselineClauseIds, supersededBaselineClauseIds: [...supersededIds], clauseResults, unexpectedChanges },
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
//# sourceMappingURL=frontendContractEvaluation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontendContractEvaluation.js","sourceRoot":"","sources":["../../src/domain/frontendContractEvaluation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { PRODUCER_NAME } from './schema.js';
|
|
2
|
+
import type { ClauseEvaluationResult, OverallVerdict, FrontendContractObservationReference } from './frontendContracts.js';
|
|
3
|
+
import type { UnexpectedChangeResult } from './frontendContractEvaluation.js';
|
|
4
|
+
export declare const EVALUATION_ARTIFACT_KIND: "my-frontend-observer/frontend-contract-evaluation";
|
|
5
|
+
export declare const EVALUATION_SCHEMA_VERSION: "1.0.0";
|
|
6
|
+
/** Enough logical identity to trace an evaluation back to its authoritative baseline/per-change contract without embedding either in full. */
|
|
7
|
+
export interface FrontendContractEvaluationSourceReference {
|
|
8
|
+
baselineId: string;
|
|
9
|
+
contractId: string;
|
|
10
|
+
}
|
|
11
|
+
export interface FrontendContractEvaluationArtifact {
|
|
12
|
+
artifactKind: typeof EVALUATION_ARTIFACT_KIND;
|
|
13
|
+
schemaVersion: typeof EVALUATION_SCHEMA_VERSION;
|
|
14
|
+
evaluationId: string;
|
|
15
|
+
evaluationRequestId: string;
|
|
16
|
+
producer: {
|
|
17
|
+
name: typeof PRODUCER_NAME;
|
|
18
|
+
version: string;
|
|
19
|
+
};
|
|
20
|
+
provenance: {
|
|
21
|
+
evaluatedAt: string;
|
|
22
|
+
};
|
|
23
|
+
contracts: FrontendContractEvaluationSourceReference;
|
|
24
|
+
before: FrontendContractObservationReference;
|
|
25
|
+
after: FrontendContractObservationReference;
|
|
26
|
+
comparisonId: string;
|
|
27
|
+
comparisonRequestId: string;
|
|
28
|
+
overallVerdict: OverallVerdict;
|
|
29
|
+
activeBaselineClauseIds: string[];
|
|
30
|
+
supersededBaselineClauseIds: string[];
|
|
31
|
+
clauseResults: ClauseEvaluationResult[];
|
|
32
|
+
unexpectedChanges: UnexpectedChangeResult[];
|
|
33
|
+
}
|
|
34
|
+
export type FrontendContractEvaluationArtifactValidationResult = {
|
|
35
|
+
valid: true;
|
|
36
|
+
} | {
|
|
37
|
+
valid: false;
|
|
38
|
+
reason: string;
|
|
39
|
+
};
|
|
40
|
+
export declare function isValidFrontendContractEvaluationArtifact(value: unknown): FrontendContractEvaluationArtifactValidationResult;
|
|
41
|
+
/**
|
|
42
|
+
* Pure assembly of the persistence envelope around an already-computed
|
|
43
|
+
* `FrontendContractEvaluationResult` (from `evaluateFrontendContract`) - never
|
|
44
|
+
* recomputes or reinterprets the evaluation. Callers (the application layer)
|
|
45
|
+
* supply the fresh `evaluationId`/`evaluationRequestId` from
|
|
46
|
+
* `frontendContractIdentity.ts` and the `evaluatedAt` timestamp.
|
|
47
|
+
*/
|
|
48
|
+
export interface BuildFrontendContractEvaluationArtifactInput {
|
|
49
|
+
evaluationId: string;
|
|
50
|
+
evaluationRequestId: string;
|
|
51
|
+
producerVersion: string;
|
|
52
|
+
evaluatedAt: string;
|
|
53
|
+
baselineId: string;
|
|
54
|
+
contractId: string;
|
|
55
|
+
before: FrontendContractObservationReference;
|
|
56
|
+
after: FrontendContractObservationReference;
|
|
57
|
+
comparisonId: string;
|
|
58
|
+
comparisonRequestId: string;
|
|
59
|
+
overallVerdict: OverallVerdict;
|
|
60
|
+
activeBaselineClauseIds: string[];
|
|
61
|
+
supersededBaselineClauseIds: string[];
|
|
62
|
+
clauseResults: ClauseEvaluationResult[];
|
|
63
|
+
unexpectedChanges: UnexpectedChangeResult[];
|
|
64
|
+
}
|
|
65
|
+
export declare function buildFrontendContractEvaluationArtifact(input: BuildFrontendContractEvaluationArtifactInput): FrontendContractEvaluationArtifact;
|