@ryuenn3123/agentic-senior-core 3.0.37 → 3.0.38
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/.agent-context/prompts/bootstrap-design.md +108 -146
- package/.agent-context/rules/frontend-architecture.md +92 -108
- package/.agent-context/state/README.md +26 -0
- package/.cursor/mcp.json +10 -0
- package/.cursor/rules/agentic-senior-core.mdc +48 -0
- package/.cursorrules +22 -88
- package/.gemini/instructions.md +25 -16
- package/.github/copilot-instructions.md +25 -16
- package/.github/instructions/agentic-senior-core.instructions.md +47 -0
- package/.instructions.md +98 -207
- package/.windsurf/rules/agentic-senior-core.md +43 -0
- package/.windsurfrules +22 -88
- package/AGENTS.md +23 -26
- package/CLAUDE.md +43 -0
- package/CONTRIBUTING.md +5 -2
- package/GEMINI.md +43 -0
- package/README.md +24 -7
- package/lib/cli/backup.mjs +4 -4
- package/lib/cli/commands/init/project-context.mjs +101 -0
- package/lib/cli/commands/init/runtime-environment.mjs +59 -0
- package/lib/cli/commands/init/setup-decisions.mjs +83 -0
- package/lib/cli/commands/init.mjs +33 -250
- package/lib/cli/commands/optimize.mjs +1 -1
- package/lib/cli/commands/upgrade.mjs +32 -7
- package/lib/cli/compiler.mjs +59 -17
- package/lib/cli/constants.mjs +5 -0
- package/lib/cli/detector.mjs +4 -0
- package/lib/cli/preflight.mjs +3 -3
- package/lib/cli/project-scaffolder/design-contract/validation.mjs +789 -0
- package/lib/cli/project-scaffolder/design-contract.mjs +119 -924
- package/lib/cli/project-scaffolder/prompt-builders.mjs +69 -84
- package/lib/cli/utils/filesystem.mjs +79 -0
- package/lib/cli/utils/managed-surface.mjs +237 -0
- package/lib/cli/utils/prompting.mjs +44 -0
- package/lib/cli/utils.mjs +33 -335
- package/package.json +21 -2
- package/scripts/clean-local-artifacts.mjs +76 -0
- package/scripts/docs-quality-drift-report.mjs +5 -0
- package/scripts/frontend-usability-audit.mjs +23 -19
- package/scripts/governance-weekly-report.mjs +37 -15
- package/scripts/single-source-lazy-loading-audit.mjs +24 -0
- package/scripts/sync-thin-adapters.mjs +99 -129
- package/scripts/v3-purge-audit.mjs +5 -0
- package/scripts/validate/config.mjs +10 -0
- package/scripts/validate/coverage-checks.mjs +55 -0
- package/.agent-context/marketplace/trust-tiers.json +0 -114
- package/.agent-context/state/benchmark-analysis.json +0 -431
- package/.agent-context/state/benchmark-evidence-bundle.json +0 -1040
- package/.agent-context/state/benchmark-history.json +0 -75
- package/.agent-context/state/benchmark-trend-report.csv +0 -5
- package/.agent-context/state/benchmark-trend-report.json +0 -140
- package/.agent-context/state/benchmark-writer-judge-matrix.json +0 -462
- package/.agent-context/state/memory-continuity-benchmark.json +0 -132
- package/.agent-context/state/onboarding-report.json +0 -102
- package/.agent-context/state/quality-trend-report.json +0 -89
- package/.agent-context/state/token-optimization-benchmark.json +0 -130
- package/.agent-context/state/weekly-governance-report.json +0 -329
- package/lib/cli/compatibility.mjs +0 -124
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
import { toTitleCase } from '../utils.mjs';
|
|
2
2
|
import { DESIGN_REQUIRED_SECTIONS } from './constants.mjs';
|
|
3
|
+
import { validateDesignIntentContract } from './design-contract/validation.mjs';
|
|
4
|
+
|
|
5
|
+
const GENERICITY_DRIFT_SIGNALS = [
|
|
6
|
+
'offline-prescribed-style-used-as-final-direction',
|
|
7
|
+
'unresearched-library-or-framework-choice',
|
|
8
|
+
'missing-conceptual-anchor-without-external-research',
|
|
9
|
+
'visual-decisions-not-derived-from-conceptual-anchor',
|
|
10
|
+
'ai-safe-ui-template-look',
|
|
11
|
+
'ai-color-default-palette-without-product-role-behavior',
|
|
12
|
+
'brandless-clean-template-look',
|
|
13
|
+
'interchangeable-product-renaming-test-fails',
|
|
14
|
+
'decorative-grid-or-glow-wallpaper-without-product-function',
|
|
15
|
+
'safe-cream-slate-or-monochrome-palette-used-as-readability-excuse',
|
|
16
|
+
'generic-abstract-logo-or-iconography',
|
|
17
|
+
'timid-anchor-that-renames-dashboard-or-admin-shell',
|
|
18
|
+
'motion-suppressed-without-accessibility-or-performance-reason',
|
|
19
|
+
'motion-or-3d-omitted-from-fear-without-fit-analysis',
|
|
20
|
+
'scale-only-responsive-layout',
|
|
21
|
+
'zero-based-redesign-kept-prior-visual-dna',
|
|
22
|
+
'restyle-instead-of-recomposition',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const FORBIDDEN_PATTERN_SIGNALS = [
|
|
26
|
+
...GENERICITY_DRIFT_SIGNALS.filter((signal) => signal !== 'unresearched-library-or-framework-choice'),
|
|
27
|
+
'single-safe-typographic-family-without-role-contrast-or-rationale',
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const VALID_BOLD_SIGNALS = [
|
|
31
|
+
'single-cohesive-conceptual-anchor',
|
|
32
|
+
'high-variance-candidate-selection',
|
|
33
|
+
'context-derived-visual-direction',
|
|
34
|
+
'three-at-a-glance-product-specific-signals',
|
|
35
|
+
'visually-exploratory-accessible-palette-derived-from-product',
|
|
36
|
+
'audacious-accessible-palette-with-product-role-behavior',
|
|
37
|
+
'background-or-geometry-serves-product-function',
|
|
38
|
+
'motion-or-spatial-experience-derived-from-anchor',
|
|
39
|
+
'explicit-3d-canvas-fit-or-nonfit-decision',
|
|
40
|
+
'responsive-recomposition-by-task-priority',
|
|
41
|
+
'purposeful-motion-with-reduced-motion-path',
|
|
42
|
+
];
|
|
3
43
|
|
|
4
44
|
export function shouldBootstrapDesignDocument(discoveryAnswers, initContext) {
|
|
5
45
|
const normalizedDomain = String(discoveryAnswers.primaryDomain || '').trim().toLowerCase();
|
|
@@ -51,26 +91,26 @@ function buildStructureFirstSeedSignals({
|
|
|
51
91
|
: 'the current product context';
|
|
52
92
|
|
|
53
93
|
return {
|
|
54
|
-
designPhilosophy: `
|
|
94
|
+
designPhilosophy: `Synthesize design for ${projectName || 'this project'} from ${evidenceSourceLabel}. Choose visual language, libraries, color, type, spacing, and interaction from ${projectContextLabel}; verify technology claims with official docs.`,
|
|
55
95
|
typographyScaleRatio: 'agent-calibrated-from-content-platform-and-readability',
|
|
56
96
|
baseGridUnit: 'agent-calibrated-from-platform-density-and-implementation-stack',
|
|
57
97
|
spacingPattern: 'agent-defined-from-task-flow-and-viewport-needs',
|
|
58
98
|
densityMode: 'agent-defined-from-user-task-device-and-content-pressure',
|
|
59
|
-
colorIntent: `Choose semantic palette roles from ${projectContextLabel},
|
|
99
|
+
colorIntent: `Choose semantic palette roles from ${projectContextLabel}, repo evidence, and accessibility. Reject scaffold or SaaS palette defaults.`,
|
|
60
100
|
paletteRoles: ['agent-defined-semantic-roles'],
|
|
61
101
|
distinctiveMoves: [
|
|
62
|
-
'Choose one
|
|
102
|
+
'Choose one product-specific move from task, audience, content, repo evidence, and docs.',
|
|
63
103
|
],
|
|
64
|
-
motionPurpose: '
|
|
104
|
+
motionPurpose: 'Use expressive motion when it improves hierarchy, continuity, feedback, memorability, or confidence. Verify new motion libraries with official docs.',
|
|
65
105
|
componentMorphology: {
|
|
66
|
-
mobile: 'Recompose
|
|
67
|
-
tablet: 'Regroup surfaces for medium
|
|
68
|
-
desktop: 'Use
|
|
106
|
+
mobile: 'Recompose for touch, task priority, and constrained attention.',
|
|
107
|
+
tablet: 'Regroup surfaces for medium width without cloning desktop or mobile.',
|
|
108
|
+
desktop: 'Use space for hierarchy and scanability; avoid template grids.',
|
|
69
109
|
},
|
|
70
110
|
mutationRules: {
|
|
71
|
-
mobile: '
|
|
72
|
-
tablet: '
|
|
73
|
-
desktop: '
|
|
111
|
+
mobile: 'Reorder, merge, or disclose content for mobile. Reject scale-only shrink.',
|
|
112
|
+
tablet: 'Regroup for tablet instead of width-only desktop reduction.',
|
|
113
|
+
desktop: 'Use space intentionally; avoid equal-weight modules without evidence.',
|
|
74
114
|
},
|
|
75
115
|
};
|
|
76
116
|
}
|
|
@@ -132,7 +172,7 @@ function buildDesignIntentContractObject({
|
|
|
132
172
|
'ui-primitives-or-rich-media',
|
|
133
173
|
'typography-and-interaction',
|
|
134
174
|
],
|
|
135
|
-
finalDecisionAuthority: '
|
|
175
|
+
finalDecisionAuthority: 'project-fit-accessibility-performance-maintainability-official-docs',
|
|
136
176
|
},
|
|
137
177
|
conceptualAnchor: {
|
|
138
178
|
mode: 'required-when-no-external-research',
|
|
@@ -163,7 +203,7 @@ function buildDesignIntentContractObject({
|
|
|
163
203
|
'typographicDecision',
|
|
164
204
|
],
|
|
165
205
|
rejectGenericQualityWordsOnly: true,
|
|
166
|
-
specificityFloor: 'name-
|
|
206
|
+
specificityFloor: 'name-real-material-instrument-artifact-architecture-editorial-genre-cinematic-behavior-exhibition-system-scientific-apparatus-or-industrial-mechanism',
|
|
167
207
|
},
|
|
168
208
|
forbiddenFinalAnchorTerms: [
|
|
169
209
|
'dashboard',
|
|
@@ -219,64 +259,64 @@ function buildDesignIntentContractObject({
|
|
|
219
259
|
},
|
|
220
260
|
derivedTokenLogic: {
|
|
221
261
|
anchorReference: 'agent-defined-anchor-reference',
|
|
222
|
-
colorDerivationSource: '
|
|
223
|
-
spacingDerivationSource: '
|
|
224
|
-
typographyDerivationSource: '
|
|
225
|
-
motionDerivationSource: '
|
|
226
|
-
validationRule: 'Every
|
|
262
|
+
colorDerivationSource: 'Explain semantic color roles from anchorReference; reject generic palettes without anchor evidence.',
|
|
263
|
+
spacingDerivationSource: 'Explain grid, rhythm, density, and exceptions from anchorReference.',
|
|
264
|
+
typographyDerivationSource: 'Explain display, body, metadata, and data roles from anchorReference.',
|
|
265
|
+
motionDerivationSource: 'Explain duration, easing, choreography, and reduced-motion from anchorReference.',
|
|
266
|
+
validationRule: 'Every token must trace to anchorReference; revise tokens that cannot.',
|
|
227
267
|
},
|
|
228
268
|
motionPaletteDecision: {
|
|
229
269
|
productCategorySignal: 'agent-inferred-starting-heuristic',
|
|
230
|
-
densityDecisionSource: '
|
|
270
|
+
densityDecisionSource: 'Choose motion density from task, content, brand, device, performance, and accessibility. Categories are heuristics.',
|
|
231
271
|
requiredInteractionStates: ['default', 'hover', 'focus-visible', 'active', 'disabled', 'loading', 'empty', 'error', 'success', 'transition'],
|
|
232
272
|
paletteAutopilotRisks: ['dark-slate-default', 'cream-beige-default', 'purple-blue-gradient-default', 'monochrome-template-default', 'uniform-card-surface-default', 'generic-grid-wallpaper-default', 'soft-glow-ai-template-default', 'cyber-neon-terminal-default'],
|
|
233
|
-
spatialDecision: '
|
|
273
|
+
spatialDecision: 'State 3D/canvas/WebGL fit. If omitted, name product-fit reason and replacement interaction quality.',
|
|
234
274
|
},
|
|
235
275
|
aiSafeUiAudit: {
|
|
236
276
|
status: 'agent-must-complete-before-ui-implementation',
|
|
237
|
-
failureDefinition: '
|
|
238
|
-
interchangeabilityTest: `If this UI can be renamed from ${projectName} to another product category without changing composition, palette, iconography, and motion
|
|
277
|
+
failureDefinition: 'AI-safe UI uses template cards, generic marks, decorative grid wallpaper, safe palettes, glow backgrounds, or copied scaffold composition.',
|
|
278
|
+
interchangeabilityTest: `If this UI can be renamed from ${projectName} to another product category without changing composition, palette, iconography, and motion, revise it.`,
|
|
239
279
|
requiredProductSpecificSignals: [
|
|
240
280
|
'agent-defined-product-specific-data-treatment',
|
|
241
281
|
'agent-defined-product-specific-motion-or-state-behavior',
|
|
242
282
|
'agent-defined-product-specific-morphology-iconography-or-spatial-structure',
|
|
243
283
|
],
|
|
244
|
-
paletteExplorationRule: 'Use a visually exploratory product-derived palette
|
|
245
|
-
backgroundPatternRule: 'Lines, grids, scanlines, noise, glows, blobs, logos, and
|
|
284
|
+
paletteExplorationRule: 'Use a visually exploratory product-derived palette with WCAG contrast and status clarity.',
|
|
285
|
+
backgroundPatternRule: 'Lines, grids, scanlines, noise, glows, blobs, logos, and geometry must serve a named product function.',
|
|
246
286
|
aiColorAudit: {
|
|
247
287
|
status: 'agent-must-complete-before-ui-implementation',
|
|
248
|
-
failureDefinition: 'AI color drift
|
|
288
|
+
failureDefinition: 'AI color drift uses safe defaults before deriving roles from the product anchor.',
|
|
249
289
|
autopilotRisks: ['cream-editorial-default', 'dark-slate-dashboard-default', 'purple-blue-gradient-default', 'monochrome-minimal-default', 'cyber-neon-terminal-default', 'soft-glow-atmosphere-default'],
|
|
250
290
|
requiredEvidence: [
|
|
251
291
|
'anchor-derived-color-logic',
|
|
252
292
|
'semantic-role-contrast-beyond-surface-decoration',
|
|
253
293
|
'product-specific-color-behavior-that-would-not-transfer',
|
|
254
294
|
],
|
|
255
|
-
reviewQuestion: 'Why does this palette belong to this product
|
|
295
|
+
reviewQuestion: 'Why does this palette belong to this product?',
|
|
256
296
|
},
|
|
257
297
|
motionSpatialCourageAudit: {
|
|
258
298
|
status: 'agent-must-complete-before-ui-implementation',
|
|
259
|
-
defaultStance: 'Treat motion, scroll choreography, canvas, WebGL, and 3D as first-class options
|
|
299
|
+
defaultStance: 'Treat motion, scroll choreography, canvas, WebGL, and 3D as first-class options.',
|
|
260
300
|
requiredDecisionFields: [
|
|
261
301
|
'signature-motion-or-interaction',
|
|
262
302
|
'spatial-or-3d-fit',
|
|
263
303
|
'performance-and-reduced-motion-fallback',
|
|
264
304
|
],
|
|
265
|
-
rejectionRule: '
|
|
266
|
-
reviewQuestion: '
|
|
305
|
+
rejectionRule: 'State a product reason and replacement interaction quality before omitting 3D/canvas.',
|
|
306
|
+
reviewQuestion: 'Is the interaction as expressive as the product can responsibly support?',
|
|
267
307
|
},
|
|
268
|
-
reviewQuestion: 'What
|
|
308
|
+
reviewQuestion: 'What visible evidence proves this is product-specific?',
|
|
269
309
|
blockingByDefault: true,
|
|
270
310
|
},
|
|
271
311
|
libraryResearchStatus: 'pending-verification',
|
|
272
312
|
libraryDecisions: [
|
|
273
313
|
{
|
|
274
314
|
library: 'agent-defined-or-none',
|
|
275
|
-
purpose: '
|
|
315
|
+
purpose: 'Verify UI-related libraries against current official docs before imports.',
|
|
276
316
|
verifiedAt: null,
|
|
277
317
|
sourceUrl: null,
|
|
278
318
|
stableVersion: null,
|
|
279
|
-
fallbackIfUnavailable: 'Use native CSS, browser APIs, or existing
|
|
319
|
+
fallbackIfUnavailable: 'Use native CSS, browser APIs, or existing dependencies.',
|
|
280
320
|
},
|
|
281
321
|
],
|
|
282
322
|
mathSystems: {
|
|
@@ -391,12 +431,12 @@ function buildDesignIntentContractObject({
|
|
|
391
431
|
status: 'seed-needs-refinement',
|
|
392
432
|
seedMode: 'structure-first-scaffold',
|
|
393
433
|
requiresTaskSpecificRefinement: true,
|
|
394
|
-
primaryExperienceGoal: `Define the main ${String(primaryDomain || 'product').toLowerCase()} journey for ${projectName} from repo evidence,
|
|
434
|
+
primaryExperienceGoal: `Define the main ${String(primaryDomain || 'product').toLowerCase()} journey for ${projectName} from repo evidence, brief, and docs.`,
|
|
395
435
|
surfacePlan: [
|
|
396
436
|
{
|
|
397
437
|
surfaceId: 'agent-defined-primary-experience',
|
|
398
438
|
role: 'primary-context-synthesized-by-agent',
|
|
399
|
-
goal: 'Choose the first task
|
|
439
|
+
goal: 'Choose the first task path from product evidence; reject template shells.',
|
|
400
440
|
antiPatterns: ['dashboard-default', 'scale-only-responsive-layout'],
|
|
401
441
|
},
|
|
402
442
|
],
|
|
@@ -471,12 +511,12 @@ function buildDesignIntentContractObject({
|
|
|
471
511
|
{
|
|
472
512
|
componentId: 'primary-interaction',
|
|
473
513
|
states: ['default', 'hover', 'focus', 'loading', 'error'],
|
|
474
|
-
notes: 'Refine states from project language and
|
|
514
|
+
notes: 'Refine states from project language and anchor; reject anonymous panels.',
|
|
475
515
|
},
|
|
476
516
|
],
|
|
477
517
|
taskFlowNarrative: [
|
|
478
|
-
`Entry:
|
|
479
|
-
'Resolution: define proof, feedback, recovery, and next action
|
|
518
|
+
`Entry: start ${projectName} from real evidence, not a generic opener.`,
|
|
519
|
+
'Resolution: define proof, feedback, recovery, and next action.',
|
|
480
520
|
],
|
|
481
521
|
visualResetStrategy: {
|
|
482
522
|
activatesWhenUserRequests: [
|
|
@@ -487,7 +527,7 @@ function buildDesignIntentContractObject({
|
|
|
487
527
|
existingUiForbiddenAs: ['palette-source', 'layout-source', 'motion-source'],
|
|
488
528
|
requiredResetAxes: ['composition', 'hierarchy', 'motion-or-interaction', 'responsive-information-architecture'],
|
|
489
529
|
},
|
|
490
|
-
signatureMoveRationale: '
|
|
530
|
+
signatureMoveRationale: 'Choose one project-specific visual, motion, type, or interaction move.',
|
|
491
531
|
creativeCommitment: {
|
|
492
532
|
status: 'agent-must-complete-before-ui-implementation',
|
|
493
533
|
requiredFields: [
|
|
@@ -495,7 +535,7 @@ function buildDesignIntentContractObject({
|
|
|
495
535
|
'signatureMotion',
|
|
496
536
|
'typographicDecision',
|
|
497
537
|
],
|
|
498
|
-
failureMode: 'generic quality words without a
|
|
538
|
+
failureMode: 'generic quality words without a real-world reference fail',
|
|
499
539
|
},
|
|
500
540
|
implementationGuardrails: {
|
|
501
541
|
requireBuildFromHandoff: true,
|
|
@@ -510,61 +550,31 @@ function buildDesignIntentContractObject({
|
|
|
510
550
|
{
|
|
511
551
|
key: 'distinctiveness',
|
|
512
552
|
blockingByDefault: true,
|
|
513
|
-
question: '
|
|
553
|
+
question: 'Is the UI authored and product-specific?',
|
|
514
554
|
},
|
|
515
555
|
{
|
|
516
556
|
key: 'contractFidelity',
|
|
517
557
|
blockingByDefault: true,
|
|
518
|
-
question: 'Does the
|
|
558
|
+
question: 'Does the UI follow contract, priorities, and accessibility?',
|
|
519
559
|
},
|
|
520
560
|
{
|
|
521
561
|
key: 'visualConsistency',
|
|
522
562
|
blockingByDefault: false,
|
|
523
|
-
question: 'Do
|
|
563
|
+
question: 'Do type, spacing, color, and states form one system?',
|
|
524
564
|
},
|
|
525
565
|
{
|
|
526
566
|
key: 'heuristicUxQuality',
|
|
527
567
|
blockingByDefault: false,
|
|
528
|
-
question: 'Does the UI preserve
|
|
568
|
+
question: 'Does the UI preserve clarity, feedback, and confidence?',
|
|
529
569
|
},
|
|
530
570
|
{
|
|
531
571
|
key: 'motionDiscipline',
|
|
532
572
|
blockingByDefault: false,
|
|
533
|
-
question: '
|
|
573
|
+
question: 'Is motion purposeful, performant, reduced-motion-safe, and on-tone?',
|
|
534
574
|
},
|
|
535
575
|
],
|
|
536
|
-
genericitySignals: [
|
|
537
|
-
|
|
538
|
-
'unresearched-library-or-framework-choice',
|
|
539
|
-
'missing-conceptual-anchor-without-external-research',
|
|
540
|
-
'visual-decisions-not-derived-from-conceptual-anchor',
|
|
541
|
-
'ai-safe-ui-template-look',
|
|
542
|
-
'ai-color-default-palette-without-product-role-behavior',
|
|
543
|
-
'brandless-clean-template-look',
|
|
544
|
-
'interchangeable-product-renaming-test-fails',
|
|
545
|
-
'decorative-grid-or-glow-wallpaper-without-product-function',
|
|
546
|
-
'safe-cream-slate-or-monochrome-palette-used-as-readability-excuse',
|
|
547
|
-
'generic-abstract-logo-or-iconography',
|
|
548
|
-
'timid-anchor-that-renames-dashboard-or-admin-shell',
|
|
549
|
-
'motion-suppressed-without-accessibility-or-performance-reason',
|
|
550
|
-
'motion-or-3d-omitted-from-fear-without-fit-analysis',
|
|
551
|
-
'scale-only-responsive-layout',
|
|
552
|
-
'zero-based-redesign-kept-prior-visual-dna',
|
|
553
|
-
'restyle-instead-of-recomposition',
|
|
554
|
-
],
|
|
555
|
-
validBoldSignals: [
|
|
556
|
-
'single-cohesive-conceptual-anchor',
|
|
557
|
-
'high-variance-candidate-selection',
|
|
558
|
-
'context-derived-visual-direction',
|
|
559
|
-
'three-at-a-glance-product-specific-signals',
|
|
560
|
-
'visually-exploratory-accessible-palette-derived-from-product',
|
|
561
|
-
'audacious-accessible-palette-with-product-role-behavior',
|
|
562
|
-
'background-or-geometry-serves-product-function',
|
|
563
|
-
'motion-or-spatial-experience-derived-from-anchor',
|
|
564
|
-
'explicit-3d-canvas-fit-or-nonfit-decision',
|
|
565
|
-
'responsive-recomposition-by-task-priority',
|
|
566
|
-
'purposeful-motion-with-reduced-motion-path',
|
|
567
|
-
],
|
|
576
|
+
genericitySignals: [...GENERICITY_DRIFT_SIGNALS],
|
|
577
|
+
validBoldSignals: [...VALID_BOLD_SIGNALS],
|
|
568
578
|
reportingRules: {
|
|
569
579
|
mustExplainGenericity: true,
|
|
570
580
|
mustSeparateTasteFromFailure: true,
|
|
@@ -588,74 +598,45 @@ function buildDesignIntentContractObject({
|
|
|
588
598
|
repoEvidenceOverridesMemory: true,
|
|
589
599
|
requireExplicitContinuityApproval: true,
|
|
590
600
|
forbidCarryoverWhenUnapproved: true,
|
|
591
|
-
approvedExternalConstraintUsage: 'Convert
|
|
601
|
+
approvedExternalConstraintUsage: 'Convert approved external constraints into current-project rules; do not imitate source surfaces.',
|
|
592
602
|
driftSignals: [
|
|
593
603
|
'palette-reused-without-brief-support',
|
|
594
604
|
'prior-ui-visual-dna-carried-into-reset-request',
|
|
595
605
|
],
|
|
596
606
|
},
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
'
|
|
600
|
-
'
|
|
601
|
-
'
|
|
602
|
-
'
|
|
603
|
-
'
|
|
604
|
-
'
|
|
605
|
-
'
|
|
606
|
-
'
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
'
|
|
610
|
-
'
|
|
611
|
-
'
|
|
612
|
-
'
|
|
613
|
-
'
|
|
614
|
-
'
|
|
615
|
-
'
|
|
616
|
-
'
|
|
617
|
-
'
|
|
618
|
-
'
|
|
619
|
-
'
|
|
620
|
-
'
|
|
621
|
-
'
|
|
622
|
-
'
|
|
623
|
-
'
|
|
624
|
-
'
|
|
625
|
-
'
|
|
607
|
+
forbiddenPatterns: [...FORBIDDEN_PATTERN_SIGNALS],
|
|
608
|
+
validationHints: [
|
|
609
|
+
'rejectArbitraryHexOnlyPalette',
|
|
610
|
+
'requireViewportMutationRules',
|
|
611
|
+
'requirePerceptualColorRationale',
|
|
612
|
+
'requireTokenLayering',
|
|
613
|
+
'requireTokenAliasingPlan',
|
|
614
|
+
'allowHexDerivatives',
|
|
615
|
+
'requireMotionRationale',
|
|
616
|
+
'requireStateMorphology',
|
|
617
|
+
'requireAccessibilitySplit',
|
|
618
|
+
'requireWcagHardFloor',
|
|
619
|
+
'requireStructuredDesignExecutionPolicy',
|
|
620
|
+
'requireStructuredDesignHandoff',
|
|
621
|
+
'requireVisualResetStrategyWhenZeroBasedRedesignRequested',
|
|
622
|
+
'requireConceptualAnchorWhenNoExternalResearch',
|
|
623
|
+
'requireAgentLedAnchorResearchWhenUserResearchMissing',
|
|
624
|
+
'rejectTimidDashboardAnchor',
|
|
625
|
+
'requireReviewRubric',
|
|
626
|
+
'requireGenericityExplanation',
|
|
627
|
+
'genericityAutoFail',
|
|
628
|
+
'requireSignatureMove',
|
|
629
|
+
'rejectTemplateNeutralLayout',
|
|
630
|
+
'requireAiSafeUiAudit',
|
|
631
|
+
'requireAiColorAudit',
|
|
632
|
+
'rejectAiColorDefaults',
|
|
633
|
+
'requireMotionSpatialCourageAudit',
|
|
634
|
+
'requireExplicit3dCanvasFitDecision',
|
|
635
|
+
'rejectSafetyAsCreativitySubstitute',
|
|
636
|
+
'rejectAiSafeUiTemplateLook',
|
|
637
|
+
'requireThreeProductSpecificSignals',
|
|
638
|
+
'rejectDecorativeBackgroundPatternsWithoutProductFunction',
|
|
626
639
|
],
|
|
627
|
-
validationHints: {
|
|
628
|
-
rejectArbitraryHexOnlyPalette: true,
|
|
629
|
-
requireViewportMutationRules: true,
|
|
630
|
-
requirePerceptualColorRationale: true,
|
|
631
|
-
requireTokenLayering: true,
|
|
632
|
-
requireTokenAliasingPlan: true,
|
|
633
|
-
allowHexDerivatives: true,
|
|
634
|
-
requireMotionRationale: true,
|
|
635
|
-
requireStateMorphology: true,
|
|
636
|
-
requireAccessibilitySplit: true,
|
|
637
|
-
requireWcagHardFloor: true,
|
|
638
|
-
requireStructuredDesignExecutionPolicy: true,
|
|
639
|
-
requireStructuredDesignHandoff: true,
|
|
640
|
-
requireVisualResetStrategyWhenZeroBasedRedesignRequested: true,
|
|
641
|
-
requireConceptualAnchorWhenNoExternalResearch: true,
|
|
642
|
-
requireAgentLedAnchorResearchWhenUserResearchMissing: true,
|
|
643
|
-
rejectTimidDashboardAnchor: true,
|
|
644
|
-
requireReviewRubric: true,
|
|
645
|
-
requireGenericityExplanation: true,
|
|
646
|
-
genericityAutoFail: true,
|
|
647
|
-
requireSignatureMove: true,
|
|
648
|
-
rejectTemplateNeutralLayout: true,
|
|
649
|
-
requireAiSafeUiAudit: true,
|
|
650
|
-
requireAiColorAudit: true,
|
|
651
|
-
rejectAiColorDefaults: true,
|
|
652
|
-
requireMotionSpatialCourageAudit: true,
|
|
653
|
-
requireExplicit3dCanvasFitDecision: true,
|
|
654
|
-
rejectSafetyAsCreativitySubstitute: true,
|
|
655
|
-
rejectAiSafeUiTemplateLook: true,
|
|
656
|
-
requireThreeProductSpecificSignals: true,
|
|
657
|
-
rejectDecorativeBackgroundPatternsWithoutProductFunction: true,
|
|
658
|
-
},
|
|
659
640
|
requiredDesignSections: DESIGN_REQUIRED_SECTIONS,
|
|
660
641
|
implementation: {
|
|
661
642
|
requiredDeliverables: ['docs/DESIGN.md', 'docs/design-intent.json'],
|
|
@@ -681,793 +662,7 @@ function buildDesignIntentContractObject({
|
|
|
681
662
|
};
|
|
682
663
|
}
|
|
683
664
|
|
|
684
|
-
|
|
685
|
-
return typeof value === 'string' && value.trim().length > 0;
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
export function validateDesignContractCompleteness(designIntentContract) {
|
|
689
|
-
const validationIssues = [];
|
|
690
|
-
const conceptualAnchor = designIntentContract?.conceptualAnchor;
|
|
691
|
-
const derivedTokenLogic = designIntentContract?.derivedTokenLogic;
|
|
692
|
-
const libraryDecisions = designIntentContract?.libraryDecisions;
|
|
693
|
-
|
|
694
|
-
const anchorReference = conceptualAnchor?.anchorReference || derivedTokenLogic?.anchorReference;
|
|
695
|
-
if (!hasNonEmptyString(anchorReference)) {
|
|
696
|
-
validationIssues.push('designIntent.conceptualAnchor.anchorReference must be a stable non-empty ID for deterministic validation.');
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
if (!derivedTokenLogic || typeof derivedTokenLogic !== 'object') {
|
|
700
|
-
validationIssues.push('designIntent.derivedTokenLogic must exist.');
|
|
701
|
-
} else {
|
|
702
|
-
if (derivedTokenLogic.anchorReference !== anchorReference) {
|
|
703
|
-
validationIssues.push('designIntent.derivedTokenLogic.anchorReference must exactly match designIntent.conceptualAnchor.anchorReference.');
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
for (const requiredFieldName of [
|
|
707
|
-
'colorDerivationSource',
|
|
708
|
-
'spacingDerivationSource',
|
|
709
|
-
'typographyDerivationSource',
|
|
710
|
-
'motionDerivationSource',
|
|
711
|
-
'validationRule',
|
|
712
|
-
]) {
|
|
713
|
-
if (!hasNonEmptyString(derivedTokenLogic[requiredFieldName])) {
|
|
714
|
-
validationIssues.push(`designIntent.derivedTokenLogic.${requiredFieldName} must be a non-empty string.`);
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
if (
|
|
719
|
-
hasNonEmptyString(derivedTokenLogic.validationRule)
|
|
720
|
-
&& !derivedTokenLogic.validationRule.includes('anchorReference')
|
|
721
|
-
) {
|
|
722
|
-
validationIssues.push('designIntent.derivedTokenLogic.validationRule must require traceability to anchorReference.');
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
if (!['verified', 'pending-verification', 'no-external-library-needed'].includes(designIntentContract?.libraryResearchStatus)) {
|
|
727
|
-
validationIssues.push('designIntent.libraryResearchStatus must be verified, pending-verification, or no-external-library-needed.');
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
if (!Array.isArray(libraryDecisions)) {
|
|
731
|
-
validationIssues.push('designIntent.libraryDecisions must be an array.');
|
|
732
|
-
} else {
|
|
733
|
-
for (const [libraryIndex, libraryDecision] of libraryDecisions.entries()) {
|
|
734
|
-
if (!libraryDecision || typeof libraryDecision !== 'object') {
|
|
735
|
-
validationIssues.push(`designIntent.libraryDecisions[${libraryIndex}] must be an object.`);
|
|
736
|
-
continue;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
if (!hasNonEmptyString(libraryDecision.library)) {
|
|
740
|
-
validationIssues.push(`designIntent.libraryDecisions[${libraryIndex}].library must be a non-empty string.`);
|
|
741
|
-
}
|
|
742
|
-
if (!hasNonEmptyString(libraryDecision.purpose)) {
|
|
743
|
-
validationIssues.push(`designIntent.libraryDecisions[${libraryIndex}].purpose must be a non-empty string.`);
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
const hasVerification = hasNonEmptyString(libraryDecision.verifiedAt)
|
|
747
|
-
&& hasNonEmptyString(libraryDecision.sourceUrl);
|
|
748
|
-
const hasFallback = hasNonEmptyString(libraryDecision.fallbackIfUnavailable);
|
|
749
|
-
|
|
750
|
-
if (!hasVerification && !hasFallback) {
|
|
751
|
-
validationIssues.push(`designIntent.libraryDecisions[${libraryIndex}] must either record verification source or provide fallbackIfUnavailable.`);
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
return validationIssues;
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
export function validateDesignIntentContract(designIntentContract) {
|
|
760
|
-
const validationErrors = [];
|
|
761
|
-
|
|
762
|
-
if (!designIntentContract || typeof designIntentContract !== 'object') {
|
|
763
|
-
return ['Design intent contract must be an object.'];
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
validationErrors.push(...validateDesignContractCompleteness(designIntentContract));
|
|
767
|
-
|
|
768
|
-
if (designIntentContract.mode !== 'dynamic') {
|
|
769
|
-
validationErrors.push('designIntent.mode must equal "dynamic".');
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
if (!designIntentContract.project || typeof designIntentContract.project !== 'object') {
|
|
773
|
-
validationErrors.push('designIntent.project must exist.');
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
if (!designIntentContract.designPhilosophy || typeof designIntentContract.designPhilosophy !== 'string') {
|
|
777
|
-
validationErrors.push('designIntent.designPhilosophy must be a non-empty string.');
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
if (!designIntentContract.externalResearchIntake || typeof designIntentContract.externalResearchIntake !== 'object') {
|
|
781
|
-
validationErrors.push('designIntent.externalResearchIntake must exist.');
|
|
782
|
-
} else {
|
|
783
|
-
if (designIntentContract.externalResearchIntake.userSuppliedResearchPolicy !== 'read-as-candidate-evidence-not-final-prescription') {
|
|
784
|
-
validationErrors.push('designIntent.externalResearchIntake.userSuppliedResearchPolicy must preserve user research as candidate evidence.');
|
|
785
|
-
}
|
|
786
|
-
if (designIntentContract.externalResearchIntake.requireOfficialDocsVerificationForTechnologyClaims !== true) {
|
|
787
|
-
validationErrors.push('designIntent.externalResearchIntake.requireOfficialDocsVerificationForTechnologyClaims must equal true.');
|
|
788
|
-
}
|
|
789
|
-
if (
|
|
790
|
-
!Array.isArray(designIntentContract.externalResearchIntake.candidateDomains)
|
|
791
|
-
|| !designIntentContract.externalResearchIntake.candidateDomains.includes('motion-and-scroll')
|
|
792
|
-
) {
|
|
793
|
-
validationErrors.push('designIntent.externalResearchIntake.candidateDomains must include motion-and-scroll.');
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
if (!designIntentContract.conceptualAnchor || typeof designIntentContract.conceptualAnchor !== 'object') {
|
|
798
|
-
validationErrors.push('designIntent.conceptualAnchor must exist.');
|
|
799
|
-
} else {
|
|
800
|
-
const conceptualAnchor = designIntentContract.conceptualAnchor;
|
|
801
|
-
if (conceptualAnchor.mode !== 'required-when-no-external-research') {
|
|
802
|
-
validationErrors.push('designIntent.conceptualAnchor.mode must equal "required-when-no-external-research".');
|
|
803
|
-
}
|
|
804
|
-
if (conceptualAnchor.seedMode !== 'selection-policy-only') {
|
|
805
|
-
validationErrors.push('designIntent.conceptualAnchor.seedMode must equal "selection-policy-only".');
|
|
806
|
-
}
|
|
807
|
-
if (conceptualAnchor.requiresAgentSelectionBeforeUiImplementation !== true) {
|
|
808
|
-
validationErrors.push('designIntent.conceptualAnchor.requiresAgentSelectionBeforeUiImplementation must equal true.');
|
|
809
|
-
}
|
|
810
|
-
if (!hasNonEmptyString(conceptualAnchor.anchorReference)) {
|
|
811
|
-
validationErrors.push('designIntent.conceptualAnchor.anchorReference must be a stable non-empty ID.');
|
|
812
|
-
}
|
|
813
|
-
const userResearchAbsencePolicy = conceptualAnchor.userResearchAbsencePolicy;
|
|
814
|
-
if (!userResearchAbsencePolicy || typeof userResearchAbsencePolicy !== 'object') {
|
|
815
|
-
validationErrors.push('designIntent.conceptualAnchor.userResearchAbsencePolicy must exist.');
|
|
816
|
-
} else {
|
|
817
|
-
if (userResearchAbsencePolicy.userSuppliedResearchOnly !== true) {
|
|
818
|
-
validationErrors.push('designIntent.conceptualAnchor.userResearchAbsencePolicy.userSuppliedResearchOnly must equal true.');
|
|
819
|
-
}
|
|
820
|
-
if (userResearchAbsencePolicy.scaffoldSeedDoesNotCountAsResearch !== true) {
|
|
821
|
-
validationErrors.push('designIntent.conceptualAnchor.userResearchAbsencePolicy.scaffoldSeedDoesNotCountAsResearch must equal true.');
|
|
822
|
-
}
|
|
823
|
-
if (userResearchAbsencePolicy.priorUiDoesNotCountAsResearch !== true) {
|
|
824
|
-
validationErrors.push('designIntent.conceptualAnchor.userResearchAbsencePolicy.priorUiDoesNotCountAsResearch must equal true.');
|
|
825
|
-
}
|
|
826
|
-
if (userResearchAbsencePolicy.requireAgentLedResearchWhenAvailable !== true) {
|
|
827
|
-
validationErrors.push('designIntent.conceptualAnchor.userResearchAbsencePolicy.requireAgentLedResearchWhenAvailable must equal true.');
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
const candidateSelectionPolicy = conceptualAnchor.candidateSelectionPolicy;
|
|
831
|
-
if (!candidateSelectionPolicy || typeof candidateSelectionPolicy !== 'object') {
|
|
832
|
-
validationErrors.push('designIntent.conceptualAnchor.candidateSelectionPolicy must exist.');
|
|
833
|
-
} else {
|
|
834
|
-
if (candidateSelectionPolicy.considerAtLeast < 3) {
|
|
835
|
-
validationErrors.push('designIntent.conceptualAnchor.candidateSelectionPolicy.considerAtLeast must be at least 3.');
|
|
836
|
-
}
|
|
837
|
-
if (candidateSelectionPolicy.discardObviousCandidateCount < 2) {
|
|
838
|
-
validationErrors.push('designIntent.conceptualAnchor.candidateSelectionPolicy.discardObviousCandidateCount must be at least 2.');
|
|
839
|
-
}
|
|
840
|
-
if (candidateSelectionPolicy.minimumCandidateDistance !== 'high') {
|
|
841
|
-
validationErrors.push('designIntent.conceptualAnchor.candidateSelectionPolicy.minimumCandidateDistance must equal "high".');
|
|
842
|
-
}
|
|
843
|
-
if (candidateSelectionPolicy.discardPredictableCandidates !== true) {
|
|
844
|
-
validationErrors.push('designIntent.conceptualAnchor.candidateSelectionPolicy.discardPredictableCandidates must equal true.');
|
|
845
|
-
}
|
|
846
|
-
if (candidateSelectionPolicy.preferDistinctiveOverSafe !== true) {
|
|
847
|
-
validationErrors.push('designIntent.conceptualAnchor.candidateSelectionPolicy.preferDistinctiveOverSafe must equal true.');
|
|
848
|
-
}
|
|
849
|
-
if (candidateSelectionPolicy.doNotRevealHiddenCandidateList !== true) {
|
|
850
|
-
validationErrors.push('designIntent.conceptualAnchor.candidateSelectionPolicy.doNotRevealHiddenCandidateList must equal true.');
|
|
851
|
-
}
|
|
852
|
-
if (candidateSelectionPolicy.outputOnlyChosenAnchor !== true) {
|
|
853
|
-
validationErrors.push('designIntent.conceptualAnchor.candidateSelectionPolicy.outputOnlyChosenAnchor must equal true.');
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
const creativeCommitmentPolicy = conceptualAnchor.creativeCommitmentPolicy;
|
|
857
|
-
if (!creativeCommitmentPolicy || typeof creativeCommitmentPolicy !== 'object') {
|
|
858
|
-
validationErrors.push('designIntent.conceptualAnchor.creativeCommitmentPolicy must exist.');
|
|
859
|
-
} else {
|
|
860
|
-
if (creativeCommitmentPolicy.requiredBeforeComplianceReview !== true) {
|
|
861
|
-
validationErrors.push('designIntent.conceptualAnchor.creativeCommitmentPolicy.requiredBeforeComplianceReview must equal true.');
|
|
862
|
-
}
|
|
863
|
-
if (creativeCommitmentPolicy.recordInDesignDocs !== true) {
|
|
864
|
-
validationErrors.push('designIntent.conceptualAnchor.creativeCommitmentPolicy.recordInDesignDocs must equal true.');
|
|
865
|
-
}
|
|
866
|
-
if (
|
|
867
|
-
!Array.isArray(creativeCommitmentPolicy.requiredCommitmentFields)
|
|
868
|
-
|| !creativeCommitmentPolicy.requiredCommitmentFields.includes('specificReferencePoint')
|
|
869
|
-
|| !creativeCommitmentPolicy.requiredCommitmentFields.includes('signatureMotion')
|
|
870
|
-
|| !creativeCommitmentPolicy.requiredCommitmentFields.includes('typographicDecision')
|
|
871
|
-
) {
|
|
872
|
-
validationErrors.push('designIntent.conceptualAnchor.creativeCommitmentPolicy.requiredCommitmentFields must include specificReferencePoint, signatureMotion, and typographicDecision.');
|
|
873
|
-
}
|
|
874
|
-
if (creativeCommitmentPolicy.rejectGenericQualityWordsOnly !== true) {
|
|
875
|
-
validationErrors.push('designIntent.conceptualAnchor.creativeCommitmentPolicy.rejectGenericQualityWordsOnly must equal true.');
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
if (
|
|
879
|
-
!Array.isArray(conceptualAnchor.forbiddenFinalAnchorTerms)
|
|
880
|
-
|| !conceptualAnchor.forbiddenFinalAnchorTerms.includes('dashboard')
|
|
881
|
-
|| !conceptualAnchor.forbiddenFinalAnchorTerms.includes('cards')
|
|
882
|
-
|| !conceptualAnchor.forbiddenFinalAnchorTerms.includes('safe-admin-layout')
|
|
883
|
-
) {
|
|
884
|
-
validationErrors.push('designIntent.conceptualAnchor.forbiddenFinalAnchorTerms must reject basic UI labels.');
|
|
885
|
-
}
|
|
886
|
-
if (
|
|
887
|
-
!Array.isArray(conceptualAnchor.sourceDomains)
|
|
888
|
-
|| conceptualAnchor.sourceDomains.length < 4
|
|
889
|
-
|| !conceptualAnchor.sourceDomains.includes('complex-physical-engineering')
|
|
890
|
-
|| !conceptualAnchor.sourceDomains.includes('cinematic-spatial-interface')
|
|
891
|
-
|| !conceptualAnchor.sourceDomains.includes('premium-interactive-web-experiences')
|
|
892
|
-
) {
|
|
893
|
-
validationErrors.push('designIntent.conceptualAnchor.sourceDomains must list broad non-template anchor domains.');
|
|
894
|
-
}
|
|
895
|
-
const visualRiskBudget = conceptualAnchor.visualRiskBudget;
|
|
896
|
-
if (!visualRiskBudget || typeof visualRiskBudget !== 'object') {
|
|
897
|
-
validationErrors.push('designIntent.conceptualAnchor.visualRiskBudget must exist.');
|
|
898
|
-
} else {
|
|
899
|
-
if (visualRiskBudget.mode !== 'high-distinctiveness-with-accessibility-and-performance-guardrails') {
|
|
900
|
-
validationErrors.push('designIntent.conceptualAnchor.visualRiskBudget.mode must preserve high-distinctiveness guardrails.');
|
|
901
|
-
}
|
|
902
|
-
if (visualRiskBudget.allowRichMotionAndMicroInteraction !== true) {
|
|
903
|
-
validationErrors.push('designIntent.conceptualAnchor.visualRiskBudget.allowRichMotionAndMicroInteraction must equal true.');
|
|
904
|
-
}
|
|
905
|
-
if (visualRiskBudget.rejectTimidDefaultWhenAnchorSupportsExpressiveUi !== true) {
|
|
906
|
-
validationErrors.push('designIntent.conceptualAnchor.visualRiskBudget.rejectTimidDefaultWhenAnchorSupportsExpressiveUi must equal true.');
|
|
907
|
-
}
|
|
908
|
-
if (visualRiskBudget.requireReducedMotionFallback !== true) {
|
|
909
|
-
validationErrors.push('designIntent.conceptualAnchor.visualRiskBudget.requireReducedMotionFallback must equal true.');
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
if (
|
|
913
|
-
!Array.isArray(conceptualAnchor.requiredDerivedAxes)
|
|
914
|
-
|| !conceptualAnchor.requiredDerivedAxes.includes('typography')
|
|
915
|
-
|| !conceptualAnchor.requiredDerivedAxes.includes('responsive-composition')
|
|
916
|
-
) {
|
|
917
|
-
validationErrors.push('designIntent.conceptualAnchor.requiredDerivedAxes must include typography and responsive-composition.');
|
|
918
|
-
}
|
|
919
|
-
const finalAnchorContract = conceptualAnchor.finalAnchorContract;
|
|
920
|
-
if (!finalAnchorContract || typeof finalAnchorContract !== 'object') {
|
|
921
|
-
validationErrors.push('designIntent.conceptualAnchor.finalAnchorContract must exist.');
|
|
922
|
-
} else {
|
|
923
|
-
if (
|
|
924
|
-
!Array.isArray(finalAnchorContract.requiredFields)
|
|
925
|
-
|| !finalAnchorContract.requiredFields.includes('anchorReference')
|
|
926
|
-
|| !finalAnchorContract.requiredFields.includes('agentResearchMode')
|
|
927
|
-
|| !finalAnchorContract.requiredFields.includes('specificReferencePoint')
|
|
928
|
-
|| !finalAnchorContract.requiredFields.includes('signatureMotion')
|
|
929
|
-
|| !finalAnchorContract.requiredFields.includes('typographicDecision')
|
|
930
|
-
|| !finalAnchorContract.requiredFields.includes('derivedTokenLogic')
|
|
931
|
-
|| !finalAnchorContract.requiredFields.includes('visualRiskBudget')
|
|
932
|
-
|| !finalAnchorContract.requiredFields.includes('motionRiskBudget')
|
|
933
|
-
|| !finalAnchorContract.requiredFields.includes('cohesionChecks')
|
|
934
|
-
) {
|
|
935
|
-
validationErrors.push('designIntent.conceptualAnchor.finalAnchorContract.requiredFields must require anchorReference, agentResearchMode, specificReferencePoint, signatureMotion, typographicDecision, derivedTokenLogic, visualRiskBudget, motionRiskBudget, and cohesionChecks.');
|
|
936
|
-
}
|
|
937
|
-
if (
|
|
938
|
-
!Array.isArray(finalAnchorContract.derivedTokenLogicAxes)
|
|
939
|
-
|| !finalAnchorContract.derivedTokenLogicAxes.includes('motion')
|
|
940
|
-
|| !finalAnchorContract.derivedTokenLogicAxes.includes('morphology')
|
|
941
|
-
) {
|
|
942
|
-
validationErrors.push('designIntent.conceptualAnchor.finalAnchorContract.derivedTokenLogicAxes must include motion and morphology.');
|
|
943
|
-
}
|
|
944
|
-
if (
|
|
945
|
-
!Array.isArray(finalAnchorContract.cohesionChecks)
|
|
946
|
-
|| !finalAnchorContract.cohesionChecks.includes('no-dashboard-mental-model')
|
|
947
|
-
|| !finalAnchorContract.cohesionChecks.includes('motion-derived-from-anchor')
|
|
948
|
-
) {
|
|
949
|
-
validationErrors.push('designIntent.conceptualAnchor.finalAnchorContract.cohesionChecks must reject dashboard mental models and require motion derivation.');
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
}
|
|
953
|
-
|
|
954
|
-
if (!designIntentContract.mathSystems || typeof designIntentContract.mathSystems !== 'object') {
|
|
955
|
-
validationErrors.push('designIntent.mathSystems must exist.');
|
|
956
|
-
} else {
|
|
957
|
-
if (!String(designIntentContract.mathSystems.typographyScaleRatio || '').trim()) {
|
|
958
|
-
validationErrors.push('designIntent.mathSystems.typographyScaleRatio must describe the chosen or pending type scale decision.');
|
|
959
|
-
}
|
|
960
|
-
if (!String(designIntentContract.mathSystems.baseGridUnit || '').trim()) {
|
|
961
|
-
validationErrors.push('designIntent.mathSystems.baseGridUnit must describe the chosen or pending spacing grid decision.');
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
if (!designIntentContract.aiSafeUiAudit || typeof designIntentContract.aiSafeUiAudit !== 'object') {
|
|
966
|
-
validationErrors.push('designIntent.aiSafeUiAudit must exist.');
|
|
967
|
-
} else {
|
|
968
|
-
const aiSafeUiAudit = designIntentContract.aiSafeUiAudit;
|
|
969
|
-
if (aiSafeUiAudit.status !== 'agent-must-complete-before-ui-implementation') {
|
|
970
|
-
validationErrors.push('designIntent.aiSafeUiAudit.status must require completion before UI implementation.');
|
|
971
|
-
}
|
|
972
|
-
if (!String(aiSafeUiAudit.failureDefinition || '').includes('AI-safe')) {
|
|
973
|
-
validationErrors.push('designIntent.aiSafeUiAudit.failureDefinition must define AI-safe UI drift.');
|
|
974
|
-
}
|
|
975
|
-
if (!String(aiSafeUiAudit.interchangeabilityTest || '').includes('renamed')) {
|
|
976
|
-
validationErrors.push('designIntent.aiSafeUiAudit.interchangeabilityTest must include the rename/interchangeability test.');
|
|
977
|
-
}
|
|
978
|
-
if (!Array.isArray(aiSafeUiAudit.requiredProductSpecificSignals) || aiSafeUiAudit.requiredProductSpecificSignals.length < 3) {
|
|
979
|
-
validationErrors.push('designIntent.aiSafeUiAudit.requiredProductSpecificSignals must list at least three product-specific signals.');
|
|
980
|
-
}
|
|
981
|
-
if (!String(aiSafeUiAudit.paletteExplorationRule || '').trim()) {
|
|
982
|
-
validationErrors.push('designIntent.aiSafeUiAudit.paletteExplorationRule must be a non-empty string.');
|
|
983
|
-
}
|
|
984
|
-
if (!String(aiSafeUiAudit.backgroundPatternRule || '').trim()) {
|
|
985
|
-
validationErrors.push('designIntent.aiSafeUiAudit.backgroundPatternRule must be a non-empty string.');
|
|
986
|
-
}
|
|
987
|
-
if (!aiSafeUiAudit.aiColorAudit || typeof aiSafeUiAudit.aiColorAudit !== 'object') {
|
|
988
|
-
validationErrors.push('designIntent.aiSafeUiAudit.aiColorAudit must exist.');
|
|
989
|
-
} else {
|
|
990
|
-
if (aiSafeUiAudit.aiColorAudit.status !== 'agent-must-complete-before-ui-implementation') {
|
|
991
|
-
validationErrors.push('designIntent.aiSafeUiAudit.aiColorAudit.status must require completion before UI implementation.');
|
|
992
|
-
}
|
|
993
|
-
if (!String(aiSafeUiAudit.aiColorAudit.failureDefinition || '').includes('AI color')) {
|
|
994
|
-
validationErrors.push('designIntent.aiSafeUiAudit.aiColorAudit.failureDefinition must define AI color drift.');
|
|
995
|
-
}
|
|
996
|
-
if (!Array.isArray(aiSafeUiAudit.aiColorAudit.autopilotRisks) || aiSafeUiAudit.aiColorAudit.autopilotRisks.length < 4) {
|
|
997
|
-
validationErrors.push('designIntent.aiSafeUiAudit.aiColorAudit.autopilotRisks must list common autopilot palettes.');
|
|
998
|
-
}
|
|
999
|
-
if (!Array.isArray(aiSafeUiAudit.aiColorAudit.requiredEvidence) || aiSafeUiAudit.aiColorAudit.requiredEvidence.length < 3) {
|
|
1000
|
-
validationErrors.push('designIntent.aiSafeUiAudit.aiColorAudit.requiredEvidence must list color evidence requirements.');
|
|
1001
|
-
}
|
|
1002
|
-
if (!String(aiSafeUiAudit.aiColorAudit.reviewQuestion || '').trim()) {
|
|
1003
|
-
validationErrors.push('designIntent.aiSafeUiAudit.aiColorAudit.reviewQuestion must be a non-empty string.');
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
if (!aiSafeUiAudit.motionSpatialCourageAudit || typeof aiSafeUiAudit.motionSpatialCourageAudit !== 'object') {
|
|
1007
|
-
validationErrors.push('designIntent.aiSafeUiAudit.motionSpatialCourageAudit must exist.');
|
|
1008
|
-
} else {
|
|
1009
|
-
if (aiSafeUiAudit.motionSpatialCourageAudit.status !== 'agent-must-complete-before-ui-implementation') {
|
|
1010
|
-
validationErrors.push('designIntent.aiSafeUiAudit.motionSpatialCourageAudit.status must require completion before UI implementation.');
|
|
1011
|
-
}
|
|
1012
|
-
if (!String(aiSafeUiAudit.motionSpatialCourageAudit.defaultStance || '').includes('first-class options')) {
|
|
1013
|
-
validationErrors.push('designIntent.aiSafeUiAudit.motionSpatialCourageAudit.defaultStance must treat motion and spatial UI as first-class options.');
|
|
1014
|
-
}
|
|
1015
|
-
if (!Array.isArray(aiSafeUiAudit.motionSpatialCourageAudit.requiredDecisionFields) || aiSafeUiAudit.motionSpatialCourageAudit.requiredDecisionFields.length < 3) {
|
|
1016
|
-
validationErrors.push('designIntent.aiSafeUiAudit.motionSpatialCourageAudit.requiredDecisionFields must list required motion/spatial decisions.');
|
|
1017
|
-
}
|
|
1018
|
-
if (!String(aiSafeUiAudit.motionSpatialCourageAudit.rejectionRule || '').includes('product reason')) {
|
|
1019
|
-
validationErrors.push('designIntent.aiSafeUiAudit.motionSpatialCourageAudit.rejectionRule must require a product reason before omitting spatial UI.');
|
|
1020
|
-
}
|
|
1021
|
-
if (!String(aiSafeUiAudit.motionSpatialCourageAudit.reviewQuestion || '').trim()) {
|
|
1022
|
-
validationErrors.push('designIntent.aiSafeUiAudit.motionSpatialCourageAudit.reviewQuestion must be a non-empty string.');
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
if (!String(aiSafeUiAudit.reviewQuestion || '').trim()) {
|
|
1026
|
-
validationErrors.push('designIntent.aiSafeUiAudit.reviewQuestion must be a non-empty string.');
|
|
1027
|
-
}
|
|
1028
|
-
if (aiSafeUiAudit.blockingByDefault !== true) {
|
|
1029
|
-
validationErrors.push('designIntent.aiSafeUiAudit.blockingByDefault must equal true.');
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
if (!designIntentContract.tokenSystem || typeof designIntentContract.tokenSystem !== 'object') {
|
|
1034
|
-
validationErrors.push('designIntent.tokenSystem must exist.');
|
|
1035
|
-
} else {
|
|
1036
|
-
const taxonomyOrder = designIntentContract.tokenSystem.taxonomyOrder;
|
|
1037
|
-
if (!Array.isArray(taxonomyOrder) || taxonomyOrder.join('|') !== 'primitive|semantic|component') {
|
|
1038
|
-
validationErrors.push('designIntent.tokenSystem.taxonomyOrder must equal ["primitive","semantic","component"].');
|
|
1039
|
-
}
|
|
1040
|
-
if (designIntentContract.tokenSystem.primitiveColorSpace !== 'OKLCH') {
|
|
1041
|
-
validationErrors.push('designIntent.tokenSystem.primitiveColorSpace must equal "OKLCH".');
|
|
1042
|
-
}
|
|
1043
|
-
if (designIntentContract.tokenSystem.requireSemanticAliases !== true) {
|
|
1044
|
-
validationErrors.push('designIntent.tokenSystem.requireSemanticAliases must equal true.');
|
|
1045
|
-
}
|
|
1046
|
-
if (designIntentContract.tokenSystem.semanticAliasesMutableWithoutComponentRewrite !== true) {
|
|
1047
|
-
validationErrors.push('designIntent.tokenSystem.semanticAliasesMutableWithoutComponentRewrite must equal true.');
|
|
1048
|
-
}
|
|
1049
|
-
if (designIntentContract.tokenSystem.componentTokensConsumeSemantic !== true) {
|
|
1050
|
-
validationErrors.push('designIntent.tokenSystem.componentTokensConsumeSemantic must equal true.');
|
|
1051
|
-
}
|
|
1052
|
-
const fallbackPolicy = designIntentContract.tokenSystem.fallbackPolicy;
|
|
1053
|
-
if (!fallbackPolicy || typeof fallbackPolicy !== 'object') {
|
|
1054
|
-
validationErrors.push('designIntent.tokenSystem.fallbackPolicy must exist.');
|
|
1055
|
-
} else {
|
|
1056
|
-
if (fallbackPolicy.forbidRawHexOutsidePrimitives !== true) {
|
|
1057
|
-
validationErrors.push('designIntent.tokenSystem.fallbackPolicy.forbidRawHexOutsidePrimitives must equal true.');
|
|
1058
|
-
}
|
|
1059
|
-
if (fallbackPolicy.forbidRawSpacingOutsidePrimitives !== true) {
|
|
1060
|
-
validationErrors.push('designIntent.tokenSystem.fallbackPolicy.forbidRawSpacingOutsidePrimitives must equal true.');
|
|
1061
|
-
}
|
|
1062
|
-
if (fallbackPolicy.requireDocumentedExceptionForLegacyBypass !== true) {
|
|
1063
|
-
validationErrors.push('designIntent.tokenSystem.fallbackPolicy.requireDocumentedExceptionForLegacyBypass must equal true.');
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
const namingConstraints = designIntentContract.tokenSystem.namingConstraints;
|
|
1067
|
-
if (!namingConstraints || typeof namingConstraints !== 'object') {
|
|
1068
|
-
validationErrors.push('designIntent.tokenSystem.namingConstraints must exist.');
|
|
1069
|
-
} else {
|
|
1070
|
-
if (namingConstraints.forbidCurlyBracesInNames !== true) {
|
|
1071
|
-
validationErrors.push('designIntent.tokenSystem.namingConstraints.forbidCurlyBracesInNames must equal true.');
|
|
1072
|
-
}
|
|
1073
|
-
if (namingConstraints.forbidDotsInNames !== true) {
|
|
1074
|
-
validationErrors.push('designIntent.tokenSystem.namingConstraints.forbidDotsInNames must equal true.');
|
|
1075
|
-
}
|
|
1076
|
-
if (namingConstraints.forbidSquareBracketsInNames !== true) {
|
|
1077
|
-
validationErrors.push('designIntent.tokenSystem.namingConstraints.forbidSquareBracketsInNames must equal true.');
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
if (!designIntentContract.colorTruth || typeof designIntentContract.colorTruth !== 'object') {
|
|
1083
|
-
validationErrors.push('designIntent.colorTruth must exist.');
|
|
1084
|
-
} else {
|
|
1085
|
-
if (designIntentContract.colorTruth.format !== 'OKLCH') {
|
|
1086
|
-
validationErrors.push('designIntent.colorTruth.format must equal "OKLCH".');
|
|
1087
|
-
}
|
|
1088
|
-
if (designIntentContract.colorTruth.allowHexDerivatives !== true) {
|
|
1089
|
-
validationErrors.push('designIntent.colorTruth.allowHexDerivatives must equal true.');
|
|
1090
|
-
}
|
|
1091
|
-
if (!String(designIntentContract.colorTruth.intent || '').trim()) {
|
|
1092
|
-
validationErrors.push('designIntent.colorTruth.intent must be a non-empty string.');
|
|
1093
|
-
}
|
|
1094
|
-
const paletteRoles = designIntentContract.colorTruth.paletteRoles;
|
|
1095
|
-
if (!Array.isArray(paletteRoles) || paletteRoles.length < 1) {
|
|
1096
|
-
validationErrors.push('designIntent.colorTruth.paletteRoles must define or request agent-defined semantic palette roles.');
|
|
1097
|
-
}
|
|
1098
|
-
if (designIntentContract.colorTruth.rolesMustBeAgentDefined !== true) {
|
|
1099
|
-
validationErrors.push('designIntent.colorTruth.rolesMustBeAgentDefined must equal true.');
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
if (!designIntentContract.crossViewportAdaptation || typeof designIntentContract.crossViewportAdaptation !== 'object') {
|
|
1104
|
-
validationErrors.push('designIntent.crossViewportAdaptation must exist.');
|
|
1105
|
-
} else {
|
|
1106
|
-
const mutationRules = designIntentContract.crossViewportAdaptation.mutationRules;
|
|
1107
|
-
if (!mutationRules || typeof mutationRules !== 'object') {
|
|
1108
|
-
validationErrors.push('designIntent.crossViewportAdaptation.mutationRules must exist.');
|
|
1109
|
-
} else {
|
|
1110
|
-
for (const viewportKey of ['mobile', 'tablet', 'desktop']) {
|
|
1111
|
-
if (!String(mutationRules[viewportKey] || '').trim()) {
|
|
1112
|
-
validationErrors.push(`designIntent.crossViewportAdaptation.mutationRules.${viewportKey} must be a non-empty string.`);
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
if (!designIntentContract.motionSystem || typeof designIntentContract.motionSystem !== 'object') {
|
|
1119
|
-
validationErrors.push('designIntent.motionSystem must exist.');
|
|
1120
|
-
} else {
|
|
1121
|
-
if (designIntentContract.motionSystem.allowMeaningfulMotion !== true) {
|
|
1122
|
-
validationErrors.push('designIntent.motionSystem.allowMeaningfulMotion must equal true.');
|
|
1123
|
-
}
|
|
1124
|
-
if (!String(designIntentContract.motionSystem.purpose || '').trim()) {
|
|
1125
|
-
validationErrors.push('designIntent.motionSystem.purpose must be a non-empty string.');
|
|
1126
|
-
}
|
|
1127
|
-
if (designIntentContract.motionSystem.respectReducedMotion !== true) {
|
|
1128
|
-
validationErrors.push('designIntent.motionSystem.respectReducedMotion must equal true.');
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
|
|
1132
|
-
if (!designIntentContract.componentMorphology || typeof designIntentContract.componentMorphology !== 'object') {
|
|
1133
|
-
validationErrors.push('designIntent.componentMorphology must exist.');
|
|
1134
|
-
} else {
|
|
1135
|
-
if (designIntentContract.componentMorphology.requireStateBehaviorMatrix !== true) {
|
|
1136
|
-
validationErrors.push('designIntent.componentMorphology.requireStateBehaviorMatrix must equal true.');
|
|
1137
|
-
}
|
|
1138
|
-
if (!Array.isArray(designIntentContract.componentMorphology.stateKeys) || designIntentContract.componentMorphology.stateKeys.length < 4) {
|
|
1139
|
-
validationErrors.push('designIntent.componentMorphology.stateKeys must contain multiple interaction states.');
|
|
1140
|
-
}
|
|
1141
|
-
const viewportBehavior = designIntentContract.componentMorphology.viewportBehavior;
|
|
1142
|
-
if (!viewportBehavior || typeof viewportBehavior !== 'object') {
|
|
1143
|
-
validationErrors.push('designIntent.componentMorphology.viewportBehavior must exist.');
|
|
1144
|
-
} else {
|
|
1145
|
-
for (const viewportKey of ['mobile', 'tablet', 'desktop']) {
|
|
1146
|
-
if (!String(viewportBehavior[viewportKey] || '').trim()) {
|
|
1147
|
-
validationErrors.push(`designIntent.componentMorphology.viewportBehavior.${viewportKey} must be a non-empty string.`);
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
if (!designIntentContract.accessibilityPolicy || typeof designIntentContract.accessibilityPolicy !== 'object') {
|
|
1154
|
-
validationErrors.push('designIntent.accessibilityPolicy must exist.');
|
|
1155
|
-
} else {
|
|
1156
|
-
if (designIntentContract.accessibilityPolicy.hardComplianceFloor !== 'WCAG-2.2-AA') {
|
|
1157
|
-
validationErrors.push('designIntent.accessibilityPolicy.hardComplianceFloor must equal "WCAG-2.2-AA".');
|
|
1158
|
-
}
|
|
1159
|
-
if (designIntentContract.accessibilityPolicy.advisoryContrastModel !== 'APCA') {
|
|
1160
|
-
validationErrors.push('designIntent.accessibilityPolicy.advisoryContrastModel must equal "APCA".');
|
|
1161
|
-
}
|
|
1162
|
-
if (designIntentContract.accessibilityPolicy.failOnHardViolations !== true) {
|
|
1163
|
-
validationErrors.push('designIntent.accessibilityPolicy.failOnHardViolations must equal true.');
|
|
1164
|
-
}
|
|
1165
|
-
if (designIntentContract.accessibilityPolicy.advisoryFindingsDoNotBlockByDefault !== true) {
|
|
1166
|
-
validationErrors.push('designIntent.accessibilityPolicy.advisoryFindingsDoNotBlockByDefault must equal true.');
|
|
1167
|
-
}
|
|
1168
|
-
const hardRequirements = designIntentContract.accessibilityPolicy.hardRequirements;
|
|
1169
|
-
if (!hardRequirements || typeof hardRequirements !== 'object') {
|
|
1170
|
-
validationErrors.push('designIntent.accessibilityPolicy.hardRequirements must exist.');
|
|
1171
|
-
} else {
|
|
1172
|
-
for (const requirementKey of [
|
|
1173
|
-
'textContrastMinimum',
|
|
1174
|
-
'nonTextContrast',
|
|
1175
|
-
'useOfColorOnlyProhibited',
|
|
1176
|
-
'focusVisible',
|
|
1177
|
-
'focusAppearance',
|
|
1178
|
-
'targetSizeMinimum',
|
|
1179
|
-
'keyboardAccess',
|
|
1180
|
-
'reflowRequired',
|
|
1181
|
-
'accessibleAuthenticationMinimum',
|
|
1182
|
-
'statusMessagesAndDynamicStateAccess',
|
|
1183
|
-
]) {
|
|
1184
|
-
if (hardRequirements[requirementKey] !== true) {
|
|
1185
|
-
validationErrors.push(`designIntent.accessibilityPolicy.hardRequirements.${requirementKey} must equal true.`);
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
const advisoryChecks = designIntentContract.accessibilityPolicy.advisoryChecks;
|
|
1190
|
-
if (!advisoryChecks || typeof advisoryChecks !== 'object') {
|
|
1191
|
-
validationErrors.push('designIntent.accessibilityPolicy.advisoryChecks must exist.');
|
|
1192
|
-
} else {
|
|
1193
|
-
for (const advisoryKey of [
|
|
1194
|
-
'perceptualContrastReview',
|
|
1195
|
-
'darkModeContrastTuning',
|
|
1196
|
-
'typographyReadabilityTuning',
|
|
1197
|
-
]) {
|
|
1198
|
-
if (advisoryChecks[advisoryKey] !== true) {
|
|
1199
|
-
validationErrors.push(`designIntent.accessibilityPolicy.advisoryChecks.${advisoryKey} must equal true.`);
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
if (!designIntentContract.contextHygiene || typeof designIntentContract.contextHygiene !== 'object') {
|
|
1206
|
-
validationErrors.push('designIntent.contextHygiene must exist.');
|
|
1207
|
-
} else {
|
|
1208
|
-
if (designIntentContract.contextHygiene.continuityMode !== 'opt-in-only') {
|
|
1209
|
-
validationErrors.push('designIntent.contextHygiene.continuityMode must equal "opt-in-only".');
|
|
1210
|
-
}
|
|
1211
|
-
if (designIntentContract.contextHygiene.repoEvidenceOverridesMemory !== true) {
|
|
1212
|
-
validationErrors.push('designIntent.contextHygiene.repoEvidenceOverridesMemory must equal true.');
|
|
1213
|
-
}
|
|
1214
|
-
if (designIntentContract.contextHygiene.requireExplicitContinuityApproval !== true) {
|
|
1215
|
-
validationErrors.push('designIntent.contextHygiene.requireExplicitContinuityApproval must equal true.');
|
|
1216
|
-
}
|
|
1217
|
-
if (designIntentContract.contextHygiene.forbidCarryoverWhenUnapproved !== true) {
|
|
1218
|
-
validationErrors.push('designIntent.contextHygiene.forbidCarryoverWhenUnapproved must equal true.');
|
|
1219
|
-
}
|
|
1220
|
-
if (!Array.isArray(designIntentContract.contextHygiene.allowedSources) || designIntentContract.contextHygiene.allowedSources.length < 4) {
|
|
1221
|
-
validationErrors.push('designIntent.contextHygiene.allowedSources must list the approved design evidence sources.');
|
|
1222
|
-
}
|
|
1223
|
-
if (!Array.isArray(designIntentContract.contextHygiene.taintedSources) || designIntentContract.contextHygiene.taintedSources.length < 3) {
|
|
1224
|
-
validationErrors.push('designIntent.contextHygiene.taintedSources must list tainted carryover sources.');
|
|
1225
|
-
}
|
|
1226
|
-
if (!String(designIntentContract.contextHygiene.approvedExternalConstraintUsage || '').trim()) {
|
|
1227
|
-
validationErrors.push('designIntent.contextHygiene.approvedExternalConstraintUsage must be a non-empty string.');
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
if (!designIntentContract.designExecutionPolicy || typeof designIntentContract.designExecutionPolicy !== 'object') {
|
|
1232
|
-
validationErrors.push('designIntent.designExecutionPolicy must exist.');
|
|
1233
|
-
} else {
|
|
1234
|
-
if (designIntentContract.designExecutionPolicy.representationStrategy !== 'surface-plan-v1') {
|
|
1235
|
-
validationErrors.push('designIntent.designExecutionPolicy.representationStrategy must equal "surface-plan-v1".');
|
|
1236
|
-
}
|
|
1237
|
-
for (const requiredFlagName of [
|
|
1238
|
-
'requireSurfacePlan',
|
|
1239
|
-
'requireComponentGraph',
|
|
1240
|
-
'requireViewportMutationPlan',
|
|
1241
|
-
'requireInteractionStateMatrix',
|
|
1242
|
-
'requireContentPriorityMap',
|
|
1243
|
-
'requireTaskFlowNarrative',
|
|
1244
|
-
'requireSignatureMoveRationale',
|
|
1245
|
-
'requireCreativeCommitmentGate',
|
|
1246
|
-
'requireStructuredHandoff',
|
|
1247
|
-
'requireRepoEvidenceAlignment',
|
|
1248
|
-
'forbidScreenshotDependency',
|
|
1249
|
-
'requirePerSurfaceMutationOps',
|
|
1250
|
-
'forbidUniformSiblingSurfaceTreatment',
|
|
1251
|
-
'zeroBasedRedesignResetsPriorVisualsWhenRequested',
|
|
1252
|
-
]) {
|
|
1253
|
-
if (designIntentContract.designExecutionPolicy[requiredFlagName] !== true) {
|
|
1254
|
-
validationErrors.push(`designIntent.designExecutionPolicy.${requiredFlagName} must equal true.`);
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
if (designIntentContract.designExecutionPolicy.handoffFormatVersion !== 'ui-handoff-v1') {
|
|
1258
|
-
validationErrors.push('designIntent.designExecutionPolicy.handoffFormatVersion must equal "ui-handoff-v1".');
|
|
1259
|
-
}
|
|
1260
|
-
if (
|
|
1261
|
-
!Array.isArray(designIntentContract.designExecutionPolicy.semanticReviewFocus)
|
|
1262
|
-
|| designIntentContract.designExecutionPolicy.semanticReviewFocus.length < 4
|
|
1263
|
-
) {
|
|
1264
|
-
validationErrors.push('designIntent.designExecutionPolicy.semanticReviewFocus must list the required review dimensions.');
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
if (!designIntentContract.designExecutionHandoff || typeof designIntentContract.designExecutionHandoff !== 'object') {
|
|
1269
|
-
validationErrors.push('designIntent.designExecutionHandoff must exist.');
|
|
1270
|
-
} else {
|
|
1271
|
-
if (designIntentContract.designExecutionHandoff.version !== 'ui-handoff-v1') {
|
|
1272
|
-
validationErrors.push('designIntent.designExecutionHandoff.version must equal "ui-handoff-v1".');
|
|
1273
|
-
}
|
|
1274
|
-
if (designIntentContract.designExecutionHandoff.seedMode !== 'structure-first-scaffold') {
|
|
1275
|
-
validationErrors.push('designIntent.designExecutionHandoff.seedMode must equal "structure-first-scaffold".');
|
|
1276
|
-
}
|
|
1277
|
-
if (designIntentContract.designExecutionHandoff.requiresTaskSpecificRefinement !== true) {
|
|
1278
|
-
validationErrors.push('designIntent.designExecutionHandoff.requiresTaskSpecificRefinement must equal true.');
|
|
1279
|
-
}
|
|
1280
|
-
if (!String(designIntentContract.designExecutionHandoff.primaryExperienceGoal || '').trim()) {
|
|
1281
|
-
validationErrors.push('designIntent.designExecutionHandoff.primaryExperienceGoal must be a non-empty string.');
|
|
1282
|
-
}
|
|
1283
|
-
if (!Array.isArray(designIntentContract.designExecutionHandoff.surfacePlan) || designIntentContract.designExecutionHandoff.surfacePlan.length < 1) {
|
|
1284
|
-
validationErrors.push('designIntent.designExecutionHandoff.surfacePlan must define at least one planned surface.');
|
|
1285
|
-
}
|
|
1286
|
-
const componentGraph = designIntentContract.designExecutionHandoff.componentGraph;
|
|
1287
|
-
if (!componentGraph || typeof componentGraph !== 'object') {
|
|
1288
|
-
validationErrors.push('designIntent.designExecutionHandoff.componentGraph must exist.');
|
|
1289
|
-
} else {
|
|
1290
|
-
if (!Array.isArray(componentGraph.nodes) || componentGraph.nodes.length < 2) {
|
|
1291
|
-
validationErrors.push('designIntent.designExecutionHandoff.componentGraph.nodes must list the primary execution nodes.');
|
|
1292
|
-
}
|
|
1293
|
-
if (!Array.isArray(componentGraph.edges) || componentGraph.edges.length < 1) {
|
|
1294
|
-
validationErrors.push('designIntent.designExecutionHandoff.componentGraph.edges must define relationships between UI nodes.');
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
const contentPriorityMap = designIntentContract.designExecutionHandoff.contentPriorityMap;
|
|
1298
|
-
if (!contentPriorityMap || typeof contentPriorityMap !== 'object') {
|
|
1299
|
-
validationErrors.push('designIntent.designExecutionHandoff.contentPriorityMap must exist.');
|
|
1300
|
-
} else {
|
|
1301
|
-
for (const priorityBucket of ['primary', 'secondary', 'deferred']) {
|
|
1302
|
-
if (!Array.isArray(contentPriorityMap[priorityBucket]) || contentPriorityMap[priorityBucket].length < 1) {
|
|
1303
|
-
validationErrors.push(`designIntent.designExecutionHandoff.contentPriorityMap.${priorityBucket} must contain at least one item.`);
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
const viewportMutationPlan = designIntentContract.designExecutionHandoff.viewportMutationPlan;
|
|
1308
|
-
if (!viewportMutationPlan || typeof viewportMutationPlan !== 'object') {
|
|
1309
|
-
validationErrors.push('designIntent.designExecutionHandoff.viewportMutationPlan must exist.');
|
|
1310
|
-
} else {
|
|
1311
|
-
for (const viewportKey of ['mobile', 'tablet', 'desktop']) {
|
|
1312
|
-
const viewportPlan = viewportMutationPlan[viewportKey];
|
|
1313
|
-
if (!viewportPlan || typeof viewportPlan !== 'object') {
|
|
1314
|
-
validationErrors.push(`designIntent.designExecutionHandoff.viewportMutationPlan.${viewportKey} must be an object.`);
|
|
1315
|
-
continue;
|
|
1316
|
-
}
|
|
1317
|
-
if (!String(viewportPlan.primaryOperation || '').trim()) {
|
|
1318
|
-
validationErrors.push(`designIntent.designExecutionHandoff.viewportMutationPlan.${viewportKey}.primaryOperation must be a non-empty string.`);
|
|
1319
|
-
}
|
|
1320
|
-
if (!Array.isArray(viewportPlan.requiredSurfaceActions) || viewportPlan.requiredSurfaceActions.length < 2) {
|
|
1321
|
-
validationErrors.push(`designIntent.designExecutionHandoff.viewportMutationPlan.${viewportKey}.requiredSurfaceActions must contain at least two actions.`);
|
|
1322
|
-
}
|
|
1323
|
-
if (!Array.isArray(viewportPlan.forbiddenPatterns) || viewportPlan.forbiddenPatterns.length < 1) {
|
|
1324
|
-
validationErrors.push(`designIntent.designExecutionHandoff.viewportMutationPlan.${viewportKey}.forbiddenPatterns must contain at least one anti-pattern.`);
|
|
1325
|
-
}
|
|
1326
|
-
if (!String(viewportPlan.rationale || '').trim()) {
|
|
1327
|
-
validationErrors.push(`designIntent.designExecutionHandoff.viewportMutationPlan.${viewportKey}.rationale must be a non-empty string.`);
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
if (!Array.isArray(designIntentContract.designExecutionHandoff.interactionStateMatrix) || designIntentContract.designExecutionHandoff.interactionStateMatrix.length < 1) {
|
|
1332
|
-
validationErrors.push('designIntent.designExecutionHandoff.interactionStateMatrix must list key component state expectations.');
|
|
1333
|
-
}
|
|
1334
|
-
if (!Array.isArray(designIntentContract.designExecutionHandoff.taskFlowNarrative) || designIntentContract.designExecutionHandoff.taskFlowNarrative.length < 2) {
|
|
1335
|
-
validationErrors.push('designIntent.designExecutionHandoff.taskFlowNarrative must describe the key UI task flow in sequence.');
|
|
1336
|
-
}
|
|
1337
|
-
if (!String(designIntentContract.designExecutionHandoff.signatureMoveRationale || '').trim()) {
|
|
1338
|
-
validationErrors.push('designIntent.designExecutionHandoff.signatureMoveRationale must explain the chosen authored move.');
|
|
1339
|
-
}
|
|
1340
|
-
const creativeCommitment = designIntentContract.designExecutionHandoff.creativeCommitment;
|
|
1341
|
-
if (!creativeCommitment || typeof creativeCommitment !== 'object') {
|
|
1342
|
-
validationErrors.push('designIntent.designExecutionHandoff.creativeCommitment must exist.');
|
|
1343
|
-
} else {
|
|
1344
|
-
if (creativeCommitment.status !== 'agent-must-complete-before-ui-implementation') {
|
|
1345
|
-
validationErrors.push('designIntent.designExecutionHandoff.creativeCommitment.status must equal "agent-must-complete-before-ui-implementation".');
|
|
1346
|
-
}
|
|
1347
|
-
if (
|
|
1348
|
-
!Array.isArray(creativeCommitment.requiredFields)
|
|
1349
|
-
|| !creativeCommitment.requiredFields.includes('specificReferencePoint')
|
|
1350
|
-
|| !creativeCommitment.requiredFields.includes('signatureMotion')
|
|
1351
|
-
|| !creativeCommitment.requiredFields.includes('typographicDecision')
|
|
1352
|
-
) {
|
|
1353
|
-
validationErrors.push('designIntent.designExecutionHandoff.creativeCommitment.requiredFields must include specificReferencePoint, signatureMotion, and typographicDecision.');
|
|
1354
|
-
}
|
|
1355
|
-
if (!hasNonEmptyString(creativeCommitment.failureMode)) {
|
|
1356
|
-
validationErrors.push('designIntent.designExecutionHandoff.creativeCommitment.failureMode must be a non-empty string.');
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
const implementationGuardrails = designIntentContract.designExecutionHandoff.implementationGuardrails;
|
|
1360
|
-
if (!implementationGuardrails || typeof implementationGuardrails !== 'object') {
|
|
1361
|
-
validationErrors.push('designIntent.designExecutionHandoff.implementationGuardrails must exist.');
|
|
1362
|
-
} else {
|
|
1363
|
-
for (const requiredFlagName of [
|
|
1364
|
-
'requireBuildFromHandoff',
|
|
1365
|
-
'requireGapNotesBeforeFallback',
|
|
1366
|
-
'forbidGenericLayoutFallbackWithoutReason',
|
|
1367
|
-
]) {
|
|
1368
|
-
if (implementationGuardrails[requiredFlagName] !== true) {
|
|
1369
|
-
validationErrors.push(`designIntent.designExecutionHandoff.implementationGuardrails.${requiredFlagName} must equal true.`);
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
if (!designIntentContract.reviewRubric || typeof designIntentContract.reviewRubric !== 'object') {
|
|
1376
|
-
validationErrors.push('designIntent.reviewRubric must exist.');
|
|
1377
|
-
} else {
|
|
1378
|
-
if (designIntentContract.reviewRubric.version !== 'ui-rubric-v1') {
|
|
1379
|
-
validationErrors.push('designIntent.reviewRubric.version must equal "ui-rubric-v1".');
|
|
1380
|
-
}
|
|
1381
|
-
if (designIntentContract.reviewRubric.genericityAutoFail !== true) {
|
|
1382
|
-
validationErrors.push('designIntent.reviewRubric.genericityAutoFail must equal true.');
|
|
1383
|
-
}
|
|
1384
|
-
if (!Array.isArray(designIntentContract.reviewRubric.dimensions) || designIntentContract.reviewRubric.dimensions.length < 5) {
|
|
1385
|
-
validationErrors.push('designIntent.reviewRubric.dimensions must define the required rubric dimensions.');
|
|
1386
|
-
} else {
|
|
1387
|
-
for (const requiredRubricKey of [
|
|
1388
|
-
'distinctiveness',
|
|
1389
|
-
'contractFidelity',
|
|
1390
|
-
'visualConsistency',
|
|
1391
|
-
'heuristicUxQuality',
|
|
1392
|
-
'motionDiscipline',
|
|
1393
|
-
]) {
|
|
1394
|
-
if (!designIntentContract.reviewRubric.dimensions.some((dimension) => dimension?.key === requiredRubricKey)) {
|
|
1395
|
-
validationErrors.push(`designIntent.reviewRubric.dimensions is missing "${requiredRubricKey}".`);
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
if (!Array.isArray(designIntentContract.reviewRubric.genericitySignals) || designIntentContract.reviewRubric.genericitySignals.length < 3) {
|
|
1400
|
-
validationErrors.push('designIntent.reviewRubric.genericitySignals must list common genericity drift signals.');
|
|
1401
|
-
} else {
|
|
1402
|
-
for (const requiredSignal of [
|
|
1403
|
-
'ai-safe-ui-template-look',
|
|
1404
|
-
'ai-color-default-palette-without-product-role-behavior',
|
|
1405
|
-
'interchangeable-product-renaming-test-fails',
|
|
1406
|
-
'decorative-grid-or-glow-wallpaper-without-product-function',
|
|
1407
|
-
'motion-or-3d-omitted-from-fear-without-fit-analysis',
|
|
1408
|
-
]) {
|
|
1409
|
-
if (!designIntentContract.reviewRubric.genericitySignals.includes(requiredSignal)) {
|
|
1410
|
-
validationErrors.push(`designIntent.reviewRubric.genericitySignals must include "${requiredSignal}".`);
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
if (!Array.isArray(designIntentContract.reviewRubric.validBoldSignals) || designIntentContract.reviewRubric.validBoldSignals.length < 3) {
|
|
1415
|
-
validationErrors.push('designIntent.reviewRubric.validBoldSignals must list legitimate authored signals.');
|
|
1416
|
-
} else {
|
|
1417
|
-
for (const requiredSignal of [
|
|
1418
|
-
'three-at-a-glance-product-specific-signals',
|
|
1419
|
-
'visually-exploratory-accessible-palette-derived-from-product',
|
|
1420
|
-
'audacious-accessible-palette-with-product-role-behavior',
|
|
1421
|
-
'motion-or-spatial-experience-derived-from-anchor',
|
|
1422
|
-
]) {
|
|
1423
|
-
if (!designIntentContract.reviewRubric.validBoldSignals.includes(requiredSignal)) {
|
|
1424
|
-
validationErrors.push(`designIntent.reviewRubric.validBoldSignals must include "${requiredSignal}".`);
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
if (!designIntentContract.reviewRubric.reportingRules || typeof designIntentContract.reviewRubric.reportingRules !== 'object') {
|
|
1429
|
-
validationErrors.push('designIntent.reviewRubric.reportingRules must exist.');
|
|
1430
|
-
} else {
|
|
1431
|
-
for (const requiredFlagName of [
|
|
1432
|
-
'mustExplainGenericity',
|
|
1433
|
-
'mustSeparateTasteFromFailure',
|
|
1434
|
-
'contractFidelityOverridesPersonalTaste',
|
|
1435
|
-
]) {
|
|
1436
|
-
if (designIntentContract.reviewRubric.reportingRules[requiredFlagName] !== true) {
|
|
1437
|
-
validationErrors.push(`designIntent.reviewRubric.reportingRules.${requiredFlagName} must equal true.`);
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
|
-
if (!Array.isArray(designIntentContract.requiredDesignSections) || designIntentContract.requiredDesignSections.length !== DESIGN_REQUIRED_SECTIONS.length) {
|
|
1444
|
-
validationErrors.push('designIntent.requiredDesignSections must match the required design contract sections.');
|
|
1445
|
-
} else {
|
|
1446
|
-
for (const requiredSectionName of DESIGN_REQUIRED_SECTIONS) {
|
|
1447
|
-
if (!designIntentContract.requiredDesignSections.includes(requiredSectionName)) {
|
|
1448
|
-
validationErrors.push(`designIntent.requiredDesignSections is missing "${requiredSectionName}".`);
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
if (!Array.isArray(designIntentContract.forbiddenPatterns) || designIntentContract.forbiddenPatterns.length < 4) {
|
|
1454
|
-
validationErrors.push('designIntent.forbiddenPatterns must list concrete anti-generic patterns.');
|
|
1455
|
-
} else {
|
|
1456
|
-
for (const requiredPattern of [
|
|
1457
|
-
'ai-safe-ui-template-look',
|
|
1458
|
-
'ai-color-default-palette-without-product-role-behavior',
|
|
1459
|
-
'interchangeable-product-renaming-test-fails',
|
|
1460
|
-
'decorative-grid-or-glow-wallpaper-without-product-function',
|
|
1461
|
-
'motion-or-3d-omitted-from-fear-without-fit-analysis',
|
|
1462
|
-
]) {
|
|
1463
|
-
if (!designIntentContract.forbiddenPatterns.includes(requiredPattern)) {
|
|
1464
|
-
validationErrors.push(`designIntent.forbiddenPatterns must include "${requiredPattern}".`);
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
}
|
|
1468
|
-
|
|
1469
|
-
return validationErrors;
|
|
1470
|
-
}
|
|
665
|
+
export { validateDesignContractCompleteness, validateDesignIntentContract } from './design-contract/validation.mjs';
|
|
1471
666
|
|
|
1472
667
|
export function buildDesignIntentSeedFromSignals({
|
|
1473
668
|
projectName,
|