@ryuenn3123/agentic-senior-core 2.5.22 → 3.0.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.
- package/.agent-context/prompts/init-project.md +5 -5
- package/.agent-context/prompts/refactor.md +2 -1
- package/.agent-context/prompts/review-code.md +3 -2
- package/.agent-context/review-checklists/pr-checklist.md +8 -1
- package/.agent-context/rules/architecture.md +11 -0
- package/.agent-context/rules/frontend-architecture.md +2 -2
- package/.agent-context/state/architecture-map.md +1 -1
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.agents/workflows/init-project.md +3 -3
- package/.agents/workflows/refactor.md +1 -1
- package/.agents/workflows/review-code.md +4 -5
- package/.cursorrules +27 -71
- package/.gemini/instructions.md +6 -7
- package/.github/copilot-instructions.md +5 -6
- package/.windsurfrules +27 -71
- package/AGENTS.md +7 -9
- package/CONTRIBUTING.md +18 -31
- package/README.md +21 -4
- package/bin/agentic-senior-core.js +0 -6
- package/lib/cli/commands/init.mjs +113 -650
- package/lib/cli/commands/launch.mjs +1 -23
- package/lib/cli/commands/rollback.mjs +1 -1
- package/lib/cli/commands/upgrade.mjs +1 -23
- package/lib/cli/compiler.mjs +77 -72
- package/lib/cli/constants.mjs +84 -26
- package/lib/cli/init-architecture-flow.mjs +231 -0
- package/lib/cli/init-detection-flow.mjs +123 -0
- package/lib/cli/init-options.mjs +344 -0
- package/lib/cli/init-selection.mjs +100 -0
- package/lib/cli/preflight.mjs +1 -1
- package/lib/cli/profile-packs.mjs +15 -1
- package/lib/cli/project-scaffolder.mjs +18 -154
- package/lib/cli/utils.mjs +16 -12
- package/mcp.json +19 -19
- package/package.json +5 -2
- package/scripts/context-triggered-audit.mjs +18 -18
- package/scripts/documentation-boundary-audit.mjs +92 -5
- package/scripts/forbidden-content-check.mjs +1 -1
- package/scripts/frontend-usability-audit.mjs +21 -28
- package/scripts/governance-weekly-report.mjs +29 -15
- package/scripts/llm-judge.mjs +2 -5
- package/scripts/mcp-server.mjs +389 -5
- package/scripts/release-gate.mjs +121 -145
- package/scripts/sync-thin-adapters.mjs +161 -0
- package/scripts/v3-purge-audit.mjs +231 -0
- package/scripts/validate-evidence-bundle.mjs +1 -1
- package/scripts/validate.mjs +224 -272
- package/.agent-context/blueprints/api-nextjs.md +0 -184
- package/.agent-context/blueprints/aspnet-api.md +0 -247
- package/.agent-context/blueprints/ci-github-actions.md +0 -226
- package/.agent-context/blueprints/ci-gitlab.md +0 -200
- package/.agent-context/blueprints/fastapi-service.md +0 -210
- package/.agent-context/blueprints/go-service.md +0 -217
- package/.agent-context/blueprints/graphql-grpc-api.md +0 -51
- package/.agent-context/blueprints/infrastructure-as-code.md +0 -62
- package/.agent-context/blueprints/kubernetes-manifests.md +0 -76
- package/.agent-context/blueprints/laravel-api.md +0 -233
- package/.agent-context/blueprints/mobile-app.md +0 -91
- package/.agent-context/blueprints/nestjs-logic.md +0 -247
- package/.agent-context/blueprints/observability.md +0 -227
- package/.agent-context/blueprints/spring-boot-api.md +0 -218
- package/.agent-context/profiles/platform.md +0 -13
- package/.agent-context/profiles/regulated.md +0 -13
- package/.agent-context/profiles/startup.md +0 -13
- package/.agent-context/review-checklists/frontend-excellence-rubric.md +0 -73
- package/.agent-context/review-checklists/frontend-skill-parity.md +0 -29
- package/.agent-context/review-checklists/frontend-usability.md +0 -35
- package/.agent-context/review-checklists/marketplace-acceptance.md +0 -60
- package/.agent-context/review-checklists/performance-audit.md +0 -71
- package/.agent-context/review-checklists/release-operations.md +0 -33
- package/.agent-context/review-checklists/security-audit.md +0 -119
- package/.agent-context/skills/README.md +0 -63
- package/.agent-context/skills/backend/README.md +0 -68
- package/.agent-context/skills/backend/architecture.md +0 -361
- package/.agent-context/skills/backend/compatibility-manifest.json +0 -8
- package/.agent-context/skills/backend/data-access.md +0 -231
- package/.agent-context/skills/backend/errors.md +0 -138
- package/.agent-context/skills/backend/validation.md +0 -117
- package/.agent-context/skills/backend.md +0 -29
- package/.agent-context/skills/cli/.evidence/compatibility-manifest.json +0 -5
- package/.agent-context/skills/cli/.evidence/sbom-excerpt.json +0 -10
- package/.agent-context/skills/cli/.evidence/test-report.json +0 -8
- package/.agent-context/skills/cli/CHANGELOG.md +0 -6
- package/.agent-context/skills/cli/README.md +0 -56
- package/.agent-context/skills/cli/compatibility-manifest.json +0 -8
- package/.agent-context/skills/cli/init.md +0 -38
- package/.agent-context/skills/cli/output.md +0 -36
- package/.agent-context/skills/cli/package.json +0 -5
- package/.agent-context/skills/cli/safety-telemetry.md +0 -39
- package/.agent-context/skills/cli/tests/.gitkeep +0 -1
- package/.agent-context/skills/cli/upgrade.md +0 -38
- package/.agent-context/skills/cli.md +0 -32
- package/.agent-context/skills/distribution/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/distribution/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/distribution/.evidence/test-report.json +0 -8
- package/.agent-context/skills/distribution/CHANGELOG.md +0 -7
- package/.agent-context/skills/distribution/README.md +0 -27
- package/.agent-context/skills/distribution/compatibility-manifest.json +0 -8
- package/.agent-context/skills/distribution/compatibility.md +0 -32
- package/.agent-context/skills/distribution/package.json +0 -5
- package/.agent-context/skills/distribution/provenance-attestation.md +0 -47
- package/.agent-context/skills/distribution/publish.md +0 -37
- package/.agent-context/skills/distribution/rollback.md +0 -32
- package/.agent-context/skills/distribution/tests/.gitkeep +0 -1
- package/.agent-context/skills/distribution.md +0 -32
- package/.agent-context/skills/frontend/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/frontend/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/frontend/.evidence/test-report.json +0 -8
- package/.agent-context/skills/frontend/CHANGELOG.md +0 -7
- package/.agent-context/skills/frontend/README.md +0 -50
- package/.agent-context/skills/frontend/accessibility.md +0 -107
- package/.agent-context/skills/frontend/compatibility-manifest.json +0 -8
- package/.agent-context/skills/frontend/conversion-clarity.md +0 -51
- package/.agent-context/skills/frontend/motion.md +0 -67
- package/.agent-context/skills/frontend/package.json +0 -5
- package/.agent-context/skills/frontend/performance.md +0 -63
- package/.agent-context/skills/frontend/responsive-delivery.md +0 -41
- package/.agent-context/skills/frontend/tests/.gitkeep +0 -1
- package/.agent-context/skills/frontend/ui-architecture.md +0 -128
- package/.agent-context/skills/frontend.md +0 -40
- package/.agent-context/skills/fullstack/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/fullstack/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/fullstack/.evidence/test-report.json +0 -8
- package/.agent-context/skills/fullstack/CHANGELOG.md +0 -7
- package/.agent-context/skills/fullstack/README.md +0 -27
- package/.agent-context/skills/fullstack/compatibility-manifest.json +0 -8
- package/.agent-context/skills/fullstack/contracts.md +0 -53
- package/.agent-context/skills/fullstack/end-to-end.md +0 -42
- package/.agent-context/skills/fullstack/feature-slicing.md +0 -65
- package/.agent-context/skills/fullstack/package.json +0 -5
- package/.agent-context/skills/fullstack/release-coordination.md +0 -51
- package/.agent-context/skills/fullstack/tests/.gitkeep +0 -1
- package/.agent-context/skills/fullstack.md +0 -30
- package/.agent-context/skills/index.json +0 -107
- package/.agent-context/skills/review-quality/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/review-quality/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/review-quality/.evidence/test-report.json +0 -8
- package/.agent-context/skills/review-quality/CHANGELOG.md +0 -7
- package/.agent-context/skills/review-quality/README.md +0 -27
- package/.agent-context/skills/review-quality/benchmark.md +0 -30
- package/.agent-context/skills/review-quality/compatibility-manifest.json +0 -8
- package/.agent-context/skills/review-quality/package.json +0 -5
- package/.agent-context/skills/review-quality/planning.md +0 -38
- package/.agent-context/skills/review-quality/release-decision.md +0 -49
- package/.agent-context/skills/review-quality/security.md +0 -34
- package/.agent-context/skills/review-quality/tests/.gitkeep +0 -1
- package/.agent-context/skills/review-quality.md +0 -34
- package/.agent-context/stacks/csharp.md +0 -149
- package/.agent-context/stacks/flutter.md +0 -16
- package/.agent-context/stacks/go.md +0 -181
- package/.agent-context/stacks/java.md +0 -135
- package/.agent-context/stacks/php.md +0 -192
- package/.agent-context/stacks/python.md +0 -153
- package/.agent-context/stacks/react-native.md +0 -16
- package/.agent-context/stacks/ruby.md +0 -80
- package/.agent-context/stacks/rust.md +0 -86
- package/.agent-context/stacks/typescript.md +0 -317
- package/.agent-context/state/skill-platform.json +0 -38
- package/lib/cli/skill-selector.mjs +0 -232
- package/lib/cli/templates/api-contract.md.id.tmpl +0 -143
- package/lib/cli/templates/api-contract.md.tmpl +0 -143
- package/lib/cli/templates/architecture-decision-record.md.id.tmpl +0 -106
- package/lib/cli/templates/architecture-decision-record.md.tmpl +0 -145
- package/lib/cli/templates/database-schema.md.id.tmpl +0 -74
- package/lib/cli/templates/database-schema.md.tmpl +0 -74
- package/lib/cli/templates/flow-overview.md.id.tmpl +0 -118
- package/lib/cli/templates/flow-overview.md.tmpl +0 -131
- package/lib/cli/templates/project-brief.md.id.tmpl +0 -55
- package/lib/cli/templates/project-brief.md.tmpl +0 -79
- package/scripts/init-project.ps1 +0 -105
- package/scripts/init-project.sh +0 -131
- package/scripts/skill-tier-policy.mjs +0 -76
- package/scripts/trust-scorer.mjs +0 -119
package/scripts/release-gate.mjs
CHANGED
|
@@ -17,18 +17,6 @@ const __dirname = dirname(__filename);
|
|
|
17
17
|
const REPOSITORY_ROOT = resolve(__dirname, '..');
|
|
18
18
|
|
|
19
19
|
const VERSION_PATTERN = /^\d+\.\d+\.\d+$/;
|
|
20
|
-
const NODE_MIN_PATTERN = /^\d+(\.\d+)?$/;
|
|
21
|
-
const SUPPORTED_COMPATIBILITY_PLATFORMS = new Set(['windows', 'linux', 'macos']);
|
|
22
|
-
const REQUIRED_SKILL_DOMAINS = [
|
|
23
|
-
'backend',
|
|
24
|
-
'frontend',
|
|
25
|
-
'fullstack',
|
|
26
|
-
'cli',
|
|
27
|
-
'distribution',
|
|
28
|
-
'review-quality',
|
|
29
|
-
];
|
|
30
|
-
const FRONTEND_PARITY_CHECKLIST_PATH = '.agent-context/review-checklists/frontend-skill-parity.md';
|
|
31
|
-
const FRONTEND_EXCELLENCE_RUBRIC_PATH = '.agent-context/review-checklists/frontend-excellence-rubric.md';
|
|
32
20
|
const FRONTEND_AUDIT_SCRIPT_PATH = 'scripts/frontend-usability-audit.mjs';
|
|
33
21
|
const DOCUMENTATION_BOUNDARY_AUDIT_SCRIPT_PATH = 'scripts/documentation-boundary-audit.mjs';
|
|
34
22
|
const CONTEXT_TRIGGERED_AUDIT_SCRIPT_PATH = 'scripts/context-triggered-audit.mjs';
|
|
@@ -37,14 +25,8 @@ const EXPLAIN_ON_DEMAND_AUDIT_SCRIPT_PATH = 'scripts/explain-on-demand-audit.mjs
|
|
|
37
25
|
const SINGLE_SOURCE_LAZY_LOADING_AUDIT_SCRIPT_PATH = 'scripts/single-source-lazy-loading-audit.mjs';
|
|
38
26
|
const BACKEND_ARCHITECTURE_RULE_PATH = '.agent-context/rules/architecture.md';
|
|
39
27
|
const BACKEND_REVIEW_CHECKLIST_PATH = '.agent-context/review-checklists/pr-checklist.md';
|
|
28
|
+
const ARCHITECTURE_REVIEW_CHECKLIST_PATH = '.agent-context/review-checklists/architecture-review.md';
|
|
40
29
|
const REFACTOR_PROMPT_PATH = '.agent-context/prompts/refactor.md';
|
|
41
|
-
const REQUIRED_FRONTEND_PARITY_SNIPPETS = [
|
|
42
|
-
'Architecture and Composition',
|
|
43
|
-
'Interaction and Motion',
|
|
44
|
-
'Accessibility and Responsiveness',
|
|
45
|
-
'UX Narrative and Conversion Clarity',
|
|
46
|
-
'Release Evidence',
|
|
47
|
-
];
|
|
48
30
|
const REQUIRED_BACKEND_ARCHITECTURE_RULE_SNIPPETS = [
|
|
49
31
|
'No clever hacks.',
|
|
50
32
|
'No premature abstraction.',
|
|
@@ -60,19 +42,19 @@ const REQUIRED_REFACTOR_PROMPT_SNIPPETS = [
|
|
|
60
42
|
'Enforce backend universal principles: no clever hacks, no premature abstraction, readability over brevity.',
|
|
61
43
|
'Prioritize maintainability over compressed one-liners.',
|
|
62
44
|
];
|
|
63
|
-
const
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
67
|
-
'
|
|
68
|
-
'Language and Content Consistency',
|
|
69
|
-
'Text Contrast and Collision Safety',
|
|
70
|
-
'UX Narrative and Conversion Clarity',
|
|
71
|
-
'Template Diversity and Originality',
|
|
72
|
-
'Low-Diversity Template Output Policy',
|
|
73
|
-
'Awwwards-level reference quality',
|
|
45
|
+
const REQUIRED_ARCHITECTURE_REVIEW_CHECKLIST_SNIPPETS = [
|
|
46
|
+
'## Backend Universal Principles',
|
|
47
|
+
'No clever hacks in backend and shared core modules',
|
|
48
|
+
'No premature abstraction',
|
|
49
|
+
'Readability over brevity',
|
|
74
50
|
];
|
|
75
51
|
const BENCHMARK_GATE_SCRIPT_PATH = 'scripts/benchmark-gate.mjs';
|
|
52
|
+
const AUTO_DOCS_SYNC_SCOPE_PHASE = 'phase-1';
|
|
53
|
+
const AUTO_DOCS_SYNC_SCOPE_BOUNDARIES = [
|
|
54
|
+
'public-surface',
|
|
55
|
+
'api-contract',
|
|
56
|
+
'database-structure',
|
|
57
|
+
];
|
|
76
58
|
|
|
77
59
|
function readText(relativeFilePath) {
|
|
78
60
|
const absolutePath = resolve(REPOSITORY_ROOT, relativeFilePath);
|
|
@@ -131,32 +113,6 @@ function runMachineReadableScript(scriptRelativePath, scriptArguments = []) {
|
|
|
131
113
|
}
|
|
132
114
|
}
|
|
133
115
|
|
|
134
|
-
function validateCompatibilityManifestShape(parsedManifest, skillDomainName) {
|
|
135
|
-
const validationErrors = [];
|
|
136
|
-
|
|
137
|
-
if (!Array.isArray(parsedManifest.ides) || parsedManifest.ides.length === 0) {
|
|
138
|
-
validationErrors.push(`Domain ${skillDomainName} must define non-empty ides[]`);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (!Array.isArray(parsedManifest.platforms) || parsedManifest.platforms.length === 0) {
|
|
142
|
-
validationErrors.push(`Domain ${skillDomainName} must define non-empty platforms[]`);
|
|
143
|
-
} else {
|
|
144
|
-
const unsupportedPlatformName = parsedManifest.platforms.find(
|
|
145
|
-
(platformName) => !SUPPORTED_COMPATIBILITY_PLATFORMS.has(platformName)
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
if (unsupportedPlatformName) {
|
|
149
|
-
validationErrors.push(`Domain ${skillDomainName} has unsupported platform: ${unsupportedPlatformName}`);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (typeof parsedManifest.nodeMin !== 'string' || !NODE_MIN_PATTERN.test(parsedManifest.nodeMin)) {
|
|
154
|
-
validationErrors.push(`Domain ${skillDomainName} must define nodeMin as "18" or "18.0" style string`);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return validationErrors;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
116
|
function runReleaseGate() {
|
|
161
117
|
const results = [];
|
|
162
118
|
const diagnostics = {};
|
|
@@ -208,7 +164,7 @@ function runReleaseGate() {
|
|
|
208
164
|
}
|
|
209
165
|
|
|
210
166
|
const requiredEnterpriseFiles = [
|
|
211
|
-
'.agent-context/review-checklists/
|
|
167
|
+
'.agent-context/review-checklists/architecture-review.md',
|
|
212
168
|
'docs/v1.8-operations-playbook.md',
|
|
213
169
|
'.github/workflows/release-gate.yml',
|
|
214
170
|
'.github/workflows/sbom-compliance.yml',
|
|
@@ -226,57 +182,12 @@ function runReleaseGate() {
|
|
|
226
182
|
pushResult(results, true, 'required-enterprise-file', `${requiredEnterpriseFile} is present`);
|
|
227
183
|
}
|
|
228
184
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if (!compatibilityManifestContent) {
|
|
236
|
-
pushResult(results, false, 'compatibility-manifest', `Missing ${compatibilityManifestPath}`);
|
|
237
|
-
continue;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
let parsedCompatibilityManifest;
|
|
241
|
-
try {
|
|
242
|
-
parsedCompatibilityManifest = JSON.parse(compatibilityManifestContent);
|
|
243
|
-
} catch (compatibilityManifestParseError) {
|
|
244
|
-
const parseErrorMessage = compatibilityManifestParseError instanceof Error
|
|
245
|
-
? compatibilityManifestParseError.message
|
|
246
|
-
: 'Unknown parse error';
|
|
247
|
-
pushResult(results, false, 'compatibility-manifest', `Invalid JSON in ${compatibilityManifestPath}: ${parseErrorMessage}`);
|
|
248
|
-
continue;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const compatibilityValidationErrors = validateCompatibilityManifestShape(
|
|
252
|
-
parsedCompatibilityManifest,
|
|
253
|
-
skillDomainName
|
|
254
|
-
);
|
|
255
|
-
|
|
256
|
-
if (compatibilityValidationErrors.length > 0) {
|
|
257
|
-
pushResult(results, false, 'compatibility-manifest', compatibilityValidationErrors.join('; '));
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
validatedCompatibilityManifestCount += 1;
|
|
262
|
-
pushResult(results, true, 'compatibility-manifest', `${compatibilityManifestPath} is valid`);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (validatedCompatibilityManifestCount === REQUIRED_SKILL_DOMAINS.length) {
|
|
266
|
-
pushResult(
|
|
267
|
-
results,
|
|
268
|
-
true,
|
|
269
|
-
'compatibility-manifest-coverage',
|
|
270
|
-
`Validated ${validatedCompatibilityManifestCount}/${REQUIRED_SKILL_DOMAINS.length} required skill compatibility manifests`
|
|
271
|
-
);
|
|
272
|
-
} else {
|
|
273
|
-
pushResult(
|
|
274
|
-
results,
|
|
275
|
-
false,
|
|
276
|
-
'compatibility-manifest-coverage',
|
|
277
|
-
`Validated ${validatedCompatibilityManifestCount}/${REQUIRED_SKILL_DOMAINS.length} required skill compatibility manifests`
|
|
278
|
-
);
|
|
279
|
-
}
|
|
185
|
+
pushResult(
|
|
186
|
+
results,
|
|
187
|
+
true,
|
|
188
|
+
'compatibility-manifest-coverage',
|
|
189
|
+
'Skill compatibility manifest gate has been retired in V3 purge mode'
|
|
190
|
+
);
|
|
280
191
|
|
|
281
192
|
const backendArchitectureRuleContent = readText(BACKEND_ARCHITECTURE_RULE_PATH);
|
|
282
193
|
if (!backendArchitectureRuleContent) {
|
|
@@ -359,6 +270,82 @@ function runReleaseGate() {
|
|
|
359
270
|
`documentation-boundary-audit executed (passed=${documentationBoundaryAuditExecution.report.passed}, failures=${documentationBoundaryAuditExecution.report.failureCount})`
|
|
360
271
|
);
|
|
361
272
|
|
|
273
|
+
const hasMachineReadableBoundaryDiagnostics = typeof documentationBoundaryAuditExecution.report?.reportVersion === 'string'
|
|
274
|
+
&& Array.isArray(documentationBoundaryAuditExecution.report?.boundaryResults)
|
|
275
|
+
&& Array.isArray(documentationBoundaryAuditExecution.report?.violations)
|
|
276
|
+
&& documentationBoundaryAuditExecution.report.boundaryResults.every((boundaryResult) => (
|
|
277
|
+
typeof boundaryResult?.boundaryName === 'string'
|
|
278
|
+
&& typeof boundaryResult?.requirement === 'string'
|
|
279
|
+
&& Array.isArray(boundaryResult?.expectedDocumentationPaths)
|
|
280
|
+
&& Array.isArray(boundaryResult?.suggestedActions)
|
|
281
|
+
));
|
|
282
|
+
|
|
283
|
+
if (hasMachineReadableBoundaryDiagnostics) {
|
|
284
|
+
pushResult(
|
|
285
|
+
results,
|
|
286
|
+
true,
|
|
287
|
+
'documentation-boundary-diagnostics-machine-readable',
|
|
288
|
+
`Boundary diagnostics are machine-readable and actionable (reportVersion=${documentationBoundaryAuditExecution.report.reportVersion})`
|
|
289
|
+
);
|
|
290
|
+
} else {
|
|
291
|
+
pushResult(
|
|
292
|
+
results,
|
|
293
|
+
false,
|
|
294
|
+
'documentation-boundary-diagnostics-machine-readable',
|
|
295
|
+
'Documentation boundary diagnostics are missing required machine-readable actionable fields'
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const reportScope = documentationBoundaryAuditExecution.report?.autoDocsSyncScope;
|
|
300
|
+
const explicitBoundaries = Array.isArray(reportScope?.explicitBoundaries)
|
|
301
|
+
? reportScope.explicitBoundaries
|
|
302
|
+
: [];
|
|
303
|
+
const isPhaseOneScopeBounded = reportScope?.phase === AUTO_DOCS_SYNC_SCOPE_PHASE
|
|
304
|
+
&& reportScope?.bounded === true
|
|
305
|
+
&& AUTO_DOCS_SYNC_SCOPE_BOUNDARIES.every((boundaryName) => explicitBoundaries.includes(boundaryName));
|
|
306
|
+
|
|
307
|
+
if (isPhaseOneScopeBounded) {
|
|
308
|
+
pushResult(
|
|
309
|
+
results,
|
|
310
|
+
true,
|
|
311
|
+
'auto-docs-sync-scope-phase1',
|
|
312
|
+
`Auto-doc sync scope is explicitly bounded to phase-1 boundaries (${explicitBoundaries.join(', ')})`
|
|
313
|
+
);
|
|
314
|
+
} else {
|
|
315
|
+
pushResult(
|
|
316
|
+
results,
|
|
317
|
+
false,
|
|
318
|
+
'auto-docs-sync-scope-phase1',
|
|
319
|
+
'Auto-doc sync scope is missing explicit phase-1 boundary metadata'
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const rolloutMetrics = documentationBoundaryAuditExecution.report?.rolloutMetrics;
|
|
324
|
+
const hasValidPrecision = typeof rolloutMetrics?.precision === 'number'
|
|
325
|
+
&& rolloutMetrics.precision >= 0
|
|
326
|
+
&& rolloutMetrics.precision <= 1;
|
|
327
|
+
const hasValidRecall = typeof rolloutMetrics?.recall === 'number'
|
|
328
|
+
&& rolloutMetrics.recall >= 0
|
|
329
|
+
&& rolloutMetrics.recall <= 1;
|
|
330
|
+
const hasTimestampedEvidence = typeof rolloutMetrics?.measuredAt === 'string'
|
|
331
|
+
&& rolloutMetrics.measuredAt.length > 0;
|
|
332
|
+
|
|
333
|
+
if (hasValidPrecision && hasValidRecall && hasTimestampedEvidence) {
|
|
334
|
+
pushResult(
|
|
335
|
+
results,
|
|
336
|
+
true,
|
|
337
|
+
'auto-docs-sync-rollout-metrics',
|
|
338
|
+
`Auto-doc sync rollout metrics are present (precision=${rolloutMetrics.precision.toFixed(4)}, recall=${rolloutMetrics.recall.toFixed(4)})`
|
|
339
|
+
);
|
|
340
|
+
} else {
|
|
341
|
+
pushResult(
|
|
342
|
+
results,
|
|
343
|
+
false,
|
|
344
|
+
'auto-docs-sync-rollout-metrics',
|
|
345
|
+
'Auto-doc sync rollout metrics are missing precision/recall or timestamped evidence'
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
|
|
362
349
|
if (documentationBoundaryAuditExecution.report.passed === true) {
|
|
363
350
|
pushResult(
|
|
364
351
|
results,
|
|
@@ -367,17 +354,28 @@ function runReleaseGate() {
|
|
|
367
354
|
'Documentation hard-rule passed for all triggered boundaries'
|
|
368
355
|
);
|
|
369
356
|
} else {
|
|
370
|
-
const failedDocumentationBoundaries = Array.isArray(documentationBoundaryAuditExecution.report.
|
|
371
|
-
? documentationBoundaryAuditExecution.report.
|
|
372
|
-
|
|
357
|
+
const failedDocumentationBoundaries = Array.isArray(documentationBoundaryAuditExecution.report.violations)
|
|
358
|
+
? documentationBoundaryAuditExecution.report.violations.map((violation) => {
|
|
359
|
+
const failureCode = violation?.diagnosticCode || 'BOUNDARY_DOCS_SYNC_REQUIRED';
|
|
360
|
+
const changedFiles = Array.isArray(violation?.changedFiles) && violation.changedFiles.length > 0
|
|
361
|
+
? violation.changedFiles.join(', ')
|
|
362
|
+
: 'unknown-changed-files';
|
|
363
|
+
const suggestion = Array.isArray(violation?.suggestedActions) && violation.suggestedActions.length > 0
|
|
364
|
+
? violation.suggestedActions[0]
|
|
365
|
+
: 'Update matching boundary documentation in the same scope.';
|
|
366
|
+
return `${failureCode} (${violation?.boundaryName || 'unknown-boundary'}): ${changedFiles}. Action: ${suggestion}`;
|
|
367
|
+
})
|
|
368
|
+
: Array.isArray(documentationBoundaryAuditExecution.report.failures)
|
|
369
|
+
? documentationBoundaryAuditExecution.report.failures
|
|
370
|
+
: [];
|
|
373
371
|
const failureSummary = failedDocumentationBoundaries.length > 0
|
|
374
372
|
? failedDocumentationBoundaries.join('; ')
|
|
375
|
-
: '
|
|
373
|
+
: '';
|
|
376
374
|
pushResult(
|
|
377
375
|
results,
|
|
378
376
|
false,
|
|
379
377
|
'documentation-boundary-hard-rule',
|
|
380
|
-
`Documentation hard-rule failed: ${failureSummary}`
|
|
378
|
+
`Documentation hard-rule failed: ${failureSummary || 'Documentation boundary audit failed without boundary failure details'}`
|
|
381
379
|
);
|
|
382
380
|
}
|
|
383
381
|
}
|
|
@@ -673,46 +671,24 @@ function runReleaseGate() {
|
|
|
673
671
|
}
|
|
674
672
|
}
|
|
675
673
|
|
|
676
|
-
const
|
|
677
|
-
if (!
|
|
678
|
-
pushResult(results, false, '
|
|
679
|
-
} else {
|
|
680
|
-
pushResult(results, true, 'frontend-parity-checklist-exists', `${FRONTEND_PARITY_CHECKLIST_PATH} is present`);
|
|
681
|
-
|
|
682
|
-
const missingFrontendParitySnippets = REQUIRED_FRONTEND_PARITY_SNIPPETS.filter(
|
|
683
|
-
(requiredSnippet) => !frontendParityChecklistContent.includes(requiredSnippet)
|
|
684
|
-
);
|
|
685
|
-
|
|
686
|
-
if (missingFrontendParitySnippets.length === 0) {
|
|
687
|
-
pushResult(results, true, 'frontend-parity-checklist-coverage', 'Frontend parity checklist sections are complete');
|
|
688
|
-
} else {
|
|
689
|
-
pushResult(
|
|
690
|
-
results,
|
|
691
|
-
false,
|
|
692
|
-
'frontend-parity-checklist-coverage',
|
|
693
|
-
`Missing frontend parity checklist sections: ${missingFrontendParitySnippets.join(', ')}`
|
|
694
|
-
);
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
const frontendExcellenceRubricContent = readText(FRONTEND_EXCELLENCE_RUBRIC_PATH);
|
|
699
|
-
if (!frontendExcellenceRubricContent) {
|
|
700
|
-
pushResult(results, false, 'frontend-excellence-rubric-exists', `Missing ${FRONTEND_EXCELLENCE_RUBRIC_PATH}`);
|
|
674
|
+
const architectureReviewChecklistContent = readText(ARCHITECTURE_REVIEW_CHECKLIST_PATH);
|
|
675
|
+
if (!architectureReviewChecklistContent) {
|
|
676
|
+
pushResult(results, false, 'architecture-review-checklist-exists', `Missing ${ARCHITECTURE_REVIEW_CHECKLIST_PATH}`);
|
|
701
677
|
} else {
|
|
702
|
-
pushResult(results, true, '
|
|
678
|
+
pushResult(results, true, 'architecture-review-checklist-exists', `${ARCHITECTURE_REVIEW_CHECKLIST_PATH} is present`);
|
|
703
679
|
|
|
704
|
-
const
|
|
705
|
-
(requiredSnippet) => !
|
|
680
|
+
const missingArchitectureChecklistSnippets = REQUIRED_ARCHITECTURE_REVIEW_CHECKLIST_SNIPPETS.filter(
|
|
681
|
+
(requiredSnippet) => !architectureReviewChecklistContent.includes(requiredSnippet)
|
|
706
682
|
);
|
|
707
683
|
|
|
708
|
-
if (
|
|
709
|
-
pushResult(results, true, '
|
|
684
|
+
if (missingArchitectureChecklistSnippets.length === 0) {
|
|
685
|
+
pushResult(results, true, 'architecture-review-checklist-coverage', 'Architecture review checklist sections are complete');
|
|
710
686
|
} else {
|
|
711
687
|
pushResult(
|
|
712
688
|
results,
|
|
713
689
|
false,
|
|
714
|
-
'
|
|
715
|
-
`Missing
|
|
690
|
+
'architecture-review-checklist-coverage',
|
|
691
|
+
`Missing architecture review checklist sections: ${missingArchitectureChecklistSnippets.join(', ')}`
|
|
716
692
|
);
|
|
717
693
|
}
|
|
718
694
|
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* sync-thin-adapters.mjs
|
|
5
|
+
*
|
|
6
|
+
* Regenerates thin instruction adapters from the canonical policy source
|
|
7
|
+
* and keeps canonical hash metadata synchronized.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* - node scripts/sync-thin-adapters.mjs
|
|
11
|
+
* - node scripts/sync-thin-adapters.mjs --check
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
15
|
+
import { createHash } from 'node:crypto';
|
|
16
|
+
import { dirname, join, resolve } from 'node:path';
|
|
17
|
+
import { fileURLToPath } from 'node:url';
|
|
18
|
+
|
|
19
|
+
const SCRIPT_FILE_PATH = fileURLToPath(import.meta.url);
|
|
20
|
+
const ROOT_DIR = resolve(dirname(SCRIPT_FILE_PATH), '..');
|
|
21
|
+
const CANONICAL_SOURCE_PATH = '.instructions.md';
|
|
22
|
+
const CANONICAL_SOURCE_ABSOLUTE_PATH = join(ROOT_DIR, CANONICAL_SOURCE_PATH);
|
|
23
|
+
const IS_CHECK_MODE = process.argv.includes('--check');
|
|
24
|
+
|
|
25
|
+
function normalizeLineEndings(content) {
|
|
26
|
+
return content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function buildAgentsAdapter(canonicalHash) {
|
|
30
|
+
return `# AGENTS.md - Thin Adapter
|
|
31
|
+
|
|
32
|
+
Adapter Mode: thin
|
|
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
|
+
## Mandatory Bootstrap Chain
|
|
40
|
+
|
|
41
|
+
1. Load [.instructions.md](.instructions.md) first as the single source of truth.
|
|
42
|
+
2. Read baseline governance from [.agent-context/rules/](.agent-context/rules).
|
|
43
|
+
3. Apply request templates from [.agent-context/prompts/](.agent-context/prompts).
|
|
44
|
+
4. Enforce review contracts from [.agent-context/review-checklists/](.agent-context/review-checklists).
|
|
45
|
+
5. Read change-risk maps and continuity state from [.agent-context/state/](.agent-context/state).
|
|
46
|
+
6. Enforce policy thresholds from [.agent-context/policies/](.agent-context/policies).
|
|
47
|
+
7. Use dynamic stack and architecture reasoning from project context docs and live research signals.
|
|
48
|
+
|
|
49
|
+
## Trigger Rules
|
|
50
|
+
|
|
51
|
+
- New project or module requests: propose architecture first and wait for approval.
|
|
52
|
+
- Refactor or fix requests: propose plan first, then execute safely.
|
|
53
|
+
- Completion: run [.agent-context/review-checklists/pr-checklist.md](.agent-context/review-checklists/pr-checklist.md) before declaring done.
|
|
54
|
+
|
|
55
|
+
If this adapter drifts from canonical behavior, refresh from [.instructions.md](.instructions.md) and update the hash metadata.
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function buildCopilotAdapter(canonicalHash) {
|
|
60
|
+
return `# GitHub Copilot Instructions - Thin Adapter
|
|
61
|
+
|
|
62
|
+
Adapter Mode: thin
|
|
63
|
+
Adapter Source: .instructions.md
|
|
64
|
+
Canonical Snapshot SHA256: ${canonicalHash}
|
|
65
|
+
|
|
66
|
+
The canonical policy source for this repository is [.instructions.md](../.instructions.md).
|
|
67
|
+
|
|
68
|
+
## Required Load Order
|
|
69
|
+
|
|
70
|
+
1. Read [.instructions.md](../.instructions.md) first.
|
|
71
|
+
2. Read baseline rules in [.agent-context/rules/](../.agent-context/rules).
|
|
72
|
+
3. Load request templates from [.agent-context/prompts/](../.agent-context/prompts).
|
|
73
|
+
4. Apply review contracts from [.agent-context/review-checklists/](../.agent-context/review-checklists).
|
|
74
|
+
5. Apply state awareness from [.agent-context/state/](../.agent-context/state) and thresholds from [.agent-context/policies/](../.agent-context/policies).
|
|
75
|
+
6. Resolve stack and architecture choices dynamically from project context docs plus live evidence.
|
|
76
|
+
|
|
77
|
+
## Completion Gate
|
|
78
|
+
|
|
79
|
+
Run [.agent-context/review-checklists/pr-checklist.md](../.agent-context/review-checklists/pr-checklist.md) before declaring work complete.
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function buildGeminiAdapter(canonicalHash) {
|
|
84
|
+
return `# Gemini Instructions - Thin Adapter
|
|
85
|
+
|
|
86
|
+
Adapter Mode: thin
|
|
87
|
+
Adapter Source: .instructions.md
|
|
88
|
+
Canonical Snapshot SHA256: ${canonicalHash}
|
|
89
|
+
|
|
90
|
+
Canonical policy source: [.instructions.md](../.instructions.md).
|
|
91
|
+
|
|
92
|
+
## Bootstrap Sequence
|
|
93
|
+
|
|
94
|
+
1. Load [.instructions.md](../.instructions.md) first.
|
|
95
|
+
2. Apply baseline rules from [.agent-context/rules/](../.agent-context/rules).
|
|
96
|
+
3. Load request templates from [.agent-context/prompts/](../.agent-context/prompts).
|
|
97
|
+
4. Apply review contracts from [.agent-context/review-checklists/](../.agent-context/review-checklists).
|
|
98
|
+
5. Apply state awareness from [.agent-context/state/](../.agent-context/state) and policy thresholds from [.agent-context/policies/](../.agent-context/policies).
|
|
99
|
+
6. Resolve stack and architecture choices dynamically from project context docs plus live evidence.
|
|
100
|
+
|
|
101
|
+
## Completion Gate
|
|
102
|
+
|
|
103
|
+
Run [.agent-context/review-checklists/pr-checklist.md](../.agent-context/review-checklists/pr-checklist.md) before declaring completion.
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const ADAPTERS = [
|
|
108
|
+
{
|
|
109
|
+
relativePath: 'AGENTS.md',
|
|
110
|
+
buildContent: buildAgentsAdapter,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
relativePath: '.github/copilot-instructions.md',
|
|
114
|
+
buildContent: buildCopilotAdapter,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
relativePath: '.gemini/instructions.md',
|
|
118
|
+
buildContent: buildGeminiAdapter,
|
|
119
|
+
},
|
|
120
|
+
];
|
|
121
|
+
|
|
122
|
+
async function main() {
|
|
123
|
+
const canonicalContent = normalizeLineEndings(await readFile(CANONICAL_SOURCE_ABSOLUTE_PATH, 'utf8'));
|
|
124
|
+
const canonicalHash = createHash('sha256').update(canonicalContent).digest('hex');
|
|
125
|
+
|
|
126
|
+
let hasDrift = false;
|
|
127
|
+
|
|
128
|
+
for (const adapter of ADAPTERS) {
|
|
129
|
+
const adapterAbsolutePath = join(ROOT_DIR, adapter.relativePath);
|
|
130
|
+
const expectedContent = adapter.buildContent(canonicalHash);
|
|
131
|
+
|
|
132
|
+
if (IS_CHECK_MODE) {
|
|
133
|
+
const existingContent = normalizeLineEndings(await readFile(adapterAbsolutePath, 'utf8'));
|
|
134
|
+
const expectedNormalized = normalizeLineEndings(expectedContent);
|
|
135
|
+
if (existingContent !== expectedNormalized) {
|
|
136
|
+
hasDrift = true;
|
|
137
|
+
console.error(`[DRIFT] ${adapter.relativePath} does not match canonical adapter output.`);
|
|
138
|
+
} else {
|
|
139
|
+
console.log(`[OK] ${adapter.relativePath} is synchronized.`);
|
|
140
|
+
}
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
await writeFile(adapterAbsolutePath, `${expectedContent.trimEnd()}\n`, 'utf8');
|
|
145
|
+
console.log(`[SYNC] ${adapter.relativePath}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (IS_CHECK_MODE) {
|
|
149
|
+
if (hasDrift) {
|
|
150
|
+
process.exitCode = 1;
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log('[OK] All thin adapters match canonical source output.');
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
main().catch((error) => {
|
|
159
|
+
console.error(`[FATAL] Failed to synchronize thin adapters: ${error.message}`);
|
|
160
|
+
process.exitCode = 1;
|
|
161
|
+
});
|