feat(mcp): add verify_execution_safety and simulate_workload_plan tools - #264
Merged
Conversation
Two new read-only MCP tools, filling the gaps flagged in the v0.14.7
optimization spec audit:
verify_execution_safety
Input: { command: string, surface?: string (default shell) }
Wraps internal/safety.Evaluator over DefaultRuleSet(). Maps the internal
verdict (allow/deny/prompt) to the operator-facing SAFE/PROMPT/VETO
vocabulary and returns { verdict, category, program, matched_rule,
reasons, raw_cmd, surface }. No execution — pure dry-run rule match.
simulate_workload_plan
Input: { task_description: string, cached?: bool }
Wraps placement.SelectBestNode + RankCandidates and surfaces the FULL
ranked candidate list with per-node fit_score/alloc_mb/reserved_mb,
not just the winning decision. No reservation, no execution.
Both tools are registered read-only (WithReadOnlyHintAnnotation(true))
and tested for the destructive-veto, read-only-allow, force-prompt, and
ranked-candidate-shape contracts.
Contributor
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
This was referenced Jul 27, 2026
added 2 commits
July 27, 2026 14:52
…kload_plan AGENTS.md and docs/runbooks/mcp-network-tools.md claimed 18 tools (15 read-only + 3 lease). After adding the two new read-only tools the verify-doc-facts guardrail correctly failed CI: AGENTS.md claims 18 MCP tools; internal/mcp registers 20 via s.AddTool Update both docs to 20 tools (17 read-only + 3 advisory lease) and list the new tools in the runbook. ./hack/verify-doc-facts.sh now passes.
toasterbook88
added a commit
that referenced
this pull request
Jul 27, 2026
… execution (#265) ## Summary Fills the **1A gap** from the v0.14.7 optimization spec audit: \`PeakVRAMMB\` was previously only populated from *remote* execution responses — local execution on GPU hosts recorded **zero** VRAM. This adds real local VRAM telemetry. ## Implementation New \`internal/execution/vram.go\`: - \`samplePeakVRAM(ctx, interval)\` — starts a background goroutine that polls \`nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits\` at a fixed interval, sums across all GPUs, tracks the max total observed, and returns a \`stop() int64\` closure. - \`queryTotalVRAMUsed(ctx)\` — single-shot helper, returns \`(totalMiB, ok)\`; \`(0, false)\` if nvidia-smi is missing or output unparseable. Wired into \`runLocal\` (\`internal/execution/guarded.go\`): - Sampler starts immediately before \`runWithReservationHeartbeat\`, stops immediately after. - \`resp.PeakVRAMMB\` is set on **both** success and failure paths. - Polling interval: 500ms (cheap vs. the seconds-to-minutes timescale of real workloads). ## Degradation On hosts without nvidia-smi (Apple Silicon, Intel-only, or PATH without the binary), \`queryTotalVRAMUsed\` returns \`(0, false)\` and the sampler's peak stays 0. No error surfaced — VRAM is best-effort telemetry, not load-bearing. ## Verification | Check | Result | |---|---| | \`TestSamplePeakVRAMReturnsZeroWhenNvidiaSmiMissing\` (PATH=\`/nonexistent\`) | PASS — 0 peak, no error | | \`TestSamplePeakVRAMStopsCleanly\` | PASS | | \`TestQueryTotalVRAMUsedHandlesMissingBinary\` | PASS — (0, false) | | \`TestSamplePeakVRAMLiveOnGPUHost\` on cranium (2x NVIDIA) | PASS — captured **17,896 MiB** peak over 500ms | | Full \`internal/execution\` suite | PASS | | Full \`internal/mcp\` suite | PASS (no regression) | | \`go build ./...\` | clean | ## Related Follows #264 (MCP tools, 4B). The remaining audit gap (1B pairwise link matrix) will follow as a separate PR. --------- Co-authored-by: AXIS Contributor <axis-dev@example.invalid>
toasterbook88
added a commit
that referenced
this pull request
Jul 27, 2026
…266) ## Summary Fills the **1B gap** from the v0.14.7 optimization spec audit: the spec described a \`PairwiseLinkMatrix\` / \`LinkMetric\` data structure that did not exist anywhere in the codebase. This adds it for real — a first cut that measures what's actually measurable from a single vantage. ## Types (\`internal/models/types.go\`) \`\`\`go type PairwiseLinkMatrix struct { Links []LinkMetric } type LinkMetric struct { SourceNode string TargetNode string OverlayType string // lan | tailscale | thunderbolt RTTLatencyP95 time.Duration ThroughputMBps float64 // 0 = unmeasured in this cut } \`\`\` \`ClusterSnapshot\` gains an optional \`Topology *PairwiseLinkMatrix\` field (zero-value-safe; existing consumers unaffected). ## Builder (\`internal/facts/pairwise.go\`) \`BuildPairwiseLinkMatrix(ctx, localName, nodes)\`: - Probes directional RTT from the local node to each remote node's \`ResolvedDialTarget\` (fallback \`SSHTarget\`) via \`ping -c 4 -W 1\`. - Parses the **max** RTT from the ping summary line as a P95 stand-in (4 samples). - Infers overlay from address shape: \`100.*\` → \`tailscale\`, \`169.254.*\` → \`thunderbolt\`, else \`lan\`. - **Single-vantage model**: only local→remote is probed; cross-remote edges are not measured. Throughput left at 0 (unmeasured) in this first cut — RTT is the primary signal. - **Best-effort**: unreachable nodes or missing \`ping\` are omitted, not fatal. No-local-node returns an empty matrix. \`TopologySummary(m)\` helper for logging. ## Verification | Check | Result | |---|---| | \`TestParseRTTP95\` (linux summary / no-summary / malformed) | PASS | | \`TestInferOverlay\` (tailscale / thunderbolt / lan / 10.x / hostname) | PASS | | \`TestBuildPairwiseLinkMatrixNoLocalNode\` | PASS — empty matrix, no panic | | \`TestBuildPairwiseLinkMatrixSkipsLocalAndEmptyTargets\` | PASS — self + empty skipped | | \`TestTopologySummaryEmpty\` / \`NonEmpty\` | PASS | | \`TestBuildPairwiseLinkMatrixLiveOnCranium\` (loopback) | PASS — captured \`cranium→loopback-target lan 27µs\` | | Full \`internal/facts\` + \`internal/models\` suites | PASS | | \`go build ./...\` | clean | ## Scope notes - This is a **first cut**: throughput is unmeasured, and only local→remote edges are probed. Cross-remote measurement would require distributed probing (each node probing the others) — out of scope for a single-PR addition, and the spec didn't require it. - The builder is **not yet wired into the snapshot pipeline** — it's available for callers but \`ClusterSnapshot.Topology\` stays nil by default. Wiring it into \`axis status\` / daemon refresh is a deliberate follow-up so this PR stays focused on the type + builder. ## Related Follows #264 (MCP tools, 4B) and #265 (local VRAM sampling, 1A). Completes the three real gaps flagged in the spec audit. --------- Co-authored-by: AXIS Contributor <axis-dev@example.invalid>
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.
Summary
Implements the two MCP tools flagged as missing in the v0.14.7 optimization spec audit (claim 4B). Both are read-only dry-run tools — no execution, no reservation.
verify_execution_safety
Evaluates a proposed command against the structured safety rule set without running it.
simulate_workload_plan
Dry-run placement ranker — returns best node + full ranked candidate list, not just the winner.
Tests
Full `internal/mcp` suite passes; `go build ./...` clean.
Related
Fills the 4B gap from the spec audit. The other two gaps (1A local VRAM sampling, 1B pairwise link matrix) will follow as separate PRs.