@ryuenn3123/agentic-senior-core 3.0.50 → 4.0.1

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 (89) hide show
  1. package/.agent-context/prompts/bootstrap-design.md +3 -1
  2. package/.agent-context/prompts/research-design.md +165 -0
  3. package/.agent-context/review-checklists/pr-checklist.md +1 -0
  4. package/.agent-context/rules/api-docs.md +63 -47
  5. package/.agent-context/rules/architecture.md +133 -120
  6. package/.agent-context/rules/database-design.md +36 -18
  7. package/.agent-context/rules/docker-runtime.md +66 -43
  8. package/.agent-context/rules/efficiency-vs-hype.md +38 -17
  9. package/.agent-context/rules/error-handling.md +35 -16
  10. package/.agent-context/rules/event-driven.md +35 -18
  11. package/.agent-context/rules/frontend-architecture.md +103 -76
  12. package/.agent-context/rules/git-workflow.md +81 -197
  13. package/.agent-context/rules/microservices.md +42 -41
  14. package/.agent-context/rules/naming-conv.md +27 -8
  15. package/.agent-context/rules/performance.md +32 -12
  16. package/.agent-context/rules/realtime.md +26 -9
  17. package/.agent-context/rules/security.md +39 -20
  18. package/.agent-context/rules/testing.md +36 -16
  19. package/AGENTS.md +21 -20
  20. package/README.md +10 -1
  21. package/lib/cli/commands/init.mjs +12 -0
  22. package/lib/cli/commands/upgrade.mjs +11 -0
  23. package/lib/cli/compiler.mjs +1 -0
  24. package/lib/cli/detector/constants.mjs +135 -0
  25. package/lib/cli/detector/design-evidence/collector.mjs +256 -0
  26. package/lib/cli/detector/design-evidence/constants.mjs +39 -0
  27. package/lib/cli/detector/design-evidence/file-traversal.mjs +83 -0
  28. package/lib/cli/detector/design-evidence/structured-attribute-evidence.mjs +117 -0
  29. package/lib/cli/detector/design-evidence/summary.mjs +109 -0
  30. package/lib/cli/detector/design-evidence/utility-helpers.mjs +122 -0
  31. package/lib/cli/detector/design-evidence.mjs +25 -610
  32. package/lib/cli/detector/stack-detection.mjs +243 -0
  33. package/lib/cli/detector/ui-signals.mjs +150 -0
  34. package/lib/cli/detector/workspace-scan.mjs +177 -0
  35. package/lib/cli/detector.mjs +20 -688
  36. package/lib/cli/memory-continuity.mjs +1 -0
  37. package/lib/cli/project-scaffolder/design-contract/research-dossier-migration.mjs +165 -0
  38. package/lib/cli/project-scaffolder/design-contract/sections/audits.mjs +96 -0
  39. package/lib/cli/project-scaffolder/design-contract/sections/conceptual-anchor.mjs +233 -0
  40. package/lib/cli/project-scaffolder/design-contract/sections/execution-handoff.mjs +211 -0
  41. package/lib/cli/project-scaffolder/design-contract/seed-signals.mjs +79 -0
  42. package/lib/cli/project-scaffolder/design-contract/signal-vocab.mjs +64 -0
  43. package/lib/cli/project-scaffolder/design-contract/validation/anchor-validators.mjs +456 -0
  44. package/lib/cli/project-scaffolder/design-contract/validation/audit-validators.mjs +117 -0
  45. package/lib/cli/project-scaffolder/design-contract/validation/completeness.mjs +83 -0
  46. package/lib/cli/project-scaffolder/design-contract/validation/execution-validators.mjs +328 -0
  47. package/lib/cli/project-scaffolder/design-contract/validation/helpers.mjs +8 -0
  48. package/lib/cli/project-scaffolder/design-contract/validation/research-dossier-validators.mjs +104 -0
  49. package/lib/cli/project-scaffolder/design-contract/validation/structural-validators.mjs +79 -0
  50. package/lib/cli/project-scaffolder/design-contract/validation/system-validators.mjs +256 -0
  51. package/lib/cli/project-scaffolder/design-contract/validation.mjs +61 -896
  52. package/lib/cli/project-scaffolder/design-contract.mjs +151 -556
  53. package/lib/cli/project-scaffolder/prompt-builders.mjs +9 -0
  54. package/mcp.json +30 -9
  55. package/package.json +17 -2
  56. package/scripts/audit-cache-layer-contract.mjs +258 -0
  57. package/scripts/audit-caching-scope-hygiene.mjs +263 -0
  58. package/scripts/audit-file-size.mjs +219 -0
  59. package/scripts/audit-reflection-citations.mjs +163 -0
  60. package/scripts/audit-release-bundle.mjs +170 -0
  61. package/scripts/audit-rule-id-uniqueness.mjs +313 -0
  62. package/scripts/benchmark-evidence-bundle.mjs +1 -0
  63. package/scripts/build-release-benchmark-bundle.mjs +204 -0
  64. package/scripts/context-triggered-audit.mjs +1 -0
  65. package/scripts/documentation-boundary-audit.mjs +1 -0
  66. package/scripts/explain-on-demand-audit.mjs +2 -1
  67. package/scripts/frontend-usability-audit.mjs +10 -10
  68. package/scripts/llm-judge/checklist-loader.mjs +45 -0
  69. package/scripts/llm-judge/constants.mjs +66 -0
  70. package/scripts/llm-judge/diff-collection.mjs +74 -0
  71. package/scripts/llm-judge/prompting.mjs +78 -0
  72. package/scripts/llm-judge/providers.mjs +111 -0
  73. package/scripts/llm-judge/verdict.mjs +134 -0
  74. package/scripts/llm-judge.mjs +21 -482
  75. package/scripts/mcp-server/tool-registry.mjs +55 -0
  76. package/scripts/mcp-server/tools.mjs +137 -1
  77. package/scripts/migrate-rule-format/id-prefix-table.mjs +37 -0
  78. package/scripts/migrate-rule-format/parse-legacy.mjs +180 -0
  79. package/scripts/migrate-rule-format/render-new.mjs +169 -0
  80. package/scripts/migrate-rule-format/roundtrip-validate.mjs +89 -0
  81. package/scripts/migrate-rule-format.mjs +192 -0
  82. package/scripts/release-gate/constants.mjs +1 -1
  83. package/scripts/release-gate/static-checks.mjs +1 -1
  84. package/scripts/rules-guardian-audit.mjs +5 -2
  85. package/scripts/single-source-lazy-loading-audit.mjs +2 -1
  86. package/scripts/ui-design-judge/git-input.mjs +3 -0
  87. package/scripts/validate/config.mjs +27 -2
  88. package/scripts/validate/coverage-checks.mjs +1 -1
  89. package/scripts/validate.mjs +94 -1
