@ryuenn3123/agentic-senior-core 3.0.28 → 3.0.29
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 +28 -0
- package/.agent-context/rules/frontend-architecture.md +7 -0
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.cursorrules +1 -1
- package/.gemini/instructions.md +1 -1
- package/.github/copilot-instructions.md +1 -1
- package/.instructions.md +3 -2
- package/.windsurfrules +1 -1
- package/AGENTS.md +1 -1
- package/README.md +7 -9
- package/lib/cli/compiler.mjs +75 -0
- package/lib/cli/project-scaffolder/design-contract.mjs +148 -1
- package/lib/cli/project-scaffolder/prompt-builders.mjs +35 -19
- package/lib/cli/project-scaffolder.mjs +1 -0
- package/package.json +1 -1
- package/scripts/release-gate/static-checks.mjs +32 -0
|
@@ -54,6 +54,32 @@ Write the chosen anchor into `docs/design-intent.json` as `conceptualAnchor`, in
|
|
|
54
54
|
|
|
55
55
|
Motion is not a garnish. Default to a rich motion plan: fluid transitions, spatial reveals, scroll choreography, micro-interactions, and modern motion libraries are expected when they strengthen the anchor and product experience. Keep reduced-motion fallbacks instead of suppressing motion, and solve performance deliberately instead of using safety language as a reason to stay static.
|
|
56
56
|
|
|
57
|
+
## Token Derivation Audit
|
|
58
|
+
|
|
59
|
+
Before implementation, `docs/design-intent.json` must include top-level `derivedTokenLogic` with `anchorReference`, `colorDerivationSource`, `spacingDerivationSource`, `typographyDerivationSource`, `motionDerivationSource`, and `validationRule`.
|
|
60
|
+
|
|
61
|
+
After writing `docs/design-intent.json`, audit the token plan:
|
|
62
|
+
- Why these colors instead of another palette? Answer in one sentence that references the anchorReference.
|
|
63
|
+
- Why this spacing rhythm? Answer in one sentence that references the anchorReference.
|
|
64
|
+
- Why this motion timing and easing? Answer in one sentence that references the anchorReference.
|
|
65
|
+
|
|
66
|
+
If the answer is "looks good", "common practice", "modern default", "Tailwind default", or a generic framework habit, the token is wrong. Derive it again from the chosen anchor before writing UI code.
|
|
67
|
+
|
|
68
|
+
## Library Research Protocol
|
|
69
|
+
|
|
70
|
+
If web search is available:
|
|
71
|
+
- Research current official docs for each library, framework API, animation package, scroll tool, 3D/canvas helper, charting tool, icon package, or UI primitive claim.
|
|
72
|
+
- Record source URL, fetched date, stable compatible version, purpose, risk, and fallback in `docs/design-intent.json`.
|
|
73
|
+
- Set `libraryResearchStatus` to `verified` only when each external library decision has current official evidence.
|
|
74
|
+
|
|
75
|
+
If web search is unavailable or fails:
|
|
76
|
+
- Do not hallucinate dependency APIs, package names, versions, or imports.
|
|
77
|
+
- Write `LIBRARY_TO_VERIFY: [name] - requires live research before implementation` in the design notes.
|
|
78
|
+
- Use only native CSS, browser APIs, or already-present project dependencies you can verify from local repo files.
|
|
79
|
+
- Set `libraryResearchStatus` to `pending-verification` and give every `libraryDecisions[]` entry a `fallbackIfUnavailable`.
|
|
80
|
+
|
|
81
|
+
Do not write imports from a new library until that library decision is verified or the user explicitly accepts a pending verification blocker.
|
|
82
|
+
|
|
57
83
|
## Zero-Based Redesign Protocol
|
|
58
84
|
|
|
59
85
|
If the user says "redesign from zero", "redesain dari 0", "ulang dari 0", "research ulang", or equivalent reset language, activate reset mode.
|
|
@@ -117,6 +143,8 @@ The JSON must stay machine-readable and project-specific. It should record:
|
|
|
117
143
|
- the confirmed project context and assumptions to validate
|
|
118
144
|
- agent-chosen visual direction, not scaffold-chosen direction
|
|
119
145
|
- `conceptualAnchor` and how typography, spacing, morphology, motion, and responsive composition derive from it when no external research was provided
|
|
146
|
+
- `derivedTokenLogic` with exact `anchorReference` traceability for color, spacing, typography, and motion tokens
|
|
147
|
+
- `libraryResearchStatus` plus `libraryDecisions[]` with verified source metadata or explicit native/project-local fallbacks
|
|
120
148
|
- agent-chosen semantic color roles, typography system, spacing rhythm, and motion approach
|
|
121
149
|
- token layering with primitive, semantic, and component tokens
|
|
122
150
|
- viewport mutation rules for mobile, tablet, and desktop
|
|
@@ -60,8 +60,15 @@ Do not use this file to teach generic frontend basics the model already knows.
|
|
|
60
60
|
- Reject anchors that can only be described with generic quality words such as "modern", "clean", "premium", "expressive", "minimal", or "bold"; the anchor must name a specific material, instrument, artifact class, architectural system, editorial genre, cinematic behavior, exhibition system, scientific apparatus, or industrial mechanism.
|
|
61
61
|
- Internally reject the safest dashboard, portal, card-grid, admin-shell, or minimalist-web-app mental model before writing CSS.
|
|
62
62
|
- Typography, spacing, morphology, motion, and responsive recomposition must derive from the chosen anchor, not from framework defaults.
|
|
63
|
+
- Token choices must trace to `docs/design-intent.json` `derivedTokenLogic.anchorReference`. A color, spacing, typography, or motion token that cannot be explained from the anchor is invalid.
|
|
63
64
|
- Default to an expressive motion plan derived from the anchor. Use spatial transitions, micro-interactions, scroll choreography, and modern animation libraries when they improve the experience; include reduced-motion and performance safeguards without using them as an excuse for a static UI.
|
|
64
65
|
|
|
66
|
+
## Library Research Boundary
|
|
67
|
+
|
|
68
|
+
- New UI, animation, scroll, 3D, canvas, charting, icon, styling, or primitive libraries require current official-doc verification before imports are written.
|
|
69
|
+
- If live research is unavailable, mark `libraryResearchStatus` as `pending-verification`, record the library as `LIBRARY_TO_VERIFY`, and use native CSS, browser APIs, or already-present project dependencies until verification is possible.
|
|
70
|
+
- Each `libraryDecisions[]` entry must have either verification metadata or a concrete `fallbackIfUnavailable`.
|
|
71
|
+
|
|
65
72
|
## Responsive Mutation Requirements
|
|
66
73
|
|
|
67
74
|
- Responsive quality is not allowed to be scale-only. At least one surface must materially change position, grouping, priority, or disclosure strategy between mobile and desktop.
|
package/.cursorrules
CHANGED
package/.gemini/instructions.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Adapter Mode: thin
|
|
4
4
|
Adapter Source: .instructions.md
|
|
5
|
-
Canonical Snapshot SHA256:
|
|
5
|
+
Canonical Snapshot SHA256: 5c955eab4c644e7139c0c5a5609ea9af7d47fdc8e69617f407af01ccc8c64e43
|
|
6
6
|
|
|
7
7
|
Canonical policy source: [.instructions.md](../.instructions.md).
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Adapter Mode: thin
|
|
4
4
|
Adapter Source: .instructions.md
|
|
5
|
-
Canonical Snapshot SHA256:
|
|
5
|
+
Canonical Snapshot SHA256: 5c955eab4c644e7139c0c5a5609ea9af7d47fdc8e69617f407af01ccc8c64e43
|
|
6
6
|
|
|
7
7
|
The canonical policy source for this repository is [.instructions.md](../.instructions.md).
|
|
8
8
|
|
package/.instructions.md
CHANGED
|
@@ -185,8 +185,9 @@ Use available MCP tools when you need validation, linting, or test execution.
|
|
|
185
185
|
2. Read `.agent-context/rules/frontend-architecture.md`.
|
|
186
186
|
3. Read UI-relevant repository evidence from `.agent-context/state/onboarding-report.json`, current UI code, and `docs/*`.
|
|
187
187
|
4. Before UI implementation, record a concrete creative commitment in the design contract: one specific real-world anchor reference, one signature motion behavior, and one typographic decision with meaningful role contrast.
|
|
188
|
-
5.
|
|
189
|
-
6.
|
|
188
|
+
5. Ensure `docs/design-intent.json` includes `conceptualAnchor.anchorReference`, top-level `derivedTokenLogic`, `libraryResearchStatus`, and `libraryDecisions[]` before UI code.
|
|
189
|
+
6. Generate or refine `docs/DESIGN.md` plus `docs/design-intent.json` before UI implementation.
|
|
190
|
+
7. Keep context isolated and do not eagerly load unrelated backend-only rules unless the task explicitly touches those boundaries.
|
|
190
191
|
|
|
191
192
|
---
|
|
192
193
|
|
package/.windsurfrules
CHANGED
package/AGENTS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Adapter Mode: thin
|
|
4
4
|
Adapter Source: .instructions.md
|
|
5
|
-
Canonical Snapshot SHA256:
|
|
5
|
+
Canonical Snapshot SHA256: 5c955eab4c644e7139c0c5a5609ea9af7d47fdc8e69617f407af01ccc8c64e43
|
|
6
6
|
|
|
7
7
|
This file is an adapter entrypoint for agent discovery.
|
|
8
8
|
The canonical policy source is [.instructions.md](.instructions.md).
|
package/README.md
CHANGED
|
@@ -10,15 +10,13 @@
|
|
|
10
10
|
**Production-grade Rules Engine (Governance Engine) for AI coding agents.**
|
|
11
11
|
Works with Cursor, Windsurf, GitHub Copilot, Claude Code, Gemini, and other LLM-powered IDE workflows.
|
|
12
12
|
|
|
13
|
-
Latest release: 3.0.
|
|
14
|
-
|
|
15
|
-
Highlights in 3.0.
|
|
16
|
-
-
|
|
17
|
-
- UI
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
- Agents must use live/current-year research for ecosystem, framework, dependency, Docker, and modern UI/library claims instead of offline repository guesses.
|
|
21
|
-
- Frontend guidance rejects safe dashboard/admin-panel defaults and requires responsive recomposition.
|
|
13
|
+
Latest release: 3.0.29 (2026-04-25).
|
|
14
|
+
|
|
15
|
+
Highlights in 3.0.29:
|
|
16
|
+
- UI design contracts now require deterministic `anchorReference` traceability through `derivedTokenLogic` before implementation.
|
|
17
|
+
- Compiled UI context can surface a top-of-file anchor commitment header from `docs/design-intent.json` so the creative direction is not buried under governance.
|
|
18
|
+
- Library decisions now must be verified against current official docs or marked `pending-verification` with native/project-local fallbacks.
|
|
19
|
+
- Release gate now validates the design-intent seed for token derivation and library verification completeness.
|
|
22
20
|
|
|
23
21
|
</div>
|
|
24
22
|
|
package/lib/cli/compiler.mjs
CHANGED
|
@@ -26,6 +26,75 @@ import {
|
|
|
26
26
|
buildMemoryContinuityGuidanceBlock,
|
|
27
27
|
} from './memory-continuity.mjs';
|
|
28
28
|
|
|
29
|
+
function toSingleLine(value, fallbackValue) {
|
|
30
|
+
const normalizedValue = String(value || '').replace(/\s+/g, ' ').trim();
|
|
31
|
+
return normalizedValue || fallbackValue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function readDesignIntentIfExists(targetDirectoryPath) {
|
|
35
|
+
const designIntentPath = path.join(targetDirectoryPath, 'docs', 'design-intent.json');
|
|
36
|
+
if (!(await pathExists(designIntentPath))) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(await fs.readFile(designIntentPath, 'utf8'));
|
|
42
|
+
} catch {
|
|
43
|
+
return {
|
|
44
|
+
parseError: true,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function buildAnchorCommitmentHeader(designIntent) {
|
|
50
|
+
if (!designIntent || typeof designIntent !== 'object') {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (designIntent.parseError) {
|
|
55
|
+
return [
|
|
56
|
+
'## [UI TASK ANCHOR - READ FIRST]',
|
|
57
|
+
'Source: docs/design-intent.json',
|
|
58
|
+
'Status: design-intent.json could not be parsed.',
|
|
59
|
+
'Required action: fix docs/design-intent.json before UI implementation so the creative commitment can be loaded.',
|
|
60
|
+
].join('\n');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const conceptualAnchor = designIntent.conceptualAnchor || {};
|
|
64
|
+
const derivedTokenLogic = designIntent.derivedTokenLogic || {};
|
|
65
|
+
const creativeCommitment = designIntent.designExecutionHandoff?.creativeCommitment || {};
|
|
66
|
+
const anchorReference = conceptualAnchor.anchorReference || derivedTokenLogic.anchorReference;
|
|
67
|
+
const conceptualAnchorName = conceptualAnchor.name || anchorReference;
|
|
68
|
+
const signatureMove = conceptualAnchor.signatureMove
|
|
69
|
+
|| designIntent.designExecutionHandoff?.signatureMoveRationale;
|
|
70
|
+
const signatureMotion = conceptualAnchor.signatureMotion
|
|
71
|
+
|| creativeCommitment.signatureMotion
|
|
72
|
+
|| derivedTokenLogic.motionDerivationSource;
|
|
73
|
+
const typographicDecision = conceptualAnchor.typographicDecision
|
|
74
|
+
|| creativeCommitment.typographicDecision
|
|
75
|
+
|| derivedTokenLogic.typographyDerivationSource;
|
|
76
|
+
|
|
77
|
+
if (!conceptualAnchorName && !anchorReference) {
|
|
78
|
+
return [
|
|
79
|
+
'## [UI TASK ANCHOR - READ FIRST]',
|
|
80
|
+
'Source: docs/design-intent.json',
|
|
81
|
+
'Status: Creative commitment is missing.',
|
|
82
|
+
'Required action: define conceptualAnchor.anchorReference, a concrete real-world anchor, signature motion, typographic decision, derivedTokenLogic, and libraryDecisions before UI implementation.',
|
|
83
|
+
].join('\n');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return [
|
|
87
|
+
'## [UI TASK ANCHOR - READ FIRST]',
|
|
88
|
+
'Source: docs/design-intent.json',
|
|
89
|
+
`Conceptual Anchor: ${toSingleLine(conceptualAnchorName, 'MISSING - complete Creative Commitment Gate before UI implementation')}`,
|
|
90
|
+
`Anchor Reference: ${toSingleLine(anchorReference, 'MISSING - required for deterministic token validation')}`,
|
|
91
|
+
`Signature Move: ${toSingleLine(signatureMove, 'MISSING - define one concrete authored move before UI implementation')}`,
|
|
92
|
+
`Motion Signature: ${toSingleLine(signatureMotion, 'MISSING - define timing/easing/choreography before UI implementation')}`,
|
|
93
|
+
`Typographic Decision: ${toSingleLine(typographicDecision, 'MISSING - define role contrast before UI implementation')}`,
|
|
94
|
+
'If the UI output does not reflect these lines, stop and revise the design contract before continuing.',
|
|
95
|
+
].join('\n');
|
|
96
|
+
}
|
|
97
|
+
|
|
29
98
|
export async function writeSelectedPolicy(targetDirectoryPath, selectedProfileName) {
|
|
30
99
|
const policyFilePath = path.join(targetDirectoryPath, '.agent-context', 'policies', POLICY_FILE_NAME);
|
|
31
100
|
const parsedPolicy = JSON.parse(await fs.readFile(policyFilePath, 'utf8'));
|
|
@@ -480,6 +549,12 @@ export async function buildCompiledRulesContent({
|
|
|
480
549
|
);
|
|
481
550
|
}
|
|
482
551
|
|
|
552
|
+
const designIntent = await readDesignIntentIfExists(resolvedTargetDirectoryPath);
|
|
553
|
+
const anchorCommitmentHeader = buildAnchorCommitmentHeader(designIntent);
|
|
554
|
+
if (anchorCommitmentHeader) {
|
|
555
|
+
contextBlocks.unshift(anchorCommitmentHeader);
|
|
556
|
+
}
|
|
557
|
+
|
|
483
558
|
return [
|
|
484
559
|
'# AGENTIC-SENIOR-CORE DYNAMIC GOVERNANCE RULESET',
|
|
485
560
|
'',
|
|
@@ -136,6 +136,7 @@ function buildDesignIntentContractObject({
|
|
|
136
136
|
conceptualAnchor: {
|
|
137
137
|
mode: 'required-when-no-external-research',
|
|
138
138
|
seedMode: 'selection-policy-only',
|
|
139
|
+
anchorReference: 'agent-defined-anchor-reference',
|
|
139
140
|
requiresAgentSelectionBeforeUiImplementation: true,
|
|
140
141
|
userResearchAbsencePolicy: {
|
|
141
142
|
userSuppliedResearchOnly: true,
|
|
@@ -193,6 +194,7 @@ function buildDesignIntentContractObject({
|
|
|
193
194
|
finalAnchorContract: {
|
|
194
195
|
requiredFields: [
|
|
195
196
|
'name',
|
|
197
|
+
'anchorReference',
|
|
196
198
|
'agentResearchMode',
|
|
197
199
|
'sourceDomain',
|
|
198
200
|
'specificReferencePoint',
|
|
@@ -214,6 +216,25 @@ function buildDesignIntentContractObject({
|
|
|
214
216
|
],
|
|
215
217
|
},
|
|
216
218
|
},
|
|
219
|
+
derivedTokenLogic: {
|
|
220
|
+
anchorReference: 'agent-defined-anchor-reference',
|
|
221
|
+
colorDerivationSource: 'Agent must explain how semantic color roles derive from the chosen anchorReference; default blue or generic SaaS palettes are invalid without anchor evidence.',
|
|
222
|
+
spacingDerivationSource: 'Agent must explain how base grid, rhythm, density, and spacing exceptions derive from the chosen anchorReference.',
|
|
223
|
+
typographyDerivationSource: 'Agent must explain how display, body, metadata, and data typography roles derive from the chosen anchorReference.',
|
|
224
|
+
motionDerivationSource: 'Agent must explain how duration, easing, choreography, and reduced-motion alternatives derive from the chosen anchorReference.',
|
|
225
|
+
validationRule: 'Every primitive, semantic, component, typography, spacing, and motion token must trace back to anchorReference; if a token cannot be explained from the anchor, revise the token.',
|
|
226
|
+
},
|
|
227
|
+
libraryResearchStatus: 'pending-verification',
|
|
228
|
+
libraryDecisions: [
|
|
229
|
+
{
|
|
230
|
+
library: 'agent-defined-or-none',
|
|
231
|
+
purpose: 'Agent must verify any UI, animation, scroll, 3D, canvas, chart, icon, or styling library against current official docs before implementation.',
|
|
232
|
+
verifiedAt: null,
|
|
233
|
+
sourceUrl: null,
|
|
234
|
+
stableVersion: null,
|
|
235
|
+
fallbackIfUnavailable: 'Use native CSS, browser APIs, or existing project dependencies until live verification is available.',
|
|
236
|
+
},
|
|
237
|
+
],
|
|
217
238
|
mathSystems: {
|
|
218
239
|
typographyScaleRatio: inferredKeywords.typographyScaleRatio,
|
|
219
240
|
baseGridUnit: inferredKeywords.baseGridUnit,
|
|
@@ -581,6 +602,81 @@ function buildDesignIntentContractObject({
|
|
|
581
602
|
};
|
|
582
603
|
}
|
|
583
604
|
|
|
605
|
+
function hasNonEmptyString(value) {
|
|
606
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
export function validateDesignContractCompleteness(designIntentContract) {
|
|
610
|
+
const validationIssues = [];
|
|
611
|
+
const conceptualAnchor = designIntentContract?.conceptualAnchor;
|
|
612
|
+
const derivedTokenLogic = designIntentContract?.derivedTokenLogic;
|
|
613
|
+
const libraryDecisions = designIntentContract?.libraryDecisions;
|
|
614
|
+
|
|
615
|
+
const anchorReference = conceptualAnchor?.anchorReference || derivedTokenLogic?.anchorReference;
|
|
616
|
+
if (!hasNonEmptyString(anchorReference)) {
|
|
617
|
+
validationIssues.push('designIntent.conceptualAnchor.anchorReference must be a stable non-empty ID for deterministic validation.');
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
if (!derivedTokenLogic || typeof derivedTokenLogic !== 'object') {
|
|
621
|
+
validationIssues.push('designIntent.derivedTokenLogic must exist.');
|
|
622
|
+
} else {
|
|
623
|
+
if (derivedTokenLogic.anchorReference !== anchorReference) {
|
|
624
|
+
validationIssues.push('designIntent.derivedTokenLogic.anchorReference must exactly match designIntent.conceptualAnchor.anchorReference.');
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
for (const requiredFieldName of [
|
|
628
|
+
'colorDerivationSource',
|
|
629
|
+
'spacingDerivationSource',
|
|
630
|
+
'typographyDerivationSource',
|
|
631
|
+
'motionDerivationSource',
|
|
632
|
+
'validationRule',
|
|
633
|
+
]) {
|
|
634
|
+
if (!hasNonEmptyString(derivedTokenLogic[requiredFieldName])) {
|
|
635
|
+
validationIssues.push(`designIntent.derivedTokenLogic.${requiredFieldName} must be a non-empty string.`);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
if (
|
|
640
|
+
hasNonEmptyString(derivedTokenLogic.validationRule)
|
|
641
|
+
&& !derivedTokenLogic.validationRule.includes('anchorReference')
|
|
642
|
+
) {
|
|
643
|
+
validationIssues.push('designIntent.derivedTokenLogic.validationRule must require traceability to anchorReference.');
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
if (!['verified', 'pending-verification', 'no-external-library-needed'].includes(designIntentContract?.libraryResearchStatus)) {
|
|
648
|
+
validationIssues.push('designIntent.libraryResearchStatus must be verified, pending-verification, or no-external-library-needed.');
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (!Array.isArray(libraryDecisions)) {
|
|
652
|
+
validationIssues.push('designIntent.libraryDecisions must be an array.');
|
|
653
|
+
} else {
|
|
654
|
+
for (const [libraryIndex, libraryDecision] of libraryDecisions.entries()) {
|
|
655
|
+
if (!libraryDecision || typeof libraryDecision !== 'object') {
|
|
656
|
+
validationIssues.push(`designIntent.libraryDecisions[${libraryIndex}] must be an object.`);
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
if (!hasNonEmptyString(libraryDecision.library)) {
|
|
661
|
+
validationIssues.push(`designIntent.libraryDecisions[${libraryIndex}].library must be a non-empty string.`);
|
|
662
|
+
}
|
|
663
|
+
if (!hasNonEmptyString(libraryDecision.purpose)) {
|
|
664
|
+
validationIssues.push(`designIntent.libraryDecisions[${libraryIndex}].purpose must be a non-empty string.`);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const hasVerification = hasNonEmptyString(libraryDecision.verifiedAt)
|
|
668
|
+
&& hasNonEmptyString(libraryDecision.sourceUrl);
|
|
669
|
+
const hasFallback = hasNonEmptyString(libraryDecision.fallbackIfUnavailable);
|
|
670
|
+
|
|
671
|
+
if (!hasVerification && !hasFallback) {
|
|
672
|
+
validationIssues.push(`designIntent.libraryDecisions[${libraryIndex}] must either record verification source or provide fallbackIfUnavailable.`);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
return validationIssues;
|
|
678
|
+
}
|
|
679
|
+
|
|
584
680
|
export function validateDesignIntentContract(designIntentContract) {
|
|
585
681
|
const validationErrors = [];
|
|
586
682
|
|
|
@@ -588,6 +684,8 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
588
684
|
return ['Design intent contract must be an object.'];
|
|
589
685
|
}
|
|
590
686
|
|
|
687
|
+
validationErrors.push(...validateDesignContractCompleteness(designIntentContract));
|
|
688
|
+
|
|
591
689
|
if (designIntentContract.mode !== 'dynamic') {
|
|
592
690
|
validationErrors.push('designIntent.mode must equal "dynamic".');
|
|
593
691
|
}
|
|
@@ -630,6 +728,9 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
630
728
|
if (conceptualAnchor.requiresAgentSelectionBeforeUiImplementation !== true) {
|
|
631
729
|
validationErrors.push('designIntent.conceptualAnchor.requiresAgentSelectionBeforeUiImplementation must equal true.');
|
|
632
730
|
}
|
|
731
|
+
if (!hasNonEmptyString(conceptualAnchor.anchorReference)) {
|
|
732
|
+
validationErrors.push('designIntent.conceptualAnchor.anchorReference must be a stable non-empty ID.');
|
|
733
|
+
}
|
|
633
734
|
const userResearchAbsencePolicy = conceptualAnchor.userResearchAbsencePolicy;
|
|
634
735
|
if (!userResearchAbsencePolicy || typeof userResearchAbsencePolicy !== 'object') {
|
|
635
736
|
validationErrors.push('designIntent.conceptualAnchor.userResearchAbsencePolicy must exist.');
|
|
@@ -673,6 +774,28 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
673
774
|
validationErrors.push('designIntent.conceptualAnchor.candidateSelectionPolicy.outputOnlyChosenAnchor must equal true.');
|
|
674
775
|
}
|
|
675
776
|
}
|
|
777
|
+
const creativeCommitmentPolicy = conceptualAnchor.creativeCommitmentPolicy;
|
|
778
|
+
if (!creativeCommitmentPolicy || typeof creativeCommitmentPolicy !== 'object') {
|
|
779
|
+
validationErrors.push('designIntent.conceptualAnchor.creativeCommitmentPolicy must exist.');
|
|
780
|
+
} else {
|
|
781
|
+
if (creativeCommitmentPolicy.requiredBeforeComplianceReview !== true) {
|
|
782
|
+
validationErrors.push('designIntent.conceptualAnchor.creativeCommitmentPolicy.requiredBeforeComplianceReview must equal true.');
|
|
783
|
+
}
|
|
784
|
+
if (creativeCommitmentPolicy.recordInDesignDocs !== true) {
|
|
785
|
+
validationErrors.push('designIntent.conceptualAnchor.creativeCommitmentPolicy.recordInDesignDocs must equal true.');
|
|
786
|
+
}
|
|
787
|
+
if (
|
|
788
|
+
!Array.isArray(creativeCommitmentPolicy.requiredCommitmentFields)
|
|
789
|
+
|| !creativeCommitmentPolicy.requiredCommitmentFields.includes('specificReferencePoint')
|
|
790
|
+
|| !creativeCommitmentPolicy.requiredCommitmentFields.includes('signatureMotion')
|
|
791
|
+
|| !creativeCommitmentPolicy.requiredCommitmentFields.includes('typographicDecision')
|
|
792
|
+
) {
|
|
793
|
+
validationErrors.push('designIntent.conceptualAnchor.creativeCommitmentPolicy.requiredCommitmentFields must include specificReferencePoint, signatureMotion, and typographicDecision.');
|
|
794
|
+
}
|
|
795
|
+
if (creativeCommitmentPolicy.rejectGenericQualityWordsOnly !== true) {
|
|
796
|
+
validationErrors.push('designIntent.conceptualAnchor.creativeCommitmentPolicy.rejectGenericQualityWordsOnly must equal true.');
|
|
797
|
+
}
|
|
798
|
+
}
|
|
676
799
|
if (
|
|
677
800
|
!Array.isArray(conceptualAnchor.forbiddenFinalAnchorTerms)
|
|
678
801
|
|| !conceptualAnchor.forbiddenFinalAnchorTerms.includes('dashboard')
|
|
@@ -720,13 +843,17 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
720
843
|
} else {
|
|
721
844
|
if (
|
|
722
845
|
!Array.isArray(finalAnchorContract.requiredFields)
|
|
846
|
+
|| !finalAnchorContract.requiredFields.includes('anchorReference')
|
|
723
847
|
|| !finalAnchorContract.requiredFields.includes('agentResearchMode')
|
|
848
|
+
|| !finalAnchorContract.requiredFields.includes('specificReferencePoint')
|
|
849
|
+
|| !finalAnchorContract.requiredFields.includes('signatureMotion')
|
|
850
|
+
|| !finalAnchorContract.requiredFields.includes('typographicDecision')
|
|
724
851
|
|| !finalAnchorContract.requiredFields.includes('derivedTokenLogic')
|
|
725
852
|
|| !finalAnchorContract.requiredFields.includes('visualRiskBudget')
|
|
726
853
|
|| !finalAnchorContract.requiredFields.includes('motionRiskBudget')
|
|
727
854
|
|| !finalAnchorContract.requiredFields.includes('cohesionChecks')
|
|
728
855
|
) {
|
|
729
|
-
validationErrors.push('designIntent.conceptualAnchor.finalAnchorContract.requiredFields must require agentResearchMode, derivedTokenLogic, visualRiskBudget, motionRiskBudget, and cohesionChecks.');
|
|
856
|
+
validationErrors.push('designIntent.conceptualAnchor.finalAnchorContract.requiredFields must require anchorReference, agentResearchMode, specificReferencePoint, signatureMotion, typographicDecision, derivedTokenLogic, visualRiskBudget, motionRiskBudget, and cohesionChecks.');
|
|
730
857
|
}
|
|
731
858
|
if (
|
|
732
859
|
!Array.isArray(finalAnchorContract.derivedTokenLogicAxes)
|
|
@@ -968,6 +1095,7 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
968
1095
|
'requireContentPriorityMap',
|
|
969
1096
|
'requireTaskFlowNarrative',
|
|
970
1097
|
'requireSignatureMoveRationale',
|
|
1098
|
+
'requireCreativeCommitmentGate',
|
|
971
1099
|
'requireStructuredHandoff',
|
|
972
1100
|
'requireRepoEvidenceAlignment',
|
|
973
1101
|
'forbidScreenshotDependency',
|
|
@@ -1062,6 +1190,25 @@ export function validateDesignIntentContract(designIntentContract) {
|
|
|
1062
1190
|
if (!String(designIntentContract.designExecutionHandoff.signatureMoveRationale || '').trim()) {
|
|
1063
1191
|
validationErrors.push('designIntent.designExecutionHandoff.signatureMoveRationale must explain the chosen authored move.');
|
|
1064
1192
|
}
|
|
1193
|
+
const creativeCommitment = designIntentContract.designExecutionHandoff.creativeCommitment;
|
|
1194
|
+
if (!creativeCommitment || typeof creativeCommitment !== 'object') {
|
|
1195
|
+
validationErrors.push('designIntent.designExecutionHandoff.creativeCommitment must exist.');
|
|
1196
|
+
} else {
|
|
1197
|
+
if (creativeCommitment.status !== 'agent-must-complete-before-ui-implementation') {
|
|
1198
|
+
validationErrors.push('designIntent.designExecutionHandoff.creativeCommitment.status must equal "agent-must-complete-before-ui-implementation".');
|
|
1199
|
+
}
|
|
1200
|
+
if (
|
|
1201
|
+
!Array.isArray(creativeCommitment.requiredFields)
|
|
1202
|
+
|| !creativeCommitment.requiredFields.includes('specificReferencePoint')
|
|
1203
|
+
|| !creativeCommitment.requiredFields.includes('signatureMotion')
|
|
1204
|
+
|| !creativeCommitment.requiredFields.includes('typographicDecision')
|
|
1205
|
+
) {
|
|
1206
|
+
validationErrors.push('designIntent.designExecutionHandoff.creativeCommitment.requiredFields must include specificReferencePoint, signatureMotion, and typographicDecision.');
|
|
1207
|
+
}
|
|
1208
|
+
if (!hasNonEmptyString(creativeCommitment.failureMode)) {
|
|
1209
|
+
validationErrors.push('designIntent.designExecutionHandoff.creativeCommitment.failureMode must be a non-empty string.');
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1065
1212
|
const implementationGuardrails = designIntentContract.designExecutionHandoff.implementationGuardrails;
|
|
1066
1213
|
if (!implementationGuardrails || typeof implementationGuardrails !== 'object') {
|
|
1067
1214
|
validationErrors.push('designIntent.designExecutionHandoff.implementationGuardrails must exist.');
|
|
@@ -125,23 +125,26 @@ export function buildDesignBootstrapPrompt({
|
|
|
125
125
|
'5. brandAdjectives',
|
|
126
126
|
'6. antiAdjectives',
|
|
127
127
|
'7. visualDirection',
|
|
128
|
-
'8.
|
|
129
|
-
'9.
|
|
130
|
-
'10.
|
|
131
|
-
'11.
|
|
132
|
-
'12.
|
|
133
|
-
'13.
|
|
134
|
-
'14.
|
|
135
|
-
'15.
|
|
136
|
-
'16.
|
|
137
|
-
'17.
|
|
138
|
-
'18.
|
|
139
|
-
'19.
|
|
140
|
-
'20.
|
|
141
|
-
'21.
|
|
142
|
-
'22.
|
|
143
|
-
'23.
|
|
144
|
-
'24.
|
|
128
|
+
'8. derivedTokenLogic',
|
|
129
|
+
'9. libraryResearchStatus',
|
|
130
|
+
'10. libraryDecisions',
|
|
131
|
+
'11. mathSystems',
|
|
132
|
+
'12. tokenSystem',
|
|
133
|
+
'13. colorTruth',
|
|
134
|
+
'14. crossViewportAdaptation',
|
|
135
|
+
'15. motionSystem',
|
|
136
|
+
'16. componentMorphology',
|
|
137
|
+
'17. accessibilityPolicy',
|
|
138
|
+
'18. designExecutionPolicy',
|
|
139
|
+
'19. designExecutionHandoff',
|
|
140
|
+
'20. reviewRubric',
|
|
141
|
+
'21. contextHygiene',
|
|
142
|
+
'22. experiencePrinciples',
|
|
143
|
+
'23. forbiddenPatterns',
|
|
144
|
+
'24. validationHints',
|
|
145
|
+
'25. requiredDesignSections',
|
|
146
|
+
'26. implementation',
|
|
147
|
+
'27. repoEvidence when onboarding or detector evidence exists',
|
|
145
148
|
'',
|
|
146
149
|
'## Hard Rules',
|
|
147
150
|
'1. No copy-paste from external style guides.',
|
|
@@ -180,7 +183,19 @@ export function buildDesignBootstrapPrompt({
|
|
|
180
183
|
'34. Before broad compliance review, make a creative commitment and record it in the design contract: one specific real-world anchor reference, one signature motion behavior more specific than smooth transitions, and one typographic decision with meaningful role contrast.',
|
|
181
184
|
'35. In Dynamic Avant-Garde mode, perform agent-led research when available, then internally consider at least three high-variance conceptual anchors, discard the two safest or most predictable options, output only the chosen anchor, its specific reference point, and rationale, and forbid final anchors named dashboard, portal, cards, admin panel, SaaS shell, web app shell, or minimalist interface.',
|
|
182
185
|
'36. Reject anchors that can only be described with generic quality words such as modern, clean, premium, expressive, minimal, or bold. The anchor must name a material, instrument, artifact class, architecture, editorial genre, cinematic behavior, exhibition system, scientific apparatus, or industrial mechanism.',
|
|
183
|
-
'37. The chosen anchor must
|
|
186
|
+
'37. The chosen anchor must define a stable conceptualAnchor.anchorReference. derivedTokenLogic.anchorReference must match it exactly so validation does not depend on paraphrased prose.',
|
|
187
|
+
'38. Fill derivedTokenLogic with color, spacing, typography, and motion derivation sources before UI implementation. If a token cannot be explained from anchorReference, revise the token.',
|
|
188
|
+
'39. If live web research is unavailable or fails, do not hallucinate dependency APIs, package names, versions, or imports. Set libraryResearchStatus to pending-verification, record LIBRARY_TO_VERIFY notes, and use native CSS, browser APIs, or already-present project dependencies until verification is possible.',
|
|
189
|
+
'40. Every libraryDecisions entry must either include current official-doc verification metadata or a fallbackIfUnavailable. Do not import a new library without verification or an accepted blocker.',
|
|
190
|
+
'41. The chosen anchor must drive typography, spacing, density, color behavior, morphology, motion, and responsive composition. Treat expressive motion, spatial transitions, micro-interactions, and modern animation libraries as first-class options; include performance notes and reduced-motion fallbacks instead of suppressing motion to look safe.',
|
|
191
|
+
'',
|
|
192
|
+
'## Token Derivation Audit',
|
|
193
|
+
'Before implementation, docs/design-intent.json must include derivedTokenLogic.anchorReference plus colorDerivationSource, spacingDerivationSource, typographyDerivationSource, motionDerivationSource, and validationRule.',
|
|
194
|
+
'Every token must be explainable from anchorReference. If the rationale is only looks good, common practice, modern default, or framework default, derive the token again before UI code.',
|
|
195
|
+
'',
|
|
196
|
+
'## Library Research Protocol',
|
|
197
|
+
'If web search is available, verify every new UI, animation, scroll, 3D, canvas, chart, icon, styling, or primitive library against current official docs and record source URL, fetched date, stable compatible version, purpose, risk, and fallback.',
|
|
198
|
+
'If web search is unavailable or fails, set libraryResearchStatus to pending-verification, record LIBRARY_TO_VERIFY notes, and use native CSS, browser APIs, or already-present project dependencies until verification is possible.',
|
|
184
199
|
'',
|
|
185
200
|
'## Project Inputs',
|
|
186
201
|
`- Project name: ${discoveryAnswers.projectName}`,
|
|
@@ -212,7 +227,8 @@ export function buildDesignBootstrapPrompt({
|
|
|
212
227
|
'13. Preserve externalResearchIntake so user-provided research becomes reviewed evidence without turning into an offline style or dependency preset.',
|
|
213
228
|
'14. Preserve conceptualAnchor so prompt-only UI work has one cohesive non-template concept instead of a mixed collection of bold but unrelated visual decisions.',
|
|
214
229
|
'15. Record conceptualAnchor.agentResearchMode, specificReferencePoint, signatureMotion, typographicDecision, visualRiskBudget, motionRiskBudget, and cohesionChecks so the final UI cannot quietly fall back to a timid dashboard/admin mental model.',
|
|
215
|
-
'16.
|
|
230
|
+
'16. Preserve derivedTokenLogic, libraryResearchStatus, and libraryDecisions so token choices and dependency uncertainty stay visible before implementation.',
|
|
231
|
+
'17. After the contract exists, use it as a first-class source for future UI tasks.',
|
|
216
232
|
'',
|
|
217
233
|
].join('\n');
|
|
218
234
|
}
|
package/package.json
CHANGED
|
@@ -15,6 +15,10 @@ import {
|
|
|
15
15
|
VERSION_PATTERN,
|
|
16
16
|
} from './constants.mjs';
|
|
17
17
|
import { pushResult, readText } from './runtime.mjs';
|
|
18
|
+
import {
|
|
19
|
+
buildDesignIntentSeedFromSignals,
|
|
20
|
+
validateDesignContractCompleteness,
|
|
21
|
+
} from '../../lib/cli/project-scaffolder.mjs';
|
|
18
22
|
|
|
19
23
|
export function runStaticReleaseChecks(results, diagnostics) {
|
|
20
24
|
const packageJsonPath = 'package.json';
|
|
@@ -66,6 +70,34 @@ export function runStaticReleaseChecks(results, diagnostics) {
|
|
|
66
70
|
pushResult(results, true, 'roadmap-v18', 'Roadmap includes V1.8 release track');
|
|
67
71
|
}
|
|
68
72
|
|
|
73
|
+
try {
|
|
74
|
+
const designIntentSeed = JSON.parse(buildDesignIntentSeedFromSignals({
|
|
75
|
+
projectName: 'Release Gate UI Contract',
|
|
76
|
+
projectDescription: 'Validates deterministic UI design contract completeness before release',
|
|
77
|
+
primaryDomain: 'Web application',
|
|
78
|
+
initContext: {
|
|
79
|
+
stackFileName: 'agent-decision-runtime.md',
|
|
80
|
+
blueprintFileName: 'agent-decision-architecture.md',
|
|
81
|
+
},
|
|
82
|
+
status: 'release-gate-seed-validation',
|
|
83
|
+
}));
|
|
84
|
+
const designContractIssues = validateDesignContractCompleteness(designIntentSeed);
|
|
85
|
+
|
|
86
|
+
if (designContractIssues.length === 0) {
|
|
87
|
+
pushResult(results, true, 'ui-design-contract-completeness', 'Design intent seed includes deterministic token derivation and library verification gates');
|
|
88
|
+
} else {
|
|
89
|
+
pushResult(
|
|
90
|
+
results,
|
|
91
|
+
false,
|
|
92
|
+
'ui-design-contract-completeness',
|
|
93
|
+
`Design intent seed completeness issues: ${designContractIssues.join('; ')}`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
} catch (designContractError) {
|
|
97
|
+
const designContractMessage = designContractError instanceof Error ? designContractError.message : 'Unknown design contract error';
|
|
98
|
+
pushResult(results, false, 'ui-design-contract-completeness', `Cannot validate design intent seed: ${designContractMessage}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
69
101
|
const requiredOperationsFiles = [
|
|
70
102
|
'.agent-context/review-checklists/architecture-review.md',
|
|
71
103
|
'docs/v1.8-operations-playbook.md',
|