Imported from Encapsul/daedalus (
docs/AGENTS.md). Install upstream withnpx skills add Encapsul/daedalus --skill docs. Copyright stays with the author.
AGENTS.md
Project
daedalus packages any app into a single self-extracting ELF binary. Rust workspace (3 crates): daedalus-core (library), daedalus-cli (CLI, cross-platform), daedalus-stub (launcher, Linux-only).
Critical gotchas
- vfat filesystem: repo lives on vfat (no exec bit). Cargo target dir is
/tmp/daedalus-stub-target(set in.cargo/config.toml). Build artifacts cannot live in the repo tree. - PATH: tools installed in
~/.local/bin. Prefix withexport PATH="$HOME/.local/bin:$PATH"when running pip-installed tools. - musl target: stub builds with
--target $(uname -m)-unknown-linux-muslfor static linking. Requiresrustup target addand a C compiler (musl-tools on Ubuntu). - CI runs clippy per-crate, not workspace-wide:
cargo clippy -p daedalus-core --all-targets -- -D warnings, then same fordaedalus-stub, thendaedalus-cli.
Commands
Rust (primary)
cargo fmt --check # format check
cargo clippy --all-targets -- -D warnings # lint (MUST pass before commit)
cargo test --workspace # all tests
cargo build --release # release build
cargo audit # dependency vulnerabilities (run in CI)
Python (legacy CLI in cli/, deprecated)
This directory has been removed. The Rust CLI (daedalus-cli) is now the only CLI.
# No Python CLI to lint/test — removed
Verification loop (MANDATORY before finishing any change)
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test --workspace
Architecture
Binary format (daedalus-core/src/format.rs)
Layout: [stub][payload][metadata][footer]
- Footer magic:
0xBEEF_CAFE, format magic:DAE\x01 - Integrity hash:
SHA-256(payload || meta_bytes)— computed at build, verified at runtime - Format versions: v2 (plain), v3 (signed), v4 (encrypted), v5 (squashfs)
Stub launcher (stub/src/main.rs)
Reads footer+metadata from /proc/self/exe → cache check → SHA-256 verify → extract (zstd+tar or squashfs) to ~/.cache/daedalus/<hash>/rootfs/ → execvp entrypoint.
Entrypoint resolution in detect.rs:resolve_entrypoint():
- Python:
["python3", "/app/app.py"](interpreter bare on PATH, app path absolute) - Node:
["node", "/app/index.js"] - Go/Binary:
["/app/app"]
Unsafe boundary
daedalus-coreanddaedalus-cli: zerounsafe. Memory safety via Rust type system.stub/src/main.rs: the only crate withunsafe. Allunsafeblocks MUST haveSAFETYcomments. Nounsafeoutside FFI calls andstatic mut.
Code style (high-signal)
- Edition 2021,
cargo fmtis authoritative.max_width = 100instub/rustfmt.toml. - Release profile:
opt-level = "z", LTO, strip,panic = "abort"— tiny binaries. - Clippy pedantic subset — do NOT add new
#[allow]without a comment. Seedaedalus-core/Cargo.toml [lints.clippy]. - Rust functions: ≤ 30 lines. Python functions: ≤ 40 lines.
- Functions with >7 params: use a config struct.
- Prefer
Result::ok()over|e| e.ok(). Preferif let Some(v)overmatchwithNone => {}. - Comments explain WHY, never WHAT.
Security rules (ANSSI-Rust, MUST follow)
- DENV-STABLE: stable toolchain only, never nightly/beta.
- No
panic!()in library code. PreferResult<T, E>. - No
unwrap()/expect()indaedalus-corewithout context. - Use checked/wrapping/saturating arithmetic where overflow is possible.
- No
mem::forgetor.leak()(memory leak). - All FFI calls MUST have safe wrappers.
- Ed25519 keys must have the Ed25519 bit set (CVE-2023-48022).
- No hardcoded secrets anywhere.
Boundaries
Always do:
- Rebuild after every code change:
cargo build --releasebefore testing daedalus on an app. - Run verification loop before committing.
- Preserve the
.daedalusfooter format (magic constants informat.rs). - Verify any auto-fix from
cargo clippy --fixmanually (ANSSI DENV-AUTOFIX).
Never do:
- Commit secrets, keys, or
.envfiles. - Change the
.daedalusbinary format without updatingformat.rsversion constants. - Remove clippy allows from
Cargo.tomlwithout understanding why. - Use
unsafeindaedalus-coreordaedalus-cli. - Override
debug-assertionsoroverflow-checksin profiles. - Panic in library code or leak memory.
Ask first:
- Modifying
stub/src/main.rs— security-critical launcher. - Changing encryption/signing logic in
encrypt.rs. - Adding new
unsafeblocks or FFI bindings.
Agent workflow (growth edge)
Rules distilled from the Paxel builder-profile review. They bind BOTH sides: the operator and the agent.
Plan before execution:
- Before starting a multi-step task, state a short plan up front: goal, likely failure points, the exact commands to run, and what "done" means (a pass on the verification loop, an artifact that runs, etc.). Do not start editing before the plan is stated.
- When redirecting mid-task, first report the current state: what is done, what is committed/pushed, and the cheapest validation step. No new large direction change before validating where the work actually stands.
Close the loop after environment fixes:
- After fixing PATH / toolchain / installed-dependency issues, ALWAYS re-verify final success and capture the proof in the session: the successful command output (or exit code) that shows the fix worked. A "it should work now" is not done — a green result is done.
Testing
- Unit tests:
#[cfg(test)] mod testsin each module. - Integration tests:
daedalus-cli/tests/useassert_cmd. cargo test --workspacefor all Rust tests.daedalus-clidepends onreqwest(blocking,rustls-tlsfeature) — no OpenSSL dependency.
Git conventions
- Branches:
feat/*,fix/*,dev,main. - Commits: signed (
git commit -S), conventional format (feat:,fix:,chore:). - PRs: must pass clippy + fmt + tests before merge.
Other instruction files
CLAUDE.md— Claude Code specific guidance (agents/commands/skills pattern).CODE_STYLE.md— detailed style rules with rationale.RULES.md— ANSSI-Rust rules (also in.cursor/rules/format).HANDOFF.md— project status, known build constraints, performance data..opencode/— agents, skills, and commands for OpenCode sessions.