@shrkcrft/inspector 0.1.0-alpha.26 → 0.1.0-alpha.28
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/delegate-catalog.d.ts +21 -4
- package/dist/delegate-catalog.d.ts.map +1 -1
- package/dist/delegate-catalog.js +25 -1
- package/dist/delegate-doctor.d.ts +1 -1
- package/dist/delegate-doctor.d.ts.map +1 -1
- package/dist/delegate-doctor.js +60 -9
- package/dist/delegate-grounding.d.ts +154 -0
- package/dist/delegate-grounding.d.ts.map +1 -0
- package/dist/delegate-grounding.js +427 -0
- package/dist/docs-check.d.ts.map +1 -1
- package/dist/docs-check.js +1 -0
- package/dist/git-helpers.d.ts +16 -0
- package/dist/git-helpers.d.ts.map +1 -1
- package/dist/git-helpers.js +24 -0
- package/dist/import-hygiene.d.ts.map +1 -1
- package/dist/import-hygiene.js +12 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/resolve-project-config.d.ts +1 -1
- package/dist/resolve-project-config.d.ts.map +1 -1
- package/dist/resolve-project-config.js +31 -4
- package/package.json +17 -17
|
@@ -8,17 +8,34 @@
|
|
|
8
8
|
* `shrk delegate explain` can show an author the fence is real before trusting
|
|
9
9
|
* it. Pack-contributed recipes (Phase 4) will merge in here too.
|
|
10
10
|
*/
|
|
11
|
-
import type
|
|
11
|
+
import { type DelegateRecipeMode, type IDelegateRecipe, type ISharkCraftConfig } from '@shrkcrft/config';
|
|
12
12
|
export interface IResolvedDelegateRecipe extends IDelegateRecipe {
|
|
13
|
+
/**
|
|
14
|
+
* Recipe mode after defaulting (`'patch'` when unset). Explicit so downstream
|
|
15
|
+
* surfaces (doctor, list/explain, the analyze path) don't re-derive it.
|
|
16
|
+
*/
|
|
17
|
+
mode: DelegateRecipeMode;
|
|
13
18
|
/** Provider after applying the delegation-level default (never undefined). */
|
|
14
19
|
resolvedProvider: 'auto' | 'ollama' | 'llamacpp';
|
|
15
20
|
/** Model after applying the delegation-level default (undefined = provider default). */
|
|
16
21
|
resolvedModel?: string;
|
|
17
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* (patch) The write-fence arrays, normalised to present (empty when unset) so
|
|
24
|
+
* patch consumers never juggle `undefined`. Analysis recipes leave them `[]`.
|
|
25
|
+
*/
|
|
26
|
+
guardrailGlobs: readonly string[];
|
|
27
|
+
allowedOps: readonly string[];
|
|
28
|
+
verificationIds: readonly string[];
|
|
29
|
+
/** (patch) verificationIds that do NOT resolve to a `verificationCommands[].id`. */
|
|
18
30
|
unboundVerificationIds: readonly string[];
|
|
19
|
-
/** True when every verificationId resolves AND at least one is declared. */
|
|
31
|
+
/** (patch) True when every verificationId resolves AND at least one is declared. */
|
|
20
32
|
verificationBound: boolean;
|
|
21
|
-
/** True when
|
|
33
|
+
/** (analysis) True when `groundedOn` resolves to a known grounding report. */
|
|
34
|
+
groundingBound: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* True when the recipe is safe to run — for a patch recipe, its verification is
|
|
37
|
+
* fully bound; for an analysis recipe, its grounding report is known.
|
|
38
|
+
*/
|
|
22
39
|
delegatable: boolean;
|
|
23
40
|
/** Where the recipe came from. */
|
|
24
41
|
source: 'config' | 'pack';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegate-catalog.d.ts","sourceRoot":"","sources":["../src/delegate-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"delegate-catalog.d.ts","sourceRoot":"","sources":["../src/delegate-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAA0B,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEjI,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC9D;;;OAGG;IACH,IAAI,EAAE,kBAAkB,CAAC;IACzB,8EAA8E;IAC9E,gBAAgB,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;IACjD,wFAAwF;IACxF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oFAAoF;IACpF,sBAAsB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,oFAAoF;IACpF,iBAAiB,EAAE,OAAO,CAAC;IAC3B,8EAA8E;IAC9E,cAAc,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB,kCAAkC;IAClC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,iBAAiB,EACzB,WAAW,GAAE,SAAS,gBAAgB,EAAO,GAC5C,SAAS,uBAAuB,EAAE,CAgDpC;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,MAAM,GACf,uBAAuB,GAAG,SAAS,CAErC"}
|
package/dist/delegate-catalog.js
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the delegate-recipe catalog from a loaded config (read-only, NO model).
|
|
3
|
+
*
|
|
4
|
+
* Merges the delegation-level `provider`/`model` defaults into each recipe and
|
|
5
|
+
* checks every `verificationId` against the config's `verificationCommands[]`.
|
|
6
|
+
* A recipe is `delegatable` only when ALL its verification ids are bound — a
|
|
7
|
+
* recipe with an unbound (or empty) verification has no deterministic gate, so
|
|
8
|
+
* `shrk delegate explain` can show an author the fence is real before trusting
|
|
9
|
+
* it. Pack-contributed recipes (Phase 4) will merge in here too.
|
|
10
|
+
*/
|
|
11
|
+
import { DELEGATE_GROUNDING_IDS } from '@shrkcrft/config';
|
|
1
12
|
/**
|
|
2
13
|
* Resolve the delegate catalog from config + pack-contributed recipes.
|
|
3
14
|
*
|
|
@@ -29,15 +40,28 @@ export function resolveDelegateCatalog(config, packRecipes = []) {
|
|
|
29
40
|
...(ov?.verificationIds !== undefined ? { verificationIds: ov.verificationIds } : {}),
|
|
30
41
|
...(ov?.guardrailGlobs !== undefined ? { guardrailGlobs: ov.guardrailGlobs } : {}),
|
|
31
42
|
};
|
|
43
|
+
const mode = merged.mode ?? 'patch';
|
|
32
44
|
const unbound = (merged.verificationIds ?? []).filter((id) => !known.has(id));
|
|
33
45
|
const verificationBound = unbound.length === 0 && (merged.verificationIds ?? []).length > 0;
|
|
46
|
+
const groundingBound = typeof merged.groundedOn === 'string' &&
|
|
47
|
+
DELEGATE_GROUNDING_IDS.includes(merged.groundedOn);
|
|
48
|
+
// A patch recipe is runnable when its verification binds; an analysis recipe
|
|
49
|
+
// when its grounding report is known. `delegatable` unifies "safe to run".
|
|
50
|
+
const delegatable = mode === 'analysis' ? groundingBound : verificationBound;
|
|
34
51
|
out.push({
|
|
35
52
|
...merged,
|
|
53
|
+
mode,
|
|
54
|
+
// Normalise the write-fence arrays to present so patch consumers of the
|
|
55
|
+
// resolved recipe never juggle `undefined` (analysis recipes stay `[]`).
|
|
56
|
+
guardrailGlobs: merged.guardrailGlobs ?? [],
|
|
57
|
+
allowedOps: merged.allowedOps ?? [],
|
|
58
|
+
verificationIds: merged.verificationIds ?? [],
|
|
36
59
|
resolvedProvider: merged.provider ?? delegation.provider ?? 'auto',
|
|
37
60
|
...(merged.model ?? delegation.model ? { resolvedModel: merged.model ?? delegation.model } : {}),
|
|
38
61
|
unboundVerificationIds: unbound,
|
|
39
62
|
verificationBound,
|
|
40
|
-
|
|
63
|
+
groundingBound,
|
|
64
|
+
delegatable,
|
|
41
65
|
source,
|
|
42
66
|
...(packageName ? { packageName } : {}),
|
|
43
67
|
});
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* which can load pack files async); silent when the repo hasn't opted into
|
|
10
10
|
* delegation.
|
|
11
11
|
*/
|
|
12
|
-
import type
|
|
12
|
+
import { type ISharkCraftConfig } from '@shrkcrft/config';
|
|
13
13
|
import { type IDoctorCheck } from './doctor-result.js';
|
|
14
14
|
export declare function buildDelegateRecipeChecks(config: ISharkCraftConfig | null): IDoctorCheck[];
|
|
15
15
|
//# sourceMappingURL=delegate-doctor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegate-doctor.d.ts","sourceRoot":"","sources":["../src/delegate-doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"delegate-doctor.d.ts","sourceRoot":"","sources":["../src/delegate-doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvE,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,GAAG,YAAY,EAAE,CAsE1F"}
|
package/dist/delegate-doctor.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `shrk doctor` checks for delegate-worker recipe health.
|
|
3
|
+
*
|
|
4
|
+
* Surfaces recipes that are NOT delegatable — a recipe whose `verificationIds`
|
|
5
|
+
* don't all resolve to `verificationCommands[]` (incl. after `recipeOverrides`)
|
|
6
|
+
* has no deterministic gate, so `shrk delegate run` would refuse it. `runDoctor`
|
|
7
|
+
* has no other surface for this (it doesn't run `validateConfig`), so this is the
|
|
8
|
+
* proactive catch. Sync + config-only (pack-recipe health is `delegate explain`,
|
|
9
|
+
* which can load pack files async); silent when the repo hasn't opted into
|
|
10
|
+
* delegation.
|
|
11
|
+
*/
|
|
12
|
+
import { DELEGATE_QUERY_IDS } from '@shrkcrft/config';
|
|
1
13
|
import { DoctorSeverity } from "./doctor-result.js";
|
|
2
14
|
import { resolveDelegateCatalog } from "./delegate-catalog.js";
|
|
3
15
|
export function buildDelegateRecipeChecks(config) {
|
|
@@ -9,26 +21,65 @@ export function buildDelegateRecipeChecks(config) {
|
|
|
9
21
|
const out = [];
|
|
10
22
|
const broken = catalog.filter((r) => !r.delegatable);
|
|
11
23
|
for (const r of broken) {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
24
|
+
const isAnalysis = r.mode === 'analysis';
|
|
25
|
+
const reason = isAnalysis
|
|
26
|
+
? `groundedOn "${r.groundedOn ?? '(unset)'}" is not a known grounding report`
|
|
27
|
+
: r.unboundVerificationIds.length > 0
|
|
28
|
+
? `verificationIds not in verificationCommands[]: ${r.unboundVerificationIds.join(', ')}`
|
|
29
|
+
: 'no verificationIds declared';
|
|
30
|
+
const consequence = isAnalysis
|
|
31
|
+
? `\`shrk delegate analyze --recipe ${r.id}\` has no deterministic ground truth to check the model against.`
|
|
32
|
+
: `\`shrk delegate run --recipe ${r.id}\` would refuse to apply an unverified edit.`;
|
|
15
33
|
out.push({
|
|
16
34
|
id: `delegate-recipe-${r.id}`,
|
|
17
|
-
title: `Delegate recipe "${r.id}" is not delegatable`,
|
|
35
|
+
title: `Delegate recipe "${r.id}" is not ${isAnalysis ? 'usable' : 'delegatable'}`,
|
|
18
36
|
severity: DoctorSeverity.Warning,
|
|
19
|
-
message: `${reason} —
|
|
37
|
+
message: `${reason} — ${consequence}`,
|
|
20
38
|
category: 'delegate',
|
|
21
|
-
code: 'recipe-unverified',
|
|
39
|
+
code: isAnalysis ? 'recipe-ungrounded' : 'recipe-unverified',
|
|
22
40
|
recommendedFix: `shrk delegate explain ${r.id}`,
|
|
23
|
-
whyThisMatters:
|
|
41
|
+
whyThisMatters: isAnalysis
|
|
42
|
+
? 'An analysis recipe grounds the model on a deterministic report; without a known groundedOn there is no ground truth to cross-check findings against, so the recipe is unusable.'
|
|
43
|
+
: 'A recipe with an unbound verification has no deterministic gate; the worker can only run a VERIFIED edit, so the recipe is unusable until its verificationIds bind to a verificationCommands[] entry.',
|
|
24
44
|
});
|
|
25
45
|
}
|
|
26
|
-
|
|
46
|
+
// Analysis-recipe config health beyond grounding (validateConfig isn't run at
|
|
47
|
+
// load, so these would otherwise silently misbehave): unknown query ids and an
|
|
48
|
+
// escalateTo that doesn't resolve to a patch recipe.
|
|
49
|
+
const patchIds = new Set(catalog.filter((r) => r.mode !== 'analysis').map((r) => r.id));
|
|
50
|
+
for (const r of catalog) {
|
|
51
|
+
if (r.mode !== 'analysis')
|
|
52
|
+
continue;
|
|
53
|
+
const badQueries = (r.allowedQueries ?? []).filter((q) => !DELEGATE_QUERY_IDS.includes(q));
|
|
54
|
+
if (badQueries.length > 0) {
|
|
55
|
+
out.push({
|
|
56
|
+
id: `delegate-recipe-${r.id}-queries`,
|
|
57
|
+
title: `Delegate recipe "${r.id}" has unknown allowedQueries`,
|
|
58
|
+
severity: DoctorSeverity.Warning,
|
|
59
|
+
message: `${badQueries.join(', ')} — not in DELEGATE_QUERY_IDS (${DELEGATE_QUERY_IDS.join(', ')}); the model can never call them.`,
|
|
60
|
+
category: 'delegate',
|
|
61
|
+
code: 'recipe-unknown-query',
|
|
62
|
+
recommendedFix: `shrk delegate explain ${r.id}`,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (r.escalateTo !== undefined && !patchIds.has(r.escalateTo)) {
|
|
66
|
+
out.push({
|
|
67
|
+
id: `delegate-recipe-${r.id}-escalate`,
|
|
68
|
+
title: `Delegate recipe "${r.id}" escalates to a non-patch recipe`,
|
|
69
|
+
severity: DoctorSeverity.Warning,
|
|
70
|
+
message: `escalateTo "${r.escalateTo}" is not an existing patch recipe — \`--escalate\` would be a no-op.`,
|
|
71
|
+
category: 'delegate',
|
|
72
|
+
code: 'recipe-bad-escalation',
|
|
73
|
+
recommendedFix: `shrk delegate explain ${r.id}`,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (out.length === 0) {
|
|
27
78
|
out.push({
|
|
28
79
|
id: 'delegate-recipes',
|
|
29
80
|
title: 'Delegate recipes',
|
|
30
81
|
severity: DoctorSeverity.Ok,
|
|
31
|
-
message: `${catalog.length} delegate recipe(s) configured, all
|
|
82
|
+
message: `${catalog.length} delegate recipe(s) configured, all healthy.`,
|
|
32
83
|
category: 'delegate',
|
|
33
84
|
});
|
|
34
85
|
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delegate ANALYSIS grounding (read-only, deterministic — NO model).
|
|
3
|
+
*
|
|
4
|
+
* An `analysis` delegate recipe grounds a local model's judgment on a
|
|
5
|
+
* deterministic report the engine runs FIRST. This module:
|
|
6
|
+
* 1. runs that report (`runGroundingReport`) and distils it to a compact
|
|
7
|
+
* summary + a set of known entities (files / constructs / reason codes);
|
|
8
|
+
* 2. cross-checks the model's findings against those entities
|
|
9
|
+
* (`crossCheckFindings`) — a finding that cites an entity absent from the
|
|
10
|
+
* ground truth is flagged `unverified` (or dropped, in strict mode), so the
|
|
11
|
+
* model can prioritise/explain but never fabricate a fact;
|
|
12
|
+
* 3. assembles the honest, advisory `IDelegateAnalysisReport`
|
|
13
|
+
* (`buildDelegateAnalysisReport`) — which NEVER writes.
|
|
14
|
+
*
|
|
15
|
+
* The model call itself happens in the cli orchestrator, not here (this layer is
|
|
16
|
+
* pure). MCP surfaces only the grounding, never the model — see the safety model.
|
|
17
|
+
*/
|
|
18
|
+
import type { DelegateGroundingId } from '@shrkcrft/core';
|
|
19
|
+
import { type IBuildTaskRiskOptions } from './task-risk.js';
|
|
20
|
+
import { type IUncertaintyReport } from './uncertainty-report.js';
|
|
21
|
+
import type { ISharkcraftInspection } from './sharkcraft-inspector.js';
|
|
22
|
+
export declare const DELEGATE_ANALYSIS_SCHEMA = "sharkcraft.delegate-analysis/v1";
|
|
23
|
+
/** The deterministic ground truth an analysis recipe is checked against. */
|
|
24
|
+
export interface IGroundingFacts {
|
|
25
|
+
groundedOn: string;
|
|
26
|
+
/** Compact human-readable summary fed to the model as ground truth. */
|
|
27
|
+
summary: string;
|
|
28
|
+
/** Known entities (normalised references the model may legitimately cite). */
|
|
29
|
+
entities: readonly string[];
|
|
30
|
+
/** The underlying deterministic report (surfaced in `--json`). */
|
|
31
|
+
raw: unknown;
|
|
32
|
+
}
|
|
33
|
+
/** One model finding, tagged by the deterministic cross-check. */
|
|
34
|
+
export interface IAnalysisFinding {
|
|
35
|
+
id: string;
|
|
36
|
+
message: string;
|
|
37
|
+
/** Entities the model cited (explicit refs, or refs inferred from the message). */
|
|
38
|
+
refs: readonly string[];
|
|
39
|
+
/** True when the finding is anchored to ground truth (via refs or a message mention). */
|
|
40
|
+
grounded: boolean;
|
|
41
|
+
/** Cited refs NOT present in the ground truth. */
|
|
42
|
+
unverifiedRefs: readonly string[];
|
|
43
|
+
}
|
|
44
|
+
/** The read-only advisory report an `analysis` recipe produces. */
|
|
45
|
+
export interface IDelegateAnalysisReport {
|
|
46
|
+
schema: typeof DELEGATE_ANALYSIS_SCHEMA;
|
|
47
|
+
generatedAt: string;
|
|
48
|
+
recipeId: string;
|
|
49
|
+
mode: 'analysis';
|
|
50
|
+
groundedOn: string;
|
|
51
|
+
task: string;
|
|
52
|
+
/** Which provider produced the findings (`'none'` = deterministic-only). */
|
|
53
|
+
provider: string;
|
|
54
|
+
grounding: {
|
|
55
|
+
summary: string;
|
|
56
|
+
entityCount: number;
|
|
57
|
+
};
|
|
58
|
+
findings: readonly IAnalysisFinding[];
|
|
59
|
+
groundedCount: number;
|
|
60
|
+
unverifiedCount: number;
|
|
61
|
+
/** Optional free-form note from the model (informational, never grounded). */
|
|
62
|
+
modelNote?: string;
|
|
63
|
+
/** How many read-only query rounds the model ran (Phase 3 query loop). */
|
|
64
|
+
queriesRun?: number;
|
|
65
|
+
/** How many fan-out slices ran (Phase 4), when fan-out was used. */
|
|
66
|
+
fanOutSlices?: number;
|
|
67
|
+
/** Advisory escalation into a patch recipe, when the recipe declares escalateTo. */
|
|
68
|
+
escalation?: {
|
|
69
|
+
recipe: string;
|
|
70
|
+
task: string;
|
|
71
|
+
next: string;
|
|
72
|
+
};
|
|
73
|
+
markdown: string;
|
|
74
|
+
uncertainty: IUncertaintyReport;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* A layer-neutral snapshot of a failed delegate PATCH attempt — the ground truth
|
|
78
|
+
* a `retry-analysis` recipe reasons over. Kept primitive (no dependency on the
|
|
79
|
+
* cli-layer `IExecuteDelegateRunResult`) so the cli maps its result onto this and
|
|
80
|
+
* the inspector grounds on it without an upward import.
|
|
81
|
+
*/
|
|
82
|
+
export interface IDelegateFailureContext {
|
|
83
|
+
/** The failing status, e.g. `verify-failed` / `conflicts` / `guardrail-refused`. */
|
|
84
|
+
status: string;
|
|
85
|
+
message: string;
|
|
86
|
+
conflicts?: readonly string[];
|
|
87
|
+
commandsFailed?: readonly string[];
|
|
88
|
+
refused?: readonly string[];
|
|
89
|
+
droppedOps?: readonly {
|
|
90
|
+
kind: string;
|
|
91
|
+
targetPath: string;
|
|
92
|
+
}[];
|
|
93
|
+
guardrailGlobs?: readonly string[];
|
|
94
|
+
allowedOps?: readonly string[];
|
|
95
|
+
/** 1-based attempt number this failure occurred on. */
|
|
96
|
+
attempt?: number;
|
|
97
|
+
}
|
|
98
|
+
/** Options for `runGroundingReport` — task-risk knobs plus grounding payloads. */
|
|
99
|
+
export interface IRunGroundingOptions extends IBuildTaskRiskOptions {
|
|
100
|
+
/** Required when grounding on `delegate-failure`. */
|
|
101
|
+
failure?: IDelegateFailureContext;
|
|
102
|
+
/** Required when grounding on `plan-simulation` — path to a saved plan. */
|
|
103
|
+
planPath?: string;
|
|
104
|
+
}
|
|
105
|
+
/** Distil a delegate patch failure into ground truth for `retry-analysis`. */
|
|
106
|
+
export declare function buildDelegateFailureFacts(failure: IDelegateFailureContext): IGroundingFacts;
|
|
107
|
+
/**
|
|
108
|
+
* Run the deterministic report an analysis recipe grounds on, distilled to a
|
|
109
|
+
* compact summary + the entities a finding may legitimately cite. Read-only.
|
|
110
|
+
*/
|
|
111
|
+
export declare function runGroundingReport(groundedOn: DelegateGroundingId | string, task: string, inspection: ISharkcraftInspection, options?: IRunGroundingOptions): Promise<IGroundingFacts>;
|
|
112
|
+
export interface ICrossCheckOptions {
|
|
113
|
+
/** Drop non-grounded findings instead of keeping+flagging them. */
|
|
114
|
+
strict?: boolean;
|
|
115
|
+
}
|
|
116
|
+
export interface ICrossCheckResult {
|
|
117
|
+
findings: IAnalysisFinding[];
|
|
118
|
+
groundedCount: number;
|
|
119
|
+
unverifiedCount: number;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Cross-check model findings against the deterministic ground truth. A finding is
|
|
123
|
+
* `grounded` when it cites ≥1 ref that all resolve to a report entity, OR — when
|
|
124
|
+
* it cites no explicit refs — when its MESSAGE mentions a ground-truth entity
|
|
125
|
+
* verbatim (models routinely state facts in prose without filling a refs array;
|
|
126
|
+
* the live smoke showed exactly this). A claim anchored to nothing in the ground
|
|
127
|
+
* truth stays unverified — judgment must ride on facts the model cannot fabricate.
|
|
128
|
+
*/
|
|
129
|
+
export declare function crossCheckFindings(rawFindings: readonly {
|
|
130
|
+
id?: string;
|
|
131
|
+
message: string;
|
|
132
|
+
refs?: readonly string[];
|
|
133
|
+
}[], facts: IGroundingFacts, options?: ICrossCheckOptions): ICrossCheckResult;
|
|
134
|
+
export interface IBuildAnalysisReportInput {
|
|
135
|
+
recipeId: string;
|
|
136
|
+
groundedOn: string;
|
|
137
|
+
task: string;
|
|
138
|
+
provider: string;
|
|
139
|
+
facts: IGroundingFacts;
|
|
140
|
+
crossCheck: ICrossCheckResult;
|
|
141
|
+
modelNote?: string;
|
|
142
|
+
/** True when no local model ran — the report is deterministic grounding only. */
|
|
143
|
+
modelUnavailable?: boolean;
|
|
144
|
+
/** Read-only query rounds the model ran (Phase 3), when the query loop was used. */
|
|
145
|
+
queriesRun?: number;
|
|
146
|
+
/** Fan-out slices that ran (Phase 4), when fan-out was used. */
|
|
147
|
+
fanOutSlices?: number;
|
|
148
|
+
/** A patch recipe this analysis may escalate to (Phase 4, advisory). */
|
|
149
|
+
escalateTo?: string;
|
|
150
|
+
generatedAt: string;
|
|
151
|
+
}
|
|
152
|
+
/** Assemble the honest, advisory analysis report. Never writes. */
|
|
153
|
+
export declare function buildDelegateAnalysisReport(input: IBuildAnalysisReportInput): IDelegateAnalysisReport;
|
|
154
|
+
//# sourceMappingURL=delegate-grounding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegate-grounding.d.ts","sourceRoot":"","sources":["../src/delegate-grounding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import { buildTaskRiskReport } from "./task-risk.js";
|
|
2
|
+
import { analyzeTestImpact } from "./test-impact.js";
|
|
3
|
+
import { simulatePlan } from "./plan-simulation.js";
|
|
4
|
+
import { buildAgentBrief } from "./agent-brief.js";
|
|
5
|
+
import * as nodePath from 'node:path';
|
|
6
|
+
import { buildUncertaintyReport } from "./uncertainty-report.js";
|
|
7
|
+
export const DELEGATE_ANALYSIS_SCHEMA = 'sharkcraft.delegate-analysis/v1';
|
|
8
|
+
function norm(s) {
|
|
9
|
+
// Strip surrounding delimiters/punctuation so a model that echoes a ground-truth
|
|
10
|
+
// display form (`[intent-migration]`, `` `src/foo.ts` ``) still matches the bare
|
|
11
|
+
// entity — otherwise a legitimate citation is falsely flagged `unverified`.
|
|
12
|
+
return s
|
|
13
|
+
.trim()
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.replace(/^[[\](){}`'"]+/, '')
|
|
16
|
+
.replace(/[[\](){}`'".,;:]+$/, '');
|
|
17
|
+
}
|
|
18
|
+
function basename(s) {
|
|
19
|
+
const n = norm(s);
|
|
20
|
+
const i = n.lastIndexOf('/');
|
|
21
|
+
return i >= 0 ? n.slice(i + 1) : n;
|
|
22
|
+
}
|
|
23
|
+
function looksLikePath(s) {
|
|
24
|
+
return /[\/.]/.test(s) && /\.(ts|tsx|js|jsx|mjs|cjs|md|json|ya?ml)$/i.test(s.trim());
|
|
25
|
+
}
|
|
26
|
+
/** Distil a task-risk report into the entities a finding may legitimately cite. */
|
|
27
|
+
function groundingEntitiesFromTaskRisk(r) {
|
|
28
|
+
const out = new Set();
|
|
29
|
+
const add = (xs) => {
|
|
30
|
+
for (const x of xs)
|
|
31
|
+
if (x && x.trim().length > 0)
|
|
32
|
+
out.add(x.trim());
|
|
33
|
+
};
|
|
34
|
+
add(r.affectedFiles);
|
|
35
|
+
add(r.highFanInFiles);
|
|
36
|
+
add(r.highFanOutFiles);
|
|
37
|
+
add(r.affectedConstructs);
|
|
38
|
+
add(r.reasons.map((x) => x.code));
|
|
39
|
+
add(r.ownershipGaps.filter(looksLikePath));
|
|
40
|
+
return [...out];
|
|
41
|
+
}
|
|
42
|
+
/** The path in a `"path: reason"` conflict string (the citable entity). */
|
|
43
|
+
function conflictPath(c) {
|
|
44
|
+
const i = c.indexOf(':');
|
|
45
|
+
return (i >= 0 ? c.slice(0, i) : c).trim();
|
|
46
|
+
}
|
|
47
|
+
/** Distil a delegate patch failure into ground truth for `retry-analysis`. */
|
|
48
|
+
export function buildDelegateFailureFacts(failure) {
|
|
49
|
+
const entities = new Set();
|
|
50
|
+
const add = (xs) => {
|
|
51
|
+
for (const x of xs ?? [])
|
|
52
|
+
if (x && x.trim().length > 0)
|
|
53
|
+
entities.add(x.trim());
|
|
54
|
+
};
|
|
55
|
+
add((failure.conflicts ?? []).map(conflictPath));
|
|
56
|
+
add(failure.refused);
|
|
57
|
+
add((failure.droppedOps ?? []).map((d) => d.targetPath));
|
|
58
|
+
add(failure.commandsFailed);
|
|
59
|
+
add(failure.allowedOps);
|
|
60
|
+
entities.add(failure.status);
|
|
61
|
+
const lines = [];
|
|
62
|
+
lines.push(`Delegate patch attempt failed: ${failure.status}${failure.attempt ? ` (attempt ${failure.attempt})` : ''}.`);
|
|
63
|
+
lines.push(`Message: ${failure.message}`);
|
|
64
|
+
if (failure.conflicts?.length)
|
|
65
|
+
lines.push(`Conflicts: ${failure.conflicts.join('; ')}.`);
|
|
66
|
+
if (failure.commandsFailed?.length)
|
|
67
|
+
lines.push(`Verification commands failed: ${failure.commandsFailed.join(', ')}.`);
|
|
68
|
+
if (failure.refused?.length)
|
|
69
|
+
lines.push(`Targets refused (outside guardrail globs): ${failure.refused.join(', ')}.`);
|
|
70
|
+
if (failure.droppedOps?.length) {
|
|
71
|
+
lines.push(`Ops dropped (kind not allowed): ${failure.droppedOps.map((d) => `${d.kind}→${d.targetPath}`).join(', ')}.`);
|
|
72
|
+
}
|
|
73
|
+
if (failure.allowedOps?.length)
|
|
74
|
+
lines.push(`Only these op kinds are allowed: ${failure.allowedOps.join(', ')}.`);
|
|
75
|
+
if (failure.guardrailGlobs?.length)
|
|
76
|
+
lines.push(`Only these globs may be touched: ${failure.guardrailGlobs.join(', ')}.`);
|
|
77
|
+
return { groundedOn: 'delegate-failure', summary: lines.join('\n'), entities: [...entities], raw: failure };
|
|
78
|
+
}
|
|
79
|
+
/** Entities + summary for grounding on the agent brief. */
|
|
80
|
+
function groundingFromAgentBrief(b) {
|
|
81
|
+
const entities = new Set();
|
|
82
|
+
if (b.taskRisk) {
|
|
83
|
+
for (const f of b.taskRisk.affectedFiles)
|
|
84
|
+
entities.add(f);
|
|
85
|
+
for (const c of b.taskRisk.affectedConstructs)
|
|
86
|
+
entities.add(c);
|
|
87
|
+
for (const f of b.taskRisk.highFanInFiles)
|
|
88
|
+
entities.add(f);
|
|
89
|
+
}
|
|
90
|
+
const risk = b.taskRisk ? `Risk: ${b.taskRisk.riskLevel} (score ${b.taskRisk.score}). ` : '';
|
|
91
|
+
const summary = `Agent brief for: ${b.task}\n${risk}\n${b.markdown.slice(0, 1400)}`;
|
|
92
|
+
return { summary, entities: [...entities].filter((x) => x.trim().length > 0) };
|
|
93
|
+
}
|
|
94
|
+
/** Entities a finding may cite when grounded on a test-impact report. */
|
|
95
|
+
function groundingEntitiesFromTestImpact(t) {
|
|
96
|
+
const out = new Set();
|
|
97
|
+
const add = (xs) => {
|
|
98
|
+
for (const x of xs)
|
|
99
|
+
if (x && x.trim().length > 0)
|
|
100
|
+
out.add(x.trim());
|
|
101
|
+
};
|
|
102
|
+
add(t.inputFiles);
|
|
103
|
+
add(t.likelyTestFiles);
|
|
104
|
+
add(t.missingTestFiles);
|
|
105
|
+
add(t.riskAreas);
|
|
106
|
+
return [...out];
|
|
107
|
+
}
|
|
108
|
+
/** Entities a finding may cite when grounded on a plan simulation. */
|
|
109
|
+
function groundingEntitiesFromPlanSim(p) {
|
|
110
|
+
const out = new Set();
|
|
111
|
+
const add = (xs) => {
|
|
112
|
+
for (const x of xs)
|
|
113
|
+
if (x && x.trim().length > 0)
|
|
114
|
+
out.add(x.trim());
|
|
115
|
+
};
|
|
116
|
+
add(p.files.map((f) => f.relativePath));
|
|
117
|
+
add(p.affectedAreas);
|
|
118
|
+
add(p.affectedConstructs);
|
|
119
|
+
add(p.ownershipReviewFiles);
|
|
120
|
+
add(p.likelyTests);
|
|
121
|
+
return [...out];
|
|
122
|
+
}
|
|
123
|
+
/** A compact ground-truth summary of a plan simulation for the model prompt. */
|
|
124
|
+
function compactPlanSimSummary(p) {
|
|
125
|
+
const lines = [];
|
|
126
|
+
lines.push(`Plan: ${p.source} (${p.templateId ?? 'no-template'}), signature ${p.signature}, readiness ${p.applyReadiness}.`);
|
|
127
|
+
if (p.files.length > 0)
|
|
128
|
+
lines.push(`Files: ${p.files.map((f) => `${f.changeType} ${f.relativePath}`).slice(0, 12).join(', ')}.`);
|
|
129
|
+
if (p.publicApiTouched)
|
|
130
|
+
lines.push('Touches a public API surface.');
|
|
131
|
+
if (p.ownershipReviewRequired)
|
|
132
|
+
lines.push(`Ownership review required: ${p.ownershipReviewFiles.slice(0, 6).join(', ')}.`);
|
|
133
|
+
if (p.potentialBoundaryConcerns.length > 0)
|
|
134
|
+
lines.push(`Boundary concerns: ${p.potentialBoundaryConcerns.length}.`);
|
|
135
|
+
if (p.policyConcerns.length > 0)
|
|
136
|
+
lines.push(`Policy concerns: ${p.policyConcerns.slice(0, 6).join('; ')}.`);
|
|
137
|
+
if (p.applyReadinessReasons.length > 0)
|
|
138
|
+
lines.push(`Readiness reasons: ${p.applyReadinessReasons.slice(0, 6).join('; ')}.`);
|
|
139
|
+
return lines.join('\n');
|
|
140
|
+
}
|
|
141
|
+
/** A compact ground-truth summary of a test-impact report for the model prompt. */
|
|
142
|
+
function compactTestImpactSummary(t) {
|
|
143
|
+
const lines = [];
|
|
144
|
+
lines.push(`Test impact for: ${t.task || '(repo)'} (confidence ${t.confidence}).`);
|
|
145
|
+
if (t.likelyTestFiles.length > 0)
|
|
146
|
+
lines.push(`Existing tests: ${t.likelyTestFiles.slice(0, 12).join(', ')}.`);
|
|
147
|
+
if (t.missingTestFiles.length > 0)
|
|
148
|
+
lines.push(`Missing tests (expected locations): ${t.missingTestFiles.slice(0, 12).join(', ')}.`);
|
|
149
|
+
if (t.riskAreas.length > 0)
|
|
150
|
+
lines.push(`Risk areas: ${t.riskAreas.slice(0, 8).join('; ')}.`);
|
|
151
|
+
if (t.minimalCommands.length > 0)
|
|
152
|
+
lines.push(`Minimal test command(s): ${t.minimalCommands.join(' ; ')}.`);
|
|
153
|
+
return lines.join('\n');
|
|
154
|
+
}
|
|
155
|
+
/** A compact ground-truth summary for the model prompt (not the full report). */
|
|
156
|
+
function compactTaskRiskSummary(r) {
|
|
157
|
+
const lines = [];
|
|
158
|
+
lines.push(`Task risk: ${r.riskLevel} (score ${r.score}), intent ${r.intent.kind}.`);
|
|
159
|
+
lines.push(`Human approval required: ${r.humanApprovalRequired ? 'yes' : 'no'}.`);
|
|
160
|
+
if (r.affectedFiles.length > 0)
|
|
161
|
+
lines.push(`Affected files: ${r.affectedFiles.slice(0, 12).join(', ')}.`);
|
|
162
|
+
if (r.highFanInFiles.length > 0)
|
|
163
|
+
lines.push(`High fan-in: ${r.highFanInFiles.join(', ')}.`);
|
|
164
|
+
if (r.boundaryConcerns.length > 0)
|
|
165
|
+
lines.push(`Boundary concerns: ${r.boundaryConcerns.slice(0, 6).join('; ')}.`);
|
|
166
|
+
if (r.policyConcerns.length > 0)
|
|
167
|
+
lines.push(`Policy concerns: ${r.policyConcerns.slice(0, 6).join('; ')}.`);
|
|
168
|
+
if (r.testGaps.length > 0)
|
|
169
|
+
lines.push(`Test gaps: ${r.testGaps.slice(0, 6).join('; ')}.`);
|
|
170
|
+
lines.push('Reasons:');
|
|
171
|
+
for (const reason of r.reasons.slice(0, 12))
|
|
172
|
+
lines.push(` - [${reason.code}] ${reason.message} (+${reason.weight})`);
|
|
173
|
+
return lines.join('\n');
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Run the deterministic report an analysis recipe grounds on, distilled to a
|
|
177
|
+
* compact summary + the entities a finding may legitimately cite. Read-only.
|
|
178
|
+
*/
|
|
179
|
+
export async function runGroundingReport(groundedOn, task, inspection, options = {}) {
|
|
180
|
+
switch (groundedOn) {
|
|
181
|
+
case 'task-risk': {
|
|
182
|
+
const r = await buildTaskRiskReport(task, inspection, options);
|
|
183
|
+
return {
|
|
184
|
+
groundedOn,
|
|
185
|
+
summary: compactTaskRiskSummary(r),
|
|
186
|
+
entities: groundingEntitiesFromTaskRisk(r),
|
|
187
|
+
raw: r,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
case 'test-impact': {
|
|
191
|
+
const t = analyzeTestImpact(inspection, { task });
|
|
192
|
+
return {
|
|
193
|
+
groundedOn,
|
|
194
|
+
summary: compactTestImpactSummary(t),
|
|
195
|
+
entities: groundingEntitiesFromTestImpact(t),
|
|
196
|
+
raw: t,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
case 'agent-brief': {
|
|
200
|
+
const b = await buildAgentBrief(inspection, { task });
|
|
201
|
+
const { summary, entities } = groundingFromAgentBrief(b);
|
|
202
|
+
return { groundedOn, summary, entities, raw: b };
|
|
203
|
+
}
|
|
204
|
+
case 'plan-simulation': {
|
|
205
|
+
// Grounded on a saved plan the cli supplies via `options.planPath`. Absent
|
|
206
|
+
// it (or on a read error) there is nothing to critique.
|
|
207
|
+
if (!options.planPath) {
|
|
208
|
+
return { groundedOn, summary: '(plan-simulation grounding needs a --plan <path>)', entities: [], raw: null };
|
|
209
|
+
}
|
|
210
|
+
try {
|
|
211
|
+
const abs = nodePath.isAbsolute(options.planPath)
|
|
212
|
+
? options.planPath
|
|
213
|
+
: nodePath.resolve(inspection.projectRoot, options.planPath);
|
|
214
|
+
const p = await simulatePlan(inspection, abs, { includeBoundaries: true, includeImpact: true, includeOwnership: true });
|
|
215
|
+
return { groundedOn, summary: compactPlanSimSummary(p), entities: groundingEntitiesFromPlanSim(p), raw: p };
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
return { groundedOn, summary: `(could not simulate plan: ${e.message})`, entities: [], raw: null };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
case 'delegate-failure':
|
|
222
|
+
// Grounded on a failed patch attempt — the cli supplies the failure via
|
|
223
|
+
// `options.failure` (this grounding needs no inspection). Absent it, there
|
|
224
|
+
// is nothing to reason over (e.g. a standalone MCP/CLI call with no failure).
|
|
225
|
+
return options.failure
|
|
226
|
+
? buildDelegateFailureFacts(options.failure)
|
|
227
|
+
: {
|
|
228
|
+
groundedOn,
|
|
229
|
+
summary: '(delegate-failure grounding needs a failure context — run it in the delegate retry loop)',
|
|
230
|
+
entities: [],
|
|
231
|
+
raw: null,
|
|
232
|
+
};
|
|
233
|
+
default:
|
|
234
|
+
// Config validation gates `groundedOn` to a known id, so this is a
|
|
235
|
+
// defensive fallback (empty ground truth ⇒ every claim is unverified).
|
|
236
|
+
return { groundedOn, summary: `(no grounding runner for "${groundedOn}")`, entities: [], raw: null };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Cross-check model findings against the deterministic ground truth. A finding is
|
|
241
|
+
* `grounded` when it cites ≥1 ref that all resolve to a report entity, OR — when
|
|
242
|
+
* it cites no explicit refs — when its MESSAGE mentions a ground-truth entity
|
|
243
|
+
* verbatim (models routinely state facts in prose without filling a refs array;
|
|
244
|
+
* the live smoke showed exactly this). A claim anchored to nothing in the ground
|
|
245
|
+
* truth stays unverified — judgment must ride on facts the model cannot fabricate.
|
|
246
|
+
*/
|
|
247
|
+
export function crossCheckFindings(rawFindings, facts, options = {}) {
|
|
248
|
+
const entities = new Set(facts.entities.map(norm));
|
|
249
|
+
const basenames = new Set(facts.entities.map(basename));
|
|
250
|
+
const resolves = (ref) => entities.has(norm(ref)) || basenames.has(basename(ref));
|
|
251
|
+
// Entities long enough to match unambiguously inside prose (avoid noise from
|
|
252
|
+
// very short codes). Matched case-insensitively as a substring of the message.
|
|
253
|
+
const scannable = facts.entities.filter((e) => e.trim().length >= 4);
|
|
254
|
+
const mentionedIn = (message) => {
|
|
255
|
+
const m = message.toLowerCase();
|
|
256
|
+
const hits = [];
|
|
257
|
+
for (const e of scannable) {
|
|
258
|
+
const en = e.toLowerCase();
|
|
259
|
+
const bn = basename(e);
|
|
260
|
+
if (m.includes(en) || (bn.length >= 4 && m.includes(bn)))
|
|
261
|
+
hits.push(e);
|
|
262
|
+
}
|
|
263
|
+
return hits;
|
|
264
|
+
};
|
|
265
|
+
const findings = [];
|
|
266
|
+
let groundedCount = 0;
|
|
267
|
+
let unverifiedCount = 0;
|
|
268
|
+
for (let i = 0; i < rawFindings.length; i += 1) {
|
|
269
|
+
const rf = rawFindings[i];
|
|
270
|
+
const explicit = (rf.refs ?? []).map((r) => String(r));
|
|
271
|
+
let refs = explicit;
|
|
272
|
+
let unverifiedRefs = explicit.filter((r) => !resolves(r));
|
|
273
|
+
let grounded = explicit.length > 0 && unverifiedRefs.length === 0;
|
|
274
|
+
if (!grounded && explicit.length === 0) {
|
|
275
|
+
// Fallback: the model stated facts in prose. Infer refs from the message.
|
|
276
|
+
const inferred = mentionedIn(rf.message);
|
|
277
|
+
if (inferred.length > 0) {
|
|
278
|
+
refs = inferred;
|
|
279
|
+
unverifiedRefs = [];
|
|
280
|
+
grounded = true;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (options.strict && !grounded) {
|
|
284
|
+
unverifiedCount += 1;
|
|
285
|
+
continue; // dropped
|
|
286
|
+
}
|
|
287
|
+
findings.push({
|
|
288
|
+
id: rf.id?.trim() || `finding-${i + 1}`,
|
|
289
|
+
message: rf.message,
|
|
290
|
+
refs,
|
|
291
|
+
grounded,
|
|
292
|
+
unverifiedRefs,
|
|
293
|
+
});
|
|
294
|
+
if (grounded)
|
|
295
|
+
groundedCount += 1;
|
|
296
|
+
else
|
|
297
|
+
unverifiedCount += 1;
|
|
298
|
+
}
|
|
299
|
+
return { findings, groundedCount, unverifiedCount };
|
|
300
|
+
}
|
|
301
|
+
function buildAnalysisUncertainty(input) {
|
|
302
|
+
const { crossCheck, modelUnavailable } = input;
|
|
303
|
+
let confidence = 'medium';
|
|
304
|
+
const reasons = [];
|
|
305
|
+
const missing = [];
|
|
306
|
+
if (modelUnavailable) {
|
|
307
|
+
confidence = 'unknown';
|
|
308
|
+
reasons.push('No local LLM reachable — deterministic grounding only, no judgment layer.');
|
|
309
|
+
missing.push({ id: 'no-model', message: 'No local model produced findings.' });
|
|
310
|
+
}
|
|
311
|
+
else if (crossCheck.findings.length === 0) {
|
|
312
|
+
confidence = 'low';
|
|
313
|
+
reasons.push('The model returned no findings.');
|
|
314
|
+
}
|
|
315
|
+
else if (crossCheck.unverifiedCount > crossCheck.groundedCount) {
|
|
316
|
+
confidence = 'low';
|
|
317
|
+
reasons.push(`${crossCheck.unverifiedCount} of ${crossCheck.findings.length} finding(s) are unverified (cite entities absent from the ground truth).`);
|
|
318
|
+
}
|
|
319
|
+
if (input.facts.entities.length === 0) {
|
|
320
|
+
missing.push({ id: 'empty-grounding', message: 'The grounding report yielded no entities to check against.' });
|
|
321
|
+
}
|
|
322
|
+
return buildUncertaintyReport({
|
|
323
|
+
confidence,
|
|
324
|
+
reasons,
|
|
325
|
+
missingSignals: missing,
|
|
326
|
+
suggestedCommands: [`shrk risk "${input.task || '<task>'}"`, `shrk delegate explain ${input.recipeId}`],
|
|
327
|
+
safeFallbackCommand: `shrk risk "${input.task || '<task>'}"`,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
function renderAnalysisMarkdown(input) {
|
|
331
|
+
const { crossCheck, facts } = input;
|
|
332
|
+
const lines = [];
|
|
333
|
+
lines.push(`# Delegate analysis — ${input.recipeId}`);
|
|
334
|
+
lines.push('');
|
|
335
|
+
lines.push(`- task: ${input.task || '(none)'}`);
|
|
336
|
+
lines.push(`- grounded on: **${input.groundedOn}**`);
|
|
337
|
+
lines.push(`- provider: ${input.provider}`);
|
|
338
|
+
if (input.queriesRun !== undefined)
|
|
339
|
+
lines.push(`- query rounds: ${input.queriesRun} (read-only fact-fetch loop)`);
|
|
340
|
+
if (input.fanOutSlices !== undefined)
|
|
341
|
+
lines.push(`- fan-out slices: ${input.fanOutSlices} (per-slice passes, merged)`);
|
|
342
|
+
lines.push(`- findings: ${crossCheck.findings.length} (grounded ${crossCheck.groundedCount}, unverified ${crossCheck.unverifiedCount})`);
|
|
343
|
+
lines.push('');
|
|
344
|
+
lines.push('## Ground truth');
|
|
345
|
+
lines.push('');
|
|
346
|
+
lines.push(facts.summary);
|
|
347
|
+
lines.push('');
|
|
348
|
+
lines.push('## Findings');
|
|
349
|
+
lines.push('');
|
|
350
|
+
if (crossCheck.findings.length === 0) {
|
|
351
|
+
lines.push(input.modelUnavailable
|
|
352
|
+
? '_No local LLM reachable — deterministic grounding only. Start Ollama / set LLAMACPP_MODEL_PATH to add the judgment layer._'
|
|
353
|
+
: '_(none)_');
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
for (const f of crossCheck.findings) {
|
|
357
|
+
const tag = f.grounded ? '✓ grounded' : '⚠ unverified';
|
|
358
|
+
lines.push(`- **[${tag}]** ${f.message}`);
|
|
359
|
+
if (f.refs.length > 0)
|
|
360
|
+
lines.push(` - refs: ${f.refs.join(', ')}`);
|
|
361
|
+
if (f.unverifiedRefs.length > 0)
|
|
362
|
+
lines.push(` - not in ground truth: ${f.unverifiedRefs.join(', ')}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (input.modelNote) {
|
|
366
|
+
lines.push('');
|
|
367
|
+
lines.push('## Model note (informational)');
|
|
368
|
+
lines.push('');
|
|
369
|
+
lines.push(input.modelNote);
|
|
370
|
+
}
|
|
371
|
+
const escalation = escalationHint(input);
|
|
372
|
+
if (escalation) {
|
|
373
|
+
lines.push('');
|
|
374
|
+
lines.push('## Suggested escalation (advisory — you run it)');
|
|
375
|
+
lines.push('');
|
|
376
|
+
lines.push(`This gap can be handed to the patch recipe \`${escalation.recipe}\`:`);
|
|
377
|
+
lines.push('```');
|
|
378
|
+
lines.push(escalation.next);
|
|
379
|
+
lines.push('```');
|
|
380
|
+
}
|
|
381
|
+
lines.push('');
|
|
382
|
+
lines.push('---');
|
|
383
|
+
lines.push('_Advisory, read-only — no write performed. Findings tagged `unverified` cite entities absent from the deterministic ground truth; treat them as hypotheses, not facts._');
|
|
384
|
+
return lines.join('\n');
|
|
385
|
+
}
|
|
386
|
+
/** Assemble the honest, advisory analysis report. Never writes. */
|
|
387
|
+
export function buildDelegateAnalysisReport(input) {
|
|
388
|
+
const report = {
|
|
389
|
+
schema: DELEGATE_ANALYSIS_SCHEMA,
|
|
390
|
+
generatedAt: input.generatedAt,
|
|
391
|
+
recipeId: input.recipeId,
|
|
392
|
+
mode: 'analysis',
|
|
393
|
+
groundedOn: input.groundedOn,
|
|
394
|
+
task: input.task,
|
|
395
|
+
provider: input.provider,
|
|
396
|
+
grounding: { summary: input.facts.summary, entityCount: input.facts.entities.length },
|
|
397
|
+
findings: input.crossCheck.findings,
|
|
398
|
+
groundedCount: input.crossCheck.groundedCount,
|
|
399
|
+
unverifiedCount: input.crossCheck.unverifiedCount,
|
|
400
|
+
markdown: renderAnalysisMarkdown(input),
|
|
401
|
+
uncertainty: buildAnalysisUncertainty(input),
|
|
402
|
+
};
|
|
403
|
+
if (input.modelNote)
|
|
404
|
+
report.modelNote = input.modelNote;
|
|
405
|
+
if (input.queriesRun !== undefined)
|
|
406
|
+
report.queriesRun = input.queriesRun;
|
|
407
|
+
if (input.fanOutSlices !== undefined)
|
|
408
|
+
report.fanOutSlices = input.fanOutSlices;
|
|
409
|
+
const escalation = escalationHint(input);
|
|
410
|
+
if (escalation)
|
|
411
|
+
report.escalation = escalation;
|
|
412
|
+
return report;
|
|
413
|
+
}
|
|
414
|
+
/** Advisory next-command into a patch recipe, when findings warrant escalation. */
|
|
415
|
+
function escalationHint(input) {
|
|
416
|
+
if (!input.escalateTo)
|
|
417
|
+
return undefined;
|
|
418
|
+
const anchor = input.crossCheck.findings.find((f) => f.grounded) ?? input.crossCheck.findings[0];
|
|
419
|
+
if (!anchor)
|
|
420
|
+
return undefined;
|
|
421
|
+
const task = anchor.message.slice(0, 120);
|
|
422
|
+
return {
|
|
423
|
+
recipe: input.escalateTo,
|
|
424
|
+
task,
|
|
425
|
+
next: `shrk delegate run "${task}" --recipe ${input.escalateTo} --apply`,
|
|
426
|
+
};
|
|
427
|
+
}
|
package/dist/docs-check.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs-check.d.ts","sourceRoot":"","sources":["../src/docs-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EACA,sBAAsB,GACtB,wBAAwB,GACxB,oBAAoB,GACpB,0BAA0B,GAC1B,gCAAgC,GAChC,yBAAyB,CAAC;IAC9B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,iBAAiB,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,EAAE,EAAE,OAAO,CAAC;CACb;
|
|
1
|
+
{"version":3,"file":"docs-check.d.ts","sourceRoot":"","sources":["../src/docs-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EACA,sBAAsB,GACtB,wBAAwB,GACxB,oBAAoB,GACpB,0BAA0B,GAC1B,gCAAgC,GAChC,yBAAyB,CAAC;IAC9B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,iBAAiB,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,EAAE,EAAE,OAAO,CAAC;CACb;AAyCD,MAAM,WAAW,sBAAsB;IACrC;2CACuC;IACvC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,sBAA2B,GACnC,gBAAgB,CA+IlB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAepE"}
|
package/dist/docs-check.js
CHANGED
|
@@ -19,6 +19,7 @@ const REQUIRED_DOCS = [
|
|
|
19
19
|
'philosophy.md',
|
|
20
20
|
'safety-model.md',
|
|
21
21
|
'testing.md',
|
|
22
|
+
'exit-codes.md',
|
|
22
23
|
];
|
|
23
24
|
const README_REQUIRED_KEYWORDS = ['quick demo', 'onboard', 'safety'];
|
|
24
25
|
const README_SAFETY_KEYWORDS = ['mcp', 'read-only', 'never writes', 'safety'];
|
package/dist/git-helpers.d.ts
CHANGED
|
@@ -21,6 +21,22 @@ export declare function isGitRepo(cwd: string): boolean;
|
|
|
21
21
|
export declare function getGitRoot(cwd: string): string | null;
|
|
22
22
|
export declare function getGitBranch(cwd: string): string | null;
|
|
23
23
|
export declare function getChangedFiles(cwd: string, opts?: IGitChangedOptions): string[];
|
|
24
|
+
/**
|
|
25
|
+
* True when `ref` resolves to a commit in `cwd`'s repo. Lets a caller tell a
|
|
26
|
+
* genuinely-empty diff apart from a bad ref — `getChangedFiles` returns `[]` for
|
|
27
|
+
* both (a failed `git diff <bad-ref>` yields no names), so a gate that scopes on
|
|
28
|
+
* `--base <ref>` must validate the ref first or it reports "nothing changed"
|
|
29
|
+
* (a false verified-nothing) over a typo'd ref.
|
|
30
|
+
*/
|
|
31
|
+
export declare function refExists(cwd: string, ref: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* The content of `relPath` at `ref` (e.g. `git show HEAD:src/x.ts`), or `null`
|
|
34
|
+
* when the path did not exist at that ref (a newly-added file) or git failed.
|
|
35
|
+
* `relPath` is repo-root-relative. Used to diff a file's PAST state against the
|
|
36
|
+
* working tree without a checkout — e.g. to see what a now-edited file used to
|
|
37
|
+
* provide/register.
|
|
38
|
+
*/
|
|
39
|
+
export declare function gitShowFile(cwd: string, ref: string, relPath: string): string | null;
|
|
24
40
|
export declare function getStatusSummary(cwd: string): IGitStatusSummary;
|
|
25
41
|
export interface ICommitInfo {
|
|
26
42
|
readonly hash: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-helpers.d.ts","sourceRoot":"","sources":["../src/git-helpers.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB;AAqBD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAI9C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKrD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKvD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,MAAM,EAAE,CAwBpF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAyC/D;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,EAAE,CA6BrF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKjD"}
|
|
1
|
+
{"version":3,"file":"git-helpers.d.ts","sourceRoot":"","sources":["../src/git-helpers.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB;AAqBD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAI9C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKrD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKvD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,MAAM,EAAE,CAwBpF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAI3D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGpF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAyC/D;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,EAAE,CA6BrF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKjD"}
|
package/dist/git-helpers.js
CHANGED
|
@@ -67,6 +67,30 @@ export function getChangedFiles(cwd, opts = {}) {
|
|
|
67
67
|
}
|
|
68
68
|
return [...set].sort();
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* True when `ref` resolves to a commit in `cwd`'s repo. Lets a caller tell a
|
|
72
|
+
* genuinely-empty diff apart from a bad ref — `getChangedFiles` returns `[]` for
|
|
73
|
+
* both (a failed `git diff <bad-ref>` yields no names), so a gate that scopes on
|
|
74
|
+
* `--base <ref>` must validate the ref first or it reports "nothing changed"
|
|
75
|
+
* (a false verified-nothing) over a typo'd ref.
|
|
76
|
+
*/
|
|
77
|
+
export function refExists(cwd, ref) {
|
|
78
|
+
if (!ref)
|
|
79
|
+
return false;
|
|
80
|
+
const r = runGit(cwd, ['rev-parse', '--verify', '--quiet', `${ref}^{commit}`]);
|
|
81
|
+
return r.ok && r.stdout.trim().length > 0;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The content of `relPath` at `ref` (e.g. `git show HEAD:src/x.ts`), or `null`
|
|
85
|
+
* when the path did not exist at that ref (a newly-added file) or git failed.
|
|
86
|
+
* `relPath` is repo-root-relative. Used to diff a file's PAST state against the
|
|
87
|
+
* working tree without a checkout — e.g. to see what a now-edited file used to
|
|
88
|
+
* provide/register.
|
|
89
|
+
*/
|
|
90
|
+
export function gitShowFile(cwd, ref, relPath) {
|
|
91
|
+
const r = runGit(cwd, ['show', `${ref}:${relPath}`]);
|
|
92
|
+
return r.ok ? r.stdout : null;
|
|
93
|
+
}
|
|
70
94
|
export function getStatusSummary(cwd) {
|
|
71
95
|
const empty = {
|
|
72
96
|
branch: null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-hygiene.d.ts","sourceRoot":"","sources":["../src/import-hygiene.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,qBAAqB,iCAAiC,CAAC;AAEpE,oBAAY,wBAAwB;IAClC,gBAAgB,uBAAuB;IACvC,cAAc,oBAAoB;IAClC,aAAa,mBAAmB;CACjC;AAED,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAEjE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,OAAO,qBAAqB,CAAC;IAC9C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,OAAO,EAAE,IAAI,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oDAAoD;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,gDAAgD;IAChD,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,0FAA0F;IAC1F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAC3C;AAED;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,UAAU,CAAC;AAEpD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAKvE;AAED,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,wBAAwB,CAAC;IACzC,mCAAmC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"import-hygiene.d.ts","sourceRoot":"","sources":["../src/import-hygiene.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,qBAAqB,iCAAiC,CAAC;AAEpE,oBAAY,wBAAwB;IAClC,gBAAgB,uBAAuB;IACvC,cAAc,oBAAoB;IAClC,aAAa,mBAAmB;CACjC;AAED,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAEjE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,OAAO,qBAAqB,CAAC;IAC9C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,OAAO,EAAE,IAAI,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oDAAoD;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,gDAAgD;IAChD,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,0FAA0F;IAC1F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAC3C;AAED;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,UAAU,CAAC;AAEpD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAKvE;AAED,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,wBAAwB,CAAC;IACzC,mCAAmC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAkPD,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CAyCtB;AAID,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,MAAM,EAAE,wCAAwC,CAAC;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,wBAAwB,GAAG,KAAK,CAAC;IACjD,gEAAgE;IAChE,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,oBAAoB,EAC5B,OAAO,GAAE,qBAA0B,GAClC,4BAA4B,CAyB9B;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAiB5E"}
|
package/dist/import-hygiene.js
CHANGED
|
@@ -251,6 +251,15 @@ function stripCommentsPreservingOffsets(source) {
|
|
|
251
251
|
}
|
|
252
252
|
return buf.join('');
|
|
253
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Files import-hygiene never gates: test + fixture sources. Their whole PURPOSE
|
|
256
|
+
* is often to CONTAIN import-like text (`"const x = require('./y')"` as a string
|
|
257
|
+
* literal feeding a scanner test), so gating them produces false positives. The
|
|
258
|
+
* whole-tree scan has always excluded them; this constant makes the explicit
|
|
259
|
+
* `files` path (changed-only / `finish`) apply the SAME rule so the two can't
|
|
260
|
+
* drift — a change to a test file no longer spuriously fails an imports gate.
|
|
261
|
+
*/
|
|
262
|
+
const EXCLUDED_FROM_HYGIENE = /__tests__|\/__fixtures__/;
|
|
254
263
|
function defaultRoots(projectRoot) {
|
|
255
264
|
const pkgsDir = nodePath.join(projectRoot, 'packages');
|
|
256
265
|
if (!existsSync(pkgsDir))
|
|
@@ -272,10 +281,11 @@ export function buildImportHygieneReport(projectRoot, options = {}) {
|
|
|
272
281
|
if (options.files && options.files.length > 0) {
|
|
273
282
|
scanned = options.files
|
|
274
283
|
.map((f) => (nodePath.isAbsolute(f) ? f : nodePath.join(projectRoot, f)))
|
|
275
|
-
.filter((f) => existsSync(f) && /\.(ts|tsx)$/.test(f) && !/\.d\.ts$/.test(f))
|
|
284
|
+
.filter((f) => existsSync(f) && /\.(ts|tsx)$/.test(f) && !/\.d\.ts$/.test(f))
|
|
285
|
+
.filter((f) => !EXCLUDED_FROM_HYGIENE.test(f));
|
|
276
286
|
}
|
|
277
287
|
else {
|
|
278
|
-
scanned = roots.flatMap(listSourceFiles).filter((f) =>
|
|
288
|
+
scanned = roots.flatMap(listSourceFiles).filter((f) => !EXCLUDED_FROM_HYGIENE.test(f));
|
|
279
289
|
}
|
|
280
290
|
const findings = [];
|
|
281
291
|
const strictReasons = options.strictAllowlistReasons === true;
|
package/dist/index.d.ts
CHANGED
|
@@ -146,6 +146,7 @@ export * from './migration-readiness.js';
|
|
|
146
146
|
export * from './contract-file-rule.js';
|
|
147
147
|
export * from './check-guardrail-globs.js';
|
|
148
148
|
export * from './delegate-catalog.js';
|
|
149
|
+
export * from './delegate-grounding.js';
|
|
149
150
|
export * from './delegate-pack-recipes.js';
|
|
150
151
|
export * from './delegate-doctor.js';
|
|
151
152
|
export * from './agent-contract.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -146,6 +146,7 @@ export * from "./migration-readiness.js";
|
|
|
146
146
|
export * from "./contract-file-rule.js";
|
|
147
147
|
export * from "./check-guardrail-globs.js";
|
|
148
148
|
export * from "./delegate-catalog.js";
|
|
149
|
+
export * from "./delegate-grounding.js";
|
|
149
150
|
export * from "./delegate-pack-recipes.js";
|
|
150
151
|
export * from "./delegate-doctor.js";
|
|
151
152
|
export * from "./agent-contract.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type AppError, type Result } from '@shrkcrft/core';
|
|
2
2
|
import { type LoadedConfig } from '@shrkcrft/config';
|
|
3
3
|
/**
|
|
4
|
-
* A {@link LoadedConfig} whose
|
|
4
|
+
* A {@link LoadedConfig} whose data planes have had pack contributions
|
|
5
5
|
* merged in (local-wins), plus the human-readable notes from that merge.
|
|
6
6
|
*/
|
|
7
7
|
export interface IResolvedProjectConfig extends LoadedConfig {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-project-config.d.ts","sourceRoot":"","sources":["../src/resolve-project-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-project-config.d.ts","sourceRoot":"","sources":["../src/resolve-project-config.ts"],"names":[],"mappings":"AAwBA,OAAO,EAGL,KAAK,QAAQ,EAQb,KAAK,MAAM,EACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EASL,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAG1B;;;GAGG;AACH,MAAM,WAAW,sBAAuB,SAAQ,YAAY;IAC1D;;;;;;OAMG;IACH,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AAiID;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC,CAqGnD"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pack-aware project-config resolution.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
* `policyRules`, `
|
|
4
|
+
* The "cross-file invariant as DATA" planes — `wiringRules`, `registries`,
|
|
5
|
+
* `registrationGraph`, `policyRules`, `baselines`, `generatedArtifacts`,
|
|
6
|
+
* `reusePrimitives` — can be authored inline in a repo's
|
|
6
7
|
* `sharkcraft.config.ts`. They can ALSO be SHIPPED by a framework pack (e.g. a
|
|
7
8
|
* NestJS pack contributing "every @Injectable must be registered in a module"
|
|
8
9
|
* as a wiring rule) via the new `wiringRuleFiles` / `registryFiles` /
|
|
@@ -22,7 +23,7 @@
|
|
|
22
23
|
import { existsSync } from 'node:fs';
|
|
23
24
|
import * as nodePath from 'node:path';
|
|
24
25
|
import { importModuleViaLoader, ok, } from '@shrkcrft/core';
|
|
25
|
-
import { loadProjectConfig, PolicyRuleSchema, RegistrationIdiomSchema, RegistryDeclarationSchema, ReusePrimitiveSchema, WiringRuleSchema, } from '@shrkcrft/config';
|
|
26
|
+
import { BaselineRuleSchema, GeneratedArtifactRuleSchema, loadProjectConfig, PolicyRuleSchema, RegistrationIdiomSchema, RegistryDeclarationSchema, ReusePrimitiveSchema, WiringRuleSchema, } from '@shrkcrft/config';
|
|
26
27
|
import { discoverPacks } from '@shrkcrft/packs';
|
|
27
28
|
/**
|
|
28
29
|
* Generic per-plane load + validate + merge. Seeds the merged map from the
|
|
@@ -31,7 +32,13 @@ import { discoverPacks } from '@shrkcrft/packs';
|
|
|
31
32
|
* elements, and key collisions all become diagnostics and are skipped — never a
|
|
32
33
|
* throw.
|
|
33
34
|
*/
|
|
34
|
-
async function mergePlane(localArr, packContribs, schema, keyOf, planeLabel, diagnostics
|
|
35
|
+
async function mergePlane(localArr, packContribs, schema, keyOf, planeLabel, diagnostics,
|
|
36
|
+
/**
|
|
37
|
+
* Optional per-item veto applied to PACK elements only. Returns the
|
|
38
|
+
* diagnostic to record when the element must not be adopted (used by the
|
|
39
|
+
* shell-executing planes — see the call sites).
|
|
40
|
+
*/
|
|
41
|
+
packGuard) {
|
|
35
42
|
const merged = new Map();
|
|
36
43
|
const localKeys = new Set();
|
|
37
44
|
for (const item of localArr) {
|
|
@@ -68,6 +75,11 @@ async function mergePlane(localArr, packContribs, schema, keyOf, planeLabel, dia
|
|
|
68
75
|
continue;
|
|
69
76
|
}
|
|
70
77
|
const item = parsed.data;
|
|
78
|
+
const veto = packGuard?.(item, contrib.packageName);
|
|
79
|
+
if (veto !== undefined) {
|
|
80
|
+
diagnostics.push(veto);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
71
83
|
const key = keyOf(item);
|
|
72
84
|
if (merged.has(key)) {
|
|
73
85
|
diagnostics.push(localKeys.has(key)
|
|
@@ -120,6 +132,19 @@ export async function resolveProjectConfig(cwd) {
|
|
|
120
132
|
const registries = await mergePlane(base.config.registries ?? [], gatherPackContribs(validPacks, 'registryFiles'), RegistryDeclarationSchema, (r) => r.name, 'registry', diagnostics);
|
|
121
133
|
const registrationGraph = await mergePlane(base.config.registrationGraph ?? [], gatherPackContribs(validPacks, 'registrationGraphFiles'), RegistrationIdiomSchema, (r) => r.name, 'registrationIdiom', diagnostics);
|
|
122
134
|
const policyRules = await mergePlane(base.config.policyRules ?? [], gatherPackContribs(validPacks, 'policyRuleFiles'), PolicyRuleSchema, (r) => r.id, 'policyRule', diagnostics);
|
|
135
|
+
// The two SHELL-EXECUTING planes. A pack ships code the repo did not write;
|
|
136
|
+
// letting it also ship a command that `shrk baseline check` would then RUN is
|
|
137
|
+
// the same hazard the "pack-contributed verification commands are NOT
|
|
138
|
+
// auto-run" contract already forbids. So the merge keeps the safe subset —
|
|
139
|
+
// extractor computes and header-only generated rules — and drops the rest
|
|
140
|
+
// with a diagnostic. The guarantee is structural: no downstream caller has to
|
|
141
|
+
// remember to re-check provenance.
|
|
142
|
+
const baselines = await mergePlane(base.config.baselines ?? [], gatherPackContribs(validPacks, 'baselineFiles'), BaselineRuleSchema, (r) => r.id, 'baseline', diagnostics, (item, packName) => item.compute?.kind === 'command'
|
|
143
|
+
? `pack ${packName}: baseline "${item.id}" declares a shell \`compute.run\` — pack-contributed commands are never auto-run — skipped`
|
|
144
|
+
: undefined);
|
|
145
|
+
const generatedArtifacts = await mergePlane(base.config.generatedArtifacts ?? [], gatherPackContribs(validPacks, 'generatedArtifactFiles'), GeneratedArtifactRuleSchema, (r) => r.id, 'generatedArtifact', diagnostics, (item, packName) => item.regen !== undefined
|
|
146
|
+
? `pack ${packName}: generatedArtifact "${item.id}" declares a \`regen\` command — pack-contributed commands are never auto-run — skipped`
|
|
147
|
+
: undefined);
|
|
123
148
|
const reusePrimitives = await mergePlane(base.config.reusePrimitives ?? [], gatherPackContribs(validPacks, 'reusePrimitiveFiles'), ReusePrimitiveSchema, (r) => r.symbol, 'reusePrimitive', diagnostics);
|
|
124
149
|
return ok({
|
|
125
150
|
...base,
|
|
@@ -129,6 +154,8 @@ export async function resolveProjectConfig(cwd) {
|
|
|
129
154
|
registries,
|
|
130
155
|
registrationGraph,
|
|
131
156
|
policyRules,
|
|
157
|
+
baselines,
|
|
158
|
+
generatedArtifacts,
|
|
132
159
|
reusePrimitives,
|
|
133
160
|
},
|
|
134
161
|
planeDiagnostics: diagnostics,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shrkcrft/inspector",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.28",
|
|
4
4
|
"description": "SharkCraft inspector: project overview, doctor checks, AI-agent instructions.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "SharkCraft contributors",
|
|
@@ -42,22 +42,22 @@
|
|
|
42
42
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@shrkcrft/core": "^0.1.0-alpha.
|
|
46
|
-
"@shrkcrft/config": "^0.1.0-alpha.
|
|
47
|
-
"@shrkcrft/workspace": "^0.1.0-alpha.
|
|
48
|
-
"@shrkcrft/knowledge": "^0.1.0-alpha.
|
|
49
|
-
"@shrkcrft/rules": "^0.1.0-alpha.
|
|
50
|
-
"@shrkcrft/paths": "^0.1.0-alpha.
|
|
51
|
-
"@shrkcrft/templates": "^0.1.0-alpha.
|
|
52
|
-
"@shrkcrft/context": "^0.1.0-alpha.
|
|
53
|
-
"@shrkcrft/pipelines": "^0.1.0-alpha.
|
|
54
|
-
"@shrkcrft/packs": "^0.1.0-alpha.
|
|
55
|
-
"@shrkcrft/presets": "^0.1.0-alpha.
|
|
56
|
-
"@shrkcrft/boundaries": "^0.1.0-alpha.
|
|
57
|
-
"@shrkcrft/generator": "^0.1.0-alpha.
|
|
58
|
-
"@shrkcrft/importer": "^0.1.0-alpha.
|
|
59
|
-
"@shrkcrft/plugin-api": "^0.1.0-alpha.
|
|
60
|
-
"@shrkcrft/dashboard-api": "^0.1.0-alpha.
|
|
45
|
+
"@shrkcrft/core": "^0.1.0-alpha.28",
|
|
46
|
+
"@shrkcrft/config": "^0.1.0-alpha.28",
|
|
47
|
+
"@shrkcrft/workspace": "^0.1.0-alpha.28",
|
|
48
|
+
"@shrkcrft/knowledge": "^0.1.0-alpha.28",
|
|
49
|
+
"@shrkcrft/rules": "^0.1.0-alpha.28",
|
|
50
|
+
"@shrkcrft/paths": "^0.1.0-alpha.28",
|
|
51
|
+
"@shrkcrft/templates": "^0.1.0-alpha.28",
|
|
52
|
+
"@shrkcrft/context": "^0.1.0-alpha.28",
|
|
53
|
+
"@shrkcrft/pipelines": "^0.1.0-alpha.28",
|
|
54
|
+
"@shrkcrft/packs": "^0.1.0-alpha.28",
|
|
55
|
+
"@shrkcrft/presets": "^0.1.0-alpha.28",
|
|
56
|
+
"@shrkcrft/boundaries": "^0.1.0-alpha.28",
|
|
57
|
+
"@shrkcrft/generator": "^0.1.0-alpha.28",
|
|
58
|
+
"@shrkcrft/importer": "^0.1.0-alpha.28",
|
|
59
|
+
"@shrkcrft/plugin-api": "^0.1.0-alpha.28",
|
|
60
|
+
"@shrkcrft/dashboard-api": "^0.1.0-alpha.28",
|
|
61
61
|
"typescript": "^5.6.0"
|
|
62
62
|
},
|
|
63
63
|
"publishConfig": {
|