@ryuenn3123/agentic-senior-core 3.0.19 → 3.0.21
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 +96 -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 +74 -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 +183 -108
- package/lib/cli/project-scaffolder/discovery.mjs +36 -82
- package/lib/cli/project-scaffolder/prompt-builders.mjs +45 -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 +22 -7
- 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 +5 -5
- package/scripts/ui-design-judge/reporting.mjs +3 -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 +75 -7
- 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
|
@@ -44,6 +44,13 @@ function hasRepoEvidenceSummary(designIntentContent) {
|
|
|
44
44
|
);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function hasStructuredInspectionEvidence(designIntentContent) {
|
|
48
|
+
return Boolean(
|
|
49
|
+
designIntentContent?.repoEvidence?.designEvidenceSummary?.structuredInspection
|
|
50
|
+
&& typeof designIntentContent.repoEvidence.designEvidenceSummary.structuredInspection === 'object'
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
47
54
|
function summarizeDesignExecutionHandoff(designIntentContent) {
|
|
48
55
|
const designExecutionHandoff = designIntentContent?.designExecutionHandoff
|
|
49
56
|
&& typeof designIntentContent.designExecutionHandoff === 'object'
|
|
@@ -72,6 +79,19 @@ function summarizeDesignExecutionHandoff(designIntentContent) {
|
|
|
72
79
|
? designExecutionHandoff.viewportMutationPlan
|
|
73
80
|
: {};
|
|
74
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
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
75
95
|
const artifactChecks = [
|
|
76
96
|
{ name: 'surfacePlan', present: surfacePlan.length > 0 },
|
|
77
97
|
{ name: 'componentGraphNodes', present: componentGraphNodes.length > 1 },
|
|
@@ -82,7 +102,7 @@ function summarizeDesignExecutionHandoff(designIntentContent) {
|
|
|
82
102
|
},
|
|
83
103
|
{
|
|
84
104
|
name: 'viewportMutationPlan',
|
|
85
|
-
present: ['mobile', 'tablet', 'desktop'].every((viewportKey) =>
|
|
105
|
+
present: ['mobile', 'tablet', 'desktop'].every((viewportKey) => hasViewportMutationEntry(viewportKey)),
|
|
86
106
|
},
|
|
87
107
|
{ name: 'interactionStateMatrix', present: interactionStateMatrix.length > 0 },
|
|
88
108
|
{ name: 'taskFlowNarrative', present: taskFlowNarrative.length > 1 },
|
|
@@ -131,6 +151,7 @@ export function summarizeDesignExecutionPolicy(designIntentContent) {
|
|
|
131
151
|
? designExecutionPolicy.representationStrategy
|
|
132
152
|
: null;
|
|
133
153
|
const repoEvidenceAvailable = hasRepoEvidenceSummary(designIntentContent);
|
|
154
|
+
const structuredInspectionAvailable = hasStructuredInspectionEvidence(designIntentContent);
|
|
134
155
|
const screenshotDependencyForbidden = designExecutionPolicy.forbidScreenshotDependency === true;
|
|
135
156
|
const handoffFormatVersion = typeof designExecutionPolicy.handoffFormatVersion === 'string'
|
|
136
157
|
? designExecutionPolicy.handoffFormatVersion
|
|
@@ -170,6 +191,8 @@ export function summarizeDesignExecutionPolicy(designIntentContent) {
|
|
|
170
191
|
}
|
|
171
192
|
if (!repoEvidenceAvailable) {
|
|
172
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.');
|
|
173
196
|
}
|
|
174
197
|
if (notes.length === 0) {
|
|
175
198
|
notes.push('Structured design execution policy is present and ready for contract review.');
|
|
@@ -181,6 +204,7 @@ export function summarizeDesignExecutionPolicy(designIntentContent) {
|
|
|
181
204
|
contractReady,
|
|
182
205
|
screenshotDependencyForbidden,
|
|
183
206
|
repoEvidenceAvailable,
|
|
207
|
+
structuredInspectionAvailable,
|
|
184
208
|
handoffPresent: handoffSummary.present,
|
|
185
209
|
handoffVersion: handoffSummary.version,
|
|
186
210
|
handoffReady: handoffSummary.handoffReady,
|
|
@@ -216,8 +240,10 @@ export function summarizeReviewRubric(designIntentContent) {
|
|
|
216
240
|
return {
|
|
217
241
|
version: typeof reviewRubric.version === 'string' ? reviewRubric.version : null,
|
|
218
242
|
dimensions,
|
|
243
|
+
genericityAutoFail: reviewRubric.genericityAutoFail === true,
|
|
219
244
|
genericitySignals: normalizeStringArray(reviewRubric.genericitySignals),
|
|
220
245
|
validBoldSignals: normalizeStringArray(reviewRubric.validBoldSignals),
|
|
246
|
+
forbiddenPatterns: normalizeStringArray(designIntentContent?.forbiddenPatterns),
|
|
221
247
|
reportingRules: reviewRubric.reportingRules && typeof reviewRubric.reportingRules === 'object'
|
|
222
248
|
? {
|
|
223
249
|
mustExplainGenericity: reviewRubric.reportingRules.mustExplainGenericity === true,
|
|
@@ -8,7 +8,7 @@ export function buildSystemPrompt() {
|
|
|
8
8
|
'Compare the changed UI code against the provided design contract.',
|
|
9
9
|
'Treat docs/design-intent.json as the machine-readable source of truth.',
|
|
10
10
|
'Treat docs/DESIGN.md as explanatory context, not a generic style guide.',
|
|
11
|
-
'Treat designExecutionPolicy as the execution contract for how the UI
|
|
11
|
+
'Treat designExecutionPolicy as the execution contract for how the UI must be planned, structured, and reviewed.',
|
|
12
12
|
'Treat designExecutionHandoff as the explicit bridge between design intent and implementation decisions.',
|
|
13
13
|
'Treat reviewRubric as the stable scoring frame for distinctiveness, contract fidelity, visual consistency, heuristic UX quality, and motion discipline.',
|
|
14
14
|
'Use repoEvidence.designEvidenceSummary as implementation evidence when deciding whether the diff follows the intended system.',
|
|
@@ -17,15 +17,15 @@ export function buildSystemPrompt() {
|
|
|
17
17
|
'Purposeful motion is allowed and can improve quality. Only flag motion when it drifts from the contract, ignores reduced-motion expectations, or adds avoidable performance/accessibility risk.',
|
|
18
18
|
'Only flag drift when there is a clear mismatch with the contract, accessibility non-negotiables, or cross-viewport adaptation rules.',
|
|
19
19
|
'Treat WCAG 2.2 AA failures as hard accessibility drift.',
|
|
20
|
-
'Treat APCA as advisory perceptual tuning only. Do not
|
|
20
|
+
'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
21
|
'Check focus visibility, focus appearance, target size, keyboard access, accessible authentication, and status or dynamic state access when the diff touches those surfaces.',
|
|
22
|
-
'
|
|
22
|
+
'Check design-intent.json for reviewRubric.genericityAutoFail. 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
23
|
'Focus on color intent, typographic hierarchy, responsive re-layout, purposeful motion, component morphology across states, interaction behavior, and genericity drift.',
|
|
24
24
|
'If you call something generic, explain the specific genericity signal or anti-pattern that caused that judgment.',
|
|
25
|
-
'Separate taste from failure. A bold design that follows the contract
|
|
25
|
+
'Separate taste from failure. A bold design that follows the contract must not be penalized only because it is unusual.',
|
|
26
26
|
'Return ONLY one JSON object on a single line prefixed with JSON_VERDICT:.',
|
|
27
27
|
'Schema:',
|
|
28
|
-
'{"alignmentScore": number|null, "genericityAssessment": {"status": "distinctive|mixed|generic|unclear", "reason": string}, "tasteVsFailureSeparated": boolean, "rubricBreakdown": [{"dimension": string, "score": number|null, "verdict": "strong|acceptable|weak|unclear", "reason": string, "blocking": boolean}], "notes": string[], "findings": [{"area": string, "severity": "high|medium|low", "problem": string, "evidence": string, "
|
|
28
|
+
'{"alignmentScore": number|null, "genericityAssessment": {"status": "distinctive|mixed|generic|unclear", "reason": string}, "tasteVsFailureSeparated": boolean, "rubricBreakdown": [{"dimension": string, "score": number|null, "verdict": "strong|acceptable|weak|unclear", "reason": string, "blocking": boolean}], "notes": string[], "findings": [{"area": string, "severity": "high|medium|low", "problem": string, "evidence": string, "requiredAction": string, "blockingRecommended": boolean}]}',
|
|
29
29
|
].join('\n');
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -49,7 +49,7 @@ export function normalizeFindings(rawFindings) {
|
|
|
49
49
|
severity: normalizeSeverity(rawFinding?.severity),
|
|
50
50
|
problem: String(rawFinding?.problem || 'No problem description provided.'),
|
|
51
51
|
evidence: String(rawFinding?.evidence || 'No evidence provided.'),
|
|
52
|
-
|
|
52
|
+
requiredAction: String(rawFinding?.requiredAction || 'No required action provided.'),
|
|
53
53
|
blockingRecommended: rawFinding?.blockingRecommended === true,
|
|
54
54
|
}));
|
|
55
55
|
}
|
|
@@ -107,6 +107,7 @@ export function buildReport(partialReport) {
|
|
|
107
107
|
mode: 'advisory',
|
|
108
108
|
advisoryOnly: true,
|
|
109
109
|
passed: true,
|
|
110
|
+
autoFailTriggered: false,
|
|
110
111
|
skipped: false,
|
|
111
112
|
skipReason: null,
|
|
112
113
|
provider: 'none',
|
|
@@ -154,6 +155,7 @@ export function buildReport(partialReport) {
|
|
|
154
155
|
statusChanged: false,
|
|
155
156
|
namedGenericityRequired: false,
|
|
156
157
|
matchedGenericitySignals: [],
|
|
158
|
+
matchedForbiddenPatterns: [],
|
|
157
159
|
matchedValidBoldSignals: [],
|
|
158
160
|
blockingFindingCount: 0,
|
|
159
161
|
contractFidelityWeak: false,
|
|
@@ -24,7 +24,7 @@ function collectEvidenceTexts({
|
|
|
24
24
|
finding?.area,
|
|
25
25
|
finding?.problem,
|
|
26
26
|
finding?.evidence,
|
|
27
|
-
finding?.
|
|
27
|
+
finding?.requiredAction,
|
|
28
28
|
])
|
|
29
29
|
: []),
|
|
30
30
|
...(Array.isArray(notes) ? notes : []),
|
|
@@ -93,6 +93,7 @@ export function calibrateGenericityAssessment({
|
|
|
93
93
|
});
|
|
94
94
|
const matchedGenericitySignals = collectMatchedSignals(reviewRubricSummary?.genericitySignals, evidenceTexts);
|
|
95
95
|
const matchedValidBoldSignals = collectMatchedSignals(reviewRubricSummary?.validBoldSignals, evidenceTexts);
|
|
96
|
+
const matchedForbiddenPatterns = collectMatchedSignals(reviewRubricSummary?.forbiddenPatterns, evidenceTexts);
|
|
96
97
|
const { blockingFindingCount, contractFidelityWeak, contractDriftDetected } = detectContractDrift(
|
|
97
98
|
rubricBreakdown,
|
|
98
99
|
findings,
|
|
@@ -106,17 +107,18 @@ export function calibrateGenericityAssessment({
|
|
|
106
107
|
namedGenericityRequired
|
|
107
108
|
&& ['generic', 'mixed'].includes(providerStatus)
|
|
108
109
|
&& matchedGenericitySignals.length === 0
|
|
110
|
+
&& matchedForbiddenPatterns.length === 0
|
|
109
111
|
) {
|
|
110
112
|
calibratedStatus = 'unclear';
|
|
111
113
|
calibrationNotes.push('Genericity claim was not backed by any named drift signal.');
|
|
112
114
|
}
|
|
113
115
|
|
|
114
|
-
if (matchedGenericitySignals.length > 0 && matchedValidBoldSignals.length === 0) {
|
|
115
|
-
calibratedStatus = contractDriftDetected || matchedGenericitySignals.length >= 2
|
|
116
|
+
if ((matchedGenericitySignals.length > 0 || matchedForbiddenPatterns.length > 0) && matchedValidBoldSignals.length === 0) {
|
|
117
|
+
calibratedStatus = contractDriftDetected || matchedGenericitySignals.length + matchedForbiddenPatterns.length >= 2
|
|
116
118
|
? 'generic'
|
|
117
119
|
: 'mixed';
|
|
118
120
|
calibrationNotes.push('Named genericity drift signals dominate the review evidence.');
|
|
119
|
-
} else if (matchedValidBoldSignals.length > 0 && matchedGenericitySignals.length === 0) {
|
|
121
|
+
} else if (matchedValidBoldSignals.length > 0 && matchedGenericitySignals.length === 0 && matchedForbiddenPatterns.length === 0) {
|
|
120
122
|
if (contractDriftDetected) {
|
|
121
123
|
calibratedStatus = 'mixed';
|
|
122
124
|
calibrationNotes.push('Authored signals are present, but contract drift prevents a distinctive verdict.');
|
|
@@ -127,7 +129,7 @@ export function calibrateGenericityAssessment({
|
|
|
127
129
|
calibratedStatus = 'mixed';
|
|
128
130
|
calibrationNotes.push('One valid bold signal was named, but evidence is not strong enough for a distinctive verdict.');
|
|
129
131
|
}
|
|
130
|
-
} else if (matchedGenericitySignals.length > 0 && matchedValidBoldSignals.length > 0) {
|
|
132
|
+
} else if ((matchedGenericitySignals.length > 0 || matchedForbiddenPatterns.length > 0) && matchedValidBoldSignals.length > 0) {
|
|
131
133
|
calibratedStatus = contractDriftDetected ? 'mixed' : 'mixed';
|
|
132
134
|
calibrationNotes.push('The evidence contains both generic drift and legitimate authored moves.');
|
|
133
135
|
} else if (providerStatus === 'distinctive' && contractDriftDetected) {
|
|
@@ -151,6 +153,7 @@ export function calibrateGenericityAssessment({
|
|
|
151
153
|
statusChanged: calibratedStatus !== providerStatus,
|
|
152
154
|
namedGenericityRequired,
|
|
153
155
|
matchedGenericitySignals,
|
|
156
|
+
matchedForbiddenPatterns,
|
|
154
157
|
matchedValidBoldSignals,
|
|
155
158
|
blockingFindingCount,
|
|
156
159
|
contractFidelityWeak,
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"severity": "high",
|
|
78
78
|
"problem": "Mobile layout no longer follows the contract.",
|
|
79
79
|
"evidence": "The primary action now drops below supporting proof.",
|
|
80
|
-
"
|
|
80
|
+
"requiredAction": "Restore the intended task order.",
|
|
81
81
|
"blockingRecommended": true
|
|
82
82
|
}
|
|
83
83
|
],
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"severity": "high",
|
|
116
116
|
"problem": "The page uses balanced card grid without priority shift.",
|
|
117
117
|
"evidence": "Every block carries equal weight and the CTA no longer leads.",
|
|
118
|
-
"
|
|
118
|
+
"requiredAction": "Rebuild the page around one dominant task surface.",
|
|
119
119
|
"blockingRecommended": true
|
|
120
120
|
}
|
|
121
121
|
],
|
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* ui-design-judge.mjs
|
|
6
6
|
*
|
|
7
|
-
* Advisory-
|
|
7
|
+
* Advisory-default UI design contract judge.
|
|
8
8
|
*
|
|
9
9
|
* Repo-internal workflow audit; no user-facing runtime modes.
|
|
10
|
-
*
|
|
10
|
+
* Stays advisory when no provider is configured or no auto-fail signal is found.
|
|
11
|
+
* reviewRubric.genericityAutoFail escalates named drift signals and forbidden
|
|
12
|
+
* patterns into blocking findings and blocking required actions when provider
|
|
13
|
+
* evidence is available.
|
|
11
14
|
*
|
|
12
15
|
* Validation anchors for repo governance:
|
|
13
16
|
* - Do not reward generic SaaS defaults or popular template patterns.
|
|
@@ -17,6 +20,7 @@
|
|
|
17
20
|
* - designExecutionPolicy
|
|
18
21
|
* - designExecutionHandoff
|
|
19
22
|
* - handoffReady
|
|
23
|
+
* - structuredInspectionAvailable
|
|
20
24
|
*/
|
|
21
25
|
|
|
22
26
|
import { collectChangedFiles, collectPullRequestDiff, isUiRelevantFilePath } from './ui-design-judge/git-input.mjs';
|
|
@@ -33,6 +37,56 @@ import {
|
|
|
33
37
|
} from './ui-design-judge/reporting.mjs';
|
|
34
38
|
import { loadDesignGuide, loadDesignIntent, summarizeDesignExecutionPolicy, summarizeReviewRubric } from './ui-design-judge/design-execution-summary.mjs';
|
|
35
39
|
|
|
40
|
+
function applyGenericityAutoFail({
|
|
41
|
+
reviewRubricSummary,
|
|
42
|
+
calibration,
|
|
43
|
+
findings,
|
|
44
|
+
notes,
|
|
45
|
+
}) {
|
|
46
|
+
const autoFailEnabled = reviewRubricSummary?.genericityAutoFail === true;
|
|
47
|
+
const namedGenericityDetected = Array.isArray(calibration?.matchedGenericitySignals)
|
|
48
|
+
&& calibration.matchedGenericitySignals.length > 0;
|
|
49
|
+
const forbiddenPatternDetected = Array.isArray(calibration?.matchedForbiddenPatterns)
|
|
50
|
+
&& calibration.matchedForbiddenPatterns.length > 0;
|
|
51
|
+
const shouldAutoFail = autoFailEnabled
|
|
52
|
+
&& calibration?.calibratedStatus === 'generic'
|
|
53
|
+
&& (namedGenericityDetected || forbiddenPatternDetected);
|
|
54
|
+
|
|
55
|
+
if (!shouldAutoFail) {
|
|
56
|
+
return {
|
|
57
|
+
findings,
|
|
58
|
+
notes,
|
|
59
|
+
autoFailTriggered: false,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const normalizedFindings = Array.isArray(findings) ? findings.map((finding) => ({ ...finding })) : [];
|
|
64
|
+
const updatedFindings = normalizedFindings.length > 0
|
|
65
|
+
? normalizedFindings.map((finding) => ({
|
|
66
|
+
...finding,
|
|
67
|
+
blockingRecommended: true,
|
|
68
|
+
}))
|
|
69
|
+
: [
|
|
70
|
+
{
|
|
71
|
+
area: 'design-contract',
|
|
72
|
+
severity: 'high',
|
|
73
|
+
problem: 'The UI matches named genericity drift signals that the contract marks as auto-fail.',
|
|
74
|
+
evidence: `Matched signals: ${[...(calibration.matchedGenericitySignals || []), ...(calibration.matchedForbiddenPatterns || [])].join(', ')}`,
|
|
75
|
+
requiredAction: 'Rebuild the affected UI surfaces from the contract and remove the named generic patterns instead of polishing them.',
|
|
76
|
+
blockingRecommended: true,
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
findings: updatedFindings,
|
|
82
|
+
notes: [
|
|
83
|
+
...(Array.isArray(notes) ? notes : []),
|
|
84
|
+
'reviewRubric.genericityAutoFail triggered because named genericity drift signals or forbidden patterns were detected.',
|
|
85
|
+
],
|
|
86
|
+
autoFailTriggered: true,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
36
90
|
async function main() {
|
|
37
91
|
const changedFiles = collectChangedFiles();
|
|
38
92
|
const changedUiFiles = changedFiles.filter(isUiRelevantFilePath);
|
|
@@ -100,6 +154,7 @@ async function main() {
|
|
|
100
154
|
driftCount: 0,
|
|
101
155
|
blockingCandidateCount: 0,
|
|
102
156
|
designExecutionSignalCount: designExecutionSummary.enabledCapabilities.length,
|
|
157
|
+
structuredInspectionAvailable: designExecutionSummary.structuredInspectionAvailable,
|
|
103
158
|
genericityStatus: calibration.calibratedStatus,
|
|
104
159
|
},
|
|
105
160
|
designExecution: designExecutionSummary,
|
|
@@ -154,6 +209,7 @@ async function main() {
|
|
|
154
209
|
driftCount: 0,
|
|
155
210
|
blockingCandidateCount: 0,
|
|
156
211
|
designExecutionSignalCount: designExecutionSummary.enabledCapabilities.length,
|
|
212
|
+
structuredInspectionAvailable: designExecutionSummary.structuredInspectionAvailable,
|
|
157
213
|
genericityStatus: calibration.calibratedStatus,
|
|
158
214
|
},
|
|
159
215
|
designExecution: designExecutionSummary,
|
|
@@ -188,7 +244,6 @@ async function main() {
|
|
|
188
244
|
const tasteVsFailureSeparated = typeof verdict?.tasteVsFailureSeparated === 'boolean'
|
|
189
245
|
? verdict.tasteVsFailureSeparated
|
|
190
246
|
: null;
|
|
191
|
-
const blockingCandidateCount = findings.filter((finding) => finding.blockingRecommended || finding.severity === 'high').length;
|
|
192
247
|
const alignmentScore = typeof verdict?.alignmentScore === 'number' ? verdict.alignmentScore : null;
|
|
193
248
|
const notes = Array.isArray(verdict?.notes)
|
|
194
249
|
? verdict.notes.map((note) => String(note))
|
|
@@ -202,18 +257,31 @@ async function main() {
|
|
|
202
257
|
notes,
|
|
203
258
|
tasteVsFailureSeparated,
|
|
204
259
|
});
|
|
260
|
+
const autoFailResolution = applyGenericityAutoFail({
|
|
261
|
+
reviewRubricSummary,
|
|
262
|
+
calibration,
|
|
263
|
+
findings,
|
|
264
|
+
notes,
|
|
265
|
+
});
|
|
266
|
+
const resolvedFindings = autoFailResolution.findings;
|
|
267
|
+
const resolvedNotes = autoFailResolution.notes;
|
|
268
|
+
const blockingCandidateCount = resolvedFindings.filter((finding) => finding.blockingRecommended || finding.severity === 'high').length;
|
|
205
269
|
|
|
206
270
|
emitMachineReadableReport(buildReport({
|
|
207
271
|
provider: selectedProvider.providerName,
|
|
208
272
|
contractPresent: true,
|
|
209
|
-
|
|
273
|
+
mode: autoFailResolution.autoFailTriggered ? 'blocking-recommended' : 'advisory',
|
|
274
|
+
advisoryOnly: !autoFailResolution.autoFailTriggered,
|
|
275
|
+
passed: !autoFailResolution.autoFailTriggered,
|
|
276
|
+
autoFailTriggered: autoFailResolution.autoFailTriggered,
|
|
210
277
|
malformedVerdict: malformed,
|
|
211
278
|
summary: {
|
|
212
279
|
changedUiFileCount: changedUiFiles.length,
|
|
213
280
|
alignmentScore,
|
|
214
|
-
driftCount:
|
|
281
|
+
driftCount: resolvedFindings.length,
|
|
215
282
|
blockingCandidateCount,
|
|
216
283
|
designExecutionSignalCount: designExecutionSummary.enabledCapabilities.length,
|
|
284
|
+
structuredInspectionAvailable: designExecutionSummary.structuredInspectionAvailable,
|
|
217
285
|
genericityStatus: calibration.calibratedStatus,
|
|
218
286
|
},
|
|
219
287
|
designExecution: designExecutionSummary,
|
|
@@ -229,10 +297,10 @@ async function main() {
|
|
|
229
297
|
skipped: false,
|
|
230
298
|
skipReason: null,
|
|
231
299
|
},
|
|
232
|
-
findings,
|
|
300
|
+
findings: resolvedFindings,
|
|
233
301
|
notes: malformed
|
|
234
302
|
? ['LLM response was malformed. Advisory mode kept the audit non-blocking.', ...designExecutionSummary.notes]
|
|
235
|
-
: [...
|
|
303
|
+
: [...resolvedNotes, ...calibration.notes, ...designExecutionSummary.notes],
|
|
236
304
|
}));
|
|
237
305
|
}
|
|
238
306
|
|