auditor-lambda 0.3.29 → 0.3.32

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.
@@ -1371,6 +1371,18 @@ const INSTALL_HOST_DEFINITIONS = {
1371
1371
  profile: {
1372
1372
  writeAgents: true,
1373
1373
  },
1374
+ async verify({ checks, assetPaths, collectVerifyCheck: collect }) {
1375
+ await collect(checks, 'codex_global_surface', async () => {
1376
+ const content = await readFile(assetPaths.agentsInstructionsPath, 'utf8');
1377
+ if (!content.includes('/audit-code')) {
1378
+ throw new Error(`AGENTS instructions do not reference /audit-code: ${assetPaths.agentsInstructionsPath}`);
1379
+ }
1380
+ return {
1381
+ summary: 'Codex uses the global skill surface with AGENTS fallback instructions.',
1382
+ path: assetPaths.agentsInstructionsPath,
1383
+ };
1384
+ });
1385
+ },
1374
1386
  },
1375
1387
  'claude-desktop': {
1376
1388
  host: 'claude-desktop',
@@ -1394,6 +1406,85 @@ const INSTALL_HOST_DEFINITIONS = {
1394
1406
  profile: {
1395
1407
  writeClaudeDesktop: true,
1396
1408
  },
1409
+ async verify({ checks, root, assetPaths, collectVerifyCheck: collect }) {
1410
+ const bundleManifestPath = join(
1411
+ root,
1412
+ '.audit-code',
1413
+ 'install',
1414
+ 'claude-desktop',
1415
+ 'bundle',
1416
+ 'manifest.json',
1417
+ );
1418
+ const bundleServerPath = join(
1419
+ root,
1420
+ '.audit-code',
1421
+ 'install',
1422
+ 'claude-desktop',
1423
+ 'bundle',
1424
+ 'server',
1425
+ 'index.js',
1426
+ );
1427
+
1428
+ await collect(checks, 'claude_bundle_manifest', async () => {
1429
+ const manifest = await readJson(bundleManifestPath, 'Claude Desktop bundle manifest');
1430
+ if (manifest?.server?.entry_point !== 'server/index.js') {
1431
+ throw new Error(`Claude Desktop bundle manifest has an unexpected entry_point: ${manifest?.server?.entry_point ?? 'missing'}.`);
1432
+ }
1433
+ return {
1434
+ summary: 'Claude Desktop bundle manifest parsed successfully.',
1435
+ path: bundleManifestPath,
1436
+ };
1437
+ });
1438
+ await collect(checks, 'claude_connector_template', async () => {
1439
+ const connector = await readJson(
1440
+ assetPaths.claudeDesktopRemoteConnectorPath,
1441
+ 'Claude Desktop remote connector template',
1442
+ );
1443
+ if (connector?.transport !== 'remote-mcp') {
1444
+ throw new Error(`Claude Desktop remote connector transport must be "remote-mcp", got ${connector?.transport ?? 'missing'}.`);
1445
+ }
1446
+ return {
1447
+ summary: 'Claude Desktop remote connector template parsed successfully.',
1448
+ path: assetPaths.claudeDesktopRemoteConnectorPath,
1449
+ };
1450
+ });
1451
+ await collect(checks, 'claude_dxt_archive', async () => ({
1452
+ summary: 'Claude Desktop .dxt bundle is present.',
1453
+ path: assetPaths.claudeDesktopDxtPath,
1454
+ size_bytes: await verifyZipFile(
1455
+ assetPaths.claudeDesktopDxtPath,
1456
+ 'Claude Desktop .dxt bundle',
1457
+ ),
1458
+ }));
1459
+ await collect(checks, 'claude_mcpb_archive', async () => ({
1460
+ summary: 'Claude Desktop .mcpb bundle is present.',
1461
+ path: assetPaths.claudeDesktopMcpbPath,
1462
+ size_bytes: await verifyZipFile(
1463
+ assetPaths.claudeDesktopMcpbPath,
1464
+ 'Claude Desktop .mcpb bundle',
1465
+ ),
1466
+ }));
1467
+ await collect(checks, 'claude_bundle_mcp', async () => {
1468
+ const probe = await probeMcpServer({
1469
+ label: 'Claude Desktop bundle server',
1470
+ command: process.execPath,
1471
+ args: [bundleServerPath],
1472
+ cwd: root,
1473
+ env: {
1474
+ AUDIT_CODE_REPO_ROOT: root,
1475
+ AUDIT_CODE_ARTIFACTS_DIR: join(root, '.audit-artifacts'),
1476
+ },
1477
+ });
1478
+ const toolNames = (probe.tools?.tools ?? []).map((tool) => tool.name);
1479
+ if (!toolNames.includes('start_audit')) {
1480
+ throw new Error('Claude Desktop bundle server did not expose the start_audit tool.');
1481
+ }
1482
+ return {
1483
+ summary: 'Claude Desktop bundle completed an MCP handshake.',
1484
+ tool_count: toolNames.length,
1485
+ };
1486
+ });
1487
+ },
1397
1488
  },
1398
1489
  opencode: {
1399
1490
  host: 'opencode',
@@ -1416,6 +1507,23 @@ const INSTALL_HOST_DEFINITIONS = {
1416
1507
  writeOpenCode: true,
1417
1508
  writeAgents: true,
1418
1509
  },
1510
+ async verify({ checks, assetPaths, collectVerifyCheck: collect }) {
1511
+ await collect(checks, 'opencode_config', async () => {
1512
+ const config = await readJson(assetPaths.opencodeConfigPath, 'OpenCode project config');
1513
+ if (config?.command?.['audit-code']) {
1514
+ throw new Error('OpenCode project config must not define command["audit-code"]; the slash command is global npm-installed state. Run "audit-code install --host opencode" to remove the stale local command.');
1515
+ }
1516
+ if (config?.mcp?.auditor) {
1517
+ throw new Error('OpenCode project config must not define mcp.auditor; the MCP server is supplied by the global npm-installed config. Run "audit-code install --host opencode" to remove the stale project-level MCP entry.');
1518
+ }
1519
+ assertOpenCodeAuditPermissionConfig(config?.permission, 'permission');
1520
+ assertOpenCodeAuditPermissionConfig(config?.agent?.auditor?.permission, 'agent.auditor.permission');
1521
+ return {
1522
+ summary: 'OpenCode project config has audit permissions; MCP server and /audit-code command are supplied by the global npm-installed config.',
1523
+ path: assetPaths.opencodeConfigPath,
1524
+ };
1525
+ });
1526
+ },
1419
1527
  },
1420
1528
  vscode: {
1421
1529
  host: 'vscode',
@@ -1439,6 +1547,39 @@ const INSTALL_HOST_DEFINITIONS = {
1439
1547
  writeVSCode: true,
1440
1548
  writeCopilotInstructions: true,
1441
1549
  },
1550
+ async verify({ checks, assetPaths, collectVerifyCheck: collect }) {
1551
+ await collect(checks, 'vscode_prompt', async () => {
1552
+ const content = await readFile(assetPaths.vscodePromptPath, 'utf8');
1553
+ if (!content.includes('name: audit-code')) {
1554
+ throw new Error(`VS Code prompt file is missing the expected frontmatter name: ${assetPaths.vscodePromptPath}`);
1555
+ }
1556
+ const { body: promptBody } = splitFrontmatter(content);
1557
+ const { body: sourceBody } = splitFrontmatter(await readFile(promptAssetPath, 'utf8'));
1558
+ if (promptBody !== sourceBody.trimStart()) {
1559
+ throw new Error(
1560
+ `VS Code prompt body is out of sync with the source prompt. Run "audit-code install --host vscode" or "audit-code install".`,
1561
+ );
1562
+ }
1563
+ return {
1564
+ summary: 'VS Code prompt file is present and uses the source prompt body.',
1565
+ path: assetPaths.vscodePromptPath,
1566
+ };
1567
+ });
1568
+ await collect(checks, 'vscode_mcp_config', async () => {
1569
+ const config = await readJson(assetPaths.vscodeMcpConfigPath, 'VS Code MCP config');
1570
+ const args = config?.servers?.auditor?.args;
1571
+ if (config?.servers?.auditor?.command !== 'node') {
1572
+ throw new Error(`VS Code MCP config must use node as the command, got ${config?.servers?.auditor?.command ?? 'missing'}.`);
1573
+ }
1574
+ if (!Array.isArray(args) || args[0] !== '${workspaceFolder}/.audit-code/install/run-mcp-server.mjs') {
1575
+ throw new Error(`VS Code MCP config must point at \${workspaceFolder}/.audit-code/install/${MCP_LAUNCHER_FILENAME}.`);
1576
+ }
1577
+ return {
1578
+ summary: 'VS Code MCP config parsed successfully.',
1579
+ path: assetPaths.vscodeMcpConfigPath,
1580
+ };
1581
+ });
1582
+ },
1442
1583
  },
1443
1584
  antigravity: {
1444
1585
  host: 'antigravity',
@@ -1465,6 +1606,28 @@ const INSTALL_HOST_DEFINITIONS = {
1465
1606
  writeAntigravity: true,
1466
1607
  writeAgents: true,
1467
1608
  },
1609
+ async verify({ checks, assetPaths, collectVerifyCheck: collect }) {
1610
+ await collect(checks, 'antigravity_skill', async () => {
1611
+ const content = await readFile(assetPaths.antigravitySkillPath, 'utf8');
1612
+ if (!content.includes('name: audit-code')) {
1613
+ throw new Error('Antigravity skill SKILL.md must contain "name: audit-code" in frontmatter.');
1614
+ }
1615
+ return {
1616
+ summary: 'Antigravity .agent/skills/audit-code/SKILL.md is present and valid.',
1617
+ path: assetPaths.antigravitySkillPath,
1618
+ };
1619
+ });
1620
+ await collect(checks, 'antigravity_guide', async () => {
1621
+ const content = await readFile(assetPaths.antigravityPlanningGuidePath, 'utf8');
1622
+ if (!content.includes(MCP_LAUNCHER_FILENAME) || !content.includes(INSTALLED_PROMPT_FILENAME)) {
1623
+ throw new Error(`Antigravity guide must reference both ${MCP_LAUNCHER_FILENAME} and ${INSTALLED_PROMPT_FILENAME}.`);
1624
+ }
1625
+ return {
1626
+ summary: 'Antigravity planning guide references the repo-local prompt asset and MCP launcher.',
1627
+ path: assetPaths.antigravityPlanningGuidePath,
1628
+ };
1629
+ });
1630
+ },
1468
1631
  },
1469
1632
  };
