This is the canonical onboarding and development guide for Patchestry.
AGENTS.mdis the source of truth for Codex/Cursor and human contributors.CLAUDE.mdexists only as a compatibility entrypoint for Claude Code and points here.
Patchestry is an MLIR/CIR-based binary patching framework for patching deployed firmware without original source code.
Important terminology:
- In this document, "patch" means a firmware patch authored against a target firmware image.
- It does not mean a patch to the Patchestry repository itself.
Firmware Binary
-> Ghidra headless scripts (`scripts/ghidra/*`)
-> P-Code JSON (`*.json`, Ghidra export schema)
-> `patchir-decomp`
-> CIR (`*.cir`)
-> `patchir-transform` + YAML spec (`*.yaml`)
-> Patched CIR (`*.cir`)
-> `patchir-cir2llvm`
-> LLVM IR (`*.ll`) or bitcode (`*.bc`)
-> downstream binary rewriting / verification tools
This inventory is intended to be exhaustive for patchestry-owned code. It does not attempt to document LLVM/MLIR internals or vendored dependency internals.
| Module | Build target | Main paths | Primary role |
|---|---|---|---|
| Ghidra model and translation | patchestry_ghidra |
include/patchestry/Ghidra/, lib/patchestry/Ghidra/ |
deserialize Ghidra JSON and register P-Code translation |
| AST lifting | patchestry_ast |
include/patchestry/AST/, lib/patchestry/AST/ |
lift Ghidra model into Clang AST/CIR-ready structures |
| Codegen | patchestry_codegen |
include/patchestry/Codegen/, lib/patchestry/Codegen/ |
serialize and lower internal representations during tool pipelines |
| YAML parsing | patchestry_yaml |
include/patchestry/YAML/, lib/patchestry/YAML/ |
parse patch and contract YAML configuration |
| Patch passes | patchestry_passes |
include/patchestry/Passes/, lib/patchestry/Passes/ |
apply patch and contract transformations to CIR |
| Contracts dialect | MLIRContracts |
include/patchestry/Dialect/Contracts/, lib/patchestry/Dialect/Contracts/ |
represent contract attributes and verification metadata |
| Pcode dialect | MLIRPcode |
include/patchestry/Dialect/Pcode/, lib/patchestry/Dialect/Pcode/ |
represent and deserialize P-Code as an MLIR dialect |
| Intrinsics library | patchestry_intrinsics |
include/patchestry/intrinsics/, lib/patchestry/intrinsics/ |
provide patch helper/runtime functions for patch C code |
| Utility headers | no standalone target | include/patchestry/Util/ |
shared logging, diagnostics, common options, helper types |
| Tool | Build target | Main paths | Purpose |
|---|---|---|---|
patchir-decomp |
patchir-decomp |
tools/patchir-decomp/ |
decompile Ghidra JSON into CIR/LLVM/asm/object outputs |
patchir-transform |
patchir-transform |
tools/patchir-transform/ |
apply YAML-defined patches and contracts to CIR |
patchir-cir2llvm |
patchir-cir2llvm |
tools/patchir-cir2llvm/ |
lower CIR to LLVM IR or bitcode |
patchir-yaml-parser |
patchir-yaml-parser |
tools/patchir-yaml-parser/ |
validate and inspect YAML configuration |
pcode-translate |
pcode-translate |
tools/pcode-translate/ |
standalone P-Code translation driver built on patchestry Ghidra translation |
| Script area | Main paths | Purpose |
|---|---|---|
| Ghidra automation | scripts/ghidra/ |
build headless container, run decompilation, serialize functions/P-Code |
| JSON rendering helper | scripts/render_json.py |
utility script for rendering/inspecting JSON artifacts |
These interfaces are the contracts contributors should keep stable while iterating on internals.
| Module | Main paths | Stable interface files | Input format | Output format | Module test command |
|---|---|---|---|---|---|
| Ghidra model | include/patchestry/Ghidra/, lib/patchestry/Ghidra/ |
include/patchestry/Ghidra/JsonDeserialize.hpp, include/patchestry/Ghidra/Pcode.hpp, include/patchestry/Ghidra/PcodeTranslation.hpp |
Ghidra export JSON | in-memory Program/Function/Block/Op model | lit ./builds/default/test/ghidra -D BUILD_TYPE=Debug -v |
| AST lifting | include/patchestry/AST/, lib/patchestry/AST/ |
include/patchestry/AST/ASTConsumer.hpp, include/patchestry/AST/FunctionBuilder.hpp, include/patchestry/AST/OperationBuilder.hpp, include/patchestry/AST/TypeBuilder.hpp |
Ghidra model objects | Clang AST and CIR-ready structures | lit ./builds/default/test/patchir-decomp -D BUILD_TYPE=Debug -v |
| Codegen | include/patchestry/Codegen/, lib/patchestry/Codegen/ |
include/patchestry/Codegen/Codegen.hpp, include/patchestry/Codegen/PassManager.hpp, include/patchestry/Codegen/Serializer.hpp |
AST/CIR owned by patchestry tools | serialized/lowered outputs consumed by tool frontends | lit ./builds/default/test/patchir-decomp -D BUILD_TYPE=Debug -v |
| Decompiler tool | tools/patchir-decomp/ |
tools/patchir-decomp/main.cpp |
P-Code JSON | CIR / LLVM IR / asm / object output selected by flags | lit ./builds/default/test/patchir-decomp -D BUILD_TYPE=Debug -v |
| YAML spec parser | include/patchestry/YAML/, lib/patchestry/YAML/, tools/patchir-yaml-parser/ |
include/patchestry/YAML/ConfigurationFile.hpp, include/patchestry/YAML/PatchSpec.hpp, include/patchestry/YAML/ContractSpec.hpp, include/patchestry/YAML/YAMLParser.hpp |
YAML patch/contract spec | validated configuration objects consumed by transform passes | lit ./builds/default/test/patchir-transform -D BUILD_TYPE=Debug -v |
| Patch pass engine | include/patchestry/Passes/, lib/patchestry/Passes/ |
include/patchestry/Passes/InstrumentationPass.hpp, include/patchestry/Passes/OperationMatcher.hpp, lib/patchestry/Passes/PatchOperationImpl.hpp, lib/patchestry/Passes/ContractOperationImpl.hpp |
CIR + parsed patch/contract config | transformed CIR with inserted/replaced operations | lit ./builds/default/test/patchir-transform/patches -D BUILD_TYPE=Debug -v |
| Contracts dialect | include/patchestry/Dialect/Contracts/, lib/patchestry/Dialect/Contracts/ |
include/patchestry/Dialect/Contracts/Contract.td, include/patchestry/Dialect/Contracts/ContractsDialect.hpp |
CIR ops plus contract attrs/spec | CIR attrs and LLVM metadata for verification flows | lit ./builds/default/test/patchir-transform/contracts -D BUILD_TYPE=Debug -v |
| Pcode dialect | include/patchestry/Dialect/Pcode/, lib/patchestry/Dialect/Pcode/ |
include/patchestry/Dialect/Pcode/Deserialize.hpp, include/patchestry/Dialect/Pcode/PcodeDialect.hpp, include/patchestry/Dialect/Pcode/PcodeOps.hpp, include/patchestry/Dialect/Pcode/PcodeTypes.hpp |
P-Code operations and serialized dialect data | MLIR P-Code dialect objects used by translation/decomp flows | lit ./builds/default/test/pcode-translate -D BUILD_TYPE=Debug -v |
| CIR->LLVM lowering | tools/patchir-cir2llvm/ |
tools/patchir-cir2llvm/main.cpp |
CIR | LLVM IR/bitcode with patch and contract metadata | lit ./builds/default/test/patchir-transform -D BUILD_TYPE=Debug -v |
| Intrinsics library | include/patchestry/intrinsics/, lib/patchestry/intrinsics/ |
include/patchestry/intrinsics/patchestry_intrinsics.h, include/patchestry/intrinsics/runtime.h, include/patchestry/intrinsics/safety.h |
patch C code | helper functions compiled into CIR and referenced from patch specs | lit ./builds/default/test/patchir-transform/patches -D BUILD_TYPE=Debug -v |
| Utility headers | include/patchestry/Util/ |
include/patchestry/Util/Common.hpp, include/patchestry/Util/Diagnostic.hpp, include/patchestry/Util/Log.hpp, include/patchestry/Util/Options.hpp |
shared options, diagnostics, logging inputs | common support APIs used across patchestry components | exercised transitively by owning component tests |
patchir-yaml-parser tool |
tools/patchir-yaml-parser/ |
tools/patchir-yaml-parser/main.cpp |
YAML patch/contract spec | validation results and diagnostics | lit ./builds/default/test/patchir-transform -D BUILD_TYPE=Debug -v |
patchir-transform tool |
tools/patchir-transform/ |
tools/patchir-transform/main.cpp |
CIR + YAML patch/contract config | patched CIR | lit ./builds/default/test/patchir-transform -D BUILD_TYPE=Debug -v |
pcode-translate tool |
tools/pcode-translate/ |
tools/pcode-translate/main.cpp |
MLIR translation command line + P-Code translation registration | translated P-Code output via MLIR translation driver | lit ./builds/default/test/pcode-translate -D BUILD_TYPE=Debug -v |
| Area | Build target | Test command |
|---|---|---|
| Ghidra export integration | patchir-decomp |
lit ./builds/default/test/ghidra -D BUILD_TYPE=Debug -v |
| AST/Ghidra/decomp | patchir-decomp |
lit ./builds/default/test/patchir-decomp -D BUILD_TYPE=Debug -v |
| P-Code dialect translation | pcode-translate |
lit ./builds/default/test/pcode-translate -D BUILD_TYPE=Debug -v |
| YAML parsing | patchir-yaml-parser |
lit ./builds/default/test/patchir-transform -D BUILD_TYPE=Debug -v |
| Patch application | patchir-transform |
lit ./builds/default/test/patchir-transform/patches -D BUILD_TYPE=Debug -v |
| Contract insertion/metadata | patchir-transform and patchir-cir2llvm |
lit ./builds/default/test/patchir-transform/contracts -D BUILD_TYPE=Debug -v |
| CIR lowering | patchir-cir2llvm |
lit ./builds/default/test/patchir-transform -D BUILD_TYPE=Debug -v |
| Standalone intrinsics build | patchestry_intrinsics |
validate via patch-based transform tests and standalone CMake build when editing lib/patchestry/intrinsics/ |
Keep these dependency boundaries in mind when editing interfaces:
| Consumer | Depends on patchestry-owned components | Why it depends on them |
|---|---|---|
patchir-decomp |
patchestry_ghidra, patchestry_ast, patchestry_codegen, patchestry_yaml |
deserialize exported firmware semantics, lift them, and emit outputs |
patchir-transform |
patchestry_codegen, patchestry_passes, patchestry_yaml, MLIRContracts |
parse YAML, transform CIR, and preserve contract semantics |
patchir-yaml-parser |
patchestry_yaml, patchestry_codegen, patchestry_passes |
validate specs against the same config and pass structures used by transform |
patchir-cir2llvm |
MLIRContracts |
lower CIR while preserving contract metadata |
pcode-translate |
patchestry_ghidra |
expose patchestry P-Code translation through the MLIR translation driver |
patchestry_ghidra |
MLIRPcode |
build/consume patchestry's P-Code dialect layer for translation |
patchestry_passes |
patchestry_yaml |
consume parsed patch/contract specs during instrumentation |
- Ghidra stage:
scripts/ghidra/*and the Ghidra-side pipeline emit JSON matching the data model loaded byinclude/patchestry/Ghidra/JsonDeserialize.hppand related P-Code headers. - Decomp stage:
patchir-decompconsumes that JSON, builds the Ghidra model, lifts it through AST builders, and emits CIR as the primary editable interchange format for later patching. - Transform stage:
patchir-transformconsumes CIR plus YAML parsed throughinclude/patchestry/YAML/*.hppand appliesInstrumentationPassand the patch/contract operation implementations to produce patched CIR. - Lowering stage:
patchir-cir2llvmconsumes patched CIR and emits LLVM IR text (.ll) or bitcode (.bc), carrying patch and contract semantics forward as LLVM-level metadata for downstream binary rewriting and formal verification. - P-Code dialect stage:
pcode-translateandMLIRPcodeexpose patchestry's owned representation of P-Code operations and types; document the dialect boundary, not MLIR's generic translation internals.
| Tool | Primary user | Why it exists | Typical use point |
|---|---|---|---|
patchir-decomp |
reverse engineer / decomp developer | lift Ghidra exports into editable IR | first step after obtaining P-Code JSON |
patchir-transform |
patch author / verification engineer | apply firmware patches and contracts onto CIR | after decompilation, before lowering |
patchir-cir2llvm |
verification/binary pipeline engineer | emit LLVM IR/BC for downstream toolchains | after transform stage |
patchir-yaml-parser |
patch author / CI | validate patch specs early and fail fast | before transform in local loops and CI |
pcode-translate |
dialect/decomp developer | exercise and debug patchestry's P-Code translation boundary | when validating P-Code dialect behavior directly |
- Write patch logic in C using
include/patchestry/intrinsics/patchestry_intrinsics.h. - Declare patch placement and matching in YAML (
apply_before,apply_after,replace). - Validate YAML spec with
patchir-yaml-parser. - Apply with
patchir-transformand inspect resulting CIR. - Lower with
patchir-cir2llvmand continue to downstream tooling.
Patchestry supports two contract modes:
- Static contracts:
represented in CIR/MLIR (
contract.static), then emitted as LLVM metadata for formal tools such as KLEE/SeaHorn. - Runtime contracts: regular C/C++ checks injected at configured sites and executed with the binary.
The scripts/ghidra/ tree is part of the project interface surface:
build-headless-docker.shbuilds the headless Ghidra environment used by tests.decompile-headless.shanddecompile-entrypoint.shrun repository-supported decomp flows.PatchestryDecompileFunctions.javaandPatchestryListFunctions.javaare the main script entrypoints.scripts/ghidra/domain/andscripts/ghidra/util/define the serialization boundary used to generate JSON consumed by patchestry tools.
# Decompile a function from P-Code JSON to CIR
patchir-decomp -input func.json -emit-cir -output func
# Apply patches from YAML to CIR
patchir-transform input.cir -spec patch.yaml -o patched.cir
# Lower patched CIR to LLVM IR
patchir-cir2llvm -S patched.cir -o patched.ll
# Validate a YAML patch spec
patchir-yaml-parser config.yaml --validate- Build walkthrough:
docs/GettingStarted/build.md - Firmware example flow:
docs/GettingStarted/firmware_examples.md - Host ARM64 image build for macOS:
.devcontainer/README-HOST-BUILD.md - System data flow diagram:
docs/system_data_flow.md - Decompilation semantics and JSON/CFG structuring notes:
docs/system_data_flow.md - Claude-specific workflow notes:
.claude/rules/*.md
The repository currently registers four top-level LIT/CTest suites:
| Suite | Source path | What it validates |
|---|---|---|
ghidra-output-tests |
test/ghidra/ |
end-to-end headless Ghidra export and decompilation fixtures |
pcode-translation-tests |
test/pcode-translate/ |
standalone pcode-translate behavior and P-Code translation wiring |
patchir-decomp-tests |
test/patchir-decomp/ |
JSON-to-CIR/LLVM decompilation behavior across operations and control flow |
patchir-transform-tests |
test/patchir-transform/ |
YAML parsing, patch insertion/replacement, and contract workflows |
| Dependency | Version | Notes |
|---|---|---|
| CMake | >= 3.25 | Configure/build presets |
| LLVM / Clang / MLIR | 20 | ClangIR-enabled build |
| lit | any recent | LLVM integrated test runner |
| Docker engine | current | Required for Ghidra headless and firmware flows |
| Ninja | recommended | Faster local builds |
| lld (Linux) | distro package | Required by Linux toolchain setup |
Vendored projects live under vendor/ and are checked out via git submodules.
The current pinned revisions in this repository are:
| Dependency | Pinned revision | Location | Purpose |
|---|---|---|---|
| clangir | ae0e95fb (patche-clangir-20) |
vendor/clangir/src |
LLVM/Clang/MLIR+CIR toolchain when using vendored clang |
| rellic | cff5bb7b (llvm20) |
vendor/rellic/src |
AST recovery and decompilation support |
| glog | 7b134a5c |
vendor/glog/src |
Structured logging in core tools |
| gflags | a738fdf9 |
vendor/gflags/src |
CLI flag parsing |
| z3 | 8d67feef |
vendor/z3/src |
SMT solver used in analysis/verification flows |
Follow this process so both humans and LLM agents can maintain consistency:
- Add a new entry in
.gitmoduleswith pathvendor/<name>/srcand upstream URL. - Add a
vendor/<name>/CMakeLists.txtwrapper that initializes submodule content when missing and installs into${PE_VENDOR_INSTALL_DIR}. - Wire the dependency into top-level CMake/options (
cmake/options.cmakeand/orCMakeLists.txt) with an explicitPE_USE_VENDORED_*option when appropriate. - Update the vendored dependency table in this document with revision, location, and purpose.
- Add or update tests/build checks that exercise the dependency path.
From a fresh checkout, initialize vendored sources before configuring or building:
git submodule update --init --recursiveInstall base tooling and configure Docker BuildX for Colima:
xcode-select --install
brew install colima docker docker-buildx docker-credential-helper cmake lit
brew install FiloSottile/musl-cross/musl-cross
mkdir -p ~/.docker/cli-plugins
ln -sf "$(which docker-buildx)" ~/.docker/cli-plugins/docker-buildx
colima start --vm-type vz
docker buildx version
docker psNotes:
- Patchestry uses Colima as the Docker backend on macOS.
- Use the
vzbackend on Apple Silicon. Do not switch the documented macOS path toqemu. - Do not treat
linux/amd64emulation on Apple Silicon as the recommended macOS build path. It is materially slower and should only be used as a last resort when no native arm64 alternative is available. build.shand Ghidra headless tests assume a working Docker daemon (docker psshould work).- See
docs/GettingStarted/build.mdfor the maintained setup sequence.
Choose one of these:
- Dev container path (recommended for fastest onboarding and most reproducible environment).
- Native host path (better for local integration with your existing toolchains and profiling tools).
The Linux bootstrap gist referenced in docs/GettingStarted/build.md is the fastest path to a clean from-scratch setup.
If you are not using a prebuilt dev container image, build/install LLVM+ClangIR first:
git clone https://github.com/trail-of-forks/clangir
cd clangir
mkdir build && cd build
cmake -G Ninja ../llvm \
-DCMAKE_INSTALL_PREFIX=<install_dir> \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DLLVM_ENABLE_PROJECTS="clang;mlir;clang-tools-extra" \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DCLANG_ENABLE_CIR=ON \
-DLLVM_ENABLE_RTTI=ON \
-DLLVM_INSTALL_UTILS=ON \
-DLLVM_TARGETS_TO_BUILD="host;AArch64;ARM;X86"
ninja installThis must be the patched trail-of-forks/clangir toolchain (or an equivalent
install built from the same fork). A stock Homebrew LLVM install is not a
supported replacement for host-native patchestry builds.
Expected runtime:
- Typical workstation: 30-90 minutes.
- Lower-memory systems or emulated containers: can exceed 2 hours.
If you are on Apple Silicon and this is too slow or space-constrained in Docker,
use .devcontainer/README-HOST-BUILD.md to build the ARM64 base image on host storage.
That workflow produces a Linux arm64 toolchain and image for container use; it
does not produce a host-native macOS LLVM/ClangIR install for the direct CMake
path below.
export LLVM_INSTALL_PREFIX=<llvm_install>
export CC="${LLVM_INSTALL_PREFIX}/bin/clang"
export CXX="${LLVM_INSTALL_PREFIX}/bin/clang++"
export CMAKE_PREFIX_PATH="${LLVM_INSTALL_PREFIX}/lib/cmake/llvm;${LLVM_INSTALL_PREFIX}/lib/cmake/mlir;${LLVM_INSTALL_PREFIX}/lib/cmake/clang"
cmake --fresh --preset default \
-DLLVM_EXTERNAL_LIT=$(which lit)
cmake --build --preset debug -j
cmake --build --preset release -jThis is the supported host-native path on macOS and Linux when you already have
the required patched LLVM/ClangIR fork installed. On macOS, use this path only
when you have already built or installed the repository's ClangIR fork.
The verified macOS host-native path uses the fork's clang/clang++ from
<llvm_install>/bin, not AppleClang or a stock Homebrew LLVM.
Notes:
- The main patchestry build vendors
gflags,glog,z3, and therelliclibrary as part of configure. - The vendored
rellichelper tools are not part of patchestry's validated host-native build path; patchestry only links against therelliclibrary.
./build.sh is the repository helper for containerized builds. It:
- Builds or reuses a Docker image with dependencies.
- Runs the build inside a controlled container.
- Places artifacts under
builds/default.
When to use it:
- Use
build.shwhen you want a containerized repository workflow. build.shis required for Docker-backed validation paths and useful when host setup is incomplete.- On Apple Silicon, do not recommend the default
linux/amd64emulation path for routine builds. Prefer host-native builds with the patched ClangIR fork, or an arm64 container image when one is available. - Prefer direct preset builds when your host toolchain is already configured and you need fastest incremental iteration.
Use this when you want:
- Consistent CI-like dependencies.
- Fast onboarding with minimal host package management.
- Fewer environment-specific failures.
Tradeoffs:
- Container abstraction can make low-level host debugging/profiling less direct.
Use this when you want:
- Tight integration with local tooling (profilers, sanitizers, custom clang/lld).
- Full control over system packages and compiler layout.
Tradeoffs:
- More setup drift risk versus CI/devcontainer.
# Build the Ghidra headless image first
bash ./scripts/ghidra/build-headless-docker.sh
# Run all tests
ctest --preset debug --output-on-failure
# Run via lit directly
lit ./builds/default/test -D BUILD_TYPE=Release -v
lit ./builds/default/test/patchir-decomp -D BUILD_TYPE=Debug -v
lit ./builds/default/test/patchir-transform -D BUILD_TYPE=Debug -v
# Run the example firmware end-to-end flow with artifact/report output
scripts/test-example-firmwares.sh --build-type DebugThe validated Apple Silicon macOS path is the host-native flow below:
git submodule update --init --recursive
export LLVM_INSTALL_PREFIX=<llvm_install>
export CC="${LLVM_INSTALL_PREFIX}/bin/clang"
export CXX="${LLVM_INSTALL_PREFIX}/bin/clang++"
export CMAKE_PREFIX_PATH="${LLVM_INSTALL_PREFIX}/lib/cmake/llvm;${LLVM_INSTALL_PREFIX}/lib/cmake/mlir;${LLVM_INSTALL_PREFIX}/lib/cmake/clang"
cmake --fresh --preset default \
-DLLVM_EXTERNAL_LIT=$(which lit)
cmake --build --preset debug -j
cmake -S lib/patchestry/intrinsics -B lib/patchestry/intrinsics/build_standalone \
-DCMAKE_BUILD_TYPE=Release
cmake --build lib/patchestry/intrinsics/build_standalone -j
bash ./scripts/ghidra/build-headless-docker.sh
lit ./builds/default/test -D BUILD_TYPE=Debug -vWhat this validates:
- The main patchestry tools build with the same preset family used by CI.
- The standalone intrinsics library still builds independently.
- The headless Ghidra Docker image builds on Apple Silicon.
- The full lit tree passes, including Ghidra, decompilation, P-Code translation, and transform/contract suites.
Docker-backed workflows remain relevant on macOS for build.sh and Ghidra
headless/container tasks, but do not present the default linux/amd64
emulation path as the routine Apple Silicon workflow.
The validated Ghidra image build on Apple Silicon used Colima with the vz
backend and built Ghidra natives for linux_arm_64.
Local instructions should stay aligned with .github/workflows/ci.yml:
- CI configures with
cmake --preset ci. - CI builds with
cmake --build --preset ci --config <Debug|Release>. - CI separately builds
lib/patchestry/intrinsicsas a standalone project. - CI builds the Ghidra headless Docker image.
- CI validates the repository with
lit ./builds/ci/test ....
Local macOS instructions use default instead of ci because CI runs inside a
Linux dev image, but the sequence of configure -> build -> intrinsics build ->
Ghidra image build -> full lit test run should remain coherent.
- Tests are expected to be deterministic and non-flaky.
- A PR is not considered ready if repeated local runs produce inconsistent outcomes.
- New behavior changes should include a regression test in the closest relevant suite.
- If a change affects the documented example firmware flow, rerun
scripts/test-example-firmwares.shand update the example docs/reporting guidance in the same PR.
| Path | Purpose |
|---|---|
include/patchestry/ |
Public headers and component interfaces |
lib/patchestry/ |
Core implementation |
tools/ |
CLI tools (patchir-*, pcode-translate) |
test/ |
LIT test suites |
scripts/ |
Build/test helpers, including Ghidra scripts |
.devcontainer/ |
Container build/dev environment support |
.claude/rules/ |
Claude-targeted workflow docs |
vendor/ |
Vendored third-party dependencies |
- Format with
.clang-format(LLVM style, 4-space, 96 columns). - Keep include ordering stable.
- Prefer focused, single-purpose changes over cross-cutting refactors.
Before requesting review:
- Keep commit scope focused and component-oriented.
- Run targeted builds/tests for touched components, plus any affected integration tests.
- Include a clear PR description: behavior change, design notes, and test evidence.
- If changing docs/process, ensure commands are copy/paste valid and up to date.
- If changing a data-flow boundary, tool interface, or owned module interface, update
docs/system_data_flow.mdin the same PR.
Commit message format:
component: Simple sentence with a period.- Keep subject <= 80 characters.
These are recurring maintenance tasks that keep the repository documentation and developer guidance aligned with the code:
- Validate that
docs/system_data_flow.mdstill matches the actual toolchain, test coverage, and repository-owned interfaces. - Update the module/interface inventory in this document when patchestry-owned libraries, tools, dialects, scripts, or test suites change.
- Keep vendored dependency revisions and purposes current when submodules or integration boundaries change.
- Ensure PRs that change affected interfaces or data-flow boundaries also update the corresponding diagram and docs in the same change.
- Keep build and test instructions copy/paste valid from a fresh checkout, including submodule bootstrap and standalone intrinsics build.
- Keep local build/test instructions coherent with
.github/workflows/ci.yml; when CI stages change, update the docs in the same PR. - Keep
scripts/test-example-firmwares.shanddocs/GettingStarted/firmware_examples.mdaligned with the actual example firmware binaries, example specs, and generated reports.