@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.
Files changed (77) hide show
  1. package/.agent-context/prompts/bootstrap-design.md +96 -103
  2. package/.agent-context/prompts/init-project.md +32 -100
  3. package/.agent-context/prompts/refactor.md +22 -44
  4. package/.agent-context/prompts/review-code.md +28 -52
  5. package/.agent-context/review-checklists/architecture-review.md +31 -62
  6. package/.agent-context/review-checklists/pr-checklist.md +74 -108
  7. package/.agent-context/rules/api-docs.md +18 -206
  8. package/.agent-context/rules/architecture.md +40 -207
  9. package/.agent-context/rules/database-design.md +10 -199
  10. package/.agent-context/rules/docker-runtime.md +5 -5
  11. package/.agent-context/rules/efficiency-vs-hype.md +11 -149
  12. package/.agent-context/rules/error-handling.md +9 -231
  13. package/.agent-context/rules/event-driven.md +17 -221
  14. package/.agent-context/rules/frontend-architecture.md +74 -119
  15. package/.agent-context/rules/git-workflow.md +1 -1
  16. package/.agent-context/rules/microservices.md +28 -161
  17. package/.agent-context/rules/naming-conv.md +8 -138
  18. package/.agent-context/rules/performance.md +9 -175
  19. package/.agent-context/rules/realtime.md +11 -44
  20. package/.agent-context/rules/security.md +11 -295
  21. package/.agent-context/rules/testing.md +9 -174
  22. package/.agent-context/state/benchmark-analysis.json +3 -3
  23. package/.agent-context/state/memory-continuity-benchmark.json +1 -1
  24. package/.agent-context/state/onboarding-report.json +71 -11
  25. package/.agents/workflows/init-project.md +7 -24
  26. package/.agents/workflows/refactor.md +7 -24
  27. package/.agents/workflows/review-code.md +7 -24
  28. package/.cursorrules +22 -21
  29. package/.gemini/instructions.md +2 -2
  30. package/.github/copilot-instructions.md +2 -2
  31. package/.instructions.md +112 -213
  32. package/.windsurfrules +22 -21
  33. package/AGENTS.md +4 -4
  34. package/CONTRIBUTING.md +13 -22
  35. package/README.md +6 -20
  36. package/lib/cli/commands/init.mjs +102 -148
  37. package/lib/cli/commands/launch.mjs +3 -3
  38. package/lib/cli/commands/optimize.mjs +14 -4
  39. package/lib/cli/commands/upgrade.mjs +25 -23
  40. package/lib/cli/compiler.mjs +96 -62
  41. package/lib/cli/constants.mjs +28 -136
  42. package/lib/cli/detector/design-evidence.mjs +189 -6
  43. package/lib/cli/detector.mjs +6 -7
  44. package/lib/cli/init-detection-flow.mjs +10 -93
  45. package/lib/cli/init-selection.mjs +2 -68
  46. package/lib/cli/project-scaffolder/constants.mjs +1 -1
  47. package/lib/cli/project-scaffolder/design-contract.mjs +183 -108
  48. package/lib/cli/project-scaffolder/discovery.mjs +36 -82
  49. package/lib/cli/project-scaffolder/prompt-builders.mjs +45 -55
  50. package/lib/cli/project-scaffolder/storage.mjs +0 -2
  51. package/lib/cli/token-optimization.mjs +1 -1
  52. package/lib/cli/utils.mjs +75 -9
  53. package/package.json +2 -2
  54. package/scripts/detection-benchmark.mjs +4 -15
  55. package/scripts/documentation-boundary-audit.mjs +9 -9
  56. package/scripts/explain-on-demand-audit.mjs +11 -11
  57. package/scripts/forbidden-content-check.mjs +9 -9
  58. package/scripts/frontend-usability-audit.mjs +45 -35
  59. package/scripts/llm-judge.mjs +1 -1
  60. package/scripts/mcp-server/constants.mjs +2 -2
  61. package/scripts/mcp-server/tool-registry.mjs +1 -1
  62. package/scripts/release-gate/audit-checks.mjs +22 -7
  63. package/scripts/release-gate/static-checks.mjs +5 -5
  64. package/scripts/release-gate.mjs +1 -1
  65. package/scripts/rules-guardian-audit.mjs +14 -13
  66. package/scripts/single-source-lazy-loading-audit.mjs +3 -3
  67. package/scripts/sync-thin-adapters.mjs +5 -5
  68. package/scripts/ui-design-judge/design-execution-summary.mjs +27 -1
  69. package/scripts/ui-design-judge/prompting.mjs +5 -5
  70. package/scripts/ui-design-judge/reporting.mjs +3 -1
  71. package/scripts/ui-design-judge/rubric-calibration.mjs +8 -5
  72. package/scripts/ui-design-judge/rubric-goldset.json +2 -2
  73. package/scripts/ui-design-judge.mjs +75 -7
  74. package/scripts/validate/config.mjs +138 -48
  75. package/scripts/validate/coverage-checks.mjs +32 -7
  76. package/scripts/validate.mjs +8 -4
  77. 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) => String(viewportMutationPlan?.[viewportKey] || '').trim().length > 0),
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 should be planned, structured, and reviewed.',
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 recommend blocking solely because APCA would prefer a stronger readability adjustment when WCAG hard requirements still pass.',
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
- 'This audit always runs in advisory mode for this repository workflow.',
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 should not be penalized only because it is unusual.',
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, "recommendation": string, "blockingRecommended": boolean}]}',
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
- recommendation: String(rawFinding?.recommendation || 'No recommendation provided.'),
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?.recommendation,
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
- "recommendation": "Restore the intended task order.",
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
- "recommendation": "Rebuild the page around one dominant task surface.",
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-first UI design contract judge.
7
+ * Advisory-default UI design contract judge.
8
8
  *
9
9
  * Repo-internal workflow audit; no user-facing runtime modes.
10
- * Runs only in advisory mode for this repository workflow.
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
- passed: true,
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: findings.length,
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
- : [...notes, ...calibration.notes, ...designExecutionSummary.notes],
303
+ : [...resolvedNotes, ...calibration.notes, ...designExecutionSummary.notes],
236
304
  }));
237
305
  }
238
306