mirror of
https://github.com/morluto/rea
synced 2026-10-25 22:08:11 -04:00
fix(discovery): use contract prerequisites and provider effects
This commit is contained in:
@@ -558,7 +558,14 @@ should expand `tool_availability.groups` and use `tools/list` for schemas. The
|
||||
same catalog identity summary is returned by CLI `capabilities` and `providers`;
|
||||
MCP tool definitions remain available through `tools/list`.
|
||||
|
||||
Provider capabilities are grouped by provider identity and shared facts. In each
|
||||
Provider capabilities are grouped by provider identity and shared facts.
|
||||
Tool families group discovery; they do not imply an active-binary prerequisite.
|
||||
Contracts whose handlers dispatch through that session declare it explicitly.
|
||||
Cutter, GDB and Rizin debugger tools use their independent session/input owners,
|
||||
so discovery does not ask them to open an unrelated binary. Session tool effects
|
||||
also retain the applicable provider composition's UI, process, network and
|
||||
filesystem declarations; for example, attached IDA navigation may show UI while
|
||||
a headless profile launches a worker. In each
|
||||
set, `shared_limitations` is the ordered common prefix; append a group's ordered
|
||||
`limitations` suffix to recover each operation's exact limitations. Group
|
||||
`effects` arrays use the same true-only closed-vocabulary rule as tool
|
||||
|
||||
@@ -5,6 +5,8 @@ import {
|
||||
buildCapabilityInventory,
|
||||
compactToolAvailability,
|
||||
} from "./CapabilityInventory.js";
|
||||
import { idaCapabilities } from "../ida/IdaProviderCapabilities.js";
|
||||
import { providerCapabilitySets } from "./binary/BinarySessionStatus.js";
|
||||
import { TOOL_CONTRACTS } from "../contracts/toolContracts.js";
|
||||
import {
|
||||
expandToolAvailability,
|
||||
@@ -843,3 +845,57 @@ it.each(["darwin", "linux", "win32"])(
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
it("keeps independent native sessions discoverable without an unrelated binary target", () => {
|
||||
const entries = buildCapabilityInventory(status(), enabledPolicy);
|
||||
for (const name of [
|
||||
"list_cutter_sessions",
|
||||
"cutter_command",
|
||||
"start_gdb_session",
|
||||
"gdb_command",
|
||||
"gdb_session_status",
|
||||
"close_gdb_session",
|
||||
"start_rizin_debug_session",
|
||||
"rizin_debug_command",
|
||||
"rizin_debug_session_status",
|
||||
"close_rizin_debug_session",
|
||||
"inspect_with_objdump",
|
||||
"execute_rizin_command",
|
||||
]) {
|
||||
expect(
|
||||
entries.find((entry) => entry.name === name),
|
||||
name,
|
||||
).toMatchObject({ available: true });
|
||||
}
|
||||
expect(entries.find((entry) => entry.name === "inspect_macho")).toMatchObject(
|
||||
{ available: false, reason: "target_required" },
|
||||
);
|
||||
});
|
||||
|
||||
it.each([false, true])(
|
||||
"retains selected provider UI/process/network effects in direct and composed discovery (UI=%s)",
|
||||
(showUi) => {
|
||||
const input = {
|
||||
open: true,
|
||||
kind: "executable",
|
||||
capabilities: providerCapabilitySets(
|
||||
idaCapabilities(showUi ? "attached" : "headless", false),
|
||||
),
|
||||
};
|
||||
const entries = buildCapabilityInventory(input, enabledPolicy);
|
||||
for (const name of [
|
||||
"procedure_pseudo_code",
|
||||
"analyze_function",
|
||||
"batch_decompile",
|
||||
]) {
|
||||
expect(entries.find((entry) => entry.name === name)).toMatchObject({
|
||||
effects: {
|
||||
changesUiState: showUi,
|
||||
accessesNetwork: true,
|
||||
launchesProcess: !showUi,
|
||||
},
|
||||
annotations: { open_world: true },
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -25,6 +25,10 @@ import {
|
||||
type ToolAvailabilityMode,
|
||||
type ToolUnavailabilityReason,
|
||||
} from "../contracts/toolOutputSchemaPrimitives.js";
|
||||
import {
|
||||
annotationsFromEffects,
|
||||
type ToolEffects,
|
||||
} from "../contracts/toolEffects.js";
|
||||
import type { ToolKind } from "../contracts/toolContractTypes.js";
|
||||
import type { JsonValue } from "../domain/jsonValue.js";
|
||||
import { isMachOFormat } from "../domain/binaryTargetTypes.js";
|
||||
@@ -34,7 +38,6 @@ import type {
|
||||
} from "./AnalysisProvider.js";
|
||||
import type { JebAnalysisAvailability } from "./jeb/JebAnalysisPort.js";
|
||||
import { TOOL_CONTRACTS } from "../contracts/toolContracts.js";
|
||||
import { FRIDA_TOOL_CONTRACTS } from "../contracts/fridaToolContracts.js";
|
||||
import {
|
||||
clientRequirementsFor,
|
||||
NO_CLIENT_FEATURES,
|
||||
@@ -121,6 +124,7 @@ type AvailabilityContext = {
|
||||
readonly name: string;
|
||||
readonly kind: ToolKind;
|
||||
readonly targetOpen: boolean;
|
||||
readonly requiresActiveTarget: boolean;
|
||||
readonly targetKind:
|
||||
| "executable"
|
||||
| "database"
|
||||
@@ -212,17 +216,6 @@ const ENHANCED_REQUIREMENTS: ReadonlyMap<string, ProviderComposition> = new Map(
|
||||
} satisfies Readonly<Record<EnhancedContractName, ProviderComposition>>),
|
||||
);
|
||||
|
||||
/** Contract kinds whose operations run on the active session target. */
|
||||
const ACTIVE_TARGET_KINDS: ReadonlySet<ToolKind> = new Set([
|
||||
"official-proxy",
|
||||
"enhanced",
|
||||
"native-provider",
|
||||
"artifact-provider",
|
||||
]);
|
||||
const FRIDA_OPERATION_NAMES: ReadonlySet<string> = new Set(
|
||||
FRIDA_TOOL_CONTRACTS.map(({ name }) => name),
|
||||
);
|
||||
|
||||
/** Native contracts defined only for an active Mach-O executable. */
|
||||
const MACHO_TARGET_OPERATIONS: ReadonlySet<string> = new Set([
|
||||
"inspect_signature",
|
||||
@@ -263,6 +256,9 @@ export const buildCapabilityInventory = (
|
||||
name: contract.name,
|
||||
kind: contract.kind,
|
||||
targetOpen: status.open,
|
||||
requiresActiveTarget:
|
||||
"requiresActiveTarget" in contract &&
|
||||
contract.requiresActiveTarget === true,
|
||||
targetKind: status.kind,
|
||||
targetFormat: status.format,
|
||||
descriptors,
|
||||
@@ -273,6 +269,12 @@ export const buildCapabilityInventory = (
|
||||
clientFeatures,
|
||||
);
|
||||
const clientBlocked = clientRequirements.missing_required.length > 0;
|
||||
const effects = composedEffects(
|
||||
contract.name,
|
||||
contract.effects,
|
||||
status.capabilities,
|
||||
);
|
||||
const annotations = annotationsFromEffects(effects);
|
||||
const facts = {
|
||||
name: contract.name,
|
||||
surface: contract.kind,
|
||||
@@ -283,12 +285,12 @@ export const buildCapabilityInventory = (
|
||||
? {}
|
||||
: { modes: [...availability.modes] }),
|
||||
client_requirements: clientRequirements,
|
||||
effects: { ...contract.effects },
|
||||
effects,
|
||||
annotations: {
|
||||
read_only: contract.annotations.readOnlyHint ?? false,
|
||||
destructive: contract.annotations.destructiveHint ?? false,
|
||||
idempotent: contract.annotations.idempotentHint ?? false,
|
||||
open_world: contract.annotations.openWorldHint ?? true,
|
||||
read_only: annotations.readOnlyHint,
|
||||
destructive: annotations.destructiveHint,
|
||||
idempotent: annotations.idempotentHint,
|
||||
open_world: annotations.openWorldHint,
|
||||
},
|
||||
};
|
||||
if (clientBlocked)
|
||||
@@ -733,10 +735,10 @@ const targetAvailability = ({
|
||||
targetKind,
|
||||
targetFormat,
|
||||
targetOpen,
|
||||
requiresActiveTarget,
|
||||
descriptors,
|
||||
}: AvailabilityContext): Availability | null => {
|
||||
if (FRIDA_OPERATION_NAMES.has(name)) return null;
|
||||
if (!targetOpen && ACTIVE_TARGET_KINDS.has(kind))
|
||||
if (!targetOpen && requiresActiveTarget)
|
||||
return {
|
||||
reason: "target_required",
|
||||
remediation: "Call open_binary with a supported local target.",
|
||||
@@ -978,3 +980,39 @@ const availabilityFailurePriority = (
|
||||
return 3;
|
||||
}
|
||||
};
|
||||
|
||||
/** Use the same composition requirements as availability when exposing provider effects. */
|
||||
const composedEffects = (
|
||||
name: string,
|
||||
base: ToolEffects,
|
||||
descriptors: readonly ProviderDescriptor[],
|
||||
): ToolEffects => {
|
||||
const composition: ProviderComposition | undefined =
|
||||
name === "get_navigation_context"
|
||||
? { modes: NAVIGATION_CONTEXT_MODES }
|
||||
: ENHANCED_REQUIREMENTS.get(name);
|
||||
const requirements: CompositionRequirements =
|
||||
composition === undefined
|
||||
? []
|
||||
: "modes" in composition
|
||||
? composition.modes.flatMap(({ requirements }) => requirements)
|
||||
: composition;
|
||||
const operations = new Set<string>([
|
||||
name,
|
||||
...requirements.flatMap((group) =>
|
||||
typeof group === "string" ? [group] : group,
|
||||
),
|
||||
]);
|
||||
const effects = { ...base };
|
||||
for (const descriptor of descriptors) {
|
||||
if (!operations.has(descriptor.operation)) continue;
|
||||
const source = descriptor.effects;
|
||||
effects.mutatesTarget ||= source.mutates_artifact;
|
||||
effects.launchesProcess ||= source.launches_process;
|
||||
effects.changesUiState ||= source.may_show_ui;
|
||||
effects.accessesNetwork ||= source.may_access_network;
|
||||
effects.writesFilesystem ||=
|
||||
source.may_write_filesystem || source.changes_permissions;
|
||||
}
|
||||
return effects;
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@ export const INSPECT_APK_SIGNATURE_CONTRACT = {
|
||||
name: "inspect_apk_signature",
|
||||
...toolContractMetadata("inspect_apk_signature"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect declared v1/v2/v3/v3.1 APK signers, certificate fingerprints, algorithm IDs, content digests, SDK ranges, rotation lineage and source stamp without executing Android code. SHA-256 identifies the exact local file. Summary retains complete Evidence; an optional view selects signers/digests/lineage using stable IDs, scheme or signer-ID batches, fields and paging. Read retained pages with inspect_analysis_view kind apk-signature after the source is removed. IDs include artifact digest, scheme and source ordinal; certificates retain raw-DER SHA-256. Content-digest equality is not cryptographic signature verification: modified declarations can match modified bytes. Authenticity, signatures, lineage trust and v1 entry coverage remain unverified. Malformed structures and resource refusals are explicit; no device, network or SDK is used by REA.",
|
||||
inputSchema: inspectApkSignatureInputSchema,
|
||||
|
||||
@@ -65,6 +65,7 @@ const artifact = <
|
||||
...toolContractMetadata(name),
|
||||
description,
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
inputSchema,
|
||||
outputSchema,
|
||||
examples: [
|
||||
|
||||
@@ -14,6 +14,7 @@ export const CAPTURE_TOOL_CONTRACTS = [
|
||||
name: "inspect_packet_fields",
|
||||
...toolContractMetadata("inspect_packet_fields"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Discover protocols or field names/types registered in the installed TShark 4.x. kind defaults to protocols; use fields and optional exact protocol abbreviation to select field definitions. query searches name/abbreviation/description by case-insensitive literal substring using Unicode simple case folding. Return 50 matches by default with offset/limit paging; null requests all remaining within resource limits. Preserve type/base/bitmask/description, duplicate registrations, source line numbers, coverage, tool identity and diagnostics. Linux, TShark 4.x (PATH or absolute REA_TSHARK_COMMAND) and prlimit required. No capture file, interface or binary target needed. Registrations describe tool capabilities, not observed traffic. Each call rereads the glossary; use selected fields with inspect_packet_capture.",
|
||||
inputSchema: inspectPacketFieldsInputSchema,
|
||||
@@ -30,6 +31,7 @@ export const CAPTURE_TOOL_CONTRACTS = [
|
||||
name: "inspect_packet_capture",
|
||||
...toolContractMetadata("inspect_packet_capture"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect caller-selected fields in an existing local packet capture with TShark 4.x. Return 50 matching frames by default, with match_offset/match_limit paging and coverage counts; match_limit:null requests all remaining matches. Preserve repeated values, frame numbers, display filter, decode-as rules and pass mode in inline Evidence with source/tool identity and diagnostics. Optional packet_limit counts input packets before filtering; output paging does not shorten dissection or two-pass reassembly. Requires Linux, util-linux prlimit, and TShark 4.x on PATH or through absolute REA_TSHARK_COMMAND. File-only analysis; no live capture or device communication. Missing fields or no matches do not establish absence of device traffic.",
|
||||
inputSchema: inspectPacketCaptureInputSchema,
|
||||
|
||||
@@ -14,6 +14,7 @@ export const DESKTOP_APPLICATION_TOOL_CONTRACTS = [
|
||||
name: "inspect_desktop_application",
|
||||
...toolContractMetadata("inspect_desktop_application"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect a local desktop application directory using bounded listings, file headers and selected metadata. Returns .NET, Unity Mono/IL2CPP, Unreal, Godot, GameMaker and Electron candidates, supporting paths/range hashes, component path markers and concrete next probes. No target execution, extraction, network or target changes. Default summary retains complete Evidence for inspect_analysis_view kind desktop-application; collections files/candidates/components/next_probes support paging and field selection, with exact file paths or candidate families. detail complete returns every retained fact inline. Snapshot identity covers examined metadata/read ranges, not all file contents; coverage and unavailable probes remain explicit.",
|
||||
inputSchema: inspectDesktopApplicationInputSchema.extend({
|
||||
|
||||
@@ -18,6 +18,7 @@ const enhanced = <Name extends string, Schema extends z.ZodObject>(
|
||||
...toolContractMetadata(name),
|
||||
description,
|
||||
kind: "enhanced",
|
||||
requiresActiveTarget: true,
|
||||
inputSchema,
|
||||
outputSchema: requireOutputSchema(enhancedOutputSchemas, name),
|
||||
examples: examplesFor(name, inputSchema),
|
||||
|
||||
@@ -12,6 +12,7 @@ export const ERLANG_BEAM_TOOL_CONTRACTS = [
|
||||
name: "inspect_erlang_beam",
|
||||
...toolContractMetadata("inspect_erlang_beam"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect one explicit local Erlang BEAM IFF container without executing bytecode or installing Erlang. Returns FOR1 form bounds, chunk names, payload SHA-256, Atom/AtU8 names, export/import/lambda tables with resolved atom names when present, and the Code chunk instruction-set header. Missing optional tables stay null rather than empty-everywhere. Reads a stable regular file; malformed FOR1/BEAM headers, truncated chunks and exhausted budgets return no partial success. Portable on supported Node hosts; no BEAM emulator is required.",
|
||||
inputSchema: inspectErlangBeamInputSchema,
|
||||
|
||||
@@ -22,6 +22,7 @@ export const INSPECT_EVM_INTERFACE_CONTRACT = {
|
||||
name: "inspect_evm_interface",
|
||||
...toolContractMetadata("inspect_evm_interface"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
'Inspect explicit local flat EVM bytecode without target execution or chain/RPC access. Select raw or hex encoding explicitly. Omitted or complete detail returns original carrier and decoded identities, full bytecode and all inferred interface candidates inline. For all inferred selectors/offsets/arguments/mutability and identities without bytecode hex or duplicated stdout, select detail: "summary" on this first call: it retains unchanged complete Evidence and returns a distinct linked inspect_analysis_view summary. Read original function rows or bytecode_hex/stdout/stderr text pages using view kind evm and normalized_result.parent_evidence_id; original complete Evidence remains accessible. Bytecode kind, hardfork, deployed authenticity and discovery completeness stay unknown; summary coverage covers only producer-returned candidates. Unchanged bundled EVMole 0.9.3/WASM in an owned bounded worker is initially real-verified on Linux x64; EOF-style EF00 containers are unsupported. Adjust timeout_ms (default 30000 ms, integer 1..2147483647) for the owned worker command on the next call; omitted timeout_ms keeps 30000 ms. Fixed byte, address-space, and CPU allowances stay unchanged. No signature lookup, wallet action or transaction broadcast.',
|
||||
inputSchema: evmInterfaceInspectionInputSchema,
|
||||
|
||||
@@ -19,6 +19,7 @@ const functionWorkflow = <Name extends FunctionWorkflowName>(
|
||||
...toolContractMetadata(name),
|
||||
description,
|
||||
kind: "enhanced",
|
||||
requiresActiveTarget: true,
|
||||
inputSchema,
|
||||
outputSchema,
|
||||
examples: [
|
||||
|
||||
@@ -13,6 +13,7 @@ export const GO_TOOL_CONTRACTS = [
|
||||
name: "inspect_go_binary",
|
||||
...toolContractMetadata("inspect_go_binary"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect embedded Go compiler version, main module, dependency/replacement versions and build settings in an explicit local ELF, PE or thin Mach-O image, or the slice of a universal Mach-O named by architecture (read without lipo; artifact stays the universal file, selected_slice records the slice and source ranges stay file offsets). Default detail complete returns original artifact SHA-256, exact build-info source ranges, raw framed module bytes and unparsed module-text lines inline as observed Evidence. Explicit detail summary retains the same complete parent and returns compiler/main-module identity, counts, source ranges and parent_evidence_id. Query retained rows through inspect_analysis_view kind go, collection dependencies or settings; select exact dependency paths or setting keys, indices, fields and pagination. Rows always retain their original index scoped to the parent Evidence; empty filters select none. Runtime dependency completeness remains unknown. Supports inline and historical pointer encodings without installing Go, opening a disassembler, executing the target, writing temporary files or accessing the network. Missing metadata is reported as unknown, not proof that an image is not Go. Does not recover functions, source mappings, types or runtime behavior. Resource guards bound files to 256 MiB and charge each distinct build-info search span in full against a cumulative 256 MiB header-search budget, with partial overlaps charged separately; they also bound aggregate embedded strings to 1 MiB, structural table decoding to 16 MiB and complete inline metadata to 8 MiB; malformed, unsupported and oversized inputs receive typed failures rather than partial success.",
|
||||
inputSchema: inspectGoBinaryInputSchema,
|
||||
|
||||
@@ -15,6 +15,7 @@ export const GPU_TOOL_CONTRACTS = [
|
||||
name: "inspect_gpu_code_objects",
|
||||
...toolContractMetadata("inspect_gpu_code_objects"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect static CUDA/HIP GPU code objects in local ELF/PE hosts, CUDA fatbins, CUBIN, PTX and Clang HIP bundles (CUDA LZ4/Zstd and CCOB v1/v2/v3 zlib/Zstd). Default inventory reads directories; full-file SHA-256 always streams every byte. analysis kernels decodes only selected object_ids/targets (object_ids require expected_sha256 from their inventory), retaining all inventory rows and explicit partial/unknown states. Reports PTX virtual registers, CUBIN physical registers/nv.info parameters/shared memory and AMDGPU MessagePack kernel declarations separately. No GPU tools, target execution, network, SASS disassembly or host launch correlation. Unsupported CUDA compression retains encoded locations. Default summary retains complete Evidence; optional view returns a selected targets/objects/kernels page or PTX text page in this call. inspect_analysis_view kind gpu-code-objects reuses retained facts without reopening files; PTX text uses UTF-16 code-unit pages. Object IDs are positional within artifact.sha256. One active inspection; 128 MiB/object, 512 MiB decoded work, 16 MiB retained facts. Full Evidence includes selected PTX text artifacts with SHA-256 and encoded/decoded provenance.",
|
||||
inputSchema: inspectGpuCodeObjectsInputSchema,
|
||||
|
||||
@@ -14,6 +14,7 @@ export const IL2CPP_TOOL_CONTRACTS = [
|
||||
name: "inspect_il2cpp_metadata",
|
||||
...toolContractMetadata("inspect_il2cpp_metadata"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect local Unity IL2CPP metadata (24/27/29/31/39), optionally linking a caller-selected 64-bit little-endian Mach-O, PE or ELF binary. Static reading only. Default summary retains complete Evidence; use parent_evidence_id with inspect_analysis_view kind il2cpp-metadata for named collections, indices, fields and paging. Parameters accept method_indices; method_addresses accept addresses and states. Stable row indices are scoped to the metadata digest; native pages also identify the binary. Native states distinguish executable code, observed zero slots (no-body), and unknown owners/relocations. Shared addresses preserve all methods. code_gen_modules pages accept image_indices; summaries omit that table. Type names are C#-like; version27 retains indices with unknown names. Unrequested native counts are null. Static-table links are derived; the x86-64 executable-byte fallback is inferred and does not verify instruction boundaries. Input guards:256MiB metadata/1GiB binary;64MiB encoded report; one active inspection. Unsupported layouts, pointer encodings and resource limits have typed reasons. Full Evidence remains available with detail complete. Neither static linking nor structural agreement proves runtime behavior or a same-build pair.",
|
||||
inputSchema: inspectIl2cppMetadataInputSchema,
|
||||
|
||||
@@ -167,6 +167,7 @@ export const ELECTRON_TOOL_CONTRACTS = [
|
||||
name: "inspect_electron_fuses",
|
||||
...toolContractMetadata("inspect_electron_fuses"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect packaged Electron fuse bytes in one local macOS app bundle, Electron Framework binary, Windows PE executable, or Linux ELF executable. Returns the artifact digest, per-slice wire version, fuse index, version-1 name, state, and raw byte, plus derived implications for Inspector flags, ELECTRON_RUN_AS_NODE, embedded ASAR integrity, and app.asar-only loading. A missing sentinel is unknown fuse state. Reads artifact bytes only and does not modify the selected file or open a runtime target.",
|
||||
inputSchema: inspectElectronFusesInputSchema,
|
||||
|
||||
@@ -14,6 +14,7 @@ export const MODEL_TOOL_CONTRACTS = [
|
||||
name: "inspect_model_artifact",
|
||||
...toolContractMetadata("inspect_model_artifact"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect local GGUF v2/v3 or safetensors declarations by content, without loading models or executing code. Default hash header reads only the header: full-file SHA-256 and Evidence subject are unknown; artifact.header_sha256 is a scoped prefix commitment, not weight identity. hash full additionally streams all file bytes for SHA-256. Optional view returns a selected metadata/tensor/type page plus model context in this call. Summary retains complete Evidence for inspect_analysis_view kind model-artifact, collection metadata (keys/indices/fields) or tensors (names/types/indices/fields), with stable header-scoped indices and paging. Metadata arrays retain eight-element typed previews; scalar metadata is complete. Tensor counts, shapes, numeric type IDs and offsets are observed; textual types and parameter/storage totals use established format facts. Unknown or historically ambiguous GGUF types retain IDs with unknown nonempty byte lengths; ambiguous identities use AMBIGUOUS_<id> labels. Unresolved Q8_1 and K-block layouts also keep nonempty byte lengths unknown. Tensor payload, model behavior and inference quality are not inspected. One active inspection, 100 MB header ceiling and 32 MiB retained-facts budget; resource refusals are explicit. No network, external files, Python, model runtime, extraction or deserialization of pickle.",
|
||||
inputSchema: inspectModelArtifactInputSchema,
|
||||
|
||||
@@ -53,6 +53,7 @@ const native = <Name extends string, Schema extends z.ZodObject>(
|
||||
...toolContractMetadata(name),
|
||||
description,
|
||||
kind: "native-provider",
|
||||
requiresActiveTarget: true,
|
||||
inputSchema: strictInputSchema,
|
||||
outputSchema,
|
||||
examples: [
|
||||
|
||||
@@ -33,6 +33,7 @@ const official = <Name extends string, Schema extends z.ZodObject>(
|
||||
...toolContractMetadata(name),
|
||||
description,
|
||||
kind: "official-proxy",
|
||||
requiresActiveTarget: true,
|
||||
inputSchema: strictInputSchema,
|
||||
outputSchema: requireOutputSchema(officialOutputSchemas, name),
|
||||
examples: examplesFor(name, strictInputSchema),
|
||||
|
||||
@@ -12,6 +12,7 @@ export const PYTHON_PYC_TOOL_CONTRACTS = [
|
||||
name: "inspect_python_pyc",
|
||||
...toolContractMetadata("inspect_python_pyc"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect one explicit local CPython 3.7–3.13 .pyc file with a supported 16-byte header without executing bytecode, invoking CPython or recovering source. Returns the header (magic, pinned python_version, PEP 552 flags, source hash or mtime/size), the top-level code object with nested functions, names, const summaries, and bytecode length/SHA-256. Marshal is walked with object, depth and string budgets; unsupported magics/layouts, truncated streams and exhausted budgets return no partial success. A decoded header is not proof the matching .py is present. Portable on supported Node hosts; no Python installation required.",
|
||||
inputSchema: inspectPythonPycInputSchema,
|
||||
|
||||
@@ -15,6 +15,7 @@ export const RUST_TOOL_CONTRACTS = [
|
||||
name: "inspect_rust_binary",
|
||||
...toolContractMetadata("inspect_rust_binary"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect the cargo-auditable crate dependency list embedded in an explicit local ELF, PE or thin Mach-O image, or the slice of a universal Mach-O named by architecture (read without lipo; artifact stays the universal file, selected_slice records the slice and offsets stay file offsets). Returns the artifact SHA-256, the .dep-v0 section file offset and size, compressed and uncompressed sizes, format version, packages in their original order, the root package index, and dependency edges by index. Omitted or explicit complete detail preserves the full report. Optional detail summary retains that complete Evidence and returns source ranges, counts and parent_evidence_id. Optional view directly selects packages or edges in this call; it cannot be combined with explicit complete detail. Query the same retained facts with inspect_analysis_view kind rust: exact names/versions or package indices, edge from_indices/to_indices, fields and matching-row pagination. Row indices are original and scoped to the parent Evidence; empty filters select none. Default package fields omit dependency vectors; explicitly select dependencies for direct index references. Every matching observed version is retained. No current runtime state is inferred from historical reads. Reads zlib-compressed JSON without installing Rust, opening a disassembler, executing the target, writing temporary files or accessing the network. A missing section is null metadata with a limitation and is not proof that the binary has no dependencies. A rustc commit hash is reported only as an inference when a /rustc/<40-hex>/ path is present in read-only data. Resource guards bound files to 256 MiB, compressed dependency streams to 1 MiB, inflated JSON to the smaller of 8 MiB and 64 times the consumed compressed-stream length, and the complete report to 8 MiB. Malformed, unsupported and oversized inputs receive typed failures rather than partial success.",
|
||||
inputSchema: inspectRustBinaryRequestSchema,
|
||||
|
||||
@@ -14,6 +14,7 @@ export const SIGNAL_TOOL_CONTRACTS = [
|
||||
name: "inspect_signal_decoders",
|
||||
...toolContractMetadata("inspect_signal_decoders"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Discover installed sigrok protocol decoders or inspect one decoder's channel/option help on Linux. Omit decoder to list ID/name pairs; supply its exact ID for literal help lines with source line numbers. query is a case-insensitive literal substring using Unicode simple case folding; catalog queries match the ID or name independently. Page matches with offset/limit (default 50; null returns all remaining). Reports tool identity, version, diagnostics and examined/matching coverage. Uses configured REA_SIGROK_COMMAND and prlimit; no recording, binary target, hardware scan or acquisition. Each call probes again; decoder modules are trusted, not fully fingerprinted. Use returned IDs/options with decode_signal_recording.",
|
||||
inputSchema: inspectSignalDecodersInputSchema,
|
||||
@@ -30,6 +31,7 @@ export const SIGNAL_TOOL_CONTRACTS = [
|
||||
name: "decode_signal_recording",
|
||||
...toolContractMetadata("decode_signal_recording"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Decode an existing local logic/signal recording on Linux with sigrok-cli 0.7.2 and util-linux prlimit. Supply decoder stack, channels and options explicitly; optionally select input format and annotation classes. Return 50 literal output lines by default, with line_offset/line_limit paging; line_limit:null requests all remaining lines. Output windows count display lines, not annotations or samples, and do not shorten decoding. Preserve selected text, sample ranges, stderr, source/tool identity and coverage inline. Configure absolute REA_SIGROK_COMMAND. File-only analysis; no hardware acquisition or device communication. Empty output does not prove absence of traffic.",
|
||||
inputSchema: decodeSignalRecordingInputSchema,
|
||||
|
||||
@@ -12,6 +12,7 @@ export const SQLITE_TOOL_CONTRACTS = [
|
||||
name: "inspect_sqlite_database",
|
||||
...toolContractMetadata("inspect_sqlite_database"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
"Inspect an explicit local SQLite database snapshot and its existing sibling WAL without modifying source files or opening a native analysis provider. Requires Node.js 24.x >=24.15 or 26+ with native DatabaseSync.limits support, checked by the worker. Returns observed Evidence with database/WAL SHA-256 and a compact schema inventory. Selecting an exact ordinary table expands only its schema and samples rows (default 20, subject to byte and worker resource limits). Select exact columns in the requested order to avoid unrelated or large values; schema_scope=database explicitly expands the whole schema; returned rows retain 64-bit integers, text bytes and blobs with explicit truncation. Adjust worker_timeout_ms (default 30000 ms) for worker startup, queries and reply writing; allow separate client headroom for snapshot acquisition, reply reads, cleanup and delivery. The result retains the actual budget; byte/heap safety limits stay fixed. No arbitrary SQL, view or virtual-table execution, extension loading, database repair, encryption support or live-snapshot atomicity claim. At most two inspections per provider are admitted; occupied capacity is retryable. An isolated temporary copy and owned worker enforce input, value/record, SQL-statement, JSON-reply, JavaScript-heap and deadline limits; overall native heap is not capped. Supply a quiescent snapshot for coherent database/WAL evidence.",
|
||||
inputSchema: inspectSqliteDatabaseInputSchema,
|
||||
|
||||
@@ -55,6 +55,8 @@ export interface ToolContract<
|
||||
readonly title: string;
|
||||
readonly description: string;
|
||||
readonly kind: ToolKind;
|
||||
/** This handler dispatches through the active binary-analysis session. */
|
||||
readonly requiresActiveTarget?: boolean;
|
||||
readonly inputSchema: InputSchema;
|
||||
readonly outputSchema: OutputSchema;
|
||||
readonly effects: ToolEffects;
|
||||
|
||||
@@ -21,6 +21,7 @@ export const INSPECT_WASM_ARTIFACT_CONTRACT = {
|
||||
name: "inspect_wasm_artifact",
|
||||
...toolContractMetadata("inspect_wasm_artifact"),
|
||||
kind: "artifact-provider",
|
||||
requiresActiveTarget: true,
|
||||
description:
|
||||
'Validate an explicit local WASM artifact with caller-supplied WABT 1.0.42. Optional custom-section interpretation errors do not invalidate the core module; warnings and name-section interpretation status remain in the result. Omitted or complete detail returns exact byte SHA-256, sections, upstream import/export WAT forms and decoded WAT inline as Evidence. For counts, validation and WAT identity without WAT text, pass detail: "summary" on this first call; it retains the complete original Evidence and returns the same typed summary as inspect_analysis_view, avoiding oversized complete delivery. Read exact imports/exports or WAT pages with inspect_analysis_view using normalized_result.parent_evidence_id. Delivery selection does not change analysis, provider inputs or source identity. Adjust command_timeout_ms for each WABT command (default 30000 ms), separately from the client deadline; input/output safety limits stay fixed. Optionally associate selected JavaScript glue literals with explicit local candidates while preserving ambiguous URL/basename matches. Configure absolute REA_WABT_BIN_DIRECTORY. No installation, implicit fetch, WASM execution or original-source claim.',
|
||||
inputSchema: wasmArtifactInspectionInputSchema,
|
||||
|
||||
Reference in New Issue
Block a user