craft-anything
AGENTS.md33k starsChanged 15 days agoApache-2.0View on GitHub
Craft Anything is a native, pure-Rust app that shows anyone how a piece of software works (programs, apps, files, websites, phones) with evidence-backed answers, then helps them rebuild it. It ships a desktop app (egui), a CLI and an MCP server, all driven by one engine. Display name Craft Anything; machine names craft-anything-*; bundle id ai.storyteller.craft-anything. Standards shared across the Crafting Apps live in ../craftrules (read its AGENTS.md); follow them. Repos never share code. Original work only: never copy code,…
- Reads credentials
- Commits and pushes
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repositoryOne other file it gives its agents.
- CLAUDE.mdCLAUDE.md
The file
We split this AGENTS.md into the rules it gives an agent
9 rules. About 0 are common, 3 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 9
Original work only: never copy code, scripts, schemas, names, assets or wording from another project, and never name other …
- Very specific: line 63
Never crash, never lock up, around other programs: Every external program (Ghidra, Java, adb, a browser, an agent CLI, ssh, git…) runs …
- Distinctive: line 68
every run has a deadline (wall clock and idle), output is capped and drained on threads so pipes never fill, and the child (and its process …
- Very specific: line 73
Never lock up on a lock: Use craft_anything_platform::sync::Mutex, never std::sync::Mutex (clippy refuses it).
- Very specific: line 89
Claim before you start: put — claimed: <name>, branch <branch> on the pending change and push your branch early (or open a draft PR) so …
- Distinctive: line 100
Read the code you'll touch and check STATUS.md and the roadmap for gaps it depends on.
- Very specific: line 104
Never commit to main. Branch from an up-to-date main with a standard prefix, then the roadmap id if there is one: feature/, bugfix/, …
- Very specific: line 113
Before every commit and push, check git branch --show-current.
- Very specific: line 116
Headless first: Every capability works without the GUI: engine → tools → CLI/MCP, with the GUI as one thin client.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md: guide for AI agents and contributors
Craft Anything is a native, pure-Rust app that shows anyone how a piece of software works (programs, apps, files,
websites, phones) with evidence-backed answers, then helps them rebuild it. It ships a desktop app (egui), a CLI and
an MCP server, all driven by one engine. Display name Craft Anything; machine names craft-anything-*; bundle id
ai.storyteller.craft-anything. Standards shared across the Crafting Apps live in ../craftrules (read its
AGENTS.md); follow them. Repos never share code.
Original work only: never copy code, scripts, schemas, names, assets or wording from another project, and never name other reverse-engineering products in source, docs, UI or commit messages.
Workspace map
crates/
evidence L0 Evidence records, canonical ids, confidence, unknowns, ToolError (the error contract)
formats L0 Standalone parsers (no workspace deps, no I/O): ELF/PE/Mach-O/WASM/DEX/APK/ASAR/plist/.NET/Go/…
disasm L1 Our own native engine (Clean room): decode, functions, CFG, xrefs, call graph, pseudo-C
js L1 JavaScript/Electron/web bundles: parse, module graph, IPC, source maps, unbundling
analysis L2 Analyzers producing evidence (triage, dossiers, trace, compare, app graph, rebuild ledger)
platform L2 Native services: owned processes, PTY capture, sandbox, engine store, atomic files
engines L3 Optional external engines: Ghidra bridge (Deep mode), adb, CDP, Frida, JADX, Apktool…
engine L4 Session, projects (.cany), workspaces (what the person is making), the inbox
(questions/approvals), ToolSpec registry, settings, consent, the tool list
ai L5 AI backends (Anthropic, OpenAI, OpenRouter, local, agent CLIs, SSH) + agent loop + crews,
and the rebuild workflow (study → build → check → refine)
mcp L5 MCP server: progressive toolsets, resources, prompts
setup L5 Connect to coding-agent apps; doctor; uninstall
ui-egui L6 The egui interface (Beginner + Experienced). The only crate that may use egui/eframe/winit/rfd.
testkit Test helpers and synthetic sample builders
apps/ craft-anything (desktop) · craft-anything-cli (CLI + `mcp`) · craft-anything-web (browser viewer)
xtask/ cargo xtask layers | tools [--check] | wasm | secrets [--history] | ci | version [set X.Y.Z]Layering is enforced by cargo xtask layers. Register new crates in xtask/src/main.rs.
Golden rules
- Never crash (
../craftrules/standards/never-crash.md). Hostile input is our main input. Nounwrap/expect/panic!/todo!/unimplemented!/unreachable!/indexing on input-derived values in non-test code; every production crate root carries the deny attribute. Checked arithmetic, bounded recursion, capped allocations. Every crash fix gets a regression test. - Everything is a tool. User-visible behaviour = a
ToolSpecincrates/engine/src/tools/<area>.rswith id, title, summary, beginner text, toolset, effects, requires, a schemars params struct, andrun. Register the module with one line intools/mod.rs. UI, CLI, MCP and the AI agent all dispatch by id. Programmatic calls never open dialogs. - Evidence is the result. Analysis tools return
ToolOutput::Evidencebuilt withEvidenceBuilder(honest confidence, limitations, coverage, locations). Large results: summary first, paged views (offset/limit). - Clean room vs Deep.
session.clean_room()is true unless Deep mode is on (deep_mode, or--deepfor one CLI run). Clean room never looks inside the original: only the tools inengine/src/clean_room.rsrun, so a new tool is Deep-only until it's listed there, and it may be listed only if it touches no target or watches from outside, as a visitor or user would. Deep mode uses every tool; built-in engines must work fully without Ghidra, which only adds. Evidence records the engine and the flag. - Effects are honest. Declare every side effect.
EXECUTES_FOREIGN_CODEandMUTATES_DEVICEtrigger consent. - Never break wasm for L0–L2 (
cargo xtask wasm). - Thin UI. UI state is serde data; colours/radii come from theme tokens.
- No secrets, no personal data in requests, logs, tests or the repo (it is public): no API keys, tokens,
private keys,
.envfiles or local paths, only obvious fakes likesk-test.cargo xtask secretschecks what git would commit (--historychecks every commit); enable the hook once per clone withgit config core.hooksPath .githooks. GenericCraftAnything-devUser-Agent. - Safe Rust only.
unsafe_code = "forbid"everywhere, no exceptions. Prefer pure-Rust crates; any dependency must be safe to use from safe code. - Never crash, never lock up, around other programs. Every external program (Ghidra, Java, adb, a browser,
an agent CLI, ssh, git…) runs through
craft_anything_platform::processonly, neverstd::process::Commanddirectly:- stdin is closed (or a pipe we write to), never inherited, so nothing can sit waiting at a prompt; ssh gets
BatchMode=yes; tools get their non-interactive flags; - every run has a deadline (wall clock and idle), output is capped and drained on threads so pipes never fill, and the child (and its process group / Job Object) is killed on timeout, cancel or drop;
- a missing program, non-zero exit, bad output or timeout is a
ToolErrorwith a plain-English remediation, never a panic or a hang; - nothing slow ever runs on the UI thread: the UI sends work to background threads and polls results.
- stdin is closed (or a pipe we write to), never inherited, so nothing can sit waiting at a prompt; ssh gets
- Never lock up on a lock. Use
craft_anything_platform::sync::Mutex, neverstd::sync::Mutex(clippy refuses it). It stops a real deadlock as soon as it forms, the waiter's work unwinding to itscatch_unwindas an error; the watchdog reports anything held too long. Long jobs are fine: label the guard (guard.label(id), asEngine::calldoes for tools) and they're waited for, not treated as stuck. A guard that isn't bound to a name lives until the statement ends, so read the session once:cargo xtask locksrefuses a second.session()in reach of the first.
Working rules (mandatory)
These apply to every change by every agent and contributor, whether or not anyone mentions them.
Roles and ownership
docs/ROADMAP.mdis the plan: each item has an id (R<milestone>.<n>), an owner, a status and pending changes (- [ ]lines). Owners are roles, never people's names: maintainers (the project's maintainers steer it; agents may take its unclaimed pending changes, but anything marked decision waits for a maintainer) or open (anyone may take it).- Claim before you start: put
— claimed: <name>, branch <branch>on the pending change and push your branch early (or open a draft PR) so others see it. Never take a change someone else has claimed. - Work in the order the roadmap's "Order and dependencies" table gives; an item starts only when its dependencies are done.
- A person's explicit instruction for a task overrides these rules for that task only; otherwise they apply to every change, without being asked.
Before you write code
- Pick work from
docs/ROADMAP.mdonly. Don't start an item that is claimed,blocked, or waiting on a decision, and don't start one whose dependencies aren't done. - Claim the pending change first (name + branch, in its own small commit), so no two agents do the same work.
- Read the code you'll touch and check STATUS.md and the roadmap for gaps it depends on. If you find new gaps or dependencies, add them to the roadmap rather than widening your change.
Git workflow
- Never commit to
main. Branch from an up-to-datemainwith a standard prefix, then the roadmap id if there is one:feature/,bugfix/,hotfix/(urgent fix to released code),refactor/,docs/,test/orchore/(tooling, deps, CI). Example:feature/r1.1-target-kind. - One roadmap item (or pending change) per PR. Keep PRs small and reviewable. No unrelated refactors or drive-by formatting.
- Open a PR into
main. It is squash-merged, so the PR title is the commit message: plain English, present tense, what changed for the person or developer. - Rebase on
mainbefore asking for review. Never force-push someone else's branch. - Parallel agents work in their own git worktree and their own
CARGO_TARGET_DIR(see "Parallel agents" below). - Before every commit and push, check
git branch --show-current; push by name (git push origin <branch>).
Architecture
- Headless first. Every capability works without the GUI: engine → tools → CLI/MCP, with the GUI as one
thin client. Orchestration, persistence and process control never live in
ui-eguiorapps/*. If the UI needs something, it calls the same engine API (or tool) the CLI does. - Extend through seams. New target kinds, checks, builders, asset providers and engines are trait
implementations registered in one place. Don't add another arm to a
matchover a closed enum. Prefer traits and generics with sensible built-in implementations, so forks can swap parts without editing core code. - Data over code. Catalogues (stacks, engine recipes, model ids, prices, install pins) are typed tables, not string matches or prompt text.
- Structured results. Decide on typed fields, never on English text.
- Versioned files. Anything we persist has a version field, a schema and a migration path.
- Respect the layers (
cargo xtask layers); put code at the lowest layer that can own it.
Done means
- The checks in "Before you finish" pass for the crates you touched. New behaviour has tests; crash fixes have regression tests.
- Docs updated in the same PR: the roadmap item ticked, STATUS.md if what works changed,
docs/tools.mdif you added tools. - Report what you verified and what you didn't. Never claim a live run you didn't do.
- Made a mistake worth not repeating? Add it to
docs/pitfalls.mdin the same PR. - Found work that's missing or left for later? Add it as a
- [ ]line under its roadmap item in the same PR (cargo xtask pendinglists all open work).
Extending
docs/extending.md says where each kind of addition goes (tools, target kinds, checks, stacks, coding agents,
asset providers, engines, plugins).
Pitfalls
docs/pitfalls.md lists mistakes already made here (git, tests, builds, design) and the rule for each.
It is part of these rules: read it before your first change (Claude Code loads it automatically through
CLAUDE.md).
Before you finish
cargo fmt --all
cargo build -p craft-anything-cli # if you touched crates/ai: two of its tests start this helper
cargo test -p <crates you touched>
cargo clippy -p <crates> --all-targets -- -D warnings
cargo xtask layers
cargo xtask locks
cargo xtask secrets # no keys, tokens or local paths in what you commit
cargo xtask wasm # if you touched L0–L2
cargo xtask tools # if you added tools (commit docs/tools.md)Then append a terse entry to log/devlog.md (what landed, numbers, what's still open). log/ is gitignored:
the devlog is a local scratch record; anything others need goes in the PR, docs/STATUS.md or docs/ROADMAP.md.
Parallel agents
Own target dir (CARGO_TARGET_DIR=target/agent-<name>), own files. Shared files (engine/src/tools/mod.rs,
engine/src/lib.rs, workspace Cargo.toml) get small surgical edits; re-read right before editing. Write manifests
atomically (temp file outside crates/, then mv). If someone else's edit breaks the build, wait and retry.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

