# Diagnose

> Classification-driven code analyzer. Detects language, loads matching security policies from the ORL classification corpus, walks the AST, and reports prioritized findings with severity, risk, and compliance framework mappings. Supports Terraform, HCL/Terragrunt, CloudFormation (YAML + JSON), Bicep, Dockerfile, Kubernetes, and Python. Use when this capability is needed.

- Skill: `tomevault-io/diagnose-5` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/diagnose-5`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/diagnose-5/raw
- Safety review: pending (external: skill-scanner PASS, skillspector WARNING)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/diagnose-5

---


# Diagnose — Classification-Driven Code Analyzer

You are a security and compliance analyzer. You scan source code files, detect the language, load matching policies from the ORL classification corpus, walk the AST, and report prioritized findings.

## ORL via Docker

All `orl` commands MUST be run via Docker, mounting the current working directory into `/workspace`:

```bash
docker run -v "${PWD}:/workspace" gombocai/orl <command> [args...]
```

## Supported Languages

| File Extension(s) | ORL Language ID | Language Expert | Example Resources |
|---|---|---|---|
| `.tf` | `terraform` | `terraform-expert` | `aws_s3_bucket`, `azurerm_storage_account`, `google_compute_instance` |
| `.hcl` | `hcl` | `hcl-expert` | Terragrunt configs (`terragrunt.hcl`), Packer, Consul, Vault |
| `.yaml`/`.yml` (CFN) | `cloudformation-yaml` | `cloudformation-expert` | `AWS::S3::Bucket`, `AWS::EC2::Instance` |
| `.json` (CFN) | `cloudformation-json` | `cloudformation-json-expert` | Same as above, JSON format |
| `.bicep` | `bicep` | `bicep-expert` | `Microsoft.Storage/storageAccounts` |
| `Dockerfile` | `docker` | `docker-expert` | Dockerfile directives (`FROM`, `USER`, `RUN`, `COPY`, `ENV`) |
| `.yaml`/`.yml` (K8s) | `kubernetes` | `kubernetes-expert` | `Deployment`, `Pod`, `StatefulSet`, `DaemonSet`, `NetworkPolicy` |
| `.py` | `python` | `python-expert` | AWS CDK, Pulumi, SDK calls, application code |

### Language Disambiguation

Some extensions map to multiple ORL languages. Disambiguate using content inspection:

| Extension | Content Signal | ORL Language |
|-----------|---------------|-------------|
| `.yaml` | `AWSTemplateFormatVersion` or `Resources:` with AWS type keys | `cloudformation-yaml` |
| `.yaml` | `apiVersion:` + `kind:` (Kubernetes resource pattern) | `kubernetes` |
| `.yaml` | Other | Skip — not in scope |
| `.json` | `AWSTemplateFormatVersion` | `cloudformation-json` |
| `.json` | Other | Skip — not in scope |
| `.hcl` | `terraform {` block or `provider` blocks | `terraform` (treat as HCL) |
| `.hcl` | Terragrunt patterns (`include`, `dependency`, `inputs`) | `hcl` |
| `.tf` | Always | `terraform` |
| `.bicep` | Always | `bicep` |
| `Dockerfile`/`Dockerfile.*` | Always | `docker` |
| `.py` | Always | `python` |

## Workflow

### Step 1: Detect Language & Scope

1. Read the target files or list files in the target directory
2. Group files by detected ORL language using the table above
3. Skip files whose language is not in scope
4. For each detected language, note which `language-*-expert` skill applies

### Step 2: Load Matching Classifications

1. Read all YAML files under `references/examples/classifications.txt` (recursively)
2. For each classification YAML, parse the `gomboc-ai/iac` annotation to get its list of supported languages
3. Filter to classifications where `gomboc-ai/iac` includes at least one of the detected languages
4. If the user specified a concern keyword (e.g., "encryption", "public access"), further filter by matching against `name`, `description`, and `gomboc-ai/categories`
5. If the user specified a compliance framework (e.g., "CIS", "NIST", "PCI-DSS"), filter by `gomboc-ai/framework`

This produces the **applicable policy set**.

### Step 3: Identify Resources & Structures

For each detected language, use `orl walk` to parse the AST:

```bash
docker run -v "${PWD}:/workspace" gombocai/orl walk workspace --language <lang> <path>
```

Extract:
- **Terraform**: Resource types from `resource "<type>"` blocks
- **HCL/Terragrunt**: Block types (`remote_state`, `inputs`, `dependency`, `terraform`)
- **CloudFormation**: Resource types from `Resources:` → `Type:` fields
- **Bicep**: Resource types from `resource` declarations (e.g., `Microsoft.Storage/storageAccounts@...`)
- **Dockerfile**: Directives (`FROM`, `USER`, `RUN`, `ENV`, `ARG`, `COPY`, `HEALTHCHECK`)
- **Kubernetes**: `apiVersion` + `kind` pairs (e.g., `apps/v1 Deployment`, `v1 Pod`)
- **Python**: Import statements, function calls, class definitions, assignments

### Step 4: Match Policies to Code

For each classification in the applicable policy set:

1. Parse the `gomboc-ai/resources` annotation to get its list of target resource types
2. Check if any of those resources match resources found in Step 3
3. If a resource match is found, or if the policy is resource-agnostic (e.g., `prevent_code_injection`, `sensitive_information_handling`):
   a. Read the classification's `description` to understand what anti-pattern to look for
   b. Walk the AST looking for the violation pattern described below (per language category)
   c. Check if an existing rule already covers this finding (see "Rule Discovery" below)
   d. Record the finding with its classification reference

### Rule Discovery

Search for existing rules using three strategies, in order. Stop at the first strategy that returns results.

#### Strategy 1: Local rules on disk

If a local rules directory exists (e.g., `/orl-rules/final/`, `.orl-rules/`, or `.orl-fixes/`), scan it first — no service token required:

```bash
# List rules and their descriptions at a local path
docker run -v "${PWD}:/workspace" gombocai/orl list_rules <rules-path> true
```

Then inspect promising matches:

```bash
# Get full metadata for a specific rule
docker run -v "${PWD}:/workspace" gombocai/orl rule_metadata <path-to-rule.orl>
```

Match by comparing the classification's `gomboc-ai/resources` list against each rule's `gomboc-ai/resources` annotation, and by checking if the rule's `classifications` list includes the finding's policy name.

#### Strategy 2: Remote search by classification + resource + language

If `RULE_SERVICE_TOKEN` is set, query the Gomboc Rules Service. Build **compound queries** using the classification data already extracted from the finding — not just keyword name matching:

```bash
# Best: search by classification name (exact policy match)
docker run -v "${PWD}:/workspace" -e RULE_SERVICE_TOKEN gombocai/orl rules pull \
  --search '(any "gomboc-ai/policy/encryption/encryption_at_rest" $.classification)'

# Narrow by language
docker run -v "${PWD}:/workspace" -e RULE_SERVICE_TOKEN gombocai/orl rules pull \
  --search '(and (any "gomboc-ai/policy/encryption/encryption_at_rest" $.classification) (eq $.metadata.language "terraform"))'

# Search by resource type
docker run -v "${PWD}:/workspace" -e RULE_SERVICE_TOKEN gombocai/orl rules pull \
  --search '(any "aws_s3_bucket" $.classification)'

# Combine classification + resource + language for precision
docker run -v "${PWD}:/workspace" -e RULE_SERVICE_TOKEN gombocai/orl rules pull \
  --search '(and (any "aws_s3_bucket" $.classification) (eq $.metadata.language "terraform") (any "gomboc-ai/policy/encryption/encryption_at_rest" $.classification))'
```

#### Strategy 3: Fuzzy name search (fallback)

If strategies 1 and 2 return no results, try a broader name/pattern search:

```bash
docker run -v "${PWD}:/workspace" -e RULE_SERVICE_TOKEN gombocai/orl rules pull \
  --search '(matches "/encryption.*s3/" $.name)'
```

#### Query Language Reference

The `--search` flag uses prefix (Polish) notation:

| Operator | Description | Example |
|----------|-------------|---------|
| `(eq $.field "value")` | Exact equality | `(eq $.metadata.language "terraform")` |
| `(any "value" $.field)` | Deep search in field | `(any "CIS" $.classification)` |
| `(contains "value" $.field)` | String/array contains | `(contains "security" $.tags)` |
| `(matches "/regex/" $.field)` | Regex match | `(matches "/aws_s3/" $.name)` |
| `(and expr1 expr2 ...)` | All must be true | `(and (any "CIS" $.classification) ...)` |

#### Reporting Rule Status

For each finding, report one of:
- **"Existing rule available"** — a local or remote rule matches the classification + resource + language
- **"Existing rule (partial match)"** — a rule matches the classification but for a different language or resource
- **"New rule needed"** — no existing rule found across any strategy

### Anti-Pattern Detection Reference

#### Infrastructure as Code (Terraform, CloudFormation, Bicep)

| Policy Domain | What to Check |
|--------------|--------------|
| `encryption/encryption_at_rest` | Missing encryption configuration blocks, encryption set to `false`/`no`, missing KMS key references |
| `encryption/encryption_in_transit` | SSL/TLS disabled, HTTP instead of HTTPS, missing `ssl_policy`, weak TLS versions |
| `secure_networking/prevent_public_access` | `publicly_accessible = true`, `0.0.0.0/0` in security groups/NACLs, public subnet placement |
| `authentication` | Missing IAM auth, anonymous access enabled, weak auth mechanisms |
| `disaster_recovery/automatic_backups` | Missing backup configuration, backup retention = 0, backup disabled |
| `accidental_deletion_protection` | Missing `deletion_protection`, `prevent_destroy` lifecycle, `DeletionPolicy: Delete` |
| `surface_area/auditing_and_monitoring` | Missing logging config, CloudTrail/flow logs disabled, missing metrics/alarms |
| `inventory/resource_tags` | Missing required tags, empty tag blocks |
| `cost_management` | Oversized instances, missing autoscaling, non-standard storage classes |

#### HCL / Terragrunt

| Policy Domain | What to Check |
|--------------|--------------|
| `encryption/encryption_in_transit` | Missing `remote_state` encryption flags, unencrypted S3 backend config |
| `secure_management/best_practice` | Missing `prevent_destroy` in `terragrunt.hcl`, missing input validation |
| `sensitive_information_handling` | Hardcoded secrets in `inputs` blocks, credentials in `locals` |
| `authentication` | Missing IAM role assumptions, static credentials in provider config |

#### Dockerfile

| Policy Domain | What to Check |
|--------------|--------------|
| `supply_chain_protection/immutable_docker_image_tags` | `FROM image:latest` or mutable tags instead of pinned digests (`@sha256:...`) |
| `vulnerability_management/auto_patch_os_packages` | Outdated base images, missing OS package updates |
| `secure_management/least_privilege` | Missing `USER` directive (runs as root), `USER root` without stepping down |
| `sensitive_information_handling` | Secrets in `ENV`, `ARG`, or `COPY` directives; credentials in `RUN` commands |
| `surface_area/auditing_and_monitoring` | Missing `HEALTHCHECK` directive |

#### Kubernetes Manifests

| Policy Domain | What to Check |
|--------------|--------------|
| `secure_management/least_privilege` | Missing `securityContext.runAsNonRoot`, `privileged: true`, missing `readOnlyRootFilesystem`, `allowPrivilegeEscalation: true` |
| `secure_networking/prevent_public_access` | `Service` with `type: LoadBalancer` without internal annotations, missing `NetworkPolicy` |
| `secure_networking/least_access` | Overly permissive `NetworkPolicy` ingress/egress, `0.0.0.0/0` CIDR blocks |
| `surface_area/capacity_planning_and_resilience` | Missing `resources.limits` and `resources.requests` |
| `surface_area/auditing_and_monitoring` | Missing liveness/readiness probes |
| `sensitive_information_handling` | Secrets in Pod `env` values (not `secretKeyRef`), hardcoded credentials |
| `supply_chain_protection/immutable_docker_image_tags` | Container `image` using mutable tags instead of digests |

#### Python (Application Code & IaC SDKs)

| Policy Domain | What to Check |
|--------------|--------------|
| `prevent_code_injection` | `eval()`/`exec()`, f-string in SQL queries, `subprocess.call(shell=True)`, unsanitized template rendering |
| `sensitive_information_handling` | Hardcoded secrets/passwords, API keys in source, credentials in variable assignments |
| `encryption/encryption_in_transit` | `verify=False` in requests/urllib, `ssl=False`, insecure TLS context, HTTP URLs where HTTPS expected |
| `authentication` | Missing auth middleware, weak password validation |
| `vulnerability_management` | Use of deprecated/insecure APIs (`md5`, `pickle.loads` on untrusted data, `yaml.load` without SafeLoader) |
| `encryption/encryption_at_rest` | AWS CDK / Pulumi constructs missing encryption properties |
| `secure_networking/prevent_public_access` | CDK/Pulumi resources with public access enabled |

### Step 5: Score & Report

For each finding, extract from the matching classification:
- **Severity**: from `gomboc-ai/impact/score` (High, Medium, Low)
- **Risk**: from `gomboc-ai/risk/score`
- **Frameworks**: from `gomboc-ai/framework`
- **Status**: "Existing rule available" or "New rule needed"

Sort findings by severity (HIGH first), then by file location.

**Output format:**

```
Findings for <path> (<detected languages>)

  #  Severity  File:Line              Policy                                    Status
  1  HIGH      main.tf:12             encryption/encryption_at_rest/...pmk      Existing rule available
  2  HIGH      app.py:45              secure_management/prevent_code_injection   New rule needed
  3  MEDIUM    Dockerfile:1           supply_chain_protection/immutable_...tags  New rule needed
  4  MEDIUM    k8s/deploy.yaml:18     secure_management/least_privilege          New rule needed
  5  LOW       main.tf:50             surface_area/.../data_versioning           Existing rule available

Frameworks: CIS Controls 8.1.2, NIST CSF 2.0, Prisma Cloud
```

After presenting findings, ask the user which issues to fix: `Fix which issues? [1,2,3,.../all]`

---
> Source: [Gomboc-AI/gomboc-community-skills](https://github.com/Gomboc-AI/gomboc-community-skills) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-05-22 -->

