@ryuenn3123/agentic-senior-core 4.3.6 → 4.3.8
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 +30 -40
- package/.agent-context/prompts/init-project.md +2 -4
- package/.agent-context/prompts/refactor.md +1 -1
- package/.agent-context/prompts/review-code.md +2 -2
- package/.agent-context/review-checklists/pr-checklist.md +2 -2
- package/.agent-context/rules/architecture.md +1 -5
- package/.agent-context/rules/frontend-architecture.md +1 -1
- package/AGENTS.md +3 -2
- package/README.md +1 -1
- package/lib/cli/adaptive-context/catalog.mjs +1 -36
- package/lib/cli/audits/typography-palette-anti-repeat-audit.mjs +7 -23
- package/lib/cli/compiler.mjs +0 -1
- package/lib/cli/project-scaffolder/prompt-builders.mjs +13 -14
- package/lib/cli/project-scaffolder/storage.mjs +1 -1
- package/lib/cli/project-scaffolder/ui-scope-detection.mjs +36 -0
- package/lib/cli/project-scaffolder.mjs +1 -3
- package/package.json +1 -1
- package/scripts/adaptive-context/fixtures.mjs +7 -12
- package/scripts/context-triggered-audit.mjs +1 -6
- package/scripts/frontend-usability-audit.mjs +2 -7
- package/scripts/release-gate/constants.mjs +0 -12
- package/scripts/ui-design-judge/constants.mjs +1 -12
- package/scripts/ui-design-judge/design-execution-summary.mjs +50 -228
- package/scripts/ui-design-judge/prompting.mjs +4 -25
- package/scripts/ui-design-judge.mjs +6 -5
- package/scripts/validate/config.mjs +5 -89
- package/scripts/validate/file-structure.mjs +0 -3
- package/.agent-context/rules/efficiency-vs-hype.md +0 -15
- package/.agent-context/rules/git-workflow.md +0 -15
- package/.agent-context/rules/naming-conv.md +0 -35
- package/lib/cli/project-scaffolder/design-contract/sections/audits.mjs +0 -96
- package/lib/cli/project-scaffolder/design-contract/sections/conceptual-anchor.mjs +0 -167
- package/lib/cli/project-scaffolder/design-contract/sections/execution-handoff.mjs +0 -211
- package/lib/cli/project-scaffolder/design-contract/seed-signals.mjs +0 -79
- package/lib/cli/project-scaffolder/design-contract/signal-vocab.mjs +0 -64
- package/lib/cli/project-scaffolder/design-contract/validation/anchor-validators.mjs +0 -294
- package/lib/cli/project-scaffolder/design-contract/validation/audit-validators.mjs +0 -117
- package/lib/cli/project-scaffolder/design-contract/validation/completeness.mjs +0 -121
- package/lib/cli/project-scaffolder/design-contract/validation/execution-validators.mjs +0 -328
- package/lib/cli/project-scaffolder/design-contract/validation/helpers.mjs +0 -8
- package/lib/cli/project-scaffolder/design-contract/validation/research-dossier-validators.mjs +0 -104
- package/lib/cli/project-scaffolder/design-contract/validation/structural-validators.mjs +0 -79
- package/lib/cli/project-scaffolder/design-contract/validation/system-validators.mjs +0 -256
- package/lib/cli/project-scaffolder/design-contract/validation.mjs +0 -74
- package/lib/cli/project-scaffolder/design-contract.mjs +0 -470
|
@@ -2,31 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import { existsSync, readFileSync } from 'node:fs';
|
|
4
4
|
import {
|
|
5
|
-
DESIGN_EXECUTION_REQUIRED_CAPABILITIES,
|
|
6
5
|
DESIGN_GUIDE_PATH,
|
|
7
|
-
DESIGN_INTENT_PATH,
|
|
8
6
|
} from './constants.mjs';
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return rawValue
|
|
16
|
-
.map((entryValue) => String(entryValue || '').trim())
|
|
17
|
-
.filter(Boolean);
|
|
18
|
-
}
|
|
19
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Legacy design-intent.json is no longer generated.
|
|
10
|
+
* Returns null unconditionally.
|
|
11
|
+
*/
|
|
20
12
|
export function loadDesignIntent() {
|
|
21
|
-
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
return JSON.parse(readFileSync(DESIGN_INTENT_PATH, 'utf8'));
|
|
27
|
-
} catch {
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
13
|
+
return null;
|
|
30
14
|
}
|
|
31
15
|
|
|
32
16
|
export function loadDesignGuide() {
|
|
@@ -37,223 +21,61 @@ export function loadDesignGuide() {
|
|
|
37
21
|
return readFileSync(DESIGN_GUIDE_PATH, 'utf8');
|
|
38
22
|
}
|
|
39
23
|
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
&& typeof designIntentContent.repoEvidence.designEvidenceSummary === 'object'
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function hasStructuredInspectionEvidence(designIntentContent) {
|
|
48
|
-
return Boolean(
|
|
49
|
-
designIntentContent?.repoEvidence?.designEvidenceSummary?.structuredInspection
|
|
50
|
-
&& typeof designIntentContent.repoEvidence.designEvidenceSummary.structuredInspection === 'object'
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function summarizeDesignExecutionHandoff(designIntentContent) {
|
|
55
|
-
const designExecutionHandoff = designIntentContent?.designExecutionHandoff
|
|
56
|
-
&& typeof designIntentContent.designExecutionHandoff === 'object'
|
|
57
|
-
? designIntentContent.designExecutionHandoff
|
|
58
|
-
: {};
|
|
59
|
-
|
|
60
|
-
const surfacePlan = Array.isArray(designExecutionHandoff.surfacePlan)
|
|
61
|
-
? designExecutionHandoff.surfacePlan
|
|
62
|
-
: [];
|
|
63
|
-
const componentGraphNodes = Array.isArray(designExecutionHandoff.componentGraph?.nodes)
|
|
64
|
-
? designExecutionHandoff.componentGraph.nodes
|
|
65
|
-
: [];
|
|
66
|
-
const componentGraphEdges = Array.isArray(designExecutionHandoff.componentGraph?.edges)
|
|
67
|
-
? designExecutionHandoff.componentGraph.edges
|
|
68
|
-
: [];
|
|
69
|
-
const interactionStateMatrix = Array.isArray(designExecutionHandoff.interactionStateMatrix)
|
|
70
|
-
? designExecutionHandoff.interactionStateMatrix
|
|
71
|
-
: [];
|
|
72
|
-
const taskFlowNarrative = normalizeStringArray(designExecutionHandoff.taskFlowNarrative);
|
|
73
|
-
const contentPriorityMap = designExecutionHandoff.contentPriorityMap
|
|
74
|
-
&& typeof designExecutionHandoff.contentPriorityMap === 'object'
|
|
75
|
-
? designExecutionHandoff.contentPriorityMap
|
|
76
|
-
: {};
|
|
77
|
-
const viewportMutationPlan = designExecutionHandoff.viewportMutationPlan
|
|
78
|
-
&& typeof designExecutionHandoff.viewportMutationPlan === 'object'
|
|
79
|
-
? designExecutionHandoff.viewportMutationPlan
|
|
80
|
-
: {};
|
|
81
|
-
|
|
82
|
-
function hasViewportMutationEntry(viewportKey) {
|
|
83
|
-
const viewportEntry = viewportMutationPlan?.[viewportKey];
|
|
84
|
-
return Boolean(
|
|
85
|
-
viewportEntry
|
|
86
|
-
&& typeof viewportEntry === 'object'
|
|
87
|
-
&& String(viewportEntry.primaryOperation || '').trim().length > 0
|
|
88
|
-
&& Array.isArray(viewportEntry.requiredSurfaceActions)
|
|
89
|
-
&& viewportEntry.requiredSurfaceActions.length > 0
|
|
90
|
-
&& Array.isArray(viewportEntry.forbiddenPatterns)
|
|
91
|
-
&& viewportEntry.forbiddenPatterns.length > 0
|
|
92
|
-
);
|
|
24
|
+
export function normalizeStringArray(rawValue) {
|
|
25
|
+
if (!Array.isArray(rawValue)) {
|
|
26
|
+
return [];
|
|
93
27
|
}
|
|
94
28
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
{ name: 'componentGraphEdges', present: componentGraphEdges.length > 0 },
|
|
99
|
-
{
|
|
100
|
-
name: 'contentPriorityMap',
|
|
101
|
-
present: ['primary', 'secondary', 'deferred'].every((bucketKey) => Array.isArray(contentPriorityMap?.[bucketKey]) && contentPriorityMap[bucketKey].length > 0),
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
name: 'viewportMutationPlan',
|
|
105
|
-
present: ['mobile', 'tablet', 'desktop'].every((viewportKey) => hasViewportMutationEntry(viewportKey)),
|
|
106
|
-
},
|
|
107
|
-
{ name: 'interactionStateMatrix', present: interactionStateMatrix.length > 0 },
|
|
108
|
-
{ name: 'taskFlowNarrative', present: taskFlowNarrative.length > 1 },
|
|
109
|
-
{ name: 'signatureMoveRationale', present: String(designExecutionHandoff.signatureMoveRationale || '').trim().length > 0 },
|
|
110
|
-
];
|
|
111
|
-
|
|
112
|
-
const presentArtifacts = artifactChecks.filter((artifactCheck) => artifactCheck.present).map((artifactCheck) => artifactCheck.name);
|
|
113
|
-
const missingArtifacts = artifactChecks.filter((artifactCheck) => !artifactCheck.present).map((artifactCheck) => artifactCheck.name);
|
|
114
|
-
const implementationGuardrails = designExecutionHandoff.implementationGuardrails
|
|
115
|
-
&& typeof designExecutionHandoff.implementationGuardrails === 'object'
|
|
116
|
-
? designExecutionHandoff.implementationGuardrails
|
|
117
|
-
: {};
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
present: Object.keys(designExecutionHandoff).length > 0,
|
|
121
|
-
version: typeof designExecutionHandoff.version === 'string' ? designExecutionHandoff.version : null,
|
|
122
|
-
handoffReady: (typeof designExecutionHandoff.version === 'string' && designExecutionHandoff.version === 'ui-handoff-v1')
|
|
123
|
-
&& missingArtifacts.length === 0
|
|
124
|
-
&& implementationGuardrails.requireBuildFromHandoff === true
|
|
125
|
-
&& implementationGuardrails.requireGapNotesBeforeFallback === true
|
|
126
|
-
&& implementationGuardrails.forbidGenericLayoutFallbackWithoutReason === true,
|
|
127
|
-
artifactCount: presentArtifacts.length,
|
|
128
|
-
presentArtifacts,
|
|
129
|
-
missingArtifacts,
|
|
130
|
-
};
|
|
29
|
+
return rawValue
|
|
30
|
+
.map((entryValue) => String(entryValue || '').trim())
|
|
31
|
+
.filter(Boolean);
|
|
131
32
|
}
|
|
132
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Simplified design execution policy summary.
|
|
36
|
+
* With the design-intent.json contract removed, this returns
|
|
37
|
+
* a minimal stub that downstream consumers (main judge, reporting)
|
|
38
|
+
* can safely consume without null checks.
|
|
39
|
+
*/
|
|
133
40
|
export function summarizeDesignExecutionPolicy(designIntentContent) {
|
|
134
|
-
const designExecutionPolicy = designIntentContent?.designExecutionPolicy
|
|
135
|
-
&& typeof designIntentContent.designExecutionPolicy === 'object'
|
|
136
|
-
? designIntentContent.designExecutionPolicy
|
|
137
|
-
: {};
|
|
138
|
-
|
|
139
|
-
const requiredCapabilities = DESIGN_EXECUTION_REQUIRED_CAPABILITIES.map((capability) => ({
|
|
140
|
-
name: capability,
|
|
141
|
-
enabled: designExecutionPolicy[capability] === true,
|
|
142
|
-
}));
|
|
143
|
-
const enabledCapabilities = requiredCapabilities
|
|
144
|
-
.filter((capability) => capability.enabled)
|
|
145
|
-
.map((capability) => capability.name);
|
|
146
|
-
const missingCapabilities = requiredCapabilities
|
|
147
|
-
.filter((capability) => !capability.enabled)
|
|
148
|
-
.map((capability) => capability.name);
|
|
149
|
-
const semanticReviewFocus = normalizeStringArray(designExecutionPolicy.semanticReviewFocus);
|
|
150
|
-
const representationStrategy = typeof designExecutionPolicy.representationStrategy === 'string'
|
|
151
|
-
? designExecutionPolicy.representationStrategy
|
|
152
|
-
: null;
|
|
153
|
-
const repoEvidenceAvailable = hasRepoEvidenceSummary(designIntentContent);
|
|
154
|
-
const structuredInspectionAvailable = hasStructuredInspectionEvidence(designIntentContent);
|
|
155
|
-
const screenshotDependencyForbidden = designExecutionPolicy.forbidScreenshotDependency === true;
|
|
156
|
-
const handoffFormatVersion = typeof designExecutionPolicy.handoffFormatVersion === 'string'
|
|
157
|
-
? designExecutionPolicy.handoffFormatVersion
|
|
158
|
-
: null;
|
|
159
|
-
const handoffSummary = summarizeDesignExecutionHandoff(designIntentContent);
|
|
160
|
-
const policyPresent = Object.keys(designExecutionPolicy).length > 0;
|
|
161
|
-
const contractReady = policyPresent
|
|
162
|
-
&& representationStrategy === 'surface-plan-v1'
|
|
163
|
-
&& handoffFormatVersion === 'ui-handoff-v1'
|
|
164
|
-
&& missingCapabilities.length === 0
|
|
165
|
-
&& semanticReviewFocus.length >= 4
|
|
166
|
-
&& screenshotDependencyForbidden
|
|
167
|
-
&& handoffSummary.handoffReady
|
|
168
|
-
&& repoEvidenceAvailable;
|
|
169
|
-
|
|
170
|
-
const notes = [];
|
|
171
|
-
if (!policyPresent) {
|
|
172
|
-
notes.push('designExecutionPolicy is missing from docs/design-intent.json.');
|
|
173
|
-
}
|
|
174
|
-
if (representationStrategy !== 'surface-plan-v1') {
|
|
175
|
-
notes.push('Structured design execution should declare representationStrategy "surface-plan-v1".');
|
|
176
|
-
}
|
|
177
|
-
if (handoffFormatVersion !== 'ui-handoff-v1') {
|
|
178
|
-
notes.push('Structured design execution should declare handoffFormatVersion "ui-handoff-v1".');
|
|
179
|
-
}
|
|
180
|
-
if (missingCapabilities.length > 0) {
|
|
181
|
-
notes.push(`Structured design execution is missing required capabilities: ${missingCapabilities.join(', ')}.`);
|
|
182
|
-
}
|
|
183
|
-
if (semanticReviewFocus.length < 4) {
|
|
184
|
-
notes.push('Structured design execution should declare semantic review focus dimensions before UI implementation review.');
|
|
185
|
-
}
|
|
186
|
-
if (!screenshotDependencyForbidden) {
|
|
187
|
-
notes.push('Structured design execution must explicitly forbid screenshot dependency as a baseline requirement.');
|
|
188
|
-
}
|
|
189
|
-
if (!handoffSummary.handoffReady) {
|
|
190
|
-
notes.push(`Structured design handoff is incomplete: ${handoffSummary.missingArtifacts.join(', ') || 'missing or invalid handoff metadata'}.`);
|
|
191
|
-
}
|
|
192
|
-
if (!repoEvidenceAvailable) {
|
|
193
|
-
notes.push('repoEvidence.designEvidenceSummary is missing or unreadable.');
|
|
194
|
-
} else if (!structuredInspectionAvailable) {
|
|
195
|
-
notes.push('repoEvidence.designEvidenceSummary.structuredInspection is missing; class and inline-style evidence will stay lower-confidence.');
|
|
196
|
-
}
|
|
197
|
-
if (notes.length === 0) {
|
|
198
|
-
notes.push('Structured design execution policy is present and ready for contract review.');
|
|
199
|
-
}
|
|
200
|
-
|
|
201
41
|
return {
|
|
202
|
-
policyPresent,
|
|
203
|
-
representationStrategy,
|
|
204
|
-
contractReady,
|
|
205
|
-
screenshotDependencyForbidden,
|
|
206
|
-
repoEvidenceAvailable,
|
|
207
|
-
structuredInspectionAvailable,
|
|
208
|
-
handoffPresent:
|
|
209
|
-
handoffVersion:
|
|
210
|
-
handoffReady:
|
|
211
|
-
handoffArtifactCount:
|
|
212
|
-
presentHandoffArtifacts:
|
|
213
|
-
missingHandoffArtifacts:
|
|
214
|
-
repoEvidenceSummaryVersion:
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
semanticReviewFocus,
|
|
221
|
-
notes,
|
|
42
|
+
policyPresent: false,
|
|
43
|
+
representationStrategy: null,
|
|
44
|
+
contractReady: false,
|
|
45
|
+
screenshotDependencyForbidden: false,
|
|
46
|
+
repoEvidenceAvailable: false,
|
|
47
|
+
structuredInspectionAvailable: false,
|
|
48
|
+
handoffPresent: false,
|
|
49
|
+
handoffVersion: null,
|
|
50
|
+
handoffReady: false,
|
|
51
|
+
handoffArtifactCount: 0,
|
|
52
|
+
presentHandoffArtifacts: [],
|
|
53
|
+
missingHandoffArtifacts: [],
|
|
54
|
+
repoEvidenceSummaryVersion: null,
|
|
55
|
+
requiredCapabilities: [],
|
|
56
|
+
enabledCapabilities: [],
|
|
57
|
+
missingCapabilities: [],
|
|
58
|
+
semanticReviewFocus: [],
|
|
59
|
+
notes: ['Design execution policy is not applicable under the compact token file architecture.'],
|
|
222
60
|
};
|
|
223
61
|
}
|
|
224
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Simplified review rubric summary.
|
|
65
|
+
* Returns a minimal stub since the JSON contract rubric system was removed.
|
|
66
|
+
*/
|
|
225
67
|
export function summarizeReviewRubric(designIntentContent) {
|
|
226
|
-
const reviewRubric = designIntentContent?.reviewRubric && typeof designIntentContent.reviewRubric === 'object'
|
|
227
|
-
? designIntentContent.reviewRubric
|
|
228
|
-
: {};
|
|
229
|
-
|
|
230
|
-
const dimensions = Array.isArray(reviewRubric.dimensions)
|
|
231
|
-
? reviewRubric.dimensions
|
|
232
|
-
.map((dimension) => ({
|
|
233
|
-
key: String(dimension?.key || '').trim(),
|
|
234
|
-
blockingByDefault: dimension?.blockingByDefault === true,
|
|
235
|
-
question: String(dimension?.question || '').trim(),
|
|
236
|
-
}))
|
|
237
|
-
.filter((dimension) => Boolean(dimension.key))
|
|
238
|
-
: [];
|
|
239
|
-
|
|
240
68
|
return {
|
|
241
|
-
version:
|
|
242
|
-
dimensions,
|
|
243
|
-
genericityAutoFail:
|
|
244
|
-
genericitySignals:
|
|
245
|
-
validBoldSignals:
|
|
246
|
-
forbiddenPatterns:
|
|
247
|
-
reportingRules:
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
: {
|
|
254
|
-
mustExplainGenericity: false,
|
|
255
|
-
mustSeparateTasteFromFailure: false,
|
|
256
|
-
contractFidelityOverridesPersonalTaste: false,
|
|
257
|
-
},
|
|
69
|
+
version: null,
|
|
70
|
+
dimensions: [],
|
|
71
|
+
genericityAutoFail: false,
|
|
72
|
+
genericitySignals: [],
|
|
73
|
+
validBoldSignals: [],
|
|
74
|
+
forbiddenPatterns: [],
|
|
75
|
+
reportingRules: {
|
|
76
|
+
mustExplainGenericity: false,
|
|
77
|
+
mustSeparateTasteFromFailure: false,
|
|
78
|
+
contractFidelityOverridesPersonalTaste: false,
|
|
79
|
+
},
|
|
258
80
|
};
|
|
259
81
|
}
|
|
@@ -6,11 +6,7 @@ export function buildSystemPrompt() {
|
|
|
6
6
|
return [
|
|
7
7
|
'You are a Principal UI/UX Design Reviewer.',
|
|
8
8
|
'Compare the changed UI code against the provided design contract.',
|
|
9
|
-
'Treat docs/
|
|
10
|
-
'Treat docs/DESIGN.md as explanatory context, not a generic style guide.',
|
|
11
|
-
'Treat designExecutionPolicy as the execution contract for how the UI must be planned, structured, and reviewed.',
|
|
12
|
-
'Treat designExecutionHandoff as the explicit bridge between design intent and implementation decisions.',
|
|
13
|
-
'Treat reviewRubric as the stable scoring frame for distinctiveness, contract fidelity, visual consistency, heuristic UX quality, and motion discipline.',
|
|
9
|
+
'Treat docs/DESIGN.md as the design contract source of truth.',
|
|
14
10
|
'Use repoEvidence.designEvidenceSummary as implementation evidence when deciding whether the diff follows the intended system.',
|
|
15
11
|
'Do not reward generic SaaS defaults or popular template patterns.',
|
|
16
12
|
'Do not penalize originality when the implementation still aligns with the contract.',
|
|
@@ -19,7 +15,7 @@ export function buildSystemPrompt() {
|
|
|
19
15
|
'Treat WCAG 2.2 AA failures as hard accessibility drift.',
|
|
20
16
|
'Treat APCA as advisory perceptual tuning only. Do not set blocking solely because APCA indicates a stronger readability adjustment when WCAG hard requirements still pass.',
|
|
21
17
|
'Check focus visibility, focus appearance, target size, keyboard access, accessible authentication, and status or dynamic state access when the diff touches those surfaces.',
|
|
22
|
-
'Check
|
|
18
|
+
'Check the optional reviewRubric.genericityAutoFail flag when structured context is present. If true and forbiddenPatterns or genericitySignals are detected in the changed UI, this audit is no longer merely advisory for that finding: set blockingRecommended to true, mark the relevant rubric dimension as blocking, and require rebuilding the drifted surface instead of polishing it.',
|
|
23
19
|
'Focus on color intent, typographic hierarchy, responsive re-layout, purposeful motion, component morphology across states, interaction behavior, and genericity drift.',
|
|
24
20
|
'If you call something generic, explain the specific genericity signal or anti-pattern that caused that judgment.',
|
|
25
21
|
'Separate taste from failure. A bold design that follows the contract must not be penalized only because it is unusual.',
|
|
@@ -38,30 +34,13 @@ export function buildUserMessage(designIntentContent, designGuideContent, diffCo
|
|
|
38
34
|
'## Changed UI Files',
|
|
39
35
|
changedUiFiles.length > 0 ? changedUiFiles.map((filePath) => `- ${filePath}`).join('\n') : '- none',
|
|
40
36
|
'',
|
|
41
|
-
'##
|
|
42
|
-
'```json',
|
|
43
|
-
JSON.stringify(designIntentContent, null, 2),
|
|
44
|
-
'```',
|
|
45
|
-
'',
|
|
46
|
-
'## Review Rubric',
|
|
47
|
-
'```json',
|
|
48
|
-
JSON.stringify(designIntentContent?.reviewRubric || null, null, 2),
|
|
49
|
-
'```',
|
|
50
|
-
'',
|
|
51
|
-
'## Structured Design Handoff',
|
|
52
|
-
'```json',
|
|
53
|
-
JSON.stringify(designIntentContent?.designExecutionHandoff || null, null, 2),
|
|
54
|
-
'```',
|
|
37
|
+
'## Design Contract',
|
|
55
38
|
'',
|
|
56
39
|
'## DESIGN.md',
|
|
57
40
|
'```md',
|
|
58
41
|
designGuideContent.trim() || '(missing DESIGN.md)',
|
|
59
42
|
'```',
|
|
60
|
-
|
|
61
|
-
'## Structured Design Execution Summary',
|
|
62
|
-
'```json',
|
|
63
|
-
JSON.stringify(designExecutionSummary, null, 2),
|
|
64
|
-
'```',
|
|
43
|
+
|
|
65
44
|
'',
|
|
66
45
|
'## UI Diff',
|
|
67
46
|
'```diff',
|
|
@@ -94,12 +94,12 @@ async function main() {
|
|
|
94
94
|
const designIntentContent = loadDesignIntent();
|
|
95
95
|
const designGuideContent = loadDesignGuide();
|
|
96
96
|
|
|
97
|
-
if (!
|
|
97
|
+
if (!designGuideContent.trim()) {
|
|
98
98
|
emitMachineReadableReport(buildReport({
|
|
99
99
|
skipped: true,
|
|
100
|
-
skipReason: 'Design
|
|
100
|
+
skipReason: 'Design guide is missing or unreadable. Skipping UI design judge.',
|
|
101
101
|
contractPresent: false,
|
|
102
|
-
notes: ['docs/
|
|
102
|
+
notes: ['docs/DESIGN.md is required for contract-aware UI judging.'],
|
|
103
103
|
}));
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
@@ -115,14 +115,15 @@ async function main() {
|
|
|
115
115
|
driftCount: 0,
|
|
116
116
|
blockingCandidateCount: 0,
|
|
117
117
|
designExecutionSignalCount: 0,
|
|
118
|
+
genericityStatus: 'unclear',
|
|
118
119
|
},
|
|
119
120
|
notes: ['UI design judge only evaluates changed UI surfaces.'],
|
|
120
121
|
}));
|
|
121
122
|
return;
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
const designExecutionSummary = summarizeDesignExecutionPolicy(designIntentContent);
|
|
125
|
-
const reviewRubricSummary = summarizeReviewRubric(designIntentContent);
|
|
125
|
+
const designExecutionSummary = summarizeDesignExecutionPolicy(designIntentContent || {});
|
|
126
|
+
const reviewRubricSummary = summarizeReviewRubric(designIntentContent || {});
|
|
126
127
|
|
|
127
128
|
const systemPrompt = buildSystemPrompt();
|
|
128
129
|
const userMessage = buildUserMessage(
|
|
@@ -193,7 +193,7 @@ export const REQUIRED_UNIVERSAL_SOP_SNIPPETS = [
|
|
|
193
193
|
'Coding flow is blocked if `docs/flow-overview.md` is missing',
|
|
194
194
|
'Coding flow is blocked if `docs/database-schema.md` is missing while the project uses persistent data',
|
|
195
195
|
'Coding flow is blocked if `docs/api-contract.md` is missing while the project exposes API or web application flows',
|
|
196
|
-
'UI implementation flow is blocked if `docs/DESIGN.md`
|
|
196
|
+
'UI implementation flow is blocked if `docs/DESIGN.md` is missing',
|
|
197
197
|
],
|
|
198
198
|
},
|
|
199
199
|
{
|
|
@@ -308,12 +308,9 @@ export const REQUIRED_UI_DESIGN_AUTOMATION_SNIPPETS = [
|
|
|
308
308
|
'Name Your Defaults',
|
|
309
309
|
'Choose an Anchor',
|
|
310
310
|
'Creative Commitments',
|
|
311
|
-
'
|
|
312
|
-
'Named Defaults to Avoid',
|
|
313
|
-
'Post-Implementation Check',
|
|
311
|
+
'Previous Directions',
|
|
314
312
|
'Redesign Protocol',
|
|
315
313
|
'research current official docs',
|
|
316
|
-
'product-specific reason',
|
|
317
314
|
],
|
|
318
315
|
},
|
|
319
316
|
{
|
|
@@ -357,83 +354,9 @@ export const REQUIRED_UI_DESIGN_AUTOMATION_SNIPPETS = [
|
|
|
357
354
|
],
|
|
358
355
|
},
|
|
359
356
|
{
|
|
360
|
-
path: 'lib/cli/project-scaffolder/
|
|
361
|
-
snippets: [
|
|
362
|
-
'
|
|
363
|
-
'seedPolicy',
|
|
364
|
-
'structure-first-scaffold',
|
|
365
|
-
'colorTruth',
|
|
366
|
-
'motionPaletteDecision',
|
|
367
|
-
'designFlexibilityPolicy',
|
|
368
|
-
'aiSafeUiAudit',
|
|
369
|
-
'aiColorAudit',
|
|
370
|
-
'motionSpatialCourageAudit',
|
|
371
|
-
'ai-color-default-palette-without-product-role-behavior',
|
|
372
|
-
'motion-or-3d-omitted-from-fear-without-fit-analysis',
|
|
373
|
-
'requireAiColorAudit',
|
|
374
|
-
'requireMotionSpatialCourageAudit',
|
|
375
|
-
'ai-safe-ui-template-look',
|
|
376
|
-
'interchangeable-product-renaming-test-fails',
|
|
377
|
-
'decorative-grid-or-glow-wallpaper-without-product-function',
|
|
378
|
-
'requireAiSafeUiAudit',
|
|
379
|
-
'forbidAutopilotPalettesWithoutEvidence',
|
|
380
|
-
'rolesAreMinimumScaffold',
|
|
381
|
-
'crossViewportAdaptation',
|
|
382
|
-
'motionSystem',
|
|
383
|
-
'densitySource',
|
|
384
|
-
'seedToneLocked',
|
|
385
|
-
'componentMorphology',
|
|
386
|
-
'seedBehaviorsRequireRefinement',
|
|
387
|
-
'accessibilityPolicy',
|
|
388
|
-
'designExecutionPolicy',
|
|
389
|
-
'separateRequiredOutcomesFromCandidateMoves',
|
|
390
|
-
'forbidCandidateMovesAsLockedRequirements',
|
|
391
|
-
'seedRefinementRequiredBeforeUiImplementation',
|
|
392
|
-
'requirePerSurfaceMutationOps',
|
|
393
|
-
'forbidUniformSiblingSurfaceTreatment',
|
|
394
|
-
'requireStructuredHandoff',
|
|
395
|
-
'handoffFormatVersion',
|
|
396
|
-
'designExecutionHandoff',
|
|
397
|
-
'seedMode',
|
|
398
|
-
'requiresTaskSpecificRefinement',
|
|
399
|
-
'representationStrategy',
|
|
400
|
-
'requireSurfacePlan',
|
|
401
|
-
'requireComponentGraph',
|
|
402
|
-
'requireViewportMutationPlan',
|
|
403
|
-
'requireInteractionStateMatrix',
|
|
404
|
-
'requireContentPriorityMap',
|
|
405
|
-
'forbidScreenshotDependency',
|
|
406
|
-
'semanticReviewFocus',
|
|
407
|
-
'primaryExperienceGoal',
|
|
408
|
-
'surfacePlan',
|
|
409
|
-
'contentPriorityMap',
|
|
410
|
-
'viewportMutationPlan',
|
|
411
|
-
'interactionStateMatrix',
|
|
412
|
-
'taskFlowNarrative',
|
|
413
|
-
'signatureMoveRationale',
|
|
414
|
-
'implementationGuardrails',
|
|
415
|
-
'expressionFlexibility',
|
|
416
|
-
'reviewRubric',
|
|
417
|
-
'genericityAutoFail',
|
|
418
|
-
'genericitySignals',
|
|
419
|
-
'validBoldSignals',
|
|
420
|
-
'mustExplainGenericity',
|
|
421
|
-
'mustSeparateTasteFromFailure',
|
|
422
|
-
'offline-prescribed-style-used-as-final-direction',
|
|
423
|
-
'unresearched-library-or-framework-choice',
|
|
424
|
-
'single-safe-typographic-family-without-role-contrast-or-rationale',
|
|
425
|
-
'modern-library-rejected-from-dependency-fear-without-tradeoff-analysis',
|
|
426
|
-
'component-library-selected-by-habit-without-product-fit',
|
|
427
|
-
'official-docs-backed-modern-library-choice',
|
|
428
|
-
'hardComplianceFloor',
|
|
429
|
-
'advisoryContrastModel',
|
|
430
|
-
'contextHygiene',
|
|
431
|
-
'repoEvidenceOverridesMemory',
|
|
432
|
-
'requireExplicitContinuityApproval',
|
|
433
|
-
'forbidCarryoverWhenUnapproved',
|
|
434
|
-
'approvedExternalConstraintUsage',
|
|
435
|
-
'requireViewportMutationRules',
|
|
436
|
-
'allowHexDerivatives',
|
|
357
|
+
path: 'lib/cli/project-scaffolder/ui-scope-detection.mjs',
|
|
358
|
+
snippets: [
|
|
359
|
+
'shouldBootstrapDesignDocument',
|
|
437
360
|
],
|
|
438
361
|
},
|
|
439
362
|
{
|
|
@@ -538,13 +461,6 @@ export const FORBIDDEN_ACTIVE_BIAS_ANCHOR_SNIPPETS = [
|
|
|
538
461
|
'ask for confirmation instead of silently choosing a stack',
|
|
539
462
|
],
|
|
540
463
|
},
|
|
541
|
-
{
|
|
542
|
-
path: 'lib/cli/project-scaffolder/design-contract.mjs',
|
|
543
|
-
snippets: [
|
|
544
|
-
'explicitly-approved-reference-systems',
|
|
545
|
-
'approvedReferenceUsage',
|
|
546
|
-
],
|
|
547
|
-
},
|
|
548
464
|
{
|
|
549
465
|
path: 'lib/cli/constants.mjs',
|
|
550
466
|
snippets: [
|
|
@@ -86,14 +86,11 @@ export async function validateRuleFiles(context) {
|
|
|
86
86
|
console.log('\nChecking rule, checklist, prompt, and state files...');
|
|
87
87
|
|
|
88
88
|
const expectedPaths = [
|
|
89
|
-
'rules/naming-conv.md',
|
|
90
89
|
'rules/architecture.md',
|
|
91
90
|
'rules/security.md',
|
|
92
91
|
'rules/performance.md',
|
|
93
92
|
'rules/error-handling.md',
|
|
94
93
|
'rules/testing.md',
|
|
95
|
-
'rules/git-workflow.md',
|
|
96
|
-
'rules/efficiency-vs-hype.md',
|
|
97
94
|
'rules/api-docs.md',
|
|
98
95
|
'rules/microservices.md',
|
|
99
96
|
'rules/event-driven.md',
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id_prefix: DEP
|
|
3
|
-
domain: efficiency-vs-hype
|
|
4
|
-
priority: medium
|
|
5
|
-
scope: all-tasks
|
|
6
|
-
applies_to: [backend, frontend, fullstack]
|
|
7
|
-
keywords: [efficiency, dependency]
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Dependency Boundary
|
|
11
|
-
|
|
12
|
-
## DEP-001: Execution Rules
|
|
13
|
-
1. ALWAYS perform Live Research / Web Search for official library docs before installation.
|
|
14
|
-
2. Choose the latest stable compatible version.
|
|
15
|
-
3. Do not blindly avoid dependencies if they solve complex domains securely (e.g., Auth, Crypto, Accessibility).
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id_prefix: GIT
|
|
3
|
-
domain: git-workflow
|
|
4
|
-
priority: medium
|
|
5
|
-
scope: all-tasks
|
|
6
|
-
applies_to: [backend, frontend, fullstack]
|
|
7
|
-
keywords: [git-workflow, git, commit, pr]
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Git Workflow Boundary
|
|
11
|
-
|
|
12
|
-
## GIT-001: Execution Rules
|
|
13
|
-
1. Enforce .gitignore standards. NEVER commit .env or secrets.
|
|
14
|
-
2. Write semantic commit messages (feat:, fix:, chore:).
|
|
15
|
-
3. Keep commits atomic and focused.
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id_prefix: NAME
|
|
3
|
-
domain: naming-conv
|
|
4
|
-
priority: medium
|
|
5
|
-
scope: all-tasks
|
|
6
|
-
applies_to:
|
|
7
|
-
- backend
|
|
8
|
-
- frontend
|
|
9
|
-
- fullstack
|
|
10
|
-
keywords:
|
|
11
|
-
- naming-conv
|
|
12
|
-
- name
|
|
13
|
-
- naming
|
|
14
|
-
- comments
|
|
15
|
-
- intent
|
|
16
|
-
- conventions
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
# Naming Boundary
|
|
20
|
-
|
|
21
|
-
Use the target language and framework conventions. Do not invent a naming style from this repo.
|
|
22
|
-
|
|
23
|
-
## NAME-001: Naming and Comment Rules
|
|
24
|
-
|
|
25
|
-
1. Prefer names that explain domain intent, user action, state, and boundary responsibility.
|
|
26
|
-
2. Reject these common LLM bad habits: vague names that hide meaning, such as `data`, `result`, `item`, `thing`, `temp`, `handle`, or `process` when a precise domain name exists.
|
|
27
|
-
3. Reject names that require reading the implementation to understand the value.
|
|
28
|
-
4. Keep file and directory naming styles consistent inside the same feature unless a framework reason requires mixed styles.
|
|
29
|
-
5. Reject booleans, units, and side-effect functions whose names hide what they represent or change.
|
|
30
|
-
6. Name collections as collections when the language convention supports it.
|
|
31
|
-
7. Name side-effect functions with an action plus the domain outcome they change.
|
|
32
|
-
8. Avoid broad function names that describe activity without domain intent.
|
|
33
|
-
9. Inline comments must explain why, not what.
|
|
34
|
-
10. Put a one-line rationale near non-obvious choices that deserve explanation, such as retry strategy, index column order, denormalized field, intentional swallow with named recovery, or magic constant tied to an external system.
|
|
35
|
-
11. Treat comments that paraphrase the code as noise.
|