appsec-agent 2.4.5 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +1 -1
- package/conf/appsec_agent.yaml +9 -0
- package/dist/bin/agent-run.js +27 -0
- package/dist/bin/agent-run.js.map +1 -1
- package/dist/conf/appsec_agent.yaml +9 -0
- package/dist/src/agent_actions.d.ts +13 -0
- package/dist/src/agent_actions.d.ts.map +1 -1
- package/dist/src/agent_actions.js +86 -0
- package/dist/src/agent_actions.js.map +1 -1
- package/dist/src/agent_options.d.ts +19 -0
- package/dist/src/agent_options.d.ts.map +1 -1
- package/dist/src/agent_options.js +50 -0
- package/dist/src/agent_options.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/main.d.ts.map +1 -1
- package/dist/src/main.js +132 -3
- package/dist/src/main.js.map +1 -1
- package/dist/src/schemas/codebase_graph.d.ts +135 -0
- package/dist/src/schemas/codebase_graph.d.ts.map +1 -0
- package/dist/src/schemas/codebase_graph.js +169 -0
- package/dist/src/schemas/codebase_graph.js.map +1 -0
- package/dist/src/schemas/learned_guidance.d.ts +96 -0
- package/dist/src/schemas/learned_guidance.d.ts.map +1 -0
- package/dist/src/schemas/learned_guidance.js +286 -0
- package/dist/src/schemas/learned_guidance.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codebase-graph context input (v2.6.0 / parent-app plan §8.18 Phase 2) —
|
|
3
|
+
* per-changed-file structural-graph summary passed to `pr_reviewer` so the LLM
|
|
4
|
+
* can factor symbol-level callers/callees and downstream blast-radius into its
|
|
5
|
+
* severity + confidence calls.
|
|
6
|
+
*
|
|
7
|
+
* Distinct from `--import-graph-context` (file-level inbound import counts via
|
|
8
|
+
* SCIP). This context is *symbol-level* (cbm tree-sitter graph; 155 languages):
|
|
9
|
+
* - `callers` — qualified symbol names whose body invokes a symbol
|
|
10
|
+
* defined in the changed file.
|
|
11
|
+
* - `callees` — qualified symbol names invoked from a symbol defined
|
|
12
|
+
* in the changed file.
|
|
13
|
+
* - `blast_radius_files_count` — number of unique files reachable via
|
|
14
|
+
* outbound CALLS edges within the configured depth.
|
|
15
|
+
*
|
|
16
|
+
* The parent app's `composeCodebaseGraphContextPayload`
|
|
17
|
+
* (`<parent-app>/backend/src/services/codebaseGraph/`) does the cbm MCP queries
|
|
18
|
+
* (`search_graph` to find symbols defined in each changed file →
|
|
19
|
+
* `trace_path(direction=both, mode=calls, depth=2)` per symbol) and writes the
|
|
20
|
+
* JSON file. The agent here only parses + formats it for the prompt — no MCP
|
|
21
|
+
* query at agent runtime (Phase 3 is the live-MCP variant).
|
|
22
|
+
*
|
|
23
|
+
* Shape mirrors the v5.4.0 import-graph and v2.3.0 runtime-enrichment patterns
|
|
24
|
+
* exactly so that `prScanProcessor` can reuse the same fail-open + size-cap +
|
|
25
|
+
* coverage tagging conventions across all three structural-context families.
|
|
26
|
+
*
|
|
27
|
+
* **§8.5 PHI gate**: cbm sees only source-code text from CapsuleHealth-owned
|
|
28
|
+
* repos (no PHI). The schema accepts only structural-edge fields; any extras
|
|
29
|
+
* on per-file entries are silently dropped (mirrors runtime-enrichment's PHI
|
|
30
|
+
* minimization invariant defensively, even though cbm's input surface
|
|
31
|
+
* cannot contain PHI by construction).
|
|
32
|
+
*/
|
|
33
|
+
export interface CodebaseGraphFileEntry {
|
|
34
|
+
/** Repository-relative file path. Must be non-empty after trimming. */
|
|
35
|
+
file: string;
|
|
36
|
+
/**
|
|
37
|
+
* Optional list of qualified symbol names defined in this file that the PR
|
|
38
|
+
* actually changes. When present, the parent app scoped the
|
|
39
|
+
* callers/callees query to these symbols only (instead of every symbol
|
|
40
|
+
* defined in the file). Truncated at 20 to bound the prompt budget.
|
|
41
|
+
*/
|
|
42
|
+
symbols_changed?: string[];
|
|
43
|
+
/**
|
|
44
|
+
* Inbound callers — qualified symbol names whose body invokes a symbol
|
|
45
|
+
* defined in this file. Truncated at 20 (most-popular first per the
|
|
46
|
+
* parent app's ranking) so the most structurally-important callers
|
|
47
|
+
* survive the prompt-budget cap.
|
|
48
|
+
*/
|
|
49
|
+
callers?: string[];
|
|
50
|
+
/**
|
|
51
|
+
* Outbound callees — qualified symbol names invoked from any symbol
|
|
52
|
+
* defined in this file. Same truncation contract as `callers`.
|
|
53
|
+
*/
|
|
54
|
+
callees?: string[];
|
|
55
|
+
/**
|
|
56
|
+
* Number of unique files reachable from this file via outbound CALLS
|
|
57
|
+
* edges within the parent app's configured `trace_path` depth (default
|
|
58
|
+
* 2). The LLM uses this as a "blast radius" signal — high counts
|
|
59
|
+
* indicate the changed file sits structurally upstream of much of the
|
|
60
|
+
* codebase, so a regression here propagates broadly.
|
|
61
|
+
*
|
|
62
|
+
* Coerced to a non-negative integer (fractional values floored,
|
|
63
|
+
* negatives clamped to 0).
|
|
64
|
+
*/
|
|
65
|
+
blast_radius_files_count: number;
|
|
66
|
+
/**
|
|
67
|
+
* Per-file resolution outcome:
|
|
68
|
+
* - `ok` — symbols found in cbm graph; callers/callees populated
|
|
69
|
+
* from `trace_path` results.
|
|
70
|
+
* - `no_symbols` — file is in the changed set but cbm's `search_graph`
|
|
71
|
+
* returned no Function/Method nodes for it (data file,
|
|
72
|
+
* config, generated code, language not in cbm's 155).
|
|
73
|
+
* - `missing` — cbm artifact for the project's current head SHA was
|
|
74
|
+
* not found on the PVC; the parent app's load step
|
|
75
|
+
* short-circuited with an empty entry per file.
|
|
76
|
+
* - `partial` — at least one `trace_path` query failed (cbm
|
|
77
|
+
* transient error, depth limit, or query timeout); the
|
|
78
|
+
* callers/callees lists may be incomplete.
|
|
79
|
+
*/
|
|
80
|
+
graph_status?: 'ok' | 'no_symbols' | 'missing' | 'partial';
|
|
81
|
+
}
|
|
82
|
+
export interface CodebaseGraphContext {
|
|
83
|
+
/** Optional default-branch SHA the cbm artifact was indexed from. */
|
|
84
|
+
default_branch_sha?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Optional ISO-8601 timestamp recorded when the parent app composed
|
|
87
|
+
* this payload. Useful for forensic debugging if the soak shows
|
|
88
|
+
* unexpected behavior; not surfaced in the prompt.
|
|
89
|
+
*/
|
|
90
|
+
parsed_at?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Roll-up resolution status across all files in the request:
|
|
93
|
+
* - `full` — every changed file was found in the cbm graph and at
|
|
94
|
+
* least one symbol traced.
|
|
95
|
+
* - `partial` — some files traced cleanly, others were `no_symbols` or
|
|
96
|
+
* `partial`.
|
|
97
|
+
* - `none` — the cbm artifact was loaded but no changed file
|
|
98
|
+
* produced traceable symbols (highly unusual; surface
|
|
99
|
+
* to ops via `coverage` panel).
|
|
100
|
+
* - `empty` — the parent app could not load a cbm artifact for the
|
|
101
|
+
* current head SHA (`codebase_graph_heads` row missing
|
|
102
|
+
* or stale). Fail-open; the LLM ignores this block.
|
|
103
|
+
*/
|
|
104
|
+
coverage?: 'full' | 'partial' | 'none' | 'empty';
|
|
105
|
+
/**
|
|
106
|
+
* Per-file rows — already filtered by the parent app to the PR's
|
|
107
|
+
* changed-file set, so the LLM sees a compact "files touched by this
|
|
108
|
+
* PR with their structural-graph context" slice. Empty array means
|
|
109
|
+
* "graph configured but no overlap" — the formatter short-circuits
|
|
110
|
+
* to empty string in that case.
|
|
111
|
+
*/
|
|
112
|
+
files: CodebaseGraphFileEntry[];
|
|
113
|
+
/** Optional metadata block for forensic/debug correlation; not surfaced in prompt. */
|
|
114
|
+
metadata?: {
|
|
115
|
+
project_name?: string;
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Parse and validate a codebase-graph context JSON payload (throws on
|
|
120
|
+
* structural error). Caps mirror import-graph (500 files, 20 callers per
|
|
121
|
+
* file) so the prompt-budget worst case is symmetric across the two
|
|
122
|
+
* structural contexts.
|
|
123
|
+
*/
|
|
124
|
+
export declare function parseCodebaseGraphContext(data: unknown): CodebaseGraphContext;
|
|
125
|
+
/**
|
|
126
|
+
* Format the context for inclusion in a PR-reviewer user prompt. Compact by
|
|
127
|
+
* design — symbol lists are truncated and the table renders only the most
|
|
128
|
+
* structurally-significant signals so the block stays well under the
|
|
129
|
+
* import-graph + runtime-enrichment budget envelope.
|
|
130
|
+
*
|
|
131
|
+
* Files are rendered most-blast-radius first to anchor the LLM's attention
|
|
132
|
+
* on the structurally-upstream files when the prompt is truncated.
|
|
133
|
+
*/
|
|
134
|
+
export declare function formatCodebaseGraphContextForPrompt(ctx: CodebaseGraphContext): string;
|
|
135
|
+
//# sourceMappingURL=codebase_graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebase_graph.d.ts","sourceRoot":"","sources":["../../../src/schemas/codebase_graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;;;;;OASG;IACH,wBAAwB,EAAE,MAAM,CAAC;IACjC;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,IAAI,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC;CAC5D;AAED,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACjD;;;;;;OAMG;IACH,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,sFAAsF;IACtF,QAAQ,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACtC;AA+BD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG,oBAAoB,CA8D7E;AAED;;;;;;;;GAQG;AACH,wBAAgB,mCAAmC,CAAC,GAAG,EAAE,oBAAoB,GAAG,MAAM,CAkDrF"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Codebase-graph context input (v2.6.0 / parent-app plan §8.18 Phase 2) —
|
|
4
|
+
* per-changed-file structural-graph summary passed to `pr_reviewer` so the LLM
|
|
5
|
+
* can factor symbol-level callers/callees and downstream blast-radius into its
|
|
6
|
+
* severity + confidence calls.
|
|
7
|
+
*
|
|
8
|
+
* Distinct from `--import-graph-context` (file-level inbound import counts via
|
|
9
|
+
* SCIP). This context is *symbol-level* (cbm tree-sitter graph; 155 languages):
|
|
10
|
+
* - `callers` — qualified symbol names whose body invokes a symbol
|
|
11
|
+
* defined in the changed file.
|
|
12
|
+
* - `callees` — qualified symbol names invoked from a symbol defined
|
|
13
|
+
* in the changed file.
|
|
14
|
+
* - `blast_radius_files_count` — number of unique files reachable via
|
|
15
|
+
* outbound CALLS edges within the configured depth.
|
|
16
|
+
*
|
|
17
|
+
* The parent app's `composeCodebaseGraphContextPayload`
|
|
18
|
+
* (`<parent-app>/backend/src/services/codebaseGraph/`) does the cbm MCP queries
|
|
19
|
+
* (`search_graph` to find symbols defined in each changed file →
|
|
20
|
+
* `trace_path(direction=both, mode=calls, depth=2)` per symbol) and writes the
|
|
21
|
+
* JSON file. The agent here only parses + formats it for the prompt — no MCP
|
|
22
|
+
* query at agent runtime (Phase 3 is the live-MCP variant).
|
|
23
|
+
*
|
|
24
|
+
* Shape mirrors the v5.4.0 import-graph and v2.3.0 runtime-enrichment patterns
|
|
25
|
+
* exactly so that `prScanProcessor` can reuse the same fail-open + size-cap +
|
|
26
|
+
* coverage tagging conventions across all three structural-context families.
|
|
27
|
+
*
|
|
28
|
+
* **§8.5 PHI gate**: cbm sees only source-code text from CapsuleHealth-owned
|
|
29
|
+
* repos (no PHI). The schema accepts only structural-edge fields; any extras
|
|
30
|
+
* on per-file entries are silently dropped (mirrors runtime-enrichment's PHI
|
|
31
|
+
* minimization invariant defensively, even though cbm's input surface
|
|
32
|
+
* cannot contain PHI by construction).
|
|
33
|
+
*/
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.parseCodebaseGraphContext = parseCodebaseGraphContext;
|
|
36
|
+
exports.formatCodebaseGraphContextForPrompt = formatCodebaseGraphContextForPrompt;
|
|
37
|
+
const MAX_FILES = 500;
|
|
38
|
+
const MAX_CALLERS_PER_FILE = 20;
|
|
39
|
+
const MAX_CALLEES_PER_FILE = 20;
|
|
40
|
+
const MAX_SYMBOLS_PER_FILE = 20;
|
|
41
|
+
const VALID_GRAPH_STATUSES = new Set([
|
|
42
|
+
'ok',
|
|
43
|
+
'no_symbols',
|
|
44
|
+
'missing',
|
|
45
|
+
'partial',
|
|
46
|
+
]);
|
|
47
|
+
const VALID_COVERAGE_VALUES = new Set([
|
|
48
|
+
'full',
|
|
49
|
+
'partial',
|
|
50
|
+
'none',
|
|
51
|
+
'empty',
|
|
52
|
+
]);
|
|
53
|
+
const sanitizeStringArray = (input, cap) => {
|
|
54
|
+
if (!Array.isArray(input)) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const cleaned = input
|
|
58
|
+
.filter((c) => typeof c === 'string' && c.trim().length > 0)
|
|
59
|
+
.slice(0, cap);
|
|
60
|
+
return cleaned.length > 0 ? cleaned : undefined;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Parse and validate a codebase-graph context JSON payload (throws on
|
|
64
|
+
* structural error). Caps mirror import-graph (500 files, 20 callers per
|
|
65
|
+
* file) so the prompt-budget worst case is symmetric across the two
|
|
66
|
+
* structural contexts.
|
|
67
|
+
*/
|
|
68
|
+
function parseCodebaseGraphContext(data) {
|
|
69
|
+
if (!data || typeof data !== 'object') {
|
|
70
|
+
throw new Error('Codebase-graph context must be a JSON object');
|
|
71
|
+
}
|
|
72
|
+
const o = data;
|
|
73
|
+
if (!Array.isArray(o.files)) {
|
|
74
|
+
throw new Error('Codebase-graph context must include a "files" array');
|
|
75
|
+
}
|
|
76
|
+
if (o.files.length > MAX_FILES) {
|
|
77
|
+
throw new Error(`Codebase-graph context supports at most ${MAX_FILES} files per run`);
|
|
78
|
+
}
|
|
79
|
+
const files = [];
|
|
80
|
+
for (const item of o.files) {
|
|
81
|
+
if (!item || typeof item !== 'object') {
|
|
82
|
+
throw new Error('Each codebase-graph file entry must be an object');
|
|
83
|
+
}
|
|
84
|
+
const f = item;
|
|
85
|
+
if (typeof f.file !== 'string' || !f.file.trim()) {
|
|
86
|
+
throw new Error('Each codebase-graph file entry must have a non-empty string "file"');
|
|
87
|
+
}
|
|
88
|
+
if (typeof f.blast_radius_files_count !== 'number' ||
|
|
89
|
+
!Number.isFinite(f.blast_radius_files_count)) {
|
|
90
|
+
throw new Error('Each codebase-graph file entry must have a numeric "blast_radius_files_count"');
|
|
91
|
+
}
|
|
92
|
+
const graphStatus = typeof f.graph_status === 'string' &&
|
|
93
|
+
VALID_GRAPH_STATUSES.has(f.graph_status)
|
|
94
|
+
? f.graph_status
|
|
95
|
+
: undefined;
|
|
96
|
+
files.push({
|
|
97
|
+
file: String(f.file),
|
|
98
|
+
symbols_changed: sanitizeStringArray(f.symbols_changed, MAX_SYMBOLS_PER_FILE),
|
|
99
|
+
callers: sanitizeStringArray(f.callers, MAX_CALLERS_PER_FILE),
|
|
100
|
+
callees: sanitizeStringArray(f.callees, MAX_CALLEES_PER_FILE),
|
|
101
|
+
blast_radius_files_count: Math.max(0, Math.trunc(f.blast_radius_files_count)),
|
|
102
|
+
graph_status: graphStatus,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const coverage = typeof o.coverage === 'string' &&
|
|
106
|
+
VALID_COVERAGE_VALUES.has(o.coverage)
|
|
107
|
+
? o.coverage
|
|
108
|
+
: undefined;
|
|
109
|
+
return {
|
|
110
|
+
default_branch_sha: typeof o.default_branch_sha === 'string' ? o.default_branch_sha : undefined,
|
|
111
|
+
parsed_at: typeof o.parsed_at === 'string' ? o.parsed_at : undefined,
|
|
112
|
+
coverage,
|
|
113
|
+
files,
|
|
114
|
+
metadata: o.metadata && typeof o.metadata === 'object'
|
|
115
|
+
? {
|
|
116
|
+
project_name: typeof o.metadata.project_name === 'string'
|
|
117
|
+
? o.metadata.project_name
|
|
118
|
+
: undefined,
|
|
119
|
+
}
|
|
120
|
+
: undefined,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Format the context for inclusion in a PR-reviewer user prompt. Compact by
|
|
125
|
+
* design — symbol lists are truncated and the table renders only the most
|
|
126
|
+
* structurally-significant signals so the block stays well under the
|
|
127
|
+
* import-graph + runtime-enrichment budget envelope.
|
|
128
|
+
*
|
|
129
|
+
* Files are rendered most-blast-radius first to anchor the LLM's attention
|
|
130
|
+
* on the structurally-upstream files when the prompt is truncated.
|
|
131
|
+
*/
|
|
132
|
+
function formatCodebaseGraphContextForPrompt(ctx) {
|
|
133
|
+
if (ctx.files.length === 0) {
|
|
134
|
+
return '';
|
|
135
|
+
}
|
|
136
|
+
const sorted = [...ctx.files].sort((a, b) => b.blast_radius_files_count - a.blast_radius_files_count);
|
|
137
|
+
const lines = [];
|
|
138
|
+
lines.push('### Codebase-graph context (symbol-level callers/callees, plan §8.18 Phase 2)');
|
|
139
|
+
lines.push('For each changed file below, the parent app queried the codebase-memory-mcp graph for symbols defined in the file and traced their inbound (callers) and outbound (callees) CALLS edges. Use this as a structural-impact signal: a high `blast radius` means a regression in the file propagates to many downstream files; a non-empty `callers` list means the changed code is reached by other code paths and is more likely to fire under realistic traffic.');
|
|
140
|
+
lines.push('Treat this as advisory — when callers ≥ 1 and blast radius ≥ 5, lean toward keeping medium/high-severity findings on the file even if the diff alone looks low-risk. When `graph_status` is `no_symbols` (data file, generated code, unsupported language), structural reach is not measurable from this signal — fall back to your default judgment.');
|
|
141
|
+
if (ctx.default_branch_sha) {
|
|
142
|
+
lines.push(`Graph built from default-branch SHA \`${ctx.default_branch_sha.slice(0, 12)}\`.`);
|
|
143
|
+
}
|
|
144
|
+
if (ctx.coverage && ctx.coverage !== 'full') {
|
|
145
|
+
lines.push(`_Coverage: **${ctx.coverage}** — entries with \`graph_status=missing\` or \`partial\` will **not** be downranked (fail-open)._`);
|
|
146
|
+
}
|
|
147
|
+
lines.push('');
|
|
148
|
+
lines.push('| File | Callers | Callees | Blast radius | Status |');
|
|
149
|
+
lines.push('|---|---|---|---:|:---:|');
|
|
150
|
+
for (const f of sorted) {
|
|
151
|
+
const status = f.graph_status ?? 'ok';
|
|
152
|
+
const callers = f.callers && f.callers.length > 0
|
|
153
|
+
? f.callers
|
|
154
|
+
.slice(0, 3)
|
|
155
|
+
.map((c) => `\`${c}\``)
|
|
156
|
+
.join(', ') + (f.callers.length > 3 ? ` (+${f.callers.length - 3})` : '')
|
|
157
|
+
: '—';
|
|
158
|
+
const callees = f.callees && f.callees.length > 0
|
|
159
|
+
? f.callees
|
|
160
|
+
.slice(0, 3)
|
|
161
|
+
.map((c) => `\`${c}\``)
|
|
162
|
+
.join(', ') + (f.callees.length > 3 ? ` (+${f.callees.length - 3})` : '')
|
|
163
|
+
: '—';
|
|
164
|
+
lines.push(`| \`${f.file}\` | ${callers} | ${callees} | ${f.blast_radius_files_count} | ${status} |`);
|
|
165
|
+
}
|
|
166
|
+
lines.push('');
|
|
167
|
+
return lines.join('\n');
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=codebase_graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebase_graph.js","sourceRoot":"","sources":["../../../src/schemas/codebase_graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learned-guidance synthesizer schemas (v2.5.0 / parent-app plan §3.8 — CLLG).
|
|
3
|
+
*
|
|
4
|
+
* The parent app collects three signal streams (dismissal validations,
|
|
5
|
+
* `addressed` PR outcomes, 👍 feedback) and buckets them by CWE. For each
|
|
6
|
+
* eligible bucket it asks this role to emit ONE short policy bullet that
|
|
7
|
+
* captures the class-level pattern (e.g. *"Trust the CSRF middleware in
|
|
8
|
+
* `auth/csrf.ts`; do not flag PR routes that go through it."*).
|
|
9
|
+
*
|
|
10
|
+
* Input file shape (passed via `--inputs <file>`; matches the JSON the
|
|
11
|
+
* parent app's `runSynthesizerAgent` writes in `learnedGuidanceSynthesizer.ts`):
|
|
12
|
+
*
|
|
13
|
+
* {
|
|
14
|
+
* "buckets": [
|
|
15
|
+
* {
|
|
16
|
+
* "cwe": "CWE-79",
|
|
17
|
+
* "signal_count": 12,
|
|
18
|
+
* "example_dismissal_reasons": [
|
|
19
|
+
* "duplicate of issue #4321 - already mitigated by helmet middleware",
|
|
20
|
+
* "auto-escaped by React JSX",
|
|
21
|
+
* ...
|
|
22
|
+
* ]
|
|
23
|
+
* },
|
|
24
|
+
* ...
|
|
25
|
+
* ]
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* Output shape on stdout (structured JSON, written to `-o <file>` per the
|
|
29
|
+
* parent app's spawn contract; backend rejects anything off-schema with
|
|
30
|
+
* `outcome=validation_error`):
|
|
31
|
+
*
|
|
32
|
+
* {
|
|
33
|
+
* "bullets": [
|
|
34
|
+
* {
|
|
35
|
+
* "cwe": "CWE-79",
|
|
36
|
+
* "bullet": "≤300 chars positive-form rule the pr_reviewer can apply",
|
|
37
|
+
* "confidence": 0.85
|
|
38
|
+
* },
|
|
39
|
+
* ...
|
|
40
|
+
* ]
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* The role is a pure transform: no Read/Grep tools, no source-tree
|
|
44
|
+
* access. Output is constrained by `LEARNED_GUIDANCE_OUTPUT_SCHEMA` so a
|
|
45
|
+
* malformed bullet list never reaches the parent app's prompt budget.
|
|
46
|
+
*/
|
|
47
|
+
export interface LearnedGuidanceBucketInput {
|
|
48
|
+
cwe: string;
|
|
49
|
+
signal_count: number;
|
|
50
|
+
example_dismissal_reasons: string[];
|
|
51
|
+
}
|
|
52
|
+
export interface LearnedGuidanceInputs {
|
|
53
|
+
buckets: LearnedGuidanceBucketInput[];
|
|
54
|
+
}
|
|
55
|
+
/** Output character cap. Stays in lockstep with the parent app's `MAX_BULLET_LEN = 300`. */
|
|
56
|
+
export declare const MAX_BULLET_LEN = 300;
|
|
57
|
+
export interface LearnedGuidanceBullet {
|
|
58
|
+
cwe: string;
|
|
59
|
+
bullet: string;
|
|
60
|
+
confidence: number;
|
|
61
|
+
}
|
|
62
|
+
export interface LearnedGuidanceOutput {
|
|
63
|
+
bullets: LearnedGuidanceBullet[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Parse and validate a `LearnedGuidanceInputs` object loaded from the
|
|
67
|
+
* `--inputs` JSON file. Throws on any structural deviation; the CLI
|
|
68
|
+
* wrapper in `main.ts` exits non-zero so the parent app sees the error
|
|
69
|
+
* via stderr (and stays fail-closed: zero bullets persisted).
|
|
70
|
+
*/
|
|
71
|
+
export declare function parseLearnedGuidanceInputs(data: unknown): LearnedGuidanceInputs;
|
|
72
|
+
/**
|
|
73
|
+
* Convenience loader matching the pattern used by `loadRetestContext`
|
|
74
|
+
* etc. — read JSON from disk, parse, validate, return.
|
|
75
|
+
*
|
|
76
|
+
* Caller is responsible for path validation (we expect `main.ts` to run
|
|
77
|
+
* the file path through `validateInputFilePath` before calling this so
|
|
78
|
+
* traversal attempts never reach the loader).
|
|
79
|
+
*/
|
|
80
|
+
export declare function loadLearnedGuidanceInputs(absolutePath: string): LearnedGuidanceInputs;
|
|
81
|
+
/**
|
|
82
|
+
* Build the user-facing prompt for the synthesizer role. The prompt:
|
|
83
|
+
* 1. States the task and the success bar (positive-form rule, not generic).
|
|
84
|
+
* 2. Lists each bucket with its CWE, signal count, and a few example reasons.
|
|
85
|
+
* 3. Reminds the model of the schema, the per-bullet length cap, and the
|
|
86
|
+
* confidence scale.
|
|
87
|
+
*
|
|
88
|
+
* The system prompt (set in `agent_options.ts`) plus the JSON schema
|
|
89
|
+
* enforcement (set on `Options.outputFormat`) enforce the structural
|
|
90
|
+
* contract; this prompt focuses on the *content* contract.
|
|
91
|
+
*/
|
|
92
|
+
export declare function buildLearnedGuidanceUserPrompt(inputs: LearnedGuidanceInputs): string;
|
|
93
|
+
export declare const LEARNED_GUIDANCE_OUTPUT_SCHEMA: Record<string, unknown>;
|
|
94
|
+
/** Convenience empty-output shell for tests / agent-side fallback. */
|
|
95
|
+
export declare function emptyLearnedGuidanceOutput(): LearnedGuidanceOutput;
|
|
96
|
+
//# sourceMappingURL=learned_guidance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learned_guidance.d.ts","sourceRoot":"","sources":["../../../src/schemas/learned_guidance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAQH,MAAM,WAAW,0BAA0B;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,yBAAyB,EAAE,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,0BAA0B,EAAE,CAAC;CACvC;AAaD,4FAA4F;AAC5F,eAAO,MAAM,cAAc,MAAM,CAAC;AAMlC,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,qBAAqB,EAAE,CAAC;CAClC;AAMD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,qBAAqB,CA2D/E;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG,qBAAqB,CAYrF;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAmDpF;AAMD,eAAO,MAAM,8BAA8B,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAoClE,CAAC;AAEF,sEAAsE;AACtE,wBAAgB,0BAA0B,IAAI,qBAAqB,CAElE"}
|