decdn-cli 0.0.4

User-facing deCDN CLI (decdn binary): probe, fetch, pools, publishing, origin import, node admin
# Maintaining `TERMS.md`

`TERMS.md` is the **canonical operator terms** — the single source of the terms
text the node software embeds and displays at registration. Its exact bytes are
the preimage of the on-chain `termsHash`: the registration clickwrap records
`keccak256(<bytes of TERMS.md>)` (see ADR 019 § Operator Safety Obligations).

**This file (`TERMS_README.md`) is not embedded or hashed** — it is maintainer
guidance only. Keep all developer notes here, never inside `TERMS.md`, so that
editing guidance can never perturb the terms hash.

Both files live in `crates/cli/` rather than at the repo root because
`crates/cli/src/commands/terms.rs` embeds `TERMS.md` with `include_str!`, which
cannot reach outside its own package — from the repo root the path would be
unreachable in the published `.crate` and `cargo install decdn-cli` would fail
to build.

## Rules

- **Any byte change to `TERMS.md` changes the hash.** A new version becomes
  canonical only when governance sets `currentTermsHash` to the new hash
  (`DecdnGovernor` + timelock). Until then, a node built against the new text
  would submit a hash that `registerNode` rejects.
- **Do not paraphrase the terms in code or docs** — reference them by version.
- Bump the `Version:` line in `TERMS.md` for any substantive change so the
  accepted version is self-identifying.
- The embedding/clickwrap wiring (display + `keccak256` + acceptance) lives in
  `crates/cli/src/commands/terms.rs`. A `#[test]` there locks the embedded hash
  to a literal, so any edit to `TERMS.md` fails the test suite until that literal
  is updated too — deliberately, since a terms change is a gated event that must
  be paired with a governance `setCurrentTermsHash` bump.