Repository navigation
Answer known questions locally; gate egress; approve every key use - #13
Merged
Merged
Conversation
Local router: every prompt is classified on the operator's machine first. - an intent catalog (YAML, built-ins plus ~/.cometcli/intents) answers known questions — jailed validators, validator count, peers, sync, missed blocks, consensus, proposals, pending votes, rewards, balance, upgrade plan, slashing params — with read-only tools and a fixed template: no model call; repeats within 30s come from a cache - open-ended prompts, actions, long or multi-line prompts and anything the catalog doesn't clearly match go to the model; a failed lookup too - /incident triages locally; when one known case is clearly the root and has a playbook, cometcli runs it (changes and transactions still ask), records the incident and reports. A failed step hands over to the model with the triage and the steps done; a declined step stops - playbooks for node down, jailed for downtime, halt-height left set and container memory limit; kb show lists them - /llm forces the model, /route explains the routing, /cost counts local answers; agent.router: off disables it Egress gate, in front of every provider call: - key material (PEM/OpenSSH keys, consensus keys, BIP-39 mnemonics, keystores, file-keyring entries, private-key hex, API and bot tokens) withholds the whole message, in history too; a prompt with a mnemonic isn't sent at all - strict egress (default on validators): bash/read/grep/node.logs/fleet output reaches the model only as a local summary — identifiers masked, repeats folded, errors first; the UI and audit keep the raw output - keystore paths join the protected paths for the shell and file tools Key access: - every signature is approved on its own with the account, which key and where, the decoded messages, fee and the agent's stated reason; never auto-approved, audited as a key event; Telegram approvals of a key use expire in 5 minutes - the local keyring no longer signs during gas simulation — the key is untouched until the operator approves Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- shell guard: refuse deleting a node's data dir or stores (state reset, takes priv_validator_state.json with it), copying or dd onto priv_validator_state.json, interpreter scripts that touch it, and <chain>d start / init / rollback — a model with every approval granted ran all of these on a drill node - key_seed.json (evmd testnet's operator mnemonic) is protected key material - strict egress masks peer topology (node.peers, sec.exposure, fleet.status) - playbook conditions are checked against fresh signals: a halted node is jailed while the playbook runs - container-memory-limit and node-crash-loop explain val-in-set-while-syncing, so the playbook isn't handed to the model - the key use of a playbook step says which case and step it's for; raw-output steps are summarized by line count in the report - config set agent.router / agent.egress; profile values merge - init offers only persistent keyring backends (test is in-memory) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- fee denom and gas price come from the node's own app.toml (host home,
or inside the container) when the profile doesn't set them: a profile
made with profile add couldn't unjail ('no fee denom')
- profile add: --signer-mode, --container-home, --container-keyring, so
container signing works without init
- val-pvs-ahead no longer fires on healthy validators of a fast chain:
the chain height is read with the state file, and the case needs
evidence the node isn't signing
- triage collectors get 60s on SSH nodes (20s timed out across the WAN)
- gov propose defaults to a text proposal
- failed steps of local answers and playbooks render as errors
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- node.service stops docker nodes with a 60s grace period: docker's default 10s SIGKILLed evmd on every stop (exit 137) - node-killed-sigkill (a forced or timed-out stop) gets a playbook, so /incident revives such a node locally: the live run went to the model - wait.until fails when the condition isn't reached (non-zero exit; a playbook no longer carries on as if it held), and signal waits honor --validator instead of watching the profile's own validator - -p explains that it never approves transactions or key use and names the exact cometcli command to run in a terminal (the model invented one) - a playbook stops, rather than handing off to the model, when -p can't approve a step - gov propose: integer flags no longer block the text default Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- upgrade.releases: releases newer than the running image (version and source repo from its labels), the upgrade handler names each one registers, and a choice when there are several - upgrade.build: build the target on the node with the Dockerfile that built the running image (beside the compose project, else found under the home dir); optionally adds a no-op handler (RunMigrations) when the release registers none for the upgrade; checks version and handler in the built binary - upgrade.ready: the new image registers the plan name, the running binary doesn't, the deployed compose file is known - gov.propose --kind upgrade on docker nodes needs --image and refuses unless upgrade.ready passes: a name the new binary doesn't register halts the chain for good, one the old binary has switches nothing - upgrade.switch: only after the 'UPGRADE NEEDED' halt, and only to an image that registers the halted plan — sed the image in the deployed compose file (backup kept), compose down, up -d, same data dir Found on primium-1: every v0.6.x release registers only v0.5.0-to-v0.6.0, which v0.6.0 has too, so v0.6.1 can't be reached by a governed upgrade without a handler of its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
upgrade.build takes an image template — {tag} is the release tag,
{version} the tag without v — e.g. primium-{tag} → primium-v0.7.3.
profile add --image-name saves it as the profile's naming scheme. The
build is the official tag as-is; the upgrade-handler patch is for forks
only and stays opt-in.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A node's Dockerfile was written for the release it runs; a newer release may need a newer Go (cosmos/evm v0.7.x needs 1.25.9, the deployed Dockerfile pins 1.25.8). The build reads go.mod's go/toolchain line and, when the builder image is older, builds from a copy with the Go image raised — the original Dockerfile is untouched — and says so in a line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
upgrade.build reads the release notes: a state- or consensus-breaking release always asks (RequireApproval, whatever --yes or autopilot say) and the prompt says every validator must switch together at an upgrade height. The Go builder bump is decided before the prompt and shown in it. upgrade.releases marks breaking releases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the plan agreed for v0.4.x. The end-to-end run on a throwaway testnet comes next, before any release.
Local router: no model call for known questions and incidents
~/.cometcli/intents) answers them with read-only tools and a fixed template./incident: triage runs locally. When one known case is clearly the root cause and has a playbook, cometcli runs it, records the incident and reports./llmforces the model,/routeexplains the routing,/costcounts local answers, andagent.router: offdisables routing.Egress gate
Key material: a message carrying any of these is withheld whole, in the history too:
A prompt containing a mnemonic is refused before it's sent.
Strict egress (default on validators): the model sees
bash/read/grep/node.logs/fleetoutput only as a local summary, with identifiers masked, repeats folded and errors first. The UI and the audit log keep the raw output. RPC/sentry profiles and general mode default tofiltered.Key access
keyevent.Tests
🤖 Generated with Claude Code