1470
1633
 
@@ -1505,6 +1668,13 @@ function getInstallProfile(host) {
1505
1668
  return profile;
1506
1669
  }
1507
1670
 
1671
+ export {
1672
+ INSTALL_HOST_ORDER as _INSTALL_HOST_ORDER,
1673
+ INSTALL_HOST_DEFINITIONS as _INSTALL_HOST_DEFINITIONS,
1674
+ getInstallHostKeys as _getInstallHostKeys,
1675
+ getInstallProfile as _getInstallProfile,
1676
+ };
1677
+
1508
1678
  function buildHostCatalog({ root, host, assets }) {
1509
1679
  return getInstallHostKeys(host)
1510
1680
  .map((hostKey) => {
@@ -2028,177 +2198,15 @@ async function verifyInstalledBootstrap(argv) {
2028
2198
  primary_path: hostEntry.primary_path,
2029
2199
  }));
2030
2200
 
2031
- switch (hostKey) {
2032
- case 'codex':
2033
- await collectVerifyCheck(checks, 'codex_global_surface', async () => {
2034
- const content = await readFile(assetPaths.agentsInstructionsPath, 'utf8');
2035
- if (!content.includes('/audit-code')) {
2036
- throw new Error(`AGENTS instructions do not reference /audit-code: ${assetPaths.agentsInstructionsPath}`);
2037
- }
2038
- return {
2039
- summary: 'Codex uses the global skill surface with AGENTS fallback instructions.',
2040
- path: assetPaths.agentsInstructionsPath,
2041
- };
2042
- });
2043
- break;
2044
- case 'claude-desktop': {
2045
- const bundleManifestPath = join(
2046
- root,
2047
- '.audit-code',
2048
- 'install',
2049
- 'claude-desktop',
2050
- 'bundle',
2051
- 'manifest.json',
2052
- );
2053
- const bundleServerPath = join(
2054
- root,
2055
- '.audit-code',
2056
- 'install',
2057
- 'claude-desktop',
2058
- 'bundle',
2059
- 'server',
2060
- 'index.js',
2061
- );
2062
-
2063
- await collectVerifyCheck(checks, 'claude_bundle_manifest', async () => {
2064
- const manifest = await readJson(bundleManifestPath, 'Claude Desktop bundle manifest');
2065
- if (manifest?.server?.entry_point !== 'server/index.js') {
2066
- throw new Error(`Claude Desktop bundle manifest has an unexpected entry_point: ${manifest?.server?.entry_point ?? 'missing'}.`);
2067
- }
2068
- return {
2069
- summary: 'Claude Desktop bundle manifest parsed successfully.',
2070
- path: bundleManifestPath,
2071
- };
2072
- });
2073
- await collectVerifyCheck(checks, 'claude_connector_template', async () => {
2074
- const connector = await readJson(
2075
- assetPaths.claudeDesktopRemoteConnectorPath,
2076
- 'Claude Desktop remote connector template',
2077
- );
2078
- if (connector?.transport !== 'remote-mcp') {
2079
- throw new Error(`Claude Desktop remote connector transport must be "remote-mcp", got ${connector?.transport ?? 'missing'}.`);
2080
- }
2081
- return {
2082
- summary: 'Claude Desktop remote connector template parsed successfully.',
2083
- path: assetPaths.claudeDesktopRemoteConnectorPath,
2084
- };
2085
- });
2086
- await collectVerifyCheck(checks, 'claude_dxt_archive', async () => ({
2087
- summary: 'Claude Desktop .dxt bundle is present.',
2088
- path: assetPaths.claudeDesktopDxtPath,
2089
- size_bytes: await verifyZipFile(
2090
- assetPaths.claudeDesktopDxtPath,
2091
- 'Claude Desktop .dxt bundle',
2092
- ),
2093
- }));
2094
- await collectVerifyCheck(checks, 'claude_mcpb_archive', async () => ({
2095
- summary: 'Claude Desktop .mcpb bundle is present.',
2096
- path: assetPaths.claudeDesktopMcpbPath,
2097
- size_bytes: await verifyZipFile(
2098
- assetPaths.claudeDesktopMcpbPath,
2099
- 'Claude Desktop .mcpb bundle',
2100
- ),
2101
- }));
2102
- await collectVerifyCheck(checks, 'claude_bundle_mcp', async () => {
2103
- const probe = await probeMcpServer({
2104
- label: 'Claude Desktop bundle server',
2105
- command: process.execPath,
2106
- args: [bundleServerPath],
2107
- cwd: root,
2108
- env: {
2109
- AUDIT_CODE_REPO_ROOT: root,
2110
- AUDIT_CODE_ARTIFACTS_DIR: join(root, '.audit-artifacts'),
2111
- },
2112
- });
2113
- const toolNames = (probe.tools?.tools ?? []).map((tool) => tool.name);
2114
- if (!toolNames.includes('start_audit')) {
2115
- throw new Error('Claude Desktop bundle server did not expose the start_audit tool.');
2116
- }
2117
- return {
2118
- summary: 'Claude Desktop bundle completed an MCP handshake.',
2119
- tool_count: toolNames.length,
2120
- };
2121
- });
2122
- break;
2123
- }
2124
- case 'opencode':
2125
- await collectVerifyCheck(checks, 'opencode_config', async () => {
2126
- const config = await readJson(assetPaths.opencodeConfigPath, 'OpenCode project config');
2127
- if (config?.command?.['audit-code']) {
2128
- throw new Error('OpenCode project config must not define command["audit-code"]; the slash command is global npm-installed state. Run "audit-code install --host opencode" to remove the stale local command.');
2129
- }
2130
- if (config?.mcp?.auditor) {
2131
- throw new Error('OpenCode project config must not define mcp.auditor; the MCP server is supplied by the global npm-installed config. Run "audit-code install --host opencode" to remove the stale project-level MCP entry.');
2132
- }
2133
- assertOpenCodeAuditPermissionConfig(config?.permission, 'permission');
2134
- assertOpenCodeAuditPermissionConfig(config?.agent?.auditor?.permission, 'agent.auditor.permission');
2135
- return {
2136
- summary: 'OpenCode project config has audit permissions; MCP server and /audit-code command are supplied by the global npm-installed config.',
2137
- path: assetPaths.opencodeConfigPath,
2138
- };
2139
- });
2140
- break;
2141
- case 'vscode':
2142
- await collectVerifyCheck(checks, 'vscode_prompt', async () => {
2143
- const content = await readFile(assetPaths.vscodePromptPath, 'utf8');
2144
- if (!content.includes('name: audit-code')) {
2145
- throw new Error(`VS Code prompt file is missing the expected frontmatter name: ${assetPaths.vscodePromptPath}`);
2146
- }
2147
- const { body: promptBody } = splitFrontmatter(content);
2148
- const { body: sourceBody } = splitFrontmatter(await readFile(promptAssetPath, 'utf8'));
2149
- if (promptBody !== sourceBody.trimStart()) {
2150
- throw new Error(
2151
- `VS Code prompt body is out of sync with the source prompt. Run "audit-code install --host vscode" or "audit-code install".`,
2152
- );
2153
- }
2154
- return {
2155
- summary: 'VS Code prompt file is present and uses the source prompt body.',
2156
- path: assetPaths.vscodePromptPath,
2157
- };
2158
- });
2159
- await collectVerifyCheck(checks, 'vscode_mcp_config', async () => {
2160
- const config = await readJson(assetPaths.vscodeMcpConfigPath, 'VS Code MCP config');
2161
- const args = config?.servers?.auditor?.args;
2162
- if (config?.servers?.auditor?.command !== 'node') {
2163
- throw new Error(`VS Code MCP config must use node as the command, got ${config?.servers?.auditor?.command ?? 'missing'}.`);
2164
- }
2165
- if (!Array.isArray(args) || args[0] !== '${workspaceFolder}/.audit-code/install/run-mcp-server.mjs') {
2166
- throw new Error(`VS Code MCP config must point at \${workspaceFolder}/.audit-code/install/${MCP_LAUNCHER_FILENAME}.`);
2167
- }
2168
- return {
2169
- summary: 'VS Code MCP config parsed successfully.',
2170
- path: assetPaths.vscodeMcpConfigPath,
2171
- };
2172
- });
2173
- break;
2174
- case 'antigravity':
2175
- await collectVerifyCheck(checks, 'antigravity_skill', async () => {
2176
- const content = await readFile(assetPaths.antigravitySkillPath, 'utf8');
2177
- if (!content.includes('name: audit-code')) {
2178
- throw new Error('Antigravity skill SKILL.md must contain "name: audit-code" in frontmatter.');
2179
- }
2180
- return {
2181
- summary: 'Antigravity .agent/skills/audit-code/SKILL.md is present and valid.',
2182
- path: assetPaths.antigravitySkillPath,
2183
- };
2184
- });
2185
- await collectVerifyCheck(checks, 'antigravity_guide', async () => {
2186
- const content = await readFile(assetPaths.antigravityPlanningGuidePath, 'utf8');
2187
- if (!content.includes(MCP_LAUNCHER_FILENAME) || !content.includes(INSTALLED_PROMPT_FILENAME)) {
2188
- throw new Error(`Antigravity guide must reference both ${MCP_LAUNCHER_FILENAME} and ${INSTALLED_PROMPT_FILENAME}.`);
2189
- }
2190
- return {
2191
- summary: 'Antigravity planning guide references the repo-local prompt asset and MCP launcher.',
2192
- path: assetPaths.antigravityPlanningGuidePath,
2193
- };
2194
- });
2195
- break;
2196
- default:
2197
- checks.push({
2198
- id: 'host_handler',
2199
- status: 'error',
2200
- summary: `No verification handler is implemented for host "${hostKey}".`,
2201
- });
2201
+ const hostDefinition = INSTALL_HOST_DEFINITIONS[hostKey];
2202
+ if (hostDefinition?.verify) {
2203
+ await hostDefinition.verify({ checks, root, assetPaths, collectVerifyCheck });
2204
+ } else {
2205
+ checks.push({
2206
+ id: 'host_handler',
2207
+ status: 'error',
2208
+ summary: `No verification handler is implemented for host "${hostKey}".`,
2209
+ });
2202
2210
  }
2203
2211
 
2204
2212
  hostResults.push({
package/dist/cli.js CHANGED
@@ -112,6 +112,21 @@ function quoteCommandArg(value) {
112
112
  function renderCommand(argv) {
113
113
  return argv.map((item) => quoteCommandArg(item)).join(" ");
114
114
  }
115
+ function summarizeLaunchExit(result) {
116
+ if (result.accepted !== false && !result.error) {
117
+ return null;
118
+ }
119
+ const parts = [
120
+ result.signal
121
+ ? `signal ${result.signal}`
122
+ : `exit code ${result.exitCode ?? "unknown"}`,
123
+ result.command ? `command: ${result.command}` : null,
124
+ result.stdoutPath ? `stdout: ${result.stdoutPath}` : null,
125
+ result.stderrPath ? `stderr: ${result.stderrPath}` : null,
126
+ result.error ?? null,
127
+ ].filter((part) => Boolean(part));
128
+ return parts.join("; ");
129
+ }
115
130
  function taskResultPath(taskResultsDir, taskId) {
116
131
  return join(taskResultsDir, artifactNameForId(taskId, "json"));
117
132
  }
@@ -1548,6 +1563,12 @@ async function cmdRunToCompletion(argv) {
1548
1563
  ? outcome.reason.message
1549
1564
  : String(outcome.reason));
1550
1565
  }
1566
+ else if (outcome?.status === "fulfilled") {
1567
+ const launchExitSummary = summarizeLaunchExit(outcome.value);
1568
+ if (launchExitSummary) {
1569
+ launchErrorsByRunId.set(workerSlots[index].runId, launchExitSummary);
1570
+ }
1571
+ }
1551
1572
  }
1552
1573
  // Result ingestion is intentionally sequential even though agent launch
1553
1574
  // was parallel. Writing to coverage_matrix.json is not atomic, so
@@ -1856,8 +1877,9 @@ async function cmdRunToCompletion(argv) {
1856
1877
  }
1857
1878
  const startedAt = new Date().toISOString();
1858
1879
  let workerResult;
1880
+ let launchResult = null;
1859
1881
  try {
1860
- await provider.launch({
1882
+ launchResult = await provider.launch({
1861
1883
  repoRoot: root,
1862
1884
  runId,
1863
1885
  obligationId,
@@ -1870,9 +1892,12 @@ async function cmdRunToCompletion(argv) {
1870
1892
  timeoutMs,
1871
1893
  });
1872
1894
  const candidate = await readJsonFile(paths.resultPath);
1873
- workerResult = isWorkerResult(candidate)
1874
- ? candidate
1875
- : {
1895
+ if (isWorkerResult(candidate)) {
1896
+ workerResult = candidate;
1897
+ }
1898
+ else {
1899
+ const launchExitSummary = summarizeLaunchExit(launchResult);
1900
+ workerResult = {
1876
1901
  contract_version: WORKER_RESULT_CONTRACT_VERSION,
1877
1902
  run_id: runId,
1878
1903
  obligation_id: obligationId,
@@ -1880,13 +1905,17 @@ async function cmdRunToCompletion(argv) {
1880
1905
  progress_made: false,
1881
1906
  selected_executor: preferredExecutor,
1882
1907
  artifacts_written: [],
1883
- summary: "Worker did not emit a valid worker result.",
1908
+ summary: launchExitSummary
1909
+ ? `Worker did not emit a valid worker result after provider exit: ${launchExitSummary}`
1910
+ : "Worker did not emit a valid worker result.",
1884
1911
  next_likely_step: decision.selected_obligation,
1885
1912
  errors: ["Invalid worker result contract."],
1886
1913
  };
1914
+ }
1887
1915
  }
1888
1916
  catch (error) {
1889
1917
  const message = error instanceof Error ? error.message : String(error);
1918
+ const launchExitSummary = launchResult && summarizeLaunchExit(launchResult);
1890
1919
  workerResult = {
1891
1920
  contract_version: WORKER_RESULT_CONTRACT_VERSION,
1892
1921
  run_id: runId,
@@ -1895,9 +1924,9 @@ async function cmdRunToCompletion(argv) {
1895
1924
  progress_made: false,
1896
1925
  selected_executor: preferredExecutor,
1897
1926
  artifacts_written: [],
1898
- summary: `Worker launch failed for ${preferredExecutor}: ${message}`,
1927
+ summary: `Worker launch failed for ${preferredExecutor}: ${launchExitSummary ?? message}`,
1899
1928
  next_likely_step: decision.selected_obligation,
1900
- errors: [message],
1929
+ errors: launchExitSummary ? [message, launchExitSummary] : [message],
1901
1930
  };
1902
1931
  await persistWorkerRunArtifacts(paths, workerResult, "provider-launch");
1903
1932
  }
@@ -1,3 +1,4 @@
1
+ const MAX_RISK_SCORE = 10;
1
2
  export function buildRiskRegister(unitManifest, criticalFlows, externalAnalyzerResults) {
2
3
  const flowMap = new Map();
3
4
  for (const flow of criticalFlows?.flows ?? []) {
@@ -30,12 +31,13 @@ export function buildRiskRegister(unitManifest, criticalFlows, externalAnalyzerR
30
31
  if (externalHits > 0) {
31
32
  signals.push("external_analyzer_signal");
32
33
  }
34
+ const riskScore = (unit.risk_score ?? 0) +
35
+ flowHits +
36
+ externalHits +
37
+ (signals.includes("path_level_stateful_behavior") ? 1 : 0);
33
38
  return {
34
39
  unit_id: unit.unit_id,
35
- risk_score: (unit.risk_score ?? 0) +
36
- flowHits +
37
- externalHits +
38
- (signals.includes("path_level_stateful_behavior") ? 1 : 0),
40
+ risk_score: Math.min(MAX_RISK_SCORE, riskScore),
39
41
  signals,
40
42
  notes: [
41
43
  "Initial heuristic risk scoring.",
@@ -26,6 +26,7 @@ type ArtifactPayloadMap = {
26
26
  runtime_validation_tasks: RuntimeValidationTaskManifest;
27
27
  runtime_validation_report: RuntimeValidationReport;
28
28
  external_analyzer_results: ExternalAnalyzerResults;
29
+ syntax_resolution_status: unknown;
29
30
  audit_results: AuditResult[];
30
31
  audit_tasks: AuditTask[];
31
32
  audit_plan_metrics: AuditPlanMetrics;
@@ -63,6 +64,7 @@ export declare const ARTIFACT_DEFINITIONS: {
63
64
  readonly runtime_validation_tasks: ArtifactDefinition<"runtime_validation_tasks">;
64
65
  readonly runtime_validation_report: ArtifactDefinition<"runtime_validation_report">;
65
66
  readonly external_analyzer_results: ArtifactDefinition<"external_analyzer_results">;
67
+ readonly syntax_resolution_status: ArtifactDefinition<"syntax_resolution_status">;
66
68
  readonly audit_results: ArtifactDefinition<"audit_results">;
67
69
  readonly audit_tasks: ArtifactDefinition<"audit_tasks">;
68
70
  readonly audit_plan_metrics: ArtifactDefinition<"audit_plan_metrics">;
@@ -40,6 +40,7 @@ export const ARTIFACT_DEFINITIONS = {
40
40
  runtime_validation_tasks: jsonArtifact("runtime_validation_tasks.json", "execution"),
41
41
  runtime_validation_report: jsonArtifact("runtime_validation_report.json", "execution"),
42
42
  external_analyzer_results: jsonArtifact("external_analyzer_results.json", "execution"),
43
+ syntax_resolution_status: jsonArtifact("syntax_resolution_status.json", "execution"),
43
44
  audit_results: ndjsonArtifact("audit_results.jsonl", "execution"),
44
45
  audit_tasks: jsonArtifact("audit_tasks.json", "execution"),
45
46
  audit_plan_metrics: jsonArtifact("audit_plan_metrics.json", "execution"),
@@ -1,2 +1,3 @@
1
1
  import type { ToolingManifest } from "../types/toolingManifest.js";
2
+ export declare const TOOLING_INPUTS: readonly ["audit-code.mjs", "audit-code-wrapper-lib.mjs", "package.json", "dist", "schemas", "skills/audit-code"];
2
3
  export declare function buildToolingManifest(): Promise<ToolingManifest>;
@@ -3,7 +3,7 @@ import { readdir, readFile, stat } from "node:fs/promises";
3
3
  import { dirname, join, relative, resolve } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
6
- const TOOLING_INPUTS = [
6
+ export const TOOLING_INPUTS = [
7
7
  "audit-code.mjs",
8
8
  "audit-code-wrapper-lib.mjs",
9
9
  "package.json",
@@ -1 +1,72 @@
1
+ interface ServerOptions {
2
+ root: string;
3
+ artifactsDir: string;
4
+ }
5
+ interface JsonRpcRequest {
6
+ jsonrpc?: string;
7
+ id?: string | number | null;
8
+ method?: string;
9
+ params?: Record<string, unknown>;
10
+ }
11
+ interface JsonRpcResponse {
12
+ jsonrpc: "2.0";
13
+ id: string | number | null;
14
+ result?: unknown;
15
+ error?: {
16
+ code: number;
17
+ message: string;
18
+ data?: unknown;
19
+ };
20
+ }
21
+ interface ToolCallContext {
22
+ root: string;
23
+ artifactsDir: string;
24
+ }
25
+ export declare function parseContentLength(headerBlock: string): number;
26
+ interface ResourceRegistryEntry {
27
+ uri: string;
28
+ name: string;
29
+ description: string;
30
+ mimeType: string;
31
+ read: (context: ToolCallContext) => Promise<{
32
+ mimeType: string;
33
+ text: string;
34
+ }>;
35
+ }
36
+ export declare const resourceRegistry: ResourceRegistryEntry[];
37
+ interface PromptRegistryEntry {
38
+ name: string;
39
+ description: string;
40
+ arguments: Array<{
41
+ name: string;
42
+ required?: boolean;
43
+ description: string;
44
+ }>;
45
+ render: (args: Record<string, unknown> | undefined) => string;
46
+ }
47
+ export declare const promptRegistry: PromptRegistryEntry[];
48
+ /**
49
+ * Extract zero or more complete Content-Length framed messages from a buffer.
50
+ * Returns an array of parsed body strings and the remaining unconsumed buffer.
51
+ * On framing errors, emits a framing error response via `emit` and resets the buffer.
52
+ */
53
+ export declare function extractFrames(buffer: Buffer, emit: (response: JsonRpcResponse) => void): {
54
+ bodies: string[];
55
+ remaining: Buffer<ArrayBufferLike>;
56
+ };
57
+ interface DispatchContext {
58
+ version: string;
59
+ defaults: ServerOptions;
60
+ shutdownRequested: boolean;
61
+ }
62
+ /**
63
+ * Dispatch a single JSON-RPC request and return the response(s) to send,
64
+ * plus updated shutdown state.
65
+ */
66
+ export declare function dispatchRequest(request: JsonRpcRequest, ctx: DispatchContext): Promise<{
67
+ responses: JsonRpcResponse[];
68
+ shutdownRequested: boolean;
69
+ exit?: number;
70
+ }>;
1
71
  export declare function runAuditCodeMcpServer(argv: string[]): Promise<void>;
72
+ export {};