@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
|
@@ -29,7 +29,7 @@ const BOUNDARY_RULES = [
|
|
|
29
29
|
{
|
|
30
30
|
boundaryName: 'public-surface',
|
|
31
31
|
requirement: 'Public surface changes must update README.md, CHANGELOG.md, or docs/* in the same scope.',
|
|
32
|
-
|
|
32
|
+
requiredDocumentationUpdates: [
|
|
33
33
|
'README.md',
|
|
34
34
|
'CHANGELOG.md',
|
|
35
35
|
'docs/architecture-decision-record.md',
|
|
@@ -45,7 +45,7 @@ const BOUNDARY_RULES = [
|
|
|
45
45
|
{
|
|
46
46
|
boundaryName: 'api-contract',
|
|
47
47
|
requirement: 'API endpoint or contract changes must update API/OpenAPI documentation in the same scope.',
|
|
48
|
-
|
|
48
|
+
requiredDocumentationUpdates: [
|
|
49
49
|
'docs/api-contract.md',
|
|
50
50
|
'docs/flow-overview.md',
|
|
51
51
|
'.agent-context/rules/api-docs.md',
|
|
@@ -67,7 +67,7 @@ const BOUNDARY_RULES = [
|
|
|
67
67
|
{
|
|
68
68
|
boundaryName: 'database-structure',
|
|
69
69
|
requirement: 'Database structure changes must update schema or migration documentation in the same scope.',
|
|
70
|
-
|
|
70
|
+
requiredDocumentationUpdates: [
|
|
71
71
|
'docs/database-schema.md',
|
|
72
72
|
'docs/flow-overview.md',
|
|
73
73
|
'.agent-context/rules/database-design.md',
|
|
@@ -163,8 +163,8 @@ function isDocumentationFilePath(filePath) {
|
|
|
163
163
|
|
|
164
164
|
function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles) {
|
|
165
165
|
const boundaryChangedFiles = changedFiles.filter((filePath) => boundaryRule.trigger(filePath));
|
|
166
|
-
const expectedDocumentationPaths = Array.isArray(boundaryRule.
|
|
167
|
-
? boundaryRule.
|
|
166
|
+
const expectedDocumentationPaths = Array.isArray(boundaryRule.requiredDocumentationUpdates)
|
|
167
|
+
? boundaryRule.requiredDocumentationUpdates
|
|
168
168
|
: [];
|
|
169
169
|
|
|
170
170
|
if (boundaryChangedFiles.length === 0) {
|
|
@@ -177,14 +177,14 @@ function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles)
|
|
|
177
177
|
documentationFiles: [],
|
|
178
178
|
expectedDocumentationPaths,
|
|
179
179
|
missingDocumentationUpdates: false,
|
|
180
|
-
|
|
180
|
+
requiredActions: [],
|
|
181
181
|
details: 'Boundary not triggered by changed scope.',
|
|
182
182
|
};
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
const matchingDocumentationFiles = changedDocumentationFiles.filter((filePath) => boundaryRule.docsMatcher(filePath));
|
|
186
186
|
const boundaryPassed = matchingDocumentationFiles.length > 0;
|
|
187
|
-
const
|
|
187
|
+
const requiredActions = boundaryPassed
|
|
188
188
|
? []
|
|
189
189
|
: [
|
|
190
190
|
`Update one or more boundary docs: ${expectedDocumentationPaths.join(', ')}`,
|
|
@@ -204,7 +204,7 @@ function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles)
|
|
|
204
204
|
documentationFiles: matchingDocumentationFiles,
|
|
205
205
|
expectedDocumentationPaths,
|
|
206
206
|
missingDocumentationUpdates: !boundaryPassed,
|
|
207
|
-
|
|
207
|
+
requiredActions,
|
|
208
208
|
details,
|
|
209
209
|
};
|
|
210
210
|
}
|
|
@@ -225,7 +225,7 @@ function runDocumentationBoundaryAudit() {
|
|
|
225
225
|
requirement: boundaryResult.requirement,
|
|
226
226
|
changedFiles: boundaryResult.changedFiles,
|
|
227
227
|
expectedDocumentationPaths: boundaryResult.expectedDocumentationPaths,
|
|
228
|
-
|
|
228
|
+
requiredActions: boundaryResult.requiredActions,
|
|
229
229
|
diagnosticCode: `BOUNDARY_${boundaryResult.boundaryName.toUpperCase().replace(/-/g, '_')}_DOCS_SYNC_REQUIRED`,
|
|
230
230
|
}));
|
|
231
231
|
|
|
@@ -39,7 +39,7 @@ const REQUIRED_PR_CHECKLIST_SNIPPETS = [
|
|
|
39
39
|
];
|
|
40
40
|
|
|
41
41
|
const REQUIRED_REVIEW_PROMPT_SNIPPETS = [
|
|
42
|
-
'
|
|
42
|
+
'Review the code with a production-risk mindset.',
|
|
43
43
|
];
|
|
44
44
|
|
|
45
45
|
const INTERNAL_STATE_SIGNAL_PATTERNS = [
|
|
@@ -225,11 +225,11 @@ function assertSnippetCoverage(sourceLabel, sourcePath, requiredSnippets, failur
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
function buildDefaultResponseSummary(onboardingReport) {
|
|
228
|
-
const
|
|
229
|
-
const
|
|
228
|
+
const runtimeDecision = String(onboardingReport?.runtimeDecision?.mode || onboardingReport?.selectedStack || 'unknown-runtime-decision').trim() || 'unknown-runtime-decision';
|
|
229
|
+
const architectureDecision = String(onboardingReport?.architectureDecision?.mode || onboardingReport?.selectedBlueprint || 'unknown-architecture-decision').trim() || 'unknown-architecture-decision';
|
|
230
230
|
const selectedProfile = String(onboardingReport?.selectedProfile || 'unknown-profile').trim() || 'unknown-profile';
|
|
231
231
|
|
|
232
|
-
return `Active setup summary:
|
|
232
|
+
return `Active setup summary: runtimeDecision=${runtimeDecision}, architectureDecision=${architectureDecision}, profile=${selectedProfile}.`;
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
function detectInternalSignals(textValue) {
|
|
@@ -240,14 +240,14 @@ function detectInternalSignals(textValue) {
|
|
|
240
240
|
function buildDiagnosticDecisionSummaries(onboardingReport) {
|
|
241
241
|
const explanations = [];
|
|
242
242
|
|
|
243
|
-
const
|
|
244
|
-
if (
|
|
245
|
-
explanations.push(`
|
|
243
|
+
const runtimeDecision = String(onboardingReport?.runtimeDecision?.mode || onboardingReport?.selectedStack || '').trim();
|
|
244
|
+
if (runtimeDecision) {
|
|
245
|
+
explanations.push(`Runtime decision: ${runtimeDecision}.`);
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
const
|
|
249
|
-
if (
|
|
250
|
-
explanations.push(`
|
|
248
|
+
const architectureDecision = String(onboardingReport?.architectureDecision?.mode || onboardingReport?.selectedBlueprint || '').trim();
|
|
249
|
+
if (architectureDecision) {
|
|
250
|
+
explanations.push(`Architecture decision: ${architectureDecision}.`);
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
const selectedProfile = String(onboardingReport?.selectedProfile || '').trim();
|
|
@@ -423,4 +423,4 @@ function runAudit() {
|
|
|
423
423
|
process.exit(reportPayload.passed ? 0 : 1);
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
-
runAudit();
|
|
426
|
+
runAudit();
|
|
@@ -15,22 +15,22 @@ const FORBIDDEN_PATTERNS = [
|
|
|
15
15
|
{
|
|
16
16
|
name: 'Hardcoded API Key',
|
|
17
17
|
regex: /api_?key\s*[:=]\s*['"][a-zA-Z0-9_\-]{16,}['"]/i,
|
|
18
|
-
|
|
18
|
+
requiredAction: 'API Keys must be provided via environment variables (process.env) or config files, never hardcoded.'
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
name: 'Hardcoded Password',
|
|
22
22
|
regex: /password\s*[:=]\s*['"][^'"]+['"]/i,
|
|
23
|
-
|
|
23
|
+
requiredAction: 'Passwords must be injected via secret managers or environment variables.'
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
name: 'Absolute Local Desktop Path',
|
|
27
27
|
regex: /file:\/\/\/?([c-zC-Z]:|\/Users\/|\/home\/)/,
|
|
28
|
-
|
|
28
|
+
requiredAction: 'Do not commit local absolute file paths. Use relative paths or process.cwd().'
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
name: 'Stray Breakpoint (debugger)',
|
|
32
32
|
regex: /\bdebugger\s*;?/,
|
|
33
|
-
|
|
33
|
+
requiredAction: 'Remove debug breakpoints before publishing to production.'
|
|
34
34
|
}
|
|
35
35
|
];
|
|
36
36
|
|
|
@@ -48,7 +48,7 @@ function scanFile(filePath) {
|
|
|
48
48
|
line: i + 1,
|
|
49
49
|
content: line.trim().substring(0, 80), // truncate long lines
|
|
50
50
|
rule: pattern.name,
|
|
51
|
-
|
|
51
|
+
requiredAction: pattern.requiredAction
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -97,12 +97,12 @@ async function runCheck() {
|
|
|
97
97
|
|
|
98
98
|
if (violations.length > 0) {
|
|
99
99
|
const relPath = relative(ROOT_DIR, file);
|
|
100
|
-
console.error(`\
|
|
100
|
+
console.error(`\nFORBIDDEN CONTENT DETECTED IN: ${relPath}`);
|
|
101
101
|
|
|
102
102
|
for (const v of violations) {
|
|
103
103
|
console.error(` Line ${v.line}: [${v.rule}]`);
|
|
104
104
|
console.error(` > ${v.content}`);
|
|
105
|
-
console.error(` Action required: ${v.
|
|
105
|
+
console.error(` Action required: ${v.requiredAction}`);
|
|
106
106
|
totalViolations++;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
@@ -112,10 +112,10 @@ async function runCheck() {
|
|
|
112
112
|
console.log(`\nScanned ${filesScanned.length} files across ${SCAN_DIRECTORIES.length} source directories.`);
|
|
113
113
|
|
|
114
114
|
if (totalViolations > 0) {
|
|
115
|
-
console.error(`\
|
|
115
|
+
console.error(`\nPUBLISH ABORTED: Found ${totalViolations} forbidden content violation(s).`);
|
|
116
116
|
process.exit(1);
|
|
117
117
|
} else {
|
|
118
|
-
console.log('
|
|
118
|
+
console.log('Clean. No forbidden content detected.');
|
|
119
119
|
process.exit(0);
|
|
120
120
|
}
|
|
121
121
|
}
|
|
@@ -53,49 +53,52 @@ const REQUIRED_ARCHITECTURE_CHECKLIST_SNIPPETS = [
|
|
|
53
53
|
];
|
|
54
54
|
|
|
55
55
|
const REQUIRED_FRONTEND_RULE_SNIPPETS = [
|
|
56
|
-
'Frontend
|
|
57
|
-
'UI
|
|
58
|
-
'
|
|
59
|
-
'
|
|
60
|
-
'
|
|
61
|
-
'
|
|
56
|
+
'Frontend Design and Interaction Boundaries',
|
|
57
|
+
'UI work must load the smallest relevant surface, not the entire engineering handbook.',
|
|
58
|
+
'## Auto Activation',
|
|
59
|
+
'UI scope triggers:',
|
|
60
|
+
'Do not use this file to teach generic frontend basics the model already knows.',
|
|
61
|
+
'## Source Hygiene and Source Boundaries',
|
|
62
|
+
'This rule guides the LLM; it must not choose the final style',
|
|
62
63
|
'Design continuity is opt-in.',
|
|
63
|
-
'
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
67
|
-
'
|
|
68
|
-
'
|
|
69
|
-
'
|
|
70
|
-
'
|
|
71
|
-
'Responsive
|
|
64
|
+
'Repo evidence outranks memory residue every time.',
|
|
65
|
+
'## Accessibility Split',
|
|
66
|
+
'Treat WCAG 2.2 AA as the hard compliance floor.',
|
|
67
|
+
'Treat APCA as advisory perceptual tuning only.',
|
|
68
|
+
'## Anti-Generic UI Boundaries',
|
|
69
|
+
'Do not default to interchangeable dashboard chrome',
|
|
70
|
+
'Do not let repeated surfaces share the same visual treatment by habit.',
|
|
71
|
+
'Do not use default framework button and input treatment as the final UI language.',
|
|
72
|
+
'## Responsive Mutation Requirements',
|
|
73
|
+
'Responsive quality is not allowed to be scale-only.',
|
|
74
|
+
'## Surface and Morphology Requirements',
|
|
75
|
+
'Define the primary user task or reading path from current evidence',
|
|
76
|
+
'## Implementation Boundaries',
|
|
77
|
+
'Do not hardcode Zustand, React Query, smart/dumb component doctrine',
|
|
72
78
|
];
|
|
73
79
|
|
|
74
80
|
const REQUIRED_BOOTSTRAP_DESIGN_SNIPPETS = [
|
|
75
|
-
'
|
|
76
|
-
'
|
|
81
|
+
'This contract is a decision scaffold, not a style preset.',
|
|
82
|
+
'We guide the agent; we do not pick the final style',
|
|
83
|
+
'Responsive Recomposition Plan',
|
|
77
84
|
'Token Architecture and Alias Strategy',
|
|
78
|
-
'
|
|
79
|
-
'
|
|
80
|
-
'
|
|
81
|
-
'
|
|
82
|
-
'
|
|
83
|
-
'
|
|
84
|
-
'
|
|
85
|
-
'
|
|
86
|
-
'
|
|
87
|
-
'
|
|
88
|
-
'Design continuity is opt-in.',
|
|
89
|
-
'WCAG 2.2 AA as the blocking baseline',
|
|
90
|
-
'APCA only as advisory perceptual tuning',
|
|
91
|
-
'Structured design execution must stay representation-first',
|
|
92
|
-
'structured handoff',
|
|
85
|
+
'repoEvidence.designEvidenceSummary',
|
|
86
|
+
'research current official docs',
|
|
87
|
+
'Responsive design means recomposition, not resizing.',
|
|
88
|
+
'agent-chosen visual direction',
|
|
89
|
+
'viewport mutation rules',
|
|
90
|
+
'WCAG 2.2 AA is the hard floor',
|
|
91
|
+
'APCA may be used only as advisory perceptual tuning',
|
|
92
|
+
'unresearched dependency choices',
|
|
93
|
+
'default component-kit styling without product rationale',
|
|
94
|
+
'genericity findings that cannot name the exact drift signal',
|
|
93
95
|
];
|
|
94
96
|
|
|
95
97
|
const REQUIRED_UI_DESIGN_JUDGE_SNIPPETS = [
|
|
96
|
-
'Advisory-
|
|
98
|
+
'Advisory-default UI design contract judge.',
|
|
97
99
|
'Repo-internal workflow audit; no user-facing runtime modes.',
|
|
98
|
-
'
|
|
100
|
+
'genericityAutoFail',
|
|
101
|
+
'blocking required actions',
|
|
99
102
|
'Do not reward generic SaaS defaults or popular template patterns.',
|
|
100
103
|
'UI design judge only evaluates changed UI surfaces.',
|
|
101
104
|
'Structured design execution summary was supplied to semantic review.',
|
|
@@ -106,15 +109,18 @@ const REQUIRED_UI_DESIGN_JUDGE_SNIPPETS = [
|
|
|
106
109
|
'genericityStatus',
|
|
107
110
|
'handoffReady',
|
|
108
111
|
'calibratedStatus',
|
|
112
|
+
'structuredInspectionAvailable',
|
|
113
|
+
'applyGenericityAutoFail',
|
|
109
114
|
];
|
|
110
115
|
|
|
111
116
|
const REQUIRED_INSTRUCTIONS_SNIPPETS = [
|
|
112
117
|
'UI Design Mode',
|
|
118
|
+
'Resolve the smallest relevant layer set for the current request.',
|
|
113
119
|
'bootstrap-design.md',
|
|
114
120
|
'frontend-architecture.md',
|
|
115
121
|
'do not eagerly load unrelated backend-only rules',
|
|
116
122
|
'valid style context',
|
|
117
|
-
'
|
|
123
|
+
'External references, prior-chat memory, unrelated-project visuals, and remembered screenshots are tainted',
|
|
118
124
|
'WCAG 2.2 AA as the hard compliance floor',
|
|
119
125
|
'APCA as advisory perceptual tuning only',
|
|
120
126
|
'Do not require screenshot capture as a baseline dependency',
|
|
@@ -125,6 +131,9 @@ const REQUIRED_DESIGN_EVIDENCE_SNIPPETS = [
|
|
|
125
131
|
"source: 'lightweight-static-scan'",
|
|
126
132
|
'cssVariables',
|
|
127
133
|
'componentInventory',
|
|
134
|
+
'structuredInspection',
|
|
135
|
+
'classAttributeCount',
|
|
136
|
+
'inlineStyleObjectCount',
|
|
128
137
|
'tokenBypassSignals',
|
|
129
138
|
];
|
|
130
139
|
|
|
@@ -254,6 +263,7 @@ function runAudit() {
|
|
|
254
263
|
extractorIncludesSummaryVersion: designEvidenceExtractorContent.includes('summaryVersion'),
|
|
255
264
|
extractorIncludesCssVariables: designEvidenceExtractorContent.includes('cssVariables'),
|
|
256
265
|
extractorIncludesComponentInventory: designEvidenceExtractorContent.includes('componentInventory'),
|
|
266
|
+
extractorIncludesStructuredInspection: designEvidenceExtractorContent.includes('structuredInspection'),
|
|
257
267
|
extractorIncludesTokenBypassSignals: designEvidenceExtractorContent.includes('tokenBypassSignals'),
|
|
258
268
|
compilerProjectsFrontendEvidenceMetrics: compilerContent.includes('frontendEvidenceMetrics'),
|
|
259
269
|
compilerProjectsDesignEvidenceSummary: compilerContent.includes('designEvidenceSummary'),
|
package/scripts/llm-judge.mjs
CHANGED
|
@@ -242,7 +242,7 @@ You must categorize each violation with a severity level: critical, high, medium
|
|
|
242
242
|
- critical: Security vulnerabilities (hardcoded secrets, SQL/command injection, missing auth checks, CORS), unvalidated external inputs.
|
|
243
243
|
- high: N+1 database queries, swallowed errors (empty catch blocks without re-throw/recovery), layer boundary violations.
|
|
244
244
|
- medium: TypeScript \`any\` type used without justification, missing test coverage, bad architectural patterns.
|
|
245
|
-
- low: Style preferences, minor naming nitpicks, documentation
|
|
245
|
+
- low: Style preferences, minor naming nitpicks, documentation nitpicks, performance micro-optimizations.
|
|
246
246
|
|
|
247
247
|
## Mandatory output format:
|
|
248
248
|
You MUST output your findings in EXACTLY this structure:
|
|
@@ -33,9 +33,9 @@ function resolvePackageVersion() {
|
|
|
33
33
|
export const PACKAGE_VERSION = resolvePackageVersion();
|
|
34
34
|
|
|
35
35
|
export const TEST_SUITE_ARGS = {
|
|
36
|
-
full: ['--test', './tests/cli-smoke.test.mjs', './tests/mcp-server.test.mjs', './tests/llm-judge.test.mjs', './tests/
|
|
36
|
+
full: ['--test', './tests/cli-smoke.test.mjs', './tests/mcp-server.test.mjs', './tests/llm-judge.test.mjs', './tests/operations.test.mjs'],
|
|
37
37
|
cli: ['--test', './tests/cli-smoke.test.mjs'],
|
|
38
|
-
|
|
38
|
+
operations: ['--test', './tests/operations.test.mjs'],
|
|
39
39
|
'llm-judge': ['--test', './tests/llm-judge.test.mjs'],
|
|
40
40
|
};
|
|
41
41
|
|
|
@@ -112,7 +112,7 @@ export function buildToolDefinitions() {
|
|
|
112
112
|
properties: {
|
|
113
113
|
path: {
|
|
114
114
|
type: 'string',
|
|
115
|
-
description: 'Path relative to .agent-context/state
|
|
115
|
+
description: 'Path relative to .agent-context/state, such as memory-continuity-benchmark.json.',
|
|
116
116
|
},
|
|
117
117
|
},
|
|
118
118
|
required: ['path'],
|
|
@@ -39,7 +39,7 @@ export function runAuditReleaseChecks(results, diagnostics) {
|
|
|
39
39
|
typeof boundaryResult?.boundaryName === 'string'
|
|
40
40
|
&& typeof boundaryResult?.requirement === 'string'
|
|
41
41
|
&& Array.isArray(boundaryResult?.expectedDocumentationPaths)
|
|
42
|
-
&& Array.isArray(boundaryResult?.
|
|
42
|
+
&& Array.isArray(boundaryResult?.requiredActions)
|
|
43
43
|
));
|
|
44
44
|
|
|
45
45
|
if (hasMachineReadableBoundaryDiagnostics) {
|
|
@@ -117,10 +117,10 @@ export function runAuditReleaseChecks(results, diagnostics) {
|
|
|
117
117
|
const changedFiles = Array.isArray(violation?.changedFiles) && violation.changedFiles.length > 0
|
|
118
118
|
? violation.changedFiles.join(', ')
|
|
119
119
|
: 'unknown-changed-files';
|
|
120
|
-
const
|
|
121
|
-
? violation.
|
|
120
|
+
const requiredAction = Array.isArray(violation?.requiredActions) && violation.requiredActions.length > 0
|
|
121
|
+
? violation.requiredActions[0]
|
|
122
122
|
: 'Update matching boundary documentation in the same scope.';
|
|
123
|
-
return `${failureCode} (${violation?.boundaryName || 'unknown-boundary'}): ${changedFiles}. Action: ${
|
|
123
|
+
return `${failureCode} (${violation?.boundaryName || 'unknown-boundary'}): ${changedFiles}. Action: ${requiredAction}`;
|
|
124
124
|
})
|
|
125
125
|
: Array.isArray(documentationBoundaryAuditExecution.report.failures)
|
|
126
126
|
? documentationBoundaryAuditExecution.report.failures
|
|
@@ -66,7 +66,7 @@ export function runStaticReleaseChecks(results, diagnostics) {
|
|
|
66
66
|
pushResult(results, true, 'roadmap-v18', 'Roadmap includes V1.8 release track');
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
const
|
|
69
|
+
const requiredOperationsFiles = [
|
|
70
70
|
'.agent-context/review-checklists/architecture-review.md',
|
|
71
71
|
'docs/v1.8-operations-playbook.md',
|
|
72
72
|
'.github/workflows/release-gate.yml',
|
|
@@ -75,14 +75,14 @@ export function runStaticReleaseChecks(results, diagnostics) {
|
|
|
75
75
|
'scripts/governance-weekly-report.mjs',
|
|
76
76
|
];
|
|
77
77
|
|
|
78
|
-
for (const
|
|
79
|
-
const absoluteRequiredPath = resolve(REPOSITORY_ROOT,
|
|
78
|
+
for (const requiredOperationsFile of requiredOperationsFiles) {
|
|
79
|
+
const absoluteRequiredPath = resolve(REPOSITORY_ROOT, requiredOperationsFile);
|
|
80
80
|
if (!existsSync(absoluteRequiredPath)) {
|
|
81
|
-
pushResult(results, false, 'required-
|
|
81
|
+
pushResult(results, false, 'required-operations-file', `Missing ${requiredOperationsFile}`);
|
|
82
82
|
continue;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
pushResult(results, true, 'required-
|
|
85
|
+
pushResult(results, true, 'required-operations-file', `${requiredOperationsFile} is present`);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
pushResult(
|
package/scripts/release-gate.mjs
CHANGED
|
@@ -36,15 +36,15 @@ const SUPPORTED_WORKFLOWS = new Set([
|
|
|
36
36
|
const CORE_PATTERN_SIGNALS = [
|
|
37
37
|
{
|
|
38
38
|
pattern: 'layer-separation',
|
|
39
|
-
snippet: '
|
|
39
|
+
snippet: '## Layer Boundaries (Mandatory)',
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
|
-
pattern: '
|
|
43
|
-
snippet: '
|
|
42
|
+
pattern: 'agent-decides-topology',
|
|
43
|
+
snippet: 'Do not force a default architecture label before the repo, delivery model, and boundary evidence are clear.',
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
pattern: 'feature-based-grouping',
|
|
47
|
-
snippet: '
|
|
47
|
+
snippet: 'Group code by feature or domain',
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
pattern: 'rules-as-guardian-cross-session',
|
|
@@ -55,7 +55,7 @@ const CORE_PATTERN_SIGNALS = [
|
|
|
55
55
|
const REQUIRED_ARCHITECTURE_RULE_SNIPPETS = [
|
|
56
56
|
'## Rules as Guardian (Cross-Session Consistency)',
|
|
57
57
|
'Session handoff must include active architecture contract summary.',
|
|
58
|
-
'Detect drift before changing
|
|
58
|
+
'Detect drift before changing runtime choices, topology, public contracts, or core patterns.',
|
|
59
59
|
'Direction changes require explicit user confirmation before applying changes.',
|
|
60
60
|
];
|
|
61
61
|
|
|
@@ -66,7 +66,8 @@ const REQUIRED_PR_CHECKLIST_SNIPPETS = [
|
|
|
66
66
|
];
|
|
67
67
|
|
|
68
68
|
const REQUIRED_REVIEW_PROMPT_SNIPPETS = [
|
|
69
|
-
'
|
|
69
|
+
'Review the code with a production-risk mindset.',
|
|
70
|
+
'Do not invent stack-specific concerns unless the repo or changed files prove they apply.',
|
|
70
71
|
];
|
|
71
72
|
|
|
72
73
|
function pushResult(results, isPassed, checkName, details) {
|
|
@@ -295,8 +296,8 @@ function parseBooleanFromEnvironment(rawEnvironmentValue) {
|
|
|
295
296
|
|
|
296
297
|
function buildArchitectureContract(onboardingReport, corePatterns) {
|
|
297
298
|
return {
|
|
298
|
-
|
|
299
|
-
|
|
299
|
+
runtimeDecision: String(onboardingReport?.runtimeDecision?.mode || onboardingReport?.selectedStack || 'unknown').trim() || 'unknown',
|
|
300
|
+
architectureDecision: String(onboardingReport?.architectureDecision?.mode || onboardingReport?.selectedBlueprint || 'unknown').trim() || 'unknown',
|
|
300
301
|
profile: String(onboardingReport?.selectedProfile || 'unknown').trim() || 'unknown',
|
|
301
302
|
corePatterns: normalizeCorePatterns(corePatterns),
|
|
302
303
|
};
|
|
@@ -312,7 +313,7 @@ function toComparableContractValue(value) {
|
|
|
312
313
|
|
|
313
314
|
function detectContractDrift(baseContract, targetContract, driftSource) {
|
|
314
315
|
const driftItems = [];
|
|
315
|
-
const fieldNames = ['
|
|
316
|
+
const fieldNames = ['runtimeDecision', 'architectureDecision', 'profile', 'corePatterns'];
|
|
316
317
|
|
|
317
318
|
for (const fieldName of fieldNames) {
|
|
318
319
|
const baseValue = toComparableContractValue(baseContract?.[fieldName]);
|
|
@@ -336,7 +337,7 @@ function buildSessionHandoffSummary(architectureContract) {
|
|
|
336
337
|
? architectureContract.corePatterns.join(', ')
|
|
337
338
|
: 'none';
|
|
338
339
|
|
|
339
|
-
return `Architecture contract summary:
|
|
340
|
+
return `Architecture contract summary: runtimeDecision=${architectureContract.runtimeDecision}, architectureDecision=${architectureContract.architectureDecision}, profile=${architectureContract.profile}, corePatterns=${corePatternsSummary}.`;
|
|
340
341
|
}
|
|
341
342
|
|
|
342
343
|
function assertSnippetCoverage(sourceLabel, sourcePath, requiredSnippets, failures, results) {
|
|
@@ -468,8 +469,8 @@ function runAudit() {
|
|
|
468
469
|
);
|
|
469
470
|
|
|
470
471
|
const proposedContract = {
|
|
471
|
-
|
|
472
|
-
|
|
472
|
+
runtimeDecision: parsedArguments.proposedStack || activeContract.runtimeDecision,
|
|
473
|
+
architectureDecision: parsedArguments.proposedBlueprint || activeContract.architectureDecision,
|
|
473
474
|
profile: activeContract.profile,
|
|
474
475
|
corePatterns: parsedArguments.proposedCorePatterns.length > 0
|
|
475
476
|
? parsedArguments.proposedCorePatterns
|
|
@@ -573,4 +574,4 @@ function runAudit() {
|
|
|
573
574
|
process.exit(reportPayload.passed ? 0 : 1);
|
|
574
575
|
}
|
|
575
576
|
|
|
576
|
-
runAudit();
|
|
577
|
+
runAudit();
|
|
@@ -76,8 +76,8 @@ const REQUIRED_REVIEW_PROMPT_SNIPPETS = [
|
|
|
76
76
|
|
|
77
77
|
const REQUIRED_COMPILER_SNIPPETS = [
|
|
78
78
|
'## LAYER 2 POLICY: LAZY RULE LOADING',
|
|
79
|
-
'Load
|
|
80
|
-
'Avoid eager loading unrelated
|
|
79
|
+
'Load runtime-specific guidance only when task scope touches that runtime.',
|
|
80
|
+
'Avoid eager loading unrelated runtime guidance to prevent instruction conflicts.',
|
|
81
81
|
"stackLoadingMode: 'lazy'",
|
|
82
82
|
];
|
|
83
83
|
|
|
@@ -532,4 +532,4 @@ function runAudit() {
|
|
|
532
532
|
process.exit(reportPayload.passed ? 0 : 1);
|
|
533
533
|
}
|
|
534
534
|
|
|
535
|
-
runAudit();
|
|
535
|
+
runAudit();
|
|
@@ -45,7 +45,7 @@ If your host stops at this file instead of following the full chain, obey the Cr
|
|
|
45
45
|
- For UI, UX, layout, screen, tailwind, frontend, or redesign requests: load [.agent-context/prompts/bootstrap-design.md](.agent-context/prompts/bootstrap-design.md) and [.agent-context/rules/frontend-architecture.md](.agent-context/rules/frontend-architecture.md) before editing code.
|
|
46
46
|
- For UI scope: if \`docs/DESIGN.md\` or \`docs/design-intent.json\` is missing, materialize or refine them before implementing UI changes.
|
|
47
47
|
- For refactor, improve, clean up, or fix requests: inspect the active rules and propose a plan before editing.
|
|
48
|
-
- For new project or module requests:
|
|
48
|
+
- For new project or module requests: clarify constraints, stack decisions, and required docs before generating code.
|
|
49
49
|
- For ecosystem, framework, dependency, or Docker claims: perform live web research instead of relying on stale local heuristics.
|
|
50
50
|
|
|
51
51
|
## Mandatory Bootstrap Chain
|
|
@@ -57,11 +57,11 @@ If your host stops at this file instead of following the full chain, obey the Cr
|
|
|
57
57
|
5. Enforce review contracts from [.agent-context/review-checklists/](.agent-context/review-checklists).
|
|
58
58
|
6. Read change-risk maps and continuity state from [.agent-context/state/](.agent-context/state).
|
|
59
59
|
7. Enforce policy thresholds from [.agent-context/policies/](.agent-context/policies).
|
|
60
|
-
8. Use dynamic stack and
|
|
60
|
+
8. Use dynamic stack, structure, and live research signals from project context docs.
|
|
61
61
|
|
|
62
62
|
## Trigger Rules
|
|
63
63
|
|
|
64
|
-
- New project or module requests: propose
|
|
64
|
+
- New project or module requests: propose scope, constraints, and required docs first, then wait for approval.
|
|
65
65
|
- Refactor or fix requests: propose plan first, then execute safely.
|
|
66
66
|
- Completion: run [.agent-context/review-checklists/pr-checklist.md](.agent-context/review-checklists/pr-checklist.md) before declaring done.
|
|
67
67
|
|
|
@@ -92,7 +92,7 @@ If your host stops at this file, follow this minimum floor:
|
|
|
92
92
|
4. Load request templates from [.agent-context/prompts/](../.agent-context/prompts).
|
|
93
93
|
5. Apply review contracts from [.agent-context/review-checklists/](../.agent-context/review-checklists).
|
|
94
94
|
6. Apply state awareness from [.agent-context/state/](../.agent-context/state) and thresholds from [.agent-context/policies/](../.agent-context/policies).
|
|
95
|
-
7. Resolve stack and
|
|
95
|
+
7. Resolve stack, structure, and dependency choices from project context docs plus live evidence.
|
|
96
96
|
|
|
97
97
|
## Completion Gate
|
|
98
98
|
|
|
@@ -123,7 +123,7 @@ If your host stops at this file, follow this minimum floor:
|
|
|
123
123
|
4. Load request templates from [.agent-context/prompts/](../.agent-context/prompts).
|
|
124
124
|
5. Apply review contracts from [.agent-context/review-checklists/](../.agent-context/review-checklists).
|
|
125
125
|
6. Apply state awareness from [.agent-context/state/](../.agent-context/state) and policy thresholds from [.agent-context/policies/](../.agent-context/policies).
|
|
126
|
-
7. Resolve stack and
|
|
126
|
+
7. Resolve stack, structure, and dependency choices from project context docs plus live evidence.
|
|
127
127
|
|
|
128
128
|
## Completion Gate
|
|
129
129
|
|
|
@@ -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,
|