codecartographer-pi 0.24.0 → 0.25.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/.codecarto/broadside/SKILL.md +31 -9
- package/.codecarto/workflow/scaffold-version.yaml +1 -1
- package/README.md +4 -3
- package/agent-skill/codecartographer/references/broadside.md +5 -1
- package/dist/core/amendment.d.ts +6 -3
- package/dist/core/amendment.js +21 -10
- package/dist/core/broadside.d.ts +87 -16
- package/dist/core/broadside.js +230 -30
- package/dist/core/status.d.ts +14 -0
- package/dist/core/status.js +104 -13
- package/dist/extensions/codecarto/agent-state.d.ts +7 -1
- package/dist/extensions/codecarto/agent-state.js +9 -1
- package/dist/extensions/codecarto/auto-runner.d.ts +7 -0
- package/dist/extensions/codecarto/auto-runner.js +16 -2
- package/dist/extensions/codecarto/broadside-flags.d.ts +3 -1
- package/dist/extensions/codecarto/broadside-flags.js +13 -0
- package/dist/extensions/codecarto/index.js +38 -8
- package/dist/mcp-server/server.d.ts +1 -0
- package/dist/mcp-server/server.js +18 -1
- package/package.json +1 -1
|
@@ -35,6 +35,10 @@ not replace any phase; it tells phases where to look.
|
|
|
35
35
|
it describes), **discarded** (the claim is wrong about the code, with the
|
|
36
36
|
guard or line that shows it), or **unclear**. Start from the confirmed
|
|
37
37
|
ones; treat a discarded one as answered unless the reasoning is thin.
|
|
38
|
+
Then make sure the work order was built from it: `status` shows
|
|
39
|
+
`triage: completed (built from N verdicts)`; if it says `(no verdicts)`,
|
|
40
|
+
run `collect --regenerate` (`regenerate_post_passes: true`) before
|
|
41
|
+
reading `triage.md`.
|
|
38
42
|
Measured on this repository, the top twelve findings by severity were two
|
|
39
43
|
real defects and ten that a look at the guard, the caller, or the tsconfig
|
|
40
44
|
dismissed — the pass agreed with a reviewer on all twelve for about a cent
|
|
@@ -50,7 +54,11 @@ not replace any phase; it tells phases where to look.
|
|
|
50
54
|
- `architecture-*.json` → the architecture phase's seed of prior knowledge
|
|
51
55
|
- `api-*.json` → endpoints and data types (contracts/protocols phases)
|
|
52
56
|
- `security-*.json` → auth, trust boundaries (defect-scan-semantic pass 5)
|
|
53
|
-
- `defect-*.json` → mechanical defect leads (defect-scan-mechanical)
|
|
57
|
+
- `defect-*.json` → mechanical defect leads (defect-scan-mechanical). The
|
|
58
|
+
scan is asked to name the input, call site, or sequence that reaches
|
|
59
|
+
each failure, and to file a cast, assertion, or style observation that
|
|
60
|
+
every caller satisfies at severity low under the pattern `type-hygiene`
|
|
61
|
+
— read those as notes, not defects.
|
|
54
62
|
- `conventions-*.json` → naming/idiom candidates for CONVENTIONS.md
|
|
55
63
|
- `porting-*.json` → platform coupling (porting phase)
|
|
56
64
|
4. `run-meta.json` records scope: which lenses ran, at what cost, with what
|
|
@@ -81,6 +89,7 @@ Broad-Side is an executable-surface feature. On the Pi extension:
|
|
|
81
89
|
/codecarto-broadside status # show recorded runs
|
|
82
90
|
/codecarto-broadside models # compare batch models
|
|
83
91
|
/codecarto-broadside verify --top=10 # read the top findings against the source
|
|
92
|
+
/codecarto-broadside collect --regenerate # rebuild synthesis and triage from the verdicts
|
|
84
93
|
```
|
|
85
94
|
|
|
86
95
|
On the MCP server:
|
|
@@ -91,6 +100,7 @@ codecarto_broadside {cwd, action: "collect"} # poll, save, synt
|
|
|
91
100
|
codecarto_broadside {cwd, action: "status"} # show recorded runs
|
|
92
101
|
codecarto_broadside {cwd, action: "models"} # compare batch models
|
|
93
102
|
codecarto_broadside {cwd, action: "verify", top: 10} # read the top findings against the source
|
|
103
|
+
codecarto_broadside {cwd, action: "collect", regenerate_post_passes: true} # rebuild synthesis and triage from the verdicts
|
|
94
104
|
```
|
|
95
105
|
|
|
96
106
|
The `models` action lists every `:batch` variant on OpenRouter — pricing per
|
|
@@ -108,14 +118,16 @@ every source file; the **security** and **API** lenses target where the
|
|
|
108
118
|
trust boundary usually lives — `server/**`, `**/auth*`, `**/middleware/**`,
|
|
109
119
|
`SECURITY.md` (security) and `server/**`, `api/**`, `src/server/**`,
|
|
110
120
|
`src/api/**`, `**/*routes*`, `**/*router*`, `**/*handler*`, `**/*endpoint*`
|
|
111
|
-
(API). A repository whose server is `src/server.js` matches none of those,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
(API). A repository whose server is `src/server.js` matches none of those,
|
|
122
|
+
and one whose only match is `SECURITY.md` has given the lens a policy to read
|
|
123
|
+
and no code to check it against; so when the targeted patterns find **no
|
|
124
|
+
source file** those two lenses **fall back to every source file**, on top of
|
|
125
|
+
whatever did match — priced as such, chunked at the lens's slice size rather
|
|
126
|
+
than truncated, and said so on the lens line of the estimate, the submit
|
|
127
|
+
report, `status`, and the prompt the model receives. A lens whose targeted
|
|
128
|
+
patterns and fallback both find nothing (only test files, say) is skipped
|
|
129
|
+
with a line naming both. `max_cost` is the guard against a fallback scan on
|
|
130
|
+
a large repository being more than you meant to spend.
|
|
119
131
|
|
|
120
132
|
Collect runs two cross-lens post-passes by default: **synthesis** (the
|
|
121
133
|
executive report) and **triage** (the prioritized work order). Pass
|
|
@@ -133,6 +145,16 @@ cap here, since a sync call's cost is known only when it returns: the pass
|
|
|
133
145
|
stops before the next finding once the calls so far have reached it and
|
|
134
146
|
reports `partial`. About a cent a finding on the default model.
|
|
135
147
|
|
|
148
|
+
The post-passes read the verdicts when they exist: a synthesis or triage
|
|
149
|
+
built after a `verify` ranks the confirmed findings first, drops the
|
|
150
|
+
discarded ones, lists the not-a-defect ones apart in `omitted`, and says in
|
|
151
|
+
its summary how many verdicts it was built from; `status` and the collect
|
|
152
|
+
report show `(built from N verdicts)` or `(no verdicts)` on each pass. A run
|
|
153
|
+
collected before it was verified has a work order built from batch
|
|
154
|
+
severities alone — `collect --regenerate` (`regenerate_post_passes: true`)
|
|
155
|
+
resets the settled passes and runs them again with the verdicts, for another
|
|
156
|
+
post-pass pair's cost; a pass still in flight is left to finish.
|
|
157
|
+
|
|
136
158
|
Two caveats apply to any model you pick. The `models` action lists every id
|
|
137
159
|
OpenRouter advertises a `:batch` variant for, and many of those variants do not
|
|
138
160
|
exist — submitting one returns `does not have a :batch endpoint`, with nothing in
|
package/README.md
CHANGED
|
@@ -383,7 +383,7 @@ Each workflow tool accepts an absolute `cwd` for the target repository. `codecar
|
|
|
383
383
|
|
|
384
384
|
## Broad-Side (batch reconnaissance)
|
|
385
385
|
|
|
386
|
-
Broad-Side is the cheap sweep you run *before* the expensive interactive run. It fires six analysis lenses — architecture, API surface, security, mechanical defect scan, convention extraction, porting — at a repository as single-turn prompts over the [OpenRouter Batch API](https://openrouter.ai/docs), then cross-references them into one executive report (`synthesis.md`) and a prioritized P0–P3 work order (`triage.md`). The security and API lenses target the paths where a trust boundary usually lives (`server/`, `auth*`, `middleware/`, routers and handlers) and fall back to every source file when a repository has
|
|
386
|
+
Broad-Side is the cheap sweep you run *before* the expensive interactive run. It fires six analysis lenses — architecture, API surface, security, mechanical defect scan, convention extraction, porting — at a repository as single-turn prompts over the [OpenRouter Batch API](https://openrouter.ai/docs), then cross-references them into one executive report (`synthesis.md`) and a prioritized P0–P3 work order (`triage.md`). The security and API lenses target the paths where a trust boundary usually lives (`server/`, `auth*`, `middleware/`, routers and handlers) and fall back to every source file when a repository has no code under them — priced as such, and said so on the estimate — so a service whose server is `src/server.js`, or one whose only match is its `SECURITY.md`, still gets its security review.
|
|
387
387
|
|
|
388
388
|
**Broad-Side findings are unverified scouting leads, not evidence.** Each lens is one shot: no cross-file traversal, no runtime verification, no builds, no tests. Every finding is a `file:line` pointer that the interactive pipeline — or you — must confirm before it is a fact. That division of labor is the point: a sub-dollar unattended sweep that tells the expensive run where to look. Nothing downstream may cite a Broad-Side report as a source.
|
|
389
389
|
|
|
@@ -395,15 +395,16 @@ codecarto_broadside {cwd, action: "submit", lenses: [...]} # fire the batches
|
|
|
395
395
|
codecarto_broadside {cwd, action: "status"} # what is in flight
|
|
396
396
|
codecarto_broadside {cwd, action: "collect"} # poll, save, synthesize, triage
|
|
397
397
|
codecarto_broadside {cwd, action: "verify", top: 10} # read the top findings against the source
|
|
398
|
+
codecarto_broadside {cwd, action: "collect", regenerate_post_passes: true} # rebuild the report and work order from the verdicts
|
|
398
399
|
```
|
|
399
400
|
|
|
400
|
-
A third action, `verify`, reads the top defect and security findings of a collected run against the real source — one sync-priced call each with read-only tools (`read_file`, `grep`, `list_dir`) confined to the repository — and writes `verified.md` with a verdict per finding: **confirmed** (a reachable failure, with the trigger), **not-a-defect**, **discarded**, or **unclear**. Measured on this repository, the top twelve findings by severity were two real defects and ten claims a look at the guard or the caller dismissed; the pass agreed with a reviewer on all twelve for a cent a finding. Read `verified.md` before `triage.md
|
|
401
|
+
A third action, `verify`, reads the top defect and security findings of a collected run against the real source — one sync-priced call each with read-only tools (`read_file`, `grep`, `list_dir`) confined to the repository — and writes `verified.md` with a verdict per finding: **confirmed** (a reachable failure, with the trigger), **not-a-defect**, **discarded**, or **unclear**. Measured on this repository, the top twelve findings by severity were two real defects and ten claims a look at the guard or the caller dismissed; the pass agreed with a reviewer on all twelve for a cent a finding. Read `verified.md` before `triage.md` — and have `triage.md` built from it: the synthesis and triage passes rank on the verdicts when they exist (confirmed first, discarded dropped, not-a-defect listed apart), and `collect` with `regenerate_post_passes: true` (`--regenerate` on Pi) rebuilds both for a run that was collected before it was verified.
|
|
401
402
|
|
|
402
403
|
Submit and collect are separate because batch jobs routinely take tens of minutes; collect is resumable and picks up whatever is still in flight (`wait_seconds: 0`, the default, polls once and returns), and two collects on one run — a retried tool call, a second session — never pay for the synthesis, triage, or truncation retry twice: each is claimed in the run's state before it is submitted, and a collect whose client has gone away stops polling and submits nothing further. Submit prices the run from the collected file sizes against the model's live per-token pricing (cached 24h) and refuses when the estimate exceeds `max_cost` — $1.00 unless the config or the call sets another value, `0` for no limit — unless `force: true` is passed — a pre-flight estimate, not a runtime stop. Actual spend lands in each run's `run-meta.json`.
|
|
403
404
|
|
|
404
405
|
Repository defaults live in `.codecarto/broadside/config.yaml` (`model`, `api_key`, `default_lenses`, `max_cost`, `pricing` overrides, `lens_models`, `incremental`, `retry_truncated`, `include_synthesis`, `include_triage`, `wait_seconds`); an explicit tool parameter always wins. `lens_models` routes individual lenses to their own batch model — a stronger model changes security and defect findings far more than it changes an architecture map — and each override is priced, capability-checked, and clamped exactly like the default, with the estimate broken out per lens so a mixed-model run cannot be approved without seeing which lens costs what. CodeCartographer ships no stronger default: which model earns its price depends on your repository and budget, so compare candidates with the `models` action and choose — for one run with the `model` and `lens_models` parameters (Pi: `--model=ID`, `--lens-model=LENS:ID`), or for the repository in `config.yaml`. The `models` listing is advisory: OpenRouter's catalog returns a `:batch` id for some models its Batch API then refuses (`does not have a :batch endpoint`), at no cost, and nothing in the catalog tells them apart — so the listing tags the ids this repository's own submits have seen accepted or refused, and a refused lens says why in the submit report. `codecarto_skill {cwd, name: "broadside"}` returns the reading guide for a completed run, and unlike post-pipeline skills it is not gated on a finished pipeline.
|
|
405
406
|
|
|
406
|
-
On the Pi extension the same run is `/codecarto-broadside [submit|collect|status|models|verify] [lenses…] [--model=ID] [--lens-model=LENS:ID] [--top=N]`, with tab-completion for actions, lens names, and flags and live per-lens progress while batches poll. The two surfaces differ in one deliberate place: MCP cannot ask a human, so it refuses a run over `max_cost` until you pass `force`; Pi shows the per-lens breakdown and asks, and your approval *is* the force flag. Neither surface takes an API key as a command argument — a key typed into a slash command lands in the session transcript.
|
|
407
|
+
On the Pi extension the same run is `/codecarto-broadside [submit|collect|status|models|verify] [lenses…] [--model=ID] [--lens-model=LENS:ID] [--top=N] [--regenerate]`, with tab-completion for actions, lens names, and flags and live per-lens progress while batches poll. The two surfaces differ in one deliberate place: MCP cannot ask a human, so it refuses a run over `max_cost` until you pass `force`; Pi shows the per-lens breakdown and asks, and your approval *is* the force flag. Neither surface takes an API key as a command argument — a key typed into a slash command lands in the session transcript.
|
|
407
408
|
|
|
408
409
|
Broad-Side needs runtime code, so firing a run is an executable-surface feature: Pi and MCP have it, the pure drop-in template does not (it carries only the reading guide).
|
|
409
410
|
|
|
@@ -99,7 +99,11 @@ Results land in `.codecarto/broadside/<run>/`. If `verified.md` is there, read
|
|
|
99
99
|
it before anything else: `action: "verify"` has read the top defect and
|
|
100
100
|
security findings against the source with read-only tools and given each a
|
|
101
101
|
verdict (confirmed with its trigger, not-a-defect, discarded with the guard
|
|
102
|
-
that shows it, unclear).
|
|
102
|
+
that shows it, unclear). The post-passes rank on those verdicts when they
|
|
103
|
+
exist; a run collected before it was verified has a work order built from
|
|
104
|
+
batch severities alone (`status` says `(no verdicts)`), and
|
|
105
|
+
`action: "collect", regenerate_post_passes: true` rebuilds both passes from
|
|
106
|
+
the verdicts for another post-pass pair's cost. Then, in this order:
|
|
103
107
|
|
|
104
108
|
1. `synthesis.md` — executive summary, severity counts, top cross-lens
|
|
105
109
|
findings, per-module risk.
|
package/dist/core/amendment.d.ts
CHANGED
|
@@ -39,8 +39,11 @@ export declare function listAmendmentNames(workspaceDir: string): Promise<string
|
|
|
39
39
|
export declare function loadAmendmentFile(name: string, workspaceDir: string): Promise<Amendment>;
|
|
40
40
|
/**
|
|
41
41
|
* Apply one amendment to canonical state under the completion lock. Refuses
|
|
42
|
-
* while the pipeline is incomplete
|
|
43
|
-
*
|
|
44
|
-
*
|
|
42
|
+
* while the pipeline is incomplete, judged on the state read under the lock:
|
|
43
|
+
* the check used to run on a read taken before the lock, so a status change
|
|
44
|
+
* that landed in between — a pipeline switch, a re-init, a rolled-back
|
|
45
|
+
* completion — was amended over as if the pipeline were still complete
|
|
46
|
+
* (Broad-Side verify, 2026-09-13 run). Idempotent: ids that no longer match
|
|
47
|
+
* anything are reported, not fatal.
|
|
45
48
|
*/
|
|
46
49
|
export declare function applyAmendment(cwd: string, name: string): Promise<AmendmentResult>;
|
package/dist/core/amendment.js
CHANGED
|
@@ -91,17 +91,12 @@ function renderAmendmentCloseout(amendment, applied, timestamp) {
|
|
|
91
91
|
return lines.join("\n");
|
|
92
92
|
}
|
|
93
93
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* Idempotent: ids that no longer match anything are reported, not fatal.
|
|
94
|
+
* The refusal an amendment gets while the pipeline is incomplete —
|
|
95
|
+
* mid-pipeline resolutions belong in the phase handoff, and allowing both
|
|
96
|
+
* channels at once would race them.
|
|
98
97
|
*/
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
if (!initialState)
|
|
102
|
-
throw new Error("CodeCartographer workspace not found. Run /codecarto-init first.");
|
|
103
|
-
const amendment = await loadAmendmentFile(name, initialState.workspaceDir);
|
|
104
|
-
const outcome = resolvePipelineOutcome(initialState);
|
|
98
|
+
function refuseUnlessComplete(state) {
|
|
99
|
+
const outcome = resolvePipelineOutcome(state);
|
|
105
100
|
if (outcome.kind === "eligible") {
|
|
106
101
|
throw new Error(`Cannot amend: the pipeline is not complete (next phase: ${outcome.phase.id}). `
|
|
107
102
|
+ `Resolve open questions and routed items through that phase's handoff (open_question_closures / carry_forward_closures) instead.`);
|
|
@@ -111,10 +106,26 @@ export async function applyAmendment(cwd, name) {
|
|
|
111
106
|
// finish is not there yet (#228).
|
|
112
107
|
throw new Error(`Cannot amend: the pipeline is not complete. ${describeStuckPipeline(outcome.blocked)}`);
|
|
113
108
|
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Apply one amendment to canonical state under the completion lock. Refuses
|
|
112
|
+
* while the pipeline is incomplete, judged on the state read under the lock:
|
|
113
|
+
* the check used to run on a read taken before the lock, so a status change
|
|
114
|
+
* that landed in between — a pipeline switch, a re-init, a rolled-back
|
|
115
|
+
* completion — was amended over as if the pipeline were still complete
|
|
116
|
+
* (Broad-Side verify, 2026-09-13 run). Idempotent: ids that no longer match
|
|
117
|
+
* anything are reported, not fatal.
|
|
118
|
+
*/
|
|
119
|
+
export async function applyAmendment(cwd, name) {
|
|
120
|
+
const initialState = await getWorkspaceState(cwd);
|
|
121
|
+
if (!initialState)
|
|
122
|
+
throw new Error("CodeCartographer workspace not found. Run /codecarto-init first.");
|
|
123
|
+
const amendment = await loadAmendmentFile(name, initialState.workspaceDir);
|
|
114
124
|
const timestamp = new Date().toISOString();
|
|
115
125
|
const applied = { openQuestionsClosed: [], postPipelineClosed: [], unknownIds: [] };
|
|
116
126
|
let closeoutNotice = "";
|
|
117
127
|
const updatedState = await updateStatusAtomically(cwd, async (lockedState) => {
|
|
128
|
+
refuseUnlessComplete(lockedState);
|
|
118
129
|
const nextStatus = normalizeStatus(lockedState.status, lockedState.pipeline, lockedState.status.pipeline, lockedState.cwd);
|
|
119
130
|
for (const closureId of amendment.open_question_closures) {
|
|
120
131
|
if (!closureId)
|
package/dist/core/broadside.d.ts
CHANGED
|
@@ -226,6 +226,12 @@ export type BroadsideSynthesisEntry = {
|
|
|
226
226
|
cost?: number;
|
|
227
227
|
/** Why the pass was retired, when the batch reported one. */
|
|
228
228
|
error?: string;
|
|
229
|
+
/**
|
|
230
|
+
* How many verification verdicts the pass was built from (#338): the
|
|
231
|
+
* `verified.json` a `verify` pass wrote before this pass was submitted.
|
|
232
|
+
* Absent when the pass was built from the lens findings alone.
|
|
233
|
+
*/
|
|
234
|
+
verdicts?: number;
|
|
229
235
|
};
|
|
230
236
|
/** One triage item — a scouting lead turned into a work-order entry. */
|
|
231
237
|
export type TriageItem = {
|
|
@@ -238,12 +244,8 @@ export type TriageItem = {
|
|
|
238
244
|
effort_estimate: string;
|
|
239
245
|
rationale: string;
|
|
240
246
|
};
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
status: "pending" | "submitted" | "completed" | "failed";
|
|
244
|
-
cost?: number;
|
|
245
|
-
error?: string;
|
|
246
|
-
};
|
|
247
|
+
/** The triage post-pass entry: the same shape as synthesis's. */
|
|
248
|
+
export type BroadsideTriageEntry = BroadsideSynthesisEntry;
|
|
247
249
|
/** Recorded on the run once a verification pass has run (#143); see core/broadside-verify.ts. */
|
|
248
250
|
export type BroadsideVerifyEntry = {
|
|
249
251
|
/** `completed`: every selected finding got a verdict; `partial`: the cost cap or an abort stopped it early. */
|
|
@@ -264,6 +266,8 @@ export type BroadsideRetryEntry = {
|
|
|
264
266
|
}>;
|
|
265
267
|
/** When the owning collect claimed the pass (#322). */
|
|
266
268
|
claimedAt: string;
|
|
269
|
+
/** What the retry batches cost, once polled to completion. */
|
|
270
|
+
cost?: number;
|
|
267
271
|
};
|
|
268
272
|
/**
|
|
269
273
|
* The parts of a run that cost money to submit and that exactly one collect
|
|
@@ -288,6 +292,11 @@ export type BroadsideRun = {
|
|
|
288
292
|
retry?: BroadsideRetryEntry;
|
|
289
293
|
/** The verification pass over the top findings, when one has run (#143). */
|
|
290
294
|
verify?: BroadsideVerifyEntry;
|
|
295
|
+
/**
|
|
296
|
+
* What post-pass results that were later regenerated had cost (#338):
|
|
297
|
+
* money the run spent that no current entry accounts for.
|
|
298
|
+
*/
|
|
299
|
+
retiredCost?: number;
|
|
291
300
|
totalCost?: number;
|
|
292
301
|
pricing?: ModelPricing;
|
|
293
302
|
maxCost?: number;
|
|
@@ -505,6 +514,8 @@ export type BroadsideCollectResult = {
|
|
|
505
514
|
summary: string;
|
|
506
515
|
}[];
|
|
507
516
|
topTriageItems: TriageItem[];
|
|
517
|
+
/** The post-passes this collect reset and re-ran on request (#338). */
|
|
518
|
+
regenerated?: Array<"synthesis" | "triage">;
|
|
508
519
|
};
|
|
509
520
|
type LensDefinition = {
|
|
510
521
|
id: BroadsideLensId;
|
|
@@ -518,12 +529,16 @@ type LensDefinition = {
|
|
|
518
529
|
skipTestFiles?: boolean;
|
|
519
530
|
globsFor: (info: RepoInfo) => string[];
|
|
520
531
|
/**
|
|
521
|
-
* Where to look when `globsFor` matches
|
|
522
|
-
* api lenses target server/, auth, and middleware paths
|
|
523
|
-
* where the trust boundary usually lives; a service whose
|
|
524
|
-
* `src/server.js` matched none of them and got no security
|
|
525
|
-
*
|
|
526
|
-
*
|
|
532
|
+
* Where to look when `globsFor` matches no source file (#319). The
|
|
533
|
+
* security and api lenses target server/, auth, and middleware paths
|
|
534
|
+
* because that is where the trust boundary usually lives; a service whose
|
|
535
|
+
* server is `src/server.js` matched none of them and got no security
|
|
536
|
+
* review at all. A match that is only documents is the same starvation:
|
|
537
|
+
* `SECURITY.md` satisfied the security lens on CodeCartographer itself,
|
|
538
|
+
* which then reviewed a policy and reported zero findings. The fallback
|
|
539
|
+
* is the language's whole source set, added to whatever did match —
|
|
540
|
+
* priced as such, and said so in the estimate, the run record, and the
|
|
541
|
+
* prompt.
|
|
527
542
|
*/
|
|
528
543
|
fallbackGlobsFor?: (info: RepoInfo) => string[];
|
|
529
544
|
systemPrompt: (info: RepoInfo) => string;
|
|
@@ -554,10 +569,15 @@ type CollectedFile = {
|
|
|
554
569
|
moduleName: string;
|
|
555
570
|
};
|
|
556
571
|
/**
|
|
557
|
-
* The files a lens will read: its targeted globs, or — when those match
|
|
558
|
-
*
|
|
559
|
-
* sentence saying so (#319). The sentence
|
|
560
|
-
* batch entry, and the prompt, so a fallback
|
|
572
|
+
* The files a lens will read: its targeted globs, or — when those match no
|
|
573
|
+
* source file and the lens declares a fallback — the fallback globs on top
|
|
574
|
+
* of whatever did match, with a sentence saying so (#319). The sentence
|
|
575
|
+
* travels to the estimate, the batch entry, and the prompt, so a fallback
|
|
576
|
+
* scan is never a silent one.
|
|
577
|
+
*
|
|
578
|
+
* "No source file" rather than "no file": a policy document or a config
|
|
579
|
+
* file under a targeted path satisfies the globs and leaves the lens with
|
|
580
|
+
* nothing to review, and the coverage note it writes back is the only sign.
|
|
561
581
|
*/
|
|
562
582
|
export declare function selectLensFiles(allFiles: string[], lens: LensDefinition, info: RepoInfo): {
|
|
563
583
|
files: CollectedFile[];
|
|
@@ -671,6 +691,17 @@ export declare function persistBroadsideRunMerging(broadsideDir: string, run: Br
|
|
|
671
691
|
* flight elsewhere.
|
|
672
692
|
*/
|
|
673
693
|
export declare function claimRunSlot(broadsideDir: string, run: BroadsideRun, slot: BroadsideRunSlot): Promise<boolean>;
|
|
694
|
+
/**
|
|
695
|
+
* Put a run's settled post-passes back to `pending` on disk so the next
|
|
696
|
+
* claim re-runs them (#338). A pass another collect has in flight is left
|
|
697
|
+
* alone — its result is still coming. The replaced results' cost moves to
|
|
698
|
+
* `retiredCost`, so the run's total keeps counting money it spent. Returns
|
|
699
|
+
* the passes that were reset, in the order they will be re-run.
|
|
700
|
+
*/
|
|
701
|
+
export declare function resetRunPostPasses(broadsideDir: string, run: BroadsideRun, wanted: {
|
|
702
|
+
synthesis: boolean;
|
|
703
|
+
triage: boolean;
|
|
704
|
+
}): Promise<Array<"synthesis" | "triage">>;
|
|
674
705
|
export declare function loadBroadsideConfig(broadsideDir: string): Promise<BroadsideConfig>;
|
|
675
706
|
/** The shipped defaults: what an absent config.yaml means. */
|
|
676
707
|
export declare function defaultBroadsideConfig(): BroadsideConfig;
|
|
@@ -822,6 +853,39 @@ export declare function saveLensResults(runDir: string, lensId: BroadsideLensId,
|
|
|
822
853
|
* "a resumed collect can finish whichever is still pending" true.
|
|
823
854
|
*/
|
|
824
855
|
export declare function loadSavedLensResults(runDir: string, lenses: BroadsideLensId[]): Promise<StoredLensResult[]>;
|
|
856
|
+
/**
|
|
857
|
+
* One verdict from a run's `verified.json` (written by the verify pass in
|
|
858
|
+
* `broadside-verify.ts`), reduced to what the post-passes are told.
|
|
859
|
+
*/
|
|
860
|
+
export type PostPassVerdict = {
|
|
861
|
+
lensId: string;
|
|
862
|
+
customId: string;
|
|
863
|
+
severity: string;
|
|
864
|
+
title: string;
|
|
865
|
+
location: string;
|
|
866
|
+
verdict: string;
|
|
867
|
+
confidence: string;
|
|
868
|
+
evidence: Array<{
|
|
869
|
+
file: string;
|
|
870
|
+
lines: string;
|
|
871
|
+
note: string;
|
|
872
|
+
}>;
|
|
873
|
+
reasoning: string;
|
|
874
|
+
};
|
|
875
|
+
/**
|
|
876
|
+
* The verdicts a verify pass left in the run directory, or null when none
|
|
877
|
+
* has run (#338). A file that does not parse is treated as absent: the
|
|
878
|
+
* post-passes then run from the findings alone, which is what they did
|
|
879
|
+
* before verdicts existed, and `status` shows the pass carried no verdicts.
|
|
880
|
+
*/
|
|
881
|
+
export declare function loadPostPassVerdicts(runDir: string): Promise<PostPassVerdict[] | null>;
|
|
882
|
+
/**
|
|
883
|
+
* The verdicts as a section of the post-pass user message: one line per
|
|
884
|
+
* finding with the verdict, the evidence the verifier cited, and its
|
|
885
|
+
* reasoning, so the pass can rank on them rather than on the batch model's
|
|
886
|
+
* own severities (#338).
|
|
887
|
+
*/
|
|
888
|
+
export declare function renderPostPassVerdicts(verdicts: PostPassVerdict[]): string;
|
|
825
889
|
export declare function runBroadsideCollect(cwd: string, apiKey: string, opts?: {
|
|
826
890
|
waitMs?: number;
|
|
827
891
|
includeSynthesis?: boolean;
|
|
@@ -844,6 +908,13 @@ export declare function runBroadsideCollect(cwd: string, apiKey: string, opts?:
|
|
|
844
908
|
signal?: AbortSignal;
|
|
845
909
|
/** Poll cadence override; tests drive the loop faster than 15 s. */
|
|
846
910
|
pollIntervalMs?: number;
|
|
911
|
+
/**
|
|
912
|
+
* Reset the wanted post-passes of a collected run and run them again
|
|
913
|
+
* (#338) — after a `verify`, so the executive report and the work order
|
|
914
|
+
* are built from the verdicts. A pass still in flight is left to finish;
|
|
915
|
+
* a run whose lens batches are still running is refused.
|
|
916
|
+
*/
|
|
917
|
+
regeneratePostPasses?: boolean;
|
|
847
918
|
}): Promise<BroadsideCollectResult>;
|
|
848
919
|
export declare function runBroadsideStatus(cwd: string): Promise<{
|
|
849
920
|
state: BroadsideStateFile;
|