@ryuenn3123/agentic-senior-core 4.3.14 → 4.4.0

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 (25) hide show
  1. package/.agent-context/prompts/init-project.md +1 -1
  2. package/.agent-context/prompts/refactor.md +1 -0
  3. package/.agent-context/review-checklists/pr-checklist.md +1 -3
  4. package/.agent-context/rules/architecture.md +5 -0
  5. package/AGENTS.md +67 -115
  6. package/bin/agentic-senior-core.js +2 -5
  7. package/lib/cli/adaptive-context/catalog.mjs +4 -0
  8. package/lib/cli/adaptive-context.mjs +87 -301
  9. package/lib/cli/compiler.mjs +6 -389
  10. package/lib/cli/token-optimization.mjs +4 -89
  11. package/package.json +2 -9
  12. package/scripts/context-triggered-audit.mjs +1 -1
  13. package/scripts/{audit-cache-layer-contract.mjs → validate/audits/cache-layer-contract.mjs} +4 -37
  14. package/scripts/{audit-caching-scope-hygiene.mjs → validate/audits/caching-scope-hygiene.mjs} +1 -34
  15. package/scripts/{audit-file-size.mjs → validate/audits/file-size.mjs} +1 -62
  16. package/scripts/{audit-reflection-citations.mjs → validate/audits/reflection-citations.mjs} +2 -35
  17. package/scripts/{audit-release-bundle.mjs → validate/audits/release-bundle.mjs} +1 -36
  18. package/scripts/{audit-rule-id-uniqueness.mjs → validate/audits/rule-id-uniqueness.mjs} +1 -36
  19. package/scripts/validate/config.mjs +0 -18
  20. package/scripts/validate/file-structure.mjs +0 -4
  21. package/scripts/validate/utils.mjs +52 -0
  22. package/scripts/validate.mjs +10 -81
  23. package/lib/cli/audits/typography-palette-anti-repeat-audit.mjs +0 -239
  24. package/lib/cli/commands/audit-design-anti-repeat.mjs +0 -39
  25. package/scripts/audit-typography-palette-anti-repeat.mjs +0 -120
