fix(config): validate runtime settings before startup side effects

RM
4d ago
+481-63

User description

Closes #67

Summary

  • Add one public, side-effect-free DaemonConfig::validate() gate used by TOML loading, daemon constructors, and checkpoint restoration. Timed and bounded runs now require valid configuration at construction, rather than checking tick frequency after startup.
  • Enforce the existing tick range 1..=1_000_000, checked neuron-count arithmetic and 1..=65_535 total neurons, nonzero channels bounded by ingress.max_payload_len, and a documented cap of 1,048,576 neuron×channel slots. Reject multiplication overflow without allocating a network. Preserve simulation with either neuron type and the supported LIF-only live checkpoint path.
  • Validate ingress settings, control bind syntax, PUB host syntax and bounded PUB settings before the binary creates its runtime, restores a checkpoint, initializes sources, or binds sockets. Keep the default stub independent of libzmq. Print the full validation cause in CLI startup errors.
  • Document tightened configuration contracts and migration, including the raw-serde/custom-backend responsibility boundary. Retain exit status 1 and provide explicit bounded systemd restart guidance (RestartSec=5s, three starts per 60 seconds), rather than claiming that earlier rejection alone stops restart loops.
  • Add CLI and public-entry-point regressions and preserve minimal simulation/boundary and existing live-fixture coverage. Update two legacy TOML test fixtures to explicitly request simulation when using Izhikevich cells.
  • Add an idempotent .agents/setup because the fresh orb lacked Rust; it installs the repository-pinned toolchain/components and optional ZeroMQ build prerequisites without changing toolchain pins or default features.

Verification

All checks passed locally on Rust 1.98.1 / Linux:

  • cargo fmt --check — clean.
  • cargo clippy --locked --all-targets -- -D warnings — zero warnings.
  • cargo build --locked — passed.
  • cargo test --locked — 156 unit tests and the CLI integration test passed; the existing process-wide SIGTERM test remains intentionally ignored.
  • CC=gcc CXX=g++ cargo clippy --locked --all-targets --all-features -- -D warnings — zero warnings.
  • CC=gcc CXX=g++ cargo build --locked --all-features — passed.
  • CC=gcc CXX=g++ cargo test --locked --all-features — 178 unit tests, the CLI integration test, and all 9 Thalamic smoke tests passed; the same existing SIGTERM test remains ignored.
  • Real CLI regressions hold a bind port occupied and use a missing checkpoint: invalid tick rate/dimensions/live mode/endpoints exit 1 with the offending field before runtime logging, checkpoint failures, or bind errors.
  • Minimal 1-neuron/1-channel simulation CLI with corpus-ipc stayed running and handled SIGTERM with exit 0.
  • Extracted README service example passed systemd-analyze verify --man=no using the built binary as ExecStart. This verifies syntax, not a live systemd restart cycle.
  • .agents/setup passed bash -n and two executions (warm run ~0.4 seconds); a clean login shell finds Rust 1.98.1.
  • git diff --check — clean.

Regression tests were observed failing before the fixes (invalid tick rate accepted at load, CLI hiding the cause, malformed bracketed IPv4 PUB host accepted).

Release qualification / scope

Part of 02 — v0.3.0 release qualification. Local acceptance work is complete; the unchanged GitHub Actions matrix will verify Linux/macOS/Windows default builds and Linux corpus-ipc on this PR. No merge or release is performed.

Validation cannot undo side effects in a backend pair already constructed by a library caller; callers can invoke validate() first. Host syntax validation does not perform DNS resolution or guarantee that a syntactically valid bind address is available. Invalid configuration still exits 1, so supervisors must use the documented restart/start limits.

Devin Review


Summary by cubic

Moves all runtime configuration validation to a single public DaemonConfig::validate() gate that runs before any network allocation, checkpoint read, backend or socket startup, so invalid settings fail at load or construction instead of after startup.

  • Enforces tick rate 1..=1_000_000, neuron total 1..=65_535, nonzero channels bounded by ingress.max_payload_len, and a MAX_NETWORK_INPUTS cap of 1,048,576 neuron×channel slots with checked arithmetic and operand details on overflow.
  • Validates ingress settings, control_bind syntax, and PUB bind host/options early; digit-and-dot-only names that are malformed IPv4 literals (for example 5555 or 999.999.999.999) are rejected before socket startup, while numeric-TLD hostnames like pub.example.123 stay accepted. CLI errors print the full offending field.
  • Splits validation into focused helpers (validate_dimensions, validate_pub_bind_host, is_dns_label) and reorganizes tests into table-driven fixtures; no behavior change.
  • Adds an idempotent .agents/setup for the pinned Rust toolchain and build prerequisites, including curl for the rustup bootstrap, and documents the tightened config contracts, migration steps, and bounded systemd restart guidance.

CodeAnt-AI Description

Reject invalid daemon settings before startup

What Changed

  • Settings are checked before checkpoint access, network creation, backend setup, or socket startup. Invalid tick rates, ingress settings, and control or PUB bind addresses now fail early.
  • Neuron and channel limits are checked together; overflow and networks exceeding 1,048,576 neuron-channel slots are rejected before allocation. Live mode continues to require LIF-only networks.
  • The CLI reports the validation cause and exits with status 1. The configuration guide now explains the limits and bounded systemd restart guidance.

Impact

✅ Invalid settings fail before socket or checkpoint startup
✅ Oversized networks are rejected before allocation
✅ Startup errors identify the invalid setting

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.