@ryuenn3123/agentic-senior-core 3.0.19 → 3.0.20
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 +84 -103
- package/.agent-context/prompts/init-project.md +32 -100
- package/.agent-context/prompts/refactor.md +22 -44
- package/.agent-context/prompts/review-code.md +28 -52
- package/.agent-context/review-checklists/architecture-review.md +31 -62
- package/.agent-context/review-checklists/pr-checklist.md +74 -108
- package/.agent-context/rules/api-docs.md +18 -206
- package/.agent-context/rules/architecture.md +40 -207
- package/.agent-context/rules/database-design.md +10 -199
- package/.agent-context/rules/docker-runtime.md +5 -5
- package/.agent-context/rules/efficiency-vs-hype.md +11 -149
- package/.agent-context/rules/error-handling.md +9 -231
- package/.agent-context/rules/event-driven.md +17 -221
- package/.agent-context/rules/frontend-architecture.md +66 -119
- package/.agent-context/rules/git-workflow.md +1 -1
- package/.agent-context/rules/microservices.md +28 -161
- package/.agent-context/rules/naming-conv.md +8 -138
- package/.agent-context/rules/performance.md +9 -175
- package/.agent-context/rules/realtime.md +11 -44
- package/.agent-context/rules/security.md +11 -295
- package/.agent-context/rules/testing.md +9 -174
- package/.agent-context/state/benchmark-analysis.json +3 -3
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.agent-context/state/onboarding-report.json +71 -11
- package/.agents/workflows/init-project.md +7 -24
- package/.agents/workflows/refactor.md +7 -24
- package/.agents/workflows/review-code.md +7 -24
- package/.cursorrules +22 -21
- package/.gemini/instructions.md +2 -2
- package/.github/copilot-instructions.md +2 -2
- package/.instructions.md +112 -213
- package/.windsurfrules +22 -21
- package/AGENTS.md +4 -4
- package/CONTRIBUTING.md +13 -22
- package/README.md +6 -20
- package/lib/cli/commands/init.mjs +102 -148
- package/lib/cli/commands/launch.mjs +3 -3
- package/lib/cli/commands/optimize.mjs +14 -4
- package/lib/cli/commands/upgrade.mjs +25 -23
- package/lib/cli/compiler.mjs +96 -62
- package/lib/cli/constants.mjs +28 -136
- package/lib/cli/detector/design-evidence.mjs +189 -6
- package/lib/cli/detector.mjs +6 -7
- package/lib/cli/init-detection-flow.mjs +10 -93
- package/lib/cli/init-selection.mjs +2 -68
- package/lib/cli/project-scaffolder/constants.mjs +1 -1
- package/lib/cli/project-scaffolder/design-contract.mjs +162 -108
- package/lib/cli/project-scaffolder/discovery.mjs +36 -82
- package/lib/cli/project-scaffolder/prompt-builders.mjs +41 -55
- package/lib/cli/project-scaffolder/storage.mjs +0 -2
- package/lib/cli/token-optimization.mjs +1 -1
- package/lib/cli/utils.mjs +75 -9
- package/package.json +2 -2
- package/scripts/detection-benchmark.mjs +4 -15
- package/scripts/documentation-boundary-audit.mjs +9 -9
- package/scripts/explain-on-demand-audit.mjs +11 -11
- package/scripts/forbidden-content-check.mjs +9 -9
- package/scripts/frontend-usability-audit.mjs +45 -35
- package/scripts/llm-judge.mjs +1 -1
- package/scripts/mcp-server/constants.mjs +2 -2
- package/scripts/mcp-server/tool-registry.mjs +1 -1
- package/scripts/release-gate/audit-checks.mjs +4 -4
- package/scripts/release-gate/static-checks.mjs +5 -5
- package/scripts/release-gate.mjs +1 -1
- package/scripts/rules-guardian-audit.mjs +14 -13
- package/scripts/single-source-lazy-loading-audit.mjs +3 -3
- package/scripts/sync-thin-adapters.mjs +5 -5
- package/scripts/ui-design-judge/design-execution-summary.mjs +27 -1
- package/scripts/ui-design-judge/prompting.mjs +4 -4
- package/scripts/ui-design-judge/reporting.mjs +2 -1
- package/scripts/ui-design-judge/rubric-calibration.mjs +8 -5
- package/scripts/ui-design-judge/rubric-goldset.json +2 -2
- package/scripts/ui-design-judge.mjs +70 -6
- package/scripts/validate/config.mjs +138 -48
- package/scripts/validate/coverage-checks.mjs +32 -7
- package/scripts/validate.mjs +8 -4
- package/lib/cli/architect.mjs +0 -431
|
@@ -36,7 +36,6 @@ function buildStructureFirstSeedSignals({
|
|
|
36
36
|
supplementalFields = {},
|
|
37
37
|
}) {
|
|
38
38
|
const normalizedDescription = String(projectDescription || '').trim();
|
|
39
|
-
const normalizedDomain = String(primaryDomain || '').trim().toLowerCase();
|
|
40
39
|
const repoEvidenceSummary = supplementalFields?.repoEvidence?.designEvidenceSummary || null;
|
|
41
40
|
const hasRepoEvidence = Boolean(
|
|
42
41
|
repoEvidenceSummary
|
|
@@ -49,38 +48,37 @@ function buildStructureFirstSeedSignals({
|
|
|
49
48
|
const projectContextLabel = normalizedDescription
|
|
50
49
|
? `the product context "${normalizedDescription}"`
|
|
51
50
|
: 'the current product context';
|
|
52
|
-
const isMobileLikeSurface = normalizedDomain.includes('mobile');
|
|
53
51
|
|
|
54
52
|
return {
|
|
55
|
-
designPhilosophy: `Use ${evidenceSourceLabel} to synthesize
|
|
56
|
-
brandAdjectives: ['
|
|
57
|
-
antiAdjectives: ['template-
|
|
58
|
-
typographyScaleRatio: '
|
|
59
|
-
baseGridUnit:
|
|
60
|
-
spacingPattern:
|
|
61
|
-
densityMode:
|
|
62
|
-
colorIntent: `
|
|
63
|
-
paletteRoles: ['
|
|
53
|
+
designPhilosophy: `Use ${evidenceSourceLabel} to synthesize the design system for ${projectName || 'this project'}. This seed is only a decision scaffold: the LLM must choose the visual language, libraries, color system, typography, spacing, and interaction model from ${projectContextLabel}, current repo evidence, and live official documentation when a technology claim is needed.`,
|
|
54
|
+
brandAdjectives: ['agent-synthesized-from-current-context'],
|
|
55
|
+
antiAdjectives: ['offline-prescribed-style', 'template-by-default', 'scale-only-responsive', 'unresearched-library-choice'],
|
|
56
|
+
typographyScaleRatio: 'agent-calibrated-from-content-platform-and-readability',
|
|
57
|
+
baseGridUnit: 'agent-calibrated-from-platform-density-and-implementation-stack',
|
|
58
|
+
spacingPattern: 'agent-defined-from-task-flow-and-viewport-needs',
|
|
59
|
+
densityMode: 'agent-defined-from-user-task-device-and-content-pressure',
|
|
60
|
+
colorIntent: `Choose semantic palette roles from ${projectContextLabel}, current repo evidence, and accessibility needs. Do not inherit fixed palettes or generic SaaS color defaults from this scaffold.`,
|
|
61
|
+
paletteRoles: ['agent-defined-semantic-roles'],
|
|
64
62
|
distinctiveMoves: [
|
|
65
|
-
'
|
|
66
|
-
'
|
|
67
|
-
'Document why the
|
|
63
|
+
'Research and choose a current, project-fit visual direction instead of inheriting any offline preset from this scaffold.',
|
|
64
|
+
'Define at least one recognizable design move from the product task, audience, content, and repo evidence before implementation.',
|
|
65
|
+
'Document why the chosen move belongs to this project and which common LLM bad habit it intentionally avoids.',
|
|
68
66
|
],
|
|
69
|
-
motionPurpose: 'Use motion
|
|
70
|
-
motionChoreography: '
|
|
67
|
+
motionPurpose: 'Use modern motion when it improves hierarchy, continuity, feedback, memorability, or perceived product quality. If implementation needs a motion library, the LLM must choose a current compatible option from official docs instead of relying on an offline default.',
|
|
68
|
+
motionChoreography: 'Define choreography from the product experience and implementation stack. Keep it performant and reduced-motion-safe; do not suppress rich interaction by default.',
|
|
71
69
|
motionDurations: {
|
|
72
|
-
desktop:
|
|
73
|
-
mobile:
|
|
70
|
+
desktop: 'agent-calibrated',
|
|
71
|
+
mobile: 'agent-calibrated',
|
|
74
72
|
},
|
|
75
73
|
componentMorphology: {
|
|
76
|
-
mobile: '
|
|
77
|
-
tablet: '
|
|
78
|
-
desktop: '
|
|
74
|
+
mobile: 'Recompose the experience for touch, task priority, and constrained attention. Mobile should be a deliberate mobile design, not a shrunken desktop.',
|
|
75
|
+
tablet: 'Regroup surfaces for medium-width use, preserving task clarity without cloning either desktop or mobile blindly.',
|
|
76
|
+
desktop: 'Use the available space to improve hierarchy, scanability, and interaction quality without defaulting to template grids or generic dashboard chrome.',
|
|
79
77
|
},
|
|
80
78
|
mutationRules: {
|
|
81
|
-
mobile: '
|
|
82
|
-
tablet: '
|
|
83
|
-
desktop: '
|
|
79
|
+
mobile: 'Define a mobile-specific composition with reordered, merged, or disclosed content where appropriate. Scale-only shrink behavior is failure.',
|
|
80
|
+
tablet: 'Define a tablet-specific regrouping strategy rather than a width-only reduction of desktop.',
|
|
81
|
+
desktop: 'Define a desktop composition that uses space intentionally and avoids generic equal-weight modules unless the project evidence justifies them.',
|
|
84
82
|
},
|
|
85
83
|
};
|
|
86
84
|
}
|
|
@@ -115,8 +113,12 @@ function buildDesignIntentContractObject({
|
|
|
115
113
|
name: projectName,
|
|
116
114
|
context: projectDescription,
|
|
117
115
|
domain: primaryDomain,
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
runtimeConstraint: initContext.stackFileName === 'agent-decision-runtime.md'
|
|
117
|
+
? 'agent-recommendation-required'
|
|
118
|
+
: toTitleCase(initContext.stackFileName),
|
|
119
|
+
architectureConstraint: initContext.blueprintFileName === 'agent-decision-architecture.md'
|
|
120
|
+
? 'agent-recommendation-required'
|
|
121
|
+
: toTitleCase(initContext.blueprintFileName),
|
|
120
122
|
},
|
|
121
123
|
designPhilosophy: inferredKeywords.designPhilosophy,
|
|
122
124
|
brandAdjectives: inferredKeywords.brandAdjectives,
|
|
@@ -124,7 +126,8 @@ function buildDesignIntentContractObject({
|
|
|
124
126
|
visualDirection: {
|
|
125
127
|
seedMode: 'scaffold-only',
|
|
126
128
|
requiresProjectSpecificSynthesis: true,
|
|
127
|
-
|
|
129
|
+
selectionAuthority: 'agent-llm-after-current-context-repo-evidence-and-live-official-docs',
|
|
130
|
+
trendStance: 'current-context-first-not-offline-preset-first',
|
|
128
131
|
distinctiveMoves: inferredKeywords.distinctiveMoves,
|
|
129
132
|
copiedReferenceAllowed: false,
|
|
130
133
|
},
|
|
@@ -169,6 +172,7 @@ function buildDesignIntentContractObject({
|
|
|
169
172
|
paletteRoles: inferredKeywords.paletteRoles,
|
|
170
173
|
rolePolicy: 'minimum-semantic-scaffold',
|
|
171
174
|
rolesAreMinimumScaffold: true,
|
|
175
|
+
rolesMustBeAgentDefined: true,
|
|
172
176
|
intent: inferredKeywords.colorIntent,
|
|
173
177
|
},
|
|
174
178
|
crossViewportAdaptation: {
|
|
@@ -231,6 +235,8 @@ function buildDesignIntentContractObject({
|
|
|
231
235
|
requireRepoEvidenceAlignment: true,
|
|
232
236
|
forbidScreenshotDependency: true,
|
|
233
237
|
handoffFormatVersion: 'ui-handoff-v1',
|
|
238
|
+
requirePerSurfaceMutationOps: true,
|
|
239
|
+
forbidUniformSiblingSurfaceTreatment: true,
|
|
234
240
|
semanticReviewFocus: [
|
|
235
241
|
'distinctiveness-vs-genericity',
|
|
236
242
|
'contract-fidelity',
|
|
@@ -245,77 +251,99 @@ function buildDesignIntentContractObject({
|
|
|
245
251
|
status: 'seed-needs-refinement',
|
|
246
252
|
seedMode: 'structure-first-scaffold',
|
|
247
253
|
requiresTaskSpecificRefinement: true,
|
|
248
|
-
primaryExperienceGoal: `
|
|
254
|
+
primaryExperienceGoal: `Ask the LLM to define the main ${String(primaryDomain || 'product').toLowerCase()} journey in ${projectName} from repo evidence, product context, user goals, and current official documentation where technology choices matter. This scaffold must not prescribe the final visual layout.`,
|
|
249
255
|
surfacePlan: [
|
|
250
256
|
{
|
|
251
|
-
surfaceId: 'primary-
|
|
252
|
-
role: '
|
|
253
|
-
goal: `
|
|
254
|
-
primaryAction: '
|
|
255
|
-
supportingModules: ['context'
|
|
256
|
-
|
|
257
|
+
surfaceId: 'agent-defined-primary-experience',
|
|
258
|
+
role: 'llm-synthesized-from-current-context',
|
|
259
|
+
goal: `Define the primary UI experience for ${projectName} from the actual product task, audience, data, and repo evidence before coding.`,
|
|
260
|
+
primaryAction: 'The LLM must choose the first decisive action or reading path and explain why it fits the project.',
|
|
261
|
+
supportingModules: ['agent-defined-from-current-context'],
|
|
262
|
+
layoutAntiPatternToAvoid: 'template-default-without-product-rationale',
|
|
263
|
+
signatureMoveHint: 'Choose and document one project-specific visual, interaction, or content move. Do not inherit it from this scaffold.',
|
|
257
264
|
},
|
|
258
265
|
{
|
|
259
|
-
surfaceId: 'supporting-
|
|
260
|
-
role: '
|
|
261
|
-
goal: 'Define
|
|
262
|
-
primaryAction: '
|
|
263
|
-
supportingModules: ['
|
|
264
|
-
|
|
266
|
+
surfaceId: 'agent-defined-supporting-experience',
|
|
267
|
+
role: 'llm-synthesized-supporting-context',
|
|
268
|
+
goal: 'Define supporting, proof, utility, or recovery surfaces from actual user needs instead of cloning generic cards or rails.',
|
|
269
|
+
primaryAction: 'The LLM must decide what belongs beside, below, hidden behind disclosure, or removed based on task priority.',
|
|
270
|
+
supportingModules: ['agent-defined-from-current-context'],
|
|
271
|
+
layoutAntiPatternToAvoid: 'scale-only-responsive-layout',
|
|
272
|
+
signatureMoveHint: 'Explain how supporting content changes across viewports and why the change improves the experience.',
|
|
265
273
|
},
|
|
266
274
|
],
|
|
267
275
|
componentGraph: {
|
|
268
276
|
nodes: [
|
|
269
277
|
{
|
|
270
|
-
id: 'primary-
|
|
271
|
-
role: '
|
|
278
|
+
id: 'agent-defined-primary-experience',
|
|
279
|
+
role: 'primary-experience-after-synthesis',
|
|
272
280
|
priority: 'high',
|
|
273
281
|
},
|
|
274
282
|
{
|
|
275
|
-
id: 'supporting-
|
|
276
|
-
role: '
|
|
277
|
-
priority: 'medium',
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
id: 'feedback-status-module',
|
|
281
|
-
role: 'feedback-and-proof',
|
|
283
|
+
id: 'agent-defined-supporting-experience',
|
|
284
|
+
role: 'supporting-experience-after-synthesis',
|
|
282
285
|
priority: 'medium',
|
|
283
286
|
},
|
|
284
287
|
],
|
|
285
288
|
edges: [
|
|
286
289
|
{
|
|
287
|
-
from: 'primary-
|
|
288
|
-
to: 'supporting-
|
|
289
|
-
relationship: '
|
|
290
|
-
},
|
|
291
|
-
{
|
|
292
|
-
from: 'primary-action-surface',
|
|
293
|
-
to: 'feedback-status-module',
|
|
294
|
-
relationship: 'state-feedback',
|
|
290
|
+
from: 'agent-defined-primary-experience',
|
|
291
|
+
to: 'agent-defined-supporting-experience',
|
|
292
|
+
relationship: 'agent-defined-from-task-priority',
|
|
295
293
|
},
|
|
296
294
|
],
|
|
297
295
|
},
|
|
298
296
|
contentPriorityMap: {
|
|
299
297
|
primary: [
|
|
300
|
-
'core-task-
|
|
301
|
-
'primary-status-or-value-message',
|
|
302
|
-
'decisive-action-labeling',
|
|
298
|
+
'agent-defined-core-task-or-reading-path',
|
|
303
299
|
],
|
|
304
300
|
secondary: [
|
|
305
|
-
'supporting-
|
|
306
|
-
'navigation-context',
|
|
307
|
-
'secondary-actions',
|
|
301
|
+
'agent-defined-supporting-context',
|
|
308
302
|
],
|
|
309
303
|
deferred: [
|
|
310
|
-
'
|
|
311
|
-
'tertiary-metadata',
|
|
312
|
-
'low-priority-decoration',
|
|
304
|
+
'agent-defined-deferred-or-hidden-content',
|
|
313
305
|
],
|
|
314
306
|
},
|
|
315
307
|
viewportMutationPlan: {
|
|
316
|
-
mobile:
|
|
317
|
-
|
|
318
|
-
|
|
308
|
+
mobile: {
|
|
309
|
+
primaryOperation: 'agent-defined-mobile-recomposition',
|
|
310
|
+
requiredSurfaceActions: [
|
|
311
|
+
'choose-mobile-specific-task-order',
|
|
312
|
+
'merge-disclose-or-remove-low-priority-content',
|
|
313
|
+
'adapt-interaction-model-for-touch',
|
|
314
|
+
],
|
|
315
|
+
forbiddenPatterns: [
|
|
316
|
+
'scale-only-shrink',
|
|
317
|
+
'desktop-order-preserved-without-priority-shift',
|
|
318
|
+
],
|
|
319
|
+
rationale: inferredKeywords.mutationRules.mobile,
|
|
320
|
+
},
|
|
321
|
+
tablet: {
|
|
322
|
+
primaryOperation: 'agent-defined-tablet-regrouping',
|
|
323
|
+
requiredSurfaceActions: [
|
|
324
|
+
'define-medium-width-information-architecture',
|
|
325
|
+
'avoid-cloning-desktop-by-width-only',
|
|
326
|
+
'preserve-task-clarity',
|
|
327
|
+
],
|
|
328
|
+
forbiddenPatterns: [
|
|
329
|
+
'desktop-layout-reduced-by-width-only',
|
|
330
|
+
'uniform-module-grid-without-role-change',
|
|
331
|
+
],
|
|
332
|
+
rationale: inferredKeywords.mutationRules.tablet,
|
|
333
|
+
},
|
|
334
|
+
desktop: {
|
|
335
|
+
primaryOperation: 'agent-defined-desktop-composition',
|
|
336
|
+
requiredSurfaceActions: [
|
|
337
|
+
'use-space-to-improve-hierarchy',
|
|
338
|
+
'define-scan-pattern-and-action-priority',
|
|
339
|
+
'avoid-equalizing-unrelated-content',
|
|
340
|
+
],
|
|
341
|
+
forbiddenPatterns: [
|
|
342
|
+
'template-shell-without-product-rationale',
|
|
343
|
+
'interchangeable-dashboard-or-landing-chrome',
|
|
344
|
+
],
|
|
345
|
+
rationale: inferredKeywords.mutationRules.desktop,
|
|
346
|
+
},
|
|
319
347
|
},
|
|
320
348
|
interactionStateMatrix: [
|
|
321
349
|
{
|
|
@@ -330,11 +358,11 @@ function buildDesignIntentContractObject({
|
|
|
330
358
|
},
|
|
331
359
|
],
|
|
332
360
|
taskFlowNarrative: [
|
|
333
|
-
`Entry:
|
|
334
|
-
'Decision: define
|
|
335
|
-
'Resolution:
|
|
361
|
+
`Entry: the LLM must define how ${projectName} starts the user journey from real product evidence instead of a generic opening pattern.`,
|
|
362
|
+
'Decision: the LLM must define hierarchy, proof, state language, and interaction behavior from the actual task.',
|
|
363
|
+
'Resolution: the LLM must define feedback, recovery, and next-useful-action behavior without defaulting to leftover template chrome.',
|
|
336
364
|
],
|
|
337
|
-
signatureMoveRationale: '
|
|
365
|
+
signatureMoveRationale: 'The LLM must choose the project-specific visual, motion, typographic, compositional, or interaction move after reading current context and explain why a generic fallback would weaken the product.',
|
|
338
366
|
implementationGuardrails: {
|
|
339
367
|
requireBuildFromHandoff: true,
|
|
340
368
|
requireGapNotesBeforeFallback: true,
|
|
@@ -343,10 +371,11 @@ function buildDesignIntentContractObject({
|
|
|
343
371
|
},
|
|
344
372
|
reviewRubric: {
|
|
345
373
|
version: 'ui-rubric-v1',
|
|
374
|
+
genericityAutoFail: true,
|
|
346
375
|
dimensions: [
|
|
347
376
|
{
|
|
348
377
|
key: 'distinctiveness',
|
|
349
|
-
blockingByDefault:
|
|
378
|
+
blockingByDefault: true,
|
|
350
379
|
question: 'Does the UI feel authored and project-specific rather than like a default framework or template kit?',
|
|
351
380
|
},
|
|
352
381
|
{
|
|
@@ -371,18 +400,20 @@ function buildDesignIntentContractObject({
|
|
|
371
400
|
},
|
|
372
401
|
],
|
|
373
402
|
genericitySignals: [
|
|
374
|
-
'
|
|
375
|
-
'
|
|
376
|
-
'default-
|
|
377
|
-
'
|
|
378
|
-
'
|
|
403
|
+
'offline-prescribed-style-used-as-final-direction',
|
|
404
|
+
'unresearched-library-or-framework-choice',
|
|
405
|
+
'default-component-kit-treatment-without-product-rationale',
|
|
406
|
+
'scale-only-responsive-layout',
|
|
407
|
+
'template-shell-without-product-rationale',
|
|
408
|
+
'inaccessible-or-decorative-motion',
|
|
379
409
|
],
|
|
380
410
|
validBoldSignals: [
|
|
381
|
-
'
|
|
382
|
-
'
|
|
383
|
-
'
|
|
384
|
-
'
|
|
385
|
-
'
|
|
411
|
+
'context-derived-visual-direction',
|
|
412
|
+
'official-docs-backed-library-choice',
|
|
413
|
+
'responsive-recomposition-by-task-priority',
|
|
414
|
+
'purposeful-motion-with-reduced-motion-path',
|
|
415
|
+
'documented-design-rationale-before-code',
|
|
416
|
+
'clean-component-and-token-architecture',
|
|
386
417
|
],
|
|
387
418
|
reportingRules: {
|
|
388
419
|
mustExplainGenericity: true,
|
|
@@ -396,7 +427,7 @@ function buildDesignIntentContractObject({
|
|
|
396
427
|
'current-repo-evidence',
|
|
397
428
|
'current-user-brief',
|
|
398
429
|
'current-project-docs',
|
|
399
|
-
'explicitly-approved-
|
|
430
|
+
'explicitly-approved-current-task-constraints',
|
|
400
431
|
],
|
|
401
432
|
taintedSources: [
|
|
402
433
|
'prior-chat-visual-memory',
|
|
@@ -407,7 +438,7 @@ function buildDesignIntentContractObject({
|
|
|
407
438
|
repoEvidenceOverridesMemory: true,
|
|
408
439
|
requireExplicitContinuityApproval: true,
|
|
409
440
|
forbidCarryoverWhenUnapproved: true,
|
|
410
|
-
|
|
441
|
+
approvedExternalConstraintUsage: 'Convert explicit user-supplied external constraints into current-project rules without comparing against or imitating the source surface.',
|
|
411
442
|
driftSignals: [
|
|
412
443
|
'palette-reused-without-brief-support',
|
|
413
444
|
'motion-signature-reused-without-approval',
|
|
@@ -419,15 +450,17 @@ function buildDesignIntentContractObject({
|
|
|
419
450
|
'Major interface decisions must be explainable in product and user terms.',
|
|
420
451
|
'Accessibility, responsiveness, and implementation realism are non-negotiable.',
|
|
421
452
|
'Cross-viewport behavior must reorganize tasks and navigation, not just scale the desktop layout down.',
|
|
422
|
-
'
|
|
423
|
-
'
|
|
453
|
+
'Modern libraries and interaction patterns may be used when the LLM verifies they fit the project and current official docs.',
|
|
454
|
+
'Motion may be rich and memorable when it improves the product experience, but it must stay purposeful, performant, and optional for reduced-motion users.',
|
|
455
|
+
'At least one visual, interaction, content, or motion decision must be recognizable at a glance and justified from context.',
|
|
424
456
|
],
|
|
425
457
|
forbiddenPatterns: [
|
|
426
|
-
'
|
|
427
|
-
'
|
|
428
|
-
'
|
|
429
|
-
'placeholder-design-language',
|
|
458
|
+
'offline-prescribed-style-used-as-final-direction',
|
|
459
|
+
'unresearched-library-or-framework-choice',
|
|
460
|
+
'default-component-kit-treatment-without-product-rationale',
|
|
430
461
|
'scale-only-responsive-layout',
|
|
462
|
+
'template-shell-without-product-rationale',
|
|
463
|
+
'single-safe-typographic-family-without-role-contrast-or-rationale',
|
|
431
464
|
],
|
|
432
465
|
validationHints: {
|
|
433
466
|
rejectArbitraryHexOnlyPalette: true,
|
|
@@ -444,6 +477,7 @@ function buildDesignIntentContractObject({
|
|
|
444
477
|
requireStructuredDesignHandoff: true,
|
|
445
478
|
requireReviewRubric: true,
|
|
446
479
|
requireGenericityExplanation: true,
|
|
480
|
+
genericityAutoFail: true,
|
|
447
481
|
requireSignatureMove: true,
|
|
448
482
|
rejectTemplateNeutralLayout: true,
|
|
449
483
|
},
|
|
@@ -493,11 +527,11 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
493
527
|
if (!designIntentContract.mathSystems || typeof designIntentContract.mathSystems !== 'object') {
|
|
494
528
|
validationErrors.push('designIntent.mathSystems must exist.');
|
|
495
529
|
} else {
|
|
496
|
-
if (
|
|
497
|
-
validationErrors.push('designIntent.mathSystems.typographyScaleRatio must
|
|
530
|
+
if (!String(designIntentContract.mathSystems.typographyScaleRatio || '').trim()) {
|
|
531
|
+
validationErrors.push('designIntent.mathSystems.typographyScaleRatio must describe the chosen or pending type scale decision.');
|
|
498
532
|
}
|
|
499
|
-
if (!
|
|
500
|
-
validationErrors.push('designIntent.mathSystems.baseGridUnit must
|
|
533
|
+
if (!String(designIntentContract.mathSystems.baseGridUnit || '').trim()) {
|
|
534
|
+
validationErrors.push('designIntent.mathSystems.baseGridUnit must describe the chosen or pending spacing grid decision.');
|
|
501
535
|
}
|
|
502
536
|
}
|
|
503
537
|
|
|
@@ -563,14 +597,11 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
563
597
|
validationErrors.push('designIntent.colorTruth.intent must be a non-empty string.');
|
|
564
598
|
}
|
|
565
599
|
const paletteRoles = designIntentContract.colorTruth.paletteRoles;
|
|
566
|
-
if (!Array.isArray(paletteRoles) || paletteRoles.length <
|
|
567
|
-
validationErrors.push('designIntent.colorTruth.paletteRoles must define
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
validationErrors.push(`designIntent.colorTruth.paletteRoles is missing "${requiredPaletteRole}".`);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
600
|
+
if (!Array.isArray(paletteRoles) || paletteRoles.length < 1) {
|
|
601
|
+
validationErrors.push('designIntent.colorTruth.paletteRoles must define or request agent-defined semantic palette roles.');
|
|
602
|
+
}
|
|
603
|
+
if (designIntentContract.colorTruth.rolesMustBeAgentDefined !== true) {
|
|
604
|
+
validationErrors.push('designIntent.colorTruth.rolesMustBeAgentDefined must equal true.');
|
|
574
605
|
}
|
|
575
606
|
}
|
|
576
607
|
|
|
@@ -697,8 +728,8 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
697
728
|
if (!Array.isArray(designIntentContract.contextHygiene.taintedSources) || designIntentContract.contextHygiene.taintedSources.length < 3) {
|
|
698
729
|
validationErrors.push('designIntent.contextHygiene.taintedSources must list tainted carryover sources.');
|
|
699
730
|
}
|
|
700
|
-
if (!String(designIntentContract.contextHygiene.
|
|
701
|
-
validationErrors.push('designIntent.contextHygiene.
|
|
731
|
+
if (!String(designIntentContract.contextHygiene.approvedExternalConstraintUsage || '').trim()) {
|
|
732
|
+
validationErrors.push('designIntent.contextHygiene.approvedExternalConstraintUsage must be a non-empty string.');
|
|
702
733
|
}
|
|
703
734
|
}
|
|
704
735
|
|
|
@@ -719,6 +750,8 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
719
750
|
'requireStructuredHandoff',
|
|
720
751
|
'requireRepoEvidenceAlignment',
|
|
721
752
|
'forbidScreenshotDependency',
|
|
753
|
+
'requirePerSurfaceMutationOps',
|
|
754
|
+
'forbidUniformSiblingSurfaceTreatment',
|
|
722
755
|
]) {
|
|
723
756
|
if (designIntentContract.designExecutionPolicy[requiredFlagName] !== true) {
|
|
724
757
|
validationErrors.push(`designIntent.designExecutionPolicy.${requiredFlagName} must equal true.`);
|
|
@@ -779,8 +812,22 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
779
812
|
validationErrors.push('designIntent.designExecutionHandoff.viewportMutationPlan must exist.');
|
|
780
813
|
} else {
|
|
781
814
|
for (const viewportKey of ['mobile', 'tablet', 'desktop']) {
|
|
782
|
-
|
|
783
|
-
|
|
815
|
+
const viewportPlan = viewportMutationPlan[viewportKey];
|
|
816
|
+
if (!viewportPlan || typeof viewportPlan !== 'object') {
|
|
817
|
+
validationErrors.push(`designIntent.designExecutionHandoff.viewportMutationPlan.${viewportKey} must be an object.`);
|
|
818
|
+
continue;
|
|
819
|
+
}
|
|
820
|
+
if (!String(viewportPlan.primaryOperation || '').trim()) {
|
|
821
|
+
validationErrors.push(`designIntent.designExecutionHandoff.viewportMutationPlan.${viewportKey}.primaryOperation must be a non-empty string.`);
|
|
822
|
+
}
|
|
823
|
+
if (!Array.isArray(viewportPlan.requiredSurfaceActions) || viewportPlan.requiredSurfaceActions.length < 2) {
|
|
824
|
+
validationErrors.push(`designIntent.designExecutionHandoff.viewportMutationPlan.${viewportKey}.requiredSurfaceActions must contain at least two actions.`);
|
|
825
|
+
}
|
|
826
|
+
if (!Array.isArray(viewportPlan.forbiddenPatterns) || viewportPlan.forbiddenPatterns.length < 1) {
|
|
827
|
+
validationErrors.push(`designIntent.designExecutionHandoff.viewportMutationPlan.${viewportKey}.forbiddenPatterns must contain at least one anti-pattern.`);
|
|
828
|
+
}
|
|
829
|
+
if (!String(viewportPlan.rationale || '').trim()) {
|
|
830
|
+
validationErrors.push(`designIntent.designExecutionHandoff.viewportMutationPlan.${viewportKey}.rationale must be a non-empty string.`);
|
|
784
831
|
}
|
|
785
832
|
}
|
|
786
833
|
}
|
|
@@ -815,6 +862,9 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
815
862
|
if (designIntentContract.reviewRubric.version !== 'ui-rubric-v1') {
|
|
816
863
|
validationErrors.push('designIntent.reviewRubric.version must equal "ui-rubric-v1".');
|
|
817
864
|
}
|
|
865
|
+
if (designIntentContract.reviewRubric.genericityAutoFail !== true) {
|
|
866
|
+
validationErrors.push('designIntent.reviewRubric.genericityAutoFail must equal true.');
|
|
867
|
+
}
|
|
818
868
|
if (!Array.isArray(designIntentContract.reviewRubric.dimensions) || designIntentContract.reviewRubric.dimensions.length < 5) {
|
|
819
869
|
validationErrors.push('designIntent.reviewRubric.dimensions must define the required rubric dimensions.');
|
|
820
870
|
} else {
|
|
@@ -861,6 +911,10 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
861
911
|
}
|
|
862
912
|
}
|
|
863
913
|
|
|
914
|
+
if (!Array.isArray(designIntentContract.forbiddenPatterns) || designIntentContract.forbiddenPatterns.length < 4) {
|
|
915
|
+
validationErrors.push('designIntent.forbiddenPatterns must list concrete anti-generic patterns.');
|
|
916
|
+
}
|
|
917
|
+
|
|
864
918
|
return validationErrors;
|
|
865
919
|
}
|
|
866
920
|
|