@@ -1,239 +0,0 @@
1
- // @ts-check
2
-
3
- /**
4
- * Typography and palette anti-repeat audit.
5
- *
6
- * Scans CSS-like files for font-family declarations and color values, then
7
- *
8
- * DEPRECATED: This audit was built for the legacy design-intent.json system
9
- * and its machine-readable antiRepeatLedger. In the 2026 Context Ops Paradigm,
10
- * anti-repeat checks are handled by the LLM reading docs/DESIGN.md's
11
- * "Previous Directions" blocklist. This audit now unconditionally skips.
12
- * - Typography matches are EXACT family-name matches and are always
13
- * blocking (kind: typography.previously-shipped-family,
14
- * diagnosticCode: BOUNDARY_TYPOGRAPHY_LEDGER_VIOLATION).
15
- * - Palette matches are HEURISTIC. OKLCH-to-OKLCH distance is perceptually
16
- * uniform (deltaE < threshold => match). Hex-to-hex matches are exact
17
- * normalized equality. Cross-type matches (hex declared in CSS vs OKLCH
18
- * in the ledger, or vice versa) are NOT performed; reporting cross-type
19
- * would require a color-space conversion that is its own correctness
20
- * surface (tracked in docs/deep-analysis-and-roadmap-backlog.md).
21
- * - Palette findings BLOCK by default with kind:
22
- * palette.previously-shipped-color and diagnosticCode:
23
- * BOUNDARY_PALETTE_LEDGER_VIOLATION. Pass
24
- * `treatPaletteAsAdvisory: true` (or `--palette-advisory` on the CLI)
25
- * to opt a project into advisory-only palette reporting; severity drops
26
- * to "advisory" and the diagnostic code becomes
27
- * BOUNDARY_PALETTE_LEDGER_ADVISORY. Use the advisory mode only when a
28
- * project knowingly accepts the false-positive risk of OKLCH distance
29
- * matching at its chosen threshold.
30
- */
31
-
32
- import { existsSync, readFileSync } from 'node:fs';
33
- import { join, relative } from 'node:path';
34
-
35
- import {
36
- collectScannableFilePaths,
37
- lineNumberFromIndex,
38
- } from './typography-palette-anti-repeat/file-scanner.mjs';
39
- import {
40
- extractFontFamiliesFromText,
41
- extractLedgerTypographyFamilies,
42
- } from './typography-palette-anti-repeat/typography-utils.mjs';
43
- import {
44
- extractColorOccurrencesFromText,
45
- extractLedgerColors,
46
- oklchPerceptualDistance,
47
- } from './typography-palette-anti-repeat/color-utils.mjs';
48
-
49
- const DEFAULT_OKLCH_DISTANCE_THRESHOLD = 0.04;
50
-
51
- function findTypographyViolationsForFile({ relativeFilePath, sourceText, ledgerFamilies }) {
52
- const violations = [];
53
- const fontFamilyOccurrences = extractFontFamiliesFromText(sourceText);
54
- for (const familyOccurrence of fontFamilyOccurrences) {
55
- const ledgerEntry = ledgerFamilies.get(familyOccurrence.family);
56
- if (!ledgerEntry) {
57
- continue;
58
- }
59
- violations.push({
60
- file: relativeFilePath,
61
- line: lineNumberFromIndex(sourceText, familyOccurrence.index),
62
- kind: 'typography.previously-shipped-family',
63
- severity: 'blocking',
64
- diagnosticCode: 'BOUNDARY_TYPOGRAPHY_LEDGER_VIOLATION',
65
- detail: `CSS declares font-family "${familyOccurrence.family}" which appears in researchDossier.metadata.antiRepeatLedger.previousTypographyChoices ("${ledgerEntry.summary}"). Either escape the previously-shipped trio, or set derivedTokenLogic.tokenContinuityClassification.typography to continuity-retained with explicit rationale.`,
66
- });
67
- }
68
- return violations;
69
- }
70
-
71
- function buildHexAdvisory({ relativeFilePath, sourceText, colorOccurrence, ledgerColor, paletteSeverity, paletteDiagnosticCode }) {
72
- return {
73
- file: relativeFilePath,
74
- line: lineNumberFromIndex(sourceText, colorOccurrence.index),
75
- kind: 'palette.previously-shipped-color',
76
- severity: paletteSeverity,
77
- diagnosticCode: paletteDiagnosticCode,
78
- detail: `CSS hex "${colorOccurrence.raw}" matches a hex color in researchDossier.metadata.antiRepeatLedger.previousPalettes ("${ledgerColor.sourceEntry.summary}"). Either escape the previously-shipped palette or set derivedTokenLogic.tokenContinuityClassification.palette to continuity-retained with explicit rationale.`,
79
- };
80
- }
81
-
82
- function buildOklchAdvisory({ relativeFilePath, sourceText, colorOccurrence, ledgerColor, perceptualDistance, oklchDistanceThreshold, paletteSeverity, paletteDiagnosticCode }) {
83
- return {
84
- file: relativeFilePath,
85
- line: lineNumberFromIndex(sourceText, colorOccurrence.index),
86
- kind: 'palette.previously-shipped-color',
87
- severity: paletteSeverity,
88
- diagnosticCode: paletteDiagnosticCode,
89
- detail: `CSS OKLCH "${colorOccurrence.raw}" is within ${perceptualDistance.toFixed(4)} of an OKLCH color in researchDossier.metadata.antiRepeatLedger.previousPalettes ("${ledgerColor.sourceEntry.summary}") (threshold ${oklchDistanceThreshold}). Heuristic match on perceptually-uniform OKLCH distance; either escape the previously-shipped palette, raise the threshold via --threshold, or set derivedTokenLogic.tokenContinuityClassification.palette to continuity-retained with explicit rationale.`,
90
- };
91
- }
92
-
93
- function findPaletteFindingsForFile({ relativeFilePath, sourceText, ledgerColors, oklchDistanceThreshold, paletteSeverity, paletteDiagnosticCode }) {
94
- const findings = [];
95
- const colorOccurrences = extractColorOccurrencesFromText(sourceText);
96
- for (const colorOccurrence of colorOccurrences) {
97
- for (const ledgerColor of ledgerColors) {
98
- if (colorOccurrence.kind === 'hex' && ledgerColor.kind === 'hex') {
99
- if (
100
- colorOccurrence.normalized
101
- && ledgerColor.normalized
102
- && colorOccurrence.normalized === ledgerColor.normalized
103
- ) {
104
- findings.push(buildHexAdvisory({
105
- relativeFilePath, sourceText, colorOccurrence, ledgerColor,
106
- paletteSeverity, paletteDiagnosticCode,
107
- }));
108
- }
109
- continue;
110
- }
111
- if (colorOccurrence.kind === 'oklch' && ledgerColor.kind === 'oklch' && colorOccurrence.oklch && ledgerColor.oklch) {
112
- const perceptualDistance = oklchPerceptualDistance(colorOccurrence.oklch, ledgerColor.oklch);
113
- if (perceptualDistance <= oklchDistanceThreshold) {
114
- findings.push(buildOklchAdvisory({
115
- relativeFilePath, sourceText, colorOccurrence, ledgerColor, perceptualDistance, oklchDistanceThreshold,
116
- paletteSeverity, paletteDiagnosticCode,
117
- }));
118
- }
119
- }
120
- // Cross-type (hex declared vs OKLCH ledger or vice versa) is intentionally
121
- // skipped here; reporting cross-type would require a color-space conversion
122
- // pass that is its own correctness surface. Tracked in
123
- // docs/deep-analysis-and-roadmap-backlog.md.
124
- }
125
- }
126
- return findings;
127
- }
128
-
129
- function loadDesignIntentContract() {
130
- return { contract: null, reason: 'design-intent-deprecated-use-design-md-blocklist' };
131
- }
132
-
133
- function buildSkippedReport(reportShell, reason) {
134
- return {
135
- ...reportShell,
136
- passed: true,
137
- skipped: true,
138
- reason,
139
- filesScanned: 0,
140
- typographyViolationCount: 0,
141
- paletteFindingCount: 0,
142
- typographyViolations: [],
143
- paletteFindings: [],
144
- };
145
- }
146
-
147
- /**
148
- * Runs the typography and palette anti-repeat audit.
149
- *
150
- * @param {object} [auditOptions]
151
- * @param {string} [auditOptions.repositoryRootPath]
152
- * @param {string[]} [auditOptions.scanRoots]
153
- * @param {string} [auditOptions.designIntentRelativePath]
154
- * @param {number} [auditOptions.oklchDistanceThreshold]
155
- * @param {boolean} [auditOptions.treatPaletteAsAdvisory]
156
- */
157
- export function runTypographyPaletteAntiRepeatAudit(auditOptions = {}) {
158
- const repositoryRootPath = auditOptions.repositoryRootPath || process.cwd();
159
- const scanRoots = Array.isArray(auditOptions.scanRoots) && auditOptions.scanRoots.length > 0
160
- ? auditOptions.scanRoots
161
- : ['.'];
162
- const designIntentRelativePath = auditOptions.designIntentRelativePath || 'docs/design-intent.json';
163
- const oklchDistanceThreshold = typeof auditOptions.oklchDistanceThreshold === 'number'
164
- ? auditOptions.oklchDistanceThreshold
165
- : DEFAULT_OKLCH_DISTANCE_THRESHOLD;
166
- const treatPaletteAsAdvisory = auditOptions.treatPaletteAsAdvisory === true;
167
- const paletteSeverity = treatPaletteAsAdvisory ? 'advisory' : 'blocking';
168
- const paletteDiagnosticCode = treatPaletteAsAdvisory
169
- ? 'BOUNDARY_PALETTE_LEDGER_ADVISORY'
170
- : 'BOUNDARY_PALETTE_LEDGER_VIOLATION';
171
-
172
- const reportShell = {
173
- auditName: 'audit-typography-palette-anti-repeat',
174
- reportVersion: '2.0.0',
175
- generatedAt: new Date().toISOString(),
176
- designIntentRelativePath,
177
- paletteSeverity,
178
- paletteDiagnosticCode,
179
- oklchDistanceThreshold,
180
- scope: {
181
- typographyMatching: 'exact-family-name-after-normalization',
182
- paletteHexMatching: 'exact-hex-after-7-digit-normalization',
183
- paletteOklchMatching: 'l*c*h-distance-under-threshold',
184
- paletteCrossTypeMatching: 'not-supported-color-conversion-out-of-scope',
185
- paletteCrossTypeMatchingTrackedIn: 'docs/deep-analysis-and-roadmap-backlog.md',
186
- },
187
- };
188
-
189
- const designIntentLoad = loadDesignIntentContract();
190
- if (!designIntentLoad.contract) {
191
- return buildSkippedReport(reportShell, designIntentLoad.reason);
192
- }
193
- if (!antiRepeatLedger || typeof antiRepeatLedger !== 'object') {
194
- return buildSkippedReport(reportShell, 'anti-repeat-ledger-absent');
195
- }
196
-
197
- const ledgerFamilies = extractLedgerTypographyFamilies(antiRepeatLedger);
198
- const ledgerColors = extractLedgerColors(antiRepeatLedger);
199
- const scannableFilePaths = collectScannableFilePaths(repositoryRootPath, scanRoots);
200
-
201
- /** @type {any[]} */
202
- const typographyViolations = [];
203
- /** @type {any[]} */
204
- const paletteFindings = [];
205
-
206
- for (const absoluteFilePath of scannableFilePaths) {
207
- const relativeFilePath = relative(repositoryRootPath, absoluteFilePath).replace(/\\/g, '/');
208
- let sourceText;
209
- try {
210
- sourceText = readFileSync(absoluteFilePath, 'utf8');
211
- } catch {
212
- continue;
213
- }
214
- if (ledgerFamilies.size > 0) {
215
- typographyViolations.push(...findTypographyViolationsForFile({
216
- relativeFilePath, sourceText, ledgerFamilies,
217
- }));
218
- }
219
- if (ledgerColors.length > 0) {
220
- paletteFindings.push(...findPaletteFindingsForFile({
221
- relativeFilePath, sourceText, ledgerColors, oklchDistanceThreshold,
222
- paletteSeverity, paletteDiagnosticCode,
223
- }));
224
- }
225
- }
226
-
227
- const blockingViolationCount = typographyViolations.length + (treatPaletteAsAdvisory ? 0 : paletteFindings.length);
228
-
229
- return {
230
- ...reportShell,
231
- passed: blockingViolationCount === 0,
232
- skipped: false,
233
- filesScanned: scannableFilePaths.length,
234
- typographyViolationCount: typographyViolations.length,
235
- paletteFindingCount: paletteFindings.length,
236
- typographyViolations,
237
- paletteFindings,
238
- };
239
- }
@@ -1,39 +0,0 @@
1
- // @ts-check
2
-
3
- /**
4
- * `agentic-senior-core audit:design-anti-repeat`
5
- *
6
- * [DEPRECATED in 2026 Context Ops Paradigm]
7
- * This script is retired because the anti-repeat ledger is now maintained
8
- * as plain-text inside docs/DESIGN.md. The Adaptive Context AI agent enforces
9
- * this naturally without needing regex-based JSON compliance theater.
10
- */
11
-
12
- export async function runDesignAntiRepeatAuditCommand(commandLineArgs = []) {
13
- if (commandLineArgs.includes('--json')) {
14
- process.stdout.write(JSON.stringify({
15
- passed: true,
16
- skipped: true,
17
- reason: 'audit-design-anti-repeat is deprecated in Context Ops 2026. Plain text ledgers in DESIGN.md are handled by the agent contextually.',
18
- targetDirectoryPath: process.cwd(),
19
- filesScanned: 0,
20
- typographyViolationCount: 0,
21
- paletteFindingCount: 0,
22
- paletteSeverity: 'advisory',
23
- oklchDistanceThreshold: 0.04,
24
- typographyViolations: [],
25
- paletteFindings: []
26
- }, null, 2) + '\n');
27
- return 0;
28
- }
29
-
30
- console.log('===============================================');
31
- console.log(' audit:design-anti-repeat (DEPRECATED)');
32
- console.log('===============================================');
33
- console.log(' Audit skipped: audit-design-anti-repeat is retired in Context Ops 2026.');
34
- console.log(' Plain text ledgers in docs/DESIGN.md are handled by the agent contextually.');
35
- console.log(' You can safely remove this check from your CI pipeline.');
36
- console.log('');
37
-
38
- return 0;
39
- }
@@ -1,120 +0,0 @@
1
- #!/usr/bin/env node
2
- // @ts-check
3
-
4
- /**
5
- * audit-typography-palette-anti-repeat.mjs
6
- *
7
- * Thin CLI wrapper around lib/cli/audits/typography-palette-anti-repeat-audit.mjs.
8
- * The wrapper defaults to scanning the current working directory so it works
9
- * for both repo-internal `npm run audit:typography-palette-anti-repeat` (npm
10
- * sets cwd to the repo root) and direct invocation from a user project. The
11
- * user-facing entry point is the `audit:design-anti-repeat` subcommand on
12
- * the published bin (see lib/cli/commands/audit-design-anti-repeat.mjs).
13
- *
14
- * Usage:
15
- * node scripts/audit-typography-palette-anti-repeat.mjs
16
- * node scripts/audit-typography-palette-anti-repeat.mjs --json
17
- * node scripts/audit-typography-palette-anti-repeat.mjs --palette-advisory
18
- * node scripts/audit-typography-palette-anti-repeat.mjs --threshold 0.05
19
- * node scripts/audit-typography-palette-anti-repeat.mjs --root /path/to/project
20
- *
21
- * Default severity:
22
- * - Typography matches always block.
23
- * - Palette matches block by default. Pass --palette-advisory to opt a
24
- * project into advisory-only palette reporting (release stays unblocked
25
- * by palette findings; typography still blocks).
26
- *
27
- * Exit codes:
28
- * 0 = no blocking violations
29
- * 1 = at least one BOUNDARY_TYPOGRAPHY_LEDGER_VIOLATION or, in default
30
- * mode, BOUNDARY_PALETTE_LEDGER_VIOLATION
31
- */
32
-
33
- import { resolve } from 'node:path';
34
-
35
- import { runTypographyPaletteAntiRepeatAudit } from '../lib/cli/audits/typography-palette-anti-repeat-audit.mjs';
36
-
37
- const COMMAND_LINE_ARGS = process.argv.slice(2);
38
- const SHOULD_OUTPUT_JSON_ONLY = COMMAND_LINE_ARGS.includes('--json');
39
- const SHOULD_TREAT_PALETTE_AS_ADVISORY = COMMAND_LINE_ARGS.includes('--palette-advisory');
40
-
41
- function readStringFlag(flagName) {
42
- const flagIndex = COMMAND_LINE_ARGS.indexOf(flagName);
43
- if (flagIndex === -1) {
44
- return null;
45
- }
46
- const flagValue = COMMAND_LINE_ARGS[flagIndex + 1];
47
- if (typeof flagValue !== 'string' || flagValue.length === 0 || flagValue.startsWith('--')) {
48
- return null;
49
- }
50
- return flagValue;
51
- }
52
-
53
- function readNumericFlag(flagName) {
54
- const stringValue = readStringFlag(flagName);
55
- if (stringValue === null) {
56
- return null;
57
- }
58
- const numericValue = Number(stringValue);
59
- return Number.isFinite(numericValue) ? numericValue : null;
60
- }
61
-
62
- function main() {
63
- const oklchDistanceThreshold = readNumericFlag('--threshold');
64
- const explicitRootPath = readStringFlag('--root');
65
- const repositoryRootPath = resolve(explicitRootPath || process.cwd());
66
-
67
- const auditReport = runTypographyPaletteAntiRepeatAudit({
68
- repositoryRootPath,
69
- treatPaletteAsAdvisory: SHOULD_TREAT_PALETTE_AS_ADVISORY,
70
- ...(typeof oklchDistanceThreshold === 'number' ? { oklchDistanceThreshold } : {}),
71
- });
72
-
73
- if (SHOULD_OUTPUT_JSON_ONLY) {
74
- process.stdout.write(`${JSON.stringify({ ...auditReport, repositoryRootPath }, null, 2)}\n`);
75
- process.exit(auditReport.passed ? 0 : 1);
76
- }
77
-
78
- console.log('===============================================');
79
- console.log(' audit:typography-palette-anti-repeat');
80
- console.log('===============================================');
81
- console.log(` Target directory: ${repositoryRootPath}`);
82
- console.log(` Files scanned: ${auditReport.filesScanned}`);
83
- console.log(` Typography violations: ${auditReport.typographyViolationCount} (blocking)`);
84
- console.log(` Palette findings: ${auditReport.paletteFindingCount} (${auditReport.paletteSeverity})`);
85
- console.log(` OKLCH distance threshold: ${auditReport.oklchDistanceThreshold}`);
86
- console.log('');
87
-
88
- if (auditReport.skipped) {
89
- console.log(` Audit skipped: ${auditReport.reason}`);
90
- process.exit(0);
91
- }
92
-
93
- if (auditReport.typographyViolations.length > 0) {
94
- console.log(' Typography violations (blocking):');
95
- for (const violation of auditReport.typographyViolations) {
96
- console.log(` [${violation.kind}] ${violation.file}:${violation.line} ${violation.detail}`);
97
- }
98
- console.log('');
99
- }
100
-
101
- if (auditReport.paletteFindings.length > 0) {
102
- console.log(` Palette findings (${auditReport.paletteSeverity}):`);
103
- for (const finding of auditReport.paletteFindings) {
104
- console.log(` [${finding.kind}] ${finding.file}:${finding.line} ${finding.detail}`);
105
- }
106
- console.log('');
107
- }
108
-
109
- if (auditReport.passed) {
110
- console.log(' No blocking violations against the anti-repeat ledger.');
111
- process.exit(0);
112
- }
113
- const blockingPaletteCount = auditReport.paletteSeverity === 'blocking' ? auditReport.paletteFindingCount : 0;
114
- console.log(` ${auditReport.typographyViolationCount} typography violation(s) and ${blockingPaletteCount} palette violation(s) found; release blocked.`);
115
- process.exit(1);
116
- }
117
-
118
- if (process.argv[1] && (import.meta.url === `file://${process.argv[1].replace(/\\/g, '/')}` || process.argv[1].endsWith('audit-typography-palette-anti-repeat.mjs'))) {
119
- main();
120
- }