Contributing

Project · Source: CONTRIBUTING.md

Contributing to cubby.network

Thanks for your interest in contributing. This project is an open-source, deterministic NetOps control plane with an LLM-driven agent layer on top. Because the harness eventually controls real production networks, code quality and safety bars are high. This document explains how to work in the repo and what we expect from a pull request.

TL;DR

  1. Fork the repo and create a feature branch off main.
  2. Run pytest locally — the suite must be green before you push.
  3. Add tests for everything you change. Adapters and validators must ship with golden fixture coverage.
  4. Open a PR that explains the why, not just the what. Link any related issue or architecture decision record (ADR).
  5. Sign off every commit with a DCO line (git commit -s).

Branching, versioning, and releases

We use GitHub Flow with semantic-version tags:

Developer Certificate of Origin (DCO)

By contributing you certify that your contribution is made under the terms of the Developer Certificate of Origin 1.1. Sign off every commit:

git commit -s -m "feat: …"

This appends Signed-off-by: Your Name <you@example.com> to the commit message. The DCO bot on GitHub checks every PR.

Project layout

PathWhat lives there
apps/api, apps/cli, apps/worker, apps/schedulerProcess entry points.
packages/domainTyped entities, enums, dataclasses. The single source of truth for shapes.
packages/sdkPlugin contracts (ABCs), the registry, and SDK errors. Every plugin must inherit from the matching ABC and set simulated.
packages/orchestratorWorkflow state machine, evidence service, signing.
packages/policy, packages/validation, packages/execution, packages/verificationThe deterministic core.
packages/stateAuthoritative intended/observed state, topology graph store.
packages/discoveryBoot-crawl: BFS LLDP/CDP/SNMP probing.
packages/transportOne interface for SSH/NETCONF/RESTCONF/gNMI/SNMP/REST. Adapters compose transports.
packages/knowledgeDocument store, embeddings, retrieval.
packages/agentsLLM-backed reasoning workers + safety gate. Agents are read-only.
packages/autonomyDigital twin, forecasting, multi-agent coordinator, self-improvement.
plugins/device, plugins/auth, plugins/inventory, plugins/telemetry, plugins/ticketing, plugins/validators, plugins/knowledge_ingestors, plugins/workflow_packsConcrete adapters and packs. Add new vendors here.
tests/unit, tests/contract, tests/integrationTest tiers. Unit tests must run offline.

Hard rules

These are non-negotiable. PRs violating them will be sent back without deeper review.

Adding a new device adapter

  1. Create plugins/device/<vendor>_<os>/. Inherit from packages.sdk.contracts.DeviceAdapter and set:
    • name, vendor, os_family, transports,
    • simulated = False (or True if you can't reach a real device yet),
    • capabilities (frozenset of snapshot, render, precheck, execute, rollback, verify).
  2. Compose a Transport from packages.transport. Don't import scrapli directly — request the right transport from the registry.
  3. Write parsers in plugins/device/<vendor>_<os>/parsers.py. Pure functions, no I/O. Cover them with golden tests under tests/unit/plugins/device/<vendor>_<os>/test_parsers.py using captured real device output stored in tests/fixtures/<vendor>/<os>/.
  4. Wire the adapter into packages/orchestrator/bootstrap.py so the registry knows about it.
  5. Add an integration test under tests/integration/plugins/device/... marked @pytest.mark.devicelab. It must skip cleanly when NETOPS_DEVICELAB is not set.

Adding a new validator

  1. Create plugins/validators/<name>/plugin.py. Inherit from ValidatorPlugin and implement supports() and validate(). Return a dict with findings, risk_score, blast_radius.
  2. If your validator is a wrapper around an external system (Batfish, lab emulator), set simulated accurately and put the heavy code path behind an extras dependency.
  3. Add unit tests under tests/unit/plugins/validators/<name>/.

Adding a workflow pack

Workflow packs are pure metadata. Create plugins/workflow_packs/<name>/pack.py with the required attributes from WorkflowPack. The orchestrator picks up new packs automatically once they are registered in bootstrap.build_demo_harness.

Tests and CI

Run pytest -q before pushing. CI runs the same suite plus linters.

Style

Commit messages

Use imperative present tense ("Add NX-OS adapter", not "Added"). Keep the subject under 72 characters. The body should explain why the change matters.

Reporting security issues

Do not open a public GitHub issue. See SECURITY.md.

Code of conduct

Be kind, be professional, assume good faith. The full text is in CODE_OF_CONDUCT.md.