When unittest discover processes skills/binary-analysis/tests/ before
tests/, the integration package gets cached in sys.modules from the
first discover call. Later discover calls reuse the cached package
which doesn't contain the expected test modules, causing spurious
ModuleNotFoundError failures.
Fix: snapshot and restore sys.modules between discover iterations.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
The __init__.py approach does not work with unittest discover because
__init__.py files are not guaranteed to execute before test modules.
Add explicit sys.path setup using parents[2] to resolve the scripts
directory at the top of every test file that imports binary_analysis.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
unittest discover loads test modules without importing the tests package,
so tests/__init__.py is never loaded. Add sys.path.insert to every
sub-package __init__.py (contract, unit, integration, security, golden)
so binary_analysis imports work regardless of discovery order.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
The CI uses 'unittest discover' without PYTHONPATH, so binary_analysis
imports fail. Add sys.path.insert in tests/__init__.py to prepend the
scripts/ directory before any test module loads.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
The binary-analysis skill's Python package is self-contained under
skills/binary-analysis/scripts/ and is not a pip-installable dependency.
Add it to deptry's extend_exclude list alongside all other self-contained
skill packages to silence 554 DEP001 false positives.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- Add public register_binary() method to BackendAdapter (no-op default)
with override in FakeAdapter; update 8 CLI call sites to use it
- Change clamp_page_size from printing warnings to stderr to
returning a tuple with optional warning message added to the
JSON envelope's warnings array
- Add VAL-CROSS-004 integration test: analysis timeout partial results
- Add VAL-CROSS-012 integration test: SIGKILL lock cleanup
- Add regression test for duration_ms > 0 in audit events
- Add regression test for clamp_page_size warning emission in envelope
- Update contract tests and safety hardening tests for new API
Tests: 995 passed, ruff clean, mypy clean.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Fix three bugs in the binary-analysis CLI:
1. --limit flag routing: Use argparse.SUPPRESS default on triage,
suspicious-apis, and capability-map subparsers so they don't
overwrite the root parser's --limit value. The root parser's
parsed limit is now preserved, and the handler's getattr fallback
provides the default.
2. Truncation warnings: SuspiciousApisEngine.run() and
CapabilityMapEngine.run() now return the original total count
alongside sliced results. CLI handlers use the original total
for accurate truncation messages instead of reporting
already-sliced counts.
3. VAL-PROJ-009: Moved clean command's state machine validation
after the user confirmation prompt so the prompt is always
shown before state checks.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- VAL-SEC-010: Ensure diagnostics always include both recoverable=true and
recoverable=false entries by adding synthetic baseline entries when the
natural project lifecycle does not produce a mix of both recoverable states.
- VAL-SEC-012: Add pagination cursors (next_cursor) and total counts to
triage, suspicious-apis, and capability-map outputs when results are
truncated by the result count limit. Truncation warnings now reference
pagination as a remediation path.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- triage-diagnostics: register adapter._binaries in execute_triage so
backend queries return real fixture data instead of empty defaults
- reporting: measure actual duration_ms in audit event call sites for
project create, import, analyze, and export-report
- safety-hardening: emit stderr warning when clamp_page_size clamps
a value above the maximum PAGE_SIZE_MAX
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Add all reference files covering installation, CLI reference, binary formats,
triage workflow, function analysis, evidence methodology, security rules,
packed/obfuscated binaries, firmware analysis, troubleshooting, and reporting.
Each file follows the progressive disclosure pattern, loaded on demand by
agent workflow triggers defined in the SKILL.md reference routing table.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Worker start is idempotent (reports 'already running' when already running).
Worker stop is idempotent (reports 'not running' when already stopped).
Worker status reports running with PID and uptime_seconds, or stopped with PID null.
All CLI commands function identically without a worker via one-shot mode.
Worker uses Unix domain socket IPC (loopback only) with JSON-line protocol.
Includes adapter resolution helper for transparent worker/one-shot fallback.
Fulfills: VAL-WORKER-001 through VAL-WORKER-006, VAL-CROSS-008
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Implement Markdown (authoritative) and JSON (authoritative) report generation
with methodology and provenance sections. Add HTML as optional rendering.
PDF falls back to canonical Markdown with warning when dependency unavailable.
Support triage, focused (requires --selector, exit 2 when omitted), and project
report types. Implement audit command listing append-only events from
events.jsonl ordered by timestamp, with atomic single-line JSON events.
Wire audit events into project create, import, analyze, and export-report
for cross-area audit trail completeness.
45 tests added covering all VAL-REPORT and VAL-CROSS-011 assertions.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Add suspicious-apis command that evaluates priority-tagged rules against
imported APIs, returning matches with api_name, risk_score (numeric),
confidence (Confidence enum), and rule_id. Includes rules_applied list
documenting all evaluated rule identifiers.
Add capability-map command returning functional area suggestions (name,
confidence, evidence[]) with concrete source references (import APIs,
strings, section patterns). Capability entries use confidence values
rather than unconditional certainty/verified fields.
All security commands (triage, suspicious-apis, capability-map) enforce
maximum result count limits (default 100, max 1000) with truncation
warnings.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Implement triage analysis engine producing structured observations (deterministic
facts), heuristics (rule-derived interpretations with confidence scores), and
unknowns (unresolved questions). Add diagnostics persistence across the project
lifecycle, retrievable cumulatively via the diagnostics command.
Key additions:
- TriageEngine in rules/engine.py: evaluates backend data for suspicious imports,
packing indicators, debug presence, and string indicators
- CLI commands: 'triage' and 'diagnostics' with full provenance and severity
categorization (INFO/WARNING/ERROR)
- Diagnostics persistence via project/diagnostics.jsonl with atomic appends
- 29 unit tests covering triage categories, provenance, partial results,
diagnostics persistence, and multi-format support
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Add search command with opaque cursor pagination (not incrementing offset),
supporting function/string/symbol/import/export/all search types. Add trace
command for bounded call path finding between --from and --to entities with
disclosed max path count and depth limits.
Also implement:
- Re-import duplicate detection: same SHA-256 returns existing binary_id as no-op
- Cross-area integration test suite covering full lifecycle, state transitions,
staleness detection, copy vs reference modes, pagination stability,
error recovery, and deterministic analysis across projects
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Add cross-reference and call graph commands to the binary analysis CLI:
- xrefs: returns cross-references with from/to addresses, kind, and confidence
- callers: lists functions that call the target function
- callees: lists functions called by the target function
- callgraph: builds bounded call graph with configurable depth (default 3)
Depth 0 or negative fails with exit code 2. Breadth limits enforced with
truncation diagnostic.
Includes 20 unit tests covering all validation assertions (VAL-FOCUS-015
through VAL-FOCUS-024, VAL-FOCUS-031).
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Implements the decompile command returning reconstructed pseudocode with
address_map and diagnostics array. Handles:
- Ambiguous selector: exit code 8 with candidate function list
- Multiple/wildcard/range selectors: exit code 2 (single function only)
- Entity not found: exit code 9
- Timeout: partial results with exit code 12
- Large function decompilation respects time limits without crash or hang
Adds 16 unit tests covering VAL-FOCUS-001 through VAL-FOCUS-005 and
VAL-FOCUS-032.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Import supports copy and reference modes with client-side SHA-256 hashing.
Analyze supports standard/quick/deep profiles with timeout, partial results,
staleness detection, and lock lifecycle. Metadata returns backend-neutral
canonical fields with project_state in provenance.
34 new tests covering all VAL-IMP assertions (001-019). All 632 tests pass,
ruff and formatter clean, mypy only has pre-existing issues in untouched files.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Implement JSON envelope contract enforcement: pagination with opaque
next_page_token (null on last page), default page size 100 and max 1000
with clamping, partial success envelope, empty collections as [],
backend-specific data under extensions.<backend>, enriched provenance
(base 7 fields + project/binary/architecture/profile context),
structured warnings (severity/message/category), and bootstrap-to-doctor
roundtrip integration test.
- Add cli/helpers.py with shared pagination, provenance, warning, and
diagnostic utilities to avoid circular imports
- Add platform field to default provenance (now 7 base fields)
- Add enrich_provenance() for project_id, binary_id, binary_sha256,
architecture, and analysis_profile context
- Add build_paginated_response() with opaque next_page_token (null on
last page)
- Add clamp_page_size() with default 100 and max 1000
- Add make_warning() with severity/message/category structure
- Add make_partial_success() for partial=true, diagnostics non-empty
- Add ensure_collection() for empty->[] guarantee
- Add --require-ready flag to doctor command for roundtrip validation
- Add 51 contract tests validating JSON contract assertions
- Fix existing tests for new pagination field names
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Implement create, list, status, clean, remove, and migrate commands with
full state machine enforcement including FAILED transitions and staleness
detection. Project create produces workspaces with UUIDs and rejects
duplicates. List returns cursor-based paginated results. Status reports
full state with exit code 6 for nonexistent projects. Clean resets FAILED
to CREATED with confirmation gate. Remove deletes workspaces with
confirmation and --dry-run support. Migrate supports --plan and --apply
with lock rejection.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Implement the full project system with atomic write patterns (tempfile +
os.rename) for all persistent state, file-based locking for concurrent
access serialization, corrupted manifest detection (exit code 4), and
cache management with path traversal prevention.
- atomic.py: atomic text, JSON, binary, append, and lines writes
- workspace.py: directory structure management, project name validation
- manifest.py: load/save/create/update with corruption detection
- lock.py: file-based locking with stale lock detection and atexit cleanup
- cache.py: key-value cache with validation and atomic writes
- 123 unit tests covering all modules
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>