montana/Montana-Protocol/Code/AGENTS.md
2026-05-21 03:44:38 +03:00

12 KiB
Raw Blame History

AGENTS.md — entry point for AI agents and security researchers

This document is the canonical entry point for any AI agent or human researcher who wants to deploy a Montana node, stress-test it, audit the code, and report findings. Read top-to-bottom; commands are copy-paste ready.

What Montana is, in 60 seconds

Montana is a from-scratch post-quantum blockchain. Three architectural primitives:

  1. Sequential-delay TimeChain — globally-ordered windows of ~60 seconds each, sealed by a sequential SHA-256 chain (D = 325 000 000 iterations per window). Cannot be parallelized, cannot be skipped. Verification costs the same order of work as computation, so this is not a VDF in the efficient-verification literature sense.
  2. Time-as-scarcity — anti-spam through window-rate-limits, chain_length thresholds, seniority gating. No transaction fees. No gas. Cannot accelerate operations by paying.
  3. Post-quantum where the protocol currently claims it — ML-DSA-65 (FIPS 204) for consensus signatures, ML-KEM-768 (FIPS 203) at the application layer, SHA-256 for hashing and TimeChain, PBKDF2 for key derivation. Transport confidentiality is tracked separately through the Noise_PQ migration.

Spec is the single source of truth: ../Montana Protocol v35.25.1.md. ~600 KB markdown, full protocol specification.

Status

Pre-mainnet v0.2. No mainnet date. No token launch. No premine. The implementation is M1-M6 + M9 ready for external audit; M8 (node binary) is still in progress, with known deviations and closures tracked in docs/SPEC_DEVIATIONS.md. DEV-012 (multi-node proposal apply in the node binary) remains the current mainnet blocker.

Singleton means: each deployed node is its own genesis bootstrap, ticking TimeChain locally and writing its own state. Until multi-node proposal apply is wired into the binary, nodes do not provide production BFT consensus.

This is intentional for v0.2 — it lets you deploy and break a Montana node end-to-end without needing a production network of peers.


Deploy

One command on a clean Linux VPS (Ubuntu 24.04 / Debian 12 / Fedora / Alpine)

git clone https://github.com/efir369999/Montana.git /opt/montana && \
sudo bash /opt/montana/Code/scripts/install-vps-full.sh

What this does (≈10 minutes on a 1 vCPU VPS):

  1. Installs system deps (build-essential, clang, git, perl, ca-certificates)
  2. Installs Rust toolchain (rustup, stable channel)
  3. Builds montana-node from source (cargo build --release -p montana-node)
  4. Creates system user montana and /var/lib/montana
  5. Generates 24-word recovery mnemonic and prints it once — save it immediately, no second chance
  6. Installs systemd unit with hardening (User=montana, NoNewPrivileges, ProtectSystem=strict)
  7. Starts montana-node.service
  8. Installs xray Reality VPN endpoint as a separate systemd service (optional, runs alongside the node — see montana-vpn/README.md)

After install:

systemctl status montana-node            # is it running
journalctl -u montana-node -f            # live logs (one line per ~60s window)
montana-node status --data-dir /var/lib/montana    # phase, balance, current_window

Just the node, no VPN

sudo bash /opt/montana/Code/scripts/install-vps.sh

Just the VPN, no node

sudo bash /opt/montana/Code/montana-vpn/install.sh

macOS (Apple Silicon)

git clone https://github.com/efir369999/Montana.git ~/Montana && \
bash ~/Montana/Code/scripts/install-local-mac.sh

This installs the node under ~/Library/Application Support/Montana/node/ with a launchd agent.

Build from source manually

See docs/build-from-source.md for the reproducible-build path. Short version:

cd Code
cargo build --release -p montana-node
./target/release/montana-node --help

Verify the node is healthy

After 5 minutes of running:

montana-node status --data-dir /var/lib/montana

Expected output (numbers will differ):

phase                : Active
current_window       : 5
D (current)          : 325000000
NodeTable            : 1 records
balance              : 65000000000 nɈ      (5 windows × 13 Ɉ baseline emission)
supply (closed-form) : 78000000000 nɈ      (must equal Σ balance + future emission curve)

Healthy invariants:

  • phase == Active (genesis bootstrap activates immediately, no Candidate VDF wait)
  • current_window increases by exactly 1 per ~60 seconds
  • Σ balance == supply (closed-form) × correction-for-emission-schedule
  • state_root after each apply_proposal byte-equals the expected recompute (logged at INFO level)

Pathological signs (file an Issue):

  • Phase regresses (Active → Bootstrap)
  • current_window stops advancing for >2 minutes
  • state_root mismatch in logs
  • Process panics or OOMs
  • Disk usage grows >10 MiB per hour (it should be ~50 KiB per hour)

Stress test — what to throw at it

We have not stress-tested at scale. Here is what would help:

1. VDF correctness under chaos

Kill the node mid-window and restart. State must resume from the last cemented window without divergence. Repeat 100×, automate with kill -9 + immediate systemctl start.

for i in {1..100}; do
  systemctl restart montana-node
  sleep $((RANDOM % 30 + 5))
  systemctl kill -s KILL montana-node
done
journalctl -u montana-node --since "10 minutes ago" | grep -iE 'panic|error|state_root mismatch'

Expected: zero panic, zero state_root mismatch. Any divergence = blocker-level finding.

