This file provides guidance for AI assistants (Claude Code, Codex, etc.) working with Vibehouse.
Vibehouse is a fork of Lighthouse from v8.0.1 (post-Fulu).
- Read
PLAN.mdfirst - it defines the work process, priorities, and phase status - Read
docs/tasks/- active task docs with detailed progress logs - Read
docs/workstreams/- implementation design docs and reference - All work must be tracked in committed markdown docs (see plan.md "documentation-driven development")
- Commit messages: lowercase, human-readable, no conventional commits
- Branch from
main(notunstable- that's upstream's branch) - Origin:
dapplion/vibehouse ⚠️ NO UPSTREAM SYNC. NEVER cherry-pick, merge, or pull ANY code from sigp/lighthouse after v8.0.1. vibehouse is an independent project, not a tracking fork. We write ALL our own code. If upstream has a useful fix, understand the problem and implement our own solution from scratch. Do not reference upstream diffs. Do not rungit cherry-pick. Do not add sigp/lighthouse as a remote.⚠️ NO EXTERNAL INTERACTIONS. NEVER comment on, open, or modify issues/PRs on ANY repo other than dapplion/vibehouse. Do not usegh issue comment,gh pr comment, orgh apito write to external repos. You may READ external issues/PRs for awareness, but NEVER write to them. This includes sigp/lighthouse, ethereum/consensus-specs, and any other repo. Only dapplion can interact with external projects.
The rest of this file is inherited from the Lighthouse v8.0.1 fork point and still applies to code quality standards.
# Build
cargo build --release
# Lint
cargo fmt --all && make lint-fix
make lintNever run make test-ef or make test-full routinely. Pick the command that matches the code you touched.
EF spec test feature flags:
ef_tests— required to run any EF testsfake_crypto— skips BLS signature verification, 2-3x fasterminimal_testing— skips mainnet preset, only runs minimal (much faster)
cargo nextest run --release -p types
cargo nextest run --release -p ef_tests --features "ef_tests,fake_crypto,minimal_testing" -E 'test(/^ssz_static/)'cargo nextest run --release -p state_processing
cargo nextest run --release -p ef_tests --features "ef_tests,fake_crypto,minimal_testing" -E 'test(/^operations_|^epoch_processing_|^sanity_/)'For a single operation (e.g. withdrawals):
cargo nextest run --release -p ef_tests --features "ef_tests,fake_crypto,minimal_testing" -E 'test(operations_withdrawals)'cargo nextest run --release -p proto_array
cargo nextest run --release -p fork_choice
cargo nextest run --release -p ef_tests --features "ef_tests,minimal_testing" -E 'test(/^fork_choice_/)'Fork choice tests need real crypto (no fake_crypto).
env FORK_NAME=gloas cargo nextest run --release --features "fork_from_env" -p networkenv FORK_NAME=gloas cargo nextest run --release --features "fork_from_env,slasher/lmdb" -p beacon_chainenv FORK_NAME=fulu cargo nextest run --release --features "beacon_chain/fork_from_env" -p http_apienv FORK_NAME=gloas cargo nextest run --release --features "beacon_chain/fork_from_env" -p operation_poolcargo nextest run --release -p validator_clientcargo nextest run --workspace --release --exclude ef_tests --exclude beacon_chain --exclude slasher --exclude network --exclude http_api --exclude web3signer_testscargo nextest run --release -p ef_tests --features "ef_tests,minimal_testing"
cargo nextest run --release -p ef_tests --features "ef_tests,fake_crypto,minimal_testing"cargo nextest run --release -p ef_tests --features "ef_tests"
cargo nextest run --release -p ef_tests --features "ef_tests,fake_crypto"Read the relevant guide for your task:
| Task | Read This First |
|---|---|
| Code review | .ai/CODE_REVIEW.md |
| Creating issues/PRs | .ai/ISSUES.md |
| Development patterns | .ai/DEVELOPMENT.md |
// NEVER
let value = option.unwrap();
let item = array[1];
// ALWAYS
let value = option?;
let item = array.get(1)?;Only acceptable during startup for CLI/config validation.
In consensus/ (excluding types/), use saturating or checked arithmetic:
// NEVER
let result = a + b;
// ALWAYS
let result = a.saturating_add(b);// NEVER
async fn handler() { expensive_computation(); }
// ALWAYS
async fn handler() {
tokio::task::spawn_blocking(|| expensive_computation()).await?;
}Document lock ordering to avoid deadlocks. See canonical_head.rs:9-32 for the pattern.
Use scoped rayon pools from beacon processor, not global pool. Global pool causes CPU oversubscription when beacon processor has allocated all CPUs.
All TODO comments must link to a GitHub issue.
Avoid ambiguous abbreviations (bb, bl). Use beacon_block, blob.
- Branch from
unstable, targetunstablefor PRs - Run
cargo sortwhen adding dependencies - Run
make cli-localwhen updating CLI flags
beacon_node/ # Consensus client
beacon_chain/ # State transition logic
store/ # Database (hot/cold)
network/ # P2P networking
execution_layer/ # EL integration
validator_client/ # Validator duties
consensus/
types/ # Core data structures
fork_choice/ # Proto-array
See .ai/DEVELOPMENT.md for detailed architecture.
These AI docs should evolve based on real interactions.
If a developer corrects your review feedback or points out something you missed:
- Ask: "Should I update
.ai/CODE_REVIEW.mdwith this lesson?" - Add to the "Common Review Patterns" or create a new "Lessons Learned" entry
- Include: what went wrong, what the feedback was, what to do differently
If a developer refines your PR description or issue format:
- Ask: "Should I update
.ai/ISSUES.mdto capture this?" - Document the preferred style or format
If you learn something about the codebase architecture or patterns:
- Ask: "Should I update
.ai/DEVELOPMENT.mdwith this?" - Add to relevant section or create new patterns
### Lesson: [Brief Title]
**Context:** [What task were you doing?]
**Issue:** [What went wrong or was corrected?]
**Learning:** [What to do differently next time]- Minor preference differences (not worth documenting)
- One-off edge cases unlikely to recur
- Already covered by existing documentation
# Build Docker image (fast — uses host cargo cache, ~30s incremental)
scripts/build-docker.sh
# Run full devnet lifecycle (build + start + assertoor check + teardown)
scripts/kurtosis-run.sh
# Skip build (reuse existing vibehouse:local image)
scripts/kurtosis-run.sh --no-build
# Leave enclave running after test (for manual inspection)
scripts/kurtosis-run.sh --no-teardown
# Genesis sync test (stop non-validators, finalize, restart, verify sync)
scripts/kurtosis-run.sh --sync
# Node churn test (kill validator, verify chain continues, restart, verify recovery)
scripts/kurtosis-run.sh --churn
# Mainnet preset test (32 slots/epoch, 12s slots, 512 validators, ~40 min)
scripts/kurtosis-run.sh --mainnet
# Long-running test (30+ min, epoch 50, resource monitoring, ~40 min)
scripts/kurtosis-run.sh --long
# Network partition test (stop 2/4 nodes, verify stall, heal, verify recovery)
scripts/kurtosis-run.sh --partition
# Heze fork test (Gloas@epoch1, Heze/FOCIL@epoch3, verify fork transition)
scripts/kurtosis-run.sh --heze- Minimal preset: 8 slots/epoch, 6s/slot
- Gloas (ePBS) fork at epoch 1 (slot 8)
- 4 nodes: vibehouse CL + geth EL, spamoor (tx load), dora (explorer)
- Script polls beacon API directly for health (no assertoor — it doesn't understand gloas yet)
- Success = finalized epoch >= 8 (sustained chain health across 4 nodes)
- 12-minute timeout with stall detection (chain stuck for 36s = fail)
- All logs go to
/tmp/kurtosis-runs/<RUN_ID>/with separate files
- Make code change
- Run
scripts/kurtosis-run.sh - On failure: read logs in
/tmp/kurtosis-runs/<RUN_ID>/— checkhealth.logfirst, thendump/CL logs, then EL logs - Fix the issue
- Repeat
See docs/devnet-checks.md for the full list of checks an agent should perform when debugging.
- Fork transition failures: Check CL logs around epoch 1 boundary (slot 8)
- Self-build envelope errors: Check
process_self_build_envelopeandget_execution_payloadpaths - Engine API failures: Check EL logs for
newPayload/forkchoiceUpdatederrors - Stale head hash: Gloas uses fork choice head_hash, not
state.latest_block_hash() - Block production 400s: VC getting 400 from
/eth/v3/validator/blocks/{slot}— check CL block production logs
- NEVER use the main
Dockerfilefor dev builds — it does a full Rust rebuild in Docker (5-10 min) - NEVER run
kurtosis rundirectly — old enclaves accumulate and waste resources - ALWAYS use
scripts/kurtosis-run.sh— it handles cleanup, health polling, and timeout - ALWAYS use
scripts/build-docker.sh— it builds on host with incremental cargo cache