@ryuenn3123/agentic-senior-core 3.0.37 → 3.0.38
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 +108 -146
- package/.agent-context/rules/frontend-architecture.md +92 -108
- package/.agent-context/state/README.md +26 -0
- package/.cursor/mcp.json +10 -0
- package/.cursor/rules/agentic-senior-core.mdc +48 -0
- package/.cursorrules +22 -88
- package/.gemini/instructions.md +25 -16
- package/.github/copilot-instructions.md +25 -16
- package/.github/instructions/agentic-senior-core.instructions.md +47 -0
- package/.instructions.md +98 -207
- package/.windsurf/rules/agentic-senior-core.md +43 -0
- package/.windsurfrules +22 -88
- package/AGENTS.md +23 -26
- package/CLAUDE.md +43 -0
- package/CONTRIBUTING.md +5 -2
- package/GEMINI.md +43 -0
- package/README.md +24 -7
- package/lib/cli/backup.mjs +4 -4
- package/lib/cli/commands/init/project-context.mjs +101 -0
- package/lib/cli/commands/init/runtime-environment.mjs +59 -0
- package/lib/cli/commands/init/setup-decisions.mjs +83 -0
- package/lib/cli/commands/init.mjs +33 -250
- package/lib/cli/commands/optimize.mjs +1 -1
- package/lib/cli/commands/upgrade.mjs +32 -7
- package/lib/cli/compiler.mjs +59 -17
- package/lib/cli/constants.mjs +5 -0
- package/lib/cli/detector.mjs +4 -0
- package/lib/cli/preflight.mjs +3 -3
- package/lib/cli/project-scaffolder/design-contract/validation.mjs +789 -0
- package/lib/cli/project-scaffolder/design-contract.mjs +119 -924
- package/lib/cli/project-scaffolder/prompt-builders.mjs +69 -84
- package/lib/cli/utils/filesystem.mjs +79 -0
- package/lib/cli/utils/managed-surface.mjs +237 -0
- package/lib/cli/utils/prompting.mjs +44 -0
- package/lib/cli/utils.mjs +33 -335
- package/package.json +21 -2
- package/scripts/clean-local-artifacts.mjs +76 -0
- package/scripts/docs-quality-drift-report.mjs +5 -0
- package/scripts/frontend-usability-audit.mjs +23 -19
- package/scripts/governance-weekly-report.mjs +37 -15
- package/scripts/single-source-lazy-loading-audit.mjs +24 -0
- package/scripts/sync-thin-adapters.mjs +99 -129
- package/scripts/v3-purge-audit.mjs +5 -0
- package/scripts/validate/config.mjs +10 -0
- package/scripts/validate/coverage-checks.mjs +55 -0
- package/.agent-context/marketplace/trust-tiers.json +0 -114
- package/.agent-context/state/benchmark-analysis.json +0 -431
- package/.agent-context/state/benchmark-evidence-bundle.json +0 -1040
- package/.agent-context/state/benchmark-history.json +0 -75
- package/.agent-context/state/benchmark-trend-report.csv +0 -5
- package/.agent-context/state/benchmark-trend-report.json +0 -140
- package/.agent-context/state/benchmark-writer-judge-matrix.json +0 -462
- package/.agent-context/state/memory-continuity-benchmark.json +0 -132
- package/.agent-context/state/onboarding-report.json +0 -102
- package/.agent-context/state/quality-trend-report.json +0 -89
- package/.agent-context/state/token-optimization-benchmark.json +0 -130
- package/.agent-context/state/weekly-governance-report.json +0 -329
- package/lib/cli/compatibility.mjs +0 -124
|
@@ -253,7 +253,7 @@ function collectCommitSignals(windowDays) {
|
|
|
253
253
|
};
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
async function
|
|
256
|
+
async function collectGovernanceSurfaceTrustSignals() {
|
|
257
257
|
const trustRows = [];
|
|
258
258
|
const tierCounts = {
|
|
259
259
|
verified: 0,
|
|
@@ -265,8 +265,8 @@ async function collectSkillTrustSignals() {
|
|
|
265
265
|
return leftName.localeCompare(rightName);
|
|
266
266
|
});
|
|
267
267
|
|
|
268
|
-
for (const
|
|
269
|
-
const relativeSurfacePath = GOVERNANCE_SURFACE_PATHS[
|
|
268
|
+
for (const surfaceDomainName of sortedDomainNames) {
|
|
269
|
+
const relativeSurfacePath = GOVERNANCE_SURFACE_PATHS[surfaceDomainName];
|
|
270
270
|
const absoluteSurfacePath = join(REPOSITORY_ROOT, relativeSurfacePath);
|
|
271
271
|
const surfaceExists = existsSync(absoluteSurfacePath);
|
|
272
272
|
const trustTier = surfaceExists ? 'verified' : 'experimental';
|
|
@@ -277,7 +277,7 @@ async function collectSkillTrustSignals() {
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
trustRows.push({
|
|
280
|
-
domain:
|
|
280
|
+
domain: surfaceDomainName,
|
|
281
281
|
tier: trustTier,
|
|
282
282
|
score: trustScore,
|
|
283
283
|
sourcePath: relativeSurfacePath,
|
|
@@ -297,8 +297,8 @@ async function collectSkillTrustSignals() {
|
|
|
297
297
|
};
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
-
function buildBackendGovernancePosture(
|
|
301
|
-
const backendSurfaceRows =
|
|
300
|
+
function buildBackendGovernancePosture(governanceSurfaceTrustSignals) {
|
|
301
|
+
const backendSurfaceRows = governanceSurfaceTrustSignals.domains.filter((trustRow) => {
|
|
302
302
|
return BACKEND_REQUIRED_DOMAIN_NAMES.has(trustRow.domain);
|
|
303
303
|
});
|
|
304
304
|
const missingBackendSurfaceNames = backendSurfaceRows
|
|
@@ -328,7 +328,7 @@ function buildBackendGovernancePosture(skillTrustSignals) {
|
|
|
328
328
|
};
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
-
function buildBlockers(qualityTrendReport,
|
|
331
|
+
function buildBlockers(qualityTrendReport, governanceSurfaceTrustSignals, commitSignals) {
|
|
332
332
|
const blockers = [];
|
|
333
333
|
|
|
334
334
|
const qualityGatePassRatePercent = qualityTrendReport?.governanceHealth?.gatePassRatePercent;
|
|
@@ -336,9 +336,9 @@ function buildBlockers(qualityTrendReport, skillTrustSignals, commitSignals) {
|
|
|
336
336
|
blockers.push('Governance gate pass rate is below 100%.');
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
-
if (!
|
|
339
|
+
if (!governanceSurfaceTrustSignals.allRequiredVerified) {
|
|
340
340
|
blockers.push(
|
|
341
|
-
`Required verified
|
|
341
|
+
`Required verified governance surfaces missing: ${governanceSurfaceTrustSignals.requiredVerifiedDomainFailures.join(', ')}`
|
|
342
342
|
);
|
|
343
343
|
}
|
|
344
344
|
|
|
@@ -355,15 +355,37 @@ function buildHistoryEntry(weeklyReport) {
|
|
|
355
355
|
readinessStatus: weeklyReport.releaseReadiness.isReady ? 'ready' : 'blocked',
|
|
356
356
|
blockerCount: weeklyReport.releaseReadiness.blockers.length,
|
|
357
357
|
gatePassRatePercent: weeklyReport.qualitySignals.governanceHealth.gatePassRatePercent,
|
|
358
|
-
|
|
358
|
+
verifiedGovernanceSurfaceCount: weeklyReport.governanceSurfaceTrust.tierCounts.verified,
|
|
359
359
|
backendVerifiedSurfaceCount: weeklyReport.backendGovernance?.verifiedSurfaceCount ?? null,
|
|
360
360
|
releaseFrequencyPercent: weeklyReport.commitSignals.releaseFrequencyPercent,
|
|
361
361
|
rollbackFrequencyPercent: weeklyReport.commitSignals.rollbackFrequencyPercent,
|
|
362
362
|
};
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
+
function normalizeHistoryEntry(historyEntry) {
|
|
366
|
+
if (!historyEntry || typeof historyEntry !== 'object') {
|
|
367
|
+
return historyEntry;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const {
|
|
371
|
+
verifiedSkillDomainCount,
|
|
372
|
+
...normalizedHistoryEntry
|
|
373
|
+
} = historyEntry;
|
|
374
|
+
|
|
375
|
+
if (
|
|
376
|
+
typeof normalizedHistoryEntry.verifiedGovernanceSurfaceCount !== 'number'
|
|
377
|
+
&& typeof verifiedSkillDomainCount === 'number'
|
|
378
|
+
) {
|
|
379
|
+
normalizedHistoryEntry.verifiedGovernanceSurfaceCount = verifiedSkillDomainCount;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return normalizedHistoryEntry;
|
|
383
|
+
}
|
|
384
|
+
|
|
365
385
|
function mergeHistory(previousReport, currentHistoryEntry) {
|
|
366
|
-
const existingHistory = Array.isArray(previousReport?.history)
|
|
386
|
+
const existingHistory = Array.isArray(previousReport?.history)
|
|
387
|
+
? previousReport.history.map((historyEntry) => normalizeHistoryEntry(historyEntry))
|
|
388
|
+
: [];
|
|
367
389
|
const mergedHistory = [...existingHistory, currentHistoryEntry];
|
|
368
390
|
|
|
369
391
|
if (mergedHistory.length <= HISTORY_LIMIT) {
|
|
@@ -377,10 +399,10 @@ async function runWeeklyGovernanceReport() {
|
|
|
377
399
|
const qualityTrendState = loadQualityTrendReport();
|
|
378
400
|
const qualityTrendReport = qualityTrendState.report;
|
|
379
401
|
|
|
380
|
-
const
|
|
381
|
-
const backendGovernance = buildBackendGovernancePosture(
|
|
402
|
+
const governanceSurfaceTrustSignals = await collectGovernanceSurfaceTrustSignals();
|
|
403
|
+
const backendGovernance = buildBackendGovernancePosture(governanceSurfaceTrustSignals);
|
|
382
404
|
const commitSignals = collectCommitSignals(WEEKLY_WINDOW_DAYS);
|
|
383
|
-
const blockers = buildBlockers(qualityTrendReport,
|
|
405
|
+
const blockers = buildBlockers(qualityTrendReport, governanceSurfaceTrustSignals, commitSignals);
|
|
384
406
|
|
|
385
407
|
const weeklyReportSnapshot = {
|
|
386
408
|
generatedAt: new Date().toISOString(),
|
|
@@ -402,7 +424,7 @@ async function runWeeklyGovernanceReport() {
|
|
|
402
424
|
: [],
|
|
403
425
|
tokenEfficiency: qualityTrendReport?.tokenEfficiency || null,
|
|
404
426
|
},
|
|
405
|
-
|
|
427
|
+
governanceSurfaceTrust: governanceSurfaceTrustSignals,
|
|
406
428
|
backendGovernance,
|
|
407
429
|
commitSignals,
|
|
408
430
|
releaseReadiness: {
|
|
@@ -22,8 +22,13 @@ const REPOSITORY_ROOT = resolve(__dirname, '..');
|
|
|
22
22
|
const CANONICAL_SOURCE_PATH = '.instructions.md';
|
|
23
23
|
const ADAPTER_PATHS = [
|
|
24
24
|
'AGENTS.md',
|
|
25
|
+
'CLAUDE.md',
|
|
26
|
+
'GEMINI.md',
|
|
25
27
|
'.github/copilot-instructions.md',
|
|
28
|
+
'.github/instructions/agentic-senior-core.instructions.md',
|
|
26
29
|
'.gemini/instructions.md',
|
|
30
|
+
'.cursor/rules/agentic-senior-core.mdc',
|
|
31
|
+
'.windsurf/rules/agentic-senior-core.md',
|
|
27
32
|
];
|
|
28
33
|
const COMPILER_PATH = 'lib/cli/compiler.mjs';
|
|
29
34
|
const ONBOARDING_REPORT_PATH = '.agent-context/state/onboarding-report.json';
|
|
@@ -31,6 +36,11 @@ const ARCHITECTURE_RULE_PATH = '.agent-context/rules/architecture.md';
|
|
|
31
36
|
const PR_CHECKLIST_PATH = '.agent-context/review-checklists/pr-checklist.md';
|
|
32
37
|
const REVIEW_PROMPT_PATH = '.agent-context/prompts/review-code.md';
|
|
33
38
|
const COMPILED_RULE_PATHS = ['.cursorrules', '.windsurfrules'];
|
|
39
|
+
const REQUIRED_LEGACY_ROOT_ADAPTER_SNIPPETS = [
|
|
40
|
+
'Adapter Mode: legacy-thin',
|
|
41
|
+
'Adapter Source: .agent-instructions.md',
|
|
42
|
+
'Canonical baseline: .instructions.md',
|
|
43
|
+
];
|
|
34
44
|
|
|
35
45
|
const DEFAULT_WORKFLOW = 'standard';
|
|
36
46
|
const SUPPORTED_WORKFLOWS = new Set([
|
|
@@ -432,6 +442,20 @@ function runAudit() {
|
|
|
432
442
|
|
|
433
443
|
const stackMentionCount = countStackMentions(compiledRuleContent);
|
|
434
444
|
const isEagerLoading = stackMentionCount > MAX_EAGER_STACK_MENTIONS;
|
|
445
|
+
const missingLegacyAdapterSnippets = REQUIRED_LEGACY_ROOT_ADAPTER_SNIPPETS
|
|
446
|
+
.filter((requiredSnippet) => !compiledRuleContent.includes(requiredSnippet));
|
|
447
|
+
|
|
448
|
+
if (missingLegacyAdapterSnippets.length > 0) {
|
|
449
|
+
failures.push(`${compiledRulePath} must stay a legacy thin adapter`);
|
|
450
|
+
pushResult(
|
|
451
|
+
results,
|
|
452
|
+
false,
|
|
453
|
+
'legacy-root-adapter-thin-mode',
|
|
454
|
+
`${compiledRulePath} is missing: ${missingLegacyAdapterSnippets.join(', ')}`
|
|
455
|
+
);
|
|
456
|
+
} else {
|
|
457
|
+
pushResult(results, true, 'legacy-root-adapter-thin-mode', `${compiledRulePath} stays legacy-thin`);
|
|
458
|
+
}
|
|
435
459
|
|
|
436
460
|
if (isEagerLoading) {
|
|
437
461
|
eagerLoadingDetected = true;
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
* - node scripts/sync-thin-adapters.mjs --check
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { readFile, writeFile } from 'node:fs/promises';
|
|
14
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
15
15
|
import { createHash } from 'node:crypto';
|
|
16
|
-
import { dirname, join, resolve } from 'node:path';
|
|
16
|
+
import { dirname, join, posix, resolve } from 'node:path';
|
|
17
17
|
import { fileURLToPath } from 'node:url';
|
|
18
18
|
|
|
19
19
|
const SCRIPT_FILE_PATH = fileURLToPath(import.meta.url);
|
|
@@ -26,144 +26,110 @@ function normalizeLineEndings(content) {
|
|
|
26
26
|
return content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Adapter Source: .instructions.md
|
|
34
|
-
Canonical Snapshot SHA256: ${canonicalHash}
|
|
35
|
-
|
|
36
|
-
This file is an adapter entrypoint for agent discovery.
|
|
37
|
-
The canonical policy source is [.instructions.md](.instructions.md).
|
|
38
|
-
|
|
39
|
-
If your host stops at this file instead of following the full chain, obey the Critical Bootstrap Floor below before coding.
|
|
40
|
-
|
|
41
|
-
## Critical Bootstrap Floor
|
|
42
|
-
|
|
43
|
-
- If \`.agent-instructions.md\` exists, prefer it immediately after this file because it is the compiled project-specific snapshot.
|
|
44
|
-
- Memory continuity does not replace bootstrap loading. It is host-dependent project memory, not a guarantee that instructions were reloaded for this session.
|
|
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
|
-
- For UI scope, include a one-line Motion/Palette Decision in the Bootstrap Receipt; product categories are heuristics, not style presets.
|
|
47
|
-
- For UI scope: if \`docs/DESIGN.md\` or \`docs/design-intent.json\` is missing, materialize or refine them before implementing UI changes.
|
|
48
|
-
- For documentation-first requests: create or refine required project docs in English by default and do not write application, firmware, or UI code until the user asks or approves.
|
|
49
|
-
- For backend, API, data, auth, error, event, queue, worker, or distributed-system requests: load the relevant global rules from [.agent-context/rules/](.agent-context/rules); do not create stack-specific governance adapters.
|
|
50
|
-
- For refactor, improve, clean up, or fix requests: inspect the active rules and propose a plan before editing.
|
|
51
|
-
- For new project or module requests: clarify constraints, runtime decisions, and required docs before generating code.
|
|
52
|
-
- For ecosystem, framework, dependency, or Docker claims: perform live web research instead of relying on stale local heuristics.
|
|
53
|
-
|
|
54
|
-
## Mandatory Bootstrap Chain
|
|
55
|
-
|
|
56
|
-
1. Load [.instructions.md](.instructions.md) first as the canonical baseline.
|
|
57
|
-
2. If \`.agent-instructions.md\` exists, read it next as the compiled project-specific snapshot.
|
|
58
|
-
3. Read baseline governance from [.agent-context/rules/](.agent-context/rules).
|
|
59
|
-
4. Apply request templates from [.agent-context/prompts/](.agent-context/prompts).
|
|
60
|
-
5. Enforce review contracts from [.agent-context/review-checklists/](.agent-context/review-checklists).
|
|
61
|
-
6. Read change-risk maps and continuity state from [.agent-context/state/](.agent-context/state).
|
|
62
|
-
7. Enforce policy thresholds from [.agent-context/policies/](.agent-context/policies).
|
|
63
|
-
8. Use runtime evidence, structure, and live research signals from project context docs.
|
|
64
|
-
|
|
65
|
-
## Bootstrap Receipt
|
|
66
|
-
|
|
67
|
-
For non-trivial coding, review, planning, or governance work, produce a short Bootstrap Receipt before implementation output: \`loaded_files\`, \`selected_rules\`, \`skipped_rules\`, \`unreachable_files\`, and \`validation_plan\`.
|
|
68
|
-
|
|
69
|
-
## Trigger Rules
|
|
70
|
-
|
|
71
|
-
- New project or module requests: propose scope, constraints, and required docs first, then wait for approval.
|
|
72
|
-
- Refactor or fix requests: propose plan first, then execute safely.
|
|
73
|
-
- Completion: run [.agent-context/review-checklists/pr-checklist.md](.agent-context/review-checklists/pr-checklist.md) before declaring done.
|
|
74
|
-
|
|
75
|
-
If this adapter drifts from canonical behavior, refresh from [.instructions.md](.instructions.md) and update the hash metadata.
|
|
76
|
-
`;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function buildCopilotAdapter(canonicalHash) {
|
|
80
|
-
return `# GitHub Copilot Instructions - Thin Adapter
|
|
81
|
-
|
|
82
|
-
Adapter Mode: thin
|
|
83
|
-
Adapter Source: .instructions.md
|
|
84
|
-
Canonical Snapshot SHA256: ${canonicalHash}
|
|
85
|
-
|
|
86
|
-
The canonical policy source for this repository is [.instructions.md](../.instructions.md).
|
|
87
|
-
|
|
88
|
-
If your host stops at this file, follow this minimum floor:
|
|
89
|
-
- Read \`.agent-instructions.md\` next when it exists.
|
|
90
|
-
- For UI 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 coding.
|
|
91
|
-
- For UI scope, include a one-line Motion/Palette Decision in the Bootstrap Receipt; product categories are heuristics, not style presets.
|
|
92
|
-
- If UI scope and \`docs/DESIGN.md\` or \`docs/design-intent.json\` is missing, materialize them before UI implementation.
|
|
93
|
-
- For documentation-first requests, create or refine required project docs in English by default and do not write application, firmware, or UI code until the user asks or approves.
|
|
94
|
-
- For backend/API/data/auth/event requests, load relevant global rules from [.agent-context/rules/](../.agent-context/rules) and do not create stack-specific governance adapters.
|
|
95
|
-
- Memory continuity is host-dependent project memory and does not replace bootstrap loading.
|
|
96
|
-
|
|
97
|
-
## Required Load Order
|
|
98
|
-
|
|
99
|
-
1. Read [.instructions.md](../.instructions.md) first as the canonical baseline.
|
|
100
|
-
2. If \`.agent-instructions.md\` exists, read it next as the compiled project-specific snapshot.
|
|
101
|
-
3. Read baseline rules in [.agent-context/rules/](../.agent-context/rules).
|
|
102
|
-
4. Load request templates from [.agent-context/prompts/](../.agent-context/prompts).
|
|
103
|
-
5. Apply review contracts from [.agent-context/review-checklists/](../.agent-context/review-checklists).
|
|
104
|
-
6. Apply state awareness from [.agent-context/state/](../.agent-context/state) and thresholds from [.agent-context/policies/](../.agent-context/policies).
|
|
105
|
-
7. Resolve runtime, structure, and dependency choices from project context docs plus live evidence.
|
|
106
|
-
|
|
107
|
-
## Bootstrap Receipt
|
|
108
|
-
|
|
109
|
-
For non-trivial coding, review, planning, or governance work, produce a short Bootstrap Receipt before implementation output: \`loaded_files\`, \`selected_rules\`, \`skipped_rules\`, \`unreachable_files\`, and \`validation_plan\`.
|
|
110
|
-
|
|
111
|
-
## Completion Gate
|
|
112
|
-
|
|
113
|
-
Run [.agent-context/review-checklists/pr-checklist.md](../.agent-context/review-checklists/pr-checklist.md) before declaring work complete.
|
|
114
|
-
`;
|
|
29
|
+
function buildAdapterLink(adapterRelativePath, targetRelativePath) {
|
|
30
|
+
const adapterDirectoryPath = posix.dirname(adapterRelativePath);
|
|
31
|
+
const relativePath = posix.relative(adapterDirectoryPath === '.' ? '' : adapterDirectoryPath, targetRelativePath);
|
|
32
|
+
return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
|
|
115
33
|
}
|
|
116
34
|
|
|
117
|
-
function
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
35
|
+
function buildThinAdapter({
|
|
36
|
+
relativePath,
|
|
37
|
+
title,
|
|
38
|
+
canonicalHash,
|
|
39
|
+
frontmatter = '',
|
|
40
|
+
}) {
|
|
41
|
+
const canonicalLink = buildAdapterLink(relativePath, '.instructions.md');
|
|
42
|
+
const rulesLink = buildAdapterLink(relativePath, '.agent-context/rules');
|
|
43
|
+
const promptsLink = buildAdapterLink(relativePath, '.agent-context/prompts');
|
|
44
|
+
const designPromptLink = buildAdapterLink(relativePath, '.agent-context/prompts/bootstrap-design.md');
|
|
45
|
+
const frontendRuleLink = buildAdapterLink(relativePath, '.agent-context/rules/frontend-architecture.md');
|
|
46
|
+
const checklistLink = buildAdapterLink(relativePath, '.agent-context/review-checklists/pr-checklist.md');
|
|
47
|
+
const stateLink = buildAdapterLink(relativePath, '.agent-context/state');
|
|
48
|
+
const policiesLink = buildAdapterLink(relativePath, '.agent-context/policies');
|
|
49
|
+
const adapterHeader = frontmatter.trim() ? [frontmatter.trim(), ''] : [];
|
|
50
|
+
|
|
51
|
+
return [
|
|
52
|
+
...adapterHeader,
|
|
53
|
+
`# ${title}`,
|
|
54
|
+
'',
|
|
55
|
+
'Adapter Mode: thin',
|
|
56
|
+
'Adapter Source: .instructions.md',
|
|
57
|
+
`Canonical Snapshot SHA256: ${canonicalHash}`,
|
|
58
|
+
'',
|
|
59
|
+
'This repository is governed by a strict instruction contract.',
|
|
60
|
+
`Use [${CANONICAL_SOURCE_PATH}](${canonicalLink}) as the canonical policy source.`,
|
|
61
|
+
'Use .agent-context/ for technical rules, prompts, checklists, policies, and state.',
|
|
62
|
+
'Treat README.md as overview/install/user context only when governance files conflict.',
|
|
63
|
+
'',
|
|
64
|
+
'## Critical Bootstrap Floor',
|
|
65
|
+
'',
|
|
66
|
+
'- If your host stops at this file, continue the chain manually before coding.',
|
|
67
|
+
'- Read `.agent-instructions.md` next when it exists.',
|
|
68
|
+
'- Memory continuity does not replace bootstrap loading.',
|
|
69
|
+
`- For UI, UX, layout, screen, tailwind, frontend, or redesign requests, load [bootstrap-design.md](${designPromptLink}) and [frontend-architecture.md](${frontendRuleLink}) before code edits.`,
|
|
70
|
+
'- For UI scope, include a one-line Motion/Palette Decision in the Bootstrap Receipt; product categories are heuristics, not style presets.',
|
|
71
|
+
'- For UI scope, create or refine `docs/DESIGN.md` and `docs/design-intent.json` before UI implementation.',
|
|
72
|
+
'- For documentation-first requests, create or refine required project docs in English by default and do not write application, firmware, or UI code until the user asks or approves.',
|
|
73
|
+
`- For backend, API, data, auth, error, event, queue, worker, or distributed-system requests, load only relevant global rules from .agent-context/rules/ ([link](${rulesLink})).`,
|
|
74
|
+
'- For ecosystem, framework, dependency, or Docker claims, perform live web research.',
|
|
75
|
+
'- Resolve runtime choices from project evidence and live official documentation; resolve structural planning from constraints and architecture boundaries.',
|
|
76
|
+
'',
|
|
77
|
+
'## Mandatory Bootstrap Chain',
|
|
78
|
+
'',
|
|
79
|
+
`1. Load [${CANONICAL_SOURCE_PATH}](${canonicalLink}).`,
|
|
80
|
+
'2. Load `.agent-instructions.md` when present.',
|
|
81
|
+
`3. Load only relevant files from .agent-context/rules/ ([link](${rulesLink})).`,
|
|
82
|
+
`4. Apply matching prompts from .agent-context/prompts/ ([link](${promptsLink})).`,
|
|
83
|
+
`5. Enforce .agent-context/review-checklists/ ([link](${checklistLink})).`,
|
|
84
|
+
`6. Use .agent-context/state/ ([link](${stateLink})) and .agent-context/policies/ ([link](${policiesLink})) only when relevant.`,
|
|
85
|
+
'7. Use project docs and live evidence for runtime, dependency, and architecture claims.',
|
|
86
|
+
'',
|
|
87
|
+
'## Bootstrap Receipt',
|
|
88
|
+
'',
|
|
89
|
+
'For non-trivial coding, review, planning, or governance work, produce a short Bootstrap Receipt before implementation output: `loaded_files`, `selected_rules`, `skipped_rules`, `unreachable_files`, and `validation_plan`.',
|
|
90
|
+
'',
|
|
91
|
+
'## Completion Gate',
|
|
92
|
+
'',
|
|
93
|
+
`Run [pr-checklist.md](${checklistLink}) before declaring work complete.`,
|
|
94
|
+
'',
|
|
95
|
+
`If this adapter drifts from canonical behavior, refresh from [${CANONICAL_SOURCE_PATH}](${canonicalLink}) and update the hash metadata.`,
|
|
96
|
+
].join('\n');
|
|
153
97
|
}
|
|
154
98
|
|
|
155
99
|
const ADAPTERS = [
|
|
156
100
|
{
|
|
157
101
|
relativePath: 'AGENTS.md',
|
|
158
|
-
|
|
102
|
+
title: 'AGENTS.md - Thin Adapter',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
relativePath: 'CLAUDE.md',
|
|
106
|
+
title: 'CLAUDE.md - Thin Adapter',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
relativePath: 'GEMINI.md',
|
|
110
|
+
title: 'GEMINI.md - Thin Adapter',
|
|
159
111
|
},
|
|
160
112
|
{
|
|
161
113
|
relativePath: '.github/copilot-instructions.md',
|
|
162
|
-
|
|
114
|
+
title: 'GitHub Copilot Instructions - Thin Adapter',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
relativePath: '.github/instructions/agentic-senior-core.instructions.md',
|
|
118
|
+
title: 'GitHub Copilot Path Instructions - Thin Adapter',
|
|
119
|
+
frontmatter: '---\napplyTo: "**"\n---',
|
|
163
120
|
},
|
|
164
121
|
{
|
|
165
122
|
relativePath: '.gemini/instructions.md',
|
|
166
|
-
|
|
123
|
+
title: 'Gemini Instructions - Thin Adapter',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
relativePath: '.cursor/rules/agentic-senior-core.mdc',
|
|
127
|
+
title: 'Cursor Rule - Thin Adapter',
|
|
128
|
+
frontmatter: '---\ndescription: Agentic Senior Core bootstrap adapter\nalwaysApply: true\n---',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
relativePath: '.windsurf/rules/agentic-senior-core.md',
|
|
132
|
+
title: 'Windsurf Rule - Thin Adapter',
|
|
167
133
|
},
|
|
168
134
|
];
|
|
169
135
|
|
|
@@ -175,11 +141,14 @@ async function main() {
|
|
|
175
141
|
|
|
176
142
|
for (const adapter of ADAPTERS) {
|
|
177
143
|
const adapterAbsolutePath = join(ROOT_DIR, adapter.relativePath);
|
|
178
|
-
const expectedContent =
|
|
144
|
+
const expectedContent = buildThinAdapter({
|
|
145
|
+
...adapter,
|
|
146
|
+
canonicalHash,
|
|
147
|
+
});
|
|
179
148
|
|
|
180
149
|
if (IS_CHECK_MODE) {
|
|
181
150
|
const existingContent = normalizeLineEndings(await readFile(adapterAbsolutePath, 'utf8'));
|
|
182
|
-
const expectedNormalized = normalizeLineEndings(expectedContent);
|
|
151
|
+
const expectedNormalized = normalizeLineEndings(`${expectedContent.trimEnd()}\n`);
|
|
183
152
|
if (existingContent !== expectedNormalized) {
|
|
184
153
|
hasDrift = true;
|
|
185
154
|
console.error(`[DRIFT] ${adapter.relativePath} does not match canonical adapter output.`);
|
|
@@ -189,6 +158,7 @@ async function main() {
|
|
|
189
158
|
continue;
|
|
190
159
|
}
|
|
191
160
|
|
|
161
|
+
await mkdir(dirname(adapterAbsolutePath), { recursive: true });
|
|
192
162
|
await writeFile(adapterAbsolutePath, `${expectedContent.trimEnd()}\n`, 'utf8');
|
|
193
163
|
console.log(`[SYNC] ${adapter.relativePath}`);
|
|
194
164
|
}
|
|
@@ -27,9 +27,14 @@ const NON_BLOCKING_REFERENCE_FILE_PATHS = new Set([
|
|
|
27
27
|
|
|
28
28
|
const RUNTIME_BLOCKING_PATH_PATTERNS = [
|
|
29
29
|
/^AGENTS\.md$/,
|
|
30
|
+
/^CLAUDE\.md$/,
|
|
31
|
+
/^GEMINI\.md$/,
|
|
30
32
|
/^\.instructions\.md$/,
|
|
31
33
|
/^\.github\/copilot-instructions\.md$/,
|
|
34
|
+
/^\.github\/instructions\/agentic-senior-core\.instructions\.md$/,
|
|
32
35
|
/^\.gemini\/instructions\.md$/,
|
|
36
|
+
/^\.cursor\/rules\/agentic-senior-core\.mdc$/,
|
|
37
|
+
/^\.windsurf\/rules\/agentic-senior-core\.md$/,
|
|
33
38
|
/^mcp\.json$/,
|
|
34
39
|
/^lib\//,
|
|
35
40
|
/^scripts\//,
|
|
@@ -2,8 +2,13 @@ export const ALLOWED_SEVERITIES = new Set(['critical', 'high', 'medium', 'low'])
|
|
|
2
2
|
export const OVERRIDE_WARNING_WINDOW_DAYS = 30;
|
|
3
3
|
export const THIN_ADAPTER_PATHS = [
|
|
4
4
|
'AGENTS.md',
|
|
5
|
+
'CLAUDE.md',
|
|
6
|
+
'GEMINI.md',
|
|
5
7
|
'.github/copilot-instructions.md',
|
|
8
|
+
'.github/instructions/agentic-senior-core.instructions.md',
|
|
6
9
|
'.gemini/instructions.md',
|
|
10
|
+
'.cursor/rules/agentic-senior-core.mdc',
|
|
11
|
+
'.windsurf/rules/agentic-senior-core.md',
|
|
7
12
|
];
|
|
8
13
|
export const FORMAL_ARTIFACT_PATHS = [
|
|
9
14
|
'.instructions.md',
|
|
@@ -14,8 +19,13 @@ export const FORMAL_ARTIFACT_PATHS = [
|
|
|
14
19
|
'.agent-context/review-checklists/pr-checklist.md',
|
|
15
20
|
'.agent-context/prompts/review-code.md',
|
|
16
21
|
'AGENTS.md',
|
|
22
|
+
'CLAUDE.md',
|
|
23
|
+
'GEMINI.md',
|
|
17
24
|
'.github/copilot-instructions.md',
|
|
25
|
+
'.github/instructions/agentic-senior-core.instructions.md',
|
|
18
26
|
'.gemini/instructions.md',
|
|
27
|
+
'.cursor/rules/agentic-senior-core.mdc',
|
|
28
|
+
'.windsurf/rules/agentic-senior-core.md',
|
|
19
29
|
];
|
|
20
30
|
export const REQUIRED_HUMAN_WRITING_SNIPPETS = [
|
|
21
31
|
{
|
|
@@ -396,6 +396,12 @@ export async function validateInstructionAdapters(context) {
|
|
|
396
396
|
'Motion/Palette Decision',
|
|
397
397
|
'product categories are heuristics',
|
|
398
398
|
];
|
|
399
|
+
const instructionFootprintLimits = [
|
|
400
|
+
{ path: '.instructions.md', maxLines: 220 },
|
|
401
|
+
{ path: '.agent-context/prompts/bootstrap-design.md', maxLines: 180 },
|
|
402
|
+
{ path: '.agent-context/rules/frontend-architecture.md', maxLines: 110 },
|
|
403
|
+
];
|
|
404
|
+
const legacyRootAdapterPaths = ['.cursorrules', '.windsurfrules'];
|
|
399
405
|
|
|
400
406
|
for (const requiredBootstrapReceiptSnippet of requiredBootstrapReceiptSnippets) {
|
|
401
407
|
if (canonicalInstructionContent.includes(requiredBootstrapReceiptSnippet)) {
|
|
@@ -413,6 +419,22 @@ export async function validateInstructionAdapters(context) {
|
|
|
413
419
|
}
|
|
414
420
|
}
|
|
415
421
|
|
|
422
|
+
for (const footprintLimit of instructionFootprintLimits) {
|
|
423
|
+
const absoluteFootprintPath = join(ROOT_DIR, footprintLimit.path);
|
|
424
|
+
if (!(await fileExists(absoluteFootprintPath))) {
|
|
425
|
+
fail(`Missing instruction footprint source: ${footprintLimit.path}`);
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const footprintContent = await readTextFile(absoluteFootprintPath);
|
|
430
|
+
const footprintLineCount = footprintContent.split(/\r?\n/u).length;
|
|
431
|
+
if (footprintLineCount <= footprintLimit.maxLines) {
|
|
432
|
+
pass(`${footprintLimit.path} stays compact (${footprintLineCount}/${footprintLimit.maxLines} lines)`);
|
|
433
|
+
} else {
|
|
434
|
+
fail(`${footprintLimit.path} is too long for the active instruction surface (${footprintLineCount}/${footprintLimit.maxLines} lines)`);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
416
438
|
for (const thinAdapterPath of THIN_ADAPTER_PATHS) {
|
|
417
439
|
const absoluteAdapterPath = join(ROOT_DIR, thinAdapterPath);
|
|
418
440
|
|
|
@@ -467,6 +489,39 @@ export async function validateInstructionAdapters(context) {
|
|
|
467
489
|
fail(`${thinAdapterPath} is too large for thin-adapter mode (${thinAdapterLineCount} lines)`);
|
|
468
490
|
}
|
|
469
491
|
}
|
|
492
|
+
|
|
493
|
+
for (const legacyRootAdapterPath of legacyRootAdapterPaths) {
|
|
494
|
+
const absoluteLegacyRootAdapterPath = join(ROOT_DIR, legacyRootAdapterPath);
|
|
495
|
+
if (!(await fileExists(absoluteLegacyRootAdapterPath))) {
|
|
496
|
+
fail(`Missing legacy root adapter file: ${legacyRootAdapterPath}`);
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
const legacyRootAdapterContent = await readTextFile(absoluteLegacyRootAdapterPath);
|
|
501
|
+
const requiredLegacyRootAdapterSnippets = [
|
|
502
|
+
'Generated by Agentic-Senior-Core CLI v',
|
|
503
|
+
'Adapter Mode: legacy-thin',
|
|
504
|
+
'Adapter Source: .agent-instructions.md',
|
|
505
|
+
'Canonical baseline: .instructions.md',
|
|
506
|
+
'.agent-instructions.md',
|
|
507
|
+
'.agent-context/rules/',
|
|
508
|
+
];
|
|
509
|
+
|
|
510
|
+
for (const requiredLegacyRootAdapterSnippet of requiredLegacyRootAdapterSnippets) {
|
|
511
|
+
if (legacyRootAdapterContent.includes(requiredLegacyRootAdapterSnippet)) {
|
|
512
|
+
pass(`${legacyRootAdapterPath} includes legacy-thin snippet: ${requiredLegacyRootAdapterSnippet}`);
|
|
513
|
+
} else {
|
|
514
|
+
fail(`${legacyRootAdapterPath} is missing legacy-thin snippet: ${requiredLegacyRootAdapterSnippet}`);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
const legacyRootAdapterLineCount = legacyRootAdapterContent.split(/\r?\n/u).length;
|
|
519
|
+
if (legacyRootAdapterLineCount <= 40) {
|
|
520
|
+
pass(`${legacyRootAdapterPath} remains thin (${legacyRootAdapterLineCount} lines)`);
|
|
521
|
+
} else {
|
|
522
|
+
fail(`${legacyRootAdapterPath} is too large for legacy-thin mode (${legacyRootAdapterLineCount} lines)`);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
470
525
|
}
|
|
471
526
|
|
|
472
527
|
export async function validateSkillPurgeSurface(context) {
|