Install
$ agentstack add skill-knoxops-open-devops-skills-resource-cleaner ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Input Parameters
| Name | Type | Required | Description | |------|------|----------|-------------| | rundir | string | Yes | Workspace root directory for file passing between steps | | phase5decisionfile | string | Yes | Path to Phase 5 confirmation decision JSON (from zombie-decision-handler) | | resourceids | array | Yes | List of resource IDs to delete | | batchsizemax | integer | No | Max resources per deletion batch | | batchintervalsec | integer | No | Interval between batches (seconds) | | deletionparallelism | integer | No | Max concurrent deletion operations per batch | | enableeipdnscheck | boolean | No | Enable DNS record check before elastic IP deletion | | dry_run | boolean | No | Dry-run mode (validate logic but do not execute actual deletion) |
Execution Flow
Task Context
Before starting execution, initialize task_context.json:
{
"task_id": "",
"current_step": 0,
"current_step_id": null,
"status": "running",
"steps": {
"load_phase5_decision": "pending",
"preflight_check_cooling_period": "pending",
"preflight_check_decision_status": "pending",
"preflight_check_resource_existence": "pending",
"preflight_check_isolation_state": "pending",
"preflight_check_no_new_traffic": "pending",
"preflight_check_dependencies": "pending",
"preflight_check_owner": "pending",
"preflight_aggregate_result": "pending",
"verify_backup_creator_output": "pending",
"build_dependency_graph": "pending",
"topological_sort_resources": "pending",
"create_batch_plan": "pending",
"execute_batch_deletions": "pending",
"verify_deletion_completion": "pending",
"check_orphaned_objects": "pending",
"check_billing_charges": "pending",
"update_cmdb": "pending",
"update_monitoring": "pending",
"collect_all_events": "pending",
"build_audit_trail": "pending",
"calculate_cost_savings": "pending",
"generate_batch_summary": "pending",
"merge_reports": "pending",
"generate_notifications": "pending"
},
"updated_at": ""
}
Update this file after each step completes. On error, set step status to "failed" and overall status to "failed".
Step 1: loadphase5decision
Type: inline Description: Load Phase 5 confirmation decision and validate format
Execution
Follow these instructions:
Read the Phase 5 confirmation decision from {rundir}/{phase5decision_file}.
Validate that it is valid JSON and contains:
- Top level: decisionid, decisiontimestamp, total_resources, resources (non-empty array)
- Per resource: resourceid, observationresult, resourcetype, entitytype
- Per resource: environment, cloudprovider, resourcemetadata, estimatedmonthlycost
Note: observationresult is the authoritative gating field -- resources with observationresult="passed" have completed the isolation observation period and are safe to delete.
Output to {rundir}/delete/phase5decision_loaded.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"load_phase5_decision" - Set
steps.load_phase5_decisionto"completed"
Step 2: preflightcheckcooling_period
Type: inline Description: Verify observation period has completed (isolation observation IS the cooling period)
Input Files
delete/phase5_decision_loaded.json(from Step loadphase5decision, schema: schemas/phase5_confirmation.schema.json)
Execution
Follow these instructions:
Read {rundir}/delete/phase5decision_loaded.json to get resource IDs.
The isolation observation period from Phase 2 serves as the cooling period. Each resource must have passed observation before deletion can proceed.
For each resource in {resource_ids}:
- Verify observation_result is "passed" in the phase5 decision.
- If observation_result is "failed" or "uncertain": output BLOCKED reason.
- If observation_result is "passed": output passed status.
Note: There is no separate coolingperiodtracker.json in the new flow. The Phase 2 isolation observation IS the cooling period. Resources that passed observation are safe to delete.
Output to {rundir}/delete/preflightcooling_period.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"preflight_check_cooling_period" - Set
steps.preflight_check_cooling_periodto"completed"
Step 3: preflightcheckdecision_status
Type: inline Description: Verify decision is valid (decisionid + decisiontimestamp exist)
Input Files
delete/phase5_decision_loaded.json(from Step loadphase5decision, schema: schemas/phase5_confirmation.schema.json)
Execution
Follow these instructions:
Read {rundir}/delete/phase5decision_loaded.json.
phase5decision.json does NOT contain a decisionstatus field. Instead, validate:
- decision_id is present and non-empty
- decision_timestamp is a valid ISO8601 timestamp
- total_resources > 0
- resources array is non-empty
If all checks pass: output PASSED If any check fails: output BLOCKED with reason
Output to {rundir}/delete/preflightdecision_status.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"preflight_check_decision_status" - Set
steps.preflight_check_decision_statusto"completed"
Step 4: preflightcheckresource_existence
Type: inline Description: Verify resources still exist in cloud (query cloud APIs)
Execution
Follow these instructions:
For each resourceid in {resourceids}:
Query cloud API to check if resource exists:
- For CloudVM: describeinstances(resourceid)
- For RDS: describedbinstances(resource_id)
- For K8s: kubectl get resource resource_id
- etc.
Record: exists (true/false), resource_state (running/stopped/etc)
Output to {rundir}/delete/preflightresource_existence.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"preflight_check_resource_existence" - Set
steps.preflight_check_resource_existenceto"completed"
Step 5: preflightcheckisolation_state
Type: inline Description: Verify Phase 3 isolation is still valid (stopped, security group denied, etc)
Execution
Follow these instructions:
For each resourceid in {resourceids}:
Check isolation state based on entity_type:
- CloudVM: verify instance is Stopped
- RDS: verify security group has Deny All inbound
- K8s Deployment: verify replicas == 0
- Redis: verify whitelist is empty or denies all
Record: isolationvalid (true/false), currentstate
Output to {rundir}/delete/preflightisolation_state.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"preflight_check_isolation_state" - Set
steps.preflight_check_isolation_stateto"completed"
Step 6: preflightchecknonewtraffic
Type: inline Description: Verify no new traffic in last 7 days (check metrics, access logs)
Execution
Follow these instructions:
For each resourceid in {resourceids}:
Query monitoring/metrics APIs for last 7 days:
- Traffic volume
- Connection count
- Access log entries
- Request count
If any metric > 0: flag as warning, record data If all metrics == 0: flag as passed
Output to {rundir}/delete/preflighttraffic_check.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"preflight_check_no_new_traffic" - Set
steps.preflight_check_no_new_trafficto"completed"
Step 7: preflightcheckdependencies
Type: inline Description: Verify no new dependencies created
Execution
Follow these instructions:
For each resourceid in {resourceids}:
Query dependency records:
- Find all resources that depend on this resource
- Check if any dependencies were created after Phase 5 decision timestamp
- Record new dependencies
Output to {rundir}/delete/preflightdependencies.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"preflight_check_dependencies" - Set
steps.preflight_check_dependenciesto"completed"
Step 8: preflightcheckowner
Type: inline Description: Verify Owner unchanged compared to Phase 2 record
Execution
Follow these instructions:
For each resourceid in {resourceids}:
Read Phase 5 decision resource's ownerdetail.userid Query current asset system for owner_id
If changed: flag warning, record old vs new If unchanged: flag passed
Output to {rundir}/delete/preflightowner_check.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"preflight_check_owner" - Set
steps.preflight_check_ownerto"completed"
Step 9: preflightaggregateresult
Type: inline Description: Aggregate all pre-flight checks and determine overall result
Execution
Follow these instructions:
Read all preflight check results:
- cooling_period
- decision_status
- resource_existence
- isolation_state
- traffic_check
- dependencies
- owner_check
Determine overall result:
- BLOCKED: if any critical check fails (resourceexistence shows resource missing, isolationstate invalid, owner_changed)
- BLOCKED: if coolingperiod check fails (observationresult is not "passed")
- BLOCKED: if decisionstatus check fails (decisionid/timestamp missing or invalid)
- WARNING: if traffic detected or new dependencies found
- PASSED: all checks pass
If WARNING: create a review request, record waiting for human approval
Output to {rundir}/delete/preflight_report.json
Write the output to the specified output file.
Output
- Schema: schemas/preflightreevaluation_result.schema.json
- File: delete/preflightreport.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"preflight_aggregate_result" - Set
steps.preflight_aggregate_resultto"completed"
Step 10: verifybackupcreator_output
Type: inline Description: Verify backup-creator has produced valid backups for all resources about to be deleted
Execution
Follow these instructions:
The zombie-backup-creator runs before resource-cleaner and produces the following output files in {run_dir}/delete/:
- backup_summary.json -- aggregate summary with statistics, per-resource status,
nextsteps.readyfordeletion, nextsteps.successful_resources, escalations
- backupstrategies.json -- per-resource backup strategy (method, retentiondays)
- backupreport{resource_id}.json -- per-resource detailed backup report
Verification checklist:
- Read {rundir}/delete/backupsummary.json.
- Confirm the file exists and is valid JSON.
- Check statistics.successful_backups > 0.
- Check nextsteps.readyfor_deletion is true.
- Read {rundir}/delete/backupstrategies.json.
- Confirm the file exists and contains a strategy entry for each
resourceid in {resourceids}.
- For each resourceid in {resourceids}:
a. Verify a backupreport{resourceid}.json exists in {rundir}/delete/ b. Verify the report's backuprecord.status is "success" c. Verify backuprecord.verification.passed is true d. Verify backuprecord.protection.tagsapplied is true
- Cross-reference: every resourceid in {resourceids} MUST have a
successful backup record in backup_summary.json. If any resource is missing a backup or has a failed backup -> HALT DELETION and output error.
- If escalations exist in backup_summary.json, check whether any escalated
resources are in {resource_ids}. If so -> HALT DELETION for those specific resources, proceed with non-escalated ones if possible.
If canproceedwith_deletion is false, DO NOT continue to Phase 3. Output the verification failure and escalate to manual review.
Output to {rundir}/delete/backupverification_summary.json
Write the output to the specified output file.
Output
- Schema: schemas/backupverificationsummary.schema.json
- File: delete/backupverificationsummary.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"verify_backup_creator_output" - Set
steps.verify_backup_creator_outputto"completed"
Step 11: builddependencygraph
Type: inline Description: Build resource dependency graph (for batch sequencing)
Execution
Follow these instructions:
For each resourceid in {resourceids}:
Read Phase 5 decision blast_radius to find dependencies
- If resource A's blast_radius includes resource B
- Add edge: A -> B (A depends on B, so B should be deleted first)
Output to {rundir}/delete/dependencygraph.json
Write the output to the specified output file.
Output
- Schema: schemas/dependency_graph.schema.json
- File: delete/dependency_graph.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"build_dependency_graph" - Set
steps.build_dependency_graphto"completed"
Step 12: topologicalsortresources
Type: inline Description: Perform topological sort on dependency graph
Input Files
delete/dependency_graph.json(from Step builddependencygraph, schema: schemas/dependency_graph.schema.json)
Execution
Follow these instructions:
Read {rundir}/delete/dependencygraph.json
Perform topological sort: resources with no dependencies first, then resources whose dependencies are already sorted
Output sorted list to {rundir}/delete/sortedresources.json
Write the output to the specified output file.
Output
- Schema: schemas/sorted_resources.schema.json
- File: delete/sorted_resources.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"topological_sort_resources" - Set
steps.topological_sort_resourcesto"completed"
Step 13: createbatchplan
Type: inline Description: Create batch execution plan (max batchsizemax per batch, 5min intervals)
Input Files
delete/sorted_resources.json(from Step topologicalsortresources, schema: schemas/sorted_resources.schema.json)
Execution
Follow these instructions:
Read {rundir}/delete/sortedresources.json
Create batches:
- Max {batchsizemax} resources per batch
- Resources in each batch have no inter-dependencies
- Total batches: ceil(totalresources / {batchsize_max})
Output to {rundir}/delete/batchdelete_plan.json
Write the output to the specified output file.
Output
- Schema: schemas/batchdeletionplan.schema.json
- File: delete/batchdeleteplan.json
Progress Tracking
After completing this step, update task_context.json:
- Set
current_step_idto"create_batch_plan" - Set
steps.create_batch_planto"completed"
Step 14: executebatchdeletions
Type: inline Description: Execute deletion batches sequentially, resources in batch in parallel
Input Files
delete/batch_delete_plan.json(from Step createbatchplan, schema: schemas/batchdeletionplan.schema.json)
Execution
Follow these instructions:
Read {rundir}/delete/batchdelete_plan.json and Phase 5 decision.
For each batch (sequentially): For each resource in batch (up to {deletion_parallelism} in parallel): Execute 6-step deletion:
- Detach traffic
- Remove from load balancer backends
- Clear DNS records
- Verify K8s endpoints empty
- Unbind elastic IP (release separately)
- Stop services
- Stop VM instance
- K8s: scale replicas to 0
- Redis: clear whitelist
- Delete sub-resources
- RDS: delete read replicas first
- K8s: delete HPA, Service (if cohabited)
- Delete data disks, ENI
- Delete main resource
- DELETE instance / DB / workload / etc
- Special for elastic IP: check DNS records before release (if {en
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: KnoxOps
- Source: KnoxOps/open-devops-skills
- License: Apache-2.0
- Homepage: https://knoxops.app?invite_token=GITHUB26
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.