name: jdcloud-vm-ops
description: >-
Use when managing JD Cloud VMs — create, start, stop, restart, delete, resize;
manage disks, key pairs, snapshots; configure EIPs, security groups; run
scripts via cloud assistant; diagnose issues. Works with "实例", "服务器",
"云服务器", or "CVM" without saying "VM". NOT for monitoring, VPC,
load balancers, or billing.
license: MIT
compatibility: >-
Official JD Cloud SDK (Python 3.10+), valid API credentials, network
access to JD Cloud endpoints, and official JD Cloud CLI (jdc).
metadata:
author: buhaiqing
version: "1.8.0"
last_updated: "2026-06-18"
runtime: Harness AI Agent
api_profile: "VM API v1.0 - https://docs.jdcloud.com/cn/virtual-machines/api"
cli_applicability: jdc-first-with-fallback
cli_version_locked: "1.2.12"
sdk_version_locked: ">=1.6.26"
cli_support_evidence: >-
Official jdc CLI supports VM operations. Verified via jdc vm --help
and documentation at https://docs.jdcloud.com/cn/cli
environment:
- JDC_ACCESS_KEY
- JDC_SECRET_KEY
- JDC_REGION
This skill follows the Agent Skill OpenSpec.
JD Cloud VM Operations Skill
Overview
JD Cloud Virtual Machine (VM) is a core computing service that provides elastic, scalable, and secure cloud servers. This skill enables efficient operations, including automated deployment, real-time monitoring, and rapid troubleshooting of VM resources.
CLI applicability (repository policy)
cli_applicability: jdc-first-with-fallback: OfficialjdcCLI supports VM operations. The Agent MUST attempt to usejdcas the primary execution path. Ifjdcinstallation or command execution fails, the Agent MUST retry up to 3 times (with exponential backoff). Only after 3 consecutive failures should the Agent fall back to SDK/API. Both paths MUST be documented.- Path Preference: Follow jdc-first with SDK fallback strategy. See API & SDK Usage for detailed comparison.
Trigger & Scope (Agent-Readable)
SHOULD Use This Skill When
- User mentions "JD Cloud VM" OR "云主机" OR "Virtual Machine" OR "CVM" OR "VM"
- Task involves CRUD operations on VM instances: create, describe, start, stop, reboot, delete, resize
- Task involves image management, disk management, keypair management
- Task involves cloud assistant (云助手) operations: create commands, invoke commands on VMs, batch execute scripts
- Task keywords: create-instances, describe-instances, start-instance, stop-instance, delete-instance, createCommand, invokeCommand, describeCommands, describeInvocations, cloud-assistant, 云助手, 批量执行命令
SHOULD NOT Use This Skill When
- Task is about monitoring metrics / alarms for VMs → delegate to:
jdcloud-cloudmonitor-ops - Task is about VPC / subnet / security group creation → delegate to:
jdcloud-vpc-ops - Task is about load balancer configuration → delegate to:
jdcloud-lb-ops - Task is purely about billing / account management → delegate to:
jdcloud-billing-ops
Delegation Rules
- If user asks "why is my VM slow / high CPU", use this Skill to describe the VM, then suggest
jdcloud-cloudmonitor-opsfor metrics data - If user wants a VM in a new VPC, suggest creating VPC first via
jdcloud-vpc-ops, then return here
Variable Convention (Agent-Readable)
This Skill uses structured placeholders to avoid prompt injection and parsing ambiguity:
| Placeholder | Meaning | Agent Action |
|---|---|---|
{{env.JDC_ACCESS_KEY}} |
Resolved from Agent runtime environment | NEVER prompt user for this; fail if not set |
{{env.JDC_SECRET_KEY}} |
Resolved from Agent runtime environment | NEVER prompt user for this; fail if not set |
{{env.JDC_REGION}} |
Resolved from Agent runtime environment | Use cn-north-1 as default if unset |
{{user.region}} |
Must be collected from user | Ask user once and reuse |
{{user.instance_id}} |
Must be collected from user | Ask user once and reuse |
{{user.instance_name}} |
Must be collected from user | Ask user once and reuse |
{{output.instance_id}} |
Captured from CLI JSON output | Parse from $.result.instanceIds[0] |
Rule: Placeholders wrapped in
{{env.*}}MUST NOT be exposed to or requested from the user. Placeholders wrapped in{{user.*}}MUST be collected interactively.
Security Warning: NEVER log, print, or expose
JDC_SECRET_KEY(or any secret) in console output, debug messages, or logs. When verification is needed, check existence only (e.g.,if os.environ.get('JDC_SECRET_KEY')) without printing the actual value. If logging credential status is required, use masked placeholders likeJDC_SECRET_KEY=<masked>orJDC_SECRET_KEY=***. This applies to all execution flows (SDK, CLI, and debugging scripts).
Output Parsing Rules (Agent-Readable)
Mandatory CLI Conventions
ponytail: full details in
references/cli-usage.mdand AGENTS.md.
--output jsonMUST be BEFORE the subcommand:jdc --output json vm <command>--no-interactivedoes NOT exist — omit it- CLI reads from
~/.jdc/configINI only (NOT env vars). SDK uses env vars - Resource IDs:
i-[hash](instance),img-[hash](image),vol-[hash](disk)
Key JSON Paths for Common Operations
| Operation | JSON Path | Type | Description |
|---|---|---|---|
| Create | $.result.instanceIds[0] |
string | Instance ID to track |
| Describe | $.result.instances[0].status |
string | Current state (running, stopped, etc.) |
| List | $.result.instances[*].instanceId |
array | All instance IDs |
| Start/Stop | $.requestId |
string | Non-empty means accepted |
Expected State Transitions
| Operation | Initial State | Target State | Poll Interval | Max Wait |
|---|---|---|---|---|
| Create | - | running |
5s | 300s |
| Start | stopped |
running |
5s | 120s |
| Stop | running |
stopped |
5s | 120s |
| Reboot | running |
running |
5s | 180s |
| Delete | running/stopped |
(404 on describe) | 5s | 300s |
Changelog
| Version | Date | Changes |
|---|---|---|
| 1.8.0 | 2026-06-18 | GCL v2 rollout: Enhanced Quality Gate with Phase 6 Hallucination Detection Layer (H, mandatory) and Phase 7 Reflexion Integration. Added pre-execution structural validity check for CLI parameters and JSON payloads. Integrated docs/failure-patterns.md for cross-session failure memory. Aligned with AGENTS.md GCL v2 specification (§10-11). |
| 1.7.0 | 2026-06-04 | GCL pilot: Added ## Quality Gate (GCL) chapter wiring this skill into the repository-wide Generator-Critic-Loop. Added references/rubric.md (5-dimension rubric, op-specific overrides) and references/prompt-templates.md (G/C/O prompt skeletons). max_iterations=2. safety_confirm_required=true for destructive ops. |
| 1.4.0 | 2026-05-07 | Cloud Assistant support: Added cloud assistant (云助手) operations — createCommand, invokeCommand, describeCommands, deleteCommands, describeInvocations. Added new reference cloud-assistant.md. Cloud assistant uses SDK/API only (jdc CLI not supported). |
| 1.3.0 | 2026-05-06 | Critical CLI behavioral fixes: Fixed --output json positioning (must be BEFORE subcommand), removed non-existent --no-interactive flag, corrected credential docs (CLI uses ~/.jdc/config INI, NOT env vars), added sandbox config workaround |
| 1.2.0 | 2026-05-06 | jdc-first with fallback strategy: execution flows now prioritize jdc CLI (primary) with SDK/API fallback after 3 retries; Prerequisites updated to uv-based bootstrap with Phase 1 (jdc) / Phase 2 (SDK fallback); Path Preference flipped to jdc-first; pre-flight checks reordered |
| 1.1.0 | 2026-05-03 | Added dual-path execution (SDK + CLI), complete frontmatter, api-sdk-usage.md, path preference |
| 1.0.0 | 2026-04-28 | Initial version, includes basic operational guide and reference templates |
| 1.0.1 | 2026-04-28 | Added VM instance management, network configuration, and security group operations guide |
Execution Flows (Agent-Readable)
Every operation follows the pattern: Pre-flight → Execute (jdc primary / SDK fallback) → Validate → Recover. The Agent MUST NOT skip any phase.
jdc-first strategy: The Agent MUST attempt jdc CLI first (primary path). If jdc fails after 3 retries with exponential backoff, fall back to SDK/API. Documentation below lists jdc before SDK to reflect execution priority.
Operation: Create VM Instance
Pre-flight Checks
| Check | Command | Expected | On Failure |
|---|---|---|---|
| CLI installed | jdc --version |
exit code 0 | Retry up to 3 times; then fall back to SDK |
| Credentials valid | jdc --output json vm describe-instances --region-id cn-north-1 --page-number 1 --page-size 1 |
$.error == null |
Prompt user to config CLI credentials (~/.jdc/config) or set SDK env vars |
| SDK available | python -c "import jdcloud_sdk" |
No import error | Document install pin (fallback path) |
| Instance types available | jdc --output json vm describe-instance-types --region-id {{user.region}} |
list non-empty | Suggest another region |
| Image exists | jdc --output json vm describe-images --region-id {{user.region}} --image-ids '["{{user.image_id}}"]' |
returns image | Suggest available public image |
| Subnet exists | jdc --output json vpc describe-subnet --region-id {{user.region}} --subnet-id {{user.subnet_id}} |
returns subnet | Suggest creating subnet first |
Execution — CLI (jdc) [Primary Path]
jdc --output json vm create-instances \
--region-id {{user.region}} \
--az "{{user.az}}" \
--instance-type "{{user.instance_type}}" \
--image-id "{{user.image_id}}" \
--name "{{user.instance_name}}" \
--primary-network-interface "{\"subnetId\":\"{{user.subnet_id}}\",\"securityGroupIds\":[\"{{user.sg_id}}\"]}" \
--system-disk "{\"diskCategory\":\"cloud_ssd\",\"diskSizeGB\":{{user.disk_size}}}" \
--charge-mode "postpaid_by_duration"
Execution (SDK Fallback — after 3 jdc failures)
SDK fallback: use
VmClient.create_instances()— see references/api-sdk-usage.md.
Post-execution Validation
- Capture
{{output.instance_id}}from$.result.instanceIds[0] - Poll until running:
for i in $(seq 1 60); do STATUS=$(jdc --output json vm describe-instances \ --region-id {{user.region}} \ --instance-ids '["{{output.instance_id}}"]' | jq -r '.result.instances[0].status') [ "$STATUS" = "running" ] && break sleep 5 done - If status is
running→ operation succeeded, report instance ID, public IP, private IP to user - If status is
error→ capture error from$.result.instances[0].errorMessage, go to Failure Recovery
Failure Recovery
| Exit Code | Error Pattern (regex) | Max Retries | Backoff | Agent Action |
|---|---|---|---|---|
| 1 | InvalidParameter |
1 | - | Re-check parameter format, retry with corrected params |
| 1 | QuotaExceeded |
0 | - | HALT. Inform user quota is full, suggest requesting increase |
| 1 | InsufficientBalance |
0 | - | HALT. Inform user to top up account |
| 1 | InsufficientResource |
1 | - | Suggest switching to another AZ via jdc vm describe-azs |
| 3 | InternalError |
3 | 2s, 4s, 8s | Retry with exponential backoff. After 3rd failure, report to user |
| Other | .* |
3 | 5s, 10s, 15s | Retry. On final failure, extract full error message and present to user |
Operation: Describe VM Instance
Execution — CLI (jdc) [Primary Path]
jdc --output json vm describe-instances \
--region-id {{env.JDC_REGION}} \
--instance-ids '["{{user.instance_id}}"]'
Execution (SDK Fallback — after 3 jdc failures)
SDK fallback: use
VmClient.describe_instances()— see references/api-sdk-usage.md.
Output to Present to User
| Field | JSON Path | Display Format |
|---|---|---|
| ID | $.result.instances[0].instanceId |
Plain text |
| Name | $.result.instances[0].name |
Plain text |
| Status | $.result.instances[0].status |
Badge: 🟢 running / 🟡 starting / 🔴 stopped |
| Type | $.result.instances[0].instanceType |
Plain text |
| Private IP | $.result.instances[0].primaryNetworkInterface.privateIpAddress |
Plain text |
| Public IP | $.result.instances[0].primaryNetworkInterface.elasticIp.publicIpAddress |
- if null |
Operation: Stop VM Instance
Pre-flight (Safety Gate)
- MUST ask user: "Are you sure you want to stop
{{user.instance_name}}({{user.instance_id}})? Running services will be interrupted." - MUST wait for explicit "yes" / "confirm" before proceeding
Execution — CLI (jdc) [Primary Path]
jdc --output json vm stop-instance \
--region-id {{env.JDC_REGION}} \
--instance-id {{user.instance_id}}
Execution (SDK Fallback — after 3 jdc failures)
SDK fallback: use
VmClient.stop_instance()— see references/api-sdk-usage.md.
Post-execution Validation
- Poll until status ==
stopped(max 120s)
Operation: Delete VM Instance
Pre-flight (Safety Gate)
- MUST ask user: "Are you sure you want to delete
{{user.instance_name}}({{user.instance_id}})? This is IRREVERSIBLE and will release all associated resources." - MUST wait for explicit "yes" / "confirm" before proceeding
Execution — CLI (jdc) [Primary Path]
jdc --output json vm delete-instance \
--region-id {{env.JDC_REGION}} \
--instance-id {{user.instance_id}}
Execution (SDK Fallback — after 3 jdc failures)
SDK fallback: use
VmClient.delete_instance()— see references/api-sdk-usage.md.
Post-execution Validation
- Poll
describe-instancesuntil HTTP 404 (max 300s)
Quality Gate (GCL)
This skill participates in the repository-wide Generator-Critic-Loop (GCL) defined in
AGENTS.md§Quality Gate. The quality gate is required for this skill (perAGENTS.md§8 — destructive ops).
Parameters (override AGENTS.md §8 defaults)
| Parameter | Value | Reason |
|---|---|---|
max_iterations |
2 | delete / stop are destructive; do not retry repeatedly on production VMs |
rubric_version |
v2 |
see rubric.md |
trace_path |
./audit-results/gcl-trace-YYYYMMDD-HHMMSS.json |
unified with jdcloud-audit-ops |
safety_confirm_required |
true for delete, stop, reboot, resize on running, detach-disk |
matches repository safety gate policy |
hallucination_check |
mandatory | Phase 6 H layer; validates CLI parameters before execution |
reflexion_integration |
enabled | Phase 7 lightweight Reflexion; loads docs/failure-patterns.md |
Loop overview
User request
│
▼
[0] Orchestrator pre-flight ──► load rubric, classify operation
│ optionally load failure-patterns.md
▼
[1] Generator (G) ──► jdc (primary) → SDK (after 3 fails)
│ generate command (DO NOT execute yet)
▼
[1.5] Hallucination Detection (H) ──► pre-execution structural validity check
│ (mandatory for vm-ops) - CLI parameter existence
│ - JSON structure compliance
│
├── PASS → [1a] Execute (run the jdc/SDK call)
├── FAIL → [1b] Regenerate (H retriggers G with hallucination report; max 1 retry)
│ still FAIL → HALT with "HALLUCINATION_ABORT"
▼
[2] Critic (C) ──► isolated context, blind to user request
│ score every rubric dimension (5+3)
│ assess test accuracy + regression gate
▼
[3] Orchestrator decider
├─ HALLUCINATION_ABORT → ABORT (no partial)
├─ Safety=0 / blocking → ABORT
├─ all pass → RETURN
├─ iter<2 & not all pass → RETRY (inject suggestions)
└─ iter=2 & not all pass → RETURN_BEST
Hallucination Detection Layer (H) — Mandatory
Purpose: Catch LLM-generated CLI/SDK calls that contain structurally invalid elements before they reach the JD Cloud VM API. This is a pre-execution gate placed between G's generation and actual API execution.
Two-Category Check (for vm-ops):
| Category | Check | Method |
|---|---|---|
| CLI Parameter Existence | Verify every --flag exists in jdc vm <operation> |
Compare against references/api-sdk-usage.md operation tables |
| JSON Structure Compliance | For JSON payloads (e.g., --tags, --user-data) |
Validate field nesting matches OpenAPI schema |
Key Parameters to Validate:
| Operation | Critical Parameters |
|---|---|
create-instance |
--instanceType, --az, --subnetId, --imageId, --name, --password/--keyNames |
delete-instance |
--instanceId, --includeDataDisk (if present) |
stop-instance |
--instanceId, --forceStop (if present) |
reboot-instance |
--instanceId, --forceReboot (if present) |
modify-instance-spec |
--instanceId, --instanceType |
resize-disk |
--diskId, --diskSize (must be larger) |
Termination:
| Condition | Exit Code | Action |
|---|---|---|
| H_PASS | — | Continue to [1a] Execute |
| H_FAIL → Regenerate | — | Inject hallucination report into G; max 1 regeneration attempt |
| HALLUCINATION_ABORT | 5 | HALT — structural hallucinations persist after regeneration |
Trace Integration:
The H result is embedded in the GCL trace JSON under iterations[].hallucination_detector:
{
"iter": 1,
"hallucination_detector": {
"status": "PASS|FAIL",
"checks": {
"cli_parameters": { "status": "PASS|FAIL", "unrecognized_params": [] },
"json_structure": { "status": "PASS|FAIL", "issues": [] }
},
"report": "..."
},
"regenerated": false,
"generator": { ... },
"critic": { ... }
}
Reflexion Integration (Lightweight Reflexion)
Purpose: Enable cross-session learning from failure patterns, complementing the within-session GCL loop with persistent failure memory.
Architecture:
┌─────────────────────────────────────────────────────────────────┐
│ GCL Execution (per-session) │
│ [0] Pre-flight → [1] Generate → [1.5] H → [2] C → [3] Decide │
└──────────────────────────┬──────────────────────────────────────┘
│
failure_pattern (in trace)
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Reflexion Memory (cross-session) │
│ docs/failure-patterns.md (structured text, ≤200 lines) │
│ §1 CLI Parameter Errors | §2 Skill Generation | §3 Cross-Skill│
└──────────────────────────┬──────────────────────────────────────┘
│
Pre-flight retrieval (optional)
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Prevention (next session) │
│ Inject known patterns into Generator context │
│ Agent avoids repeating known mistakes │
└─────────────────────────────────────────────────────────────────┘
Pre-flight Retrieval (Optional):
During GCL Pre-flight (step [0]), the Orchestrator MAY:
# 1. Load docs/failure-patterns.md (lazy-load, ~150 lines)
# 2. Filter patterns by current skill name (jdcloud-vm-ops)
# 3. Inject top-3 relevant patterns into Generator context as prevention hints
# Example injection:
"Known failure patterns for this skill:
- InvalidInstanceType: Use exact instance type code from describe-instance-types
- MissingSubnetId: Subnet ID is required for instance creation
- InvalidAz: Availability zone must match region (e.g., cn-north-1a)"
This is a HINT, not a CONSTRAINT — the Generator should use these patterns to avoid known mistakes, but is not required to follow them if the context differs.
Failure Pattern Extraction:
When a GCL iteration fails (SAFETY_FAIL, HALLUCINATION_ABORT, or rubric dimension < threshold), the Orchestrator SHOULD extract a structured failure pattern and append it to the trace:
{
"failure_pattern": {
"category": "cli_parameter" | "skill_generation" | "cross_skill" | "runtime" | "token_efficiency",
"skill": "jdcloud-vm-ops",
"command": "jdc vm create-instance ...",
"error": "InvalidParameter: InvalidInstanceType",
"fix": "Use exact instance type code from describe-instance-types",
"reusable": true
}
}
Reusable patterns (reusable=true) are candidates for docs/failure-patterns.md — the centralized Reflexion memory.
Artifacts
- Rubric (concrete scoring rules): references/rubric.md
- Prompt templates (G / C / O / H): references/prompt-templates.md
- Failure patterns (cross-session memory): docs/failure-patterns.md
Integration with existing flows
The GCL wraps the jdc-first / SDK-fallback flow defined under
## Execution Flows above. The Generator (G) IS the existing jdc-or-SDK
executor. The Critic (C) is a new, read-only role with no jdc / SDK access.
The Orchestrator (O) owns the loop and persists the GCL trace.
The Hallucination Detector (H) is a mandatory pre-execution structural check.
Operation-specific behavior
delete-instance— Critic checks the trace contains both a pre-deletedescribe-instancessnapshot and a post-deletedescribe-instances404. Missing either → Correctness = 0. H layer validates--instanceIdformat before execution.create-instance— Critic verifies--client-tokenwas set (Idempotency = 1 required). Missing → Idempotency = 0. H layer validates--instanceType,--az,--subnetIdbefore execution.stop-instance/reboot-instance— Safety = 0 if the pre-state was notrunningand the user did not explicitly opt in. H layer validates--instanceIdbefore execution.- Cloud assistant
run-command— All command output MUST appear in the trace; Traceability = 0 otherwise. H layer validates--commandContent(base64) before execution.
Cloud Assistant Operations
Important: Cloud assistant uses the separate endpoint
assistant.jdcloud-api.com.jdcCLI does NOT currently support cloud assistant commands. Use SDK/API only for all cloud assistant operations. See Cloud Assistant Guide for complete reference.
Operation: Create Cloud Assistant Command
Pre-flight Checks
| Check | Command | Expected | On Failure |
|---|---|---|---|
| SDK available | python -c "import jdcloud_sdk" |
No import error | Install SDK via uv pip install jdcloud_sdk |
| Region ID known | - | Non-empty | Prompt user or default to cn-north-1 |
Execution — SDK
SDK-only (CLI not supported). Use
AssistantClient.create_command()— see references/cloud-assistant.md.
Post-execution Validation
- Capture
{{output.command_id}}fromresponse.result.commandId - Verify via
describeCommands
Failure Recovery
| Code | Max Retries | Agent Action |
|---|---|---|
QUOTA_EXCEEDED |
0 | HALT; delete unused commands |
INVALID_ARGUMENT |
1 | Re-check params, retry |
INTERNAL|UNKNOWN |
3 (2s/4s/8s) | Retry, then HALT |
Operation: Invoke Cloud Assistant Command
Pre-flight (Safety Gate)
- MUST confirm with user: "Execute command
{{user.command_name}}on {{user.instance_count}} VM(s)? This will run the command immediately." - MUST wait for explicit "yes" / "confirm" before proceeding
Pre-flight Checks
| Check | Command | Expected | On Failure |
|---|---|---|---|
| SDK available | python -c "import jdcloud_sdk" |
No import error | Install SDK |
| Command exists | describeCommands with commandIds |
Returns command | Suggest creating command first |
| VMs are running | describe-instances for each instanceId |
All status == running |
Skip non-running instances, warn user |
Execution — SDK
SDK-only (CLI not supported). Use
AssistantClient.invoke_command()— see references/cloud-assistant.md.
Post-execution Validation
- Capture
{{output.invoke_id}}fromresponse.result.invokeId - Poll via
DescribeInvocationsRequestuntil status in (finished,failed,partial_failed) — max 300s, 5s interval - Report table:
| Field | Display |
|---|---|
| Aggregate Status | ✅ finished / ❌ failed / ⚠️ partial_failed |
| Instance ID | Plain text |
| Exit Code | 0 = success |
| Output | Truncated (max 6000B) |
| Error | Red if non-empty |
| Duration | e.g., 3s |
Prerequisites
Python 3.10 is REQUIRED —
jdcloud_cli==1.2.12usesSafeConfigParserremoved in Python 3.12. Full setup is inAGENTS.mdMANDATORY Pre-flight Checks.
Quick Setup
uv venv --python 3.10
source .venv/bin/activate
uv pip install jdcloud_cli==1.2.12 jdcloud_sdk>=1.6.26
Credentials (CLI)
export HOME=/tmp/jdc-home
mkdir -p /tmp/jdc-home/.jdc
cat > /tmp/jdc-home/.jdc/config << 'CONFIGEOF'
[default]
access_key = {{env.JDC_ACCESS_KEY}}
secret_key = {{env.JDC_SECRET_KEY}}
region_id = {{env.JDC_REGION}}
endpoint = vm.jdcloud-api.com
scheme = https
timeout = 20
CONFIGEOF
printf "%s" "default" > /tmp/jdc-home/.jdc/current
CRITICAL: CLI reads credentials only from ~/.jdc/config INI, NOT env vars. SDK reads from env vars. Both paths require configuration.