@@ -1,3 +1,4 @@
1
+ // @file-size-exception: Multiple memory passes (normalize + redact + index + hydrate); planned for split in Phase 1.
1
2
  /**
2
3
  * Cross-agent memory continuity utilities.
3
4
  * Provides provider-agnostic observation normalization, privacy redaction,
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Research-dossier migration helper.
3
+ *
4
+ * Adds the `researchDossier.metadata` block to existing `docs/design-intent.json`
5
+ * files when it is absent, populating `antiRepeatLedger` from the existing
6
+ * conceptual anchor, palette, and motion fields so future UI work cannot
7
+ * unknowingly repeat shipped direction.
8
+ *
9
+ * Idempotent: if the metadata block already exists, the file is left untouched.
10
+ * Additive: never overwrites existing fields.
11
+ */
12
+
13
+ import fs from 'node:fs/promises';
14
+
15
+ import { pathExists } from '../../utils.mjs';
16
+
17
+ const FRESHNESS_WINDOW_DAYS = 90;
18
+ const FRESHNESS_RULE = 'Research dossier is stale when researchVerifiedAt is null or older than freshnessWindowDays. Stale dossiers must run research-design.md before UI implementation. User-explicit redesign requests bypass freshness and force fresh research regardless of age.';
19
+
20
+ function takeFirstNonEmpty(...candidateValues) {
21
+ for (const candidateValue of candidateValues) {
22
+ if (typeof candidateValue === 'string' && candidateValue.trim().length > 0) {
23
+ return candidateValue.trim();
24
+ }
25
+ }
26
+ return null;
27
+ }
28
+
29
+ function buildPreviousAnchorEntry(designIntentContract) {
30
+ const conceptualAnchor = designIntentContract?.conceptualAnchor;
31
+ if (!conceptualAnchor || typeof conceptualAnchor !== 'object') {
32
+ return [];
33
+ }
34
+ const anchorReference = takeFirstNonEmpty(conceptualAnchor.anchorReference);
35
+ if (!anchorReference || anchorReference === 'agent-defined-anchor-reference') {
36
+ return [];
37
+ }
38
+ const specificReferencePoint = takeFirstNonEmpty(conceptualAnchor.specificReferencePoint);
39
+ const summary = specificReferencePoint
40
+ ? `${anchorReference} (${specificReferencePoint})`
41
+ : anchorReference;
42
+ return [{
43
+ summary,
44
+ source: 'migrated-from-existing-design-intent',
45
+ blockedBecause: 'previously-shipped-direction',
46
+ }];
47
+ }
48
+
49
+ function buildPreviousPaletteEntry(designIntentContract) {
50
+ const derivedTokenLogic = designIntentContract?.derivedTokenLogic;
51
+ const colorTruth = designIntentContract?.colorTruth;
52
+ const colorDerivationSummary = takeFirstNonEmpty(derivedTokenLogic?.colorDerivationSource);
53
+ const colorIntent = takeFirstNonEmpty(colorTruth?.intent);
54
+ const summary = takeFirstNonEmpty(colorIntent, colorDerivationSummary);
55
+ if (!summary) {
56
+ return [];
57
+ }
58
+ return [{
59
+ summary,
60
+ source: 'migrated-from-existing-design-intent',
61
+ blockedBecause: 'previously-shipped-palette-behavior',
62
+ }];
63
+ }
64
+
65
+ function buildPreviousMotionEntry(designIntentContract) {
66
+ const motionPaletteDecision = designIntentContract?.motionPaletteDecision;
67
+ const motionSystem = designIntentContract?.motionSystem;
68
+ const derivedTokenLogic = designIntentContract?.derivedTokenLogic;
69
+
70
+ const motionSignature = takeFirstNonEmpty(
71
+ motionPaletteDecision?.signatureMotion,
72
+ motionPaletteDecision?.motion,
73
+ motionSystem?.signature,
74
+ motionSystem?.purpose,
75
+ derivedTokenLogic?.motionBudget,
76
+ );
77
+ if (!motionSignature) {
78
+ return [];
79
+ }
80
+ return [{
81
+ summary: motionSignature,
82
+ source: 'migrated-from-existing-design-intent',
83
+ blockedBecause: 'previously-shipped-motion-signature',
84
+ }];
85
+ }
86
+
87
+ export function buildResearchDossierMetadata({
88
+ designIntentContract = null,
89
+ populateLedgerFromExistingContract = false,
90
+ } = {}) {
91
+ const metadata = {
92
+ researchVerifiedAt: null,
93
+ freshnessWindowDays: FRESHNESS_WINDOW_DAYS,
94
+ freshnessRule: FRESHNESS_RULE,
95
+ antiRepeatLedger: {
96
+ blocklistFromHistory: true,
97
+ ledgerScope: 'signature-level-descriptors-only',
98
+ ledgerMaxEntriesPerCategory: 3,
99
+ previousAnchors: [],
100
+ previousPalettes: [],
101
+ previousMotionSignatures: [],
102
+ },
103
+ userExplicitRedesignBypassesFreshness: true,
104
+ statusAwareValidation: {
105
+ seedStatuses: [
106
+ 'seed-needs-design-synthesis',
107
+ 'seed-generated-during-init',
108
+ 'seed-generated-during-upgrade',
109
+ ],
110
+ seedSkipsDossierShape: true,
111
+ activeRequiresFreshOrExplicitRedesign: true,
112
+ },
113
+ };
114
+
115
+ if (populateLedgerFromExistingContract && designIntentContract && typeof designIntentContract === 'object') {
116
+ metadata.antiRepeatLedger.previousAnchors = buildPreviousAnchorEntry(designIntentContract).slice(0, metadata.antiRepeatLedger.ledgerMaxEntriesPerCategory);
117
+ metadata.antiRepeatLedger.previousPalettes = buildPreviousPaletteEntry(designIntentContract).slice(0, metadata.antiRepeatLedger.ledgerMaxEntriesPerCategory);
118
+ metadata.antiRepeatLedger.previousMotionSignatures = buildPreviousMotionEntry(designIntentContract).slice(0, metadata.antiRepeatLedger.ledgerMaxEntriesPerCategory);
119
+ }
120
+
121
+ return metadata;
122
+ }
123
+
124
+ /**
125
+ * Migrates an existing design-intent.json file in place by adding
126
+ * `researchDossier.metadata` when absent. Idempotent.
127
+ *
128
+ * @param {string} designIntentFilePath
129
+ * @returns {Promise<{ migrated: boolean, reason: string }>}
130
+ */
131
+ export async function migrateExistingDesignIntentToResearchDossierSchema(designIntentFilePath) {
132
+ if (!(await pathExists(designIntentFilePath))) {
133
+ return { migrated: false, reason: 'design-intent-file-absent' };
134
+ }
135
+
136
+ const fileContent = await fs.readFile(designIntentFilePath, 'utf8');
137
+ let designIntentContract;
138
+ try {
139
+ designIntentContract = JSON.parse(fileContent);
140
+ } catch {
141
+ return { migrated: false, reason: 'design-intent-file-not-valid-json' };
142
+ }
143
+
144
+ if (!designIntentContract || typeof designIntentContract !== 'object') {
145
+ return { migrated: false, reason: 'design-intent-file-not-an-object' };
146
+ }
147
+
148
+ const existingResearchDossier = designIntentContract.researchDossier;
149
+ if (existingResearchDossier && typeof existingResearchDossier === 'object' && existingResearchDossier.metadata) {
150
+ return { migrated: false, reason: 'research-dossier-metadata-already-present' };
151
+ }
152
+
153
+ const populatedMetadata = buildResearchDossierMetadata({
154
+ designIntentContract,
155
+ populateLedgerFromExistingContract: true,
156
+ });
157
+
158
+ designIntentContract.researchDossier = {
159
+ ...(existingResearchDossier && typeof existingResearchDossier === 'object' ? existingResearchDossier : {}),
160
+ metadata: populatedMetadata,
161
+ };
162
+
163
+ await fs.writeFile(designIntentFilePath, `${JSON.stringify(designIntentContract, null, 2)}\n`, 'utf8');
164
+ return { migrated: true, reason: 'research-dossier-metadata-injected' };
165
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Audit policy sections of the design intent contract: AI-safe UI audit,
3
+ * production content policy, motion-palette decision contract, and the
4
+ * accessibility policy. These are the gates that fire before UI implementation.
5
+ */
6
+
7
+ export function buildMotionPaletteDecisionSection() {
8
+ return {
9
+ productCategorySignal: 'agent-inferred-starting-heuristic',
10
+ densityDecisionSource: 'Choose motion density from task, content, brand, device, performance, and accessibility. Categories are heuristics.',
11
+ requiredInteractionStates: ['default', 'hover', 'focus-visible', 'active', 'disabled', 'loading', 'empty', 'error', 'success', 'transition'],
12
+ paletteAutopilotRisks: ['dark-slate-default', 'cream-beige-default', 'purple-blue-gradient-default', 'monochrome-template-default', 'uniform-card-surface-default', 'generic-grid-wallpaper-default', 'generic-line-wallpaper-default', 'calibration-mark-wallpaper-default', 'soft-glow-ai-template-default', 'cyber-neon-terminal-default'],
13
+ spatialDecision: 'State 3D/canvas/WebGL fit. If omitted, name product-fit reason and replacement interaction quality.',
14
+ };
15
+ }
16
+
17
+ export function buildAiSafeUiAuditSection({ projectName }) {
18
+ return {
19
+ status: 'agent-must-complete-before-ui-implementation',
20
+ failureDefinition: 'AI-safe UI uses template cards, generic marks, decorative grid or line wallpaper, calibration-mark wallpaper, test/demo/placeholder copy, terminal-only user paths, safe palettes, glow backgrounds, or copied scaffold composition.',
21
+ interchangeabilityTest: `If this UI can be renamed from ${projectName} to another product category without changing composition, palette, iconography, and motion, revise it.`,
22
+ requiredProductSpecificSignals: [
23
+ 'agent-defined-product-specific-data-treatment',
24
+ 'agent-defined-product-specific-motion-or-state-behavior',
25
+ 'agent-defined-product-specific-morphology-iconography-or-spatial-structure',
26
+ ],
27
+ paletteExplorationRule: 'Use a visually exploratory product-derived palette with WCAG contrast and status clarity.',
28
+ backgroundPatternRule: 'Lines, grids, scanlines, noise, glows, blobs, logos, calibration marks, and geometry must serve a named product function; never use grid, line, or calibration-mark backgrounds as first-output filler. Measurement and inspection marks belong to task overlays or controls, not page wallpaper.',
29
+ aiColorAudit: {
30
+ status: 'agent-must-complete-before-ui-implementation',
31
+ failureDefinition: 'AI color drift uses safe defaults before deriving roles from the product anchor.',
32
+ autopilotRisks: ['cream-editorial-default', 'dark-slate-dashboard-default', 'purple-blue-gradient-default', 'monochrome-minimal-default', 'cyber-neon-terminal-default', 'soft-glow-atmosphere-default'],
33
+ requiredEvidence: [
34
+ 'anchor-derived-color-logic',
35
+ 'semantic-role-contrast-beyond-surface-decoration',
36
+ 'product-specific-color-behavior-that-would-not-transfer',
37
+ ],
38
+ reviewQuestion: 'Why does this palette belong to this product?',
39
+ },
40
+ motionSpatialCourageAudit: {
41
+ status: 'agent-must-complete-before-ui-implementation',
42
+ defaultStance: 'Treat motion, scroll choreography, canvas, WebGL, and 3D as first-class options.',
43
+ requiredDecisionFields: [
44
+ 'signature-motion-or-interaction',
45
+ 'spatial-or-3d-fit',
46
+ 'performance-and-reduced-motion-fallback',
47
+ ],
48
+ rejectionRule: 'State a product reason and replacement interaction quality before omitting 3D/canvas. Package count or vague performance fear is not enough.',
49
+ reviewQuestion: 'Is the interaction as expressive as the product can responsibly support?',
50
+ },
51
+ reviewQuestion: 'What visible evidence proves this is product-specific?',
52
+ blockingByDefault: true,
53
+ };
54
+ }
55
+
56
+ export function buildProductionContentPolicySection() {
57
+ return {
58
+ status: 'agent-must-complete-before-ui-implementation',
59
+ userFacingCopyRule: 'Visible UI copy must be product-ready and task-specific. Do not ship testing, demo, sample, placeholder, lorem, TODO, coming soon, or scaffold labels unless they are real product states.',
60
+ terminalDependencyRule: 'User-facing workflows must be operable through the UI unless the product is explicitly a CLI, developer tool, or operational runbook. Terminal commands belong in setup and deployment docs, not as the only path for core user tasks.',
61
+ allowedExceptions: [
62
+ 'test-harness-only',
63
+ 'documented-empty-state',
64
+ 'admin-or-devtool-diagnostic-surface',
65
+ 'explicit-user-requested-prototype',
66
+ ],
67
+ reviewQuestion: 'Can this UI be shipped to real users without removing test/demo copy or terminal-only workflow dependencies?',
68
+ blockingByDefault: true,
69
+ };
70
+ }
71
+
72
+ export function buildAccessibilityPolicySection() {
73
+ return {
74
+ hardComplianceFloor: 'WCAG-2.2-AA',
75
+ advisoryContrastModel: 'APCA',
76
+ failOnHardViolations: true,
77
+ advisoryFindingsDoNotBlockByDefault: true,
78
+ hardRequirements: {
79
+ textContrastMinimum: true,
80
+ nonTextContrast: true,
81
+ useOfColorOnlyProhibited: true,
82
+ focusVisible: true,
83
+ focusAppearance: true,
84
+ targetSizeMinimum: true,
85
+ keyboardAccess: true,
86
+ reflowRequired: true,
87
+ accessibleAuthenticationMinimum: true,
88
+ statusMessagesAndDynamicStateAccess: true,
89
+ },
90
+ advisoryChecks: {
91
+ perceptualContrastReview: true,
92
+ darkModeContrastTuning: true,
93
+ typographyReadabilityTuning: true,
94
+ },
95
+ };
96
+ }
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Conceptual anchor section of the design intent contract. Encodes the rules
3
+ * that force agents to commit to a real-world reference, motion, and typography
4
+ * decision before UI implementation, instead of defaulting to spatial cliches.
5
+ *
6
+ * Carries the Section 3-5 dossier from
7
+ * `.agent-context/prompts/research-design.md`:
8
+ * - categoryCodes (Section 3)
9
+ * - morphologicalExploration (Section 4)
10
+ * - anchorCandidates (Section 5)
11
+ */
12
+
13
+ export function buildConceptualAnchorSection() {
14
+ return {
15
+ mode: 'required-when-no-external-research',
16
+ seedMode: 'selection-policy-only',
17
+ anchorReference: 'agent-defined-anchor-reference',
18
+ researchBrief: '.agent-context/prompts/research-design.md',
19
+ requiresAgentSelectionBeforeUiImplementation: true,
20
+ userResearchAbsencePolicy: {
21
+ userSuppliedResearchOnly: true,
22
+ scaffoldSeedDoesNotCountAsResearch: true,
23
+ priorUiDoesNotCountAsResearch: true,
24
+ requireAgentLedResearchWhenAvailable: true,
25
+ },
26
+ candidateSelectionPolicy: {
27
+ considerAtLeast: 3,
28
+ discardObviousCandidateCount: 2,
29
+ minimumCandidateDistance: 'high',
30
+ discardPredictableCandidates: true,
31
+ preferDistinctiveOverSafe: true,
32
+ doNotRevealHiddenCandidateList: true,
33
+ outputOnlyChosenAnchor: true,
34
+ avoidSpatialPlaceMetaphorByDefault: true,
35
+ preferMechanismOverPlace: true,
36
+ },
37
+ creativeCommitmentPolicy: {
38
+ requiredBeforeComplianceReview: true,
39
+ recordInDesignDocs: true,
40
+ requiredCommitmentFields: [
41
+ 'specificReferencePoint',
42
+ 'signatureMotion',
43
+ 'typographicDecision',
44
+ ],
45
+ rejectGenericQualityWordsOnly: true,
46
+ specificityFloor: 'name-real-material-instrument-artifact-architecture-editorial-genre-cinematic-behavior-exhibition-system-scientific-apparatus-or-industrial-mechanism',
47
+ },
48
+ forbiddenFinalAnchorTerms: [
49
+ 'dashboard',
50
+ 'cards',
51
+ 'admin-panel',
52
+ 'saas-shell',
53
+ 'minimalist-interface',
54
+ 'safe-admin-layout',
55
+ 'room',
56
+ 'darkroom',
57
+ 'counting-room',
58
+ 'control-room',
59
+ 'war-room',
60
+ 'studio',
61
+ 'lab',
62
+ 'cockpit',
63
+ 'command-center',
64
+ ],
65
+ sourceDomains: [
66
+ 'complex-physical-engineering',
67
+ 'cinematic-behavior-and-transition-systems',
68
+ 'experimental-editorial-structure',
69
+ 'scientific-instrumentation',
70
+ 'workflow-and-custody-systems',
71
+ 'material-artifacts-and-instruments',
72
+ 'premium-interactive-web-experiences',
73
+ ],
74
+ visualRiskBudget: {
75
+ mode: 'high-distinctiveness-with-accessibility-and-performance-guardrails',
76
+ allowRichMotionAndMicroInteraction: true,
77
+ rejectTimidDefaultWhenAnchorSupportsExpressiveUi: true,
78
+ rejectDependencyFearAsDownshiftReason: true,
79
+ requireReducedMotionFallback: true,
80
+ },
81
+ literalTranslationPolicy: {
82
+ preferNonLiteralTranslation: true,
83
+ allowedLiteralUse: 'Only use literal anchor artifacts when they serve a named product function, control, state, or task overlay.',
84
+ forbiddenLiteralUse: 'Do not turn anchor artifacts into decorative wallpaper, required chrome, default texture, or unavoidable theme props.',
85
+ },
86
+ spatialAutopilotPolicy: {
87
+ forbiddenHabitTerms: ['room', 'darkroom', 'counting-room', 'control-room', 'war-room', 'studio', 'lab', 'cockpit', 'command-center'],
88
+ allowedOnlyWhen: 'The product has a real physical place model, operational environment, or user workflow that depends on that place metaphor.',
89
+ replacementPreference: 'Use artifacts, custody flows, instruments, data behaviors, material systems, editorial systems, service rituals, or interaction mechanisms.',
90
+ reviewQuestion: 'Could this anchor still work if the word "room" was removed? If not, revise before UI code.',
91
+ },
92
+ requiredDerivedAxes: [
93
+ 'typography',
94
+ 'morphology',
95
+ 'motion',
96
+ 'responsive-composition',
97
+ ],
98
+ categoryCodes: {
99
+ mode: 'agent-must-complete-before-ui-implementation',
100
+ blockingByDefault: true,
101
+ researchBriefSection: 'Section 3',
102
+ researchBriefPath: '.agent-context/prompts/research-design.md',
103
+ minimumEntries: 3,
104
+ specificityRule: 'A category code is only valid if a reader unfamiliar with the project can visualize a specific aesthetic direction from the text alone, without seeing the UI and without knowing the product name.',
105
+ antiLeakageRule: 'Listing a cliche identifies a trap; it does not endorse an aesthetic. Examples in the brief are NOT target aesthetics for any project. Each category code must carry an explicit rejection note so the cliche cannot quietly become the target.',
106
+ failingExamples: [
107
+ 'clean typography (too abstract, applies to anything)',
108
+ 'modern color palette (not falsifiable)',
109
+ 'smooth animations (describes nothing specific)',
110
+ ],
111
+ passingExamples: [
112
+ "children's storybook illustration site: hand-painted gouache textures with irregular hand-lettered titles, off-grid spreads with whitespace gutters, page-turn pacing rather than scroll (instantly recognizable as kids book category default)",
113
+ 'luxury car configurator: full-bleed monochrome photography on black, ultra-thin sans-serif tracked wide, slow horizontal scroll with locked vertical alignment, micro-counters that tick instead of slide (instantly recognizable as luxury auto category default)',
114
+ 'academic philosophy journal: high-contrast black-on-cream, book-class serif body at 11pt with generous leading, footnote markers with hover panels, numbered table-of-contents navigation, no hero imagery (instantly recognizable as academic journal category default)',
115
+ ],
116
+ passingExamplesPolicy: 'These examples illustrate the description format only. They are AI-defaultable cliches of their categories and must NOT be adopted as target aesthetics for any project.',
117
+ commonAiSafeClichesToReject: [
118
+ 'dev-tool default: condensed tabular numerics with minimal chrome and monospace code blocks on dark slate background, sans-serif metadata at 11-12px, monochrome status dots, single-line settings rows',
119
+ 'AI-startup landing default: purple-to-pink gradient hero with floating 3D glass cards, sans-serif display type at 700-900 weight, vague hero copy, three-up feature grid below the fold',
120
+ 'health/wellness app default: mint accent on white surface with coral status indicators, rounded pill-shaped buttons, friendly sans-serif at high weight, soft drop shadows on cards',
121
+ 'SaaS admin default: left-side icon-only nav, top utility bar, three-card KPI row above a single data table, neutral grey-on-white with one accent color, modal-driven detail flows',
122
+ 'marketing site default: hero image with one-line headline plus subhead, three feature tiles below, two pricing tiers, testimonial carousel, footer link grid',
123
+ ],
124
+ commonAiSafeClichesPolicy: 'If the project sits anywhere near one of these AI-safe defaults, the matching cliche must appear in candidateEntries with an explicit rejection note. Software products pattern-match one of these without intervention; naming the trap is required even when the trap is uncomfortable to admit.',
125
+ selfTestRule: 'Read each category code aloud to someone unfamiliar with the project. If they cannot visualize a specific aesthetic direction from the text alone, the code is too abstract; revise. If they say "that is basically the X cliche", the description is specific enough; the cliche then belongs on the reject list with a rejection note, not as a candidate target.',
126
+ requiredFieldsPerEntry: [
127
+ 'description',
128
+ 'specificityEvidence',
129
+ 'categoryDefaultReason',
130
+ 'rejectionNote',
131
+ ],
132
+ forbiddenPlaceholderPhrases: [
133
+ 'clean typography',
134
+ 'modern color palette',
135
+ 'smooth animations',
136
+ 'best practices',
137
+ 'good design',
138
+ ],
139
+ candidateEntries: [],
140
+ },
141
+ morphologicalExploration: {
142
+ mode: 'agent-must-complete-before-ui-implementation',
143
+ blockingByDefault: true,
144
+ researchBriefSection: 'Section 4',
145
+ researchBriefPath: '.agent-context/prompts/research-design.md',
146
+ requiredMatrixShape: '5x5-or-6x5',
147
+ minimumDimensions: 5,
148
+ maximumDimensions: 6,
149
+ valuesPerDimension: 5,
150
+ forbidCategoryCodeValuesInMatrix: true,
151
+ requireSelectedCombination: true,
152
+ requireUncomfortableCombination: true,
153
+ uncomfortableCombinationRule: 'Highlight at least one combination that feels instinctively wrong or uncomfortable but can be argued with product logic. The uncomfortable combination proves the matrix actually spans the design space; if every combination feels safe, shippable, and unobjectionable, the matrix is clustering in the safe-creative zone.',
154
+ uncomfortableCombinationRequiredFields: [
155
+ 'combinationLabel',
156
+ 'discomfortReason',
157
+ 'productLogicJustification',
158
+ ],
159
+ widenDimensionsWhenUncomfortableCombinationCannotBeProduced: true,
160
+ seedDimensions: [],
161
+ seedMatrix: [],
162
+ selectedCombination: null,
163
+ uncomfortableCombination: null,
164
+ },
165
+ anchorCandidates: {
166
+ mode: 'agent-must-complete-before-ui-implementation',
167
+ blockingByDefault: true,
168
+ researchBriefSection: 'Section 5',
169
+ researchBriefPath: '.agent-context/prompts/research-design.md',
170
+ requiredCandidateCount: 5,
171
+ requiredFieldsPerCandidate: [
172
+ 'anchorReference',
173
+ 'conceptualFamily',
174
+ 'jobFit',
175
+ 'hierarchyImplication',
176
+ 'densityImplication',
177
+ 'typeImplication',
178
+ 'stateLanguage',
179
+ 'motionImplication',
180
+ 'whatItRulesOut',
181
+ 'renameTest',
182
+ 'categoryCodeOverlap',
183
+ ],
184
+ renameTest: {
185
+ mode: 'strengthened',
186
+ requiredTestCategoryCount: 3,
187
+ testCategoryDistanceRule: 'The three test categories must be remote from each other and from the actual product (for example, if the product is a health app, test against fintech dashboard, kids educational game, and industrial equipment monitoring console).',
188
+ testCategoryFreshnessRule: 'Pick fresh test categories per anchor. Reusing the same triple across every anchor lets the agent memorize the pass condition instead of stress-testing the anchor. The illustrative triple in testCategoryDistanceRule is not a fixed test set.',
189
+ verdictScoring: {
190
+ 'STRONG PASS': 'UI still coherent in 0 of 3 renamed categories.',
191
+ PASS: 'UI still coherent in 1 of 3. Pass with note.',
192
+ REVISE: 'UI still coherent in 2 of 3. Anchor is too generic. Revise the anchor to add product-specific constraints until it fails in at least 2 of 3.',
193
+ DISCARD: 'UI still coherent in 3 of 3. Anchor is category-agnostic. Discard immediately.',
194
+ },
195
+ requireTestCategoriesRecordedInDossier: true,
196
+ auditableByHumanReviewer: true,
197
+ renameTestRequiredFields: [
198
+ 'testCategories',
199
+ 'results',
200
+ 'verdict',
201
+ ],
202
+ },
203
+ categoryCodeOverlapRule: 'List any Section 3 category codes this candidate accidentally inherits, with reasoning.',
204
+ forbiddenSelectedVerdicts: ['DISCARD'],
205
+ requiredSelectedVerdicts: ['STRONG PASS', 'PASS'],
206
+ candidates: [],
207
+ },
208
+ finalAnchorContract: {
209
+ requiredFields: [
210
+ 'name',
211
+ 'anchorReference',
212
+ 'agentResearchMode',
213
+ 'sourceDomain',
214
+ 'specificReferencePoint',
215
+ 'rationale',
216
+ 'signatureMotion',
217
+ 'typographicDecision',
218
+ 'derivedTokenLogic',
219
+ 'visualRiskBudget',
220
+ 'motionRiskBudget',
221
+ 'cohesionChecks',
222
+ ],
223
+ derivedTokenLogicAxes: [
224
+ 'morphology',
225
+ 'motion',
226
+ ],
227
+ cohesionChecks: [
228
+ 'no-dashboard-mental-model',
229
+ 'motion-derived-from-anchor',
230
+ ],
231
+ },
232
+ };
233
+ }