11 KiB
Repository Guidelines
Product and Authority
REA is a local-only reverse-engineering tool exposed through a CLI and MCP server. Keep observed, derived, inferred, and unknown results distinct. Shared application workflows must provide equivalent CLI/MCP behavior, including Evidence provenance and session retention. Provider support and setup live in README.md and the linked provider guides.
Preserve provider authority boundaries: Ghidra uses an ephemeral analysis database without modifying executable bytes or controlling a GUI; Windows Ghidra P0 has no mutation authority. IDA analysis is read-only, and an attached GUI database is never saved or closed.
Configuration changes must be additive and idempotent, with backups. Installers must not install or upgrade Homebrew, Node.js, npm, Java, Ghidra, or other unrelated software. Ghidra and IDA are bring-your-own. rea setup must print its planned changes and require approval before writing files or installing Hopper.
Preserve caller-selected inputs, captured output, URLs, paths, digests, mismatch locations, and analysis metadata. Redact transport authentication credentials and values the caller explicitly marks sensitive; do not infer secrecy from names or text patterns, or persist the entire ambient environment merely because a child inherits it.
Architecture and Ownership
REA is a layered ESM TypeScript application. Dependencies flow inward; see docs/architecture.mermaid.
src/domain/owns pure provider-neutral semantics;src/contracts/owns caller-visible schemas and the canonical tool inventory.- Provider directories own engine protocols and parsing. Keep provider-specific code out of domain and application layers;
bridge/contains provider-side adapters. src/application/owns shared workflows and Evidence/session semantics.src/server/translates MCP requests;src/cli.tsandsrc/main.tsare the CLI and MCP entry points.src/process/owns shared lifecycle primitives. Reuse its supervision and identity checks; a PID and executable pathname alone do not establish ownership after exit or reuse.src/config/owns configuration parsing. Keep user-facing setup and environment documentation in README.md and the relevant provider guide.
Assess brittleness during implementation, debugging, review, and maintenance. Give each interpretation and resource a clear owner. Preserve identity, omission, uncertainty, and source evidence across boundaries. Retain ownership of resources whose cleanup failed. Fix the producing representation or ownership rule before adding downstream repairs.
Simplify duplicated rules, scattered defaults, caller-specific exceptions, and unclear invariants in touched code. Prefer standard format-aware parsers and existing shared helpers; normalize once at the owning boundary. Remove superseded representations, aliases, wrappers, and tests when their replacement is verified through affected consumers. Keep refactors focused on the task and introduce abstractions only when they remove observed complexity.
Development and Generated Files
Use the Node.js version in .nvmrc and npm version in package.json#packageManager. Confirm the active toolchain before installing dependencies. In Cursor Cloud, the image may put an older Node.js first on PATH; prepend /usr/local/bin, where environment setup installs the pinned toolchain.
npm ci: install locked dependencies.npm run build:cached: compile the runtime and bundle its authored skill; test catalogs and documentation artifacts have separate tasks.npm run test:local -- PATH...: run source tests without building; explicit paths run regardless of Git status.npm run test:focused -- PATH...: run exact test files with their required runtime and generated artifacts.npm run check:changed: run static checks and source tests affected since the merge base, defaulting toorigin/main.npm run check:fast: run cached typecheck and lint checks; also runs before push.npm run check:pr: complete local deterministic gate and generated-document checks for broad changes. Routine iterations need focused tests and relevant checks; CI owns full coverage.npm run docs:generate/npm run docs:check: generate / validate documentation artifacts.
docs/public/product-catalog.json, docs/verification/managed-conformance-*.json, and skills/ are ignored build outputs. Edit source contracts and authored instructions in skill-src/; never commit derived catalog digests or portable conformance projections. .cache/mcp-tool-catalog.json is test metadata generated by npm run mcp-catalog:generate; source checking and runtime builds do not consume it. CI retains generated outputs as artifacts rather than pushing them to feature branches.
See docs/testing.md for verification lanes and CONTRIBUTING.md for contribution checks. Keep each lane's prerequisites limited to its claim; separate host-native acceptance from optional cross-target toolchains and preflight required commands. JavaScript analysis and deterministic tests do not require Hopper, Ghidra, or IDA.
Coding and Boundary Contracts
Use ESM TypeScript, two-space indentation, and committed Oxfmt formatting. Preserve compiler strictness, including exactOptionalPropertyTypes, noUncheckedIndexedAccess, and verbatimModuleSyntax. Use camelCase for values/functions, PascalCase for classes/types, and UPPER_SNAKE_CASE for constants. Exported APIs require concise JSDoc. Avoid any, unchecked casts, non-null assertions, import-time I/O, and floating promises. Model expected failures with the tagged error algebra and Result.
Parse unknown values at MCP, environment, and subprocess boundaries. Trace the producer's actual representation through parsing, normalization, authorization, serialization, and the consumer result. Establish affected callers from code paths; inspect adjacent representations and failure paths when changing a boundary.
Keep identity, provenance, matching, and path-resolution values separate from display formatting. Absolute filesystem paths, file URLs, and HTTP paths have different semantics. Interpret provider metadata according to its producer; preserve source values and explicit unknowns when normalization loses information. Display placeholders must not feed lookup or selection.
Preserve partial facts without inventing missing metadata or requiring another provider's full representation. Inspect installed APIs and representative producer objects before claiming a capability is unavailable. Preserve meaningful failure reasons and actionable recovery guidance: malformed input, unsupported targets, unavailable providers, and host permission denial are distinct. Collected observations must survive execution and cleanup failures.
Validate advertised input and output JSON Schemas against their declared dialect after SDK conversion, and verify client compatibility at the consuming boundary. Bind handlers to named contracts with exact input/output types; catalog ordering must never select an operation or schema.
Tool Design and Verification
Start from the analyst question and inspect existing contracts before adding a tool. Prefer reusable primitives and ordinary commands/scripts for experiments; add composed workflows for observed recurring needs. Leave meaningful target, action, capture, and output choices to the caller. Remove ignored settings and repeated approval declarations; derive built-in lifecycle behavior and default optional metadata.
Return useful evidence inline, complete by default, with identity, source locations, relevant limitations, and truthful authority/lifecycle effects. Limits must follow real format, protocol, authority, or resource constraints; account for representation expansion and products of bounded dimensions before allocation. Derive completeness from what was examined and exhausted. Follow docs/tool-design.md for naming, composition, contract design, and representative CLI/MCP usability evaluation. Update canonical contracts and generated artifacts together.
Prefer full public CLI/MCP end-to-end workflows with real providers, then production-boundary integration tests, then goldens from real producers. Keep focused module tests for distinct failures or semantics that stronger workflows cannot reliably reproduce. Delete redundant assertions when stronger coverage proves the same claim; preserve distinct malformed-input, cancellation, cleanup, permission, capacity, and target-identity cases. Follow docs/testing.md for pruning criteria, test classification, fixtures, and verification commands.
Use Vitest, *.test.ts, production seams rather than module mocks, and the pinned MCP client SDK. Treat advertised examples as executable contracts using representative producer data. Provider/platform and packaged-artifact claims require their real workflows; capability probes and simulated transports prove only their narrower scope. Report unverified coverage explicitly.
Keep tool catalogs complete and self-describing; prefer capability/session-scoped availability over schema truncation. Serialized bytes alone do not establish agent usability or model context cost.
Commits and Pull Requests
Use Conventional Commit subjects, including PR titles for squash merges. Release Please always bumps minor; mark breaking changes with ! or a BREAKING CHANGE: footer. Describe behavior/contract changes, relevant validation, linked issues, and real-provider verification scope; include sanitized CLI/MCP examples for schema changes.
Never commit binaries, provider project documents, credentials, dist/, node_modules/, or local planning artifacts such as .codex/. Pre-commit formats and lints staged source.
This is NOT the Turborepo you know
Turborepo configuration, task behavior, and CLI commands can vary between installed versions and may differ from your training data. Resolve the turbo package from this file's directory or relevant workspace; in monorepos, it may not be visible from the repository root. For example, run node -p "require.resolve('turbo/package.json')" from a workspace that depends on turbo.
Read docs/README.md inside that installed package first, then read the relevant pages from its docs/ directory before changing Turborepo configuration or commands. Heed deprecation notices. These bundled docs match the installed package version and are available without network access.
This block is written and re-added by turbo before repository-scoped commands when an AI agent is detected. In the Turborepo source repository, its template is defined in crates/turborepo-cli/src/cli/agent_guidance.rs. Removing the managed block while updates are enabled means a later qualifying invocation will add it again. Set "agentGuidance": false in the root turbo.json or turbo.jsonc to opt out; this does not remove an existing block. Keep the block committed with your work to avoid an uncommitted change on the next agent invocation.