@ryuenn3123/agentic-senior-core 3.0.38 → 3.0.39
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 +2 -1
- package/.agent-context/rules/frontend-architecture.md +1 -1
- package/.agent-context/state/architecture-map.md +32 -17
- package/.agent-context/state/dependency-map.md +31 -22
- package/.cursorrules +1 -1
- package/.windsurfrules +1 -1
- package/CONTRIBUTING.md +2 -0
- package/README.md +6 -5
- package/lib/cli/commands/upgrade.mjs +2 -9
- package/lib/cli/init-detection-flow.mjs +9 -1
- package/lib/cli/init-selection.mjs +0 -5
- package/lib/cli/project-scaffolder/design-contract.mjs +2 -2
- package/lib/cli/project-scaffolder.mjs +0 -2
- package/package.json +1 -1
- package/scripts/bump-version.mjs +15 -13
- package/scripts/validate.mjs +20 -0
- package/scripts/validate-evidence-bundle.mjs +0 -76
|
@@ -57,7 +57,7 @@ Before UI code, record:
|
|
|
57
57
|
- one morphology or composition choice that avoids interchangeable card stacks when the product allows it
|
|
58
58
|
- at least three at-a-glance product-specific signals for new screens or broad redesigns
|
|
59
59
|
|
|
60
|
-
Do not ship AI-safe UI. Record exact drift signals in `reviewRubric`; at minimum reject decorative grid wallpaper, soft glow backgrounds, generic abstract marks, and first-output composition with only local copy swapped in when they have no product function.
|
|
60
|
+
Do not ship AI-safe UI. Record exact drift signals in `reviewRubric`; at minimum reject decorative grid wallpaper, default line backgrounds, soft glow backgrounds, generic abstract marks, and first-output composition with only local copy swapped in when they have no product function.
|
|
61
61
|
|
|
62
62
|
## AI Color and Template Residue Audit
|
|
63
63
|
|
|
@@ -171,6 +171,7 @@ Block or flag:
|
|
|
171
171
|
- scale-only responsive behavior
|
|
172
172
|
- default component-kit styling without product rationale
|
|
173
173
|
- nonfunctional background effects, including decorative grid wallpaper
|
|
174
|
+
- grid or line backgrounds used as filler instead of product function
|
|
174
175
|
- palette choices that use readability as an excuse for safe defaults
|
|
175
176
|
- visual direction copied from unrelated memory or external references
|
|
176
177
|
- genericity findings that cannot name the exact drift signal
|
|
@@ -43,7 +43,7 @@ For new screens or broad redesigns, make at least three at-a-glance product-spec
|
|
|
43
43
|
|
|
44
44
|
Use the rename test: if the UI can be renamed to another product category without changing composition, palette, iconography, and motion language, revise before implementation is considered complete.
|
|
45
45
|
|
|
46
|
-
Background lines, grids, scanlines, noise, glows, blobs, abstract logos, and decorative geometry are invalid as wallpaper. Use them only for a named product function such as alignment, crop guidance, map/route orientation, timeline reading, measurement, status, or motion continuity.
|
|
46
|
+
Background lines, grids, scanlines, noise, glows, blobs, abstract logos, and decorative geometry are invalid as wallpaper. Do not use grid or line backgrounds as first-output filler. Use them only for a named product function such as alignment, crop guidance, map/route orientation, timeline reading, measurement, status, or motion continuity.
|
|
47
47
|
|
|
48
48
|
## Dynamic Anchor Gate
|
|
49
49
|
|
|
@@ -1,25 +1,40 @@
|
|
|
1
|
-
# Architecture Map
|
|
1
|
+
# Architecture Map
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use this file as repo-local agent context. It records the current governance architecture and the boundaries agents must protect.
|
|
4
4
|
|
|
5
5
|
## Boundary Classification
|
|
6
6
|
|
|
7
|
-
|
|
|
8
|
-
|
|
9
|
-
| `
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
| `
|
|
13
|
-
| `
|
|
7
|
+
| Surface | Criticality | Change Policy | Required Checks |
|
|
8
|
+
| --- | --- | --- | --- |
|
|
9
|
+
| `.instructions.md`, `AGENTS.md`, generated adapters | critical | Keep `.instructions.md` canonical and adapters thin/hash-synced | `npm run sync:adapters`, `npm run check:adapters`, `npm run validate` |
|
|
10
|
+
| `.agent-context/rules/**`, `.agent-context/prompts/**`, `.agent-context/review-checklists/**` | critical | Keep rules imperative, compact, scope-resolved, and non-duplicative | adapter sync, validation, targeted smoke tests |
|
|
11
|
+
| `.agent-context/state/**` | high | Track only seed/config and current operational state; keep generated reports local-only | `npm pack --dry-run`, state README review |
|
|
12
|
+
| `lib/cli/compiler.mjs`, `scripts/sync-thin-adapters.mjs` | critical | Preserve generated surface compatibility across Codex, Cursor, Windsurf, Copilot, Claude, and Gemini | adapter tests, smoke tests, validation |
|
|
13
|
+
| `lib/cli/commands/init.mjs`, `lib/cli/commands/upgrade.mjs` | high | Preserve fresh-project and existing-project behavior without silent stack/style decisions | CLI smoke tests, onboarding report checks |
|
|
14
|
+
| `lib/cli/project-scaffolder/**` | high | Preserve docs-first and design-contract behavior without hardcoded house style | design/detection smoke tests, validation |
|
|
15
|
+
| `scripts/validate*.mjs`, `scripts/validate/**` | high | Keep validation mechanical and aligned with current shipped surfaces | `node ./scripts/validate.mjs`, targeted script checks |
|
|
16
|
+
| `tests/**` | high | Test behavior and contracts, not private implementation trivia | `npm test` |
|
|
17
|
+
| `package.json`, `package-lock.json`, package allowlist | high | Keep release metadata and tarball contents synchronized | `npm pack --dry-run`, release gate |
|
|
14
18
|
|
|
15
|
-
##
|
|
19
|
+
## Frontend Governance Context
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
- Frontend guidance is efficient enough for the current architecture because it is scope-resolved: UI tasks load `bootstrap-design.md` and `frontend-architecture.md`; backend-only tasks do not.
|
|
22
|
+
- Keep the current design contract. It does not prescribe a palette or layout; it requires product evidence, anchor-derived tokens, motion/spatial fit decisions, and accessibility.
|
|
23
|
+
- Do not reduce motion, 3D, canvas, WebGL, or animation guidance. These are capability unlocks, not mandatory decoration.
|
|
24
|
+
- Treat product categories as heuristics only. They must not become style presets.
|
|
25
|
+
- Treat grid, line, glow, blob, and abstract-logo backgrounds as review findings unless they serve a named product function.
|
|
20
26
|
|
|
21
|
-
##
|
|
27
|
+
## Backend Governance Context
|
|
22
28
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
29
|
+
- Backend guidance is efficient enough for the current architecture because backend/API rules are lazy-loaded by scope.
|
|
30
|
+
- Keep global backend principles stack-agnostic: architecture boundaries, validation, safe errors, security, testing, event boundaries, and data design.
|
|
31
|
+
- Do not add framework-specific governance adapters unless real repo evidence proves a repeated project need.
|
|
32
|
+
- New dependencies are allowed when they improve efficiency, delivery time, correctness, or maintainability, and current official docs support the choice.
|
|
33
|
+
|
|
34
|
+
## Agent Behavior
|
|
35
|
+
|
|
36
|
+
1. Load the smallest relevant rule set.
|
|
37
|
+
2. Use README only for overview/install/user context when governance files conflict.
|
|
38
|
+
3. Preserve generated adapter sync before release.
|
|
39
|
+
4. Treat stale generated state, dual lockfiles, and obsolete V2/V3 transition files as cleanup findings.
|
|
40
|
+
5. Before claiming done, run the relevant validation gate and report any skipped checks.
|
|
@@ -1,32 +1,41 @@
|
|
|
1
|
-
# Dependency Map
|
|
1
|
+
# Dependency Map
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use this map to keep Agentic-Senior-Core's CLI, governance, and validation layers from collapsing into circular or over-coupled code.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Allowed Dependency Direction
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
4.
|
|
7
|
+
1. `bin/` may call command modules only.
|
|
8
|
+
2. `lib/cli/commands/**` may orchestrate detector, compiler, scaffolder, memory, token, backup, rollback, preflight, and utility modules.
|
|
9
|
+
3. `lib/cli/compiler.mjs` may read constants and utilities, but must not import command modules.
|
|
10
|
+
4. `lib/cli/project-scaffolder/**` may use utilities and local scaffolder submodules; validation logic stays below the scaffolder entrypoint.
|
|
11
|
+
5. `scripts/**` may call CLI library modules for audits and reports, but release/validation scripts must avoid mutating generated state unless that is their explicit job.
|
|
12
|
+
6. `tests/**` may exercise public CLI commands, public module exports, scripts, and generated artifacts.
|
|
13
|
+
7. `.agent-context/**` stores governance data and must not depend on generated adapter content as its authority.
|
|
11
14
|
|
|
12
|
-
## Module
|
|
15
|
+
## Module Constraints
|
|
13
16
|
|
|
14
|
-
| Source
|
|
15
|
-
|
|
16
|
-
| `
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
19
|
-
| `
|
|
17
|
+
| Source | Allowed Dependencies | Forbidden Dependencies |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| `bin/agentic-senior-core.js` | `lib/cli/commands/*` | direct compiler, scaffolder, or validation internals |
|
|
20
|
+
| `lib/cli/commands/init.mjs` | detector, compiler, scaffolder, token/memory continuity, setup helpers | UI style presets, backend framework defaults, generated adapters as source |
|
|
21
|
+
| `lib/cli/commands/upgrade.mjs` | detector, compiler, scaffolder seeds, backup/rollback, shared setup helpers | duplicated setup-policy helpers, silent stack migration |
|
|
22
|
+
| `lib/cli/project-scaffolder.mjs` | stable public scaffolder exports | private validation helpers that do not need public API exposure |
|
|
23
|
+
| `lib/cli/project-scaffolder/design-contract.mjs` | validation submodule, constants, utilities | hardcoded final palettes, fixed layouts, external design memory |
|
|
24
|
+
| `scripts/sync-thin-adapters.mjs` | canonical instructions and adapter targets | hand-maintained duplicate policy blocks |
|
|
25
|
+
| `scripts/validate*.mjs` | config, coverage checks, file evidence | stale V2 skill-marketplace artifacts |
|
|
26
|
+
| `.agent-context/prompts/bootstrap-design.md` | current repo evidence and frontend rule | prior-chat visuals, unrelated screenshots, template style presets |
|
|
20
27
|
|
|
21
28
|
## Circular Dependency Guardrail
|
|
22
29
|
|
|
23
|
-
|
|
30
|
+
- Reject `commands -> project-scaffolder -> commands`.
|
|
31
|
+
- Reject `compiler -> commands`.
|
|
32
|
+
- Reject `scripts/validate -> tests`.
|
|
33
|
+
- Reject generated adapters becoming inputs for `.instructions.md` or `.agent-context/`.
|
|
34
|
+
- Move repeated command setup policy into shared helper modules instead of copying local functions.
|
|
24
35
|
|
|
25
|
-
|
|
26
|
-
2. Reject any change introducing `A -> B -> A` cycles.
|
|
27
|
-
3. Move shared contracts to `shared` module when two-way dependencies appear.
|
|
36
|
+
## Package Hygiene
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
- Keep
|
|
38
|
+
- Keep one npm lockfile: `package-lock.json`.
|
|
39
|
+
- Ignore Bun lockfiles unless the package manager strategy changes explicitly.
|
|
40
|
+
- Keep generated reports out of the shipped package.
|
|
41
|
+
- Keep `onboarding-report.json` tracked only as current repo operational state; installed projects regenerate it.
|
package/.cursorrules
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# .cursorrules - Legacy Thin Adapter
|
|
2
2
|
|
|
3
|
-
Generated by Agentic-Senior-Core CLI v3.0.
|
|
3
|
+
Generated by Agentic-Senior-Core CLI v3.0.39
|
|
4
4
|
Adapter Mode: legacy-thin
|
|
5
5
|
Adapter Source: .agent-instructions.md when present; fallback .instructions.md
|
|
6
6
|
Canonical baseline: .instructions.md
|
package/.windsurfrules
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# .windsurfrules - Legacy Thin Adapter
|
|
2
2
|
|
|
3
|
-
Generated by Agentic-Senior-Core CLI v3.0.
|
|
3
|
+
Generated by Agentic-Senior-Core CLI v3.0.39
|
|
4
4
|
Adapter Mode: legacy-thin
|
|
5
5
|
Adapter Source: .agent-instructions.md when present; fallback .instructions.md
|
|
6
6
|
Canonical baseline: .instructions.md
|
package/CONTRIBUTING.md
CHANGED
|
@@ -95,6 +95,8 @@ If all three are "yes", it belongs here.
|
|
|
95
95
|
|
|
96
96
|
## Local Development
|
|
97
97
|
|
|
98
|
+
The npm package is published under `@ryuenn3123`, while the GitHub repository is hosted under `fatidaprilian`.
|
|
99
|
+
|
|
98
100
|
```bash
|
|
99
101
|
# Clone
|
|
100
102
|
git clone https://github.com/fatidaprilian/Agentic-Senior-Core.git
|
package/README.md
CHANGED
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
**Production-grade Rules Engine (Governance Engine) for AI coding agents.**
|
|
11
11
|
Works with Cursor, Windsurf, GitHub Copilot, Claude Code, Gemini, and other LLM-powered IDE workflows.
|
|
12
12
|
|
|
13
|
-
Latest release: 3.0.
|
|
13
|
+
Latest release: 3.0.39 (2026-04-30).
|
|
14
14
|
|
|
15
|
-
Highlights in 3.0.
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
15
|
+
Highlights in 3.0.39:
|
|
16
|
+
- Post-release hygiene removes stale V2 evidence-bundle and Bun lockfile drift surfaces.
|
|
17
|
+
- Package and lockfile validation now blocks version drift and accidental dual package-manager state.
|
|
18
|
+
- Repo-local agent context now documents frontend/backend governance boundaries and anti-grid wallpaper handling.
|
|
19
19
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
@@ -34,6 +34,7 @@ One command to initialize rules, checklists, thin discovery adapters, and a comp
|
|
|
34
34
|
> **See [docs/deep-dive.md](docs/deep-dive.md) and [docs/roadmap.md](docs/roadmap.md) for advanced configuration, planning mode, snapshot, and realtime options.**
|
|
35
35
|
|
|
36
36
|
- This command writes `.agent-context/state/v3-purge-audit.json` and reports whether static directory deletion is safe.
|
|
37
|
+
- Package scope is `@ryuenn3123`; the GitHub repository owner is `fatidaprilian`.
|
|
37
38
|
|
|
38
39
|
---
|
|
39
40
|
|
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
buildDesignIntentSeedFromSignals,
|
|
49
49
|
} from '../project-scaffolder.mjs';
|
|
50
50
|
import { ensureActiveMemorySnapshot } from '../memory-continuity.mjs';
|
|
51
|
+
import { buildExistingProjectMajorConstraints } from '../init-detection-flow.mjs';
|
|
51
52
|
|
|
52
53
|
export function parseUpgradeArguments(commandArguments) {
|
|
53
54
|
const parsedUpgradeOptions = {
|
|
@@ -102,14 +103,6 @@ export function parseUpgradeArguments(commandArguments) {
|
|
|
102
103
|
return parsedUpgradeOptions;
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
function buildExistingProjectMajorConstraints() {
|
|
106
|
-
return [
|
|
107
|
-
'Preserve existing project markers and avoid forced stack migration.',
|
|
108
|
-
'Use runtime markers as evidence only unless the user already recorded an explicit runtime constraint.',
|
|
109
|
-
'Upgrade keeps prior explicit onboarding constraints but does not create new stack or blueprint decisions.',
|
|
110
|
-
];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
106
|
function buildUpgradeDesignIntentSeed({
|
|
114
107
|
targetDirectoryPath,
|
|
115
108
|
packageManifest,
|
|
@@ -243,7 +236,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
243
236
|
})
|
|
244
237
|
: null;
|
|
245
238
|
|
|
246
|
-
const detectionMajorConstraints = buildExistingProjectMajorConstraints();
|
|
239
|
+
const detectionMajorConstraints = buildExistingProjectMajorConstraints({ mode: 'upgrade' });
|
|
247
240
|
const detectionTransparency = {
|
|
248
241
|
declaredAt: new Date().toISOString(),
|
|
249
242
|
declarationType: 'existing-project',
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
export function buildExistingProjectMajorConstraints() {
|
|
1
|
+
export function buildExistingProjectMajorConstraints({ mode = 'init' } = {}) {
|
|
2
|
+
if (mode === 'upgrade') {
|
|
3
|
+
return [
|
|
4
|
+
'Preserve existing project markers and avoid forced stack migration.',
|
|
5
|
+
'Use runtime markers as evidence only unless the user already recorded an explicit runtime constraint.',
|
|
6
|
+
'Upgrade keeps prior explicit onboarding constraints but does not create new stack or blueprint decisions.',
|
|
7
|
+
];
|
|
8
|
+
}
|
|
9
|
+
|
|
2
10
|
return [
|
|
3
11
|
'Preserve existing project markers and avoid forced stack migration.',
|
|
4
12
|
'Use detected runtime markers as evidence only; do not convert them into stack migration or design direction.',
|
|
@@ -27,8 +27,3 @@ export function normalizeAdditionalBlueprintSelection(selectedBlueprintFileName,
|
|
|
27
27
|
(blueprintFileName) => blueprintFileName && blueprintFileName !== selectedBlueprintFileName
|
|
28
28
|
)));
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
export function resolveScopeBlueprintCandidates(projectScopeKey) {
|
|
32
|
-
void projectScopeKey;
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
@@ -274,7 +274,7 @@ function buildDesignIntentContractObject({
|
|
|
274
274
|
},
|
|
275
275
|
aiSafeUiAudit: {
|
|
276
276
|
status: 'agent-must-complete-before-ui-implementation',
|
|
277
|
-
failureDefinition: 'AI-safe UI uses template cards, generic marks, decorative grid wallpaper, safe palettes, glow backgrounds, or copied scaffold composition.',
|
|
277
|
+
failureDefinition: 'AI-safe UI uses template cards, generic marks, decorative grid or line wallpaper, safe palettes, glow backgrounds, or copied scaffold composition.',
|
|
278
278
|
interchangeabilityTest: `If this UI can be renamed from ${projectName} to another product category without changing composition, palette, iconography, and motion, revise it.`,
|
|
279
279
|
requiredProductSpecificSignals: [
|
|
280
280
|
'agent-defined-product-specific-data-treatment',
|
|
@@ -282,7 +282,7 @@ function buildDesignIntentContractObject({
|
|
|
282
282
|
'agent-defined-product-specific-morphology-iconography-or-spatial-structure',
|
|
283
283
|
],
|
|
284
284
|
paletteExplorationRule: 'Use a visually exploratory product-derived palette with WCAG contrast and status clarity.',
|
|
285
|
-
backgroundPatternRule: 'Lines, grids, scanlines, noise, glows, blobs, logos, and geometry must serve a named product function.',
|
|
285
|
+
backgroundPatternRule: 'Lines, grids, scanlines, noise, glows, blobs, logos, and geometry must serve a named product function; never use grid or line backgrounds as first-output filler.',
|
|
286
286
|
aiColorAudit: {
|
|
287
287
|
status: 'agent-must-complete-before-ui-implementation',
|
|
288
288
|
failureDefinition: 'AI color drift uses safe defaults before deriving roles from the product anchor.',
|
package/package.json
CHANGED
package/scripts/bump-version.mjs
CHANGED
|
@@ -48,7 +48,21 @@ async function bumpVersion() {
|
|
|
48
48
|
await writeTextFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
49
49
|
console.log(`Updated package.json (was ${oldVersion})`);
|
|
50
50
|
|
|
51
|
-
// 2. Update
|
|
51
|
+
// 2. Update package-lock.json when it exists.
|
|
52
|
+
const packageLockPath = path.join(ROOT_DIR, 'package-lock.json');
|
|
53
|
+
if (await fileExists(packageLockPath)) {
|
|
54
|
+
const packageLock = JSON.parse(await readTextFile(packageLockPath));
|
|
55
|
+
if (packageLock.name === packageJson.name) {
|
|
56
|
+
packageLock.version = newVersion;
|
|
57
|
+
}
|
|
58
|
+
if (packageLock.packages?.['']?.name === packageJson.name) {
|
|
59
|
+
packageLock.packages[''].version = newVersion;
|
|
60
|
+
}
|
|
61
|
+
await writeTextFile(packageLockPath, JSON.stringify(packageLock, null, 2) + '\n');
|
|
62
|
+
console.log('Updated package-lock.json');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 3. Update docs/deep_analysis_and_roadmap_backlog.md
|
|
52
66
|
const roadmapPath = path.join(ROOT_DIR, 'docs', 'deep_analysis_and_roadmap_backlog.md');
|
|
53
67
|
if (await fileExists(roadmapPath)) {
|
|
54
68
|
let roadmapContent = await readTextFile(roadmapPath);
|
|
@@ -57,18 +71,6 @@ async function bumpVersion() {
|
|
|
57
71
|
console.log('Updated docs/deep_analysis_and_roadmap_backlog.md');
|
|
58
72
|
}
|
|
59
73
|
|
|
60
|
-
// 3. Update Rule files (.cursorrules, .windsurfrules)
|
|
61
|
-
const ruleFiles = ['.cursorrules', '.windsurfrules'];
|
|
62
|
-
for (const ruleFile of ruleFiles) {
|
|
63
|
-
const fullPath = path.join(ROOT_DIR, ruleFile);
|
|
64
|
-
if (await fileExists(fullPath)) {
|
|
65
|
-
let content = await readTextFile(fullPath);
|
|
66
|
-
content = content.replace(`Generated by Agentic-Senior-Core CLI v${oldVersion}`, `Generated by Agentic-Senior-Core CLI v${newVersion}`);
|
|
67
|
-
await writeTextFile(fullPath, content);
|
|
68
|
-
console.log(`Updated ${ruleFile}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
74
|
// 4. Update CHANGELOG.md
|
|
73
75
|
const changelogPath = path.join(ROOT_DIR, 'CHANGELOG.md');
|
|
74
76
|
if (await fileExists(changelogPath)) {
|
package/scripts/validate.mjs
CHANGED
|
@@ -42,6 +42,8 @@ const ROOT_DIR = resolve(dirname(SCRIPT_FILE_PATH), '..');
|
|
|
42
42
|
const AGENT_CONTEXT_DIR = join(ROOT_DIR, '.agent-context');
|
|
43
43
|
const CANONICAL_INSTRUCTION_PATH = join(ROOT_DIR, '.instructions.md');
|
|
44
44
|
const PACKAGE_JSON_PATH = join(ROOT_DIR, 'package.json');
|
|
45
|
+
const PACKAGE_LOCK_PATH = join(ROOT_DIR, 'package-lock.json');
|
|
46
|
+
const BUN_LOCK_PATH = join(ROOT_DIR, 'bun.lock');
|
|
45
47
|
const CHANGELOG_PATH = join(ROOT_DIR, 'CHANGELOG.md');
|
|
46
48
|
const README_PATH = join(ROOT_DIR, 'README.md');
|
|
47
49
|
const POLICY_FILE_PATH = join(ROOT_DIR, '.agent-context', 'policies', 'llm-judge-threshold.json');
|
|
@@ -473,6 +475,12 @@ async function validatePackageMetadata() {
|
|
|
473
475
|
} else {
|
|
474
476
|
fail('package.json must publish .instructions.md so init and upgrade can copy the canonical root instructions file');
|
|
475
477
|
}
|
|
478
|
+
|
|
479
|
+
if (await fileExists(BUN_LOCK_PATH)) {
|
|
480
|
+
fail('bun.lock must not be tracked while npm is the package manager source of truth');
|
|
481
|
+
} else {
|
|
482
|
+
pass('No bun.lock drift file present');
|
|
483
|
+
}
|
|
476
484
|
}
|
|
477
485
|
|
|
478
486
|
async function validatePolicyFile() {
|
|
@@ -529,6 +537,18 @@ async function validateVersionConsistency() {
|
|
|
529
537
|
fail(`CHANGELOG.md is missing a ## ${packageVersion} heading`);
|
|
530
538
|
}
|
|
531
539
|
|
|
540
|
+
if (await fileExists(PACKAGE_LOCK_PATH)) {
|
|
541
|
+
const packageLock = JSON.parse(await readTextFile(PACKAGE_LOCK_PATH));
|
|
542
|
+
const rootLockVersion = packageLock.packages?.['']?.version;
|
|
543
|
+
if (packageLock.version === packageVersion && rootLockVersion === packageVersion) {
|
|
544
|
+
pass(`package-lock.json matches package version ${packageVersion}`);
|
|
545
|
+
} else {
|
|
546
|
+
fail(`package-lock.json version drift: expected ${packageVersion}, found ${packageLock.version || 'missing'} / ${rootLockVersion || 'missing'}`);
|
|
547
|
+
}
|
|
548
|
+
} else {
|
|
549
|
+
fail('package-lock.json is required for npm release consistency');
|
|
550
|
+
}
|
|
551
|
+
|
|
532
552
|
for (const generatedRuleFileName of GENERATED_RULE_FILES) {
|
|
533
553
|
const generatedRuleContent = await readTextFile(join(ROOT_DIR, generatedRuleFileName));
|
|
534
554
|
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Validates the structure and content of an evidence bundle for an artifact.
|
|
6
|
-
* Target artifact directory must be provided as an argument.
|
|
7
|
-
*/
|
|
8
|
-
export async function validateEvidenceBundle(artifactPath) {
|
|
9
|
-
const evidenceDirPath = path.join(artifactPath, '.evidence');
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
const stats = await fs.stat(evidenceDirPath);
|
|
13
|
-
if (!stats.isDirectory()) {
|
|
14
|
-
return { passed: false, error: '.evidence is not a directory' };
|
|
15
|
-
}
|
|
16
|
-
} catch {
|
|
17
|
-
return { passed: false, error: 'Missing .evidence directory' };
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const requiredFiles = [
|
|
21
|
-
'compatibility-manifest.json',
|
|
22
|
-
'test-report.json',
|
|
23
|
-
'sbom-excerpt.json'
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
for (const fileName of requiredFiles) {
|
|
27
|
-
try {
|
|
28
|
-
await fs.stat(path.join(evidenceDirPath, fileName));
|
|
29
|
-
} catch {
|
|
30
|
-
return { passed: false, error: `Missing required evidence file: ${fileName}` };
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Validate compatibility manifest structure
|
|
35
|
-
try {
|
|
36
|
-
const manifestData = JSON.parse(await fs.readFile(path.join(evidenceDirPath, 'compatibility-manifest.json'), 'utf8'));
|
|
37
|
-
if (!manifestData.ides || !Array.isArray(manifestData.ides)) {
|
|
38
|
-
return { passed: false, error: 'compatibility-manifest.json is missing the "ides" array' };
|
|
39
|
-
}
|
|
40
|
-
} catch (err) {
|
|
41
|
-
return { passed: false, error: `Invalid compatibility-manifest.json: ${err.message}` };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Validate test report structure
|
|
45
|
-
try {
|
|
46
|
-
const testReportData = JSON.parse(await fs.readFile(path.join(evidenceDirPath, 'test-report.json'), 'utf8'));
|
|
47
|
-
if (typeof testReportData.passed !== 'boolean' || typeof testReportData.total !== 'number') {
|
|
48
|
-
return { passed: false, error: 'test-report.json must contain boolean "passed" and numeric "total"' };
|
|
49
|
-
}
|
|
50
|
-
} catch (err) {
|
|
51
|
-
return { passed: false, error: `Invalid test-report.json: ${err.message}` };
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return { passed: true, error: null };
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Allow CLI usage
|
|
58
|
-
if (process.argv[1] && process.argv[1] === new URL(import.meta.url).pathname || process.argv[1] === import.meta.filename) {
|
|
59
|
-
const targetDir = process.argv[2];
|
|
60
|
-
if (!targetDir) {
|
|
61
|
-
console.error('Usage: node validate-evidence-bundle.mjs <target-directory>');
|
|
62
|
-
process.exit(1);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
validateEvidenceBundle(path.resolve(targetDir))
|
|
66
|
-
.then(result => {
|
|
67
|
-
if (result.passed) {
|
|
68
|
-
console.log('[OK] Evidence bundle is valid.');
|
|
69
|
-
process.exit(0);
|
|
70
|
-
} else {
|
|
71
|
-
console.error(`[FAIL] Evidence bundle validation failed: ${result.error}`);
|
|
72
|
-
process.exit(1);
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
.catch(console.error);
|
|
76
|
-
}
|