@shrkcrft/inspector 0.1.0-alpha.21 → 0.1.0-alpha.23
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/dist/command-recommender.d.ts.map +1 -1
- package/dist/command-recommender.js +110 -1
- package/dist/context-tuning.d.ts +14 -0
- package/dist/context-tuning.d.ts.map +1 -0
- package/dist/context-tuning.js +38 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/knowledge-stale.d.ts +23 -0
- package/dist/knowledge-stale.d.ts.map +1 -1
- package/dist/knowledge-stale.js +58 -9
- package/dist/monorepo-onboarding.d.ts.map +1 -1
- package/dist/monorepo-onboarding.js +122 -12
- package/dist/onboarding.d.ts.map +1 -1
- package/dist/onboarding.js +79 -18
- package/dist/pack-doctor.d.ts +8 -1
- package/dist/pack-doctor.d.ts.map +1 -1
- package/dist/pack-doctor.js +110 -3
- package/dist/pack-quality-score.d.ts.map +1 -1
- package/dist/pack-quality-score.js +7 -8
- package/dist/pack-release-check.d.ts.map +1 -1
- package/dist/pack-release-check.js +23 -20
- package/dist/pack-signature-status.d.ts +9 -3
- package/dist/pack-signature-status.d.ts.map +1 -1
- package/dist/pack-signature-status.js +13 -2
- package/dist/plan-simulation.d.ts.map +1 -1
- package/dist/plan-simulation.js +26 -12
- package/dist/registry-lifecycle.d.ts +8 -0
- package/dist/registry-lifecycle.d.ts.map +1 -1
- package/dist/registry-lifecycle.js +21 -3
- package/dist/resolve-project-config.d.ts +26 -0
- package/dist/resolve-project-config.d.ts.map +1 -0
- package/dist/resolve-project-config.js +128 -0
- package/dist/resolve-verification-commands.d.ts +7 -0
- package/dist/resolve-verification-commands.d.ts.map +1 -1
- package/dist/resolve-verification-commands.js +53 -4
- package/dist/review-packet.d.ts +8 -0
- package/dist/review-packet.d.ts.map +1 -1
- package/dist/review-packet.js +11 -12
- package/dist/sharkcraft-inspector.d.ts.map +1 -1
- package/dist/sharkcraft-inspector.js +28 -2
- package/dist/spec/__tests__/spec-evidence.test.d.ts +2 -0
- package/dist/spec/__tests__/spec-evidence.test.d.ts.map +1 -0
- package/dist/spec/__tests__/spec-evidence.test.js +81 -0
- package/dist/spec/spec-evidence.d.ts +62 -0
- package/dist/spec/spec-evidence.d.ts.map +1 -0
- package/dist/spec/spec-evidence.js +215 -0
- package/dist/spec/spec-review.d.ts +1 -0
- package/dist/spec/spec-review.d.ts.map +1 -1
- package/dist/spec/spec-review.js +5 -0
- package/dist/symbol-index.d.ts +9 -0
- package/dist/symbol-index.d.ts.map +1 -1
- package/dist/symbol-index.js +6 -0
- package/dist/task-packet.d.ts.map +1 -1
- package/dist/task-packet.js +6 -1
- package/dist/task-ranker.d.ts +2 -1
- package/dist/task-ranker.d.ts.map +1 -1
- package/dist/task-ranker.js +30 -5
- package/dist/test-runner.d.ts.map +1 -1
- package/dist/test-runner.js +3 -0
- package/dist/why-file.d.ts.map +1 -1
- package/dist/why-file.js +13 -0
- package/package.json +17 -17
package/dist/onboarding.js
CHANGED
|
@@ -11,7 +11,6 @@ export function buildOnboardingPlan(inspection, options = {}) {
|
|
|
11
11
|
const subDirs = listSubDirs(ws.projectRoot);
|
|
12
12
|
const inferredPathConventions = inferPathConventions(ws, subDirs);
|
|
13
13
|
const inferredVerificationCommands = inferVerificationCommands(ws);
|
|
14
|
-
const inferredBoundaryRules = inferBoundaryRules(ws, subDirs);
|
|
15
14
|
const inferredTemplateCandidates = inferTemplateCandidates(ws, {
|
|
16
15
|
scaffoldTemplates: options.scaffoldTemplates === true,
|
|
17
16
|
});
|
|
@@ -19,6 +18,12 @@ export function buildOnboardingPlan(inspection, options = {}) {
|
|
|
19
18
|
const inferredPipelines = inferPipelines(ws, inferredVerificationCommands);
|
|
20
19
|
const detectedInstructionFiles = detectInstructionFiles(ws.projectRoot);
|
|
21
20
|
const monorepoSummary = buildMonorepoSummary(ws, subDirs);
|
|
21
|
+
// Boundary rules: the non-monorepo guess intentionally returns [] (SharkCraft
|
|
22
|
+
// does not invent boundaries from folder structure). Monorepo layouts, by
|
|
23
|
+
// contrast, surface real enforceable candidates (e.g. packages/* must not
|
|
24
|
+
// import apps/*) — merge them in so they reach the boundaries draft and
|
|
25
|
+
// `init --infer`.
|
|
26
|
+
const inferredBoundaryRules = mergeMonorepoBoundaryRules(inferBoundaryRules(ws, subDirs), monorepoSummary);
|
|
22
27
|
// RecommendPresets now applies a miss penalty (-3 per missing
|
|
23
28
|
// appliesTo profile), so a preferred preset that previously ranked just
|
|
24
29
|
// inside the top 5 can drop out on minor profile changes. Use a wider
|
|
@@ -221,11 +226,40 @@ function packageManagerRunPrefix(manager) {
|
|
|
221
226
|
}
|
|
222
227
|
// ─── Boundary rule candidates ────────────────────────────────────────────────
|
|
223
228
|
export function inferBoundaryRules(_ws, _subDirs) {
|
|
224
|
-
// SharkCraft does not guess your boundary rules
|
|
225
|
-
// explicitly in `sharkcraft/boundaries.ts` once the repo's
|
|
226
|
-
// import directions are known.
|
|
229
|
+
// SharkCraft does not guess your boundary rules from folder structure.
|
|
230
|
+
// Author them explicitly in `sharkcraft/boundaries.ts` once the repo's
|
|
231
|
+
// actual import directions are known. Monorepo-derived candidates are
|
|
232
|
+
// merged in separately via `mergeMonorepoBoundaryRules`.
|
|
227
233
|
return [];
|
|
228
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Merge the monorepo summary's computed boundary candidates into the
|
|
237
|
+
* inferred boundary-rule list. These candidates are derived from the actual
|
|
238
|
+
* workspace layout (apps / packages / libs), so they are enforceable and
|
|
239
|
+
* should reach the boundaries draft + `init --infer`. Deduped by id;
|
|
240
|
+
* existing entries win.
|
|
241
|
+
*/
|
|
242
|
+
function mergeMonorepoBoundaryRules(base, monorepoSummary) {
|
|
243
|
+
const out = [...base];
|
|
244
|
+
if (!monorepoSummary)
|
|
245
|
+
return out;
|
|
246
|
+
const seen = new Set(out.map((b) => b.id));
|
|
247
|
+
for (const c of monorepoSummary.boundaryCandidates) {
|
|
248
|
+
if (seen.has(c.id))
|
|
249
|
+
continue;
|
|
250
|
+
seen.add(c.id);
|
|
251
|
+
out.push({
|
|
252
|
+
id: c.id,
|
|
253
|
+
title: c.title,
|
|
254
|
+
severity: 'warning',
|
|
255
|
+
from: c.from,
|
|
256
|
+
forbiddenImports: c.forbiddenImports,
|
|
257
|
+
suggestedFix: `Author this boundary in sharkcraft/boundaries.ts: ${c.from.join(', ')} must not import ${c.forbiddenImports.join(', ')}.`,
|
|
258
|
+
reason: c.reason,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
return out;
|
|
262
|
+
}
|
|
229
263
|
const TEMPLATE_PATTERNS = [
|
|
230
264
|
{
|
|
231
265
|
id: 'inferred.service',
|
|
@@ -319,21 +353,48 @@ export function inferRules(ws) {
|
|
|
319
353
|
reason: evidence,
|
|
320
354
|
});
|
|
321
355
|
}
|
|
322
|
-
// TypeScript.
|
|
356
|
+
// TypeScript. Resolve strict as a tri-state: confirmed-on, confirmed-off,
|
|
357
|
+
// or unknown (the tsconfig extends a base we cannot resolve — e.g. an npm
|
|
358
|
+
// package — so we must NOT assert that strict is off and bake a wrong rule).
|
|
323
359
|
if (ws.hasTypeScript) {
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
: '
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
360
|
+
const ts = ws.tsConfig;
|
|
361
|
+
const strictState = ts && ts.strictResolvable
|
|
362
|
+
? ts.strict === true
|
|
363
|
+
? 'on'
|
|
364
|
+
: 'off'
|
|
365
|
+
: 'unknown';
|
|
366
|
+
if (strictState === 'on') {
|
|
367
|
+
out.push({
|
|
368
|
+
id: 'typescript.strict-mode',
|
|
369
|
+
title: 'TypeScript strict mode enabled',
|
|
370
|
+
content: 'TypeScript strict mode is enabled. Keep it that way — do not weaken `strict` to land code.',
|
|
371
|
+
priority: 'high',
|
|
372
|
+
source: 'tsconfig',
|
|
373
|
+
reason: 'tsconfig strict=true',
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
else if (strictState === 'off') {
|
|
377
|
+
out.push({
|
|
378
|
+
id: 'typescript.strict-mode',
|
|
379
|
+
title: 'Enable TypeScript strict mode',
|
|
380
|
+
content: 'TypeScript strict mode is OFF. Turning it on is a one-line tsconfig change and significantly improves type safety. Plan a separate task for the cleanup.',
|
|
381
|
+
priority: 'medium',
|
|
382
|
+
source: 'tsconfig',
|
|
383
|
+
reason: 'tsconfig strict=false',
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
// Unknown: advisory only — do NOT emit the imperative "turn it on"
|
|
388
|
+
// rule (low priority keeps it out of high-confidence auto-adoption).
|
|
389
|
+
out.push({
|
|
390
|
+
id: 'typescript.strict-mode-unconfirmed',
|
|
391
|
+
title: 'Could not confirm TypeScript strict mode — verify manually',
|
|
392
|
+
content: 'TypeScript `strict` is not set directly and the extended base config could not be resolved (it may be an npm package such as `@tsconfig/strictest`). Confirm whether strict is enabled before relying on it; do not assume it is off.',
|
|
393
|
+
priority: 'low',
|
|
394
|
+
source: 'tsconfig',
|
|
395
|
+
reason: 'tsconfig strict unresolved (extends a non-relative / missing base)',
|
|
396
|
+
});
|
|
397
|
+
}
|
|
337
398
|
}
|
|
338
399
|
// Test runner.
|
|
339
400
|
if (ws.profiles.includes(WorkspaceProfile.HasBunTest)) {
|
package/dist/pack-doctor.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type IPackReleaseCheck } from './pack-release-check.js';
|
|
|
3
3
|
export interface IPackDoctorIssue {
|
|
4
4
|
severity: 'error' | 'warning' | 'info';
|
|
5
5
|
packageName: string;
|
|
6
|
-
code: 'invalid-manifest' | 'missing-contribution-file' | 'empty-resolved-contributions' | 'duplicate-id-local' | 'duplicate-id-pack-internal' | 'template-no-description' | 'pipeline-no-steps' | 'critical-rule-no-hints' | 'docs-file-missing' | 'unsigned-pack' | 'tampered-pack' | 'preset-composition-cycle' | 'preset-composed-not-found' | 'preset-missing-ref' | 'preset-no-includes' | 'release-manifest-issue' | 'release-contribution-issue' | 'release-signature-issue' | 'release-files-issue' | 'release-readiness-issue';
|
|
6
|
+
code: 'invalid-manifest' | 'missing-contribution-file' | 'empty-resolved-contributions' | 'duplicate-id-local' | 'duplicate-id-pack-internal' | 'template-no-description' | 'pipeline-no-steps' | 'critical-rule-no-hints' | 'docs-file-missing' | 'unsigned-pack' | 'tampered-pack' | 'signature-unverifiable' | 'dev-signature-not-trusted' | 'preset-composition-cycle' | 'preset-composed-not-found' | 'preset-missing-ref' | 'preset-no-includes' | 'pack-verification-pm-mismatch' | 'release-manifest-issue' | 'release-contribution-issue' | 'release-signature-issue' | 'release-files-issue' | 'release-readiness-issue';
|
|
7
7
|
message: string;
|
|
8
8
|
/** Free-form suggestion. */
|
|
9
9
|
suggestion?: string;
|
|
@@ -25,6 +25,13 @@ export interface IPackDoctorReport {
|
|
|
25
25
|
export interface IPackDoctorOptions {
|
|
26
26
|
/** When true, unsigned packs surface as `unsigned-pack` warnings. */
|
|
27
27
|
requireSignatures?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Opt in to trusting dev signatures. By default a dev-signed pack fails
|
|
30
|
+
* `--require-signatures` with `dev-signature-not-trusted`; when true, dev
|
|
31
|
+
* signatures are re-verified against the well-known dev secret and accepted
|
|
32
|
+
* (a tampered dev signature still surfaces as `tampered-pack`).
|
|
33
|
+
*/
|
|
34
|
+
allowDevSignatures?: boolean;
|
|
28
35
|
/** When true, also run pack-release-check per pack and fold findings into issues. */
|
|
29
36
|
release?: boolean;
|
|
30
37
|
/** When true, release-check warnings escalate to errors. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack-doctor.d.ts","sourceRoot":"","sources":["../src/pack-doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"pack-doctor.d.ts","sourceRoot":"","sources":["../src/pack-doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAWvE,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEtF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EACA,kBAAkB,GAClB,2BAA2B,GAC3B,8BAA8B,GAC9B,oBAAoB,GACpB,4BAA4B,GAC5B,yBAAyB,GACzB,mBAAmB,GACnB,wBAAwB,GACxB,mBAAmB,GACnB,eAAe,GACf,eAAe,GACf,wBAAwB,GACxB,2BAA2B,GAC3B,0BAA0B,GAC1B,2BAA2B,GAC3B,oBAAoB,GACpB,oBAAoB,GACpB,+BAA+B,GAC/B,wBAAwB,GACxB,4BAA4B,GAC5B,yBAAyB,GACzB,qBAAqB,GACrB,yBAAyB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,qFAAqF;IACrF,aAAa,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qFAAqF;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAmED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,qBAAqB,EACjC,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAoRnB;AAgBD;wEACwE;AACxE,wBAAsB,6BAA6B,CACjD,UAAU,EAAE,qBAAqB,GAChC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAa9B;AAED;8CAC8C;AAC9C,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,qBAAqB,EACjC,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,SAAS,iBAAiB,EAAE,EAC3C,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,iBAAiB,CAoCnB"}
|
package/dist/pack-doctor.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { hasActionHints } from '@shrkcrft/knowledge';
|
|
2
|
+
import { PackageManager, WorkspaceProfile, } from '@shrkcrft/workspace';
|
|
3
|
+
import { PipelineStepType } from '@shrkcrft/pipelines';
|
|
2
4
|
import { resolvePreset, resolvePresetReferences } from '@shrkcrft/presets';
|
|
5
|
+
import { PACK_SECRET_ENV, verifyPackManifest } from '@shrkcrft/plugin-api';
|
|
3
6
|
import { inspectionReferenceLookup } from "./reference-lookup.js";
|
|
4
7
|
import { runPackReleaseCheck } from "./pack-release-check.js";
|
|
5
8
|
const GEN_KEYWORDS = ['generate', 'create', 'add', 'refactor', 'test', 'review'];
|
|
@@ -15,6 +18,52 @@ function isCriticalOrHigh(e) {
|
|
|
15
18
|
const p = String(e.priority);
|
|
16
19
|
return p === 'critical' || p === 'high';
|
|
17
20
|
}
|
|
21
|
+
/** A leading package-manager / runner literal a pack verification command may
|
|
22
|
+
* bake in. Order longest-first is not required — these tokens are disjoint. */
|
|
23
|
+
const PM_LITERAL_MANAGERS = [
|
|
24
|
+
['bun ', PackageManager.Bun],
|
|
25
|
+
['pnpm ', PackageManager.Pnpm],
|
|
26
|
+
['yarn ', PackageManager.Yarn],
|
|
27
|
+
['npm ', PackageManager.Npm],
|
|
28
|
+
];
|
|
29
|
+
/** The package manager a command hard-codes as its leading runner, or null when
|
|
30
|
+
* it uses none (e.g. `make test`, a `<pm-run> test` placeholder, `shrk ...`). */
|
|
31
|
+
function literalPackageManager(command) {
|
|
32
|
+
const c = command.trim();
|
|
33
|
+
for (const [literal, manager] of PM_LITERAL_MANAGERS) {
|
|
34
|
+
if (c.startsWith(literal))
|
|
35
|
+
return manager;
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
/** The project's detected package manager (concrete only). Returns Unknown when
|
|
40
|
+
* no lockfile / packageManager field / bun profile signal is present — in that
|
|
41
|
+
* case we cannot claim a mismatch, so the lint stays silent. */
|
|
42
|
+
function detectedProjectManager(ws) {
|
|
43
|
+
const m = ws?.packageManager?.manager;
|
|
44
|
+
if (m && m !== PackageManager.Unknown)
|
|
45
|
+
return m;
|
|
46
|
+
if (ws?.profiles?.includes(WorkspaceProfile.HasBun))
|
|
47
|
+
return PackageManager.Bun;
|
|
48
|
+
return PackageManager.Unknown;
|
|
49
|
+
}
|
|
50
|
+
/** Push a warning when `command` bakes in a runner that disagrees with the
|
|
51
|
+
* project's detected toolchain. No-op when the command is templated, runner-
|
|
52
|
+
* agnostic, or already agrees with the detected manager. */
|
|
53
|
+
function pushPmMismatch(issues, packageName, origin, command, detected) {
|
|
54
|
+
if (detected === PackageManager.Unknown)
|
|
55
|
+
return;
|
|
56
|
+
const literal = literalPackageManager(command);
|
|
57
|
+
if (!literal || literal === detected)
|
|
58
|
+
return;
|
|
59
|
+
issues.push({
|
|
60
|
+
severity: 'warning',
|
|
61
|
+
packageName,
|
|
62
|
+
code: 'pack-verification-pm-mismatch',
|
|
63
|
+
message: `Verification command in ${origin} hard-codes \`${literal}\` but this project uses \`${detected}\`: "${command}".`,
|
|
64
|
+
suggestion: 'Use the `<pm-run>`/`<pm>` placeholder (resolved to the detected package manager at consume time) instead of a hard-coded runner.',
|
|
65
|
+
});
|
|
66
|
+
}
|
|
18
67
|
/**
|
|
19
68
|
* Full structural + quality audit of every discovered pack. Returns a list of
|
|
20
69
|
* issues (error / warning / info) plus an aggregated pass flag.
|
|
@@ -28,6 +77,7 @@ export function buildPackDoctorReport(inspection, options = {}) {
|
|
|
28
77
|
const localKnowledgeIds = new Set(inspection.knowledgeEntries
|
|
29
78
|
.filter((e) => inspection.entrySources.get(e.id)?.type === 'local')
|
|
30
79
|
.map((e) => e.id));
|
|
80
|
+
const detectedPm = detectedProjectManager(inspection.workspace);
|
|
31
81
|
for (const pack of inspection.packs.invalidPacks) {
|
|
32
82
|
issues.push({
|
|
33
83
|
severity: 'error',
|
|
@@ -116,6 +166,30 @@ export function buildPackDoctorReport(inspection, options = {}) {
|
|
|
116
166
|
});
|
|
117
167
|
}
|
|
118
168
|
}
|
|
169
|
+
// Verification commands that bake in a *foreign* package manager / runner.
|
|
170
|
+
// A pack playbook that ships `bun test` contradicts an npm/pnpm/yarn target;
|
|
171
|
+
// prefer the `<pm-run>`/`<pm>` placeholder. Warning, never a hard fail.
|
|
172
|
+
for (const entry of inspection.knowledgeEntries) {
|
|
173
|
+
const src = inspection.entrySources.get(entry.id);
|
|
174
|
+
if (src?.type !== 'pack' || src.packageName !== pack.packageName)
|
|
175
|
+
continue;
|
|
176
|
+
const hints = entry.actionHints;
|
|
177
|
+
for (const cmd of hints?.verificationCommands ?? []) {
|
|
178
|
+
pushPmMismatch(issues, pack.packageName, `knowledge "${entry.id}"`, cmd, detectedPm);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
for (const p of inspection.pipelines) {
|
|
182
|
+
const src = inspection.pipelineSources.get(p.id);
|
|
183
|
+
if (src?.type !== 'pack' || src.packageName !== pack.packageName)
|
|
184
|
+
continue;
|
|
185
|
+
for (const step of p.steps ?? []) {
|
|
186
|
+
if (step.type !== PipelineStepType.Command)
|
|
187
|
+
continue;
|
|
188
|
+
for (const cmd of step.cliCommands ?? []) {
|
|
189
|
+
pushPmMismatch(issues, pack.packageName, `pipeline "${p.id}" step "${step.id}"`, cmd, detectedPm);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
119
193
|
// Local-vs-pack duplicate ids.
|
|
120
194
|
for (const entry of inspection.knowledgeEntries) {
|
|
121
195
|
const src = inspection.entrySources.get(entry.id);
|
|
@@ -131,9 +205,18 @@ export function buildPackDoctorReport(inspection, options = {}) {
|
|
|
131
205
|
}
|
|
132
206
|
}
|
|
133
207
|
// Signature gating.
|
|
208
|
+
//
|
|
209
|
+
// The inspector verifies with dev signatures DISALLOWED, so a dev-signed
|
|
210
|
+
// pack arrives here as `dev-signature`. With --allow-dev-signature we
|
|
211
|
+
// re-run the HMAC against the well-known dev secret so a *tampered* dev
|
|
212
|
+
// signature still surfaces as invalid rather than being blindly trusted.
|
|
213
|
+
let sigStatus = pack.signatureStatus;
|
|
214
|
+
if (sigStatus === 'dev-signature' && options.allowDevSignatures && pack.manifest) {
|
|
215
|
+
const v = verifyPackManifest(pack.manifest, { allowDev: true });
|
|
216
|
+
sigStatus = v.ok ? 'verified' : v.status;
|
|
217
|
+
}
|
|
134
218
|
if (options.requireSignatures) {
|
|
135
|
-
|
|
136
|
-
if (!status || status === 'missing-signature' || status === 'not-checked') {
|
|
219
|
+
if (!sigStatus || sigStatus === 'missing-signature' || sigStatus === 'not-checked') {
|
|
137
220
|
issues.push({
|
|
138
221
|
severity: 'warning',
|
|
139
222
|
packageName: pack.packageName,
|
|
@@ -142,8 +225,32 @@ export function buildPackDoctorReport(inspection, options = {}) {
|
|
|
142
225
|
suggestion: 'Run `shrk packs sign <pack-dir>` and ship the signed manifest.',
|
|
143
226
|
});
|
|
144
227
|
}
|
|
228
|
+
else if (sigStatus === 'missing-secret') {
|
|
229
|
+
// S3-2: required verification that COULD NOT RUN is a failure, not a
|
|
230
|
+
// pass. A signed pack whose secret is unavailable is unverifiable —
|
|
231
|
+
// never report it as OK.
|
|
232
|
+
issues.push({
|
|
233
|
+
severity: 'error',
|
|
234
|
+
packageName: pack.packageName,
|
|
235
|
+
code: 'signature-unverifiable',
|
|
236
|
+
message: `Pack is signed but ${PACK_SECRET_ENV} is not set, so the signature could not be verified — required verification failed.`,
|
|
237
|
+
suggestion: `Set ${PACK_SECRET_ENV} (or pass --secret) and re-run with --require-signatures.`,
|
|
238
|
+
suggestedCommand: `${PACK_SECRET_ENV}=<secret> shrk packs doctor --require-signatures`,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
else if (sigStatus === 'dev-signature') {
|
|
242
|
+
// S3-1: a dev signature is verified only against the public dev secret
|
|
243
|
+
// and is NOT release-trusted; under --require-signatures it must fail.
|
|
244
|
+
issues.push({
|
|
245
|
+
severity: 'error',
|
|
246
|
+
packageName: pack.packageName,
|
|
247
|
+
code: 'dev-signature-not-trusted',
|
|
248
|
+
message: 'Pack carries a dev signature (not release-trusted) and --require-signatures was set.',
|
|
249
|
+
suggestion: 'Re-sign with the release secret (`shrk packs sign <pack-dir>`), or pass --allow-dev-signature to accept dev signatures for local-only flows.',
|
|
250
|
+
});
|
|
251
|
+
}
|
|
145
252
|
}
|
|
146
|
-
if (
|
|
253
|
+
if (sigStatus === 'invalid-signature') {
|
|
147
254
|
issues.push({
|
|
148
255
|
severity: 'error',
|
|
149
256
|
packageName: pack.packageName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack-quality-score.d.ts","sourceRoot":"","sources":["../src/pack-quality-score.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pack-quality-score.d.ts","sourceRoot":"","sources":["../src/pack-quality-score.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIvE,eAAO,MAAM,mBAAmB,qCAAqC,CAAC;AACtE,eAAO,MAAM,wBAAwB,oCAAoC,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,wBAAwB,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC9F,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,eAAe,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,iBAAiB,GAC1B,gBAAgB,CA2BlB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,mBAAmB,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC7C,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAMD,wBAAgB,SAAS,CACvB,UAAU,EAAE,qBAAqB,EACjC,IAAI,EAAE,eAAe,GACpB,iBAAiB,CAmInB;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,qBAAqB,GAAG,iBAAiB,EAAE,CAEpF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CONTRIBUTION_FILE_KEYS } from '@shrkcrft/plugin-api';
|
|
1
2
|
import { lintTemplates } from "./template-lint.js";
|
|
2
3
|
import { lintPipelines } from "./pipeline-lint.js";
|
|
3
4
|
export const PACK_QUALITY_SCHEMA = 'sharkcraft.pack-quality-score/v1';
|
|
@@ -68,14 +69,12 @@ export function scorePack(inspection, pack) {
|
|
|
68
69
|
scaffoldPatterns: 0,
|
|
69
70
|
policyChecks: 0,
|
|
70
71
|
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
pack.contributionCounts.presetFiles +
|
|
78
|
-
pack.contributionCounts.scaffoldPatternFiles;
|
|
72
|
+
// Sum EVERY canonical contribution kind (not just the original 8) so a pack
|
|
73
|
+
// that contributes only "extended" kinds (conventions / helpers / framework
|
|
74
|
+
// extractors / …) is recognised as declaring contributions instead of being
|
|
75
|
+
// scored as "Pack declares no contributions".
|
|
76
|
+
const declaredCounts = pack.contributionCounts;
|
|
77
|
+
const totalDeclared = CONTRIBUTION_FILE_KEYS.reduce((sum, key) => sum + (declaredCounts[key] ?? 0), 0);
|
|
79
78
|
const totalResolved = resolved.knowledgeEntries +
|
|
80
79
|
resolved.rules +
|
|
81
80
|
resolved.pathConventions +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack-release-check.d.ts","sourceRoot":"","sources":["../src/pack-release-check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pack-release-check.d.ts","sourceRoot":"","sources":["../src/pack-release-check.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,yBAAyB,qCAAqC,CAAC;AAE5E,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,yBAAyB,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACzC,MAAM,EAAE,OAAO,CAAC;CACjB;AA6ED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAoLtF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import * as nodePath from 'node:path';
|
|
3
|
-
import { validatePackManifest } from '@shrkcrft/plugin-api';
|
|
3
|
+
import { CONTRIBUTION_FILE_KEYS, validatePackManifest, } from '@shrkcrft/plugin-api';
|
|
4
4
|
import { importModuleViaLoader } from '@shrkcrft/core';
|
|
5
5
|
export const PACK_RELEASE_CHECK_SCHEMA = 'sharkcraft.pack-release-check/v1';
|
|
6
6
|
function findManifest(packPath) {
|
|
@@ -158,27 +158,17 @@ export async function runPackReleaseCheck(packPath) {
|
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
// Contribution file existence + load.
|
|
161
|
+
//
|
|
162
|
+
// Iterate the canonical CONTRIBUTION_FILE_KEYS (single source of truth in
|
|
163
|
+
// @shrkcrft/plugin-api) so EVERY consuming contribution slot is verified — a
|
|
164
|
+
// pack shipping a broken framework extractor / convention / helper / decision
|
|
165
|
+
// / etc. now fails the gate instead of slipping through. The two `Future`
|
|
166
|
+
// no-op slots (mcpToolFiles / aiProviderFiles) are intentionally excluded via
|
|
167
|
+
// FUTURE_CONTRIBUTION_FILE_KEYS: nothing loads them yet, so verifying them
|
|
168
|
+
// would be dishonest.
|
|
161
169
|
let contributionsFound = 0;
|
|
162
170
|
const c = manifest.contributions ?? {};
|
|
163
|
-
const
|
|
164
|
-
'knowledgeFiles',
|
|
165
|
-
'ruleFiles',
|
|
166
|
-
'pathFiles',
|
|
167
|
-
'templateFiles',
|
|
168
|
-
'pipelineFiles',
|
|
169
|
-
'docsFiles',
|
|
170
|
-
'presetFiles',
|
|
171
|
-
'boundaryFiles',
|
|
172
|
-
'contextTestFiles',
|
|
173
|
-
'agentTestFiles',
|
|
174
|
-
'scaffoldPatternFiles',
|
|
175
|
-
'policyCheckFiles',
|
|
176
|
-
'constructFiles',
|
|
177
|
-
'constructFacetFiles',
|
|
178
|
-
'playbookFiles',
|
|
179
|
-
'searchTuningFiles',
|
|
180
|
-
];
|
|
181
|
-
for (const key of allBuckets) {
|
|
171
|
+
for (const key of CONTRIBUTION_FILE_KEYS) {
|
|
182
172
|
const list = c[key];
|
|
183
173
|
if (!list || list.length === 0)
|
|
184
174
|
continue;
|
|
@@ -234,6 +224,19 @@ export async function runPackReleaseCheck(packPath) {
|
|
|
234
224
|
file: manifestFile,
|
|
235
225
|
});
|
|
236
226
|
}
|
|
227
|
+
else if (manifest.signature.dev === true) {
|
|
228
|
+
// Dev signatures verify only against the well-known public dev secret and
|
|
229
|
+
// are NOT release-trusted — shipping one in a release is almost certainly a
|
|
230
|
+
// mistake. Warn (not a hard error) so the author re-signs before tagging.
|
|
231
|
+
findings.push({
|
|
232
|
+
code: 'dev-signature',
|
|
233
|
+
severity: 'warning',
|
|
234
|
+
message: 'Manifest carries a dev signature (sig.dev = true) — verified only against the public dev secret and NOT release-trusted. Re-sign with the release secret before publishing.',
|
|
235
|
+
suggestedFix: 'Run `shrk packs sign <manifest.ts>` with SHARKCRAFT_PACK_SECRET set (no --dev) and ship the re-signed manifest.',
|
|
236
|
+
suggestedCommand: 'shrk packs sign ' + manifestFile + ' --verify-after-sign',
|
|
237
|
+
file: manifestFile,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
237
240
|
// Files whitelist sanity.
|
|
238
241
|
const filesFinding = checkFilesWhitelist(pkgFile, manifestFile);
|
|
239
242
|
if (filesFinding)
|
|
@@ -42,14 +42,20 @@ export interface IPackSignatureStatusReport {
|
|
|
42
42
|
export declare function buildPackSignatureStatusReport(inspection: ISharkcraftInspection): IPackSignatureStatusReport;
|
|
43
43
|
/**
|
|
44
44
|
* Pack signature explanation. Surfaces the distinct lifecycle
|
|
45
|
-
* states (`unsigned`, `stale`, `invalid`, `valid`, `
|
|
46
|
-
* `not-required`) per pack with a one-line
|
|
45
|
+
* states (`unsigned`, `stale`, `invalid`, `valid`, `present-unverified`,
|
|
46
|
+
* `dev-signature`, `secret-missing`, `not-required`) per pack with a one-line
|
|
47
|
+
* "why this matters".
|
|
47
48
|
*
|
|
48
49
|
* Read-only. Reads `inspection.packs.discoveredPacks[i].signatureStatus`
|
|
49
50
|
* which already reflects the verifier's outcome when the inspector was
|
|
50
51
|
* constructed with `verifyPackSignatures: true`.
|
|
52
|
+
*
|
|
53
|
+
* `valid` is reserved STRICTLY for a real HMAC pass (verifier === 'verified').
|
|
54
|
+
* A pack whose signature timestamp is merely fresher than its contribution
|
|
55
|
+
* files — but whose HMAC was not checked this run — is `present-unverified`,
|
|
56
|
+
* never `valid`: freshness is not verification.
|
|
51
57
|
*/
|
|
52
|
-
export type PackSignatureExplainState = 'valid' | 'unsigned' | 'stale' | 'invalid' | 'secret-missing' | 'not-required' | 'unknown';
|
|
58
|
+
export type PackSignatureExplainState = 'valid' | 'unsigned' | 'stale' | 'invalid' | 'present-unverified' | 'dev-signature' | 'secret-missing' | 'not-required' | 'unknown';
|
|
53
59
|
export interface IPackSignatureExplainEntry {
|
|
54
60
|
readonly packageName: string;
|
|
55
61
|
readonly packageVersion: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack-signature-status.d.ts","sourceRoot":"","sources":["../src/pack-signature-status.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE,eAAO,MAAM,4BAA4B,wCAAwC,CAAC;AAElF,oBAAY,uBAAuB;IACjC,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,MAAM,EAAE,OAAO,4BAA4B,CAAC;IACrD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,sEAAsE;QACtE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AA+BD,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,qBAAqB,GAChC,0BAA0B,CA6G5B;AAED
|
|
1
|
+
{"version":3,"file":"pack-signature-status.d.ts","sourceRoot":"","sources":["../src/pack-signature-status.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE,eAAO,MAAM,4BAA4B,wCAAwC,CAAC;AAElF,oBAAY,uBAAuB;IACjC,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,MAAM,EAAE,OAAO,4BAA4B,CAAC;IACrD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,sEAAsE;QACtE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AA+BD,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,qBAAqB,GAChC,0BAA0B,CA6G5B;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,yBAAyB,GACjC,OAAO,GACP,UAAU,GACV,OAAO,GACP,SAAS,GACT,oBAAoB,GACpB,eAAe,GACf,gBAAgB,GAChB,cAAc,GACd,SAAS,CAAC;AAEd,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,yBAAyB,CAAC;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,EAAE,sCAAsC,CAAC;IACxD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,SAAS,0BAA0B,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,kCAAkC;IACjD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,qBAAqB,EACjC,OAAO,GAAE,kCAAuC,GAC/C,2BAA2B,CAuE7B"}
|
|
@@ -191,6 +191,12 @@ export function explainPackSignatureStatus(inspection, options = {}) {
|
|
|
191
191
|
explanation = 'Manifest signature failed HMAC verification — pack contents may have been tampered with.';
|
|
192
192
|
nextCommand = 'shrk packs verify --required';
|
|
193
193
|
}
|
|
194
|
+
else if (verifier === 'dev-signature') {
|
|
195
|
+
state = 'dev-signature';
|
|
196
|
+
explanation =
|
|
197
|
+
'Manifest carries a dev signature — verified only against the well-known public dev secret, NOT release-trusted. Re-sign with the release secret before publishing.';
|
|
198
|
+
nextCommand = secretAvailable ? signCmd : 'shrk packs verify --required --allow-dev-signature';
|
|
199
|
+
}
|
|
194
200
|
else if (verifier === 'missing-signature' || (!verifier && fresh?.status === 'missing')) {
|
|
195
201
|
state = 'unsigned';
|
|
196
202
|
explanation = 'Manifest has no signature block.';
|
|
@@ -207,8 +213,13 @@ export function explainPackSignatureStatus(inspection, options = {}) {
|
|
|
207
213
|
nextCommand = signCmd;
|
|
208
214
|
}
|
|
209
215
|
else if (fresh?.status === 'present') {
|
|
210
|
-
|
|
211
|
-
|
|
216
|
+
// Freshness only — the HMAC was NOT checked this run. Reserve `valid`
|
|
217
|
+
// strictly for a real verifier pass so a bogus-HMAC-but-fresh-timestamp
|
|
218
|
+
// pack is never mislabelled as verified.
|
|
219
|
+
state = 'present-unverified';
|
|
220
|
+
explanation =
|
|
221
|
+
'Signature present and newer than every contribution file, but the HMAC was NOT checked this run.';
|
|
222
|
+
nextCommand = 'shrk packs verify --required';
|
|
212
223
|
}
|
|
213
224
|
else {
|
|
214
225
|
state = mode === 'required' ? 'unknown' : 'not-required';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan-simulation.d.ts","sourceRoot":"","sources":["../src/plan-simulation.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAK3E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AAEtE,oBAAY,8BAA8B;IACxC,KAAK,UAAU;IACf,cAAc,oBAAoB;IAClC,QAAQ,aAAa;IACrB,gBAAgB,sBAAsB;IACtC,UAAU,gBAAgB;CAC3B;AAED,oBAAY,kBAAkB;IAC5B,KAAK,UAAU;IACf,eAAe,sBAAsB;IACrC,gBAAgB,sBAAsB;IACtC,aAAa,mBAAmB;IAChC,eAAe,qBAAqB;IACpC,gBAAgB,sBAAsB;IACtC,oBAAoB,2BAA2B;CAChD;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,8BAA8B,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB;;qCAEiC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;gCAC4B;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,sBAAsB,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACtC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,uBAAuB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,sBAAsB,EAAE,OAAO,CAAC;IAChC,sBAAsB,EAAE,OAAO,CAAC;IAChC,uBAAuB,EAAE,OAAO,CAAC;IACjC,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,yBAAyB,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACjE,8BAA8B,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACtE,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,cAAc,EAAE,kBAAkB,CAAC;IACnC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mDAAmD;IACnD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAYD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAoG5K;AA+GD,wBAAsB,YAAY,CAChC,UAAU,EAAE,qBAAqB,EACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,qBAAqB,CAAC,
|
|
1
|
+
{"version":3,"file":"plan-simulation.d.ts","sourceRoot":"","sources":["../src/plan-simulation.ts"],"names":[],"mappings":"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"}
|
package/dist/plan-simulation.js
CHANGED
|
@@ -282,9 +282,11 @@ export async function simulatePlan(inspection, planPath, options = {}) {
|
|
|
282
282
|
}
|
|
283
283
|
// Re-render the template to recover virtual contents (when available).
|
|
284
284
|
let liveChanges = [];
|
|
285
|
+
let templateRequiredValidations = [];
|
|
285
286
|
if (plan.templateId) {
|
|
286
287
|
const template = inspection.templateRegistry.get(plan.templateId);
|
|
287
288
|
if (template) {
|
|
289
|
+
templateRequiredValidations = template.metadata?.requiredValidations ?? [];
|
|
288
290
|
try {
|
|
289
291
|
const dry = planGeneration(template, {
|
|
290
292
|
templateId: plan.templateId,
|
|
@@ -485,20 +487,32 @@ export async function simulatePlan(inspection, planPath, options = {}) {
|
|
|
485
487
|
likelyTests.push(`${f.relativePath} → expected ${candidate}`);
|
|
486
488
|
}
|
|
487
489
|
}
|
|
488
|
-
// Required validations.
|
|
489
|
-
//
|
|
490
|
-
//
|
|
491
|
-
//
|
|
490
|
+
// Required validations. The template's OWN declared validations come first
|
|
491
|
+
// (so an Nx lib template can surface `nx build <app>` rather than the generic
|
|
492
|
+
// boilerplate, and two templates can show different lists). We then add the
|
|
493
|
+
// project's authoritative gate set — its configured verificationCommands —
|
|
494
|
+
// via resolveVerificationCommands. The engine's generic defaults are used
|
|
495
|
+
// ONLY as a fallback when the template declared nothing of its own.
|
|
492
496
|
// No pipelineIds are passed: a saved plan carries no task query to rank
|
|
493
497
|
// pipelines against, so resolution is config-driven, not pipeline-matched.
|
|
494
|
-
const requiredValidations = new Set(
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
498
|
+
const requiredValidations = new Set();
|
|
499
|
+
for (const v of templateRequiredValidations) {
|
|
500
|
+
const cmd = v.trim();
|
|
501
|
+
if (cmd.length > 0)
|
|
502
|
+
requiredValidations.add(cmd);
|
|
503
|
+
}
|
|
504
|
+
const resolvedValidations = resolveVerificationCommands(inspection, {
|
|
505
|
+
knowledgeDefaults: templateRequiredValidations.length > 0
|
|
506
|
+
? []
|
|
507
|
+
: [
|
|
508
|
+
'bun x tsc -p tsconfig.base.json --noEmit',
|
|
509
|
+
'bun test',
|
|
510
|
+
'shrk doctor',
|
|
511
|
+
'shrk check boundaries',
|
|
512
|
+
],
|
|
513
|
+
});
|
|
514
|
+
for (const cmd of resolvedValidations)
|
|
515
|
+
requiredValidations.add(cmd);
|
|
502
516
|
if (publicApiTouched || barrelExportTouched)
|
|
503
517
|
requiredValidations.add('shrk api report --all --public-only');
|
|
504
518
|
if (pluginKeysTouched)
|
|
@@ -33,6 +33,12 @@ export interface IRegistryIgnored {
|
|
|
33
33
|
export interface IRegistryLifecycleReport {
|
|
34
34
|
schema: 'sharkcraft.registry-lifecycle/v1';
|
|
35
35
|
filesScanned: number;
|
|
36
|
+
/** Total candidate files found before the cap (>= filesScanned). */
|
|
37
|
+
totalFiles: number;
|
|
38
|
+
/** True when the scan hit the file cap and did NOT see every candidate file. */
|
|
39
|
+
truncated: boolean;
|
|
40
|
+
/** Project-relative subtree the scan was scoped to, when `--scope` was used. */
|
|
41
|
+
scope?: string;
|
|
36
42
|
registersFound: number;
|
|
37
43
|
matchedPairs: ReadonlyArray<IRegistryPair>;
|
|
38
44
|
missingRemovers: ReadonlyArray<IRegistryMissingRemover>;
|
|
@@ -48,6 +54,8 @@ export interface IRegistryLifecycleReport {
|
|
|
48
54
|
export declare function buildRegistryLifecycleReport(input: {
|
|
49
55
|
projectRoot: string;
|
|
50
56
|
limit?: number;
|
|
57
|
+
/** Project-relative subtree to scope the scan to (sub-second on a subtree). */
|
|
58
|
+
scope?: string;
|
|
51
59
|
}): IRegistryLifecycleReport;
|
|
52
60
|
export declare function renderRegistryLifecycleReportText(report: IRegistryLifecycleReport): string;
|
|
53
61
|
//# sourceMappingURL=registry-lifecycle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry-lifecycle.d.ts","sourceRoot":"","sources":["../src/registry-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,kCAAkC,CAAC;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAC3C,eAAe,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAC;IACxD;;;;OAIG;IACH,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAClD,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACzC,eAAe,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACxC;
|
|
1
|
+
{"version":3,"file":"registry-lifecycle.d.ts","sourceRoot":"","sources":["../src/registry-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,kCAAkC,CAAC;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,SAAS,EAAE,OAAO,CAAC;IACnB,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAC3C,eAAe,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAC;IACxD;;;;OAIG;IACH,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAClD,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACzC,eAAe,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACxC;AAiMD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,wBAAwB,CA2F3B;AAED,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM,CAkC1F"}
|