audit-tools 0.30.4 → 0.30.5
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/audit/contracts/schemaEnforcedEmit.d.ts +75 -0
- package/dist/audit/contracts/schemaEnforcedEmit.d.ts.map +1 -0
- package/dist/audit/contracts/schemaEnforcedEmit.js +131 -0
- package/dist/audit/contracts/schemaEnforcedEmit.js.map +1 -0
- package/dist/audit/contracts/wrapperResponse.d.ts +6 -6
- package/dist/audit/extractors/analyzers/acquisitionEngine.d.ts +140 -0
- package/dist/audit/extractors/analyzers/acquisitionEngine.d.ts.map +1 -0
- package/dist/audit/extractors/analyzers/acquisitionEngine.js +262 -0
- package/dist/audit/extractors/analyzers/acquisitionEngine.js.map +1 -0
- package/dist/audit/extractors/analyzers/registry.d.ts +2 -0
- package/dist/audit/extractors/analyzers/registry.d.ts.map +1 -1
- package/dist/audit/extractors/analyzers/registry.js +5 -0
- package/dist/audit/extractors/analyzers/registry.js.map +1 -1
- package/dist/audit/extractors/gitHistory.d.ts +46 -0
- package/dist/audit/extractors/gitHistory.d.ts.map +1 -0
- package/dist/audit/extractors/gitHistory.js +97 -0
- package/dist/audit/extractors/gitHistory.js.map +1 -0
- package/dist/audit/extractors/graph.d.ts +19 -1
- package/dist/audit/extractors/graph.d.ts.map +1 -1
- package/dist/audit/extractors/graph.js +31 -0
- package/dist/audit/extractors/graph.js.map +1 -1
- package/dist/audit/extractors/risk.d.ts +16 -0
- package/dist/audit/extractors/risk.d.ts.map +1 -1
- package/dist/audit/extractors/risk.js +28 -0
- package/dist/audit/extractors/risk.js.map +1 -1
- package/dist/audit/io/artifacts.d.ts +3 -1
- package/dist/audit/io/artifacts.d.ts.map +1 -1
- package/dist/audit/io/artifacts.js +1 -0
- package/dist/audit/io/artifacts.js.map +1 -1
- package/dist/audit/orchestrator/artifactMetadata.d.ts.map +1 -1
- package/dist/audit/orchestrator/artifactMetadata.js +24 -3
- package/dist/audit/orchestrator/artifactMetadata.js.map +1 -1
- package/dist/audit/orchestrator/dependencyMap.d.ts +7 -0
- package/dist/audit/orchestrator/dependencyMap.d.ts.map +1 -1
- package/dist/audit/orchestrator/dependencyMap.js +5 -1
- package/dist/audit/orchestrator/dependencyMap.js.map +1 -1
- package/dist/audit/orchestrator/resultBaseline.d.ts +54 -0
- package/dist/audit/orchestrator/resultBaseline.d.ts.map +1 -1
- package/dist/audit/orchestrator/resultBaseline.js +59 -0
- package/dist/audit/orchestrator/resultBaseline.js.map +1 -1
- package/dist/audit/orchestrator/staleness.d.ts.map +1 -1
- package/dist/audit/orchestrator/staleness.js +25 -1
- package/dist/audit/orchestrator/staleness.js.map +1 -1
- package/dist/audit/quota/index.d.ts +20 -20
- package/dist/audit/types/artifactMetadata.d.ts +25 -0
- package/dist/audit/types/artifactMetadata.d.ts.map +1 -1
- package/dist/audit/types/artifactMetadata.js +10 -1
- package/dist/audit/types/artifactMetadata.js.map +1 -1
- package/dist/shared/git.d.ts +41 -0
- package/dist/shared/git.d.ts.map +1 -1
- package/dist/shared/git.js +119 -0
- package/dist/shared/git.js.map +1 -1
- package/dist/shared/index.d.ts +6 -3
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +3 -2
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/providers/providerFactory.d.ts +16 -1
- package/dist/shared/providers/providerFactory.d.ts.map +1 -1
- package/dist/shared/providers/providerFactory.js +43 -0
- package/dist/shared/providers/providerFactory.js.map +1 -1
- package/dist/shared/providers/types.d.ts +40 -0
- package/dist/shared/providers/types.d.ts.map +1 -1
- package/dist/shared/quota/capacity.d.ts +8 -8
- package/dist/shared/quota/types.d.ts +4 -4
- package/dist/shared/repair/brokeredDispatch.d.ts +147 -0
- package/dist/shared/repair/brokeredDispatch.d.ts.map +1 -0
- package/dist/shared/repair/brokeredDispatch.js +220 -0
- package/dist/shared/repair/brokeredDispatch.js.map +1 -0
- package/dist/shared/repair/index.d.ts +2 -0
- package/dist/shared/repair/index.d.ts.map +1 -1
- package/dist/shared/repair/index.js +1 -0
- package/dist/shared/repair/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import { type BrokeredRepairDispatch, type BrokerDispatchInput, type RepairContract, type RepairOutcome, type RepairPatcher } from "audit-tools/shared";
|
|
3
|
+
import type { FreshSessionProvider, OutputConstraintCapability, OutputConstraintMode } from "audit-tools/shared";
|
|
4
|
+
/**
|
|
5
|
+
* Build a {@link RepairContract} from a worker-facing zod schema. The zod schema
|
|
6
|
+
* is the ONE canonical validator (re-run after every repair stage). Errors on a
|
|
7
|
+
* field that is `optional()` in the schema map to `required: false`, so O3's
|
|
8
|
+
* stage-1 coercion is allowed to clear them by dropping the optional sub-object;
|
|
9
|
+
* everything else is `required: true`.
|
|
10
|
+
*
|
|
11
|
+
* Coercion here is intentionally a NO-OP (the schema-of-record owns no
|
|
12
|
+
* deterministic drop/backfill policy beyond zod's own parse): O3 will fall
|
|
13
|
+
* straight to its bounded LLM patch / re-dispatch stages when a REQUIRED error
|
|
14
|
+
* remains. A contract that wants deterministic coercion supplies its own.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildWorkerRepairContract(contractId: string, schema: z.ZodTypeAny): RepairContract;
|
|
17
|
+
/** Inputs for one schema-enforced emit. */
|
|
18
|
+
export interface SchemaEnforcedEmitInput {
|
|
19
|
+
/** Stable contract id (e.g. 'audit_results'). */
|
|
20
|
+
contractId: string;
|
|
21
|
+
/** The canonical worker-facing zod schema to enforce. */
|
|
22
|
+
schema: z.ZodTypeAny;
|
|
23
|
+
/** The raw worker payload emitted by the backend. */
|
|
24
|
+
payload: unknown;
|
|
25
|
+
/**
|
|
26
|
+
* The dispatching provider. Its discovered {@link OutputConstraintCapability} is
|
|
27
|
+
* READ here (never recomputed) to decide whether the emit had any structural
|
|
28
|
+
* guarantee. A provider whose descriptor is absent is treated as `none`.
|
|
29
|
+
*/
|
|
30
|
+
provider: Pick<FreshSessionProvider, "outputConstraint">;
|
|
31
|
+
/** The shared F4 broker — the SOLE route for any repair LLM touch. */
|
|
32
|
+
broker: BrokeredRepairDispatch;
|
|
33
|
+
/**
|
|
34
|
+
* The broker dispatch context (provider/session/host) for the repair slot,
|
|
35
|
+
* minus the `slots` array (the emit path supplies its own single repair slot).
|
|
36
|
+
* The broker's admission decision gates whether the bounded LLM patch runs at
|
|
37
|
+
* all — an over-budget / cooled-down pool means no LLM touch.
|
|
38
|
+
*/
|
|
39
|
+
brokerContext: Omit<BrokerDispatchInput, "slots">;
|
|
40
|
+
/** Artifacts dir for O3 friction capture (best-effort). */
|
|
41
|
+
artifactsDir: string;
|
|
42
|
+
/** Per-run id for friction capture keying. */
|
|
43
|
+
runId: string;
|
|
44
|
+
/** Which orchestrator is emitting (friction record `tool` field). */
|
|
45
|
+
tool?: "audit-code" | "remediate-code";
|
|
46
|
+
/**
|
|
47
|
+
* Bounded errors-only LLM patch (O3 stage-2). The PATCH ITSELF is the caller's
|
|
48
|
+
* provider call, but it is invoked from inside `runEmitValidateRepair` only
|
|
49
|
+
* after the broker has admitted the repair slot (see {@link enforceSchemaAtEmit}).
|
|
50
|
+
* Omit to skip stage-2 (coercion + re-dispatch only).
|
|
51
|
+
*/
|
|
52
|
+
patcher?: RepairPatcher;
|
|
53
|
+
/** 1-based current attempt counter (default 1). */
|
|
54
|
+
attempt?: number;
|
|
55
|
+
}
|
|
56
|
+
/** The single result of a schema-enforced emit. */
|
|
57
|
+
export interface SchemaEnforcedEmitResult {
|
|
58
|
+
/** The constraint mode actually in force for this emit (read from the provider). */
|
|
59
|
+
mode: OutputConstraintMode;
|
|
60
|
+
/** The O3 repair outcome (status, repaired payload, warnings, re-dispatch signal). */
|
|
61
|
+
repair: RepairOutcome;
|
|
62
|
+
}
|
|
63
|
+
/** Resolve the emit's constraint mode from the provider descriptor (absent ⟹ none). */
|
|
64
|
+
export declare function resolveEmitConstraint(provider: Pick<FreshSessionProvider, "outputConstraint">): OutputConstraintCapability;
|
|
65
|
+
/**
|
|
66
|
+
* Enforce the canonical worker schema at emit time, degrading through the O3
|
|
67
|
+
* emit-validate-repair seam when there is no structural guarantee or the payload
|
|
68
|
+
* fails to validate. The stage-2 LLM patch is gated by F4's broker: a single
|
|
69
|
+
* repair slot is offered to `broker.broker`, and the bounded patcher only runs if
|
|
70
|
+
* the broker admits it. A refused/cooled-down broker means no LLM touch — O3 then
|
|
71
|
+
* falls to its deterministic coercion + re-dispatch signal. The seam NEVER spawns
|
|
72
|
+
* a dispatch itself.
|
|
73
|
+
*/
|
|
74
|
+
export declare function enforceSchemaAtEmit(input: SchemaEnforcedEmitInput): Promise<SchemaEnforcedEmitResult>;
|
|
75
|
+
//# sourceMappingURL=schemaEnforcedEmit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaEnforcedEmit.d.ts","sourceRoot":"","sources":["../../../src/audit/contracts/schemaEnforcedEmit.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAGnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,CAAC,CAAC,UAAU,GACnB,cAAc,CA+BhB;AAED,2CAA2C;AAC3C,MAAM,WAAW,uBAAuB;IACtC,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC;IACrB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,QAAQ,EAAE,IAAI,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CAAC;IACzD,sEAAsE;IACtE,MAAM,EAAE,sBAAsB,CAAC;IAC/B;;;;;OAKG;IACH,aAAa,EAAE,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IAClD,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,IAAI,CAAC,EAAE,YAAY,GAAG,gBAAgB,CAAC;IACvC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,mDAAmD;AACnD,MAAM,WAAW,wBAAwB;IACvC,oFAAoF;IACpF,IAAI,EAAE,oBAAoB,CAAC;IAC3B,sFAAsF;IACtF,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,uFAAuF;AACvF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,IAAI,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,GACvD,0BAA0B,CAO5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,wBAAwB,CAAC,CA4CnC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// F3 — schema-enforced worker generation.
|
|
2
|
+
//
|
|
3
|
+
// This is the emit-time half of the F3 ↔ F4 ↔ O3 seam set. At emit, a worker
|
|
4
|
+
// result is enforced against the canonical worker-facing zod schema
|
|
5
|
+
// (`workerSchemas.ts`). The strongest available enforcement is chosen ONCE from
|
|
6
|
+
// the provider's discovered `OutputConstraintCapability` (F3 ↔ F4: the descriptor
|
|
7
|
+
// is read here, never recomputed):
|
|
8
|
+
//
|
|
9
|
+
// - `forced_tool_call` / `json_schema_constrained` / `structured_output` — the
|
|
10
|
+
// backend already constrained its output, so the emitted payload is expected
|
|
11
|
+
// to validate; we still re-run the canonical zod validate as the single
|
|
12
|
+
// authority (defence-in-depth, no second validator).
|
|
13
|
+
// - `none` — no structural guarantee from the backend; the payload MUST go
|
|
14
|
+
// through the O3 emit-validate-repair seam to be salvaged.
|
|
15
|
+
//
|
|
16
|
+
// On capability `none` OR a validation failure under any mode, the payload is
|
|
17
|
+
// degraded through O3's `runEmitValidateRepair`. Its bounded stage-2 LLM patch is
|
|
18
|
+
// routed through F4's shared `BrokeredRepairDispatch` seam — the emit path NEVER
|
|
19
|
+
// spawns a re-dispatch directly; every LLM touch flows through the single gated
|
|
20
|
+
// broker chokepoint (broker-handle edge O3 ↔ F4).
|
|
21
|
+
import { runEmitValidateRepair, } from "audit-tools/shared";
|
|
22
|
+
/**
|
|
23
|
+
* Build a {@link RepairContract} from a worker-facing zod schema. The zod schema
|
|
24
|
+
* is the ONE canonical validator (re-run after every repair stage). Errors on a
|
|
25
|
+
* field that is `optional()` in the schema map to `required: false`, so O3's
|
|
26
|
+
* stage-1 coercion is allowed to clear them by dropping the optional sub-object;
|
|
27
|
+
* everything else is `required: true`.
|
|
28
|
+
*
|
|
29
|
+
* Coercion here is intentionally a NO-OP (the schema-of-record owns no
|
|
30
|
+
* deterministic drop/backfill policy beyond zod's own parse): O3 will fall
|
|
31
|
+
* straight to its bounded LLM patch / re-dispatch stages when a REQUIRED error
|
|
32
|
+
* remains. A contract that wants deterministic coercion supplies its own.
|
|
33
|
+
*/
|
|
34
|
+
export function buildWorkerRepairContract(contractId, schema) {
|
|
35
|
+
return {
|
|
36
|
+
contractId,
|
|
37
|
+
validate(payload) {
|
|
38
|
+
const parsed = schema.safeParse(payload);
|
|
39
|
+
if (parsed.success)
|
|
40
|
+
return { errors: [] };
|
|
41
|
+
const errors = parsed.error.issues.map((issue) => ({
|
|
42
|
+
path: issue.path.join("."),
|
|
43
|
+
message: issue.message,
|
|
44
|
+
// A missing required key is reported by zod as `invalid_type` with
|
|
45
|
+
// `received: "undefined"`; an `unrecognized_keys` issue is a strict()
|
|
46
|
+
// violation. Both gate escalation. Optional fields never produce a
|
|
47
|
+
// "Required" issue, so any issue zod emits here sits on a constraint
|
|
48
|
+
// the worker must satisfy → required.
|
|
49
|
+
required: true,
|
|
50
|
+
}));
|
|
51
|
+
return { errors };
|
|
52
|
+
},
|
|
53
|
+
coercion: {
|
|
54
|
+
coerce(payload) {
|
|
55
|
+
return {
|
|
56
|
+
payload,
|
|
57
|
+
drops: [],
|
|
58
|
+
backfills: [],
|
|
59
|
+
unrecoverableIdentity: false,
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** Resolve the emit's constraint mode from the provider descriptor (absent ⟹ none). */
|
|
66
|
+
export function resolveEmitConstraint(provider) {
|
|
67
|
+
return (provider.outputConstraint ?? {
|
|
68
|
+
mode: "none",
|
|
69
|
+
reason: "provider exposes no discovered output-constraint capability",
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Enforce the canonical worker schema at emit time, degrading through the O3
|
|
74
|
+
* emit-validate-repair seam when there is no structural guarantee or the payload
|
|
75
|
+
* fails to validate. The stage-2 LLM patch is gated by F4's broker: a single
|
|
76
|
+
* repair slot is offered to `broker.broker`, and the bounded patcher only runs if
|
|
77
|
+
* the broker admits it. A refused/cooled-down broker means no LLM touch — O3 then
|
|
78
|
+
* falls to its deterministic coercion + re-dispatch signal. The seam NEVER spawns
|
|
79
|
+
* a dispatch itself.
|
|
80
|
+
*/
|
|
81
|
+
export async function enforceSchemaAtEmit(input) {
|
|
82
|
+
const constraint = resolveEmitConstraint(input.provider);
|
|
83
|
+
const contract = buildWorkerRepairContract(input.contractId, input.schema);
|
|
84
|
+
// Gate the bounded LLM patch through the single F4 broker chokepoint. We offer
|
|
85
|
+
// exactly one repair slot sized from the payload's byte length; the patcher runs
|
|
86
|
+
// ONLY if the broker admits the slot. `awaitNextCompletion` passes the raw
|
|
87
|
+
// patched result straight back to O3's canonical validator (broker-handle edge).
|
|
88
|
+
let brokeredPatcher;
|
|
89
|
+
if (input.patcher) {
|
|
90
|
+
const slotId = `${input.contractId}:repair:${input.runId}`;
|
|
91
|
+
brokeredPatcher = async (payload, errors) => {
|
|
92
|
+
const payloadBytes = Buffer.byteLength(safeStringify(payload), "utf8");
|
|
93
|
+
const decision = input.broker.broker({
|
|
94
|
+
...input.brokerContext,
|
|
95
|
+
slots: [{ slotId, payloadBytes }],
|
|
96
|
+
});
|
|
97
|
+
if (decision.admitted < 1 || !decision.admittedSlotIds.includes(slotId)) {
|
|
98
|
+
// Broker refused (over budget / cooldown) → no LLM touch. Return the
|
|
99
|
+
// payload unchanged so O3 falls to its deterministic re-dispatch signal.
|
|
100
|
+
return payload;
|
|
101
|
+
}
|
|
102
|
+
const patched = await input.patcher(payload, errors);
|
|
103
|
+
const { rawResult } = input.broker.awaitNextCompletion({
|
|
104
|
+
slotId,
|
|
105
|
+
rawResult: patched,
|
|
106
|
+
});
|
|
107
|
+
return rawResult;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const repair = await runEmitValidateRepair({
|
|
111
|
+
contract,
|
|
112
|
+
payload: input.payload,
|
|
113
|
+
artifactsDir: input.artifactsDir,
|
|
114
|
+
runId: input.runId,
|
|
115
|
+
tool: input.tool,
|
|
116
|
+
// Capability `none` keeps the patcher available (degrade path); a constrained
|
|
117
|
+
// mode still validates and only patches if the constrained output drifted.
|
|
118
|
+
patcher: brokeredPatcher,
|
|
119
|
+
attempt: input.attempt,
|
|
120
|
+
});
|
|
121
|
+
return { mode: constraint.mode, repair };
|
|
122
|
+
}
|
|
123
|
+
function safeStringify(value) {
|
|
124
|
+
try {
|
|
125
|
+
return JSON.stringify(value) ?? "";
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return "";
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=schemaEnforcedEmit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaEnforcedEmit.js","sourceRoot":"","sources":["../../../src/audit/contracts/schemaEnforcedEmit.ts"],"names":[],"mappings":"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"}
|
|
@@ -103,8 +103,8 @@ export declare const AuditCodeResponseSchema: z.ZodObject<{
|
|
|
103
103
|
runtime_validation_tasks: z.ZodNullable<z.ZodString>;
|
|
104
104
|
friction_record: z.ZodString;
|
|
105
105
|
}, "strict", z.ZodTypeAny, {
|
|
106
|
-
current_prompt: string | null;
|
|
107
106
|
session_config: string;
|
|
107
|
+
current_prompt: string | null;
|
|
108
108
|
runtime_validation_tasks: string | null;
|
|
109
109
|
audit_tasks: string | null;
|
|
110
110
|
incoming_dir: string;
|
|
@@ -115,8 +115,8 @@ export declare const AuditCodeResponseSchema: z.ZodObject<{
|
|
|
115
115
|
current_tasks: string | null;
|
|
116
116
|
friction_record: string;
|
|
117
117
|
}, {
|
|
118
|
-
current_prompt: string | null;
|
|
119
118
|
session_config: string;
|
|
119
|
+
current_prompt: string | null;
|
|
120
120
|
runtime_validation_tasks: string | null;
|
|
121
121
|
audit_tasks: string | null;
|
|
122
122
|
incoming_dir: string;
|
|
@@ -136,8 +136,8 @@ export declare const AuditCodeResponseSchema: z.ZodObject<{
|
|
|
136
136
|
repo_root: string;
|
|
137
137
|
artifacts_dir: string;
|
|
138
138
|
artifact_paths: {
|
|
139
|
-
current_prompt: string | null;
|
|
140
139
|
session_config: string;
|
|
140
|
+
current_prompt: string | null;
|
|
141
141
|
runtime_validation_tasks: string | null;
|
|
142
142
|
audit_tasks: string | null;
|
|
143
143
|
incoming_dir: string;
|
|
@@ -173,8 +173,8 @@ export declare const AuditCodeResponseSchema: z.ZodObject<{
|
|
|
173
173
|
repo_root: string;
|
|
174
174
|
artifacts_dir: string;
|
|
175
175
|
artifact_paths: {
|
|
176
|
-
current_prompt: string | null;
|
|
177
176
|
session_config: string;
|
|
177
|
+
current_prompt: string | null;
|
|
178
178
|
runtime_validation_tasks: string | null;
|
|
179
179
|
audit_tasks: string | null;
|
|
180
180
|
incoming_dir: string;
|
|
@@ -230,8 +230,8 @@ export declare const AuditCodeResponseSchema: z.ZodObject<{
|
|
|
230
230
|
repo_root: string;
|
|
231
231
|
artifacts_dir: string;
|
|
232
232
|
artifact_paths: {
|
|
233
|
-
current_prompt: string | null;
|
|
234
233
|
session_config: string;
|
|
234
|
+
current_prompt: string | null;
|
|
235
235
|
runtime_validation_tasks: string | null;
|
|
236
236
|
audit_tasks: string | null;
|
|
237
237
|
incoming_dir: string;
|
|
@@ -287,8 +287,8 @@ export declare const AuditCodeResponseSchema: z.ZodObject<{
|
|
|
287
287
|
repo_root: string;
|
|
288
288
|
artifacts_dir: string;
|
|
289
289
|
artifact_paths: {
|
|
290
|
-
current_prompt: string | null;
|
|
291
290
|
session_config: string;
|
|
291
|
+
current_prompt: string | null;
|
|
292
292
|
runtime_validation_tasks: string | null;
|
|
293
293
|
audit_tasks: string | null;
|
|
294
294
|
incoming_dir: string;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { type AnalyzerSetting, type RunTrackedResult } from "audit-tools/shared";
|
|
2
|
+
import type { ExternalAnalyzerResults, ExternalAnalyzerToolStatus } from "../../types/externalAnalyzer.js";
|
|
3
|
+
/**
|
|
4
|
+
* F5 — external analyzer acquisition engine.
|
|
5
|
+
*
|
|
6
|
+
* On-demand acquisition + ephemeral execution of mature, ecosystem-native
|
|
7
|
+
* analyzers (eslint, ruff, cargo-clippy, …). Distinct from the in-tree
|
|
8
|
+
* `LanguageAnalyzer` registry (which enriches the regex floor from a resolved
|
|
9
|
+
* npm package directory): F5 *runs an external tool as a subprocess* and
|
|
10
|
+
* normalizes its native output through the EXISTING adapter seam
|
|
11
|
+
* (`normalizeExternal.ts`) into {@link ExternalAnalyzerResults}, which then
|
|
12
|
+
* re-enters the graph/risk artifacts through the shared
|
|
13
|
+
* CCU-analyzer-merge-helper-seam pair.
|
|
14
|
+
*
|
|
15
|
+
* Design invariants (all enforced here, never by host discretion):
|
|
16
|
+
* - **No baked-in language→tool / OS→runner table.** Ecosystem is detected
|
|
17
|
+
* deterministically from repo marker files; the runner (npx/pipx/cargo/bundle)
|
|
18
|
+
* is capability-probed at RUNTIME (`--version`) before any tool spawn.
|
|
19
|
+
* - **Single subprocess-SPAWN admission chokepoint** (`admitSpawn`): EVERY
|
|
20
|
+
* non-DEFAULT candidate is gated on the per-run consent token regardless of
|
|
21
|
+
* its `AnalyzerSetting` (auto|ephemeral|permanent) — even a `permanent`,
|
|
22
|
+
* pre-installed tool cannot spawn without consent (CE-005). The small
|
|
23
|
+
* value-curated DEFAULT set runs without prompting.
|
|
24
|
+
* - **Own-vs-acquire boundary.** git-history / secret-scan are OWNED by F6 and
|
|
25
|
+
* are rejected at registration — never acquired here.
|
|
26
|
+
* - **Run-safety gate written once** (`runSafetyGate`): capability-probe, pin
|
|
27
|
+
* version, read-only/sandboxed argv, degrade-to-empty.
|
|
28
|
+
* - **Degrade-to-empty + report-skipped-never-silently.** Every candidate
|
|
29
|
+
* yields exactly one {@link ExternalAnalyzerToolStatus}; a failure never
|
|
30
|
+
* throws and never silently drops the candidate.
|
|
31
|
+
*/
|
|
32
|
+
/** Tool ids OWNED by F6 (git-history mining / secret scanning). Never acquired. */
|
|
33
|
+
export declare const OWNED_TOOL_IDS: Set<string>;
|
|
34
|
+
/** Ecosystem runners F5 knows how to drive. */
|
|
35
|
+
export type EcosystemRunner = "npx" | "pipx" | "cargo" | "bundle";
|
|
36
|
+
/**
|
|
37
|
+
* One acquirable external analyzer. `defaultRun: true` marks a member of the
|
|
38
|
+
* small value-curated set that may run without a consent token; everything else
|
|
39
|
+
* is gated on the per-run consent token at the spawn chokepoint.
|
|
40
|
+
*/
|
|
41
|
+
export interface ExternalAnalyzerCandidate {
|
|
42
|
+
/** Stable id; also the `analyzers.<id>` session-config key. */
|
|
43
|
+
id: string;
|
|
44
|
+
/** Runner that acquires + executes the tool ephemerally. */
|
|
45
|
+
runner: EcosystemRunner;
|
|
46
|
+
/** Pinned tool spec, e.g. "eslint@9" / "ruff==0.5.0" (pinned for reproducibility). */
|
|
47
|
+
spec: string;
|
|
48
|
+
/**
|
|
49
|
+
* Build the read-only argv for the tool given the resolved runner argv prefix
|
|
50
|
+
* and repo root. MUST NOT request fixes/writes — F5 is observe-only.
|
|
51
|
+
*/
|
|
52
|
+
buildArgv(runnerPrefix: string[], root: string): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Parse the tool's stdout into the generic item shape consumed by
|
|
55
|
+
* `normalizeGenericExternalResults`. Degrades to `[]` on any parse failure.
|
|
56
|
+
*/
|
|
57
|
+
parse(stdout: string): Array<{
|
|
58
|
+
id?: string;
|
|
59
|
+
category?: string;
|
|
60
|
+
severity?: string;
|
|
61
|
+
path?: string;
|
|
62
|
+
line_start?: number;
|
|
63
|
+
line_end?: number;
|
|
64
|
+
summary?: string;
|
|
65
|
+
rule?: string;
|
|
66
|
+
raw?: unknown;
|
|
67
|
+
from?: unknown;
|
|
68
|
+
to?: unknown;
|
|
69
|
+
}>;
|
|
70
|
+
/** Whether this ecosystem is present (marker file detection). */
|
|
71
|
+
detect(root: string): boolean;
|
|
72
|
+
/** Member of the value-curated DEFAULT set (runs without prompting). */
|
|
73
|
+
defaultRun: boolean;
|
|
74
|
+
}
|
|
75
|
+
export declare function detectNodeEcosystem(root: string): boolean;
|
|
76
|
+
export declare function detectPythonEcosystem(root: string): boolean;
|
|
77
|
+
export declare function detectRustEcosystem(root: string): boolean;
|
|
78
|
+
export declare function detectRubyEcosystem(root: string): boolean;
|
|
79
|
+
export interface AcquisitionRunner {
|
|
80
|
+
(argv: string[], cwd: string): RunTrackedResult;
|
|
81
|
+
}
|
|
82
|
+
export interface AcquisitionEngineOptions {
|
|
83
|
+
/**
|
|
84
|
+
* Per-run consent token. REQUIRED to spawn any non-DEFAULT candidate (and any
|
|
85
|
+
* candidate whose setting is ephemeral/permanent). Absent ⇒ only the DEFAULT
|
|
86
|
+
* set runs; everything else is reported `skipped` with a consent note.
|
|
87
|
+
*/
|
|
88
|
+
consentToken?: string;
|
|
89
|
+
/** Per-analyzer settings (auto|ephemeral|permanent|skip|repo). */
|
|
90
|
+
analyzers?: Record<string, AnalyzerSetting>;
|
|
91
|
+
/** Injectable command runner; defaults to the shared runTracked. */
|
|
92
|
+
run?: AcquisitionRunner;
|
|
93
|
+
/** Injectable logger; defaults to a no-op (degrade quietly to status records). */
|
|
94
|
+
log?: (...args: unknown[]) => void;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Single subprocess-SPAWN admission chokepoint. Returns the reason a spawn is
|
|
98
|
+
* NOT admitted, or `undefined` when admitted. The DEFAULT set is admitted
|
|
99
|
+
* without a token; EVERY other candidate — including `permanent`/`ephemeral`
|
|
100
|
+
* pre-installed tools — requires the per-run consent token (CE-005).
|
|
101
|
+
*/
|
|
102
|
+
export declare function admitSpawn(candidate: ExternalAnalyzerCandidate, setting: AnalyzerSetting, consentToken: string | undefined): string | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* The run-safety gate, written once: capability-probe the runner, then (if the
|
|
105
|
+
* probe passes) the caller may spawn the pinned, read-only argv. Returns the
|
|
106
|
+
* probe outcome so a missing runner degrades to an empty result + a status.
|
|
107
|
+
*/
|
|
108
|
+
export declare function runSafetyGate(candidate: ExternalAnalyzerCandidate, run: AcquisitionRunner, root: string): {
|
|
109
|
+
ok: true;
|
|
110
|
+
} | {
|
|
111
|
+
ok: false;
|
|
112
|
+
reason: string;
|
|
113
|
+
};
|
|
114
|
+
export interface AcquisitionOutcome {
|
|
115
|
+
results: ExternalAnalyzerResults;
|
|
116
|
+
status: ExternalAnalyzerToolStatus;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Acquire + run ONE external analyzer candidate ephemerally, normalizing its
|
|
120
|
+
* output through the adapter seam. Never throws; always returns exactly one
|
|
121
|
+
* {@link ExternalAnalyzerToolStatus} alongside the (possibly empty) results.
|
|
122
|
+
*/
|
|
123
|
+
export declare function runExternalAnalyzer(candidate: ExternalAnalyzerCandidate, root: string, options?: AcquisitionEngineOptions): AcquisitionOutcome;
|
|
124
|
+
/**
|
|
125
|
+
* Register external analyzer candidates, rejecting any whose id is OWNED by F6
|
|
126
|
+
* (git-history/secret-scan). Returns the accepted candidates; the own-vs-acquire
|
|
127
|
+
* boundary is enforced HERE so an owned tool can never enter the engine.
|
|
128
|
+
*/
|
|
129
|
+
export declare function registerExternalAnalyzers(candidates: ExternalAnalyzerCandidate[]): ExternalAnalyzerCandidate[];
|
|
130
|
+
export interface RunAllOutcome {
|
|
131
|
+
results: ExternalAnalyzerResults[];
|
|
132
|
+
statuses: ExternalAnalyzerToolStatus[];
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Drive the whole registered candidate set through the engine for one repo,
|
|
136
|
+
* collecting one status per candidate. Owned tools are rejected at registration;
|
|
137
|
+
* each survivor passes through the spawn-admission chokepoint and run-safety gate.
|
|
138
|
+
*/
|
|
139
|
+
export declare function runAcquisitionEngine(candidates: ExternalAnalyzerCandidate[], root: string, options?: AcquisitionEngineOptions): RunAllOutcome;
|
|
140
|
+
//# sourceMappingURL=acquisitionEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acquisitionEngine.d.ts","sourceRoot":"","sources":["../../../../src/audit/extractors/analyzers/acquisitionEngine.ts"],"names":[],"mappings":"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"}
|