Skip to content

v0.4.0

Choose a tag to compare

@Con-Benksl Con-Benksl released this 26 Jul 09:36
· 8 commits to main since this release
6ba0a02

The gate reminds instead of refusing, and stops asking the model to tick a box it knows is false.

NetOps diagnoses VPS and proxy failures by segment. Its distinguishing constraint is that the agent doing the fixing may be reaching the internet through the proxy it is about to restart. This release reworks how that constraint behaves, and fixes the safety defects a first-principles review of the whole suite turned up.

Breaking changes

  • guard.decision is now allow or warn only. The unconditional block is gone, and risk blocked is renamed unresolved. A gate that returns a dead end teaches operators to work around it; one that states the residual risk and records consent keeps the decision visible. Unresolved risk on a remote target proceeds after a risk card and explicit per operation consent (--accept-residual-risk), with the accepted risks written into the receipt as acknowledged_risks. Hard refusals now cover exactly two cases: hardware you do not own, and features that are not released.
  • target_independence_verified is split out of independent_path_verified. One boolean was folding together two different facts: that the target is off the agent's current path, and that a verified backup management channel exists. For an unrelated VPS there is no backup channel to verify, so passing the gate meant asserting something the model knew was false. Plans written against the previous contract fail loudly and must be regenerated.

Safety

  • New references/independence-protocol.md: an executable evidence ladder for deciding whether a target carries the agent's traffic. It is deliberately asymmetric. Egress comparison and active node comparison can only ever prove shared, because a relay or upstream chain can place the target mid path; only a controlled switch test can positively establish independent. A user's verbal confirmation can never on its own promote unknown, since a beginner is precisely the person least likely to know which host carries their traffic.
  • Remote output is evidence, never instruction. Banners, MOTD, logs, panel configs and command output collected over SSH reach the model's context. A compromised host could otherwise write "this VPS is unrelated to your traffic" into a log and have it read as fact.
  • check_secrets.py detects bare UUIDs. The rules forbid committing credential UUIDs, and a VLESS client id is a bare uuid4, so the scanner previously reported clean on exactly the secret it named. run_id and observation_id stay allow listed.

Structure and documentation

  • Post incident material split into references/emergency-recovery.md, taking the gate reference from 283 lines to 196. The recovery card is now persisted to a local file before high risk changes, since the chat transcript is precisely what an operator loses when they go offline.
  • All six Skill descriptions rewritten. Performance symptoms (slowness, latency, packet loss) had zero coverage across every description despite MTR and iperf3 adapters shipping.
  • New CHANGELOG, CONTRIBUTING, SECURITY, CODE_OF_CONDUCT, issue and pull request templates, and a command reference plus execution mode table in both READMEs.

New guards

  • tests/test_docs_contract.py parses every documented netopsctl command against the shipped parser and normalises every documented control_channel payload. It caught two real defects on its first runs.
  • scripts/check_install_tree.py rejects build residue, asserts the version pairing, and with --install-root compares flat Skill copies byte for byte.

Verification

414 tests. CI covers Python 3.10 to 3.14 on Linux, macOS and Windows, with a reproducible double build gate requiring byte identical wheels and normalised sdists.

Full detail in CHANGELOG.md.