2. Disk-full handling

Fill /var/lib/montana to 100% mid-operation. Node must fail gracefully, not corrupt state.

fallocate -l $(df --output=avail /var/lib/montana | tail -1)k /var/lib/montana/_filler
journalctl -u montana-node -f
# clean up:
rm /var/lib/montana/_filler

3. Clock skew

Set system clock backwards 1 hour mid-operation. Node uses VDF iterations as the clock, not wall-time, so it should ignore the jump.

date -s "$(date -d '1 hour ago')"
sleep 120
date -s "$(date)"   # let NTP correct it back
journalctl -u montana-node --since "5 minutes ago"

Expected: no behavior change. Wall-time is not consensus-critical.

4. Determinism — two nodes, same mnemonic, same state_root

Critical. If two independent installs of the same git rev with the same seed mnemonic produce different state_root after N windows — that is a consensus-fork bug.

# on host A:
montana-node init --data-dir /tmp/a --mnemonic "<same 24 words>"
montana-node start --data-dir /tmp/a --max-windows 100 --d-test-override 1000

# on host B:
montana-node init --data-dir /tmp/b --mnemonic "<same 24 words>"
montana-node start --data-dir /tmp/b --max-windows 100 --d-test-override 1000

# compare:
diff <(sha256sum /tmp/a/proposals/*.bin) <(sha256sum /tmp/b/proposals/*.bin)

Expected: identical SHA-256 sums for every proposal. Any diff = consensus-fork-level finding.

5. Memory / CPU profiling

Run the node for 24 hours. Monitor RSS over time.

while true; do
  ps -p $(pgrep montana-node) -o rss=,vsz= >> /tmp/montana-mem.log
  sleep 60
done

Expected: RSS ≈ stable around 30-50 MiB (peak ~100 MiB during VDF burst). Continuous growth >1 MiB/hour = leak.

6. Fuzz inputs to apply_proposal

The state machine apply_proposal(state, proposal) → state' must reject malformed input deterministically. Use cargo-fuzz:

cd Code
cargo install cargo-fuzz
cargo fuzz run apply_proposal_arbitrary -- -max_total_time=3600

(Fuzz harness scaffolding may not yet exist for every entry point — adding more = welcome PR.)


Audit the code against the spec

The spec is at ../Montana Protocol v35.25.1.md, authoritative.

Known deviations

docs/SPEC_DEVIATIONS.md lists known deviations, acknowledgments, and closures across the implementation. Each entry:

  • Spec quote
  • Code location
  • What the code actually does
  • Severity (mainnet blocker / medium / cosmetic)
  • Closure path

Any un-documented deviation you find = high-value finding. File as an Issue with:

  • Spec section + dossier line number
  • Code path (crates/<crate>/src/<file>:LLL)
  • Test that demonstrates the deviation
  • Suggested fix or "needs architect input"

Internal audit infrastructure

Spec-vs-code comments

Every consensus-critical decision in the code references the spec section it implements:

// spec, раздел "Consensus encoding layer"
fn encode(...) { ... }

Grep for // spec, раздел to find all anchored references:

rg "// spec, раздел" --type rust

Report findings

GitHub Issues + Pull Requests at https://github.com/efir369999/Montana

Issue template (free-form, no enforcement):

Title: [SEVERITY] short description

Severity: blocker / high / medium / low / informational

What you did:
  - command sequence to reproduce

What you expected:
  - per spec section X.Y, expected behavior is Z

What happened instead:
  - actual output / log excerpt / state diff

Spec reference:
  - Protokol/Montana Protocol v35.25.1.md, section "X.Y"

Suggested fix (if any):
  - <or "needs architect input">

PR template:

  • Reference the Issue this PR closes
  • Include test that fails before the fix and passes after
  • Update docs/SPEC_DEVIATIONS.md if closing a known deviation
  • Run cargo fmt + clippy + test --all + build --release (all must be green)

No NDA. No engagement contract. Public review by default.


Things that would be especially welcome

  • Fuzz harness for every public entry point (currently partial)
  • Property-based test coverage for apply_* functions (currently has unit + invariants, not property-based)
  • Differential testing harness comparing this Rust impl vs an independent re-implementation (Go / Python / Zig)
  • CI matrix across Linux x86_64 + ARM64 + macOS ARM64 + Windows (currently single-platform local)
  • Benchmark suite measuring VDF iter/sec across CPU classes (we have one micro-bench, not a suite)
  • Deterministic-replay framework (record all inputs to apply_proposal, replay byte-for-byte)
  • Side-channel analysis on PBKDF2 / signature verify (timing, cache, branching)
  • Audit of the crowdsec / fail2ban / ufw default rules for the VPS installer
  • Independent translation of the spec (currently RU primary, EN fragments)

What we will NOT do

  • We will not sell tokens. Not now, not at mainnet. Montana has no premine, no presale, no airdrop schedule. Block reward (13 Ɉ per window to operator) is the only emission, paid to whoever ran the VDF for that window.
  • We will not add fees. Anti-spam is time-based by architectural invariant [I-15] of the spec.
  • We will not add ECDSA / RSA / curve25519 fallback. Post-quantum from day one is invariant [I-1].
  • We will not add KYC, allowlist, or compliance backdoors. Privacy-by-default is invariant [privacy-default].

Contact


Pre-mainnet. Break it, fix it, send PRs.